@launchpad-ui/menu 0.13.4 → 0.13.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/Menu.d.ts.map +1 -1
- package/dist/MenuBase.d.ts +1 -1
- package/dist/MenuBase.d.ts.map +1 -1
- package/dist/MenuDivider.d.ts.map +1 -1
- package/dist/MenuItem.d.ts.map +1 -1
- package/dist/MenuSearch.d.ts.map +1 -1
- package/dist/index.es.js +7 -3
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +9 -9
package/dist/Menu.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../src/Menu.tsx"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../src/Menu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA8BpE,KAAK,mBAAmB,CAAC,CAAC,IAAI;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAEnE,QAAA,MAAM,IAAI,6FAwHT,CAAC;AAEF,KAAK,oBAAoB,CAAC,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG;IACzE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC5B,CAAC;AAEF,QAAA,MAAM,eAAe,wGAiNpB,CAAC;AAEF,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;AACjC,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC"}
|
package/dist/MenuBase.d.ts
CHANGED
package/dist/MenuBase.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MenuBase.d.ts","sourceRoot":"","sources":["../src/MenuBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
1
|
+
{"version":3,"file":"MenuBase.d.ts","sourceRoot":"","sources":["../src/MenuBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAOxC,KAAK,aAAa,GAAG,qBAAqB,CAAC,KAAK,CAAC,GAAG;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF,QAAA,MAAM,QAAQ,uHAcb,CAAC;AAIF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MenuDivider.d.ts","sourceRoot":"","sources":["../src/MenuDivider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,KAAK,gBAAgB,GAAG,cAAc,GAAG;
|
1
|
+
{"version":3,"file":"MenuDivider.d.ts","sourceRoot":"","sources":["../src/MenuDivider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,KAAK,gBAAgB,GAAG,cAAc,GAAG;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,QAAA,MAAM,WAAW,oEAKd,gBAAgB,4CAclB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
|
package/dist/MenuItem.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MenuItem.d.ts","sourceRoot":"","sources":["../src/MenuItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE5F,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAShD,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;AAExC,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;AAE1E,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,KAAK,
|
1
|
+
{"version":3,"file":"MenuItem.d.ts","sourceRoot":"","sources":["../src/MenuItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE5F,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAShD,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;AAExC,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;AAE1E,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,KAAK,CAC7D,CAAC,SAAS,MAAM,GAAG,CAAC,iBAAiB,GAClC,YAAY,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACtC,qBAAqB,CAAC,CAAC,CAAC,EAC3B,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CACxB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IAChC,cAAc,CAAC,EAAE,qBAAqB,CAAC,OAAO,OAAO,CAAC,CAAC;IACvD,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,QAAA,MAAM,cAAc,WAAW,CAAC;AAEhC,KAAK,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,GAAG,OAAO,cAAc,IAAI,uBAAuB,CAC3F,CAAC,gBAAgB,GAAG;IACpB,IAAI,EAAE,CAAC,CAAC;CACP,CAAC,GACF,CAAC,gBAAgB,GAAG;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;CAChB,CAAC,EACJ,CAAC,CACD,CAAC;AAEF,QAAA,MAAM,QAAQ,qHAyEb,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/MenuSearch.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MenuSearch.d.ts","sourceRoot":"","sources":["../src/MenuSearch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAOzC,KAAK,eAAe,GAAG;
|
1
|
+
{"version":3,"file":"MenuSearch.d.ts","sourceRoot":"","sources":["../src/MenuSearch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAOzC,KAAK,eAAe,GAAG;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,QAAA,MAAM,UAAU,8GAyBd,CAAC;AAIH,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/index.es.js
CHANGED
@@ -72,6 +72,7 @@ const MenuItem = ({
|
|
72
72
|
icon,
|
73
73
|
nested,
|
74
74
|
groupHeader,
|
75
|
+
// biome-ignore lint/correctness/noUnusedVariables: <explanation>
|
75
76
|
item,
|
76
77
|
disabled,
|
77
78
|
className,
|
@@ -158,6 +159,7 @@ const handleKeyboardInteractions = (event, keyHandlers) => {
|
|
158
159
|
ArrowUp: keyHandlers.handleUp,
|
159
160
|
ArrowDown: keyHandlers.handleDown,
|
160
161
|
Enter: keyHandlers.handleEnter
|
162
|
+
// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>
|
161
163
|
};
|
162
164
|
if (ops[event.key]) {
|
163
165
|
event.preventDefault();
|
@@ -165,7 +167,9 @@ const handleKeyboardInteractions = (event, keyHandlers) => {
|
|
165
167
|
}
|
166
168
|
};
|
167
169
|
const chainEventHandlers = (...handlers) => (event) => {
|
168
|
-
|
170
|
+
for (const h of handlers) {
|
171
|
+
typeof h === "function" && h(event);
|
172
|
+
}
|
169
173
|
};
|
170
174
|
const Menu = (props) => {
|
171
175
|
const {
|
@@ -190,7 +194,7 @@ const Menu = (props) => {
|
|
190
194
|
if (enableVirtualization) {
|
191
195
|
let searchElem = null;
|
192
196
|
let elements = [];
|
193
|
-
|
197
|
+
for (const child of childrenProps) {
|
194
198
|
switch (child.type) {
|
195
199
|
case MenuSearch:
|
196
200
|
searchElem = child;
|
@@ -200,7 +204,7 @@ const Menu = (props) => {
|
|
200
204
|
elements = elements.concat(child);
|
201
205
|
break;
|
202
206
|
}
|
203
|
-
}
|
207
|
+
}
|
204
208
|
return { items: elements, searchElement: searchElem };
|
205
209
|
}
|
206
210
|
return childrenProps.reduce(
|
package/dist/index.es.js.map
CHANGED
@@ -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 from './styles/Menu.module.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(\n styles.Menu,\n isVirtual && styles['Menu--isVirtual'],\n size && styles[`MenuSize--${size}`]\n );\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 from './styles/Menu.module.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 (\n <div\n {...separatorProps}\n data-test-id={testId}\n ref={innerRef}\n className={styles['Menu-divider']}\n />\n );\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 from './styles/Menu.module.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?: ComponentPropsWithRef<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={styles['has-focus']}>\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n styles['Menu-item'],\n className,\n isHighlighted && styles['is-highlighted'],\n nested && styles['Menu-item--nested'],\n groupHeader && styles['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={styles['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 from './styles/Menu.module.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={styles['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 from './styles/Menu.module.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={styles['Menu-search']}>\n <TextField\n {...finalProps}\n ref={ref}\n className={styles['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 styles from './styles/Menu.module.css';\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 className: cx(child.props.className, menuItemClassName),\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={styles['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={styles['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 { ComponentPropsWithRef } from 'react';\nimport type { MenuProps } from './Menu';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n\tisVirtual?: boolean;\n\tsize?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n\t({ children, size, isVirtual, ...props }, ref) => {\n\t\tconst classes = cx(\n\t\t\tstyles.Menu,\n\t\t\tisVirtual && styles['Menu--isVirtual'],\n\t\t\tsize && styles[`MenuSize--${size}`],\n\t\t);\n\n\t\treturn (\n\t\t\t<div {...props} role=\"menu\" className={classes} ref={ref}>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\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 from './styles/Menu.module.css';\n\ntype MenuDividerProps = SeparatorProps & {\n\tinnerRef?: RefObject<HTMLDivElement>;\n\t'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n\telementType = 'div',\n\torientation,\n\tinnerRef,\n\t'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n\tconst { separatorProps } = useSeparator({\n\t\torientation,\n\t\telementType,\n\t});\n\n\treturn (\n\t\t<div\n\t\t\t{...separatorProps}\n\t\t\tdata-test-id={testId}\n\t\t\tref={innerRef}\n\t\t\tclassName={styles['Menu-divider']}\n\t\t/>\n\t);\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 from './styles/Menu.module.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\tT extends keyof JSX.IntrinsicElements\n\t\t? PropsWithRef<JSX.IntrinsicElements[T]>\n\t\t: ComponentPropsWithRef<T>,\n\tPropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n\tisHighlighted?: boolean;\n\ticon?: ReactElement<IconProps>;\n\tdisabled?: boolean;\n\tnested?: boolean;\n\tgroupHeader?: boolean;\n\ttooltip?: string | ReactElement;\n\ttooltipOptions?: ComponentPropsWithRef<typeof Tooltip>;\n\ttooltipPlacement?: PopoverPlacement;\n\tasChild?: boolean;\n\t'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n\t| (MenuItemOwnProps & {\n\t\t\titem: P; // Infer the type if it is included\n\t })\n\t| (MenuItemOwnProps & {\n\t\t\titem?: undefined;\n\t }),\n\tT\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n\t...props\n}: MenuItemProps<P, T>) => {\n\tconst {\n\t\t// TODO: remove component prop once we migrate over to asChild format\n\t\tcomponent,\n\t\tchildren,\n\t\tisHighlighted,\n\t\ticon,\n\t\tnested,\n\t\tgroupHeader,\n\t\t// biome-ignore lint/correctness/noUnusedVariables: <explanation>\n\t\titem,\n\t\tdisabled,\n\t\tclassName,\n\t\ttooltip,\n\t\trole = 'menuitem',\n\t\ttooltipPlacement,\n\t\tonKeyDown,\n\t\ttooltipOptions,\n\t\tasChild,\n\t\t'data-test-id': testId = 'menu-item',\n\t\t...rest\n\t} = props;\n\n\tconst Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n\tconst renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n\tconst renderedItem = (\n\t\t<FocusRing focusRingClass={styles['has-focus']}>\n\t\t\t<Component\n\t\t\t\t{...rest}\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-disabled={disabled ? disabled : undefined}\n\t\t\t\tclassName={cx(\n\t\t\t\t\tstyles['Menu-item'],\n\t\t\t\t\tclassName,\n\t\t\t\t\tisHighlighted && styles['is-highlighted'],\n\t\t\t\t\tnested && styles['Menu-item--nested'],\n\t\t\t\t\tgroupHeader && styles['Menu-item--header'],\n\t\t\t\t)}\n\t\t\t\tdata-test-id={testId}\n\t\t\t\trole={role}\n\t\t\t\tonKeyDown={onKeyDown}\n\t\t\t>\n\t\t\t\t{asChild ? (\n\t\t\t\t\tchildren\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{icon && <span className={styles['Menu-item-icon']}>{renderIcon}</span>}\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</Component>\n\t\t</FocusRing>\n\t);\n\n\tif (tooltip) {\n\t\treturn (\n\t\t\t<Tooltip\n\t\t\t\tcontent={tooltip}\n\t\t\t\trootElementStyle={{ display: 'block' }}\n\t\t\t\tallowBoundaryElementOverflow\n\t\t\t\tplacement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n\t\t\t\t{...(tooltipOptions || {})}\n\t\t\t>\n\t\t\t\t{renderedItem}\n\t\t\t</Tooltip>\n\t\t);\n\t}\n\n\treturn renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n\t<div {...rest} ref={ref} data-test-id=\"menu-item-list\" className={styles['Menu-item-list']}>\n\t\t{children}\n\t</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 from './styles/Menu.module.css';\n\ntype MenuSearchProps = {\n\tariaLabel?: string;\n\tvalue?: string;\n\tid?: string;\n\tplaceholder?: string;\n\tonChange?(event: ChangeEvent<HTMLInputElement>): void;\n\t'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n\tconst {\n\t\tariaLabel,\n\t\tplaceholder,\n\t\tid,\n\t\t'data-test-id': testId = 'menu-search',\n\t\t...finalProps\n\t} = props;\n\n\treturn (\n\t\t<div className={styles['Menu-search']}>\n\t\t\t<TextField\n\t\t\t\t{...finalProps}\n\t\t\t\tref={ref}\n\t\t\t\tclassName={styles['Menu-search-input']}\n\t\t\t\ttiny\n\t\t\t\tid={id}\n\t\t\t\ttype=\"search\"\n\t\t\t\tdata-test-id={testId}\n\t\t\t\tautoComplete=\"off\"\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\taria-label={ariaLabel || 'Search'}\n\t\t\t/>\n\t\t</div>\n\t);\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\tindex === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n\tevent: KeyboardEvent,\n\tkeyHandlers: Partial<\n\t\tRecord<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n\t>,\n) => {\n\tconst ops = {\n\t\tArrowUp: keyHandlers.handleUp,\n\t\tArrowDown: keyHandlers.handleDown,\n\t\tEnter: keyHandlers.handleEnter,\n\t\t// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n\t} as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n\tif (ops[event.key]) {\n\t\tevent.preventDefault();\n\t\tops[event.key]?.call(globalThis, event);\n\t}\n};\n\nconst chainEventHandlers =\n\t(...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n\t(event: SyntheticEvent) => {\n\t\tfor (const h of handlers) {\n\t\t\ttypeof h === 'function' && h(event);\n\t\t}\n\t};\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\nimport type { MenuItemProps } from './MenuItem';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n\tChildren,\n\tcloneElement,\n\tuseCallback,\n\tuseEffect,\n\tuseId,\n\tuseMemo,\n\tuseRef,\n\tuseState,\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 styles from './styles/Menu.module.css';\nimport {\n\tchainEventHandlers,\n\tcreateItemId,\n\tgetNodeForIndex,\n\thandleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n\tchildren: ReactNode;\n\tonSelect?: (item: T) => void;\n\t/**\n\t * Menus items are rendered using react-virtual for\n\t * additional rendering performance.\n\t */\n\tenableVirtualization?: boolean;\n\t/**\n\t * Class name to be applied to all MenuItem components\n\t * in the menu.\n\t */\n\tmenuItemClassName?: string;\n\t/**\n\t * Sets the width of the menu. This is especially useful when using virtual items\n\t * since the width cannot be automatically set by the widest element.\n\t */\n\tsize?: 'sm' | 'md' | 'lg' | 'xl';\n\t/**\n\t * Sets the number out of elements rendered outside of the view window\n\t * when using virtualization\n\t */\n\toverscan?: number;\n\t/**\n\t * Sets the height for each menu item when using virtualization.\n\t *\n\t */\n\titemHeight?: number;\n\t'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\tconst {\n\t\tchildren,\n\t\tmenuItemClassName,\n\t\tonSelect,\n\t\tenableVirtualization,\n\t\titemHeight,\n\t\tsize,\n\t\toverscan = 1,\n\t\t'data-test-id': testId = 'menu',\n\t} = props;\n\n\tconst focusManager = useFocusManager();\n\n\tconst handleArrowDown = useCallback(() => {\n\t\tfocusManager?.focusNext({ wrap: true });\n\t}, [focusManager]);\n\n\tconst handleArrowUp = useCallback(() => {\n\t\tfocusManager?.focusPrevious({ wrap: true });\n\t}, [focusManager]);\n\n\tconst reduceItems = useMemo(() => {\n\t\tconst childrenProps = Children.toArray(children);\n\t\tif (enableVirtualization) {\n\t\t\t// the virtualized menu has its own handlers and props\n\t\t\tlet searchElem = null;\n\t\t\tlet elements: ReactElement[] = [];\n\t\t\tfor (const child of childrenProps as ReactElement[]) {\n\t\t\t\tswitch (child.type) {\n\t\t\t\t\tcase MenuSearch:\n\t\t\t\t\t\tsearchElem = child;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MenuItem:\n\t\t\t\t\tcase MenuDivider:\n\t\t\t\t\t\telements = elements.concat(child);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { items: elements, searchElement: searchElem };\n\t\t}\n\n\t\treturn (childrenProps as ReactElement[]).reduce(\n\t\t\t(\n\t\t\t\t{ items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n\t\t\t\tchild,\n\t\t\t) => {\n\t\t\t\tswitch (child.type) {\n\t\t\t\t\tcase MenuSearch:\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\titems,\n\t\t\t\t\t\t\tsearchElement: cloneElement(child, {\n\t\t\t\t\t\t\t\tonKeyDown: (e: KeyboardEvent) =>\n\t\t\t\t\t\t\t\t\thandleKeyboardInteractions(e, {\n\t\t\t\t\t\t\t\t\t\thandleDown: handleArrowDown,\n\t\t\t\t\t\t\t\t\t\thandleUp: handleArrowUp,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t};\n\t\t\t\t\tcase MenuItem:\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\titems: items.concat(\n\t\t\t\t\t\t\t\tchild.props.disabled\n\t\t\t\t\t\t\t\t\t? cloneElement(child, {\n\t\t\t\t\t\t\t\t\t\t\tclassName: cx(child.props.className, menuItemClassName),\n\t\t\t\t\t\t\t\t\t\t\tonClick: () => undefined,\n\t\t\t\t\t\t\t\t\t\t\tonKeyDown: () => undefined,\n\t\t\t\t\t\t\t\t\t\t\ttabIndex: -1,\n\t\t\t\t\t\t\t\t\t\t\tdisabled: true,\n\t\t\t\t\t\t\t\t\t })\n\t\t\t\t\t\t\t\t\t: cloneElement(child, {\n\t\t\t\t\t\t\t\t\t\t\tclassName: cx(child.props.className, menuItemClassName),\n\t\t\t\t\t\t\t\t\t\t\titem: child.props.item ?? items.length,\n\t\t\t\t\t\t\t\t\t\t\t// set focus on the first menu item if there is no search input, and set in the tab order\n\t\t\t\t\t\t\t\t\t\t\tonClick: chainEventHandlers(child.props.onClick, () => {\n\t\t\t\t\t\t\t\t\t\t\t\tonSelect?.(child.props.item ?? items.length);\n\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\tonKeyDown: (e: KeyboardEvent) =>\n\t\t\t\t\t\t\t\t\t\t\t\thandleKeyboardInteractions(e, {\n\t\t\t\t\t\t\t\t\t\t\t\t\thandleDown: handleArrowDown,\n\t\t\t\t\t\t\t\t\t\t\t\t\thandleUp: handleArrowUp,\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t }),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tsearchElement,\n\t\t\t\t\t\t};\n\t\t\t\t\tcase MenuDivider:\n\t\t\t\t\t\treturn { items: items.concat(child), searchElement };\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn { items, searchElement };\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ items: [], searchElement: null },\n\t\t);\n\t}, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n\tif (enableVirtualization) {\n\t\treturn (\n\t\t\t<MenuBase data-test-id={testId} isVirtual size={size}>\n\t\t\t\t<ItemVirtualizer<T>\n\t\t\t\t\titems={Children.toArray(reduceItems.items) as ReactElement[]}\n\t\t\t\t\tsearchElement={reduceItems.searchElement}\n\t\t\t\t\toverscan={overscan}\n\t\t\t\t\tmenuItemClassName={menuItemClassName}\n\t\t\t\t\tonSelect={onSelect}\n\t\t\t\t\titemHeight={itemHeight}\n\t\t\t\t\tfocusManager={focusManager}\n\t\t\t\t/>\n\t\t\t</MenuBase>\n\t\t);\n\t}\n\n\treturn (\n\t\t<MenuBase data-test-id={testId} size={size}>\n\t\t\t{reduceItems.searchElement}\n\t\t\t<MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n\t\t</MenuBase>\n\t);\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n\titems: ReactElement[] | null;\n\tsearchElement?: ReactElement | null;\n\tfocusManager?: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n\tconst {\n\t\toverscan,\n\t\tsearchElement,\n\t\titemHeight = 31.5,\n\t\tmenuItemClassName,\n\t\titems,\n\t\tfocusManager,\n\t\tonSelect,\n\t} = props;\n\n\tconst menuId = useRef(`menu-ctrl-${useId()}`);\n\n\tconst focusedItemIndex = useRef<number | null>(null);\n\tconst parentRef = useRef<HTMLDivElement | null>(null);\n\tconst searchRef = useRef<HTMLInputElement>();\n\n\tconst [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n\tconst hasSearch = !!searchElement;\n\n\tconst lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n\tconst rowVirtualizer = useVirtual({\n\t\tsize: items !== null ? items.length : 0,\n\t\tparentRef,\n\t\testimateSize: useCallback(() => itemHeight, [itemHeight]),\n\t\toverscan,\n\t});\n\n\tconst focusSearchBar = useCallback(() => {\n\t\trowVirtualizer.scrollToIndex(0);\n\t\tsearchRef.current?.focus?.();\n\t}, [rowVirtualizer]);\n\n\t/**\n\t * Scrolls to the menu item with the index provided and\n\t * then manually focuses it using a side effect in useEffect\n\t */\n\tconst focusMenuItem = useCallback(\n\t\t(index: number) => {\n\t\t\trowVirtualizer.scrollToIndex(index);\n\t\t\tsetNextFocusValue(index);\n\t\t},\n\t\t[rowVirtualizer],\n\t);\n\n\tconst handleKeyboardFocusInteraction = useCallback(\n\t\t(direction: 'next' | 'previous') => {\n\t\t\tif (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst nextIndex =\n\t\t\t\tdirection === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n\t\t\tconst shouldWrap =\n\t\t\t\t(direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n\t\t\t\t(direction === 'previous' && focusedItemIndex.current === 0);\n\t\t\tif (shouldWrap) {\n\t\t\t\t// we are at the end of the list so we will\n\t\t\t\t// scroll back to the beginning of the list\n\t\t\t\tif (hasSearch) {\n\t\t\t\t\tfocusSearchBar();\n\t\t\t\t} else {\n\t\t\t\t\t// if at end, wrap to beginning, else focus last item\n\t\t\t\t\tfocusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tswitch (direction) {\n\t\t\t\tcase 'next':\n\t\t\t\t\trowVirtualizer.scrollToIndex(nextIndex);\n\t\t\t\t\tfocusManager?.focusNext();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'previous':\n\t\t\t\t\trowVirtualizer.scrollToIndex(nextIndex);\n\t\t\t\t\tfocusManager?.focusPrevious();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t\t[focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer],\n\t);\n\n\tconst getItemProps = useCallback(\n\t\t(itemElem: ReactElement, index: number) => {\n\t\t\tconst childProps = itemElem.props as MenuItemProps<T>;\n\t\t\tswitch (itemElem.type) {\n\t\t\t\tcase MenuItem:\n\t\t\t\t\treturn {\n\t\t\t\t\t\tclassName: cx(childProps.className, menuItemClassName),\n\t\t\t\t\t\t// set focus on the first menu item if there is no search input, and set in the tab order\n\t\t\t\t\t\tonKeyDown: childProps.disabled\n\t\t\t\t\t\t\t? () => undefined\n\t\t\t\t\t\t\t: (e: KeyboardEvent) =>\n\t\t\t\t\t\t\t\t\thandleKeyboardFocusKeydown(e, {\n\t\t\t\t\t\t\t\t\t\thandleFocusBackward: handleKeyboardFocusInteraction,\n\t\t\t\t\t\t\t\t\t\thandleFocusForward: handleKeyboardFocusInteraction,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tonFocus: chainEventHandlers(childProps.onFocus, () => {\n\t\t\t\t\t\t\tfocusedItemIndex.current = index;\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tid: createItemId(index, menuId.current),\n\t\t\t\t\t\tonBlur: chainEventHandlers(childProps.onBlur, () => {\n\t\t\t\t\t\t\tfocusedItemIndex.current = null;\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tonClick: childProps.disabled\n\t\t\t\t\t\t\t? () => undefined\n\t\t\t\t\t\t\t: chainEventHandlers(childProps.onClick, () => {\n\t\t\t\t\t\t\t\t\tonSelect?.(childProps.item as T);\n\t\t\t\t\t\t\t }),\n\t\t\t\t\t} as MenuItemProps<T>;\n\t\t\t\tdefault:\n\t\t\t\t\treturn {};\n\t\t\t}\n\t\t},\n\t\t[handleKeyboardFocusInteraction, menuItemClassName, onSelect],\n\t);\n\n\tuseEffect(() => {\n\t\tif (nextFocusValue !== null) {\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tconst element = getNodeForIndex(nextFocusValue, menuId.current);\n\t\t\t\telement?.focus();\n\t\t\t});\n\t\t\tsetNextFocusValue(null);\n\t\t}\n\t}, [nextFocusValue]);\n\n\t/**\n\t * Calls handleFocusForward when the user is attempting to focus forward using\n\t * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n\t */\n\tconst handleKeyboardFocusKeydown = (\n\t\te: KeyboardEvent,\n\t\tcallbacks: Record<\n\t\t\t'handleFocusForward' | 'handleFocusBackward',\n\t\t\t(direction: 'next' | 'previous') => void\n\t\t>,\n\t) => {\n\t\tconst keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n\t\tif (keyOps.includes(e.key)) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tif ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n\t\t\t\tcallbacks.handleFocusBackward?.('previous');\n\t\t\t} else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n\t\t\t\tcallbacks.handleFocusForward?.('next');\n\t\t\t}\n\t\t}\n\t};\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n\tconst renderSearch = useMemo(\n\t\t() =>\n\t\t\tsearchElement\n\t\t\t\t? cloneElement(searchElement, {\n\t\t\t\t\t\tonKeyDown: (e: KeyboardEvent) =>\n\t\t\t\t\t\t\thandleKeyboardFocusKeydown(e, {\n\t\t\t\t\t\t\t\thandleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n\t\t\t\t\t\t\t\thandleFocusForward: () => focusMenuItem(0),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tref: searchRef,\n\t\t\t\t })\n\t\t\t\t: null,\n\t\t[searchElement, lastVirtualItemIndex, focusMenuItem],\n\t);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n\tconst renderItems = useMemo(\n\t\t() =>\n\t\t\trowVirtualizer.virtualItems.map((virtualRow) => {\n\t\t\t\tif (!items) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst elem = items[virtualRow.index];\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={virtualRow.index}\n\t\t\t\t\t\tref={virtualRow.measureRef}\n\t\t\t\t\t\trole=\"presentation\"\n\t\t\t\t\t\tclassName={styles['VirtualMenu-item']}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\ttransform: `translateY(${virtualRow.start}px)`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{cloneElement(elem, getItemProps(elem, virtualRow.index))}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}),\n\t\t[rowVirtualizer.virtualItems, items, getItemProps],\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t{renderSearch}\n\t\t\t<MenuItemList ref={parentRef} role=\"presentation\">\n\t\t\t\t<div\n\t\t\t\t\trole=\"presentation\"\n\t\t\t\t\tclassName={styles['VirtualMenu-item-list']}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\theight: `${rowVirtualizer.totalSize}px`,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{renderItems}\n\t\t\t\t</div>\n\t\t\t</MenuItemList>\n\t\t</>\n\t);\n};\n\nexport { Menu, ItemVirtualizer };\nexport type { MenuProps, ItemVirtualizerProps };\n"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
@@ -74,6 +74,7 @@ const MenuItem = ({
|
|
74
74
|
icon,
|
75
75
|
nested,
|
76
76
|
groupHeader,
|
77
|
+
// biome-ignore lint/correctness/noUnusedVariables: <explanation>
|
77
78
|
item,
|
78
79
|
disabled,
|
79
80
|
className,
|
@@ -160,6 +161,7 @@ const handleKeyboardInteractions = (event, keyHandlers) => {
|
|
160
161
|
ArrowUp: keyHandlers.handleUp,
|
161
162
|
ArrowDown: keyHandlers.handleDown,
|
162
163
|
Enter: keyHandlers.handleEnter
|
164
|
+
// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>
|
163
165
|
};
|
164
166
|
if (ops[event.key]) {
|
165
167
|
event.preventDefault();
|
@@ -167,7 +169,9 @@ const handleKeyboardInteractions = (event, keyHandlers) => {
|
|
167
169
|
}
|
168
170
|
};
|
169
171
|
const chainEventHandlers = (...handlers) => (event) => {
|
170
|
-
|
172
|
+
for (const h of handlers) {
|
173
|
+
typeof h === "function" && h(event);
|
174
|
+
}
|
171
175
|
};
|
172
176
|
const Menu = (props) => {
|
173
177
|
const {
|
@@ -192,7 +196,7 @@ const Menu = (props) => {
|
|
192
196
|
if (enableVirtualization) {
|
193
197
|
let searchElem = null;
|
194
198
|
let elements = [];
|
195
|
-
|
199
|
+
for (const child of childrenProps) {
|
196
200
|
switch (child.type) {
|
197
201
|
case MenuSearch:
|
198
202
|
searchElem = child;
|
@@ -202,7 +206,7 @@ const Menu = (props) => {
|
|
202
206
|
elements = elements.concat(child);
|
203
207
|
break;
|
204
208
|
}
|
205
|
-
}
|
209
|
+
}
|
206
210
|
return { items: elements, searchElement: searchElem };
|
207
211
|
}
|
208
212
|
return childrenProps.reduce(
|
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 from './styles/Menu.module.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(\n styles.Menu,\n isVirtual && styles['Menu--isVirtual'],\n size && styles[`MenuSize--${size}`]\n );\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 from './styles/Menu.module.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 (\n <div\n {...separatorProps}\n data-test-id={testId}\n ref={innerRef}\n className={styles['Menu-divider']}\n />\n );\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 from './styles/Menu.module.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?: ComponentPropsWithRef<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={styles['has-focus']}>\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n styles['Menu-item'],\n className,\n isHighlighted && styles['is-highlighted'],\n nested && styles['Menu-item--nested'],\n groupHeader && styles['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={styles['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 from './styles/Menu.module.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={styles['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 from './styles/Menu.module.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={styles['Menu-search']}>\n <TextField\n {...finalProps}\n ref={ref}\n className={styles['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 styles from './styles/Menu.module.css';\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 className: cx(child.props.className, menuItemClassName),\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={styles['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={styles['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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,MAAM,WAAWA,sBAAA;AAAA,EACf,CAAC,EAAE,UAAU,MAAM,WAAW,GAAG,SAAS,QAAQ;AAChD,UAAM,UAAUC,QAAA;AAAA,MACd,OAAO;AAAA,MACP,aAAa,OAAO,iBAAiB;AAAA,MACrC,QAAQ,OAAO,aAAa,IAAI,EAAE;AAAA,IAAA;AAIlC,WAAAC,+BAAC,SAAK,GAAG,OAAO,MAAK,QAAO,WAAW,SAAS,KAC7C,SACH,CAAA;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;ACjBvB,MAAM,cAAc,CAAC;AAAA,EACnB,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,gBAAgB,SAAS;AAC3B,MAAwB;AAChB,QAAA,EAAE,eAAe,IAAIC,uBAAa;AAAA,IACtC;AAAA,IACA;AAAA,EAAA,CACD;AAGC,SAAAD,2BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAG;AAAA,MACJ,gBAAc;AAAA,MACd,KAAK;AAAA,MACL,WAAW,OAAO,cAAc;AAAA,IAAA;AAAA,EAAA;AAGtC;ACMA,MAAM,iBAAiB;AAYvB,MAAM,WAAW,CAAmD;AAAA,EAClE,GAAG;AACL,MAA2B;AACnB,QAAA;AAAA;AAAA,IAEJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAAA,SACAE;AAAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB,SAAS;AAAA,IACzB,GAAG;AAAA,EACD,IAAA;AAEE,QAAA,YAAyB,cAAc,UAAUC,UAAO,OAAA;AAE9D,QAAM,aAAa,QAAQC,sBAAA,aAAa,MAAM,EAAE,MAAM,SAAS;AAE/D,QAAM,eACHJ,2BAAA,IAAAK,iBAAA,EAAU,gBAAgB,OAAO,WAAW,GAC3C,UAAAL,2BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,iBAAe,WAAW,WAAW;AAAA,MACrC,WAAWD,QAAA;AAAA,QACT,OAAO,WAAW;AAAA,QAClB;AAAA,QACA,iBAAiB,OAAO,gBAAgB;AAAA,QACxC,UAAU,OAAO,mBAAmB;AAAA,QACpC,eAAe,OAAO,mBAAmB;AAAA,MAC3C;AAAA,MACA,gBAAc;AAAA,MACd;AAAA,MACA;AAAA,MAEC,UAAA,UACC,WAGGO,2BAAA,KAAAC,WAAA,UAAA,EAAA,UAAA;AAAA,QAAA,uCAAS,QAAK,EAAA,WAAW,OAAO,gBAAgB,GAAI,UAAW,YAAA;AAAA,QAC/D;AAAA,MAAA,GACH;AAAA,IAAA;AAAA,EAGN,EAAA,CAAA;AAGF,MAAIL,WAAS;AAET,WAAAF,2BAAA;AAAA,MAACQ,QAAA;AAAA,MAAA;AAAA,QACC,SAASN;AAAAA,QACT,kBAAkB,EAAE,SAAS,QAAQ;AAAA,QACrC,8BAA4B;AAAA,QAC5B,WAAW,mBAAmB,mBAAmB;AAAA,QAChD,GAAI,kBAAkB,CAAC;AAAA,QAEvB,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AAEO,SAAA;AACT;ACjHM,MAAA,eAA6DJ,sBAAAA,WAAA,CAAC,EAAE,UAAU,GAAG,QAAQ,QACzFE,2BAAA,IAAC,SAAK,GAAG,MAAM,KAAU,gBAAa,kBAAiB,WAAW,OAAO,gBAAgB,GACtF,SAAA,CACH,CACD;AAED,aAAa,cAAc;ACE3B,MAAM,aAAaF,sBAAA,WAA8C,CAAC,OAAO,QAAQ;AACzE,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB,SAAS;AAAA,IACzB,GAAG;AAAA,EACD,IAAA;AAEJ,SACGE,2BAAAA,IAAA,OAAA,EAAI,WAAW,OAAO,aAAa,GAClC,UAAAA,2BAAA;AAAA,IAACS,KAAA;AAAA,IAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,WAAW,OAAO,mBAAmB;AAAA,MACrC,MAAI;AAAA,MACJ;AAAA,MACA,MAAK;AAAA,MACL,gBAAc;AAAA,MACd,cAAa;AAAA,MACb;AAAA,MACA,cAAY,aAAa;AAAA,IAAA;AAAA,EAE7B,EAAA,CAAA;AAEJ,CAAC;AAED,WAAW,cAAc;ACzCzB,MAAM,eAAe,CAAC,OAAe,OAAe,GAAG,EAAE,SAAS,KAAK;AAEvE,MAAM,kBAAkB,CAAC,OAAsB,WAC7C,UAAU,OAAO,QAAQ,SAAS,eAAe,aAAa,OAAO,MAAM,CAAC;AAE9E,MAAM,6BAA6B,CACjC,OACA,gBAGG;;AACH,QAAM,MAAM;AAAA,IACV,SAAS,YAAY;AAAA,IACrB,WAAW,YAAY;AAAA,IACvB,OAAO,YAAY;AAAA,EAAA;AAGjB,MAAA,IAAI,MAAM,GAAG,GAAG;AAClB,UAAM,eAAe;AACrB,cAAI,MAAM,GAAG,MAAb,mBAAgB,KAAK,YAAY;AAAA,EACnC;AACF;AAEA,MAAM,qBACJ,IAAI,aACJ,CAAC,UAA0B;AAChB,WAAA,QAAQ,CAAC,MAAM,OAAO,MAAM,cAAc,EAAE,KAAK,CAAC;AAC7D;ACmCI,MAAA,OAAO,CAA4B,UAAwB;AACzD,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,gBAAgB,SAAS;AAAA,EACvB,IAAA;AAEJ,QAAM,eAAeC,MAAAA;AAEf,QAAA,kBAAkBC,MAAAA,YAAY,MAAM;AACxC,iDAAc,UAAU,EAAE,MAAM,KAAM;AAAA,EAAA,GACrC,CAAC,YAAY,CAAC;AAEX,QAAA,gBAAgBA,MAAAA,YAAY,MAAM;AACtC,iDAAc,cAAc,EAAE,MAAM,KAAM;AAAA,EAAA,GACzC,CAAC,YAAY,CAAC;AAEX,QAAA,cAAcC,MAAAA,QAAQ,MAAM;AAC1B,UAAA,gBAAgBC,MAAAA,SAAS,QAAQ,QAAQ;AAC/C,QAAI,sBAAsB;AAExB,UAAI,aAAa;AACjB,UAAI,WAA2B,CAAA;AAC9B,oBAAiC,QAAQ,CAAC,UAAwB;AACjE,gBAAQ,MAAM,MAAM;AAAA,UAClB,KAAK;AACU,yBAAA;AACb;AAAA,UACF,KAAK;AAAA,UACL,KAAK;AACQ,uBAAA,SAAS,OAAO,KAAK;AAChC;AAAA,QAGJ;AAAA,MAAA,CACD;AACD,aAAO,EAAE,OAAO,UAAU,eAAe,WAAW;AAAA,IACtD;AAEA,WAAQ,cAAiC;AAAA,MACvC,CACE,EAAE,OAAO,iBACT,UACG;AACH,gBAAQ,MAAM,MAAM;AAAA,UAClB,KAAK;AACI,mBAAA;AAAA,cACL;AAAA,cACA,eAA4BT,sBAAA,aAAA,OAAO;AAAA,gBACjC,WAAW,CAAC,MACV,2BAA2B,GAAG;AAAA,kBAC5B,YAAY;AAAA,kBACZ,UAAU;AAAA,gBAAA,CACX;AAAA,cAAA,CACJ;AAAA,YAAA;AAAA,UAEL,KAAK;AACI,mBAAA;AAAA,cACL,OAAO,MAAM;AAAA,gBACX,MAAM,MAAM,8CACK,OAAO;AAAA,kBAClB,WAAWL,QAAAA,GAAG,MAAM,MAAM,WAAW,iBAAiB;AAAA,kBACtD,SAAS,MAAM;AAAA,kBACf,WAAW,MAAM;AAAA,kBACjB,UAAU;AAAA,kBACV,UAAU;AAAA,gBAAA,CACX,IACYK,sBAAA,aAAA,OAAO;AAAA,kBAClB,WAAWL,QAAAA,GAAG,MAAM,MAAM,WAAW,iBAAiB;AAAA,kBACtD,MAAM,MAAM,MAAM,QAAQ,MAAM;AAAA;AAAA,kBAEhC,SAAS,mBAAmB,MAAM,MAAM,SAAS,MAAM;AACrD,yDAAW,MAAM,MAAM,QAAQ,MAAM;AAAA,kBAAM,CAC5C;AAAA,kBACD,WAAW,CAAC,MACV,2BAA2B,GAAG;AAAA,oBAC5B,YAAY;AAAA,oBACZ,UAAU;AAAA,kBAAA,CACX;AAAA,gBAAA,CACJ;AAAA,cACP;AAAA,cACA;AAAA,YAAA;AAAA,UAEJ,KAAK;AACH,mBAAO,EAAE,OAAO,MAAM,OAAO,KAAK,GAAG;UACvC;AACS,mBAAA,EAAE,OAAO;QACpB;AAAA,MACF;AAAA,MACA,EAAE,OAAO,CAAA,GAAI,eAAe,KAAK;AAAA,IAAA;AAAA,EACnC,GACC,CAAC,UAAU,sBAAsB,mBAAmB,iBAAiB,eAAe,QAAQ,CAAC;AAEhG,MAAI,sBAAsB;AACxB,0CACG,UAAS,EAAA,gBAAc,QAAQ,WAAS,MAAC,MACxC,UAAAC,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAOa,MAAA,SAAS,QAAQ,YAAY,KAAK;AAAA,QACzC,eAAe,YAAY;AAAA,QAC3B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,EAAA,CAAA;AAAA,EAEJ;AAEA,SACGP,2BAAAA,KAAA,UAAA,EAAS,gBAAc,QAAQ,MAC7B,UAAA;AAAA,IAAY,YAAA;AAAA,IACZN,2BAAA,IAAA,cAAA,EAAa,MAAK,gBAAgB,sBAAY,OAAM;AAAA,EACvD,EAAA,CAAA;AAEJ;AAQA,MAAM,kBAAkB,CAA4B,UAAmC;AAC/E,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACE,IAAA;AAEJ,QAAM,SAASc,MAAAA,OAAO,aAAaC,MAAA,MAAA,CAAO,EAAE;AAEtC,QAAA,mBAAmBD,aAAsB,IAAI;AAC7C,QAAA,YAAYA,aAA8B,IAAI;AACpD,QAAM,YAAYA,MAAAA;AAElB,QAAM,CAAC,gBAAgB,iBAAiB,IAAIE,eAAwB,IAAI;AAElE,QAAA,YAAY,CAAC,CAAC;AAEpB,QAAM,uBAAuB,QAAQ,MAAM,SAAS,IAAI;AAExD,QAAM,iBAAiBC,aAAAA,WAAW;AAAA,IAChC,MAAM,UAAU,OAAO,MAAM,SAAS;AAAA,IACtC;AAAA,IACA,cAAcN,MAAAA,YAAY,MAAM,YAAY,CAAC,UAAU,CAAC;AAAA,IACxD;AAAA,EAAA,CACD;AAEK,QAAA,iBAAiBA,MAAAA,YAAY,MAAM;;AACvC,mBAAe,cAAc,CAAC;AAC9B,0BAAU,YAAV,mBAAmB,UAAnB;AAAA,EAA2B,GAC1B,CAAC,cAAc,CAAC;AAMnB,QAAM,gBAAgBA,MAAA;AAAA,IACpB,CAAC,UAAkB;AACjB,qBAAe,cAAc,KAAK;AAClC,wBAAkB,KAAK;AAAA,IACzB;AAAA,IACA,CAAC,cAAc;AAAA,EAAA;AAGjB,QAAM,iCAAiCA,MAAA;AAAA,IACrC,CAAC,cAAmC;AAClC,UAAI,iBAAiB,YAAY,QAAQ,iBAAiB,YAAY,QAAW;AAC/E;AAAA,MACF;AACA,YAAM,YACJ,cAAc,SAAS,iBAAiB,UAAU,IAAI,iBAAiB,UAAU;AAC7E,YAAA,aACH,cAAc,UAAU,iBAAiB,YAAY,wBACrD,cAAc,cAAc,iBAAiB,YAAY;AAC5D,UAAI,YAAY;AAGd,YAAI,WAAW;AACE;QAAA,OACV;AAES,wBAAA,cAAc,SAAS,IAAI,oBAAoB;AAAA,QAC/D;AACA;AAAA,MACF;AACA,cAAQ,WAAW;AAAA,QACjB,KAAK;AACH,yBAAe,cAAc,SAAS;AACtC,uDAAc;AACd;AAAA,QACF,KAAK;AACH,yBAAe,cAAc,SAAS;AACtC,uDAAc;AACd;AAAA,MAGJ;AAAA,IACF;AAAA,IACA,CAAC,cAAc,eAAe,gBAAgB,WAAW,sBAAsB,cAAc;AAAA,EAAA;AAG/F,QAAM,eAAeA,MAAA;AAAA,IACnB,CAAC,UAAwB,UAAkB;AACzC,YAAM,aAAa,SAAS;AAC5B,cAAQ,SAAS,MAAM;AAAA,QACrB,KAAK;AACI,iBAAA;AAAA,YACL,WAAWZ,QAAA,GAAG,WAAW,WAAW,iBAAiB;AAAA;AAAA,YAErD,WAAW,WAAW,WAClB,MAAM,SACN,CAAC,MACC,2BAA2B,GAAG;AAAA,cAC5B,qBAAqB;AAAA,cACrB,oBAAoB;AAAA,YAAA,CACrB;AAAA,YACP,SAAS,mBAAmB,WAAW,SAAS,MAAM;AACpD,+BAAiB,UAAU;AAAA,YAAA,CAC5B;AAAA,YACD,IAAI,aAAa,OAAO,OAAO,OAAO;AAAA,YACtC,QAAQ,mBAAmB,WAAW,QAAQ,MAAM;AAClD,+BAAiB,UAAU;AAAA,YAAA,CAC5B;AAAA,YACD,SAAS,WAAW,WAChB,MAAM,SACN,mBAAmB,WAAW,SAAS,MAAM;AAC3C,mDAAW,WAAW;AAAA,YAAS,CAChC;AAAA,UAAA;AAAA,QAET;AACE,iBAAO;MACX;AAAA,IACF;AAAA,IACA,CAAC,gCAAgC,mBAAmB,QAAQ;AAAA,EAAA;AAG9DmB,QAAAA,UAAU,MAAM;AACd,QAAI,mBAAmB,MAAM;AAC3B,4BAAsB,MAAM;AAC1B,cAAM,UAAU,gBAAgB,gBAAgB,OAAO,OAAO;AAC9D,2CAAS;AAAA,MAAM,CAChB;AACD,wBAAkB,IAAI;AAAA,IACxB;AAAA,EAAA,GACC,CAAC,cAAc,CAAC;AAMb,QAAA,6BAA6B,CACjC,GACA,cAIG;;AACH,UAAM,SAAS,CAAC,OAAO,WAAW,WAAW;AAC7C,QAAI,OAAO,SAAS,EAAE,GAAG,GAAG;AAC1B,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAClB,UAAK,EAAE,QAAQ,SAAS,EAAE,YAAa,EAAE,QAAQ,WAAW;AAC1D,wBAAU,wBAAV,mCAAgC;AAAA,MAAU,WACjC,EAAE,QAAQ,eAAe,EAAE,QAAQ,OAAO;AACnD,wBAAU,uBAAV,mCAA+B;AAAA,MACjC;AAAA,IACF;AAAA,EAAA;AAGF,QAAM,eAAeN,MAAA;AAAA,IACnB,MACE,mDACiB,eAAe;AAAA,MAC1B,WAAW,CAAC,MACV,2BAA2B,GAAG;AAAA,QAC5B,qBAAqB,MAAM,cAAc,oBAAoB;AAAA,QAC7D,oBAAoB,MAAM,cAAc,CAAC;AAAA,MAAA,CAC1C;AAAA,MACH,KAAK;AAAA,IACN,CAAA,IACD;AAAA,IACN,CAAC,eAAe,sBAAsB,aAAa;AAAA,EAAA;AAGrD,QAAM,cAAcA,MAAA;AAAA,IAClB,MACE,eAAe,aAAa,IAAI,CAAC,eAAe;AAC9C,UAAI,CAAC,OAAO;AACH,eAAA;AAAA,MACT;AACM,YAAA,OAAO,MAAM,WAAW,KAAK;AAEjC,aAAAZ,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,KAAK,WAAW;AAAA,UAChB,MAAK;AAAA,UACL,WAAW,OAAO,kBAAkB;AAAA,UACpC,OAAO;AAAA,YACL,WAAW,cAAc,WAAW,KAAK;AAAA,UAC3C;AAAA,UAEC,6CAAa,MAAM,aAAa,MAAM,WAAW,KAAK,CAAC;AAAA,QAAA;AAAA,QARnD,WAAW;AAAA,MAAA;AAAA,IASlB,CAEH;AAAA,IACH,CAAC,eAAe,cAAc,OAAO,YAAY;AAAA,EAAA;AAGnD,SAEKM,2BAAA,KAAAC,qBAAA,EAAA,UAAA;AAAA,IAAA;AAAA,IACAP,2BAAA,IAAA,cAAA,EAAa,KAAK,WAAW,MAAK,gBACjC,UAAAA,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAW,OAAO,uBAAuB;AAAA,QACzC,OAAO;AAAA,UACL,QAAQ,GAAG,eAAe,SAAS;AAAA,QACrC;AAAA,QAEC,UAAA;AAAA,MAAA;AAAA,IAAA,GAEL;AAAA,EACF,EAAA,CAAA;AAEJ;;;;;;;"}
|
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 { ComponentPropsWithRef } from 'react';\nimport type { MenuProps } from './Menu';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n\tisVirtual?: boolean;\n\tsize?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n\t({ children, size, isVirtual, ...props }, ref) => {\n\t\tconst classes = cx(\n\t\t\tstyles.Menu,\n\t\t\tisVirtual && styles['Menu--isVirtual'],\n\t\t\tsize && styles[`MenuSize--${size}`],\n\t\t);\n\n\t\treturn (\n\t\t\t<div {...props} role=\"menu\" className={classes} ref={ref}>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\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 from './styles/Menu.module.css';\n\ntype MenuDividerProps = SeparatorProps & {\n\tinnerRef?: RefObject<HTMLDivElement>;\n\t'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n\telementType = 'div',\n\torientation,\n\tinnerRef,\n\t'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n\tconst { separatorProps } = useSeparator({\n\t\torientation,\n\t\telementType,\n\t});\n\n\treturn (\n\t\t<div\n\t\t\t{...separatorProps}\n\t\t\tdata-test-id={testId}\n\t\t\tref={innerRef}\n\t\t\tclassName={styles['Menu-divider']}\n\t\t/>\n\t);\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 from './styles/Menu.module.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\tT extends keyof JSX.IntrinsicElements\n\t\t? PropsWithRef<JSX.IntrinsicElements[T]>\n\t\t: ComponentPropsWithRef<T>,\n\tPropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n\tisHighlighted?: boolean;\n\ticon?: ReactElement<IconProps>;\n\tdisabled?: boolean;\n\tnested?: boolean;\n\tgroupHeader?: boolean;\n\ttooltip?: string | ReactElement;\n\ttooltipOptions?: ComponentPropsWithRef<typeof Tooltip>;\n\ttooltipPlacement?: PopoverPlacement;\n\tasChild?: boolean;\n\t'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n\t| (MenuItemOwnProps & {\n\t\t\titem: P; // Infer the type if it is included\n\t })\n\t| (MenuItemOwnProps & {\n\t\t\titem?: undefined;\n\t }),\n\tT\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n\t...props\n}: MenuItemProps<P, T>) => {\n\tconst {\n\t\t// TODO: remove component prop once we migrate over to asChild format\n\t\tcomponent,\n\t\tchildren,\n\t\tisHighlighted,\n\t\ticon,\n\t\tnested,\n\t\tgroupHeader,\n\t\t// biome-ignore lint/correctness/noUnusedVariables: <explanation>\n\t\titem,\n\t\tdisabled,\n\t\tclassName,\n\t\ttooltip,\n\t\trole = 'menuitem',\n\t\ttooltipPlacement,\n\t\tonKeyDown,\n\t\ttooltipOptions,\n\t\tasChild,\n\t\t'data-test-id': testId = 'menu-item',\n\t\t...rest\n\t} = props;\n\n\tconst Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n\tconst renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n\tconst renderedItem = (\n\t\t<FocusRing focusRingClass={styles['has-focus']}>\n\t\t\t<Component\n\t\t\t\t{...rest}\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-disabled={disabled ? disabled : undefined}\n\t\t\t\tclassName={cx(\n\t\t\t\t\tstyles['Menu-item'],\n\t\t\t\t\tclassName,\n\t\t\t\t\tisHighlighted && styles['is-highlighted'],\n\t\t\t\t\tnested && styles['Menu-item--nested'],\n\t\t\t\t\tgroupHeader && styles['Menu-item--header'],\n\t\t\t\t)}\n\t\t\t\tdata-test-id={testId}\n\t\t\t\trole={role}\n\t\t\t\tonKeyDown={onKeyDown}\n\t\t\t>\n\t\t\t\t{asChild ? (\n\t\t\t\t\tchildren\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{icon && <span className={styles['Menu-item-icon']}>{renderIcon}</span>}\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</Component>\n\t\t</FocusRing>\n\t);\n\n\tif (tooltip) {\n\t\treturn (\n\t\t\t<Tooltip\n\t\t\t\tcontent={tooltip}\n\t\t\t\trootElementStyle={{ display: 'block' }}\n\t\t\t\tallowBoundaryElementOverflow\n\t\t\t\tplacement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n\t\t\t\t{...(tooltipOptions || {})}\n\t\t\t>\n\t\t\t\t{renderedItem}\n\t\t\t</Tooltip>\n\t\t);\n\t}\n\n\treturn renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n\t<div {...rest} ref={ref} data-test-id=\"menu-item-list\" className={styles['Menu-item-list']}>\n\t\t{children}\n\t</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 from './styles/Menu.module.css';\n\ntype MenuSearchProps = {\n\tariaLabel?: string;\n\tvalue?: string;\n\tid?: string;\n\tplaceholder?: string;\n\tonChange?(event: ChangeEvent<HTMLInputElement>): void;\n\t'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n\tconst {\n\t\tariaLabel,\n\t\tplaceholder,\n\t\tid,\n\t\t'data-test-id': testId = 'menu-search',\n\t\t...finalProps\n\t} = props;\n\n\treturn (\n\t\t<div className={styles['Menu-search']}>\n\t\t\t<TextField\n\t\t\t\t{...finalProps}\n\t\t\t\tref={ref}\n\t\t\t\tclassName={styles['Menu-search-input']}\n\t\t\t\ttiny\n\t\t\t\tid={id}\n\t\t\t\ttype=\"search\"\n\t\t\t\tdata-test-id={testId}\n\t\t\t\tautoComplete=\"off\"\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\taria-label={ariaLabel || 'Search'}\n\t\t\t/>\n\t\t</div>\n\t);\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\tindex === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n\tevent: KeyboardEvent,\n\tkeyHandlers: Partial<\n\t\tRecord<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n\t>,\n) => {\n\tconst ops = {\n\t\tArrowUp: keyHandlers.handleUp,\n\t\tArrowDown: keyHandlers.handleDown,\n\t\tEnter: keyHandlers.handleEnter,\n\t\t// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n\t} as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n\tif (ops[event.key]) {\n\t\tevent.preventDefault();\n\t\tops[event.key]?.call(globalThis, event);\n\t}\n};\n\nconst chainEventHandlers =\n\t(...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n\t(event: SyntheticEvent) => {\n\t\tfor (const h of handlers) {\n\t\t\ttypeof h === 'function' && h(event);\n\t\t}\n\t};\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\nimport type { MenuItemProps } from './MenuItem';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n\tChildren,\n\tcloneElement,\n\tuseCallback,\n\tuseEffect,\n\tuseId,\n\tuseMemo,\n\tuseRef,\n\tuseState,\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 styles from './styles/Menu.module.css';\nimport {\n\tchainEventHandlers,\n\tcreateItemId,\n\tgetNodeForIndex,\n\thandleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n\tchildren: ReactNode;\n\tonSelect?: (item: T) => void;\n\t/**\n\t * Menus items are rendered using react-virtual for\n\t * additional rendering performance.\n\t */\n\tenableVirtualization?: boolean;\n\t/**\n\t * Class name to be applied to all MenuItem components\n\t * in the menu.\n\t */\n\tmenuItemClassName?: string;\n\t/**\n\t * Sets the width of the menu. This is especially useful when using virtual items\n\t * since the width cannot be automatically set by the widest element.\n\t */\n\tsize?: 'sm' | 'md' | 'lg' | 'xl';\n\t/**\n\t * Sets the number out of elements rendered outside of the view window\n\t * when using virtualization\n\t */\n\toverscan?: number;\n\t/**\n\t * Sets the height for each menu item when using virtualization.\n\t *\n\t */\n\titemHeight?: number;\n\t'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\tconst {\n\t\tchildren,\n\t\tmenuItemClassName,\n\t\tonSelect,\n\t\tenableVirtualization,\n\t\titemHeight,\n\t\tsize,\n\t\toverscan = 1,\n\t\t'data-test-id': testId = 'menu',\n\t} = props;\n\n\tconst focusManager = useFocusManager();\n\n\tconst handleArrowDown = useCallback(() => {\n\t\tfocusManager?.focusNext({ wrap: true });\n\t}, [focusManager]);\n\n\tconst handleArrowUp = useCallback(() => {\n\t\tfocusManager?.focusPrevious({ wrap: true });\n\t}, [focusManager]);\n\n\tconst reduceItems = useMemo(() => {\n\t\tconst childrenProps = Children.toArray(children);\n\t\tif (enableVirtualization) {\n\t\t\t// the virtualized menu has its own handlers and props\n\t\t\tlet searchElem = null;\n\t\t\tlet elements: ReactElement[] = [];\n\t\t\tfor (const child of childrenProps as ReactElement[]) {\n\t\t\t\tswitch (child.type) {\n\t\t\t\t\tcase MenuSearch:\n\t\t\t\t\t\tsearchElem = child;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MenuItem:\n\t\t\t\t\tcase MenuDivider:\n\t\t\t\t\t\telements = elements.concat(child);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { items: elements, searchElement: searchElem };\n\t\t}\n\n\t\treturn (childrenProps as ReactElement[]).reduce(\n\t\t\t(\n\t\t\t\t{ items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n\t\t\t\tchild,\n\t\t\t) => {\n\t\t\t\tswitch (child.type) {\n\t\t\t\t\tcase MenuSearch:\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\titems,\n\t\t\t\t\t\t\tsearchElement: cloneElement(child, {\n\t\t\t\t\t\t\t\tonKeyDown: (e: KeyboardEvent) =>\n\t\t\t\t\t\t\t\t\thandleKeyboardInteractions(e, {\n\t\t\t\t\t\t\t\t\t\thandleDown: handleArrowDown,\n\t\t\t\t\t\t\t\t\t\thandleUp: handleArrowUp,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t};\n\t\t\t\t\tcase MenuItem:\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\titems: items.concat(\n\t\t\t\t\t\t\t\tchild.props.disabled\n\t\t\t\t\t\t\t\t\t? cloneElement(child, {\n\t\t\t\t\t\t\t\t\t\t\tclassName: cx(child.props.className, menuItemClassName),\n\t\t\t\t\t\t\t\t\t\t\tonClick: () => undefined,\n\t\t\t\t\t\t\t\t\t\t\tonKeyDown: () => undefined,\n\t\t\t\t\t\t\t\t\t\t\ttabIndex: -1,\n\t\t\t\t\t\t\t\t\t\t\tdisabled: true,\n\t\t\t\t\t\t\t\t\t })\n\t\t\t\t\t\t\t\t\t: cloneElement(child, {\n\t\t\t\t\t\t\t\t\t\t\tclassName: cx(child.props.className, menuItemClassName),\n\t\t\t\t\t\t\t\t\t\t\titem: child.props.item ?? items.length,\n\t\t\t\t\t\t\t\t\t\t\t// set focus on the first menu item if there is no search input, and set in the tab order\n\t\t\t\t\t\t\t\t\t\t\tonClick: chainEventHandlers(child.props.onClick, () => {\n\t\t\t\t\t\t\t\t\t\t\t\tonSelect?.(child.props.item ?? items.length);\n\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\tonKeyDown: (e: KeyboardEvent) =>\n\t\t\t\t\t\t\t\t\t\t\t\thandleKeyboardInteractions(e, {\n\t\t\t\t\t\t\t\t\t\t\t\t\thandleDown: handleArrowDown,\n\t\t\t\t\t\t\t\t\t\t\t\t\thandleUp: handleArrowUp,\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t }),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tsearchElement,\n\t\t\t\t\t\t};\n\t\t\t\t\tcase MenuDivider:\n\t\t\t\t\t\treturn { items: items.concat(child), searchElement };\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn { items, searchElement };\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ items: [], searchElement: null },\n\t\t);\n\t}, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n\tif (enableVirtualization) {\n\t\treturn (\n\t\t\t<MenuBase data-test-id={testId} isVirtual size={size}>\n\t\t\t\t<ItemVirtualizer<T>\n\t\t\t\t\titems={Children.toArray(reduceItems.items) as ReactElement[]}\n\t\t\t\t\tsearchElement={reduceItems.searchElement}\n\t\t\t\t\toverscan={overscan}\n\t\t\t\t\tmenuItemClassName={menuItemClassName}\n\t\t\t\t\tonSelect={onSelect}\n\t\t\t\t\titemHeight={itemHeight}\n\t\t\t\t\tfocusManager={focusManager}\n\t\t\t\t/>\n\t\t\t</MenuBase>\n\t\t);\n\t}\n\n\treturn (\n\t\t<MenuBase data-test-id={testId} size={size}>\n\t\t\t{reduceItems.searchElement}\n\t\t\t<MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n\t\t</MenuBase>\n\t);\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n\titems: ReactElement[] | null;\n\tsearchElement?: ReactElement | null;\n\tfocusManager?: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n\tconst {\n\t\toverscan,\n\t\tsearchElement,\n\t\titemHeight = 31.5,\n\t\tmenuItemClassName,\n\t\titems,\n\t\tfocusManager,\n\t\tonSelect,\n\t} = props;\n\n\tconst menuId = useRef(`menu-ctrl-${useId()}`);\n\n\tconst focusedItemIndex = useRef<number | null>(null);\n\tconst parentRef = useRef<HTMLDivElement | null>(null);\n\tconst searchRef = useRef<HTMLInputElement>();\n\n\tconst [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n\tconst hasSearch = !!searchElement;\n\n\tconst lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n\tconst rowVirtualizer = useVirtual({\n\t\tsize: items !== null ? items.length : 0,\n\t\tparentRef,\n\t\testimateSize: useCallback(() => itemHeight, [itemHeight]),\n\t\toverscan,\n\t});\n\n\tconst focusSearchBar = useCallback(() => {\n\t\trowVirtualizer.scrollToIndex(0);\n\t\tsearchRef.current?.focus?.();\n\t}, [rowVirtualizer]);\n\n\t/**\n\t * Scrolls to the menu item with the index provided and\n\t * then manually focuses it using a side effect in useEffect\n\t */\n\tconst focusMenuItem = useCallback(\n\t\t(index: number) => {\n\t\t\trowVirtualizer.scrollToIndex(index);\n\t\t\tsetNextFocusValue(index);\n\t\t},\n\t\t[rowVirtualizer],\n\t);\n\n\tconst handleKeyboardFocusInteraction = useCallback(\n\t\t(direction: 'next' | 'previous') => {\n\t\t\tif (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst nextIndex =\n\t\t\t\tdirection === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n\t\t\tconst shouldWrap =\n\t\t\t\t(direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n\t\t\t\t(direction === 'previous' && focusedItemIndex.current === 0);\n\t\t\tif (shouldWrap) {\n\t\t\t\t// we are at the end of the list so we will\n\t\t\t\t// scroll back to the beginning of the list\n\t\t\t\tif (hasSearch) {\n\t\t\t\t\tfocusSearchBar();\n\t\t\t\t} else {\n\t\t\t\t\t// if at end, wrap to beginning, else focus last item\n\t\t\t\t\tfocusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tswitch (direction) {\n\t\t\t\tcase 'next':\n\t\t\t\t\trowVirtualizer.scrollToIndex(nextIndex);\n\t\t\t\t\tfocusManager?.focusNext();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'previous':\n\t\t\t\t\trowVirtualizer.scrollToIndex(nextIndex);\n\t\t\t\t\tfocusManager?.focusPrevious();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t\t[focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer],\n\t);\n\n\tconst getItemProps = useCallback(\n\t\t(itemElem: ReactElement, index: number) => {\n\t\t\tconst childProps = itemElem.props as MenuItemProps<T>;\n\t\t\tswitch (itemElem.type) {\n\t\t\t\tcase MenuItem:\n\t\t\t\t\treturn {\n\t\t\t\t\t\tclassName: cx(childProps.className, menuItemClassName),\n\t\t\t\t\t\t// set focus on the first menu item if there is no search input, and set in the tab order\n\t\t\t\t\t\tonKeyDown: childProps.disabled\n\t\t\t\t\t\t\t? () => undefined\n\t\t\t\t\t\t\t: (e: KeyboardEvent) =>\n\t\t\t\t\t\t\t\t\thandleKeyboardFocusKeydown(e, {\n\t\t\t\t\t\t\t\t\t\thandleFocusBackward: handleKeyboardFocusInteraction,\n\t\t\t\t\t\t\t\t\t\thandleFocusForward: handleKeyboardFocusInteraction,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tonFocus: chainEventHandlers(childProps.onFocus, () => {\n\t\t\t\t\t\t\tfocusedItemIndex.current = index;\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tid: createItemId(index, menuId.current),\n\t\t\t\t\t\tonBlur: chainEventHandlers(childProps.onBlur, () => {\n\t\t\t\t\t\t\tfocusedItemIndex.current = null;\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tonClick: childProps.disabled\n\t\t\t\t\t\t\t? () => undefined\n\t\t\t\t\t\t\t: chainEventHandlers(childProps.onClick, () => {\n\t\t\t\t\t\t\t\t\tonSelect?.(childProps.item as T);\n\t\t\t\t\t\t\t }),\n\t\t\t\t\t} as MenuItemProps<T>;\n\t\t\t\tdefault:\n\t\t\t\t\treturn {};\n\t\t\t}\n\t\t},\n\t\t[handleKeyboardFocusInteraction, menuItemClassName, onSelect],\n\t);\n\n\tuseEffect(() => {\n\t\tif (nextFocusValue !== null) {\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tconst element = getNodeForIndex(nextFocusValue, menuId.current);\n\t\t\t\telement?.focus();\n\t\t\t});\n\t\t\tsetNextFocusValue(null);\n\t\t}\n\t}, [nextFocusValue]);\n\n\t/**\n\t * Calls handleFocusForward when the user is attempting to focus forward using\n\t * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n\t */\n\tconst handleKeyboardFocusKeydown = (\n\t\te: KeyboardEvent,\n\t\tcallbacks: Record<\n\t\t\t'handleFocusForward' | 'handleFocusBackward',\n\t\t\t(direction: 'next' | 'previous') => void\n\t\t>,\n\t) => {\n\t\tconst keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n\t\tif (keyOps.includes(e.key)) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tif ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n\t\t\t\tcallbacks.handleFocusBackward?.('previous');\n\t\t\t} else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n\t\t\t\tcallbacks.handleFocusForward?.('next');\n\t\t\t}\n\t\t}\n\t};\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n\tconst renderSearch = useMemo(\n\t\t() =>\n\t\t\tsearchElement\n\t\t\t\t? cloneElement(searchElement, {\n\t\t\t\t\t\tonKeyDown: (e: KeyboardEvent) =>\n\t\t\t\t\t\t\thandleKeyboardFocusKeydown(e, {\n\t\t\t\t\t\t\t\thandleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n\t\t\t\t\t\t\t\thandleFocusForward: () => focusMenuItem(0),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tref: searchRef,\n\t\t\t\t })\n\t\t\t\t: null,\n\t\t[searchElement, lastVirtualItemIndex, focusMenuItem],\n\t);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n\tconst renderItems = useMemo(\n\t\t() =>\n\t\t\trowVirtualizer.virtualItems.map((virtualRow) => {\n\t\t\t\tif (!items) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst elem = items[virtualRow.index];\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={virtualRow.index}\n\t\t\t\t\t\tref={virtualRow.measureRef}\n\t\t\t\t\t\trole=\"presentation\"\n\t\t\t\t\t\tclassName={styles['VirtualMenu-item']}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\ttransform: `translateY(${virtualRow.start}px)`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{cloneElement(elem, getItemProps(elem, virtualRow.index))}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}),\n\t\t[rowVirtualizer.virtualItems, items, getItemProps],\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t{renderSearch}\n\t\t\t<MenuItemList ref={parentRef} role=\"presentation\">\n\t\t\t\t<div\n\t\t\t\t\trole=\"presentation\"\n\t\t\t\t\tclassName={styles['VirtualMenu-item-list']}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\theight: `${rowVirtualizer.totalSize}px`,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{renderItems}\n\t\t\t\t</div>\n\t\t\t</MenuItemList>\n\t\t</>\n\t);\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/dist/utils.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAEzE,QAAA,MAAM,YAAY,UAAW,MAAM,MAAM,MAAM,WAA0B,CAAC;AAE1E,QAAA,MAAM,eAAe,UAAW,MAAM,GAAG,IAAI,UAAU,MAAM,
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAEzE,QAAA,MAAM,YAAY,UAAW,MAAM,MAAM,MAAM,WAA0B,CAAC;AAE1E,QAAA,MAAM,eAAe,UAAW,MAAM,GAAG,IAAI,UAAU,MAAM,uBACiB,CAAC;AAE/E,QAAA,MAAM,0BAA0B,UACxB,aAAa,6EAEmC,aAAa,KAAK,IAAI,WAc7E,CAAC;AAEF,QAAA,MAAM,kBAAkB,gBACT,CAAC,aAAa,cAAc,CAAC,GAAG,SAAS,CAAC,EAAE,aAClD,cAAc,SAIrB,CAAC;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@launchpad-ui/menu",
|
3
|
-
"version": "0.13.
|
3
|
+
"version": "0.13.5",
|
4
4
|
"status": "beta",
|
5
5
|
"publishConfig": {
|
6
6
|
"access": "public"
|
@@ -27,15 +27,15 @@
|
|
27
27
|
"source": "src/index.ts",
|
28
28
|
"dependencies": {
|
29
29
|
"@radix-ui/react-slot": "1.0.2",
|
30
|
-
"@react-aria/focus": "3.16.
|
31
|
-
"@react-aria/separator": "3.3.
|
30
|
+
"@react-aria/focus": "3.16.2",
|
31
|
+
"@react-aria/separator": "3.3.11",
|
32
32
|
"classix": "2.1.17",
|
33
33
|
"react-virtual": "2.10.4",
|
34
|
-
"@launchpad-ui/form": "~0.11.
|
35
|
-
"@launchpad-ui/icons": "~0.16.
|
36
|
-
"@launchpad-ui/popover": "~0.11.
|
37
|
-
"@launchpad-ui/tokens": "~0.9.
|
38
|
-
"@launchpad-ui/tooltip": "~0.9.
|
34
|
+
"@launchpad-ui/form": "~0.11.5",
|
35
|
+
"@launchpad-ui/icons": "~0.16.4",
|
36
|
+
"@launchpad-ui/popover": "~0.11.16",
|
37
|
+
"@launchpad-ui/tokens": "~0.9.7",
|
38
|
+
"@launchpad-ui/tooltip": "~0.9.5"
|
39
39
|
},
|
40
40
|
"peerDependencies": {
|
41
41
|
"react": "18.2.0",
|
@@ -48,7 +48,7 @@
|
|
48
48
|
"scripts": {
|
49
49
|
"build": "vite build -c ../../vite.config.mts && tsc --project tsconfig.build.json",
|
50
50
|
"clean": "rm -rf dist",
|
51
|
-
"lint": "
|
51
|
+
"lint": "stylelint '**/*.css' --ignore-path ../../.stylelintignore",
|
52
52
|
"test": "vitest run --coverage"
|
53
53
|
}
|
54
54
|
}
|