@launchpad-ui/menu 0.16.10 → 0.16.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@launchpad-ui/menu",
3
- "version": "0.16.10",
3
+ "version": "0.16.12",
4
4
  "description": "An element that presents a list of items a user can choose from.",
5
5
  "repository": "launchdarkly/launchpad-ui",
6
6
  "license": "Apache-2.0",
@@ -24,8 +24,8 @@
24
24
  "@react-aria/separator": "3.4.13",
25
25
  "classix": "2.2.0",
26
26
  "react-virtual": "2.10.4",
27
- "@launchpad-ui/form": "~0.15.10",
28
- "@launchpad-ui/icons": "~0.25.1",
27
+ "@launchpad-ui/form": "~0.15.12",
28
+ "@launchpad-ui/icons": "~0.25.3",
29
29
  "@launchpad-ui/popover": "~0.14.2",
30
30
  "@launchpad-ui/tokens": "~0.15.1",
31
31
  "@launchpad-ui/tooltip": "~0.12.2"
package/dist/Menu.d.ts DELETED
@@ -1,48 +0,0 @@
1
- import type { FocusManager } from '@react-aria/focus';
2
- import type { ReactElement, ReactNode } from 'react';
3
- type ControlledMenuProps<T> = {
4
- children: ReactNode;
5
- onSelect?: (item: T) => void;
6
- /**
7
- * Menus items are rendered using react-virtual for
8
- * additional rendering performance.
9
- */
10
- enableVirtualization?: boolean;
11
- /**
12
- * Class name to be applied to all MenuItem components
13
- * in the menu.
14
- */
15
- menuItemClassName?: string;
16
- /**
17
- * Sets the width of the menu. This is especially useful when using virtual items
18
- * since the width cannot be automatically set by the widest element.
19
- */
20
- size?: 'sm' | 'md' | 'lg' | 'xl';
21
- /**
22
- * Sets the number out of elements rendered outside of the view window
23
- * when using virtualization
24
- */
25
- overscan?: number;
26
- /**
27
- * Sets the height for each menu item when using virtualization.
28
- *
29
- */
30
- itemHeight?: number;
31
- 'data-test-id'?: string;
32
- };
33
- type MenuProps<T extends number | string> = ControlledMenuProps<T>;
34
- /**
35
- * @deprecated use `Menu` or `ListBox` from `@launchpad-ui/components` instead
36
- *
37
- * https://launchpad.launchdarkly.com/?path=/docs/components-collections-menu--docs
38
- */
39
- declare const Menu: <T extends number | string>(props: MenuProps<T>) => import("react/jsx-runtime").JSX.Element;
40
- type ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {
41
- items: ReactElement[] | null;
42
- searchElement?: ReactElement | null;
43
- focusManager?: FocusManager;
44
- };
45
- declare const ItemVirtualizer: <T extends number | string>(props: ItemVirtualizerProps<T>) => import("react/jsx-runtime").JSX.Element;
46
- export { Menu, ItemVirtualizer };
47
- export type { MenuProps, ItemVirtualizerProps };
48
- //# sourceMappingURL=Menu.d.ts.map
@@ -1 +0,0 @@
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;;;;GAIG;AACH,QAAA,MAAM,IAAI,GAAI,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,OAAO,SAAS,CAAC,CAAC,CAAC,4CAyH3D,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,GAAI,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,OAAO,oBAAoB,CAAC,CAAC,CAAC,4CAiNjF,CAAC;AAEF,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;AACjC,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC"}
@@ -1,10 +0,0 @@
1
- import type { ComponentPropsWithRef } from 'react';
2
- import type { MenuProps } from './Menu';
3
- type MenuBaseProps = ComponentPropsWithRef<'div'> & {
4
- isVirtual?: boolean;
5
- size?: MenuProps<string>['size'];
6
- };
7
- declare const MenuBase: import("react").ForwardRefExoticComponent<Omit<MenuBaseProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
8
- export { MenuBase };
9
- export type { MenuBaseProps };
10
- //# sourceMappingURL=MenuBase.d.ts.map
@@ -1 +0,0 @@
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,10 +0,0 @@
1
- import type { SeparatorProps } from '@react-aria/separator';
2
- import type { RefObject } from 'react';
3
- type MenuDividerProps = SeparatorProps & {
4
- innerRef?: RefObject<HTMLDivElement>;
5
- 'data-test-id'?: string;
6
- };
7
- declare const MenuDivider: ({ elementType, orientation, innerRef, "data-test-id": testId, }: MenuDividerProps) => import("react/jsx-runtime").JSX.Element;
8
- export { MenuDivider };
9
- export type { MenuDividerProps };
10
- //# sourceMappingURL=MenuDivider.d.ts.map
@@ -1 +0,0 @@
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,GAAI,iEAKlB,gBAAgB,4CAclB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,31 +0,0 @@
1
- import type { IconProps } from '@launchpad-ui/icons';
2
- import type { PopoverPlacement } from '@launchpad-ui/popover';
3
- import type { ComponentPropsWithRef, ElementType, JSX, PropsWithRef, ReactElement } from 'react';
4
- import { Tooltip } from '@launchpad-ui/tooltip';
5
- type Merge<T, U> = Omit<T, keyof U> & U;
6
- type PropsWithComponent<P, T extends ElementType> = P & {
7
- component?: T;
8
- };
9
- type PolymorphicPropsWithRef<P, T extends ElementType> = Merge<T extends keyof JSX.IntrinsicElements ? PropsWithRef<JSX.IntrinsicElements[T]> : ComponentPropsWithRef<T>, PropsWithComponent<P, T>>;
10
- type MenuItemOwnProps = {
11
- isHighlighted?: boolean;
12
- icon?: ReactElement<IconProps>;
13
- disabled?: boolean;
14
- nested?: boolean;
15
- groupHeader?: boolean;
16
- tooltip?: string | ReactElement;
17
- tooltipOptions?: ComponentPropsWithRef<typeof Tooltip>;
18
- tooltipPlacement?: PopoverPlacement;
19
- asChild?: boolean;
20
- 'data-test-id'?: string;
21
- };
22
- declare const defaultElement = "button";
23
- type MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<(MenuItemOwnProps & {
24
- item: P;
25
- }) | (MenuItemOwnProps & {
26
- item?: undefined;
27
- }), T>;
28
- declare const MenuItem: <P, T extends ElementType = typeof defaultElement>({ ...props }: MenuItemProps<P, T>) => import("react/jsx-runtime").JSX.Element;
29
- export { MenuItem };
30
- export type { MenuItemProps };
31
- //# sourceMappingURL=MenuItem.d.ts.map
@@ -1 +0,0 @@
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,GAAG,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAEjG,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,GAAI,CAAC,EAAE,CAAC,SAAS,WAAW,GAAG,OAAO,cAAc,EAAE,cAEjE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,4CAuErB,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -1,6 +0,0 @@
1
- import type { ComponentPropsWithRef } from 'react';
2
- type MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;
3
- declare const MenuItemList: import("react").ForwardRefExoticComponent<Omit<MenuItemListProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
4
- export { MenuItemList };
5
- export type { MenuItemListProps };
6
- //# sourceMappingURL=MenuItemList.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MenuItemList.d.ts","sourceRoot":"","sources":["../src/MenuItemList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAMnD,KAAK,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,CAAC;AAEzE,QAAA,MAAM,YAAY,2HAIhB,CAAC;AAIH,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1,13 +0,0 @@
1
- import type { ChangeEvent } from 'react';
2
- type MenuSearchProps = {
3
- ariaLabel?: string;
4
- value?: string;
5
- id?: string;
6
- placeholder?: string;
7
- onChange?(event: ChangeEvent<HTMLInputElement>): void;
8
- 'data-test-id'?: string;
9
- };
10
- declare const MenuSearch: import("react").ForwardRefExoticComponent<MenuSearchProps & import("react").RefAttributes<HTMLInputElement>>;
11
- export { MenuSearch };
12
- export type { MenuSearchProps };
13
- //# sourceMappingURL=MenuSearch.d.ts.map
@@ -1 +0,0 @@
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.d.ts DELETED
@@ -1,13 +0,0 @@
1
- export type { MenuProps } from './Menu';
2
- export type { MenuBaseProps } from './MenuBase';
3
- export type { MenuDividerProps } from './MenuDivider';
4
- export type { MenuItemProps } from './MenuItem';
5
- export type { MenuItemListProps } from './MenuItemList';
6
- export type { MenuSearchProps } from './MenuSearch';
7
- export { Menu } from './Menu';
8
- export { MenuBase } from './MenuBase';
9
- export { MenuDivider } from './MenuDivider';
10
- export { MenuItem } from './MenuItem';
11
- export { MenuItemList } from './MenuItemList';
12
- export { MenuSearch } from './MenuSearch';
13
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.es.js DELETED
@@ -1,383 +0,0 @@
1
- import './style.css';
2
- import { FocusRing, useFocusManager } from "@react-aria/focus";
3
- import { cx } from "classix";
4
- import { Children, cloneElement, forwardRef, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
5
- import { useVirtual } from "react-virtual";
6
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
- import { useSeparator } from "@react-aria/separator";
8
- import { Tooltip } from "@launchpad-ui/tooltip";
9
- import { Slot } from "@radix-ui/react-slot";
10
- import { TextField } from "@launchpad-ui/form";
11
- const Menu$1 = "C73R2W_Menu";
12
- var Menu_module_default = {
13
- "has-focus": "C73R2W_has-focus",
14
- "is-highlighted": "C73R2W_is-highlighted",
15
- Menu: Menu$1,
16
- "Menu--isVirtual": "C73R2W_Menu--isVirtual",
17
- "Menu-divider": "C73R2W_Menu-divider",
18
- "Menu-item": "C73R2W_Menu-item",
19
- "Menu-item--header": "C73R2W_Menu-item--header",
20
- "Menu-item--nested": "C73R2W_Menu-item--nested",
21
- "Menu-item-icon": "C73R2W_Menu-item-icon",
22
- "Menu-item-list": "C73R2W_Menu-item-list",
23
- "Menu-search": "C73R2W_Menu-search",
24
- "Menu-search-hidden-placeholder": "C73R2W_Menu-search-hidden-placeholder",
25
- "MenuSize--lg": "C73R2W_MenuSize--lg",
26
- "MenuSize--md": "C73R2W_MenuSize--md",
27
- "MenuSize--sm": "C73R2W_MenuSize--sm",
28
- "MenuSize--xl": "C73R2W_MenuSize--xl",
29
- "VirtualMenu-item": "C73R2W_VirtualMenu-item",
30
- "VirtualMenu-item-list": "C73R2W_VirtualMenu-item-list"
31
- };
32
- const MenuBase = /* @__PURE__ */ forwardRef(({ children, size, isVirtual,...props }, ref) => {
33
- const classes = cx(Menu_module_default.Menu, isVirtual && Menu_module_default["Menu--isVirtual"], size && Menu_module_default[`MenuSize--${size}`]);
34
- return /* @__PURE__ */ jsx("div", {
35
- ...props,
36
- role: "menu",
37
- className: classes,
38
- ref,
39
- children
40
- });
41
- });
42
- MenuBase.displayName = "MenuBase";
43
- const MenuDivider = ({ elementType = "div", orientation, innerRef, "data-test-id": testId = "menu-divider" }) => {
44
- const { separatorProps } = useSeparator({
45
- orientation,
46
- elementType
47
- });
48
- return /* @__PURE__ */ jsx("div", {
49
- ...separatorProps,
50
- "data-test-id": testId,
51
- ref: innerRef,
52
- className: Menu_module_default["Menu-divider"]
53
- });
54
- };
55
- const defaultElement = "button";
56
- const MenuItem = ({ ...props }) => {
57
- const { component, children, isHighlighted, icon, nested, groupHeader, item, disabled, className, tooltip, role = "menuitem", tooltipPlacement, onKeyDown, tooltipOptions, asChild, "data-test-id": testId = "menu-item",...rest } = props;
58
- const Component = component || (asChild ? Slot : defaultElement);
59
- const renderIcon = icon && /* @__PURE__ */ cloneElement(icon, { size: "small" });
60
- const renderedItem = /* @__PURE__ */ jsx(FocusRing, {
61
- focusRingClass: Menu_module_default["has-focus"],
62
- children: /* @__PURE__ */ jsx(Component, {
63
- ...rest,
64
- disabled,
65
- "aria-disabled": disabled ? disabled : void 0,
66
- className: cx(Menu_module_default["Menu-item"], className, isHighlighted && Menu_module_default["is-highlighted"], nested && Menu_module_default["Menu-item--nested"], groupHeader && Menu_module_default["Menu-item--header"]),
67
- "data-test-id": testId,
68
- role,
69
- onKeyDown,
70
- children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [icon && /* @__PURE__ */ jsx("span", {
71
- className: Menu_module_default["Menu-item-icon"],
72
- children: renderIcon
73
- }), children] })
74
- })
75
- });
76
- if (tooltip) return /* @__PURE__ */ jsx(Tooltip, {
77
- content: tooltip,
78
- rootElementStyle: { display: "block" },
79
- allowBoundaryElementOverflow: true,
80
- placement: tooltipPlacement ? tooltipPlacement : "bottom",
81
- ...tooltipOptions || {},
82
- children: renderedItem
83
- });
84
- return renderedItem;
85
- };
86
- const MenuItemList = /* @__PURE__ */ forwardRef(({ children,...rest }, ref) => /* @__PURE__ */ jsx("div", {
87
- ...rest,
88
- ref,
89
- "data-test-id": "menu-item-list",
90
- className: Menu_module_default["Menu-item-list"],
91
- children
92
- }));
93
- MenuItemList.displayName = "MenuItemList";
94
- const MenuSearch = /* @__PURE__ */ forwardRef((props, ref) => {
95
- const { ariaLabel, placeholder, id, "data-test-id": testId = "menu-search",...finalProps } = props;
96
- return /* @__PURE__ */ jsx("div", {
97
- className: Menu_module_default["Menu-search"],
98
- children: /* @__PURE__ */ jsx(TextField, {
99
- ...finalProps,
100
- ref,
101
- className: Menu_module_default["Menu-search-input"],
102
- tiny: true,
103
- id,
104
- type: "search",
105
- "data-test-id": testId,
106
- autoComplete: "off",
107
- placeholder,
108
- "aria-label": ariaLabel || "Search"
109
- })
110
- });
111
- });
112
- MenuSearch.displayName = "MenuSearch";
113
- const createItemId = (index, id) => `${id}-item-${index}`;
114
- const getNodeForIndex = (index, menuId) => index === null ? index : document.getElementById(createItemId(index, menuId));
115
- const handleKeyboardInteractions = (event, keyHandlers) => {
116
- const ops = {
117
- ArrowUp: keyHandlers.handleUp,
118
- ArrowDown: keyHandlers.handleDown,
119
- Enter: keyHandlers.handleEnter
120
- };
121
- if (ops[event.key]) {
122
- event.preventDefault();
123
- ops[event.key]?.call(globalThis, event);
124
- }
125
- };
126
- const chainEventHandlers = (...handlers) => (event) => {
127
- for (const h of handlers) typeof h === "function" && h(event);
128
- };
129
- /**
130
- * @deprecated use `Menu` or `ListBox` from `@launchpad-ui/components` instead
131
- *
132
- * https://launchpad.launchdarkly.com/?path=/docs/components-collections-menu--docs
133
- */
134
- const Menu = (props) => {
135
- const { children, menuItemClassName, onSelect, enableVirtualization, itemHeight, size, overscan = 1, "data-test-id": testId = "menu" } = props;
136
- const focusManager = useFocusManager();
137
- const handleArrowDown = useCallback(() => {
138
- focusManager?.focusNext({ wrap: true });
139
- }, [focusManager]);
140
- const handleArrowUp = useCallback(() => {
141
- focusManager?.focusPrevious({ wrap: true });
142
- }, [focusManager]);
143
- const reduceItems = useMemo(() => {
144
- const childrenProps = Children.toArray(children);
145
- if (enableVirtualization) {
146
- let searchElem = null;
147
- let elements = [];
148
- for (const child of childrenProps) switch (child.type) {
149
- case MenuSearch:
150
- searchElem = child;
151
- break;
152
- case MenuItem:
153
- case MenuDivider:
154
- elements = elements.concat(child);
155
- break;
156
- default: break;
157
- }
158
- return {
159
- items: elements,
160
- searchElement: searchElem
161
- };
162
- }
163
- return childrenProps.reduce(({ items, searchElement }, child) => {
164
- switch (child.type) {
165
- case MenuSearch: return {
166
- items,
167
- searchElement: /* @__PURE__ */ cloneElement(child, { onKeyDown: (e) => handleKeyboardInteractions(e, {
168
- handleDown: handleArrowDown,
169
- handleUp: handleArrowUp
170
- }) })
171
- };
172
- case MenuItem: return {
173
- items: items.concat(child.props.disabled ? /* @__PURE__ */ cloneElement(child, {
174
- className: cx(child.props.className, menuItemClassName),
175
- onClick: () => void 0,
176
- onKeyDown: () => void 0,
177
- tabIndex: -1,
178
- disabled: true
179
- }) : /* @__PURE__ */ cloneElement(child, {
180
- className: cx(child.props.className, menuItemClassName),
181
- item: child.props.item ?? items.length,
182
- onClick: chainEventHandlers(child.props.onClick, () => {
183
- onSelect?.(child.props.item ?? items.length);
184
- }),
185
- onKeyDown: (e) => handleKeyboardInteractions(e, {
186
- handleDown: handleArrowDown,
187
- handleUp: handleArrowUp
188
- })
189
- })),
190
- searchElement
191
- };
192
- case MenuDivider: return {
193
- items: items.concat(child),
194
- searchElement
195
- };
196
- default: return {
197
- items,
198
- searchElement
199
- };
200
- }
201
- }, {
202
- items: [],
203
- searchElement: null
204
- });
205
- }, [
206
- children,
207
- enableVirtualization,
208
- menuItemClassName,
209
- handleArrowDown,
210
- handleArrowUp,
211
- onSelect
212
- ]);
213
- if (enableVirtualization) return /* @__PURE__ */ jsx(MenuBase, {
214
- "data-test-id": testId,
215
- isVirtual: true,
216
- size,
217
- children: /* @__PURE__ */ jsx(ItemVirtualizer, {
218
- items: Children.toArray(reduceItems.items),
219
- searchElement: reduceItems.searchElement,
220
- overscan,
221
- menuItemClassName,
222
- onSelect,
223
- itemHeight,
224
- focusManager
225
- })
226
- });
227
- return /* @__PURE__ */ jsxs(MenuBase, {
228
- "data-test-id": testId,
229
- size,
230
- children: [reduceItems.searchElement, /* @__PURE__ */ jsx(MenuItemList, {
231
- role: "presentation",
232
- children: reduceItems.items
233
- })]
234
- });
235
- };
236
- const ItemVirtualizer = (props) => {
237
- const { overscan, searchElement, itemHeight = 31.5, menuItemClassName, items, focusManager, onSelect } = props;
238
- const menuId = useRef(`menu-ctrl-${useId()}`);
239
- const focusedItemIndex = useRef(null);
240
- const parentRef = useRef(null);
241
- const searchRef = useRef(null);
242
- const [nextFocusValue, setNextFocusValue] = useState(null);
243
- const hasSearch = !!searchElement;
244
- const lastVirtualItemIndex = items ? items.length - 1 : 0;
245
- const rowVirtualizer = useVirtual({
246
- size: items !== null ? items.length : 0,
247
- parentRef,
248
- estimateSize: useCallback(() => itemHeight, [itemHeight]),
249
- overscan
250
- });
251
- const focusSearchBar = useCallback(() => {
252
- rowVirtualizer.scrollToIndex(0);
253
- searchRef.current?.focus?.();
254
- }, [rowVirtualizer]);
255
- /**
256
- * Scrolls to the menu item with the index provided and
257
- * then manually focuses it using a side effect in useEffect
258
- */
259
- const focusMenuItem = useCallback((index) => {
260
- rowVirtualizer.scrollToIndex(index);
261
- setNextFocusValue(index);
262
- }, [rowVirtualizer]);
263
- const handleKeyboardFocusInteraction = useCallback((direction) => {
264
- if (focusedItemIndex.current === null || focusedItemIndex.current === void 0) return;
265
- const nextIndex = direction === "next" ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;
266
- const shouldWrap = direction === "next" && focusedItemIndex.current === lastVirtualItemIndex || direction === "previous" && focusedItemIndex.current === 0;
267
- if (shouldWrap) {
268
- if (hasSearch) focusSearchBar();
269
- else focusMenuItem(direction === "next" ? 0 : lastVirtualItemIndex);
270
- return;
271
- }
272
- switch (direction) {
273
- case "next":
274
- rowVirtualizer.scrollToIndex(nextIndex);
275
- focusManager?.focusNext();
276
- break;
277
- case "previous":
278
- rowVirtualizer.scrollToIndex(nextIndex);
279
- focusManager?.focusPrevious();
280
- break;
281
- default: break;
282
- }
283
- }, [
284
- focusManager,
285
- focusMenuItem,
286
- focusSearchBar,
287
- hasSearch,
288
- lastVirtualItemIndex,
289
- rowVirtualizer
290
- ]);
291
- const getItemProps = useCallback((itemElem, index) => {
292
- const childProps = itemElem.props;
293
- switch (itemElem.type) {
294
- case MenuItem: return {
295
- className: cx(childProps.className, menuItemClassName),
296
- onKeyDown: childProps.disabled ? () => void 0 : (e) => handleKeyboardFocusKeydown(e, {
297
- handleFocusBackward: handleKeyboardFocusInteraction,
298
- handleFocusForward: handleKeyboardFocusInteraction
299
- }),
300
- onFocus: chainEventHandlers(childProps.onFocus, () => {
301
- focusedItemIndex.current = index;
302
- }),
303
- id: createItemId(index, menuId.current),
304
- onBlur: chainEventHandlers(childProps.onBlur, () => {
305
- focusedItemIndex.current = null;
306
- }),
307
- onClick: childProps.disabled ? () => void 0 : chainEventHandlers(childProps.onClick, () => {
308
- onSelect?.(childProps.item);
309
- })
310
- };
311
- default: return {};
312
- }
313
- }, [
314
- handleKeyboardFocusInteraction,
315
- menuItemClassName,
316
- onSelect
317
- ]);
318
- useEffect(() => {
319
- if (nextFocusValue !== null) {
320
- requestAnimationFrame(() => {
321
- const element = getNodeForIndex(nextFocusValue, menuId.current);
322
- element?.focus();
323
- });
324
- setNextFocusValue(null);
325
- }
326
- }, [nextFocusValue]);
327
- /**
328
- * Calls handleFocusForward when the user is attempting to focus forward using
329
- * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.
330
- */
331
- const handleKeyboardFocusKeydown = (e, callbacks) => {
332
- const keyOps = [
333
- "Tab",
334
- "ArrowUp",
335
- "ArrowDown"
336
- ];
337
- if (keyOps.includes(e.key)) {
338
- e.preventDefault();
339
- e.stopPropagation();
340
- if (e.key === "Tab" && e.shiftKey || e.key === "ArrowUp") callbacks.handleFocusBackward?.("previous");
341
- else if (e.key === "ArrowDown" || e.key === "Tab") callbacks.handleFocusForward?.("next");
342
- }
343
- };
344
- const renderSearch = useMemo(() => searchElement ? /* @__PURE__ */ cloneElement(searchElement, {
345
- onKeyDown: (e) => handleKeyboardFocusKeydown(e, {
346
- handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),
347
- handleFocusForward: () => focusMenuItem(0)
348
- }),
349
- ref: searchRef
350
- }) : null, [
351
- searchElement,
352
- lastVirtualItemIndex,
353
- focusMenuItem
354
- ]);
355
- const renderItems = useMemo(() => rowVirtualizer.virtualItems.map((virtualRow) => {
356
- if (!items) return null;
357
- const elem = items[virtualRow.index];
358
- return /* @__PURE__ */ jsx("div", {
359
- ref: virtualRow.measureRef,
360
- role: "presentation",
361
- className: Menu_module_default["VirtualMenu-item"],
362
- style: { transform: `translateY(${virtualRow.start}px)` },
363
- children: /* @__PURE__ */ cloneElement(elem, getItemProps(elem, virtualRow.index))
364
- }, virtualRow.index);
365
- }), [
366
- rowVirtualizer.virtualItems,
367
- items,
368
- getItemProps
369
- ]);
370
- return /* @__PURE__ */ jsxs(Fragment, { children: [renderSearch, /* @__PURE__ */ jsx(MenuItemList, {
371
- ref: parentRef,
372
- role: "presentation",
373
- children: /* @__PURE__ */ jsx("div", {
374
- role: "presentation",
375
- className: Menu_module_default["VirtualMenu-item-list"],
376
- style: { height: `${rowVirtualizer.totalSize}px` },
377
- children: renderItems
378
- })
379
- })] });
380
- };
381
- export { Menu, MenuBase, MenuDivider, MenuItem, MenuItemList, MenuSearch };
382
-
383
- //# sourceMappingURL=index.es.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.es.js","names":["Component: ElementType","index: number","id: string","index: number | null","menuId: string","event: KeyboardEvent","keyHandlers: Partial<\n\t\tRecord<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n\t>","event: SyntheticEvent","props: MenuProps<T>","elements: ReactElement[]","child: ReactElement<any>","e: KeyboardEvent","props: ItemVirtualizerProps<T>","index: number","direction: 'next' | 'previous'","itemElem: ReactElement","callbacks: Record<\n\t\t\t'handleFocusForward' | 'handleFocusBackward',\n\t\t\t(direction: 'next' | 'previous') => void\n\t\t>"],"sources":["../src/styles/Menu.module.css","../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":[".Menu-item {\n\tbackground-color: transparent;\n\tborder-radius: var(--lp-border-radius-regular);\n\tborder-width: var(--lp-border-width-100);\n\tcolor: var(--lp-color-text-ui-primary-base);\n\tcursor: pointer;\n\tdisplay: block;\n\tfont: var(--lp-text-label-1-medium);\n\toutline: none;\n\toverflow: hidden;\n\tpadding-inline: var(--lp-spacing-300);\n\tpadding-block: var(--lp-spacing-200);\n\tposition: relative;\n\ttext-align: left;\n\ttext-decoration: none;\n\ttext-overflow: ellipsis;\n\tuser-select: none;\n\twhite-space: nowrap;\n\twidth: 100%;\n}\n\n.Menu-item-list {\n\tmax-height: 55vh;\n\tmin-width: 7.5rem;\n\toverflow: auto;\n\tpadding: var(--lp-spacing-200);\n}\n\n.Menu .Menu-item:not([disabled]):not([aria-disabled]):not(.Menu-item--header) {\n\t&:active {\n\t\ttext-decoration: none;\n\t\tbackground-color: var(--lp-color-bg-interactive-secondary-active);\n\t}\n\n\t&:hover:not(:active):not(.has-focus) {\n\t\tbackground-color: var(--lp-color-bg-interactive-secondary-hover);\n\t}\n\n\t&.has-focus {\n\t\tbackground-color: var(--lp-color-bg-interactive-secondary-hover);\n\t\tbox-shadow: inset 0 0 0 2px var(--lp-color-shadow-interactive-focus);\n\t}\n}\n\n.Menu {\n\tbackground: var(--lp-color-bg-overlay-secondary);\n\tborder-radius: var(--lp-border-radius-medium);\n\tfont-family: var(--lp-font-family-base);\n\n\t&:focus {\n\t\toutline: none;\n\t}\n\n\t/* Override our link styles for link component */\n\t& a.Menu-item {\n\t\t&:focus:not(:hover):not(.has-focus) {\n\t\t\ttext-decoration: none;\n\t\t\tbox-shadow: none;\n\t\t}\n\n\t\t/* Ensures that links that are disabled don't show active styles */\n\t\t&:active[disabled],\n\t\t&:active[aria-disabled] {\n\t\t\ttext-decoration: none;\n\t\t\tcolor: var(--lp-color-text-interactive-disabled);\n\t\t}\n\t}\n}\n\n.Menu-item--nested {\n\tpadding-left: 2.5rem;\n}\n\n.Menu-item--header {\n\tfont: var(--lp-text-small-1-regular);\n\tcolor: var(--lp-color-text-ui-tertiary);\n}\n\n.Menu-item-icon {\n\tmargin-right: var(--lp-spacing-300);\n}\n\n.Menu-item :global(.Gravatar) {\n\tmargin-right: 0.3125rem;\n}\n\n.Menu-item.is-highlighted {\n\tbackground-color: var(--lp-color-bg-interactive-secondary-hover);\n}\n\n.Menu-item[aria-disabled],\n.Menu-item[disabled] {\n\tcolor: var(--lp-color-text-interactive-disabled);\n\tcursor: not-allowed;\n}\n\n.Menu-divider {\n\tborder-top: 1px solid var(--lp-color-border-ui-secondary);\n\tmargin: var(--lp-spacing-200) 0;\n}\n\n.Menu-search {\n\tborder-bottom: 1px solid var(--lp-color-border-ui-secondary);\n\tpadding: var(--lp-spacing-300);\n}\n\n[class*='_Popover-content'] .Menu-search {\n\twidth: 100%;\n\n\t/* Removing anything that could give it some height */\n\t& .Menu-search-hidden-placeholder {\n\t\tpadding-top: 0;\n\t\tpadding-bottom: 0;\n\t\theight: 0;\n\t\tborder: none;\n\t\tvisibility: hidden;\n\t}\n}\n\n.Menu--isVirtual {\n\tdisplay: flex;\n\talign-items: stretch;\n\tflex-direction: column;\n}\n\n.MenuSize--xl {\n\twidth: 20rem;\n}\n\n.MenuSize--lg {\n\twidth: 15rem;\n}\n\n.MenuSize--md {\n\twidth: 10rem;\n}\n\n.MenuSize--sm {\n\twidth: 7.5rem;\n}\n\n.VirtualMenu-item-list {\n\twidth: 100%;\n\tposition: relative;\n}\n\n.VirtualMenu-item {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n}\n","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, JSX, 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: ignore\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: ignore\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\n/**\n * @deprecated use `Menu` or `ListBox` from `@launchpad-ui/components` instead\n *\n * https://launchpad.launchdarkly.com/?path=/docs/components-collections-menu--docs\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\t// biome-ignore lint/suspicious/noExplicitAny: ignore\n\t\t\t\tchild: ReactElement<any>,\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\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\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 | null>(null);\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\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: ignore\n\tconst renderSearch = useMemo(\n\t\t() =>\n\t\t\tsearchElement\n\t\t\t\t? // biome-ignore lint/suspicious/noExplicitAny: ignore\n\t\t\t\t\tcloneElement(searchElement as ReactElement<any>, {\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\t})\n\t\t\t\t: null,\n\t\t[searchElement, lastVirtualItemIndex, focusMenuItem],\n\t);\n\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"],"mappings":"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"}
package/dist/index.js DELETED
@@ -1,408 +0,0 @@
1
- require('./style.css');
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
- key = keys[i];
11
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
- get: ((k) => from[k]).bind(null, key),
13
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
- });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
- value: mod,
20
- enumerable: true
21
- }) : target, mod));
22
- const __react_aria_focus = __toESM(require("@react-aria/focus"));
23
- const classix = __toESM(require("classix"));
24
- const react = __toESM(require("react"));
25
- const react_virtual = __toESM(require("react-virtual"));
26
- const react_jsx_runtime = __toESM(require("react/jsx-runtime"));
27
- const __react_aria_separator = __toESM(require("@react-aria/separator"));
28
- const __launchpad_ui_tooltip = __toESM(require("@launchpad-ui/tooltip"));
29
- const __radix_ui_react_slot = __toESM(require("@radix-ui/react-slot"));
30
- const __launchpad_ui_form = __toESM(require("@launchpad-ui/form"));
31
- const Menu$1 = "C73R2W_Menu";
32
- var Menu_module_default = {
33
- "has-focus": "C73R2W_has-focus",
34
- "is-highlighted": "C73R2W_is-highlighted",
35
- Menu: Menu$1,
36
- "Menu--isVirtual": "C73R2W_Menu--isVirtual",
37
- "Menu-divider": "C73R2W_Menu-divider",
38
- "Menu-item": "C73R2W_Menu-item",
39
- "Menu-item--header": "C73R2W_Menu-item--header",
40
- "Menu-item--nested": "C73R2W_Menu-item--nested",
41
- "Menu-item-icon": "C73R2W_Menu-item-icon",
42
- "Menu-item-list": "C73R2W_Menu-item-list",
43
- "Menu-search": "C73R2W_Menu-search",
44
- "Menu-search-hidden-placeholder": "C73R2W_Menu-search-hidden-placeholder",
45
- "MenuSize--lg": "C73R2W_MenuSize--lg",
46
- "MenuSize--md": "C73R2W_MenuSize--md",
47
- "MenuSize--sm": "C73R2W_MenuSize--sm",
48
- "MenuSize--xl": "C73R2W_MenuSize--xl",
49
- "VirtualMenu-item": "C73R2W_VirtualMenu-item",
50
- "VirtualMenu-item-list": "C73R2W_VirtualMenu-item-list"
51
- };
52
- const MenuBase = /* @__PURE__ */ (0, react.forwardRef)(({ children, size, isVirtual,...props }, ref) => {
53
- const classes = (0, classix.cx)(Menu_module_default.Menu, isVirtual && Menu_module_default["Menu--isVirtual"], size && Menu_module_default[`MenuSize--${size}`]);
54
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
55
- ...props,
56
- role: "menu",
57
- className: classes,
58
- ref,
59
- children
60
- });
61
- });
62
- MenuBase.displayName = "MenuBase";
63
- const MenuDivider = ({ elementType = "div", orientation, innerRef, "data-test-id": testId = "menu-divider" }) => {
64
- const { separatorProps } = (0, __react_aria_separator.useSeparator)({
65
- orientation,
66
- elementType
67
- });
68
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
69
- ...separatorProps,
70
- "data-test-id": testId,
71
- ref: innerRef,
72
- className: Menu_module_default["Menu-divider"]
73
- });
74
- };
75
- const defaultElement = "button";
76
- const MenuItem = ({ ...props }) => {
77
- const { component, children, isHighlighted, icon, nested, groupHeader, item, disabled, className, tooltip, role = "menuitem", tooltipPlacement, onKeyDown, tooltipOptions, asChild, "data-test-id": testId = "menu-item",...rest } = props;
78
- const Component = component || (asChild ? __radix_ui_react_slot.Slot : defaultElement);
79
- const renderIcon = icon && /* @__PURE__ */ (0, react.cloneElement)(icon, { size: "small" });
80
- const renderedItem = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__react_aria_focus.FocusRing, {
81
- focusRingClass: Menu_module_default["has-focus"],
82
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
83
- ...rest,
84
- disabled,
85
- "aria-disabled": disabled ? disabled : void 0,
86
- className: (0, classix.cx)(Menu_module_default["Menu-item"], className, isHighlighted && Menu_module_default["is-highlighted"], nested && Menu_module_default["Menu-item--nested"], groupHeader && Menu_module_default["Menu-item--header"]),
87
- "data-test-id": testId,
88
- role,
89
- onKeyDown,
90
- children: asChild ? children : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
91
- className: Menu_module_default["Menu-item-icon"],
92
- children: renderIcon
93
- }), children] })
94
- })
95
- });
96
- if (tooltip) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__launchpad_ui_tooltip.Tooltip, {
97
- content: tooltip,
98
- rootElementStyle: { display: "block" },
99
- allowBoundaryElementOverflow: true,
100
- placement: tooltipPlacement ? tooltipPlacement : "bottom",
101
- ...tooltipOptions || {},
102
- children: renderedItem
103
- });
104
- return renderedItem;
105
- };
106
- const MenuItemList = /* @__PURE__ */ (0, react.forwardRef)(({ children,...rest }, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
107
- ...rest,
108
- ref,
109
- "data-test-id": "menu-item-list",
110
- className: Menu_module_default["Menu-item-list"],
111
- children
112
- }));
113
- MenuItemList.displayName = "MenuItemList";
114
- const MenuSearch = /* @__PURE__ */ (0, react.forwardRef)((props, ref) => {
115
- const { ariaLabel, placeholder, id, "data-test-id": testId = "menu-search",...finalProps } = props;
116
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
117
- className: Menu_module_default["Menu-search"],
118
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__launchpad_ui_form.TextField, {
119
- ...finalProps,
120
- ref,
121
- className: Menu_module_default["Menu-search-input"],
122
- tiny: true,
123
- id,
124
- type: "search",
125
- "data-test-id": testId,
126
- autoComplete: "off",
127
- placeholder,
128
- "aria-label": ariaLabel || "Search"
129
- })
130
- });
131
- });
132
- MenuSearch.displayName = "MenuSearch";
133
- const createItemId = (index, id) => `${id}-item-${index}`;
134
- const getNodeForIndex = (index, menuId) => index === null ? index : document.getElementById(createItemId(index, menuId));
135
- const handleKeyboardInteractions = (event, keyHandlers) => {
136
- const ops = {
137
- ArrowUp: keyHandlers.handleUp,
138
- ArrowDown: keyHandlers.handleDown,
139
- Enter: keyHandlers.handleEnter
140
- };
141
- if (ops[event.key]) {
142
- event.preventDefault();
143
- ops[event.key]?.call(globalThis, event);
144
- }
145
- };
146
- const chainEventHandlers = (...handlers) => (event) => {
147
- for (const h of handlers) typeof h === "function" && h(event);
148
- };
149
- /**
150
- * @deprecated use `Menu` or `ListBox` from `@launchpad-ui/components` instead
151
- *
152
- * https://launchpad.launchdarkly.com/?path=/docs/components-collections-menu--docs
153
- */
154
- const Menu = (props) => {
155
- const { children, menuItemClassName, onSelect, enableVirtualization, itemHeight, size, overscan = 1, "data-test-id": testId = "menu" } = props;
156
- const focusManager = (0, __react_aria_focus.useFocusManager)();
157
- const handleArrowDown = (0, react.useCallback)(() => {
158
- focusManager?.focusNext({ wrap: true });
159
- }, [focusManager]);
160
- const handleArrowUp = (0, react.useCallback)(() => {
161
- focusManager?.focusPrevious({ wrap: true });
162
- }, [focusManager]);
163
- const reduceItems = (0, react.useMemo)(() => {
164
- const childrenProps = react.Children.toArray(children);
165
- if (enableVirtualization) {
166
- let searchElem = null;
167
- let elements = [];
168
- for (const child of childrenProps) switch (child.type) {
169
- case MenuSearch:
170
- searchElem = child;
171
- break;
172
- case MenuItem:
173
- case MenuDivider:
174
- elements = elements.concat(child);
175
- break;
176
- default: break;
177
- }
178
- return {
179
- items: elements,
180
- searchElement: searchElem
181
- };
182
- }
183
- return childrenProps.reduce(({ items, searchElement }, child) => {
184
- switch (child.type) {
185
- case MenuSearch: return {
186
- items,
187
- searchElement: /* @__PURE__ */ (0, react.cloneElement)(child, { onKeyDown: (e) => handleKeyboardInteractions(e, {
188
- handleDown: handleArrowDown,
189
- handleUp: handleArrowUp
190
- }) })
191
- };
192
- case MenuItem: return {
193
- items: items.concat(child.props.disabled ? /* @__PURE__ */ (0, react.cloneElement)(child, {
194
- className: (0, classix.cx)(child.props.className, menuItemClassName),
195
- onClick: () => void 0,
196
- onKeyDown: () => void 0,
197
- tabIndex: -1,
198
- disabled: true
199
- }) : /* @__PURE__ */ (0, react.cloneElement)(child, {
200
- className: (0, classix.cx)(child.props.className, menuItemClassName),
201
- item: child.props.item ?? items.length,
202
- onClick: chainEventHandlers(child.props.onClick, () => {
203
- onSelect?.(child.props.item ?? items.length);
204
- }),
205
- onKeyDown: (e) => handleKeyboardInteractions(e, {
206
- handleDown: handleArrowDown,
207
- handleUp: handleArrowUp
208
- })
209
- })),
210
- searchElement
211
- };
212
- case MenuDivider: return {
213
- items: items.concat(child),
214
- searchElement
215
- };
216
- default: return {
217
- items,
218
- searchElement
219
- };
220
- }
221
- }, {
222
- items: [],
223
- searchElement: null
224
- });
225
- }, [
226
- children,
227
- enableVirtualization,
228
- menuItemClassName,
229
- handleArrowDown,
230
- handleArrowUp,
231
- onSelect
232
- ]);
233
- if (enableVirtualization) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuBase, {
234
- "data-test-id": testId,
235
- isVirtual: true,
236
- size,
237
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ItemVirtualizer, {
238
- items: react.Children.toArray(reduceItems.items),
239
- searchElement: reduceItems.searchElement,
240
- overscan,
241
- menuItemClassName,
242
- onSelect,
243
- itemHeight,
244
- focusManager
245
- })
246
- });
247
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(MenuBase, {
248
- "data-test-id": testId,
249
- size,
250
- children: [reduceItems.searchElement, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuItemList, {
251
- role: "presentation",
252
- children: reduceItems.items
253
- })]
254
- });
255
- };
256
- const ItemVirtualizer = (props) => {
257
- const { overscan, searchElement, itemHeight = 31.5, menuItemClassName, items, focusManager, onSelect } = props;
258
- const menuId = (0, react.useRef)(`menu-ctrl-${(0, react.useId)()}`);
259
- const focusedItemIndex = (0, react.useRef)(null);
260
- const parentRef = (0, react.useRef)(null);
261
- const searchRef = (0, react.useRef)(null);
262
- const [nextFocusValue, setNextFocusValue] = (0, react.useState)(null);
263
- const hasSearch = !!searchElement;
264
- const lastVirtualItemIndex = items ? items.length - 1 : 0;
265
- const rowVirtualizer = (0, react_virtual.useVirtual)({
266
- size: items !== null ? items.length : 0,
267
- parentRef,
268
- estimateSize: (0, react.useCallback)(() => itemHeight, [itemHeight]),
269
- overscan
270
- });
271
- const focusSearchBar = (0, react.useCallback)(() => {
272
- rowVirtualizer.scrollToIndex(0);
273
- searchRef.current?.focus?.();
274
- }, [rowVirtualizer]);
275
- /**
276
- * Scrolls to the menu item with the index provided and
277
- * then manually focuses it using a side effect in useEffect
278
- */
279
- const focusMenuItem = (0, react.useCallback)((index) => {
280
- rowVirtualizer.scrollToIndex(index);
281
- setNextFocusValue(index);
282
- }, [rowVirtualizer]);
283
- const handleKeyboardFocusInteraction = (0, react.useCallback)((direction) => {
284
- if (focusedItemIndex.current === null || focusedItemIndex.current === void 0) return;
285
- const nextIndex = direction === "next" ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;
286
- const shouldWrap = direction === "next" && focusedItemIndex.current === lastVirtualItemIndex || direction === "previous" && focusedItemIndex.current === 0;
287
- if (shouldWrap) {
288
- if (hasSearch) focusSearchBar();
289
- else focusMenuItem(direction === "next" ? 0 : lastVirtualItemIndex);
290
- return;
291
- }
292
- switch (direction) {
293
- case "next":
294
- rowVirtualizer.scrollToIndex(nextIndex);
295
- focusManager?.focusNext();
296
- break;
297
- case "previous":
298
- rowVirtualizer.scrollToIndex(nextIndex);
299
- focusManager?.focusPrevious();
300
- break;
301
- default: break;
302
- }
303
- }, [
304
- focusManager,
305
- focusMenuItem,
306
- focusSearchBar,
307
- hasSearch,
308
- lastVirtualItemIndex,
309
- rowVirtualizer
310
- ]);
311
- const getItemProps = (0, react.useCallback)((itemElem, index) => {
312
- const childProps = itemElem.props;
313
- switch (itemElem.type) {
314
- case MenuItem: return {
315
- className: (0, classix.cx)(childProps.className, menuItemClassName),
316
- onKeyDown: childProps.disabled ? () => void 0 : (e) => handleKeyboardFocusKeydown(e, {
317
- handleFocusBackward: handleKeyboardFocusInteraction,
318
- handleFocusForward: handleKeyboardFocusInteraction
319
- }),
320
- onFocus: chainEventHandlers(childProps.onFocus, () => {
321
- focusedItemIndex.current = index;
322
- }),
323
- id: createItemId(index, menuId.current),
324
- onBlur: chainEventHandlers(childProps.onBlur, () => {
325
- focusedItemIndex.current = null;
326
- }),
327
- onClick: childProps.disabled ? () => void 0 : chainEventHandlers(childProps.onClick, () => {
328
- onSelect?.(childProps.item);
329
- })
330
- };
331
- default: return {};
332
- }
333
- }, [
334
- handleKeyboardFocusInteraction,
335
- menuItemClassName,
336
- onSelect
337
- ]);
338
- (0, react.useEffect)(() => {
339
- if (nextFocusValue !== null) {
340
- requestAnimationFrame(() => {
341
- const element = getNodeForIndex(nextFocusValue, menuId.current);
342
- element?.focus();
343
- });
344
- setNextFocusValue(null);
345
- }
346
- }, [nextFocusValue]);
347
- /**
348
- * Calls handleFocusForward when the user is attempting to focus forward using
349
- * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.
350
- */
351
- const handleKeyboardFocusKeydown = (e, callbacks) => {
352
- const keyOps = [
353
- "Tab",
354
- "ArrowUp",
355
- "ArrowDown"
356
- ];
357
- if (keyOps.includes(e.key)) {
358
- e.preventDefault();
359
- e.stopPropagation();
360
- if (e.key === "Tab" && e.shiftKey || e.key === "ArrowUp") callbacks.handleFocusBackward?.("previous");
361
- else if (e.key === "ArrowDown" || e.key === "Tab") callbacks.handleFocusForward?.("next");
362
- }
363
- };
364
- const renderSearch = (0, react.useMemo)(() => searchElement ? /* @__PURE__ */ (0, react.cloneElement)(searchElement, {
365
- onKeyDown: (e) => handleKeyboardFocusKeydown(e, {
366
- handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),
367
- handleFocusForward: () => focusMenuItem(0)
368
- }),
369
- ref: searchRef
370
- }) : null, [
371
- searchElement,
372
- lastVirtualItemIndex,
373
- focusMenuItem
374
- ]);
375
- const renderItems = (0, react.useMemo)(() => rowVirtualizer.virtualItems.map((virtualRow) => {
376
- if (!items) return null;
377
- const elem = items[virtualRow.index];
378
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
379
- ref: virtualRow.measureRef,
380
- role: "presentation",
381
- className: Menu_module_default["VirtualMenu-item"],
382
- style: { transform: `translateY(${virtualRow.start}px)` },
383
- children: /* @__PURE__ */ (0, react.cloneElement)(elem, getItemProps(elem, virtualRow.index))
384
- }, virtualRow.index);
385
- }), [
386
- rowVirtualizer.virtualItems,
387
- items,
388
- getItemProps
389
- ]);
390
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [renderSearch, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuItemList, {
391
- ref: parentRef,
392
- role: "presentation",
393
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
394
- role: "presentation",
395
- className: Menu_module_default["VirtualMenu-item-list"],
396
- style: { height: `${rowVirtualizer.totalSize}px` },
397
- children: renderItems
398
- })
399
- })] });
400
- };
401
- exports.Menu = Menu;
402
- exports.MenuBase = MenuBase;
403
- exports.MenuDivider = MenuDivider;
404
- exports.MenuItem = MenuItem;
405
- exports.MenuItemList = MenuItemList;
406
- exports.MenuSearch = MenuSearch;
407
-
408
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["Component: ElementType","index: number","id: string","index: number | null","menuId: string","event: KeyboardEvent","keyHandlers: Partial<\n\t\tRecord<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n\t>","event: SyntheticEvent","props: MenuProps<T>","elements: ReactElement[]","child: ReactElement<any>","e: KeyboardEvent","props: ItemVirtualizerProps<T>","index: number","direction: 'next' | 'previous'","itemElem: ReactElement","callbacks: Record<\n\t\t\t'handleFocusForward' | 'handleFocusBackward',\n\t\t\t(direction: 'next' | 'previous') => void\n\t\t>"],"sources":["../src/styles/Menu.module.css","../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":[".Menu-item {\n\tbackground-color: transparent;\n\tborder-radius: var(--lp-border-radius-regular);\n\tborder-width: var(--lp-border-width-100);\n\tcolor: var(--lp-color-text-ui-primary-base);\n\tcursor: pointer;\n\tdisplay: block;\n\tfont: var(--lp-text-label-1-medium);\n\toutline: none;\n\toverflow: hidden;\n\tpadding-inline: var(--lp-spacing-300);\n\tpadding-block: var(--lp-spacing-200);\n\tposition: relative;\n\ttext-align: left;\n\ttext-decoration: none;\n\ttext-overflow: ellipsis;\n\tuser-select: none;\n\twhite-space: nowrap;\n\twidth: 100%;\n}\n\n.Menu-item-list {\n\tmax-height: 55vh;\n\tmin-width: 7.5rem;\n\toverflow: auto;\n\tpadding: var(--lp-spacing-200);\n}\n\n.Menu .Menu-item:not([disabled]):not([aria-disabled]):not(.Menu-item--header) {\n\t&:active {\n\t\ttext-decoration: none;\n\t\tbackground-color: var(--lp-color-bg-interactive-secondary-active);\n\t}\n\n\t&:hover:not(:active):not(.has-focus) {\n\t\tbackground-color: var(--lp-color-bg-interactive-secondary-hover);\n\t}\n\n\t&.has-focus {\n\t\tbackground-color: var(--lp-color-bg-interactive-secondary-hover);\n\t\tbox-shadow: inset 0 0 0 2px var(--lp-color-shadow-interactive-focus);\n\t}\n}\n\n.Menu {\n\tbackground: var(--lp-color-bg-overlay-secondary);\n\tborder-radius: var(--lp-border-radius-medium);\n\tfont-family: var(--lp-font-family-base);\n\n\t&:focus {\n\t\toutline: none;\n\t}\n\n\t/* Override our link styles for link component */\n\t& a.Menu-item {\n\t\t&:focus:not(:hover):not(.has-focus) {\n\t\t\ttext-decoration: none;\n\t\t\tbox-shadow: none;\n\t\t}\n\n\t\t/* Ensures that links that are disabled don't show active styles */\n\t\t&:active[disabled],\n\t\t&:active[aria-disabled] {\n\t\t\ttext-decoration: none;\n\t\t\tcolor: var(--lp-color-text-interactive-disabled);\n\t\t}\n\t}\n}\n\n.Menu-item--nested {\n\tpadding-left: 2.5rem;\n}\n\n.Menu-item--header {\n\tfont: var(--lp-text-small-1-regular);\n\tcolor: var(--lp-color-text-ui-tertiary);\n}\n\n.Menu-item-icon {\n\tmargin-right: var(--lp-spacing-300);\n}\n\n.Menu-item :global(.Gravatar) {\n\tmargin-right: 0.3125rem;\n}\n\n.Menu-item.is-highlighted {\n\tbackground-color: var(--lp-color-bg-interactive-secondary-hover);\n}\n\n.Menu-item[aria-disabled],\n.Menu-item[disabled] {\n\tcolor: var(--lp-color-text-interactive-disabled);\n\tcursor: not-allowed;\n}\n\n.Menu-divider {\n\tborder-top: 1px solid var(--lp-color-border-ui-secondary);\n\tmargin: var(--lp-spacing-200) 0;\n}\n\n.Menu-search {\n\tborder-bottom: 1px solid var(--lp-color-border-ui-secondary);\n\tpadding: var(--lp-spacing-300);\n}\n\n[class*='_Popover-content'] .Menu-search {\n\twidth: 100%;\n\n\t/* Removing anything that could give it some height */\n\t& .Menu-search-hidden-placeholder {\n\t\tpadding-top: 0;\n\t\tpadding-bottom: 0;\n\t\theight: 0;\n\t\tborder: none;\n\t\tvisibility: hidden;\n\t}\n}\n\n.Menu--isVirtual {\n\tdisplay: flex;\n\talign-items: stretch;\n\tflex-direction: column;\n}\n\n.MenuSize--xl {\n\twidth: 20rem;\n}\n\n.MenuSize--lg {\n\twidth: 15rem;\n}\n\n.MenuSize--md {\n\twidth: 10rem;\n}\n\n.MenuSize--sm {\n\twidth: 7.5rem;\n}\n\n.VirtualMenu-item-list {\n\twidth: 100%;\n\tposition: relative;\n}\n\n.VirtualMenu-item {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n}\n","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, JSX, 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: ignore\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: ignore\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\n/**\n * @deprecated use `Menu` or `ListBox` from `@launchpad-ui/components` instead\n *\n * https://launchpad.launchdarkly.com/?path=/docs/components-collections-menu--docs\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\t// biome-ignore lint/suspicious/noExplicitAny: ignore\n\t\t\t\tchild: ReactElement<any>,\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\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\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 | null>(null);\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\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: ignore\n\tconst renderSearch = useMemo(\n\t\t() =>\n\t\t\tsearchElement\n\t\t\t\t? // biome-ignore lint/suspicious/noExplicitAny: ignore\n\t\t\t\t\tcloneElement(searchElement as ReactElement<any>, {\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\t})\n\t\t\t\t: null,\n\t\t[searchElement, lastVirtualItemIndex, focusMenuItem],\n\t);\n\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"],"mappings":"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"}
package/dist/style.css DELETED
@@ -1,2 +0,0 @@
1
- .C73R2W_Menu-item{border-radius:var(--lp-border-radius-regular);border-width:var(--lp-border-width-100);color:var(--lp-color-text-ui-primary-base);cursor:pointer;font:var(--lp-text-label-1-medium);padding-inline:var(--lp-spacing-300);padding-block:var(--lp-spacing-200);text-align:left;text-overflow:ellipsis;-webkit-user-select:none;user-select:none;white-space:nowrap;background-color:#0000;outline:none;width:100%;text-decoration:none;display:block;position:relative;overflow:hidden}.C73R2W_Menu-item-list{min-width:7.5rem;max-height:55vh;padding:var(--lp-spacing-200);overflow:auto}.C73R2W_Menu .C73R2W_Menu-item:not([disabled]):not([aria-disabled]):not(.C73R2W_Menu-item--header):active{background-color:var(--lp-color-bg-interactive-secondary-active);text-decoration:none}.C73R2W_Menu .C73R2W_Menu-item:not([disabled]):not([aria-disabled]):not(.C73R2W_Menu-item--header):hover:not(:active):not(.C73R2W_has-focus){background-color:var(--lp-color-bg-interactive-secondary-hover)}.C73R2W_Menu .C73R2W_Menu-item:not([disabled]):not([aria-disabled]):not(.C73R2W_Menu-item--header).C73R2W_has-focus{background-color:var(--lp-color-bg-interactive-secondary-hover);box-shadow:inset 0 0 0 2px var(--lp-color-shadow-interactive-focus)}.C73R2W_Menu{background:var(--lp-color-bg-overlay-secondary);border-radius:var(--lp-border-radius-medium);font-family:var(--lp-font-family-base)}.C73R2W_Menu:focus{outline:none}.C73R2W_Menu a.C73R2W_Menu-item:focus:not(:hover):not(.C73R2W_has-focus){box-shadow:none;text-decoration:none}.C73R2W_Menu a.C73R2W_Menu-item:active[disabled],.C73R2W_Menu a.C73R2W_Menu-item:active[aria-disabled]{color:var(--lp-color-text-interactive-disabled);text-decoration:none}.C73R2W_Menu-item--nested{padding-left:2.5rem}.C73R2W_Menu-item--header{font:var(--lp-text-small-1-regular);color:var(--lp-color-text-ui-tertiary)}.C73R2W_Menu-item-icon{margin-right:var(--lp-spacing-300)}.C73R2W_Menu-item .Gravatar{margin-right:.3125rem}.C73R2W_Menu-item.C73R2W_is-highlighted{background-color:var(--lp-color-bg-interactive-secondary-hover)}.C73R2W_Menu-item[aria-disabled],.C73R2W_Menu-item[disabled]{color:var(--lp-color-text-interactive-disabled);cursor:not-allowed}.C73R2W_Menu-divider{border-top:1px solid var(--lp-color-border-ui-secondary);margin:var(--lp-spacing-200)0}.C73R2W_Menu-search{border-bottom:1px solid var(--lp-color-border-ui-secondary);padding:var(--lp-spacing-300)}[class*=_Popover-content] .C73R2W_Menu-search{width:100%}[class*=_Popover-content] .C73R2W_Menu-search .C73R2W_Menu-search-hidden-placeholder{visibility:hidden;border:none;height:0;padding-top:0;padding-bottom:0}.C73R2W_Menu--isVirtual{flex-direction:column;align-items:stretch;display:flex}.C73R2W_MenuSize--xl{width:20rem}.C73R2W_MenuSize--lg{width:15rem}.C73R2W_MenuSize--md{width:10rem}.C73R2W_MenuSize--sm{width:7.5rem}.C73R2W_VirtualMenu-item-list{width:100%;position:relative}.C73R2W_VirtualMenu-item{width:100%;position:absolute;top:0;left:0}
2
- /*$vite$:1*/
package/dist/utils.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import type { EventHandler, KeyboardEvent, SyntheticEvent } from 'react';
2
- declare const createItemId: (index: number, id: string) => string;
3
- declare const getNodeForIndex: (index: number | null, menuId: string) => HTMLElement | null;
4
- declare const handleKeyboardInteractions: (event: KeyboardEvent, keyHandlers: Partial<Record<"handleUp" | "handleDown" | "handleEnter", (e: KeyboardEvent) => void>>) => void;
5
- declare const chainEventHandlers: (...handlers: (EventHandler<SyntheticEvent> | undefined)[]) => (event: SyntheticEvent) => void;
6
- export { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };
7
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
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,GAAI,OAAO,MAAM,EAAE,IAAI,MAAM,WAA0B,CAAC;AAE1E,QAAA,MAAM,eAAe,GAAI,OAAO,MAAM,GAAG,IAAI,EAAE,QAAQ,MAAM,uBACiB,CAAC;AAE/E,QAAA,MAAM,0BAA0B,GAC/B,OAAO,aAAa,EACpB,aAAa,OAAO,CACnB,MAAM,CAAC,UAAU,GAAG,YAAY,GAAG,aAAa,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC,CAC7E,SAaD,CAAC;AAEF,QAAA,MAAM,kBAAkB,GACtB,GAAG,UAAU,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC,EAAE,MACzD,OAAO,cAAc,SAIrB,CAAC;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,CAAC"}