Default

Loading interactive example. Full source is available below.

View example source
Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";

export const Default = () => {
    const itemIds = new Array(8).fill(0).map((_, index) => index.toString());
    const OverflowMenuItem = ({ id }: {
        id: string;
    }) => {
        const isVisible = useIsOverflowItemVisible(id);
        if (isVisible) {
            return null;
        }
        return <MenuItem>Item {id}</MenuItem>;
    };
    const OverflowMenu = ({ ids }: {
        ids: string[];
    }) => {
        const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
        if (!isOverflowing) {
            return null;
        }
        return (<Menu>
          <MenuTrigger disableButtonEnhancement>
            <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
          </MenuTrigger>

          <MenuPopover>
            <MenuList>
              {ids.map((id) => (<OverflowMenuItem key={id} id={id}/>))}
            </MenuList>
          </MenuPopover>
        </Menu>);
    };
    const styles = /* css */ `
      .overflow-default-example {
        display: flex;
        flex-wrap: nowrap;
        min-width: 200px;
        max-width: 800px;
        overflow: hidden;
        border: 2px solid var(--colorBrandBackground);
        padding: var(--spacingVerticalXXL) 10px 10px;
        position: relative;
        resize: horizontal;
      }

      .overflow-default-example::after {
        content: 'Resizable Area';
        position: absolute;
        padding: 1px var(--spacingHorizontalXS) 1px;
        top: -2px;
        left: -2px;
        font-family: monospace;
        font-size: 15px;
        font-weight: 900;
        line-height: 1;
        letter-spacing: 1px;
        color: var(--colorNeutralForegroundOnBrand);
        background-color: var(--colorBrandBackground);
      }
    `;
    return (<>
        <style>{styles}</style>
        <Overflow>
          <div className="overflow-default-example">
            {itemIds.map((id) => (<OverflowItem key={id} id={id}>
                <Button>Item {id}</Button>
              </OverflowItem>))}
            <OverflowMenu ids={itemIds}/>
          </div>
        </Overflow>
      </>);
};

export default Default;
API referenceGenerated CoreAI prop and type summaries

API

Generated CoreAI prop summaries, not replacement type declarations. Most native DOM/event and ARIA props are omitted. ? means optional; JSDoc shows defaults, deprecations, and conditional requirements. Defaults assume the standard CoreAI provider.

Overflow API

Provides an OverflowContext for OverflowItem descendants.

interface OverflowProps {
  children: ReactElement<any, string | JSXElementConstructor<any>>;

  /**
   * When true, reserve space as if the overflow menu were visible even with no overflowing items.
   * @default false
   */
  hasHiddenItems?: boolean;

  /**
   * Minimum number of items that must remain visible.
   */
  minimumVisible?: number;

  onOverflowChange?: ((ev: null, data: OverflowState) => void);

  /**
   * Overflow axis used for size measurement.
   * @default horizontal
   */
  overflowAxis?: "horizontal" | "vertical";

  /**
   * Direction where items are removed when overflow occurs.
   * @default end
   */
  overflowDirection?: "start" | "end";

  /**
   * Padding in pixels reserved at the end of the container before overflow occurs.
   * Useful for accounting for extra elements (for example an overflow menu button)
   * or margins between items that are difficult to measure in JavaScript.
   * @default 10
   */
  padding?: number;

  /**
   * Allows getting a ref to the component instance.
   * Once the component unmounts, React will set `ref.current` to `null`
   * (or call the ref with `null` if you passed a callback ref).
   */
  ref?: LegacyRef<unknown>;
}

OverflowItem API

Attaches overflow item behavior to its child registered with the OverflowContext. It does not render an element of its own.

Behaves similarly to other *Trigger components in Fluent UI React.

interface OverflowItemProps {
  /**
   * The single child that has overflow item behavior attached.
   */
  children: ReactElement<any, string | JSXElementConstructor<any>>;

  /**
   * Assigns the item to a group, group visibility can be watched.
   */
  groupId?: string;

  /**
   * The unique identifier for the item used by the overflow manager.
   */
  id: string;

  /**
   * If true, the item will never overflow and will always be visible.
   * Mutually exclusive with `priority`.
   */
  pinned?: boolean;

  /**
   * A higher priority means the item overflows later.
   * Mutually exclusive with `pinned`.
   */
  priority?: number;

  /**
   * Allows getting a ref to the component instance.
   * Once the component unmounts, React will set `ref.current` to `null`
   * (or call the ref with `null` if you passed a callback ref).
   */
  ref?: LegacyRef<unknown>;
}

Implementation

CoreAI 0.12.0; Fluent 9.74.9.

Setup and dependencies.

Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.

Custom Component

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import type { ForwardRefComponent } from "@coreai-ds/react-components";
import * as React from 'react';
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const ItemVisibleCustomComponent: ForwardRefComponent<{
    appId: string;
}> = React.forwardRef((props, ref) => {
    const isVisible = useIsOverflowItemVisible(props.appId);
    console.log(`Item ${props.appId} is ${isVisible ? '' : 'not '}visible'`);
    return <Button ref={ref}>Item {props.appId}</Button>;
});

export const CustomComponent = (): JSXElement => {
    const styles = useStyles();
    const itemIds = new Array(8).fill(0).map((_, i) => i.toString());
    return (<Overflow>
      <div className={mergeClasses(styles.container, styles.resizableArea)}>
        {itemIds.map(i => (<OverflowItem key={i} id={i}>
            <ItemVisibleCustomComponent appId={i}/>
          </OverflowItem>))}
      </div>
    </Overflow>);
};

export default CustomComponent;

Dividers

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';
import { useIsOverflowGroupVisible } from "@coreai-ds/react-components";
import { Divider } from "@coreai-ds/react-components";
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuDivider } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const OverflowGroupDivider: React.FC<{
    groupId: string;
}> = props => {
    const isGroupVisible = useIsOverflowGroupVisible(props.groupId);
    if (isGroupVisible === 'hidden') {
        return null;
    }
    return <Divider vertical appearance="brand" style={{ flexGrow: 0, paddingRight: '4px', paddingLeft: '4px' }}/>;
};

const OverflowMenuDivider: React.FC<{
    id: string;
}> = props => {
    const isGroupVisible = useIsOverflowGroupVisible(props.id);
    if (isGroupVisible === 'visible') {
        return null;
    }
    return <MenuDivider />;
};

const OverflowMenuItem: React.FC<{
    id: string;
}> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(i => {
            // This is purely a simplified convention for documentation examples
            // Could be done in other ways too
            if (typeof i === 'string' && i.startsWith('divider')) {
                const groupId = i.split('-')[1];
                return <OverflowMenuDivider key={i} id={groupId}/>;
            }
            return <OverflowMenuItem key={i} id={i}/>;
        })}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const Dividers = (): JSXElement => {
    const styles = useStyles();
    return (<Overflow padding={40}>
      <div className={mergeClasses(styles.container, styles.resizableArea)}>
        <OverflowItem id={'1'} groupId={'1'}>
          <Button>Item 1</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={'1'}/>
        <OverflowItem id={'2'} groupId={'2'}>
          <Button>Item 2</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={'2'}/>
        <OverflowItem id={'3'} groupId={'3'}>
          <Button>Item 3</Button>
        </OverflowItem>
        <OverflowItem id={'4'} groupId={'3'}>
          <Button>Item 4</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={'3'}/>
        <OverflowItem id={'5'} groupId={'4'}>
          <Button>Item 5</Button>
        </OverflowItem>
        <OverflowItem id={'6'} groupId={'4'}>
          <Button>Item 6</Button>
        </OverflowItem>
        <OverflowItem id={'7'} groupId={'4'}>
          <Button>Item 7</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={'4'}/>
        <OverflowItem id={'8'} groupId={'5'}>
          <Button>Item 8</Button>
        </OverflowItem>
        <OverflowMenu itemIds={['1', 'divider-1', '2', 'divider-2', '3', '4', 'divider-3', '5', '6', '7', 'divider-4', '8']}/>
      </div>
    </Overflow>);
};

export default Dividers;

Larger Dividers

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';
import { OverflowDivider } from "@coreai-ds/react-components";
import { ChevronRight20Regular } from "@fluentui/react-icons";
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { useIsOverflowGroupVisible } from "@coreai-ds/react-components";
import { MenuDivider } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const OverflowGroupDivider: React.FC<{
    groupId: string;
}> = props => {
    return (<OverflowDivider groupId={props.groupId}>
      <div>
        <ChevronRight20Regular />
      </div>
    </OverflowDivider>);
};

const OverflowMenuDivider: React.FC<{
    id: string;
}> = props => {
    const isGroupVisible = useIsOverflowGroupVisible(props.id);
    if (isGroupVisible === 'visible') {
        return null;
    }
    return <MenuDivider />;
};

const OverflowMenuItem: React.FC<{
    id: string;
}> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(i => {
            // This is purely a simplified convention for documentation examples
            // Could be done in other ways too
            if (typeof i === 'string' && i.startsWith('divider')) {
                const groupId = i.split('-')[1];
                return <OverflowMenuDivider key={i} id={groupId}/>;
            }
            return <OverflowMenuItem key={i} id={i}/>;
        })}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const LargerDividers = (): JSXElement => {
    const styles = useStyles();
    return (<Overflow>
      <div className={mergeClasses(styles.container, styles.resizableArea)}>
        <OverflowItem id={'1'} groupId={'1'}>
          <Button>Item 1</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={'1'}/>
        <OverflowItem id={'2'} groupId={'2'}>
          <Button>Item 2</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={'2'}/>
        <OverflowItem id={'3'} groupId={'3'}>
          <Button>Item 3</Button>
        </OverflowItem>
        <OverflowItem id={'4'} groupId={'3'}>
          <Button>Item 4</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={'3'}/>
        <OverflowItem id={'5'} groupId={'4'}>
          <Button>Item 5</Button>
        </OverflowItem>
        <OverflowItem id={'6'} groupId={'4'}>
          <Button>Item 6</Button>
        </OverflowItem>
        <OverflowItem id={'7'} groupId={'4'}>
          <Button>Item 7</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={'4'}/>
        <OverflowItem id={'8'} groupId={'5'}>
          <Button>Item 8</Button>
        </OverflowItem>
        <OverflowMenu itemIds={['1', 'divider-1', '2', 'divider-2', '3', '4', 'divider-3', '5', '6', '7', 'divider-4', '8']}/>
      </div>
    </Overflow>);
};

export default LargerDividers;

Listen To Changes

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import * as React from 'react';
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { OverflowItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'>> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    // As an union between button props and div props may be conflicting, casting is required
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(i => {
            return <OverflowMenuItem key={i} id={i}/>;
        })}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const ListenToChanges = (): JSXElement => {
    const styles = useStyles();
    const itemIds = new Array(8).fill(0).map((_, i) => i.toString());
    const [overflowState, setOverflowState] = React.useState<object>({});
    return (<>
      <Overflow onOverflowChange={(e, data) => setOverflowState(data)}>
        <div className={mergeClasses(styles.container, styles.resizableArea)}>
          {itemIds.map(i => (<OverflowItem key={i} id={i}>
              <Button>Item {i}</Button>
            </OverflowItem>))}
          <OverflowMenu itemIds={itemIds}/>
        </div>
      </Overflow>
      <pre>{JSON.stringify(overflowState, null, 2)}</pre>
    </>);
};

export default ListenToChanges;

Minimum Visible

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { OverflowItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'>> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    // As an union between button props and div props may be conflicting, casting is required
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(i => {
            return <OverflowMenuItem key={i} id={i}/>;
        })}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const MinimumVisible = (): JSXElement => {
    const styles = useStyles();
    const itemIds = new Array(8).fill(0).map((_, i) => i.toString());
    return (<Overflow minimumVisible={4}>
      <div className={mergeClasses(styles.container, styles.resizableArea)}>
        {itemIds.map(i => (<OverflowItem key={i} id={i}>
            <Button style={{ paddingLeft: 2, paddingRight: 2 }}>Item {i}</Button>
          </OverflowItem>))}
        <OverflowMenu itemIds={itemIds}/>
      </div>
    </Overflow>);
};

export default MinimumVisible;

Overflow By Priority

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { OverflowItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'>> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    // As an union between button props and div props may be conflicting, casting is required
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(i => {
            return <OverflowMenuItem key={i} id={i}/>;
        })}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const OverflowByPriority = (): JSXElement => {
    const styles = useStyles();
    const priorities = [2, 3, 6, 1, 4, 5, 0, 7];
    return (<Overflow>
      <div className={mergeClasses(styles.container, styles.resizableArea)}>
        {priorities.map(i => (<OverflowItem key={i} id={i.toString()} priority={i}>
            <Button>Priority {i}</Button>
          </OverflowItem>))}
        <OverflowMenu itemIds={priorities.map(x => x.toString())}/>
      </div>
    </Overflow>);
};

export default OverflowByPriority;

Pinned

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import * as React from 'react';
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { OverflowItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const OverflowSelectionItem: React.FC<{
    onSelectItem?: (item: string) => void;
    selected?: boolean;
    id: string;
}> = props => {
    const onClick = () => {
        props.onSelectItem?.(props.id);
    };
    return (<OverflowItem id={props.id} pinned={props.selected}>
      <Button aria-pressed={props.selected ? 'true' : 'false'} appearance={props.selected ? 'primary' : 'secondary'} onClick={onClick}>
        Item {props.id}
      </Button>
    </OverflowItem>);
};

const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'> & {
    onClick: () => void;
}> = props => {
    const { id, onClick } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    return <MenuItem onClick={onClick}>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
    onSelect: (itemId: string) => void;
}> = ({ itemIds, onSelect }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(i => (<OverflowMenuItem onClick={() => onSelect(i)} key={i} id={i}/>))}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const Pinned = (): JSXElement => {
    const styles = useStyles();
    const [selected, setSelected] = React.useState<Set<string>>(() => new Set(['6']));
    const onSelect = (itemId: string) => {
        setSelected(prev => {
            const next = new Set(prev);
            if (next.has(itemId)) {
                next.delete(itemId);
            }
            else {
                next.add(itemId);
            }
            return next;
        });
    };
    const itemIds = new Array(8).fill(0).map((_, i) => i.toString());
    return (<Overflow>
      <div className={mergeClasses(styles.container, styles.resizableArea)}>
        {itemIds.map(i => (<OverflowSelectionItem onSelectItem={onSelect} key={i} id={i} selected={selected.has(i)}/>))}
        <OverflowMenu itemIds={itemIds} onSelect={onSelect}/>
      </div>
    </Overflow>);
};

export default Pinned;

Priority With Dividers

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';
import { useIsOverflowGroupVisible } from "@coreai-ds/react-components";
import { Divider } from "@coreai-ds/react-components";
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuDivider } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const GROUPS = {
    ONE: 1,
    TWO: 2,
    THREE: 3,
    FOUR: 4,
    FIVE: 5,
};

const OverflowGroupDivider: React.FC<{
    groupId: number;
}> = props => {
    const groupVisibility = useIsOverflowGroupVisible(props.groupId.toString());
    if (groupVisibility === 'hidden') {
        return null;
    }
    return (<Divider data-group={props.groupId} vertical appearance="brand" style={{ flexGrow: 0, paddingRight: '4px', paddingLeft: '4px' }}/>);
};

const OverflowMenuDivider: React.FC<{
    groupId: number;
}> = props => {
    const { groupId } = props;
    // ⚠️⚠️ This is important
    // When collapsing based on custom priority, it's necessary to know
    // about other overflow groups because dividers can be rendered both
    // in the overflow container and the overflow menu.
    // The below code sorts the overflow groups and determines
    // if a divider should be rendered.
    const groupVisibilities = Object.values(GROUPS).map(group => {
        // eslint-disable-next-line react-hooks/rules-of-hooks
        return { group, visibility: useIsOverflowGroupVisible(group.toString()) };
    });
    const currentGroupPosition = groupVisibilities.findIndex(x => x.group === groupId);
    const precedesOverflowingGroup = groupVisibilities
        .slice(currentGroupPosition + 1)
        // If there is a overflowing/hidden group after the current group
        // render the menu divider.
        .some(groupVisibility => groupVisibility.visibility !== 'visible');
    if (groupVisibilities[currentGroupPosition].visibility === 'visible' || !precedesOverflowingGroup) {
        return null;
    }
    return <MenuDivider />;
};

const OverflowMenuItem: React.FC<{
    id: string;
}> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(itemId => {
            // This is purely a simplified convention for documentation examples
            // Could be done in other ways too
            if (itemId.startsWith('divider')) {
                const groupId = itemId.split('-')[1];
                return <OverflowMenuDivider key={itemId} groupId={Number(groupId)}/>;
            }
            return <OverflowMenuItem key={itemId} id={itemId}/>;
        })}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const PriorityWithDividers = (): JSXElement => {
    const styles = useStyles();
    return (<Overflow overflowDirection="start" padding={40}>
      <div className={mergeClasses(styles.container, styles.resizableArea)}>
        <OverflowItem id={'6'} priority={6} groupId={GROUPS.ONE.toString()}>
          <Button>Priority 6</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={GROUPS.ONE}/>
        <OverflowItem id={'7'} priority={7} groupId={GROUPS.TWO.toString()}>
          <Button>Priority 7</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={GROUPS.TWO}/>
        <OverflowItem id={'4'} priority={4} groupId={GROUPS.THREE.toString()}>
          <Button>Priority 4</Button>
        </OverflowItem>
        <OverflowItem id={'5'} priority={5} groupId={GROUPS.THREE.toString()}>
          <Button>Priority 5</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={GROUPS.THREE}/>
        <OverflowItem id={'1'} priority={1} groupId={GROUPS.FOUR.toString()}>
          <Button>Priority 1</Button>
        </OverflowItem>
        <OverflowItem id={'2'} priority={2} groupId={GROUPS.FOUR.toString()}>
          <Button>Priority 2</Button>
        </OverflowItem>
        <OverflowItem id={'3'} priority={3} groupId={GROUPS.FOUR.toString()}>
          <Button>Priority 3</Button>
        </OverflowItem>
        <OverflowGroupDivider groupId={GROUPS.FOUR}/>
        <OverflowItem id={'8'} priority={8} groupId={GROUPS.FIVE.toString()}>
          <Button>Priority 8</Button>
        </OverflowItem>
        <OverflowMenu itemIds={['6', 'divider-1', '7', 'divider-2', '4', '5', 'divider-3', '1', '2', '3', 'divider-4', '8']}/>
      </div>
    </Overflow>);
};

export default PriorityWithDividers;

Reorder Observer

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import * as React from 'react';
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowReorderObserver } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { OverflowItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
    controls: {
        display: 'flex',
        gap: '8px',
        marginTop: '12px',
    },
});

const INITIAL_IDS = new Array(8).fill(0).map((_, i) => i.toString());

const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'>> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(id => (<OverflowMenuItem key={id} id={id}/>))}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const ReorderObserver = (): JSXElement => {
    const styles = useStyles();
    const [itemIds, setItemIds] = React.useState(INITIAL_IDS);
    return (<>
      <Overflow>
        <div className={mergeClasses(styles.container, styles.resizableArea)}>
          <OverflowReorderObserver />
          {itemIds.map(id => (<OverflowItem key={id} id={id}>
              <Button>Item {id}</Button>
            </OverflowItem>))}
          <OverflowMenu itemIds={itemIds}/>
        </div>
      </Overflow>

      <div className={styles.controls}>
        <Button onClick={() => setItemIds(prev => [...prev].reverse())}>Reverse order</Button>
        <Button onClick={() => setItemIds(INITIAL_IDS)}>Reset</Button>
      </div>
    </>);
};

export default ReorderObserver;

Reverse Dom Order

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import * as React from 'react';
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { OverflowItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'>> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    // As an union between button props and div props may be conflicting, casting is required
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(i => {
            return <OverflowMenuItem key={i} id={i}/>;
        })}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const ReverseDomOrder = (): JSXElement => {
    const styles = useStyles();
    const itemIds = new Array(8).fill(0).map((_, i) => i.toString());
    return (<Overflow overflowDirection="start">
      <div className={mergeClasses(styles.container, styles.resizableArea)}>
        <OverflowMenu itemIds={itemIds}/>
        {itemIds.map(i => (<OverflowItem key={i} id={i}>
            <Button>Item {i}</Button>
          </OverflowItem>))}
      </div>
    </Overflow>);
};

export default ReverseDomOrder;

Vertical

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { OverflowItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        minWidth: 0,
        overflow: 'hidden',
    },
    overflowItem: {
        display: 'block',
    },
    resizableArea: {
        minWidth: '200px',
        maxWidth: '800px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        position: 'relative',
        resize: 'vertical',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'>> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(i => {
            return <OverflowMenuItem key={i} id={i}/>;
        })}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const Vertical = (): JSXElement => {
    const styles = useStyles();
    const itemIds = new Array(8).fill(0).map((_, i) => i.toString());
    return (<Overflow overflowAxis="vertical">
      <div className={mergeClasses(styles.container, styles.resizableArea)}>
        {itemIds.map(i => (<OverflowItem key={i} id={i}>
            <Button className={styles.overflowItem}>Item {i}</Button>
          </OverflowItem>))}
        <OverflowMenu itemIds={itemIds}/>
      </div>
    </Overflow>);
};

export default Vertical;

Wrapped

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { OverflowItem } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { MenuButton } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { OverflowItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexGrow: 1,
        flexWrap: 'nowrap',
        minWidth: 0,
        overflow: 'hidden',
    },
    farItems: {
        display: 'flex',
        gap: '4px',
        flexWrap: 'nowrap',
        marginRight: '10px', //to allow the resize handle to be grabbed
    },
    resizableArea: {
        display: 'flex',
        flexWrap: 'nowrap',
        minWidth: '200px',
        maxWidth: '1000px',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        overflow: 'hidden',
        position: 'relative',
        resize: 'horizontal',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});

const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'>> = props => {
    const { id } = props;
    const isVisible = useIsOverflowItemVisible(id);
    if (isVisible) {
        return null;
    }
    // As an union between button props and div props may be conflicting, casting is required
    return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{
    itemIds: string[];
}> = ({ itemIds }) => {
    const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();
    if (!isOverflowing) {
        return null;
    }
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuButton ref={ref}>+{overflowCount} items</MenuButton>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          {itemIds.map(i => {
            return <OverflowMenuItem key={i} id={i}/>;
        })}
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const Wrapped = (): JSXElement => {
    const itemIds = new Array(8).fill(0).map((_, i) => i.toString());
    const styles = useStyles();
    return (<div className={styles.resizableArea}>
      <Overflow>
        <div className={styles.container}>
          {itemIds.map(i => (<OverflowItem key={i} id={i.toString()}>
              <Button>Item{i}</Button>
            </OverflowItem>))}
          <OverflowMenu itemIds={itemIds}/>
        </div>
      </Overflow>

      <div className={styles.farItems}>
        <Button>Foo</Button>
        <Button>Bar</Button>
      </div>
    </div>);
};

export default Wrapped;