@launchpad-ui/menu 0.11.3 → 0.11.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -9,7 +9,7 @@ import { FocusRing, useFocusManager } from "@react-aria/focus";
9
9
  import { TextField } from "@launchpad-ui/form";
10
10
  import { useVirtual } from "react-virtual";
11
11
  const Menu$1 = "";
12
- const MenuBase = forwardRef(
12
+ const MenuBase = /* @__PURE__ */ forwardRef(
13
13
  ({ children, size, isVirtual, ...props }, ref) => {
14
14
  const classes = cx("Menu", isVirtual && "Menu--isVirtual", size && `MenuSize--${size}`);
15
15
  return /* @__PURE__ */ jsx("div", { ...props, role: "menu", className: classes, ref, children });
@@ -53,7 +53,7 @@ const MenuItem = ({
53
53
  ...rest
54
54
  } = props;
55
55
  const Component = component || (asChild ? Slot : defaultElement);
56
- const renderIcon = icon && cloneElement(icon, { size: "small" });
56
+ const renderIcon = icon && /* @__PURE__ */ cloneElement(icon, { size: "small" });
57
57
  const renderedItem = /* @__PURE__ */ jsx(FocusRing, { focusRingClass: "has-focus", children: /* @__PURE__ */ jsx(
58
58
  Component,
59
59
  {
@@ -91,9 +91,9 @@ const MenuItem = ({
91
91
  }
92
92
  return renderedItem;
93
93
  };
94
- const MenuItemList = forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsx("div", { ...rest, ref, "data-test-id": "menu-item-list", className: "Menu-item-list", children }));
94
+ const MenuItemList = /* @__PURE__ */ forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsx("div", { ...rest, ref, "data-test-id": "menu-item-list", className: "Menu-item-list", children }));
95
95
  MenuItemList.displayName = "MenuItemList";
96
- const MenuSearch = forwardRef((props, ref) => {
96
+ const MenuSearch = /* @__PURE__ */ forwardRef((props, ref) => {
97
97
  const {
98
98
  ariaLabel,
99
99
  placeholder,
@@ -177,7 +177,7 @@ const Menu = (props) => {
177
177
  case MenuSearch:
178
178
  return {
179
179
  items,
180
- searchElement: cloneElement(child, {
180
+ searchElement: /* @__PURE__ */ cloneElement(child, {
181
181
  onKeyDown: (e) => handleKeyboardInteractions(e, {
182
182
  handleDown: handleArrowDown,
183
183
  handleUp: handleArrowUp
@@ -187,12 +187,12 @@ const Menu = (props) => {
187
187
  case MenuItem:
188
188
  return {
189
189
  items: items.concat(
190
- child.props.disabled ? cloneElement(child, {
190
+ child.props.disabled ? /* @__PURE__ */ cloneElement(child, {
191
191
  onClick: () => void 0,
192
192
  onKeyDown: () => void 0,
193
193
  tabIndex: -1,
194
194
  disabled: true
195
- }) : cloneElement(child, {
195
+ }) : /* @__PURE__ */ cloneElement(child, {
196
196
  className: cx(child.props.className, menuItemClassName),
197
197
  item: child.props.item ?? items.length,
198
198
  // set focus on the first menu item if there is no search input, and set in the tab order
@@ -350,7 +350,7 @@ const ItemVirtualizer = (props) => {
350
350
  }
351
351
  };
352
352
  const renderSearch = useMemo(
353
- () => searchElement ? cloneElement(searchElement, {
353
+ () => searchElement ? /* @__PURE__ */ cloneElement(searchElement, {
354
354
  onKeyDown: (e) => handleKeyboardFocusKeydown(e, {
355
355
  handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),
356
356
  handleFocusForward: () => focusMenuItem(0)
@@ -374,7 +374,7 @@ const ItemVirtualizer = (props) => {
374
374
  style: {
375
375
  transform: `translateY(${virtualRow.start}px)`
376
376
  },
377
- children: cloneElement(elem, getItemProps(elem, virtualRow.index))
377
+ children: /* @__PURE__ */ cloneElement(elem, getItemProps(elem, virtualRow.index))
378
378
  },
379
379
  virtualRow.index
380
380
  );
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":["import type { MenuProps } from './Menu';\nimport type { ComponentPropsWithRef } from 'react';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n isVirtual?: boolean;\n size?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n ({ children, size, isVirtual, ...props }, ref) => {\n const classes = cx('Menu', isVirtual && 'Menu--isVirtual', size && `MenuSize--${size}`);\n\n return (\n <div {...props} role=\"menu\" className={classes} ref={ref}>\n {children}\n </div>\n );\n }\n);\n\nMenuBase.displayName = 'MenuBase';\n\nexport { MenuBase };\nexport type { MenuBaseProps };\n","import type { SeparatorProps } from '@react-aria/separator';\nimport type { RefObject } from 'react';\n\nimport { useSeparator } from '@react-aria/separator';\n\nimport './styles/Menu.css';\n\ntype MenuDividerProps = SeparatorProps & {\n innerRef?: RefObject<HTMLDivElement>;\n 'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n elementType = 'div',\n orientation,\n innerRef,\n 'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n const { separatorProps } = useSeparator({\n orientation,\n elementType,\n });\n\n return <div {...separatorProps} data-test-id={testId} ref={innerRef} className=\"Menu-divider\" />;\n};\n\nexport { MenuDivider };\nexport type { MenuDividerProps };\n","import type { IconProps } from '@launchpad-ui/icons';\nimport type { PopoverPlacement } from '@launchpad-ui/popover';\nimport type { ComponentPropsWithRef, ElementType, PropsWithRef, ReactElement } from 'react';\n\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { Slot } from '@radix-ui/react-slot';\nimport { FocusRing } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport { cloneElement } from 'react';\n\nimport './styles/Menu.css';\n\n// Merge two types and get rid of overlapping definitions\ntype Merge<T, U> = Omit<T, keyof U> & U;\n\ntype PropsWithComponent<P, T extends ElementType> = P & { component?: T };\n\ntype PolymorphicPropsWithRef<P, T extends ElementType> = Merge<\n T extends keyof JSX.IntrinsicElements\n ? PropsWithRef<JSX.IntrinsicElements[T]>\n : ComponentPropsWithRef<T>,\n PropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n isHighlighted?: boolean;\n icon?: ReactElement<IconProps>;\n disabled?: boolean;\n nested?: boolean;\n groupHeader?: boolean;\n tooltip?: string | ReactElement;\n tooltipOptions?: typeof Tooltip;\n tooltipPlacement?: PopoverPlacement;\n asChild?: boolean;\n 'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n | (MenuItemOwnProps & {\n item: P; // Infer the type if it is included\n })\n | (MenuItemOwnProps & {\n item?: undefined;\n }),\n T\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n ...props\n}: MenuItemProps<P, T>) => {\n const {\n // TODO: remove component prop once we migrate over to asChild format\n component,\n children,\n isHighlighted,\n icon,\n nested,\n groupHeader,\n item,\n disabled,\n className,\n tooltip,\n role = 'menuitem',\n tooltipPlacement,\n onKeyDown,\n tooltipOptions,\n asChild,\n 'data-test-id': testId = 'menu-item',\n ...rest\n } = props;\n\n const Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n const renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n const renderedItem = (\n <FocusRing focusRingClass=\"has-focus\">\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n 'Menu-item',\n className,\n isHighlighted && 'is-highlighted',\n nested && 'Menu-item--nested',\n groupHeader && 'Menu-item--header'\n )}\n data-test-id={testId}\n role={role}\n onKeyDown={onKeyDown}\n >\n {asChild ? (\n children\n ) : (\n <>\n {icon && <span className=\"Menu-item-icon\">{renderIcon}</span>}\n {children}\n </>\n )}\n </Component>\n </FocusRing>\n );\n\n if (tooltip) {\n return (\n <Tooltip\n content={tooltip}\n rootElementStyle={{ display: 'block' }}\n allowBoundaryElementOverflow\n placement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n {...(tooltipOptions || {})}\n >\n {renderedItem}\n </Tooltip>\n );\n }\n\n return renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n <div {...rest} ref={ref} data-test-id=\"menu-item-list\" className=\"Menu-item-list\">\n {children}\n </div>\n));\n\nMenuItemList.displayName = 'MenuItemList';\n\nexport { MenuItemList };\nexport type { MenuItemListProps };\n","import type { ChangeEvent } from 'react';\n\nimport { TextField } from '@launchpad-ui/form';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuSearchProps = {\n ariaLabel?: string;\n value?: string;\n id?: string;\n placeholder?: string;\n onChange?(event: ChangeEvent<HTMLInputElement>): void;\n 'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n const {\n ariaLabel,\n placeholder,\n id,\n 'data-test-id': testId = 'menu-search',\n ...finalProps\n } = props;\n\n return (\n <div className=\"Menu-search\">\n <TextField\n {...finalProps}\n ref={ref}\n className=\"Menu-search-input\"\n tiny\n id={id}\n type=\"search\"\n data-test-id={testId}\n autoComplete=\"off\"\n placeholder={placeholder}\n aria-label={ariaLabel || 'Search'}\n />\n </div>\n );\n});\n\nMenuSearch.displayName = 'MenuSearch';\n\nexport { MenuSearch };\nexport type { MenuSearchProps };\n","import type { EventHandler, KeyboardEvent, SyntheticEvent } from 'react';\n\nconst createItemId = (index: number, id: string) => `${id}-item-${index}`;\n\nconst getNodeForIndex = (index: number | null, menuId: string) =>\n index === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n event: KeyboardEvent,\n keyHandlers: Partial<\n Record<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n >\n) => {\n const ops = {\n ArrowUp: keyHandlers.handleUp,\n ArrowDown: keyHandlers.handleDown,\n Enter: keyHandlers.handleEnter,\n } as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n if (ops[event.key]) {\n event.preventDefault();\n ops[event.key]?.call(globalThis, event);\n }\n};\n\nconst chainEventHandlers =\n (...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n (event: SyntheticEvent) => {\n handlers.forEach((h) => typeof h === 'function' && h(event));\n };\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { MenuItemProps } from './MenuItem';\nimport type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n Children,\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useVirtual } from 'react-virtual';\n\nimport { MenuBase } from './MenuBase';\nimport { MenuDivider } from './MenuDivider';\nimport { MenuItem } from './MenuItem';\nimport { MenuItemList } from './MenuItemList';\nimport { MenuSearch } from './MenuSearch';\nimport {\n chainEventHandlers,\n createItemId,\n getNodeForIndex,\n handleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n children: ReactNode;\n onSelect?: (item: T) => void;\n /**\n * Menus items are rendered using react-virtual for\n * additional rendering performance.\n */\n enableVirtualization?: boolean;\n /**\n * Class name to be applied to all MenuItem components\n * in the menu.\n */\n menuItemClassName?: string;\n /**\n * Sets the width of the menu. This is especially useful when using virtual items\n * since the width cannot be automatically set by the widest element.\n */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /**\n * Sets the number out of elements rendered outside of the view window\n * when using virtualization\n */\n overscan?: number;\n /**\n * Sets the height for each menu item when using virtualization.\n *\n */\n itemHeight?: number;\n 'data-test-id'?: string;\n};\n\ntype MenuProps<T extends number | string> = ControlledMenuProps<T>;\n\nconst Menu = <T extends number | string>(props: MenuProps<T>) => {\n const {\n children,\n menuItemClassName,\n onSelect,\n enableVirtualization,\n itemHeight,\n size,\n overscan = 1,\n 'data-test-id': testId = 'menu',\n } = props;\n\n const focusManager = useFocusManager();\n\n const handleArrowDown = useCallback(() => {\n focusManager.focusNext({ wrap: true });\n }, [focusManager]);\n\n const handleArrowUp = useCallback(() => {\n focusManager.focusPrevious({ wrap: true });\n }, [focusManager]);\n\n const reduceItems = useMemo(() => {\n const childrenProps = Children.toArray(children);\n if (enableVirtualization) {\n // the virtualized menu has its own handlers and props\n let searchElem = null;\n let elements: ReactElement[] = [];\n (childrenProps as ReactElement[]).forEach((child: ReactElement) => {\n switch (child.type) {\n case MenuSearch:\n searchElem = child;\n break;\n case MenuItem:\n case MenuDivider:\n elements = elements.concat(child);\n break;\n default:\n break;\n }\n });\n return { items: elements, searchElement: searchElem };\n }\n\n return (childrenProps as ReactElement[]).reduce(\n (\n { items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n child\n ) => {\n switch (child.type) {\n case MenuSearch:\n return {\n items,\n searchElement: cloneElement(child, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n }),\n };\n case MenuItem:\n return {\n items: items.concat(\n child.props.disabled\n ? cloneElement(child, {\n onClick: () => undefined,\n onKeyDown: () => undefined,\n tabIndex: -1,\n disabled: true,\n })\n : cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n item: child.props.item ?? items.length,\n // set focus on the first menu item if there is no search input, and set in the tab order\n onClick: chainEventHandlers(child.props.onClick, () => {\n onSelect?.(child.props.item ?? items.length);\n }),\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n })\n ),\n searchElement,\n };\n case MenuDivider:\n return { items: items.concat(child), searchElement };\n default:\n return { items, searchElement };\n }\n },\n { items: [], searchElement: null }\n );\n }, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n if (enableVirtualization) {\n return (\n <MenuBase data-test-id={testId} isVirtual size={size}>\n <ItemVirtualizer<T>\n items={Children.toArray(reduceItems.items) as ReactElement[]}\n searchElement={reduceItems.searchElement}\n overscan={overscan}\n menuItemClassName={menuItemClassName}\n onSelect={onSelect}\n itemHeight={itemHeight}\n focusManager={focusManager}\n />\n </MenuBase>\n );\n }\n\n return (\n <MenuBase data-test-id={testId} size={size}>\n {reduceItems.searchElement}\n <MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n </MenuBase>\n );\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n items: ReactElement[] | null;\n searchElement?: ReactElement | null;\n focusManager: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n const {\n overscan,\n searchElement,\n itemHeight = 31.5,\n menuItemClassName,\n items: items,\n focusManager,\n onSelect,\n } = props;\n\n const menuId = useRef(`menu-ctrl-${useId()}`);\n\n const focusedItemIndex = useRef<number | null>(null);\n const parentRef = useRef<HTMLDivElement | null>(null);\n const searchRef = useRef<HTMLInputElement>();\n\n const [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n const hasSearch = !!searchElement;\n\n const lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n const rowVirtualizer = useVirtual({\n size: items !== null ? items.length : 0,\n parentRef,\n estimateSize: useCallback(() => itemHeight, [itemHeight]),\n overscan,\n });\n\n const focusSearchBar = useCallback(() => {\n rowVirtualizer.scrollToIndex(0);\n searchRef.current?.focus?.();\n }, [rowVirtualizer]);\n\n /**\n * Scrolls to the menu item with the index provided and\n * then manually focuses it using a side effect in useEffect\n */\n const focusMenuItem = useCallback(\n (index: number) => {\n rowVirtualizer.scrollToIndex(index);\n setNextFocusValue(index);\n },\n [rowVirtualizer]\n );\n\n const handleKeyboardFocusInteraction = useCallback(\n (direction: 'next' | 'previous') => {\n if (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n return;\n }\n const nextIndex =\n direction === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n const shouldWrap =\n (direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n (direction === 'previous' && focusedItemIndex.current === 0);\n if (shouldWrap) {\n // we are at the end of the list so we will\n // scroll back to the beginning of the list\n if (hasSearch) {\n focusSearchBar();\n } else {\n // if at end, wrap to beginning, else focus last item\n focusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n }\n return;\n }\n switch (direction) {\n case 'next':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusNext();\n break;\n case 'previous':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusPrevious();\n break;\n default:\n break;\n }\n },\n [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]\n );\n\n const getItemProps = useCallback(\n (itemElem: ReactElement, index: number) => {\n const childProps = itemElem.props as MenuItemProps<T>;\n switch (itemElem.type) {\n case MenuItem:\n return {\n className: cx(childProps.className, menuItemClassName),\n // set focus on the first menu item if there is no search input, and set in the tab order\n onKeyDown: childProps.disabled\n ? () => undefined\n : (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: handleKeyboardFocusInteraction,\n handleFocusForward: handleKeyboardFocusInteraction,\n }),\n onFocus: chainEventHandlers(childProps.onFocus, () => {\n focusedItemIndex.current = index;\n }),\n id: createItemId(index, menuId.current),\n onBlur: chainEventHandlers(childProps.onBlur, () => {\n focusedItemIndex.current = null;\n }),\n onClick: childProps.disabled\n ? () => undefined\n : chainEventHandlers(childProps.onClick, () => {\n onSelect?.(childProps.item as T);\n }),\n } as MenuItemProps<T>;\n default:\n return {};\n }\n },\n [handleKeyboardFocusInteraction, menuItemClassName, onSelect]\n );\n\n useEffect(() => {\n if (nextFocusValue !== null) {\n requestAnimationFrame(() => {\n const element = getNodeForIndex(nextFocusValue, menuId.current);\n element?.focus();\n });\n setNextFocusValue(null);\n }\n }, [nextFocusValue]);\n\n /**\n * Calls handleFocusForward when the user is attempting to focus forward using\n * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n */\n const handleKeyboardFocusKeydown = (\n e: KeyboardEvent,\n callbacks: Record<\n 'handleFocusForward' | 'handleFocusBackward',\n (direction: 'next' | 'previous') => void\n >\n ) => {\n const keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n if (keyOps.includes(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n if ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n callbacks.handleFocusBackward?.('previous');\n } else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n callbacks.handleFocusForward?.('next');\n }\n }\n };\n\n const renderSearch = useMemo(\n () =>\n searchElement\n ? cloneElement(searchElement, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n handleFocusForward: () => focusMenuItem(0),\n }),\n ref: searchRef,\n })\n : null,\n [searchElement, lastVirtualItemIndex, focusMenuItem]\n );\n\n const renderItems = useMemo(\n () =>\n rowVirtualizer.virtualItems.map((virtualRow) => {\n if (!items) {\n return null;\n }\n const elem = items[virtualRow.index];\n return (\n <div\n key={virtualRow.index}\n ref={virtualRow.measureRef}\n role=\"presentation\"\n className={cx('VirtualMenu-item')}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {cloneElement(elem, getItemProps(elem, virtualRow.index))}\n </div>\n );\n }),\n [rowVirtualizer.virtualItems, items, getItemProps]\n );\n\n return (\n <>\n {renderSearch}\n <MenuItemList ref={parentRef} role=\"presentation\">\n <div\n role=\"presentation\"\n className=\"VirtualMenu-item-list\"\n style={{\n height: `${rowVirtualizer.totalSize}px`,\n }}\n >\n {renderItems}\n </div>\n </MenuItemList>\n </>\n );\n};\n\nexport { Menu, ItemVirtualizer };\nexport type { MenuProps, ItemVirtualizerProps };\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":["import type { MenuProps } from './Menu';\nimport type { ComponentPropsWithRef } from 'react';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n isVirtual?: boolean;\n size?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n ({ children, size, isVirtual, ...props }, ref) => {\n const classes = cx('Menu', isVirtual && 'Menu--isVirtual', size && `MenuSize--${size}`);\n\n return (\n <div {...props} role=\"menu\" className={classes} ref={ref}>\n {children}\n </div>\n );\n }\n);\n\nMenuBase.displayName = 'MenuBase';\n\nexport { MenuBase };\nexport type { MenuBaseProps };\n","import type { SeparatorProps } from '@react-aria/separator';\nimport type { RefObject } from 'react';\n\nimport { useSeparator } from '@react-aria/separator';\n\nimport './styles/Menu.css';\n\ntype MenuDividerProps = SeparatorProps & {\n innerRef?: RefObject<HTMLDivElement>;\n 'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n elementType = 'div',\n orientation,\n innerRef,\n 'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n const { separatorProps } = useSeparator({\n orientation,\n elementType,\n });\n\n return <div {...separatorProps} data-test-id={testId} ref={innerRef} className=\"Menu-divider\" />;\n};\n\nexport { MenuDivider };\nexport type { MenuDividerProps };\n","import type { IconProps } from '@launchpad-ui/icons';\nimport type { PopoverPlacement } from '@launchpad-ui/popover';\nimport type { ComponentPropsWithRef, ElementType, PropsWithRef, ReactElement } from 'react';\n\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { Slot } from '@radix-ui/react-slot';\nimport { FocusRing } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport { cloneElement } from 'react';\n\nimport './styles/Menu.css';\n\n// Merge two types and get rid of overlapping definitions\ntype Merge<T, U> = Omit<T, keyof U> & U;\n\ntype PropsWithComponent<P, T extends ElementType> = P & { component?: T };\n\ntype PolymorphicPropsWithRef<P, T extends ElementType> = Merge<\n T extends keyof JSX.IntrinsicElements\n ? PropsWithRef<JSX.IntrinsicElements[T]>\n : ComponentPropsWithRef<T>,\n PropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n isHighlighted?: boolean;\n icon?: ReactElement<IconProps>;\n disabled?: boolean;\n nested?: boolean;\n groupHeader?: boolean;\n tooltip?: string | ReactElement;\n tooltipOptions?: typeof Tooltip;\n tooltipPlacement?: PopoverPlacement;\n asChild?: boolean;\n 'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n | (MenuItemOwnProps & {\n item: P; // Infer the type if it is included\n })\n | (MenuItemOwnProps & {\n item?: undefined;\n }),\n T\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n ...props\n}: MenuItemProps<P, T>) => {\n const {\n // TODO: remove component prop once we migrate over to asChild format\n component,\n children,\n isHighlighted,\n icon,\n nested,\n groupHeader,\n item,\n disabled,\n className,\n tooltip,\n role = 'menuitem',\n tooltipPlacement,\n onKeyDown,\n tooltipOptions,\n asChild,\n 'data-test-id': testId = 'menu-item',\n ...rest\n } = props;\n\n const Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n const renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n const renderedItem = (\n <FocusRing focusRingClass=\"has-focus\">\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n 'Menu-item',\n className,\n isHighlighted && 'is-highlighted',\n nested && 'Menu-item--nested',\n groupHeader && 'Menu-item--header'\n )}\n data-test-id={testId}\n role={role}\n onKeyDown={onKeyDown}\n >\n {asChild ? (\n children\n ) : (\n <>\n {icon && <span className=\"Menu-item-icon\">{renderIcon}</span>}\n {children}\n </>\n )}\n </Component>\n </FocusRing>\n );\n\n if (tooltip) {\n return (\n <Tooltip\n content={tooltip}\n rootElementStyle={{ display: 'block' }}\n allowBoundaryElementOverflow\n placement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n {...(tooltipOptions || {})}\n >\n {renderedItem}\n </Tooltip>\n );\n }\n\n return renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n <div {...rest} ref={ref} data-test-id=\"menu-item-list\" className=\"Menu-item-list\">\n {children}\n </div>\n));\n\nMenuItemList.displayName = 'MenuItemList';\n\nexport { MenuItemList };\nexport type { MenuItemListProps };\n","import type { ChangeEvent } from 'react';\n\nimport { TextField } from '@launchpad-ui/form';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuSearchProps = {\n ariaLabel?: string;\n value?: string;\n id?: string;\n placeholder?: string;\n onChange?(event: ChangeEvent<HTMLInputElement>): void;\n 'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n const {\n ariaLabel,\n placeholder,\n id,\n 'data-test-id': testId = 'menu-search',\n ...finalProps\n } = props;\n\n return (\n <div className=\"Menu-search\">\n <TextField\n {...finalProps}\n ref={ref}\n className=\"Menu-search-input\"\n tiny\n id={id}\n type=\"search\"\n data-test-id={testId}\n autoComplete=\"off\"\n placeholder={placeholder}\n aria-label={ariaLabel || 'Search'}\n />\n </div>\n );\n});\n\nMenuSearch.displayName = 'MenuSearch';\n\nexport { MenuSearch };\nexport type { MenuSearchProps };\n","import type { EventHandler, KeyboardEvent, SyntheticEvent } from 'react';\n\nconst createItemId = (index: number, id: string) => `${id}-item-${index}`;\n\nconst getNodeForIndex = (index: number | null, menuId: string) =>\n index === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n event: KeyboardEvent,\n keyHandlers: Partial<\n Record<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n >\n) => {\n const ops = {\n ArrowUp: keyHandlers.handleUp,\n ArrowDown: keyHandlers.handleDown,\n Enter: keyHandlers.handleEnter,\n } as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n if (ops[event.key]) {\n event.preventDefault();\n ops[event.key]?.call(globalThis, event);\n }\n};\n\nconst chainEventHandlers =\n (...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n (event: SyntheticEvent) => {\n handlers.forEach((h) => typeof h === 'function' && h(event));\n };\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { MenuItemProps } from './MenuItem';\nimport type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n Children,\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useVirtual } from 'react-virtual';\n\nimport { MenuBase } from './MenuBase';\nimport { MenuDivider } from './MenuDivider';\nimport { MenuItem } from './MenuItem';\nimport { MenuItemList } from './MenuItemList';\nimport { MenuSearch } from './MenuSearch';\nimport {\n chainEventHandlers,\n createItemId,\n getNodeForIndex,\n handleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n children: ReactNode;\n onSelect?: (item: T) => void;\n /**\n * Menus items are rendered using react-virtual for\n * additional rendering performance.\n */\n enableVirtualization?: boolean;\n /**\n * Class name to be applied to all MenuItem components\n * in the menu.\n */\n menuItemClassName?: string;\n /**\n * Sets the width of the menu. This is especially useful when using virtual items\n * since the width cannot be automatically set by the widest element.\n */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /**\n * Sets the number out of elements rendered outside of the view window\n * when using virtualization\n */\n overscan?: number;\n /**\n * Sets the height for each menu item when using virtualization.\n *\n */\n itemHeight?: number;\n 'data-test-id'?: string;\n};\n\ntype MenuProps<T extends number | string> = ControlledMenuProps<T>;\n\nconst Menu = <T extends number | string>(props: MenuProps<T>) => {\n const {\n children,\n menuItemClassName,\n onSelect,\n enableVirtualization,\n itemHeight,\n size,\n overscan = 1,\n 'data-test-id': testId = 'menu',\n } = props;\n\n const focusManager = useFocusManager();\n\n const handleArrowDown = useCallback(() => {\n focusManager.focusNext({ wrap: true });\n }, [focusManager]);\n\n const handleArrowUp = useCallback(() => {\n focusManager.focusPrevious({ wrap: true });\n }, [focusManager]);\n\n const reduceItems = useMemo(() => {\n const childrenProps = Children.toArray(children);\n if (enableVirtualization) {\n // the virtualized menu has its own handlers and props\n let searchElem = null;\n let elements: ReactElement[] = [];\n (childrenProps as ReactElement[]).forEach((child: ReactElement) => {\n switch (child.type) {\n case MenuSearch:\n searchElem = child;\n break;\n case MenuItem:\n case MenuDivider:\n elements = elements.concat(child);\n break;\n default:\n break;\n }\n });\n return { items: elements, searchElement: searchElem };\n }\n\n return (childrenProps as ReactElement[]).reduce(\n (\n { items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n child\n ) => {\n switch (child.type) {\n case MenuSearch:\n return {\n items,\n searchElement: cloneElement(child, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n }),\n };\n case MenuItem:\n return {\n items: items.concat(\n child.props.disabled\n ? cloneElement(child, {\n onClick: () => undefined,\n onKeyDown: () => undefined,\n tabIndex: -1,\n disabled: true,\n })\n : cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n item: child.props.item ?? items.length,\n // set focus on the first menu item if there is no search input, and set in the tab order\n onClick: chainEventHandlers(child.props.onClick, () => {\n onSelect?.(child.props.item ?? items.length);\n }),\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n })\n ),\n searchElement,\n };\n case MenuDivider:\n return { items: items.concat(child), searchElement };\n default:\n return { items, searchElement };\n }\n },\n { items: [], searchElement: null }\n );\n }, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n if (enableVirtualization) {\n return (\n <MenuBase data-test-id={testId} isVirtual size={size}>\n <ItemVirtualizer<T>\n items={Children.toArray(reduceItems.items) as ReactElement[]}\n searchElement={reduceItems.searchElement}\n overscan={overscan}\n menuItemClassName={menuItemClassName}\n onSelect={onSelect}\n itemHeight={itemHeight}\n focusManager={focusManager}\n />\n </MenuBase>\n );\n }\n\n return (\n <MenuBase data-test-id={testId} size={size}>\n {reduceItems.searchElement}\n <MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n </MenuBase>\n );\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n items: ReactElement[] | null;\n searchElement?: ReactElement | null;\n focusManager: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n const {\n overscan,\n searchElement,\n itemHeight = 31.5,\n menuItemClassName,\n items: items,\n focusManager,\n onSelect,\n } = props;\n\n const menuId = useRef(`menu-ctrl-${useId()}`);\n\n const focusedItemIndex = useRef<number | null>(null);\n const parentRef = useRef<HTMLDivElement | null>(null);\n const searchRef = useRef<HTMLInputElement>();\n\n const [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n const hasSearch = !!searchElement;\n\n const lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n const rowVirtualizer = useVirtual({\n size: items !== null ? items.length : 0,\n parentRef,\n estimateSize: useCallback(() => itemHeight, [itemHeight]),\n overscan,\n });\n\n const focusSearchBar = useCallback(() => {\n rowVirtualizer.scrollToIndex(0);\n searchRef.current?.focus?.();\n }, [rowVirtualizer]);\n\n /**\n * Scrolls to the menu item with the index provided and\n * then manually focuses it using a side effect in useEffect\n */\n const focusMenuItem = useCallback(\n (index: number) => {\n rowVirtualizer.scrollToIndex(index);\n setNextFocusValue(index);\n },\n [rowVirtualizer]\n );\n\n const handleKeyboardFocusInteraction = useCallback(\n (direction: 'next' | 'previous') => {\n if (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n return;\n }\n const nextIndex =\n direction === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n const shouldWrap =\n (direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n (direction === 'previous' && focusedItemIndex.current === 0);\n if (shouldWrap) {\n // we are at the end of the list so we will\n // scroll back to the beginning of the list\n if (hasSearch) {\n focusSearchBar();\n } else {\n // if at end, wrap to beginning, else focus last item\n focusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n }\n return;\n }\n switch (direction) {\n case 'next':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusNext();\n break;\n case 'previous':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusPrevious();\n break;\n default:\n break;\n }\n },\n [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]\n );\n\n const getItemProps = useCallback(\n (itemElem: ReactElement, index: number) => {\n const childProps = itemElem.props as MenuItemProps<T>;\n switch (itemElem.type) {\n case MenuItem:\n return {\n className: cx(childProps.className, menuItemClassName),\n // set focus on the first menu item if there is no search input, and set in the tab order\n onKeyDown: childProps.disabled\n ? () => undefined\n : (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: handleKeyboardFocusInteraction,\n handleFocusForward: handleKeyboardFocusInteraction,\n }),\n onFocus: chainEventHandlers(childProps.onFocus, () => {\n focusedItemIndex.current = index;\n }),\n id: createItemId(index, menuId.current),\n onBlur: chainEventHandlers(childProps.onBlur, () => {\n focusedItemIndex.current = null;\n }),\n onClick: childProps.disabled\n ? () => undefined\n : chainEventHandlers(childProps.onClick, () => {\n onSelect?.(childProps.item as T);\n }),\n } as MenuItemProps<T>;\n default:\n return {};\n }\n },\n [handleKeyboardFocusInteraction, menuItemClassName, onSelect]\n );\n\n useEffect(() => {\n if (nextFocusValue !== null) {\n requestAnimationFrame(() => {\n const element = getNodeForIndex(nextFocusValue, menuId.current);\n element?.focus();\n });\n setNextFocusValue(null);\n }\n }, [nextFocusValue]);\n\n /**\n * Calls handleFocusForward when the user is attempting to focus forward using\n * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n */\n const handleKeyboardFocusKeydown = (\n e: KeyboardEvent,\n callbacks: Record<\n 'handleFocusForward' | 'handleFocusBackward',\n (direction: 'next' | 'previous') => void\n >\n ) => {\n const keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n if (keyOps.includes(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n if ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n callbacks.handleFocusBackward?.('previous');\n } else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n callbacks.handleFocusForward?.('next');\n }\n }\n };\n\n const renderSearch = useMemo(\n () =>\n searchElement\n ? cloneElement(searchElement, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n handleFocusForward: () => focusMenuItem(0),\n }),\n ref: searchRef,\n })\n : null,\n [searchElement, lastVirtualItemIndex, focusMenuItem]\n );\n\n const renderItems = useMemo(\n () =>\n rowVirtualizer.virtualItems.map((virtualRow) => {\n if (!items) {\n return null;\n }\n const elem = items[virtualRow.index];\n return (\n <div\n key={virtualRow.index}\n ref={virtualRow.measureRef}\n role=\"presentation\"\n className={cx('VirtualMenu-item')}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {cloneElement(elem, getItemProps(elem, virtualRow.index))}\n </div>\n );\n }),\n [rowVirtualizer.virtualItems, items, getItemProps]\n );\n\n return (\n <>\n {renderSearch}\n <MenuItemList ref={parentRef} role=\"presentation\">\n <div\n role=\"presentation\"\n className=\"VirtualMenu-item-list\"\n style={{\n height: `${rowVirtualizer.totalSize}px`,\n }}\n >\n {renderItems}\n </div>\n </MenuItemList>\n </>\n );\n};\n\nexport { Menu, ItemVirtualizer };\nexport type { MenuProps, ItemVirtualizerProps };\n"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ const focus = require("@react-aria/focus");
11
11
  const form = require("@launchpad-ui/form");
12
12
  const reactVirtual = require("react-virtual");
13
13
  const Menu$1 = "";
14
- const MenuBase = react.forwardRef(
14
+ const MenuBase = /* @__PURE__ */ react.forwardRef(
15
15
  ({ children, size, isVirtual, ...props }, ref) => {
16
16
  const classes = classix.cx("Menu", isVirtual && "Menu--isVirtual", size && `MenuSize--${size}`);
17
17
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ...props, role: "menu", className: classes, ref, children });
@@ -55,7 +55,7 @@ const MenuItem = ({
55
55
  ...rest
56
56
  } = props;
57
57
  const Component = component || (asChild ? reactSlot.Slot : defaultElement);
58
- const renderIcon = icon && react.cloneElement(icon, { size: "small" });
58
+ const renderIcon = icon && /* @__PURE__ */ react.cloneElement(icon, { size: "small" });
59
59
  const renderedItem = /* @__PURE__ */ jsxRuntime.jsx(focus.FocusRing, { focusRingClass: "has-focus", children: /* @__PURE__ */ jsxRuntime.jsx(
60
60
  Component,
61
61
  {
@@ -93,9 +93,9 @@ const MenuItem = ({
93
93
  }
94
94
  return renderedItem;
95
95
  };
96
- const MenuItemList = react.forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ...rest, ref, "data-test-id": "menu-item-list", className: "Menu-item-list", children }));
96
+ const MenuItemList = /* @__PURE__ */ react.forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ...rest, ref, "data-test-id": "menu-item-list", className: "Menu-item-list", children }));
97
97
  MenuItemList.displayName = "MenuItemList";
98
- const MenuSearch = react.forwardRef((props, ref) => {
98
+ const MenuSearch = /* @__PURE__ */ react.forwardRef((props, ref) => {
99
99
  const {
100
100
  ariaLabel,
101
101
  placeholder,
@@ -179,7 +179,7 @@ const Menu = (props) => {
179
179
  case MenuSearch:
180
180
  return {
181
181
  items,
182
- searchElement: react.cloneElement(child, {
182
+ searchElement: /* @__PURE__ */ react.cloneElement(child, {
183
183
  onKeyDown: (e) => handleKeyboardInteractions(e, {
184
184
  handleDown: handleArrowDown,
185
185
  handleUp: handleArrowUp
@@ -189,12 +189,12 @@ const Menu = (props) => {
189
189
  case MenuItem:
190
190
  return {
191
191
  items: items.concat(
192
- child.props.disabled ? react.cloneElement(child, {
192
+ child.props.disabled ? /* @__PURE__ */ react.cloneElement(child, {
193
193
  onClick: () => void 0,
194
194
  onKeyDown: () => void 0,
195
195
  tabIndex: -1,
196
196
  disabled: true
197
- }) : react.cloneElement(child, {
197
+ }) : /* @__PURE__ */ react.cloneElement(child, {
198
198
  className: classix.cx(child.props.className, menuItemClassName),
199
199
  item: child.props.item ?? items.length,
200
200
  // set focus on the first menu item if there is no search input, and set in the tab order
@@ -352,7 +352,7 @@ const ItemVirtualizer = (props) => {
352
352
  }
353
353
  };
354
354
  const renderSearch = react.useMemo(
355
- () => searchElement ? react.cloneElement(searchElement, {
355
+ () => searchElement ? /* @__PURE__ */ react.cloneElement(searchElement, {
356
356
  onKeyDown: (e) => handleKeyboardFocusKeydown(e, {
357
357
  handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),
358
358
  handleFocusForward: () => focusMenuItem(0)
@@ -376,7 +376,7 @@ const ItemVirtualizer = (props) => {
376
376
  style: {
377
377
  transform: `translateY(${virtualRow.start}px)`
378
378
  },
379
- children: react.cloneElement(elem, getItemProps(elem, virtualRow.index))
379
+ children: /* @__PURE__ */ react.cloneElement(elem, getItemProps(elem, virtualRow.index))
380
380
  },
381
381
  virtualRow.index
382
382
  );
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":["import type { MenuProps } from './Menu';\nimport type { ComponentPropsWithRef } from 'react';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n isVirtual?: boolean;\n size?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n ({ children, size, isVirtual, ...props }, ref) => {\n const classes = cx('Menu', isVirtual && 'Menu--isVirtual', size && `MenuSize--${size}`);\n\n return (\n <div {...props} role=\"menu\" className={classes} ref={ref}>\n {children}\n </div>\n );\n }\n);\n\nMenuBase.displayName = 'MenuBase';\n\nexport { MenuBase };\nexport type { MenuBaseProps };\n","import type { SeparatorProps } from '@react-aria/separator';\nimport type { RefObject } from 'react';\n\nimport { useSeparator } from '@react-aria/separator';\n\nimport './styles/Menu.css';\n\ntype MenuDividerProps = SeparatorProps & {\n innerRef?: RefObject<HTMLDivElement>;\n 'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n elementType = 'div',\n orientation,\n innerRef,\n 'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n const { separatorProps } = useSeparator({\n orientation,\n elementType,\n });\n\n return <div {...separatorProps} data-test-id={testId} ref={innerRef} className=\"Menu-divider\" />;\n};\n\nexport { MenuDivider };\nexport type { MenuDividerProps };\n","import type { IconProps } from '@launchpad-ui/icons';\nimport type { PopoverPlacement } from '@launchpad-ui/popover';\nimport type { ComponentPropsWithRef, ElementType, PropsWithRef, ReactElement } from 'react';\n\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { Slot } from '@radix-ui/react-slot';\nimport { FocusRing } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport { cloneElement } from 'react';\n\nimport './styles/Menu.css';\n\n// Merge two types and get rid of overlapping definitions\ntype Merge<T, U> = Omit<T, keyof U> & U;\n\ntype PropsWithComponent<P, T extends ElementType> = P & { component?: T };\n\ntype PolymorphicPropsWithRef<P, T extends ElementType> = Merge<\n T extends keyof JSX.IntrinsicElements\n ? PropsWithRef<JSX.IntrinsicElements[T]>\n : ComponentPropsWithRef<T>,\n PropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n isHighlighted?: boolean;\n icon?: ReactElement<IconProps>;\n disabled?: boolean;\n nested?: boolean;\n groupHeader?: boolean;\n tooltip?: string | ReactElement;\n tooltipOptions?: typeof Tooltip;\n tooltipPlacement?: PopoverPlacement;\n asChild?: boolean;\n 'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n | (MenuItemOwnProps & {\n item: P; // Infer the type if it is included\n })\n | (MenuItemOwnProps & {\n item?: undefined;\n }),\n T\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n ...props\n}: MenuItemProps<P, T>) => {\n const {\n // TODO: remove component prop once we migrate over to asChild format\n component,\n children,\n isHighlighted,\n icon,\n nested,\n groupHeader,\n item,\n disabled,\n className,\n tooltip,\n role = 'menuitem',\n tooltipPlacement,\n onKeyDown,\n tooltipOptions,\n asChild,\n 'data-test-id': testId = 'menu-item',\n ...rest\n } = props;\n\n const Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n const renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n const renderedItem = (\n <FocusRing focusRingClass=\"has-focus\">\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n 'Menu-item',\n className,\n isHighlighted && 'is-highlighted',\n nested && 'Menu-item--nested',\n groupHeader && 'Menu-item--header'\n )}\n data-test-id={testId}\n role={role}\n onKeyDown={onKeyDown}\n >\n {asChild ? (\n children\n ) : (\n <>\n {icon && <span className=\"Menu-item-icon\">{renderIcon}</span>}\n {children}\n </>\n )}\n </Component>\n </FocusRing>\n );\n\n if (tooltip) {\n return (\n <Tooltip\n content={tooltip}\n rootElementStyle={{ display: 'block' }}\n allowBoundaryElementOverflow\n placement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n {...(tooltipOptions || {})}\n >\n {renderedItem}\n </Tooltip>\n );\n }\n\n return renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n <div {...rest} ref={ref} data-test-id=\"menu-item-list\" className=\"Menu-item-list\">\n {children}\n </div>\n));\n\nMenuItemList.displayName = 'MenuItemList';\n\nexport { MenuItemList };\nexport type { MenuItemListProps };\n","import type { ChangeEvent } from 'react';\n\nimport { TextField } from '@launchpad-ui/form';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuSearchProps = {\n ariaLabel?: string;\n value?: string;\n id?: string;\n placeholder?: string;\n onChange?(event: ChangeEvent<HTMLInputElement>): void;\n 'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n const {\n ariaLabel,\n placeholder,\n id,\n 'data-test-id': testId = 'menu-search',\n ...finalProps\n } = props;\n\n return (\n <div className=\"Menu-search\">\n <TextField\n {...finalProps}\n ref={ref}\n className=\"Menu-search-input\"\n tiny\n id={id}\n type=\"search\"\n data-test-id={testId}\n autoComplete=\"off\"\n placeholder={placeholder}\n aria-label={ariaLabel || 'Search'}\n />\n </div>\n );\n});\n\nMenuSearch.displayName = 'MenuSearch';\n\nexport { MenuSearch };\nexport type { MenuSearchProps };\n","import type { EventHandler, KeyboardEvent, SyntheticEvent } from 'react';\n\nconst createItemId = (index: number, id: string) => `${id}-item-${index}`;\n\nconst getNodeForIndex = (index: number | null, menuId: string) =>\n index === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n event: KeyboardEvent,\n keyHandlers: Partial<\n Record<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n >\n) => {\n const ops = {\n ArrowUp: keyHandlers.handleUp,\n ArrowDown: keyHandlers.handleDown,\n Enter: keyHandlers.handleEnter,\n } as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n if (ops[event.key]) {\n event.preventDefault();\n ops[event.key]?.call(globalThis, event);\n }\n};\n\nconst chainEventHandlers =\n (...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n (event: SyntheticEvent) => {\n handlers.forEach((h) => typeof h === 'function' && h(event));\n };\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { MenuItemProps } from './MenuItem';\nimport type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n Children,\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useVirtual } from 'react-virtual';\n\nimport { MenuBase } from './MenuBase';\nimport { MenuDivider } from './MenuDivider';\nimport { MenuItem } from './MenuItem';\nimport { MenuItemList } from './MenuItemList';\nimport { MenuSearch } from './MenuSearch';\nimport {\n chainEventHandlers,\n createItemId,\n getNodeForIndex,\n handleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n children: ReactNode;\n onSelect?: (item: T) => void;\n /**\n * Menus items are rendered using react-virtual for\n * additional rendering performance.\n */\n enableVirtualization?: boolean;\n /**\n * Class name to be applied to all MenuItem components\n * in the menu.\n */\n menuItemClassName?: string;\n /**\n * Sets the width of the menu. This is especially useful when using virtual items\n * since the width cannot be automatically set by the widest element.\n */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /**\n * Sets the number out of elements rendered outside of the view window\n * when using virtualization\n */\n overscan?: number;\n /**\n * Sets the height for each menu item when using virtualization.\n *\n */\n itemHeight?: number;\n 'data-test-id'?: string;\n};\n\ntype MenuProps<T extends number | string> = ControlledMenuProps<T>;\n\nconst Menu = <T extends number | string>(props: MenuProps<T>) => {\n const {\n children,\n menuItemClassName,\n onSelect,\n enableVirtualization,\n itemHeight,\n size,\n overscan = 1,\n 'data-test-id': testId = 'menu',\n } = props;\n\n const focusManager = useFocusManager();\n\n const handleArrowDown = useCallback(() => {\n focusManager.focusNext({ wrap: true });\n }, [focusManager]);\n\n const handleArrowUp = useCallback(() => {\n focusManager.focusPrevious({ wrap: true });\n }, [focusManager]);\n\n const reduceItems = useMemo(() => {\n const childrenProps = Children.toArray(children);\n if (enableVirtualization) {\n // the virtualized menu has its own handlers and props\n let searchElem = null;\n let elements: ReactElement[] = [];\n (childrenProps as ReactElement[]).forEach((child: ReactElement) => {\n switch (child.type) {\n case MenuSearch:\n searchElem = child;\n break;\n case MenuItem:\n case MenuDivider:\n elements = elements.concat(child);\n break;\n default:\n break;\n }\n });\n return { items: elements, searchElement: searchElem };\n }\n\n return (childrenProps as ReactElement[]).reduce(\n (\n { items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n child\n ) => {\n switch (child.type) {\n case MenuSearch:\n return {\n items,\n searchElement: cloneElement(child, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n }),\n };\n case MenuItem:\n return {\n items: items.concat(\n child.props.disabled\n ? cloneElement(child, {\n onClick: () => undefined,\n onKeyDown: () => undefined,\n tabIndex: -1,\n disabled: true,\n })\n : cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n item: child.props.item ?? items.length,\n // set focus on the first menu item if there is no search input, and set in the tab order\n onClick: chainEventHandlers(child.props.onClick, () => {\n onSelect?.(child.props.item ?? items.length);\n }),\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n })\n ),\n searchElement,\n };\n case MenuDivider:\n return { items: items.concat(child), searchElement };\n default:\n return { items, searchElement };\n }\n },\n { items: [], searchElement: null }\n );\n }, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n if (enableVirtualization) {\n return (\n <MenuBase data-test-id={testId} isVirtual size={size}>\n <ItemVirtualizer<T>\n items={Children.toArray(reduceItems.items) as ReactElement[]}\n searchElement={reduceItems.searchElement}\n overscan={overscan}\n menuItemClassName={menuItemClassName}\n onSelect={onSelect}\n itemHeight={itemHeight}\n focusManager={focusManager}\n />\n </MenuBase>\n );\n }\n\n return (\n <MenuBase data-test-id={testId} size={size}>\n {reduceItems.searchElement}\n <MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n </MenuBase>\n );\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n items: ReactElement[] | null;\n searchElement?: ReactElement | null;\n focusManager: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n const {\n overscan,\n searchElement,\n itemHeight = 31.5,\n menuItemClassName,\n items: items,\n focusManager,\n onSelect,\n } = props;\n\n const menuId = useRef(`menu-ctrl-${useId()}`);\n\n const focusedItemIndex = useRef<number | null>(null);\n const parentRef = useRef<HTMLDivElement | null>(null);\n const searchRef = useRef<HTMLInputElement>();\n\n const [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n const hasSearch = !!searchElement;\n\n const lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n const rowVirtualizer = useVirtual({\n size: items !== null ? items.length : 0,\n parentRef,\n estimateSize: useCallback(() => itemHeight, [itemHeight]),\n overscan,\n });\n\n const focusSearchBar = useCallback(() => {\n rowVirtualizer.scrollToIndex(0);\n searchRef.current?.focus?.();\n }, [rowVirtualizer]);\n\n /**\n * Scrolls to the menu item with the index provided and\n * then manually focuses it using a side effect in useEffect\n */\n const focusMenuItem = useCallback(\n (index: number) => {\n rowVirtualizer.scrollToIndex(index);\n setNextFocusValue(index);\n },\n [rowVirtualizer]\n );\n\n const handleKeyboardFocusInteraction = useCallback(\n (direction: 'next' | 'previous') => {\n if (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n return;\n }\n const nextIndex =\n direction === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n const shouldWrap =\n (direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n (direction === 'previous' && focusedItemIndex.current === 0);\n if (shouldWrap) {\n // we are at the end of the list so we will\n // scroll back to the beginning of the list\n if (hasSearch) {\n focusSearchBar();\n } else {\n // if at end, wrap to beginning, else focus last item\n focusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n }\n return;\n }\n switch (direction) {\n case 'next':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusNext();\n break;\n case 'previous':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusPrevious();\n break;\n default:\n break;\n }\n },\n [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]\n );\n\n const getItemProps = useCallback(\n (itemElem: ReactElement, index: number) => {\n const childProps = itemElem.props as MenuItemProps<T>;\n switch (itemElem.type) {\n case MenuItem:\n return {\n className: cx(childProps.className, menuItemClassName),\n // set focus on the first menu item if there is no search input, and set in the tab order\n onKeyDown: childProps.disabled\n ? () => undefined\n : (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: handleKeyboardFocusInteraction,\n handleFocusForward: handleKeyboardFocusInteraction,\n }),\n onFocus: chainEventHandlers(childProps.onFocus, () => {\n focusedItemIndex.current = index;\n }),\n id: createItemId(index, menuId.current),\n onBlur: chainEventHandlers(childProps.onBlur, () => {\n focusedItemIndex.current = null;\n }),\n onClick: childProps.disabled\n ? () => undefined\n : chainEventHandlers(childProps.onClick, () => {\n onSelect?.(childProps.item as T);\n }),\n } as MenuItemProps<T>;\n default:\n return {};\n }\n },\n [handleKeyboardFocusInteraction, menuItemClassName, onSelect]\n );\n\n useEffect(() => {\n if (nextFocusValue !== null) {\n requestAnimationFrame(() => {\n const element = getNodeForIndex(nextFocusValue, menuId.current);\n element?.focus();\n });\n setNextFocusValue(null);\n }\n }, [nextFocusValue]);\n\n /**\n * Calls handleFocusForward when the user is attempting to focus forward using\n * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n */\n const handleKeyboardFocusKeydown = (\n e: KeyboardEvent,\n callbacks: Record<\n 'handleFocusForward' | 'handleFocusBackward',\n (direction: 'next' | 'previous') => void\n >\n ) => {\n const keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n if (keyOps.includes(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n if ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n callbacks.handleFocusBackward?.('previous');\n } else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n callbacks.handleFocusForward?.('next');\n }\n }\n };\n\n const renderSearch = useMemo(\n () =>\n searchElement\n ? cloneElement(searchElement, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n handleFocusForward: () => focusMenuItem(0),\n }),\n ref: searchRef,\n })\n : null,\n [searchElement, lastVirtualItemIndex, focusMenuItem]\n );\n\n const renderItems = useMemo(\n () =>\n rowVirtualizer.virtualItems.map((virtualRow) => {\n if (!items) {\n return null;\n }\n const elem = items[virtualRow.index];\n return (\n <div\n key={virtualRow.index}\n ref={virtualRow.measureRef}\n role=\"presentation\"\n className={cx('VirtualMenu-item')}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {cloneElement(elem, getItemProps(elem, virtualRow.index))}\n </div>\n );\n }),\n [rowVirtualizer.virtualItems, items, getItemProps]\n );\n\n return (\n <>\n {renderSearch}\n <MenuItemList ref={parentRef} role=\"presentation\">\n <div\n role=\"presentation\"\n className=\"VirtualMenu-item-list\"\n style={{\n height: `${rowVirtualizer.totalSize}px`,\n }}\n >\n {renderItems}\n </div>\n </MenuItemList>\n </>\n );\n};\n\nexport { Menu, ItemVirtualizer };\nexport type { MenuProps, ItemVirtualizerProps };\n"],"names":["forwardRef","cx","jsx","useSeparator","tooltip","Slot","cloneElement","FocusRing","jsxs","Fragment","Tooltip","TextField","useFocusManager","useCallback","useMemo","Children","useRef","useId","useState","useVirtual","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":["import type { MenuProps } from './Menu';\nimport type { ComponentPropsWithRef } from 'react';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n isVirtual?: boolean;\n size?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n ({ children, size, isVirtual, ...props }, ref) => {\n const classes = cx('Menu', isVirtual && 'Menu--isVirtual', size && `MenuSize--${size}`);\n\n return (\n <div {...props} role=\"menu\" className={classes} ref={ref}>\n {children}\n </div>\n );\n }\n);\n\nMenuBase.displayName = 'MenuBase';\n\nexport { MenuBase };\nexport type { MenuBaseProps };\n","import type { SeparatorProps } from '@react-aria/separator';\nimport type { RefObject } from 'react';\n\nimport { useSeparator } from '@react-aria/separator';\n\nimport './styles/Menu.css';\n\ntype MenuDividerProps = SeparatorProps & {\n innerRef?: RefObject<HTMLDivElement>;\n 'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n elementType = 'div',\n orientation,\n innerRef,\n 'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n const { separatorProps } = useSeparator({\n orientation,\n elementType,\n });\n\n return <div {...separatorProps} data-test-id={testId} ref={innerRef} className=\"Menu-divider\" />;\n};\n\nexport { MenuDivider };\nexport type { MenuDividerProps };\n","import type { IconProps } from '@launchpad-ui/icons';\nimport type { PopoverPlacement } from '@launchpad-ui/popover';\nimport type { ComponentPropsWithRef, ElementType, PropsWithRef, ReactElement } from 'react';\n\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { Slot } from '@radix-ui/react-slot';\nimport { FocusRing } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport { cloneElement } from 'react';\n\nimport './styles/Menu.css';\n\n// Merge two types and get rid of overlapping definitions\ntype Merge<T, U> = Omit<T, keyof U> & U;\n\ntype PropsWithComponent<P, T extends ElementType> = P & { component?: T };\n\ntype PolymorphicPropsWithRef<P, T extends ElementType> = Merge<\n T extends keyof JSX.IntrinsicElements\n ? PropsWithRef<JSX.IntrinsicElements[T]>\n : ComponentPropsWithRef<T>,\n PropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n isHighlighted?: boolean;\n icon?: ReactElement<IconProps>;\n disabled?: boolean;\n nested?: boolean;\n groupHeader?: boolean;\n tooltip?: string | ReactElement;\n tooltipOptions?: typeof Tooltip;\n tooltipPlacement?: PopoverPlacement;\n asChild?: boolean;\n 'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n | (MenuItemOwnProps & {\n item: P; // Infer the type if it is included\n })\n | (MenuItemOwnProps & {\n item?: undefined;\n }),\n T\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n ...props\n}: MenuItemProps<P, T>) => {\n const {\n // TODO: remove component prop once we migrate over to asChild format\n component,\n children,\n isHighlighted,\n icon,\n nested,\n groupHeader,\n item,\n disabled,\n className,\n tooltip,\n role = 'menuitem',\n tooltipPlacement,\n onKeyDown,\n tooltipOptions,\n asChild,\n 'data-test-id': testId = 'menu-item',\n ...rest\n } = props;\n\n const Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n const renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n const renderedItem = (\n <FocusRing focusRingClass=\"has-focus\">\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n 'Menu-item',\n className,\n isHighlighted && 'is-highlighted',\n nested && 'Menu-item--nested',\n groupHeader && 'Menu-item--header'\n )}\n data-test-id={testId}\n role={role}\n onKeyDown={onKeyDown}\n >\n {asChild ? (\n children\n ) : (\n <>\n {icon && <span className=\"Menu-item-icon\">{renderIcon}</span>}\n {children}\n </>\n )}\n </Component>\n </FocusRing>\n );\n\n if (tooltip) {\n return (\n <Tooltip\n content={tooltip}\n rootElementStyle={{ display: 'block' }}\n allowBoundaryElementOverflow\n placement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n {...(tooltipOptions || {})}\n >\n {renderedItem}\n </Tooltip>\n );\n }\n\n return renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n <div {...rest} ref={ref} data-test-id=\"menu-item-list\" className=\"Menu-item-list\">\n {children}\n </div>\n));\n\nMenuItemList.displayName = 'MenuItemList';\n\nexport { MenuItemList };\nexport type { MenuItemListProps };\n","import type { ChangeEvent } from 'react';\n\nimport { TextField } from '@launchpad-ui/form';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuSearchProps = {\n ariaLabel?: string;\n value?: string;\n id?: string;\n placeholder?: string;\n onChange?(event: ChangeEvent<HTMLInputElement>): void;\n 'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n const {\n ariaLabel,\n placeholder,\n id,\n 'data-test-id': testId = 'menu-search',\n ...finalProps\n } = props;\n\n return (\n <div className=\"Menu-search\">\n <TextField\n {...finalProps}\n ref={ref}\n className=\"Menu-search-input\"\n tiny\n id={id}\n type=\"search\"\n data-test-id={testId}\n autoComplete=\"off\"\n placeholder={placeholder}\n aria-label={ariaLabel || 'Search'}\n />\n </div>\n );\n});\n\nMenuSearch.displayName = 'MenuSearch';\n\nexport { MenuSearch };\nexport type { MenuSearchProps };\n","import type { EventHandler, KeyboardEvent, SyntheticEvent } from 'react';\n\nconst createItemId = (index: number, id: string) => `${id}-item-${index}`;\n\nconst getNodeForIndex = (index: number | null, menuId: string) =>\n index === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n event: KeyboardEvent,\n keyHandlers: Partial<\n Record<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n >\n) => {\n const ops = {\n ArrowUp: keyHandlers.handleUp,\n ArrowDown: keyHandlers.handleDown,\n Enter: keyHandlers.handleEnter,\n } as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n if (ops[event.key]) {\n event.preventDefault();\n ops[event.key]?.call(globalThis, event);\n }\n};\n\nconst chainEventHandlers =\n (...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n (event: SyntheticEvent) => {\n handlers.forEach((h) => typeof h === 'function' && h(event));\n };\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { MenuItemProps } from './MenuItem';\nimport type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n Children,\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useVirtual } from 'react-virtual';\n\nimport { MenuBase } from './MenuBase';\nimport { MenuDivider } from './MenuDivider';\nimport { MenuItem } from './MenuItem';\nimport { MenuItemList } from './MenuItemList';\nimport { MenuSearch } from './MenuSearch';\nimport {\n chainEventHandlers,\n createItemId,\n getNodeForIndex,\n handleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n children: ReactNode;\n onSelect?: (item: T) => void;\n /**\n * Menus items are rendered using react-virtual for\n * additional rendering performance.\n */\n enableVirtualization?: boolean;\n /**\n * Class name to be applied to all MenuItem components\n * in the menu.\n */\n menuItemClassName?: string;\n /**\n * Sets the width of the menu. This is especially useful when using virtual items\n * since the width cannot be automatically set by the widest element.\n */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /**\n * Sets the number out of elements rendered outside of the view window\n * when using virtualization\n */\n overscan?: number;\n /**\n * Sets the height for each menu item when using virtualization.\n *\n */\n itemHeight?: number;\n 'data-test-id'?: string;\n};\n\ntype MenuProps<T extends number | string> = ControlledMenuProps<T>;\n\nconst Menu = <T extends number | string>(props: MenuProps<T>) => {\n const {\n children,\n menuItemClassName,\n onSelect,\n enableVirtualization,\n itemHeight,\n size,\n overscan = 1,\n 'data-test-id': testId = 'menu',\n } = props;\n\n const focusManager = useFocusManager();\n\n const handleArrowDown = useCallback(() => {\n focusManager.focusNext({ wrap: true });\n }, [focusManager]);\n\n const handleArrowUp = useCallback(() => {\n focusManager.focusPrevious({ wrap: true });\n }, [focusManager]);\n\n const reduceItems = useMemo(() => {\n const childrenProps = Children.toArray(children);\n if (enableVirtualization) {\n // the virtualized menu has its own handlers and props\n let searchElem = null;\n let elements: ReactElement[] = [];\n (childrenProps as ReactElement[]).forEach((child: ReactElement) => {\n switch (child.type) {\n case MenuSearch:\n searchElem = child;\n break;\n case MenuItem:\n case MenuDivider:\n elements = elements.concat(child);\n break;\n default:\n break;\n }\n });\n return { items: elements, searchElement: searchElem };\n }\n\n return (childrenProps as ReactElement[]).reduce(\n (\n { items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n child\n ) => {\n switch (child.type) {\n case MenuSearch:\n return {\n items,\n searchElement: cloneElement(child, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n }),\n };\n case MenuItem:\n return {\n items: items.concat(\n child.props.disabled\n ? cloneElement(child, {\n onClick: () => undefined,\n onKeyDown: () => undefined,\n tabIndex: -1,\n disabled: true,\n })\n : cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n item: child.props.item ?? items.length,\n // set focus on the first menu item if there is no search input, and set in the tab order\n onClick: chainEventHandlers(child.props.onClick, () => {\n onSelect?.(child.props.item ?? items.length);\n }),\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n })\n ),\n searchElement,\n };\n case MenuDivider:\n return { items: items.concat(child), searchElement };\n default:\n return { items, searchElement };\n }\n },\n { items: [], searchElement: null }\n );\n }, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n if (enableVirtualization) {\n return (\n <MenuBase data-test-id={testId} isVirtual size={size}>\n <ItemVirtualizer<T>\n items={Children.toArray(reduceItems.items) as ReactElement[]}\n searchElement={reduceItems.searchElement}\n overscan={overscan}\n menuItemClassName={menuItemClassName}\n onSelect={onSelect}\n itemHeight={itemHeight}\n focusManager={focusManager}\n />\n </MenuBase>\n );\n }\n\n return (\n <MenuBase data-test-id={testId} size={size}>\n {reduceItems.searchElement}\n <MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n </MenuBase>\n );\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n items: ReactElement[] | null;\n searchElement?: ReactElement | null;\n focusManager: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n const {\n overscan,\n searchElement,\n itemHeight = 31.5,\n menuItemClassName,\n items: items,\n focusManager,\n onSelect,\n } = props;\n\n const menuId = useRef(`menu-ctrl-${useId()}`);\n\n const focusedItemIndex = useRef<number | null>(null);\n const parentRef = useRef<HTMLDivElement | null>(null);\n const searchRef = useRef<HTMLInputElement>();\n\n const [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n const hasSearch = !!searchElement;\n\n const lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n const rowVirtualizer = useVirtual({\n size: items !== null ? items.length : 0,\n parentRef,\n estimateSize: useCallback(() => itemHeight, [itemHeight]),\n overscan,\n });\n\n const focusSearchBar = useCallback(() => {\n rowVirtualizer.scrollToIndex(0);\n searchRef.current?.focus?.();\n }, [rowVirtualizer]);\n\n /**\n * Scrolls to the menu item with the index provided and\n * then manually focuses it using a side effect in useEffect\n */\n const focusMenuItem = useCallback(\n (index: number) => {\n rowVirtualizer.scrollToIndex(index);\n setNextFocusValue(index);\n },\n [rowVirtualizer]\n );\n\n const handleKeyboardFocusInteraction = useCallback(\n (direction: 'next' | 'previous') => {\n if (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n return;\n }\n const nextIndex =\n direction === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n const shouldWrap =\n (direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n (direction === 'previous' && focusedItemIndex.current === 0);\n if (shouldWrap) {\n // we are at the end of the list so we will\n // scroll back to the beginning of the list\n if (hasSearch) {\n focusSearchBar();\n } else {\n // if at end, wrap to beginning, else focus last item\n focusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n }\n return;\n }\n switch (direction) {\n case 'next':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusNext();\n break;\n case 'previous':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusPrevious();\n break;\n default:\n break;\n }\n },\n [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]\n );\n\n const getItemProps = useCallback(\n (itemElem: ReactElement, index: number) => {\n const childProps = itemElem.props as MenuItemProps<T>;\n switch (itemElem.type) {\n case MenuItem:\n return {\n className: cx(childProps.className, menuItemClassName),\n // set focus on the first menu item if there is no search input, and set in the tab order\n onKeyDown: childProps.disabled\n ? () => undefined\n : (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: handleKeyboardFocusInteraction,\n handleFocusForward: handleKeyboardFocusInteraction,\n }),\n onFocus: chainEventHandlers(childProps.onFocus, () => {\n focusedItemIndex.current = index;\n }),\n id: createItemId(index, menuId.current),\n onBlur: chainEventHandlers(childProps.onBlur, () => {\n focusedItemIndex.current = null;\n }),\n onClick: childProps.disabled\n ? () => undefined\n : chainEventHandlers(childProps.onClick, () => {\n onSelect?.(childProps.item as T);\n }),\n } as MenuItemProps<T>;\n default:\n return {};\n }\n },\n [handleKeyboardFocusInteraction, menuItemClassName, onSelect]\n );\n\n useEffect(() => {\n if (nextFocusValue !== null) {\n requestAnimationFrame(() => {\n const element = getNodeForIndex(nextFocusValue, menuId.current);\n element?.focus();\n });\n setNextFocusValue(null);\n }\n }, [nextFocusValue]);\n\n /**\n * Calls handleFocusForward when the user is attempting to focus forward using\n * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n */\n const handleKeyboardFocusKeydown = (\n e: KeyboardEvent,\n callbacks: Record<\n 'handleFocusForward' | 'handleFocusBackward',\n (direction: 'next' | 'previous') => void\n >\n ) => {\n const keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n if (keyOps.includes(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n if ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n callbacks.handleFocusBackward?.('previous');\n } else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n callbacks.handleFocusForward?.('next');\n }\n }\n };\n\n const renderSearch = useMemo(\n () =>\n searchElement\n ? cloneElement(searchElement, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n handleFocusForward: () => focusMenuItem(0),\n }),\n ref: searchRef,\n })\n : null,\n [searchElement, lastVirtualItemIndex, focusMenuItem]\n );\n\n const renderItems = useMemo(\n () =>\n rowVirtualizer.virtualItems.map((virtualRow) => {\n if (!items) {\n return null;\n }\n const elem = items[virtualRow.index];\n return (\n <div\n key={virtualRow.index}\n ref={virtualRow.measureRef}\n role=\"presentation\"\n className={cx('VirtualMenu-item')}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {cloneElement(elem, getItemProps(elem, virtualRow.index))}\n </div>\n );\n }),\n [rowVirtualizer.virtualItems, items, getItemProps]\n );\n\n return (\n <>\n {renderSearch}\n <MenuItemList ref={parentRef} role=\"presentation\">\n <div\n role=\"presentation\"\n className=\"VirtualMenu-item-list\"\n style={{\n height: `${rowVirtualizer.totalSize}px`,\n }}\n >\n {renderItems}\n </div>\n </MenuItemList>\n </>\n );\n};\n\nexport { Menu, ItemVirtualizer };\nexport type { MenuProps, ItemVirtualizerProps };\n"],"names":["forwardRef","cx","jsx","useSeparator","tooltip","Slot","cloneElement","FocusRing","jsxs","Fragment","Tooltip","TextField","useFocusManager","useCallback","useMemo","Children","useRef","useId","useState","useVirtual","useEffect"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@launchpad-ui/menu",
3
- "version": "0.11.3",
3
+ "version": "0.11.5",
4
4
  "status": "beta",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -31,11 +31,11 @@
31
31
  "@react-aria/separator": "3.3.2",
32
32
  "classix": "2.1.17",
33
33
  "react-virtual": "2.10.4",
34
- "@launchpad-ui/form": "~0.9.2",
35
- "@launchpad-ui/icons": "~0.9.2",
36
- "@launchpad-ui/popover": "~0.10.8",
34
+ "@launchpad-ui/form": "~0.9.3",
35
+ "@launchpad-ui/icons": "~0.9.3",
36
+ "@launchpad-ui/popover": "~0.10.10",
37
37
  "@launchpad-ui/tokens": "~0.6.0",
38
- "@launchpad-ui/tooltip": "~0.7.18"
38
+ "@launchpad-ui/tooltip": "~0.7.20"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "react": "18.2.0",