Box UI Elements

repository·master·Indexed 20 days ago

https://github.com/box/box-ui-elements

A library of pre-built, high-level UI components for integrating core Box web application features into custom applications. It provides standard elements like ContentExplorer, ContentPicker, ContentUploader, and ContentOpenWith, as well as specialized components such as ContentPreview and ContentSidebar. The library is available as React components and includes a variety of utility components including Badge, Breadcrumb, Checkbox, ContextMenu, and DatePicker.

Tokens
98.4K
Snippets
402
Records
498
Agent score
67%

What's inside box-ui-elements

  1. Use the DraftJSMentionSelector component

    master

    <DraftJSMentionSelector /> is a component used for text editing that implements the underlying text editor using Draft.js instead of the standard <ContentEditable />. It functions similarly to the <MentionSelector /> component but uses Draft.js's immutable state model.

    Component Hierarchy:

    1. DraftJSMentionSelector (Top-level)
    2. DraftJSEditor (Internal editor implementation)
  2. Use the DraftJSEditor component

    master

    The DraftJSEditor component provides a Draft.js editor interface within box-ui-elements.

    State Management

    This component is uncontrolled regarding its editorState. It does not own or manage the editor state internally. Instead, you must manage the EditorState in your own application logic and pass it to the component.

    Handling Changes

    Whenever the content within the <Editor /> changes, the component triggers its onChange method, passing the new EditorState as an argument. You should use this callback to update your local state.

    Using Decorators

    Because the component does not own the EditorState, you cannot configure Draft.js decorators via the DraftJSEditor component itself. You must apply any decorators (for features like mentions or custom formatting) at the point where you define and manage the EditorState in your application.

    // Conceptual usage pattern:
    // 1. Manage EditorState in your parent component
    // 2. Pass state to DraftJSEditor
    // 3. Update state via onChange
    
    <DraftJSEditor 
      editorState={this.state.editorState} 
      onChange={(nextEditorState) => this.setState({ editorState: nextEditorState })} 
    />
  3. Use the Datalist Item component

    master

    The Datalist Item is an ARIA-compliant component designed to render list items within a datalist, such as a SelectorDropdown.

    Key Behaviors:

    • Automatic ID Management: It automatically generates a unique ID and propagates that ID to the parent component when the item becomes active.
    • State Management Requirement: When using this component inside a SelectorDropdown, you must specify keys based on your actual data rather than using the default array index. Using data-based keys ensures that component state is reset correctly when the underlying data changes.
  4. Use the Portal component to render children into an outside DOM hierarchy

    master

    The Portal component is used to render children into a DOM node outside of the current component's hierarchy. This is specifically useful for UI elements that need to break out of parent containers, such as modals, notifications, popovers, and flyouts.

    Key behaviors to note:

    • Logic only: Portal only manages the mounting and unmounting logic to the outside DOM; it does not provide any built-in styles, event handlers, or behaviors. You must implement these in your parent component.
    • Context: React context is preserved and passed from the Portal parent to the children components.
    • Props: Any props passed to Portal (such as className) are applied directly to the inner-wrapper div that contains the children.
    import { Portal } from 'box-ui-elements';
    
    const MyPortalExample = ({ isOpen }) => {
        if (!isOpen) return null;
        return (
            <Portal className='modal-wrapper'>
                <div className='modal'>...
                </div>
            </Portal>
        );
    }
  5. Best practice: Use `import * as React from 'react'`

    master

    To ensure Flow types are automatically included, always use the import * as React from 'react' syntax. When using this pattern, you must prefix all React functions and components with React..

    Correct:

    • React.Component
    • React.useState

    Incorrect:

    • Component
    • useState
  6. Use a Selectable Table with HotkeyLayer

    master

    To use a selectable table (via the makeSelectable HOC), you must ensure that a <HotkeyLayer> component is present somewhere above the table in the component tree. Without a <HotkeyLayer>, the selectable functionality will not work correctly.

    // Note: The makeSelectable HOC requires a HotkeyLayer in the component tree
    <HotkeyLayer>
        <SelectableTableExamples />
    </HotkeyLayer>
  7. Use the Menu component for ARIA-compliant menus

    master

    The <Menu> component provides an ARIA-compliant menu implementation, handling keyboard navigation, focus management, and appropriate ARIA attributes according to the WAI-ARIA Menu standard.

    To build a menu, you can use several sub-components:

    • <MenuItem>: A standard menu item.
    • <MenuSeparator />: A visual divider between items.
    • <MenuSectionHeader>: A header for grouping menu items.
    • <MenuLinkItem>: Required for wrapping anchor tags (<a> or <Link>) to ensure correct ARIA behavior for links within a menu.
    • <SelectMenuLinkItem>: Used for items that represent a selectable state, typically rendered with a checkmark.
    • <SubmenuItem>: Used to nest a <Menu> inside another menu to create submenus.
    const { 
      MenuItem, 
      MenuSeparator, 
      MenuLinkItem, 
      MenuSectionHeader 
    } = require('box-ui-elements/es/components/menu');
    
    <Menu>
      <MenuItem>View Profile</MenuItem>
      <MenuItem showRadar>Help</MenuItem>
      <MenuSeparator />
      <MenuSectionHeader>Menu Section</MenuSectionHeader>
      <MenuLinkItem>
        <Link href="/#">Awesome Link</Link>
      </MenuLinkItem>
    </Menu>;
  8. Work with Entities and Decorators in DraftJSMentionSelector

    master

    Rich text styling in this component is handled via two mechanisms:

    Entities

    Entities annotate a range of text with metadata. In DraftJSMentionSelector, mentions are implemented as entities.

    1. Create an entity using contentState.createEntity().
    2. Use Modifier.replaceText(...) to replace the partial text (e.g., @se) with the full entity-ified text (e.g., @Sebastian Motraghi) to generate a new ContentState.
    3. The mention entity includes an id in its metadata.

    Decorators

    Decorators scan text to determine which ranges should be rendered with special UI.

    • The mentionDecorator is applied when creating the initial EditorState.
    • The mentionStrategy identifies ranges that have an Entity annotated as type: 'MENTION'.
    • Important Implementation Rule: When creating custom components for decorators, do not set text from a prop. The decorator sets the children prop with the actual text content. Your component must use { props.children } to ensure the rendered UI matches the internal state.

    Correct Pattern:

    // Do this
    <MyDecoratorComponent>{ props.children }</MyDecoratorComponent>
    
    // Do NOT do this
    <MyDecoratorComponent text={ props.text } />
  9. Authenticate Box UI Elements

    master

    Box UI Elements are authentication-agnostic and work with both Managed Users (Box accounts) and App Users. To authenticate, you must provide an access token to the component.

    You can provide the accessToken in two ways:

    1. As a string: A static access token.
    2. As a function: A function that returns a string. The component will invoke this function whenever it needs to make an API call to Box, allowing for dynamic token retrieval (e.g., refreshing tokens).