@launchpad-ui/menu 0.12.5-alpha.0 → 0.12.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Menu.d.ts CHANGED
@@ -35,7 +35,7 @@ declare const Menu: <T extends string | number>(props: MenuProps<T>) => import("
35
35
  type ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {
36
36
  items: ReactElement[] | null;
37
37
  searchElement?: ReactElement | null;
38
- focusManager: FocusManager;
38
+ focusManager?: FocusManager;
39
39
  };
40
40
  declare const ItemVirtualizer: <T extends string | number>(props: ItemVirtualizerProps<T>) => import("react/jsx-runtime").JSX.Element;
41
41
  export { Menu, ItemVirtualizer };
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../src/Menu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA6BpE,KAAK,mBAAmB,CAAC,CAAC,IAAI;IAC5B,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;CACzB,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAEnE,QAAA,MAAM,IAAI,6FAwHT,CAAC;AAEF,KAAK,oBAAoB,CAAC,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG;IACxE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,YAAY,EAAE,YAAY,CAAC;CAC5B,CAAC;AAEF,QAAA,MAAM,eAAe,wGA+MpB,CAAC;AAEF,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;AACjC,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../src/Menu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA4BpE,KAAK,mBAAmB,CAAC,CAAC,IAAI;IAC5B,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;CACzB,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAEnE,QAAA,MAAM,IAAI,6FAwHT,CAAC;AAEF,KAAK,oBAAoB,CAAC,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG;IACxE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,QAAA,MAAM,eAAe,wGA+MpB,CAAC;AAEF,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;AACjC,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import type { MenuProps } from './Menu';
2
2
  import type { ComponentPropsWithRef } from 'react';
3
+ import './styles/Menu.css';
3
4
  type MenuBaseProps = ComponentPropsWithRef<'div'> & {
4
5
  isVirtual?: boolean;
5
6
  size?: MenuProps<string>['size'];
@@ -1 +1 @@
1
- {"version":3,"file":"MenuBase.d.ts","sourceRoot":"","sources":["../src/MenuBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAOnD,KAAK,aAAa,GAAG,qBAAqB,CAAC,KAAK,CAAC,GAAG;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,QAAA,MAAM,QAAQ,uHAcb,CAAC;AAIF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"MenuBase.d.ts","sourceRoot":"","sources":["../src/MenuBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAKnD,OAAO,mBAAmB,CAAC;AAE3B,KAAK,aAAa,GAAG,qBAAqB,CAAC,KAAK,CAAC,GAAG;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,QAAA,MAAM,QAAQ,uHAUb,CAAC;AAIF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import type { SeparatorProps } from '@react-aria/separator';
2
2
  import type { RefObject } from 'react';
3
+ import './styles/Menu.css';
3
4
  type MenuDividerProps = SeparatorProps & {
4
5
  innerRef?: RefObject<HTMLDivElement>;
5
6
  'data-test-id'?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"MenuDivider.d.ts","sourceRoot":"","sources":["../src/MenuDivider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,KAAK,gBAAgB,GAAG,cAAc,GAAG;IACvC,QAAQ,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,WAAW,oEAKd,gBAAgB,4CAclB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
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;AAIvC,OAAO,mBAAmB,CAAC;AAE3B,KAAK,gBAAgB,GAAG,cAAc,GAAG;IACvC,QAAQ,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,WAAW,oEAKd,gBAAgB,4CAOlB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
@@ -2,6 +2,7 @@ import type { IconProps } from '@launchpad-ui/icons';
2
2
  import type { PopoverPlacement } from '@launchpad-ui/popover';
3
3
  import type { ComponentPropsWithRef, ElementType, PropsWithRef, ReactElement } from 'react';
4
4
  import { Tooltip } from '@launchpad-ui/tooltip';
5
+ import './styles/Menu.css';
5
6
  type Merge<T, U> = Omit<T, keyof U> & U;
6
7
  type PropsWithComponent<P, T extends ElementType> = P & {
7
8
  component?: T;
@@ -1 +1 @@
1
- {"version":3,"file":"MenuItem.d.ts","sourceRoot":"","sources":["../src/MenuItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE5F,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAShD,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;AAExC,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;AAE1E,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,KAAK,CAC5D,CAAC,SAAS,MAAM,GAAG,CAAC,iBAAiB,GACjC,YAAY,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACtC,qBAAqB,CAAC,CAAC,CAAC,EAC5B,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CACzB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,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,OAAO,OAAO,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,cAAc,WAAW,CAAC;AAEhC,KAAK,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,GAAG,OAAO,cAAc,IAAI,uBAAuB,CAC1F,CAAC,gBAAgB,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC,GACF,CAAC,gBAAgB,GAAG;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC,EACJ,CAAC,CACF,CAAC;AAEF,QAAA,MAAM,QAAQ,qHAwEb,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"MenuItem.d.ts","sourceRoot":"","sources":["../src/MenuItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE5F,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAMhD,OAAO,mBAAmB,CAAC;AAG3B,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,CAC5D,CAAC,SAAS,MAAM,GAAG,CAAC,iBAAiB,GACjC,YAAY,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACtC,qBAAqB,CAAC,CAAC,CAAC,EAC5B,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CACzB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,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,OAAO,OAAO,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,cAAc,WAAW,CAAC;AAEhC,KAAK,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,GAAG,OAAO,cAAc,IAAI,uBAAuB,CAC1F,CAAC,gBAAgB,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC,GACF,CAAC,gBAAgB,GAAG;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC,EACJ,CAAC,CACF,CAAC;AAEF,QAAA,MAAM,QAAQ,qHAwEb,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { ComponentPropsWithRef } from 'react';
2
+ import './styles/Menu.css';
2
3
  type MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;
3
4
  declare const MenuItemList: import("react").ForwardRefExoticComponent<Omit<MenuItemListProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
4
5
  export { MenuItemList };
@@ -1 +1 @@
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
+ {"version":3,"file":"MenuItemList.d.ts","sourceRoot":"","sources":["../src/MenuItemList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAInD,OAAO,mBAAmB,CAAC;AAE3B,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,4 +1,5 @@
1
1
  import type { ChangeEvent } from 'react';
2
+ import './styles/Menu.css';
2
3
  type MenuSearchProps = {
3
4
  ariaLabel?: string;
4
5
  value?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"MenuSearch.d.ts","sourceRoot":"","sources":["../src/MenuSearch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAOzC,KAAK,eAAe,GAAG;IACrB,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;CACzB,CAAC;AAEF,QAAA,MAAM,UAAU,8GAyBd,CAAC;AAIH,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"MenuSearch.d.ts","sourceRoot":"","sources":["../src/MenuSearch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAKzC,OAAO,mBAAmB,CAAC;AAE3B,KAAK,eAAe,GAAG;IACrB,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;CACzB,CAAC;AAEF,QAAA,MAAM,UAAU,8GAyBd,CAAC;AAIH,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,CAAC"}
package/dist/index.es.js CHANGED
@@ -8,34 +8,10 @@ import { Slot } from "@radix-ui/react-slot";
8
8
  import { FocusRing, useFocusManager } from "@react-aria/focus";
9
9
  import { TextField } from "@launchpad-ui/form";
10
10
  import { useVirtual } from "react-virtual";
11
- const Menu$1 = "_Menu_dlpdi_1";
12
- const styles = {
13
- "Menu-item": "_Menu-item_dlpdi_1",
14
- "Menu-item-list": "_Menu-item-list_dlpdi_22",
15
- Menu: Menu$1,
16
- "Menu-item--header": "_Menu-item--header_dlpdi_29",
17
- "has-focus": "_has-focus_dlpdi_35",
18
- "Menu-item--nested": "_Menu-item--nested_dlpdi_70",
19
- "Menu-item-icon": "_Menu-item-icon_dlpdi_79",
20
- "is-highlighted": "_is-highlighted_dlpdi_87",
21
- "Menu-divider": "_Menu-divider_dlpdi_97",
22
- "Menu-search": "_Menu-search_dlpdi_102",
23
- "Menu-search-hidden-placeholder": "_Menu-search-hidden-placeholder_dlpdi_111",
24
- "Menu--isVirtual": "_Menu--isVirtual_dlpdi_120",
25
- "MenuSize--xl": "_MenuSize--xl_dlpdi_126",
26
- "MenuSize--lg": "_MenuSize--lg_dlpdi_130",
27
- "MenuSize--md": "_MenuSize--md_dlpdi_134",
28
- "MenuSize--sm": "_MenuSize--sm_dlpdi_138",
29
- "VirtualMenu-item-list": "_VirtualMenu-item-list_dlpdi_142",
30
- "VirtualMenu-item": "_VirtualMenu-item_dlpdi_142"
31
- };
11
+ const Menu$1 = "";
32
12
  const MenuBase = /* @__PURE__ */ forwardRef(
33
13
  ({ children, size, isVirtual, ...props }, ref) => {
34
- const classes = cx(
35
- styles.Menu,
36
- isVirtual && styles["Menu--isVirtual"],
37
- size && styles[`MenuSize--${size}`]
38
- );
14
+ const classes = cx("Menu", isVirtual && "Menu--isVirtual", size && `MenuSize--${size}`);
39
15
  return /* @__PURE__ */ jsx("div", { ...props, role: "menu", className: classes, ref, children });
40
16
  }
41
17
  );
@@ -50,15 +26,7 @@ const MenuDivider = ({
50
26
  orientation,
51
27
  elementType
52
28
  });
53
- return /* @__PURE__ */ jsx(
54
- "div",
55
- {
56
- ...separatorProps,
57
- "data-test-id": testId,
58
- ref: innerRef,
59
- className: styles["Menu-divider"]
60
- }
61
- );
29
+ return /* @__PURE__ */ jsx("div", { ...separatorProps, "data-test-id": testId, ref: innerRef, className: "Menu-divider" });
62
30
  };
63
31
  const defaultElement = "button";
64
32
  const MenuItem = ({
@@ -86,24 +54,24 @@ const MenuItem = ({
86
54
  } = props;
87
55
  const Component = component || (asChild ? Slot : defaultElement);
88
56
  const renderIcon = icon && /* @__PURE__ */ cloneElement(icon, { size: "small" });
89
- const renderedItem = /* @__PURE__ */ jsx(FocusRing, { focusRingClass: styles["has-focus"], children: /* @__PURE__ */ jsx(
57
+ const renderedItem = /* @__PURE__ */ jsx(FocusRing, { focusRingClass: "has-focus", children: /* @__PURE__ */ jsx(
90
58
  Component,
91
59
  {
92
60
  ...rest,
93
61
  disabled,
94
62
  "aria-disabled": disabled ? disabled : void 0,
95
63
  className: cx(
96
- styles["Menu-item"],
64
+ "Menu-item",
97
65
  className,
98
- isHighlighted && styles["is-highlighted"],
99
- nested && styles["Menu-item--nested"],
100
- groupHeader && styles["Menu-item--header"]
66
+ isHighlighted && "is-highlighted",
67
+ nested && "Menu-item--nested",
68
+ groupHeader && "Menu-item--header"
101
69
  ),
102
70
  "data-test-id": testId,
103
71
  role,
104
72
  onKeyDown,
105
73
  children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
106
- icon && /* @__PURE__ */ jsx("span", { className: styles["Menu-item-icon"], children: renderIcon }),
74
+ icon && /* @__PURE__ */ jsx("span", { className: "Menu-item-icon", children: renderIcon }),
107
75
  children
108
76
  ] })
109
77
  }
@@ -123,7 +91,7 @@ const MenuItem = ({
123
91
  }
124
92
  return renderedItem;
125
93
  };
126
- const MenuItemList = /* @__PURE__ */ forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsx("div", { ...rest, ref, "data-test-id": "menu-item-list", className: styles["Menu-item-list"], children }));
94
+ const MenuItemList = /* @__PURE__ */ forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsx("div", { ...rest, ref, "data-test-id": "menu-item-list", className: "Menu-item-list", children }));
127
95
  MenuItemList.displayName = "MenuItemList";
128
96
  const MenuSearch = /* @__PURE__ */ forwardRef((props, ref) => {
129
97
  const {
@@ -133,12 +101,12 @@ const MenuSearch = /* @__PURE__ */ forwardRef((props, ref) => {
133
101
  "data-test-id": testId = "menu-search",
134
102
  ...finalProps
135
103
  } = props;
136
- return /* @__PURE__ */ jsx("div", { className: styles["Menu-search"], children: /* @__PURE__ */ jsx(
104
+ return /* @__PURE__ */ jsx("div", { className: "Menu-search", children: /* @__PURE__ */ jsx(
137
105
  TextField,
138
106
  {
139
107
  ...finalProps,
140
108
  ref,
141
- className: styles["Menu-search-input"],
109
+ className: "Menu-search-input",
142
110
  tiny: true,
143
111
  id,
144
112
  type: "search",
@@ -180,10 +148,10 @@ const Menu = (props) => {
180
148
  } = props;
181
149
  const focusManager = useFocusManager();
182
150
  const handleArrowDown = useCallback(() => {
183
- focusManager.focusNext({ wrap: true });
151
+ focusManager == null ? void 0 : focusManager.focusNext({ wrap: true });
184
152
  }, [focusManager]);
185
153
  const handleArrowUp = useCallback(() => {
186
- focusManager.focusPrevious({ wrap: true });
154
+ focusManager == null ? void 0 : focusManager.focusPrevious({ wrap: true });
187
155
  }, [focusManager]);
188
156
  const reduceItems = useMemo(() => {
189
157
  const childrenProps = Children.toArray(children);
@@ -321,11 +289,11 @@ const ItemVirtualizer = (props) => {
321
289
  switch (direction) {
322
290
  case "next":
323
291
  rowVirtualizer.scrollToIndex(nextIndex);
324
- focusManager.focusNext();
292
+ focusManager == null ? void 0 : focusManager.focusNext();
325
293
  break;
326
294
  case "previous":
327
295
  rowVirtualizer.scrollToIndex(nextIndex);
328
- focusManager.focusPrevious();
296
+ focusManager == null ? void 0 : focusManager.focusPrevious();
329
297
  break;
330
298
  }
331
299
  },
@@ -403,7 +371,7 @@ const ItemVirtualizer = (props) => {
403
371
  {
404
372
  ref: virtualRow.measureRef,
405
373
  role: "presentation",
406
- className: styles["VirtualMenu-item"],
374
+ className: cx("VirtualMenu-item"),
407
375
  style: {
408
376
  transform: `translateY(${virtualRow.start}px)`
409
377
  },
@@ -420,7 +388,7 @@ const ItemVirtualizer = (props) => {
420
388
  "div",
421
389
  {
422
390
  role: "presentation",
423
- className: styles["VirtualMenu-item-list"],
391
+ className: "VirtualMenu-item-list",
424
392
  style: {
425
393
  height: `${rowVirtualizer.totalSize}px`
426
394
  },
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":["import type { MenuProps } from './Menu';\nimport type { ComponentPropsWithRef } from 'react';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n isVirtual?: boolean;\n size?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n ({ children, size, isVirtual, ...props }, ref) => {\n const classes = cx(\n styles.Menu,\n isVirtual && styles['Menu--isVirtual'],\n size && styles[`MenuSize--${size}`]\n );\n\n return (\n <div {...props} role=\"menu\" className={classes} ref={ref}>\n {children}\n </div>\n );\n }\n);\n\nMenuBase.displayName = 'MenuBase';\n\nexport { MenuBase };\nexport type { MenuBaseProps };\n","import type { SeparatorProps } from '@react-aria/separator';\nimport type { RefObject } from 'react';\n\nimport { useSeparator } from '@react-aria/separator';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuDividerProps = SeparatorProps & {\n innerRef?: RefObject<HTMLDivElement>;\n 'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n elementType = 'div',\n orientation,\n innerRef,\n 'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n const { separatorProps } = useSeparator({\n orientation,\n elementType,\n });\n\n return (\n <div\n {...separatorProps}\n data-test-id={testId}\n ref={innerRef}\n className={styles['Menu-divider']}\n />\n );\n};\n\nexport { MenuDivider };\nexport type { MenuDividerProps };\n","import type { IconProps } from '@launchpad-ui/icons';\nimport type { PopoverPlacement } from '@launchpad-ui/popover';\nimport type { ComponentPropsWithRef, ElementType, PropsWithRef, ReactElement } from 'react';\n\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { Slot } from '@radix-ui/react-slot';\nimport { FocusRing } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport { cloneElement } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\n// Merge two types and get rid of overlapping definitions\ntype Merge<T, U> = Omit<T, keyof U> & U;\n\ntype PropsWithComponent<P, T extends ElementType> = P & { component?: T };\n\ntype PolymorphicPropsWithRef<P, T extends ElementType> = Merge<\n T extends keyof JSX.IntrinsicElements\n ? PropsWithRef<JSX.IntrinsicElements[T]>\n : ComponentPropsWithRef<T>,\n PropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n isHighlighted?: boolean;\n icon?: ReactElement<IconProps>;\n disabled?: boolean;\n nested?: boolean;\n groupHeader?: boolean;\n tooltip?: string | ReactElement;\n tooltipOptions?: typeof Tooltip;\n tooltipPlacement?: PopoverPlacement;\n asChild?: boolean;\n 'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n | (MenuItemOwnProps & {\n item: P; // Infer the type if it is included\n })\n | (MenuItemOwnProps & {\n item?: undefined;\n }),\n T\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n ...props\n}: MenuItemProps<P, T>) => {\n const {\n // TODO: remove component prop once we migrate over to asChild format\n component,\n children,\n isHighlighted,\n icon,\n nested,\n groupHeader,\n item,\n disabled,\n className,\n tooltip,\n role = 'menuitem',\n tooltipPlacement,\n onKeyDown,\n tooltipOptions,\n asChild,\n 'data-test-id': testId = 'menu-item',\n ...rest\n } = props;\n\n const Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n const renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n const renderedItem = (\n <FocusRing focusRingClass={styles['has-focus']}>\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n styles['Menu-item'],\n className,\n isHighlighted && styles['is-highlighted'],\n nested && styles['Menu-item--nested'],\n groupHeader && styles['Menu-item--header']\n )}\n data-test-id={testId}\n role={role}\n onKeyDown={onKeyDown}\n >\n {asChild ? (\n children\n ) : (\n <>\n {icon && <span className={styles['Menu-item-icon']}>{renderIcon}</span>}\n {children}\n </>\n )}\n </Component>\n </FocusRing>\n );\n\n if (tooltip) {\n return (\n <Tooltip\n content={tooltip}\n rootElementStyle={{ display: 'block' }}\n allowBoundaryElementOverflow\n placement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n {...(tooltipOptions || {})}\n >\n {renderedItem}\n </Tooltip>\n );\n }\n\n return renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n <div {...rest} ref={ref} data-test-id=\"menu-item-list\" className={styles['Menu-item-list']}>\n {children}\n </div>\n));\n\nMenuItemList.displayName = 'MenuItemList';\n\nexport { MenuItemList };\nexport type { MenuItemListProps };\n","import type { ChangeEvent } from 'react';\n\nimport { TextField } from '@launchpad-ui/form';\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuSearchProps = {\n ariaLabel?: string;\n value?: string;\n id?: string;\n placeholder?: string;\n onChange?(event: ChangeEvent<HTMLInputElement>): void;\n 'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n const {\n ariaLabel,\n placeholder,\n id,\n 'data-test-id': testId = 'menu-search',\n ...finalProps\n } = props;\n\n return (\n <div className={styles['Menu-search']}>\n <TextField\n {...finalProps}\n ref={ref}\n className={styles['Menu-search-input']}\n tiny\n id={id}\n type=\"search\"\n data-test-id={testId}\n autoComplete=\"off\"\n placeholder={placeholder}\n aria-label={ariaLabel || 'Search'}\n />\n </div>\n );\n});\n\nMenuSearch.displayName = 'MenuSearch';\n\nexport { MenuSearch };\nexport type { MenuSearchProps };\n","import type { EventHandler, KeyboardEvent, SyntheticEvent } from 'react';\n\nconst createItemId = (index: number, id: string) => `${id}-item-${index}`;\n\nconst getNodeForIndex = (index: number | null, menuId: string) =>\n index === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n event: KeyboardEvent,\n keyHandlers: Partial<\n Record<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n >\n) => {\n const ops = {\n ArrowUp: keyHandlers.handleUp,\n ArrowDown: keyHandlers.handleDown,\n Enter: keyHandlers.handleEnter,\n } as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n if (ops[event.key]) {\n event.preventDefault();\n ops[event.key]?.call(globalThis, event);\n }\n};\n\nconst chainEventHandlers =\n (...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n (event: SyntheticEvent) => {\n handlers.forEach((h) => typeof h === 'function' && h(event));\n };\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { MenuItemProps } from './MenuItem';\nimport type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n Children,\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useVirtual } from 'react-virtual';\n\nimport { MenuBase } from './MenuBase';\nimport { MenuDivider } from './MenuDivider';\nimport { MenuItem } from './MenuItem';\nimport { MenuItemList } from './MenuItemList';\nimport { MenuSearch } from './MenuSearch';\nimport styles from './styles/Menu.module.css';\nimport {\n chainEventHandlers,\n createItemId,\n getNodeForIndex,\n handleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n children: ReactNode;\n onSelect?: (item: T) => void;\n /**\n * Menus items are rendered using react-virtual for\n * additional rendering performance.\n */\n enableVirtualization?: boolean;\n /**\n * Class name to be applied to all MenuItem components\n * in the menu.\n */\n menuItemClassName?: string;\n /**\n * Sets the width of the menu. This is especially useful when using virtual items\n * since the width cannot be automatically set by the widest element.\n */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /**\n * Sets the number out of elements rendered outside of the view window\n * when using virtualization\n */\n overscan?: number;\n /**\n * Sets the height for each menu item when using virtualization.\n *\n */\n itemHeight?: number;\n 'data-test-id'?: string;\n};\n\ntype MenuProps<T extends number | string> = ControlledMenuProps<T>;\n\nconst Menu = <T extends number | string>(props: MenuProps<T>) => {\n const {\n children,\n menuItemClassName,\n onSelect,\n enableVirtualization,\n itemHeight,\n size,\n overscan = 1,\n 'data-test-id': testId = 'menu',\n } = props;\n\n const focusManager = useFocusManager();\n\n const handleArrowDown = useCallback(() => {\n focusManager.focusNext({ wrap: true });\n }, [focusManager]);\n\n const handleArrowUp = useCallback(() => {\n focusManager.focusPrevious({ wrap: true });\n }, [focusManager]);\n\n const reduceItems = useMemo(() => {\n const childrenProps = Children.toArray(children);\n if (enableVirtualization) {\n // the virtualized menu has its own handlers and props\n let searchElem = null;\n let elements: ReactElement[] = [];\n (childrenProps as ReactElement[]).forEach((child: ReactElement) => {\n switch (child.type) {\n case MenuSearch:\n searchElem = child;\n break;\n case MenuItem:\n case MenuDivider:\n elements = elements.concat(child);\n break;\n default:\n break;\n }\n });\n return { items: elements, searchElement: searchElem };\n }\n\n return (childrenProps as ReactElement[]).reduce(\n (\n { items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n child\n ) => {\n switch (child.type) {\n case MenuSearch:\n return {\n items,\n searchElement: cloneElement(child, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n }),\n };\n case MenuItem:\n return {\n items: items.concat(\n child.props.disabled\n ? cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n onClick: () => undefined,\n onKeyDown: () => undefined,\n tabIndex: -1,\n disabled: true,\n })\n : cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n item: child.props.item ?? items.length,\n // set focus on the first menu item if there is no search input, and set in the tab order\n onClick: chainEventHandlers(child.props.onClick, () => {\n onSelect?.(child.props.item ?? items.length);\n }),\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n })\n ),\n searchElement,\n };\n case MenuDivider:\n return { items: items.concat(child), searchElement };\n default:\n return { items, searchElement };\n }\n },\n { items: [], searchElement: null }\n );\n }, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n if (enableVirtualization) {\n return (\n <MenuBase data-test-id={testId} isVirtual size={size}>\n <ItemVirtualizer<T>\n items={Children.toArray(reduceItems.items) as ReactElement[]}\n searchElement={reduceItems.searchElement}\n overscan={overscan}\n menuItemClassName={menuItemClassName}\n onSelect={onSelect}\n itemHeight={itemHeight}\n focusManager={focusManager}\n />\n </MenuBase>\n );\n }\n\n return (\n <MenuBase data-test-id={testId} size={size}>\n {reduceItems.searchElement}\n <MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n </MenuBase>\n );\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n items: ReactElement[] | null;\n searchElement?: ReactElement | null;\n focusManager: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n const {\n overscan,\n searchElement,\n itemHeight = 31.5,\n menuItemClassName,\n items: items,\n focusManager,\n onSelect,\n } = props;\n\n const menuId = useRef(`menu-ctrl-${useId()}`);\n\n const focusedItemIndex = useRef<number | null>(null);\n const parentRef = useRef<HTMLDivElement | null>(null);\n const searchRef = useRef<HTMLInputElement>();\n\n const [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n const hasSearch = !!searchElement;\n\n const lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n const rowVirtualizer = useVirtual({\n size: items !== null ? items.length : 0,\n parentRef,\n estimateSize: useCallback(() => itemHeight, [itemHeight]),\n overscan,\n });\n\n const focusSearchBar = useCallback(() => {\n rowVirtualizer.scrollToIndex(0);\n searchRef.current?.focus?.();\n }, [rowVirtualizer]);\n\n /**\n * Scrolls to the menu item with the index provided and\n * then manually focuses it using a side effect in useEffect\n */\n const focusMenuItem = useCallback(\n (index: number) => {\n rowVirtualizer.scrollToIndex(index);\n setNextFocusValue(index);\n },\n [rowVirtualizer]\n );\n\n const handleKeyboardFocusInteraction = useCallback(\n (direction: 'next' | 'previous') => {\n if (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n return;\n }\n const nextIndex =\n direction === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n const shouldWrap =\n (direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n (direction === 'previous' && focusedItemIndex.current === 0);\n if (shouldWrap) {\n // we are at the end of the list so we will\n // scroll back to the beginning of the list\n if (hasSearch) {\n focusSearchBar();\n } else {\n // if at end, wrap to beginning, else focus last item\n focusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n }\n return;\n }\n switch (direction) {\n case 'next':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusNext();\n break;\n case 'previous':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusPrevious();\n break;\n default:\n break;\n }\n },\n [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]\n );\n\n const getItemProps = useCallback(\n (itemElem: ReactElement, index: number) => {\n const childProps = itemElem.props as MenuItemProps<T>;\n switch (itemElem.type) {\n case MenuItem:\n return {\n className: cx(childProps.className, menuItemClassName),\n // set focus on the first menu item if there is no search input, and set in the tab order\n onKeyDown: childProps.disabled\n ? () => undefined\n : (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: handleKeyboardFocusInteraction,\n handleFocusForward: handleKeyboardFocusInteraction,\n }),\n onFocus: chainEventHandlers(childProps.onFocus, () => {\n focusedItemIndex.current = index;\n }),\n id: createItemId(index, menuId.current),\n onBlur: chainEventHandlers(childProps.onBlur, () => {\n focusedItemIndex.current = null;\n }),\n onClick: childProps.disabled\n ? () => undefined\n : chainEventHandlers(childProps.onClick, () => {\n onSelect?.(childProps.item as T);\n }),\n } as MenuItemProps<T>;\n default:\n return {};\n }\n },\n [handleKeyboardFocusInteraction, menuItemClassName, onSelect]\n );\n\n useEffect(() => {\n if (nextFocusValue !== null) {\n requestAnimationFrame(() => {\n const element = getNodeForIndex(nextFocusValue, menuId.current);\n element?.focus();\n });\n setNextFocusValue(null);\n }\n }, [nextFocusValue]);\n\n /**\n * Calls handleFocusForward when the user is attempting to focus forward using\n * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n */\n const handleKeyboardFocusKeydown = (\n e: KeyboardEvent,\n callbacks: Record<\n 'handleFocusForward' | 'handleFocusBackward',\n (direction: 'next' | 'previous') => void\n >\n ) => {\n const keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n if (keyOps.includes(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n if ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n callbacks.handleFocusBackward?.('previous');\n } else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n callbacks.handleFocusForward?.('next');\n }\n }\n };\n\n const renderSearch = useMemo(\n () =>\n searchElement\n ? cloneElement(searchElement, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n handleFocusForward: () => focusMenuItem(0),\n }),\n ref: searchRef,\n })\n : null,\n [searchElement, lastVirtualItemIndex, focusMenuItem]\n );\n\n const renderItems = useMemo(\n () =>\n rowVirtualizer.virtualItems.map((virtualRow) => {\n if (!items) {\n return null;\n }\n const elem = items[virtualRow.index];\n return (\n <div\n key={virtualRow.index}\n ref={virtualRow.measureRef}\n role=\"presentation\"\n className={styles['VirtualMenu-item']}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {cloneElement(elem, getItemProps(elem, virtualRow.index))}\n </div>\n );\n }),\n [rowVirtualizer.virtualItems, items, getItemProps]\n );\n\n return (\n <>\n {renderSearch}\n <MenuItemList ref={parentRef} role=\"presentation\">\n <div\n role=\"presentation\"\n className={styles['VirtualMenu-item-list']}\n style={{\n height: `${rowVirtualizer.totalSize}px`,\n }}\n >\n {renderItems}\n </div>\n </MenuItemList>\n </>\n );\n};\n\nexport { Menu, ItemVirtualizer };\nexport type { MenuProps, ItemVirtualizerProps };\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":["import type { MenuProps } from './Menu';\nimport type { ComponentPropsWithRef } from 'react';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n isVirtual?: boolean;\n size?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n ({ children, size, isVirtual, ...props }, ref) => {\n const classes = cx('Menu', isVirtual && 'Menu--isVirtual', size && `MenuSize--${size}`);\n\n return (\n <div {...props} role=\"menu\" className={classes} ref={ref}>\n {children}\n </div>\n );\n }\n);\n\nMenuBase.displayName = 'MenuBase';\n\nexport { MenuBase };\nexport type { MenuBaseProps };\n","import type { SeparatorProps } from '@react-aria/separator';\nimport type { RefObject } from 'react';\n\nimport { useSeparator } from '@react-aria/separator';\n\nimport './styles/Menu.css';\n\ntype MenuDividerProps = SeparatorProps & {\n innerRef?: RefObject<HTMLDivElement>;\n 'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n elementType = 'div',\n orientation,\n innerRef,\n 'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n const { separatorProps } = useSeparator({\n orientation,\n elementType,\n });\n\n return <div {...separatorProps} data-test-id={testId} ref={innerRef} className=\"Menu-divider\" />;\n};\n\nexport { MenuDivider };\nexport type { MenuDividerProps };\n","import type { IconProps } from '@launchpad-ui/icons';\nimport type { PopoverPlacement } from '@launchpad-ui/popover';\nimport type { ComponentPropsWithRef, ElementType, PropsWithRef, ReactElement } from 'react';\n\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { Slot } from '@radix-ui/react-slot';\nimport { FocusRing } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport { cloneElement } from 'react';\n\nimport './styles/Menu.css';\n\n// Merge two types and get rid of overlapping definitions\ntype Merge<T, U> = Omit<T, keyof U> & U;\n\ntype PropsWithComponent<P, T extends ElementType> = P & { component?: T };\n\ntype PolymorphicPropsWithRef<P, T extends ElementType> = Merge<\n T extends keyof JSX.IntrinsicElements\n ? PropsWithRef<JSX.IntrinsicElements[T]>\n : ComponentPropsWithRef<T>,\n PropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n isHighlighted?: boolean;\n icon?: ReactElement<IconProps>;\n disabled?: boolean;\n nested?: boolean;\n groupHeader?: boolean;\n tooltip?: string | ReactElement;\n tooltipOptions?: typeof Tooltip;\n tooltipPlacement?: PopoverPlacement;\n asChild?: boolean;\n 'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n | (MenuItemOwnProps & {\n item: P; // Infer the type if it is included\n })\n | (MenuItemOwnProps & {\n item?: undefined;\n }),\n T\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n ...props\n}: MenuItemProps<P, T>) => {\n const {\n // TODO: remove component prop once we migrate over to asChild format\n component,\n children,\n isHighlighted,\n icon,\n nested,\n groupHeader,\n item,\n disabled,\n className,\n tooltip,\n role = 'menuitem',\n tooltipPlacement,\n onKeyDown,\n tooltipOptions,\n asChild,\n 'data-test-id': testId = 'menu-item',\n ...rest\n } = props;\n\n const Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n const renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n const renderedItem = (\n <FocusRing focusRingClass=\"has-focus\">\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n 'Menu-item',\n className,\n isHighlighted && 'is-highlighted',\n nested && 'Menu-item--nested',\n groupHeader && 'Menu-item--header'\n )}\n data-test-id={testId}\n role={role}\n onKeyDown={onKeyDown}\n >\n {asChild ? (\n children\n ) : (\n <>\n {icon && <span className=\"Menu-item-icon\">{renderIcon}</span>}\n {children}\n </>\n )}\n </Component>\n </FocusRing>\n );\n\n if (tooltip) {\n return (\n <Tooltip\n content={tooltip}\n rootElementStyle={{ display: 'block' }}\n allowBoundaryElementOverflow\n placement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n {...(tooltipOptions || {})}\n >\n {renderedItem}\n </Tooltip>\n );\n }\n\n return renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n <div {...rest} ref={ref} data-test-id=\"menu-item-list\" className=\"Menu-item-list\">\n {children}\n </div>\n));\n\nMenuItemList.displayName = 'MenuItemList';\n\nexport { MenuItemList };\nexport type { MenuItemListProps };\n","import type { ChangeEvent } from 'react';\n\nimport { TextField } from '@launchpad-ui/form';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuSearchProps = {\n ariaLabel?: string;\n value?: string;\n id?: string;\n placeholder?: string;\n onChange?(event: ChangeEvent<HTMLInputElement>): void;\n 'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n const {\n ariaLabel,\n placeholder,\n id,\n 'data-test-id': testId = 'menu-search',\n ...finalProps\n } = props;\n\n return (\n <div className=\"Menu-search\">\n <TextField\n {...finalProps}\n ref={ref}\n className=\"Menu-search-input\"\n tiny\n id={id}\n type=\"search\"\n data-test-id={testId}\n autoComplete=\"off\"\n placeholder={placeholder}\n aria-label={ariaLabel || 'Search'}\n />\n </div>\n );\n});\n\nMenuSearch.displayName = 'MenuSearch';\n\nexport { MenuSearch };\nexport type { MenuSearchProps };\n","import type { EventHandler, KeyboardEvent, SyntheticEvent } from 'react';\n\nconst createItemId = (index: number, id: string) => `${id}-item-${index}`;\n\nconst getNodeForIndex = (index: number | null, menuId: string) =>\n index === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n event: KeyboardEvent,\n keyHandlers: Partial<\n Record<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n >\n) => {\n const ops = {\n ArrowUp: keyHandlers.handleUp,\n ArrowDown: keyHandlers.handleDown,\n Enter: keyHandlers.handleEnter,\n } as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n if (ops[event.key]) {\n event.preventDefault();\n ops[event.key]?.call(globalThis, event);\n }\n};\n\nconst chainEventHandlers =\n (...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n (event: SyntheticEvent) => {\n handlers.forEach((h) => typeof h === 'function' && h(event));\n };\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { MenuItemProps } from './MenuItem';\nimport type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n Children,\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useVirtual } from 'react-virtual';\n\nimport { MenuBase } from './MenuBase';\nimport { MenuDivider } from './MenuDivider';\nimport { MenuItem } from './MenuItem';\nimport { MenuItemList } from './MenuItemList';\nimport { MenuSearch } from './MenuSearch';\nimport {\n chainEventHandlers,\n createItemId,\n getNodeForIndex,\n handleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n children: ReactNode;\n onSelect?: (item: T) => void;\n /**\n * Menus items are rendered using react-virtual for\n * additional rendering performance.\n */\n enableVirtualization?: boolean;\n /**\n * Class name to be applied to all MenuItem components\n * in the menu.\n */\n menuItemClassName?: string;\n /**\n * Sets the width of the menu. This is especially useful when using virtual items\n * since the width cannot be automatically set by the widest element.\n */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /**\n * Sets the number out of elements rendered outside of the view window\n * when using virtualization\n */\n overscan?: number;\n /**\n * Sets the height for each menu item when using virtualization.\n *\n */\n itemHeight?: number;\n 'data-test-id'?: string;\n};\n\ntype MenuProps<T extends number | string> = ControlledMenuProps<T>;\n\nconst Menu = <T extends number | string>(props: MenuProps<T>) => {\n const {\n children,\n menuItemClassName,\n onSelect,\n enableVirtualization,\n itemHeight,\n size,\n overscan = 1,\n 'data-test-id': testId = 'menu',\n } = props;\n\n const focusManager = useFocusManager();\n\n const handleArrowDown = useCallback(() => {\n focusManager?.focusNext({ wrap: true });\n }, [focusManager]);\n\n const handleArrowUp = useCallback(() => {\n focusManager?.focusPrevious({ wrap: true });\n }, [focusManager]);\n\n const reduceItems = useMemo(() => {\n const childrenProps = Children.toArray(children);\n if (enableVirtualization) {\n // the virtualized menu has its own handlers and props\n let searchElem = null;\n let elements: ReactElement[] = [];\n (childrenProps as ReactElement[]).forEach((child: ReactElement) => {\n switch (child.type) {\n case MenuSearch:\n searchElem = child;\n break;\n case MenuItem:\n case MenuDivider:\n elements = elements.concat(child);\n break;\n default:\n break;\n }\n });\n return { items: elements, searchElement: searchElem };\n }\n\n return (childrenProps as ReactElement[]).reduce(\n (\n { items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n child\n ) => {\n switch (child.type) {\n case MenuSearch:\n return {\n items,\n searchElement: cloneElement(child, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n }),\n };\n case MenuItem:\n return {\n items: items.concat(\n child.props.disabled\n ? cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n onClick: () => undefined,\n onKeyDown: () => undefined,\n tabIndex: -1,\n disabled: true,\n })\n : cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n item: child.props.item ?? items.length,\n // set focus on the first menu item if there is no search input, and set in the tab order\n onClick: chainEventHandlers(child.props.onClick, () => {\n onSelect?.(child.props.item ?? items.length);\n }),\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n })\n ),\n searchElement,\n };\n case MenuDivider:\n return { items: items.concat(child), searchElement };\n default:\n return { items, searchElement };\n }\n },\n { items: [], searchElement: null }\n );\n }, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n if (enableVirtualization) {\n return (\n <MenuBase data-test-id={testId} isVirtual size={size}>\n <ItemVirtualizer<T>\n items={Children.toArray(reduceItems.items) as ReactElement[]}\n searchElement={reduceItems.searchElement}\n overscan={overscan}\n menuItemClassName={menuItemClassName}\n onSelect={onSelect}\n itemHeight={itemHeight}\n focusManager={focusManager}\n />\n </MenuBase>\n );\n }\n\n return (\n <MenuBase data-test-id={testId} size={size}>\n {reduceItems.searchElement}\n <MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n </MenuBase>\n );\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n items: ReactElement[] | null;\n searchElement?: ReactElement | null;\n focusManager?: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n const {\n overscan,\n searchElement,\n itemHeight = 31.5,\n menuItemClassName,\n items: items,\n focusManager,\n onSelect,\n } = props;\n\n const menuId = useRef(`menu-ctrl-${useId()}`);\n\n const focusedItemIndex = useRef<number | null>(null);\n const parentRef = useRef<HTMLDivElement | null>(null);\n const searchRef = useRef<HTMLInputElement>();\n\n const [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n const hasSearch = !!searchElement;\n\n const lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n const rowVirtualizer = useVirtual({\n size: items !== null ? items.length : 0,\n parentRef,\n estimateSize: useCallback(() => itemHeight, [itemHeight]),\n overscan,\n });\n\n const focusSearchBar = useCallback(() => {\n rowVirtualizer.scrollToIndex(0);\n searchRef.current?.focus?.();\n }, [rowVirtualizer]);\n\n /**\n * Scrolls to the menu item with the index provided and\n * then manually focuses it using a side effect in useEffect\n */\n const focusMenuItem = useCallback(\n (index: number) => {\n rowVirtualizer.scrollToIndex(index);\n setNextFocusValue(index);\n },\n [rowVirtualizer]\n );\n\n const handleKeyboardFocusInteraction = useCallback(\n (direction: 'next' | 'previous') => {\n if (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n return;\n }\n const nextIndex =\n direction === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n const shouldWrap =\n (direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n (direction === 'previous' && focusedItemIndex.current === 0);\n if (shouldWrap) {\n // we are at the end of the list so we will\n // scroll back to the beginning of the list\n if (hasSearch) {\n focusSearchBar();\n } else {\n // if at end, wrap to beginning, else focus last item\n focusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n }\n return;\n }\n switch (direction) {\n case 'next':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager?.focusNext();\n break;\n case 'previous':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager?.focusPrevious();\n break;\n default:\n break;\n }\n },\n [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]\n );\n\n const getItemProps = useCallback(\n (itemElem: ReactElement, index: number) => {\n const childProps = itemElem.props as MenuItemProps<T>;\n switch (itemElem.type) {\n case MenuItem:\n return {\n className: cx(childProps.className, menuItemClassName),\n // set focus on the first menu item if there is no search input, and set in the tab order\n onKeyDown: childProps.disabled\n ? () => undefined\n : (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: handleKeyboardFocusInteraction,\n handleFocusForward: handleKeyboardFocusInteraction,\n }),\n onFocus: chainEventHandlers(childProps.onFocus, () => {\n focusedItemIndex.current = index;\n }),\n id: createItemId(index, menuId.current),\n onBlur: chainEventHandlers(childProps.onBlur, () => {\n focusedItemIndex.current = null;\n }),\n onClick: childProps.disabled\n ? () => undefined\n : chainEventHandlers(childProps.onClick, () => {\n onSelect?.(childProps.item as T);\n }),\n } as MenuItemProps<T>;\n default:\n return {};\n }\n },\n [handleKeyboardFocusInteraction, menuItemClassName, onSelect]\n );\n\n useEffect(() => {\n if (nextFocusValue !== null) {\n requestAnimationFrame(() => {\n const element = getNodeForIndex(nextFocusValue, menuId.current);\n element?.focus();\n });\n setNextFocusValue(null);\n }\n }, [nextFocusValue]);\n\n /**\n * Calls handleFocusForward when the user is attempting to focus forward using\n * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n */\n const handleKeyboardFocusKeydown = (\n e: KeyboardEvent,\n callbacks: Record<\n 'handleFocusForward' | 'handleFocusBackward',\n (direction: 'next' | 'previous') => void\n >\n ) => {\n const keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n if (keyOps.includes(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n if ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n callbacks.handleFocusBackward?.('previous');\n } else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n callbacks.handleFocusForward?.('next');\n }\n }\n };\n\n const renderSearch = useMemo(\n () =>\n searchElement\n ? cloneElement(searchElement, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n handleFocusForward: () => focusMenuItem(0),\n }),\n ref: searchRef,\n })\n : null,\n [searchElement, lastVirtualItemIndex, focusMenuItem]\n );\n\n const renderItems = useMemo(\n () =>\n rowVirtualizer.virtualItems.map((virtualRow) => {\n if (!items) {\n return null;\n }\n const elem = items[virtualRow.index];\n return (\n <div\n key={virtualRow.index}\n ref={virtualRow.measureRef}\n role=\"presentation\"\n className={cx('VirtualMenu-item')}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {cloneElement(elem, getItemProps(elem, virtualRow.index))}\n </div>\n );\n }),\n [rowVirtualizer.virtualItems, items, getItemProps]\n );\n\n return (\n <>\n {renderSearch}\n <MenuItemList ref={parentRef} role=\"presentation\">\n <div\n role=\"presentation\"\n className=\"VirtualMenu-item-list\"\n style={{\n height: `${rowVirtualizer.totalSize}px`,\n }}\n >\n {renderItems}\n </div>\n </MenuItemList>\n </>\n );\n};\n\nexport { Menu, ItemVirtualizer };\nexport type { MenuProps, ItemVirtualizerProps };\n"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -10,34 +10,10 @@ const reactSlot = require("@radix-ui/react-slot");
10
10
  const focus = require("@react-aria/focus");
11
11
  const form = require("@launchpad-ui/form");
12
12
  const reactVirtual = require("react-virtual");
13
- const Menu$1 = "_Menu_dlpdi_1";
14
- const styles = {
15
- "Menu-item": "_Menu-item_dlpdi_1",
16
- "Menu-item-list": "_Menu-item-list_dlpdi_22",
17
- Menu: Menu$1,
18
- "Menu-item--header": "_Menu-item--header_dlpdi_29",
19
- "has-focus": "_has-focus_dlpdi_35",
20
- "Menu-item--nested": "_Menu-item--nested_dlpdi_70",
21
- "Menu-item-icon": "_Menu-item-icon_dlpdi_79",
22
- "is-highlighted": "_is-highlighted_dlpdi_87",
23
- "Menu-divider": "_Menu-divider_dlpdi_97",
24
- "Menu-search": "_Menu-search_dlpdi_102",
25
- "Menu-search-hidden-placeholder": "_Menu-search-hidden-placeholder_dlpdi_111",
26
- "Menu--isVirtual": "_Menu--isVirtual_dlpdi_120",
27
- "MenuSize--xl": "_MenuSize--xl_dlpdi_126",
28
- "MenuSize--lg": "_MenuSize--lg_dlpdi_130",
29
- "MenuSize--md": "_MenuSize--md_dlpdi_134",
30
- "MenuSize--sm": "_MenuSize--sm_dlpdi_138",
31
- "VirtualMenu-item-list": "_VirtualMenu-item-list_dlpdi_142",
32
- "VirtualMenu-item": "_VirtualMenu-item_dlpdi_142"
33
- };
13
+ const Menu$1 = "";
34
14
  const MenuBase = /* @__PURE__ */ react.forwardRef(
35
15
  ({ children, size, isVirtual, ...props }, ref) => {
36
- const classes = classix.cx(
37
- styles.Menu,
38
- isVirtual && styles["Menu--isVirtual"],
39
- size && styles[`MenuSize--${size}`]
40
- );
16
+ const classes = classix.cx("Menu", isVirtual && "Menu--isVirtual", size && `MenuSize--${size}`);
41
17
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ...props, role: "menu", className: classes, ref, children });
42
18
  }
43
19
  );
@@ -52,15 +28,7 @@ const MenuDivider = ({
52
28
  orientation,
53
29
  elementType
54
30
  });
55
- return /* @__PURE__ */ jsxRuntime.jsx(
56
- "div",
57
- {
58
- ...separatorProps,
59
- "data-test-id": testId,
60
- ref: innerRef,
61
- className: styles["Menu-divider"]
62
- }
63
- );
31
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ...separatorProps, "data-test-id": testId, ref: innerRef, className: "Menu-divider" });
64
32
  };
65
33
  const defaultElement = "button";
66
34
  const MenuItem = ({
@@ -88,24 +56,24 @@ const MenuItem = ({
88
56
  } = props;
89
57
  const Component = component || (asChild ? reactSlot.Slot : defaultElement);
90
58
  const renderIcon = icon && /* @__PURE__ */ react.cloneElement(icon, { size: "small" });
91
- const renderedItem = /* @__PURE__ */ jsxRuntime.jsx(focus.FocusRing, { focusRingClass: styles["has-focus"], children: /* @__PURE__ */ jsxRuntime.jsx(
59
+ const renderedItem = /* @__PURE__ */ jsxRuntime.jsx(focus.FocusRing, { focusRingClass: "has-focus", children: /* @__PURE__ */ jsxRuntime.jsx(
92
60
  Component,
93
61
  {
94
62
  ...rest,
95
63
  disabled,
96
64
  "aria-disabled": disabled ? disabled : void 0,
97
65
  className: classix.cx(
98
- styles["Menu-item"],
66
+ "Menu-item",
99
67
  className,
100
- isHighlighted && styles["is-highlighted"],
101
- nested && styles["Menu-item--nested"],
102
- groupHeader && styles["Menu-item--header"]
68
+ isHighlighted && "is-highlighted",
69
+ nested && "Menu-item--nested",
70
+ groupHeader && "Menu-item--header"
103
71
  ),
104
72
  "data-test-id": testId,
105
73
  role,
106
74
  onKeyDown,
107
75
  children: asChild ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
108
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles["Menu-item-icon"], children: renderIcon }),
76
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "Menu-item-icon", children: renderIcon }),
109
77
  children
110
78
  ] })
111
79
  }
@@ -125,7 +93,7 @@ const MenuItem = ({
125
93
  }
126
94
  return renderedItem;
127
95
  };
128
- const MenuItemList = /* @__PURE__ */ react.forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ...rest, ref, "data-test-id": "menu-item-list", className: styles["Menu-item-list"], children }));
96
+ const MenuItemList = /* @__PURE__ */ react.forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ...rest, ref, "data-test-id": "menu-item-list", className: "Menu-item-list", children }));
129
97
  MenuItemList.displayName = "MenuItemList";
130
98
  const MenuSearch = /* @__PURE__ */ react.forwardRef((props, ref) => {
131
99
  const {
@@ -135,12 +103,12 @@ const MenuSearch = /* @__PURE__ */ react.forwardRef((props, ref) => {
135
103
  "data-test-id": testId = "menu-search",
136
104
  ...finalProps
137
105
  } = props;
138
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles["Menu-search"], children: /* @__PURE__ */ jsxRuntime.jsx(
106
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "Menu-search", children: /* @__PURE__ */ jsxRuntime.jsx(
139
107
  form.TextField,
140
108
  {
141
109
  ...finalProps,
142
110
  ref,
143
- className: styles["Menu-search-input"],
111
+ className: "Menu-search-input",
144
112
  tiny: true,
145
113
  id,
146
114
  type: "search",
@@ -182,10 +150,10 @@ const Menu = (props) => {
182
150
  } = props;
183
151
  const focusManager = focus.useFocusManager();
184
152
  const handleArrowDown = react.useCallback(() => {
185
- focusManager.focusNext({ wrap: true });
153
+ focusManager == null ? void 0 : focusManager.focusNext({ wrap: true });
186
154
  }, [focusManager]);
187
155
  const handleArrowUp = react.useCallback(() => {
188
- focusManager.focusPrevious({ wrap: true });
156
+ focusManager == null ? void 0 : focusManager.focusPrevious({ wrap: true });
189
157
  }, [focusManager]);
190
158
  const reduceItems = react.useMemo(() => {
191
159
  const childrenProps = react.Children.toArray(children);
@@ -323,11 +291,11 @@ const ItemVirtualizer = (props) => {
323
291
  switch (direction) {
324
292
  case "next":
325
293
  rowVirtualizer.scrollToIndex(nextIndex);
326
- focusManager.focusNext();
294
+ focusManager == null ? void 0 : focusManager.focusNext();
327
295
  break;
328
296
  case "previous":
329
297
  rowVirtualizer.scrollToIndex(nextIndex);
330
- focusManager.focusPrevious();
298
+ focusManager == null ? void 0 : focusManager.focusPrevious();
331
299
  break;
332
300
  }
333
301
  },
@@ -405,7 +373,7 @@ const ItemVirtualizer = (props) => {
405
373
  {
406
374
  ref: virtualRow.measureRef,
407
375
  role: "presentation",
408
- className: styles["VirtualMenu-item"],
376
+ className: classix.cx("VirtualMenu-item"),
409
377
  style: {
410
378
  transform: `translateY(${virtualRow.start}px)`
411
379
  },
@@ -422,7 +390,7 @@ const ItemVirtualizer = (props) => {
422
390
  "div",
423
391
  {
424
392
  role: "presentation",
425
- className: styles["VirtualMenu-item-list"],
393
+ className: "VirtualMenu-item-list",
426
394
  style: {
427
395
  height: `${rowVirtualizer.totalSize}px`
428
396
  },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":["import type { MenuProps } from './Menu';\nimport type { ComponentPropsWithRef } from 'react';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n isVirtual?: boolean;\n size?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n ({ children, size, isVirtual, ...props }, ref) => {\n const classes = cx(\n styles.Menu,\n isVirtual && styles['Menu--isVirtual'],\n size && styles[`MenuSize--${size}`]\n );\n\n return (\n <div {...props} role=\"menu\" className={classes} ref={ref}>\n {children}\n </div>\n );\n }\n);\n\nMenuBase.displayName = 'MenuBase';\n\nexport { MenuBase };\nexport type { MenuBaseProps };\n","import type { SeparatorProps } from '@react-aria/separator';\nimport type { RefObject } from 'react';\n\nimport { useSeparator } from '@react-aria/separator';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuDividerProps = SeparatorProps & {\n innerRef?: RefObject<HTMLDivElement>;\n 'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n elementType = 'div',\n orientation,\n innerRef,\n 'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n const { separatorProps } = useSeparator({\n orientation,\n elementType,\n });\n\n return (\n <div\n {...separatorProps}\n data-test-id={testId}\n ref={innerRef}\n className={styles['Menu-divider']}\n />\n );\n};\n\nexport { MenuDivider };\nexport type { MenuDividerProps };\n","import type { IconProps } from '@launchpad-ui/icons';\nimport type { PopoverPlacement } from '@launchpad-ui/popover';\nimport type { ComponentPropsWithRef, ElementType, PropsWithRef, ReactElement } from 'react';\n\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { Slot } from '@radix-ui/react-slot';\nimport { FocusRing } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport { cloneElement } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\n// Merge two types and get rid of overlapping definitions\ntype Merge<T, U> = Omit<T, keyof U> & U;\n\ntype PropsWithComponent<P, T extends ElementType> = P & { component?: T };\n\ntype PolymorphicPropsWithRef<P, T extends ElementType> = Merge<\n T extends keyof JSX.IntrinsicElements\n ? PropsWithRef<JSX.IntrinsicElements[T]>\n : ComponentPropsWithRef<T>,\n PropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n isHighlighted?: boolean;\n icon?: ReactElement<IconProps>;\n disabled?: boolean;\n nested?: boolean;\n groupHeader?: boolean;\n tooltip?: string | ReactElement;\n tooltipOptions?: typeof Tooltip;\n tooltipPlacement?: PopoverPlacement;\n asChild?: boolean;\n 'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n | (MenuItemOwnProps & {\n item: P; // Infer the type if it is included\n })\n | (MenuItemOwnProps & {\n item?: undefined;\n }),\n T\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n ...props\n}: MenuItemProps<P, T>) => {\n const {\n // TODO: remove component prop once we migrate over to asChild format\n component,\n children,\n isHighlighted,\n icon,\n nested,\n groupHeader,\n item,\n disabled,\n className,\n tooltip,\n role = 'menuitem',\n tooltipPlacement,\n onKeyDown,\n tooltipOptions,\n asChild,\n 'data-test-id': testId = 'menu-item',\n ...rest\n } = props;\n\n const Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n const renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n const renderedItem = (\n <FocusRing focusRingClass={styles['has-focus']}>\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n styles['Menu-item'],\n className,\n isHighlighted && styles['is-highlighted'],\n nested && styles['Menu-item--nested'],\n groupHeader && styles['Menu-item--header']\n )}\n data-test-id={testId}\n role={role}\n onKeyDown={onKeyDown}\n >\n {asChild ? (\n children\n ) : (\n <>\n {icon && <span className={styles['Menu-item-icon']}>{renderIcon}</span>}\n {children}\n </>\n )}\n </Component>\n </FocusRing>\n );\n\n if (tooltip) {\n return (\n <Tooltip\n content={tooltip}\n rootElementStyle={{ display: 'block' }}\n allowBoundaryElementOverflow\n placement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n {...(tooltipOptions || {})}\n >\n {renderedItem}\n </Tooltip>\n );\n }\n\n return renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n <div {...rest} ref={ref} data-test-id=\"menu-item-list\" className={styles['Menu-item-list']}>\n {children}\n </div>\n));\n\nMenuItemList.displayName = 'MenuItemList';\n\nexport { MenuItemList };\nexport type { MenuItemListProps };\n","import type { ChangeEvent } from 'react';\n\nimport { TextField } from '@launchpad-ui/form';\nimport { forwardRef } from 'react';\n\nimport styles from './styles/Menu.module.css';\n\ntype MenuSearchProps = {\n ariaLabel?: string;\n value?: string;\n id?: string;\n placeholder?: string;\n onChange?(event: ChangeEvent<HTMLInputElement>): void;\n 'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n const {\n ariaLabel,\n placeholder,\n id,\n 'data-test-id': testId = 'menu-search',\n ...finalProps\n } = props;\n\n return (\n <div className={styles['Menu-search']}>\n <TextField\n {...finalProps}\n ref={ref}\n className={styles['Menu-search-input']}\n tiny\n id={id}\n type=\"search\"\n data-test-id={testId}\n autoComplete=\"off\"\n placeholder={placeholder}\n aria-label={ariaLabel || 'Search'}\n />\n </div>\n );\n});\n\nMenuSearch.displayName = 'MenuSearch';\n\nexport { MenuSearch };\nexport type { MenuSearchProps };\n","import type { EventHandler, KeyboardEvent, SyntheticEvent } from 'react';\n\nconst createItemId = (index: number, id: string) => `${id}-item-${index}`;\n\nconst getNodeForIndex = (index: number | null, menuId: string) =>\n index === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n event: KeyboardEvent,\n keyHandlers: Partial<\n Record<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n >\n) => {\n const ops = {\n ArrowUp: keyHandlers.handleUp,\n ArrowDown: keyHandlers.handleDown,\n Enter: keyHandlers.handleEnter,\n } as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n if (ops[event.key]) {\n event.preventDefault();\n ops[event.key]?.call(globalThis, event);\n }\n};\n\nconst chainEventHandlers =\n (...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n (event: SyntheticEvent) => {\n handlers.forEach((h) => typeof h === 'function' && h(event));\n };\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { MenuItemProps } from './MenuItem';\nimport type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n Children,\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useVirtual } from 'react-virtual';\n\nimport { MenuBase } from './MenuBase';\nimport { MenuDivider } from './MenuDivider';\nimport { MenuItem } from './MenuItem';\nimport { MenuItemList } from './MenuItemList';\nimport { MenuSearch } from './MenuSearch';\nimport styles from './styles/Menu.module.css';\nimport {\n chainEventHandlers,\n createItemId,\n getNodeForIndex,\n handleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n children: ReactNode;\n onSelect?: (item: T) => void;\n /**\n * Menus items are rendered using react-virtual for\n * additional rendering performance.\n */\n enableVirtualization?: boolean;\n /**\n * Class name to be applied to all MenuItem components\n * in the menu.\n */\n menuItemClassName?: string;\n /**\n * Sets the width of the menu. This is especially useful when using virtual items\n * since the width cannot be automatically set by the widest element.\n */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /**\n * Sets the number out of elements rendered outside of the view window\n * when using virtualization\n */\n overscan?: number;\n /**\n * Sets the height for each menu item when using virtualization.\n *\n */\n itemHeight?: number;\n 'data-test-id'?: string;\n};\n\ntype MenuProps<T extends number | string> = ControlledMenuProps<T>;\n\nconst Menu = <T extends number | string>(props: MenuProps<T>) => {\n const {\n children,\n menuItemClassName,\n onSelect,\n enableVirtualization,\n itemHeight,\n size,\n overscan = 1,\n 'data-test-id': testId = 'menu',\n } = props;\n\n const focusManager = useFocusManager();\n\n const handleArrowDown = useCallback(() => {\n focusManager.focusNext({ wrap: true });\n }, [focusManager]);\n\n const handleArrowUp = useCallback(() => {\n focusManager.focusPrevious({ wrap: true });\n }, [focusManager]);\n\n const reduceItems = useMemo(() => {\n const childrenProps = Children.toArray(children);\n if (enableVirtualization) {\n // the virtualized menu has its own handlers and props\n let searchElem = null;\n let elements: ReactElement[] = [];\n (childrenProps as ReactElement[]).forEach((child: ReactElement) => {\n switch (child.type) {\n case MenuSearch:\n searchElem = child;\n break;\n case MenuItem:\n case MenuDivider:\n elements = elements.concat(child);\n break;\n default:\n break;\n }\n });\n return { items: elements, searchElement: searchElem };\n }\n\n return (childrenProps as ReactElement[]).reduce(\n (\n { items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n child\n ) => {\n switch (child.type) {\n case MenuSearch:\n return {\n items,\n searchElement: cloneElement(child, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n }),\n };\n case MenuItem:\n return {\n items: items.concat(\n child.props.disabled\n ? cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n onClick: () => undefined,\n onKeyDown: () => undefined,\n tabIndex: -1,\n disabled: true,\n })\n : cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n item: child.props.item ?? items.length,\n // set focus on the first menu item if there is no search input, and set in the tab order\n onClick: chainEventHandlers(child.props.onClick, () => {\n onSelect?.(child.props.item ?? items.length);\n }),\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n })\n ),\n searchElement,\n };\n case MenuDivider:\n return { items: items.concat(child), searchElement };\n default:\n return { items, searchElement };\n }\n },\n { items: [], searchElement: null }\n );\n }, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n if (enableVirtualization) {\n return (\n <MenuBase data-test-id={testId} isVirtual size={size}>\n <ItemVirtualizer<T>\n items={Children.toArray(reduceItems.items) as ReactElement[]}\n searchElement={reduceItems.searchElement}\n overscan={overscan}\n menuItemClassName={menuItemClassName}\n onSelect={onSelect}\n itemHeight={itemHeight}\n focusManager={focusManager}\n />\n </MenuBase>\n );\n }\n\n return (\n <MenuBase data-test-id={testId} size={size}>\n {reduceItems.searchElement}\n <MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n </MenuBase>\n );\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n items: ReactElement[] | null;\n searchElement?: ReactElement | null;\n focusManager: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n const {\n overscan,\n searchElement,\n itemHeight = 31.5,\n menuItemClassName,\n items: items,\n focusManager,\n onSelect,\n } = props;\n\n const menuId = useRef(`menu-ctrl-${useId()}`);\n\n const focusedItemIndex = useRef<number | null>(null);\n const parentRef = useRef<HTMLDivElement | null>(null);\n const searchRef = useRef<HTMLInputElement>();\n\n const [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n const hasSearch = !!searchElement;\n\n const lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n const rowVirtualizer = useVirtual({\n size: items !== null ? items.length : 0,\n parentRef,\n estimateSize: useCallback(() => itemHeight, [itemHeight]),\n overscan,\n });\n\n const focusSearchBar = useCallback(() => {\n rowVirtualizer.scrollToIndex(0);\n searchRef.current?.focus?.();\n }, [rowVirtualizer]);\n\n /**\n * Scrolls to the menu item with the index provided and\n * then manually focuses it using a side effect in useEffect\n */\n const focusMenuItem = useCallback(\n (index: number) => {\n rowVirtualizer.scrollToIndex(index);\n setNextFocusValue(index);\n },\n [rowVirtualizer]\n );\n\n const handleKeyboardFocusInteraction = useCallback(\n (direction: 'next' | 'previous') => {\n if (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n return;\n }\n const nextIndex =\n direction === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n const shouldWrap =\n (direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n (direction === 'previous' && focusedItemIndex.current === 0);\n if (shouldWrap) {\n // we are at the end of the list so we will\n // scroll back to the beginning of the list\n if (hasSearch) {\n focusSearchBar();\n } else {\n // if at end, wrap to beginning, else focus last item\n focusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n }\n return;\n }\n switch (direction) {\n case 'next':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusNext();\n break;\n case 'previous':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager.focusPrevious();\n break;\n default:\n break;\n }\n },\n [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]\n );\n\n const getItemProps = useCallback(\n (itemElem: ReactElement, index: number) => {\n const childProps = itemElem.props as MenuItemProps<T>;\n switch (itemElem.type) {\n case MenuItem:\n return {\n className: cx(childProps.className, menuItemClassName),\n // set focus on the first menu item if there is no search input, and set in the tab order\n onKeyDown: childProps.disabled\n ? () => undefined\n : (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: handleKeyboardFocusInteraction,\n handleFocusForward: handleKeyboardFocusInteraction,\n }),\n onFocus: chainEventHandlers(childProps.onFocus, () => {\n focusedItemIndex.current = index;\n }),\n id: createItemId(index, menuId.current),\n onBlur: chainEventHandlers(childProps.onBlur, () => {\n focusedItemIndex.current = null;\n }),\n onClick: childProps.disabled\n ? () => undefined\n : chainEventHandlers(childProps.onClick, () => {\n onSelect?.(childProps.item as T);\n }),\n } as MenuItemProps<T>;\n default:\n return {};\n }\n },\n [handleKeyboardFocusInteraction, menuItemClassName, onSelect]\n );\n\n useEffect(() => {\n if (nextFocusValue !== null) {\n requestAnimationFrame(() => {\n const element = getNodeForIndex(nextFocusValue, menuId.current);\n element?.focus();\n });\n setNextFocusValue(null);\n }\n }, [nextFocusValue]);\n\n /**\n * Calls handleFocusForward when the user is attempting to focus forward using\n * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n */\n const handleKeyboardFocusKeydown = (\n e: KeyboardEvent,\n callbacks: Record<\n 'handleFocusForward' | 'handleFocusBackward',\n (direction: 'next' | 'previous') => void\n >\n ) => {\n const keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n if (keyOps.includes(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n if ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n callbacks.handleFocusBackward?.('previous');\n } else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n callbacks.handleFocusForward?.('next');\n }\n }\n };\n\n const renderSearch = useMemo(\n () =>\n searchElement\n ? cloneElement(searchElement, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n handleFocusForward: () => focusMenuItem(0),\n }),\n ref: searchRef,\n })\n : null,\n [searchElement, lastVirtualItemIndex, focusMenuItem]\n );\n\n const renderItems = useMemo(\n () =>\n rowVirtualizer.virtualItems.map((virtualRow) => {\n if (!items) {\n return null;\n }\n const elem = items[virtualRow.index];\n return (\n <div\n key={virtualRow.index}\n ref={virtualRow.measureRef}\n role=\"presentation\"\n className={styles['VirtualMenu-item']}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {cloneElement(elem, getItemProps(elem, virtualRow.index))}\n </div>\n );\n }),\n [rowVirtualizer.virtualItems, items, getItemProps]\n );\n\n return (\n <>\n {renderSearch}\n <MenuItemList ref={parentRef} role=\"presentation\">\n <div\n role=\"presentation\"\n className={styles['VirtualMenu-item-list']}\n style={{\n height: `${rowVirtualizer.totalSize}px`,\n }}\n >\n {renderItems}\n </div>\n </MenuItemList>\n </>\n );\n};\n\nexport { Menu, ItemVirtualizer };\nexport type { MenuProps, ItemVirtualizerProps };\n"],"names":["forwardRef","cx","jsx","useSeparator","tooltip","Slot","cloneElement","FocusRing","jsxs","Fragment","Tooltip","TextField","useFocusManager","useCallback","useMemo","Children","useRef","useId","useState","useVirtual","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/MenuBase.tsx","../src/MenuDivider.tsx","../src/MenuItem.tsx","../src/MenuItemList.tsx","../src/MenuSearch.tsx","../src/utils.ts","../src/Menu.tsx"],"sourcesContent":["import type { MenuProps } from './Menu';\nimport type { ComponentPropsWithRef } from 'react';\n\nimport { cx } from 'classix';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuBaseProps = ComponentPropsWithRef<'div'> & {\n isVirtual?: boolean;\n size?: MenuProps<string>['size'];\n};\n\nconst MenuBase = forwardRef<HTMLDivElement, MenuBaseProps>(\n ({ children, size, isVirtual, ...props }, ref) => {\n const classes = cx('Menu', isVirtual && 'Menu--isVirtual', size && `MenuSize--${size}`);\n\n return (\n <div {...props} role=\"menu\" className={classes} ref={ref}>\n {children}\n </div>\n );\n }\n);\n\nMenuBase.displayName = 'MenuBase';\n\nexport { MenuBase };\nexport type { MenuBaseProps };\n","import type { SeparatorProps } from '@react-aria/separator';\nimport type { RefObject } from 'react';\n\nimport { useSeparator } from '@react-aria/separator';\n\nimport './styles/Menu.css';\n\ntype MenuDividerProps = SeparatorProps & {\n innerRef?: RefObject<HTMLDivElement>;\n 'data-test-id'?: string;\n};\n\nconst MenuDivider = ({\n elementType = 'div',\n orientation,\n innerRef,\n 'data-test-id': testId = 'menu-divider',\n}: MenuDividerProps) => {\n const { separatorProps } = useSeparator({\n orientation,\n elementType,\n });\n\n return <div {...separatorProps} data-test-id={testId} ref={innerRef} className=\"Menu-divider\" />;\n};\n\nexport { MenuDivider };\nexport type { MenuDividerProps };\n","import type { IconProps } from '@launchpad-ui/icons';\nimport type { PopoverPlacement } from '@launchpad-ui/popover';\nimport type { ComponentPropsWithRef, ElementType, PropsWithRef, ReactElement } from 'react';\n\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { Slot } from '@radix-ui/react-slot';\nimport { FocusRing } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport { cloneElement } from 'react';\n\nimport './styles/Menu.css';\n\n// Merge two types and get rid of overlapping definitions\ntype Merge<T, U> = Omit<T, keyof U> & U;\n\ntype PropsWithComponent<P, T extends ElementType> = P & { component?: T };\n\ntype PolymorphicPropsWithRef<P, T extends ElementType> = Merge<\n T extends keyof JSX.IntrinsicElements\n ? PropsWithRef<JSX.IntrinsicElements[T]>\n : ComponentPropsWithRef<T>,\n PropsWithComponent<P, T>\n>;\n\ntype MenuItemOwnProps = {\n isHighlighted?: boolean;\n icon?: ReactElement<IconProps>;\n disabled?: boolean;\n nested?: boolean;\n groupHeader?: boolean;\n tooltip?: string | ReactElement;\n tooltipOptions?: typeof Tooltip;\n tooltipPlacement?: PopoverPlacement;\n asChild?: boolean;\n 'data-test-id'?: string;\n};\n\nconst defaultElement = 'button';\n\ntype MenuItemProps<P, T extends ElementType = typeof defaultElement> = PolymorphicPropsWithRef<\n | (MenuItemOwnProps & {\n item: P; // Infer the type if it is included\n })\n | (MenuItemOwnProps & {\n item?: undefined;\n }),\n T\n>;\n\nconst MenuItem = <P, T extends ElementType = typeof defaultElement>({\n ...props\n}: MenuItemProps<P, T>) => {\n const {\n // TODO: remove component prop once we migrate over to asChild format\n component,\n children,\n isHighlighted,\n icon,\n nested,\n groupHeader,\n item,\n disabled,\n className,\n tooltip,\n role = 'menuitem',\n tooltipPlacement,\n onKeyDown,\n tooltipOptions,\n asChild,\n 'data-test-id': testId = 'menu-item',\n ...rest\n } = props;\n\n const Component: ElementType = component || (asChild ? Slot : defaultElement);\n\n const renderIcon = icon && cloneElement(icon, { size: 'small' });\n\n const renderedItem = (\n <FocusRing focusRingClass=\"has-focus\">\n <Component\n {...rest}\n disabled={disabled}\n aria-disabled={disabled ? disabled : undefined}\n className={cx(\n 'Menu-item',\n className,\n isHighlighted && 'is-highlighted',\n nested && 'Menu-item--nested',\n groupHeader && 'Menu-item--header'\n )}\n data-test-id={testId}\n role={role}\n onKeyDown={onKeyDown}\n >\n {asChild ? (\n children\n ) : (\n <>\n {icon && <span className=\"Menu-item-icon\">{renderIcon}</span>}\n {children}\n </>\n )}\n </Component>\n </FocusRing>\n );\n\n if (tooltip) {\n return (\n <Tooltip\n content={tooltip}\n rootElementStyle={{ display: 'block' }}\n allowBoundaryElementOverflow\n placement={tooltipPlacement ? tooltipPlacement : 'bottom'}\n {...(tooltipOptions || {})}\n >\n {renderedItem}\n </Tooltip>\n );\n }\n\n return renderedItem;\n};\n\nexport { MenuItem };\nexport type { MenuItemProps };\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuItemListProps = Omit<ComponentPropsWithRef<'div'>, 'className'>;\n\nconst MenuItemList = forwardRef<HTMLDivElement, MenuItemListProps>(({ children, ...rest }, ref) => (\n <div {...rest} ref={ref} data-test-id=\"menu-item-list\" className=\"Menu-item-list\">\n {children}\n </div>\n));\n\nMenuItemList.displayName = 'MenuItemList';\n\nexport { MenuItemList };\nexport type { MenuItemListProps };\n","import type { ChangeEvent } from 'react';\n\nimport { TextField } from '@launchpad-ui/form';\nimport { forwardRef } from 'react';\n\nimport './styles/Menu.css';\n\ntype MenuSearchProps = {\n ariaLabel?: string;\n value?: string;\n id?: string;\n placeholder?: string;\n onChange?(event: ChangeEvent<HTMLInputElement>): void;\n 'data-test-id'?: string;\n};\n\nconst MenuSearch = forwardRef<HTMLInputElement, MenuSearchProps>((props, ref) => {\n const {\n ariaLabel,\n placeholder,\n id,\n 'data-test-id': testId = 'menu-search',\n ...finalProps\n } = props;\n\n return (\n <div className=\"Menu-search\">\n <TextField\n {...finalProps}\n ref={ref}\n className=\"Menu-search-input\"\n tiny\n id={id}\n type=\"search\"\n data-test-id={testId}\n autoComplete=\"off\"\n placeholder={placeholder}\n aria-label={ariaLabel || 'Search'}\n />\n </div>\n );\n});\n\nMenuSearch.displayName = 'MenuSearch';\n\nexport { MenuSearch };\nexport type { MenuSearchProps };\n","import type { EventHandler, KeyboardEvent, SyntheticEvent } from 'react';\n\nconst createItemId = (index: number, id: string) => `${id}-item-${index}`;\n\nconst getNodeForIndex = (index: number | null, menuId: string) =>\n index === null ? index : document.getElementById(createItemId(index, menuId));\n\nconst handleKeyboardInteractions = (\n event: KeyboardEvent,\n keyHandlers: Partial<\n Record<'handleUp' | 'handleDown' | 'handleEnter', (e: KeyboardEvent) => void>\n >\n) => {\n const ops = {\n ArrowUp: keyHandlers.handleUp,\n ArrowDown: keyHandlers.handleDown,\n Enter: keyHandlers.handleEnter,\n } as Record<string, (e: KeyboardEvent) => void | undefined>;\n\n if (ops[event.key]) {\n event.preventDefault();\n ops[event.key]?.call(globalThis, event);\n }\n};\n\nconst chainEventHandlers =\n (...handlers: (EventHandler<SyntheticEvent> | undefined)[]) =>\n (event: SyntheticEvent) => {\n handlers.forEach((h) => typeof h === 'function' && h(event));\n };\n\nexport { createItemId, getNodeForIndex, handleKeyboardInteractions, chainEventHandlers };\n","import type { MenuItemProps } from './MenuItem';\nimport type { FocusManager } from '@react-aria/focus';\nimport type { KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { useFocusManager } from '@react-aria/focus';\nimport { cx } from 'classix';\nimport {\n Children,\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useVirtual } from 'react-virtual';\n\nimport { MenuBase } from './MenuBase';\nimport { MenuDivider } from './MenuDivider';\nimport { MenuItem } from './MenuItem';\nimport { MenuItemList } from './MenuItemList';\nimport { MenuSearch } from './MenuSearch';\nimport {\n chainEventHandlers,\n createItemId,\n getNodeForIndex,\n handleKeyboardInteractions,\n} from './utils';\n\ntype ControlledMenuProps<T> = {\n children: ReactNode;\n onSelect?: (item: T) => void;\n /**\n * Menus items are rendered using react-virtual for\n * additional rendering performance.\n */\n enableVirtualization?: boolean;\n /**\n * Class name to be applied to all MenuItem components\n * in the menu.\n */\n menuItemClassName?: string;\n /**\n * Sets the width of the menu. This is especially useful when using virtual items\n * since the width cannot be automatically set by the widest element.\n */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /**\n * Sets the number out of elements rendered outside of the view window\n * when using virtualization\n */\n overscan?: number;\n /**\n * Sets the height for each menu item when using virtualization.\n *\n */\n itemHeight?: number;\n 'data-test-id'?: string;\n};\n\ntype MenuProps<T extends number | string> = ControlledMenuProps<T>;\n\nconst Menu = <T extends number | string>(props: MenuProps<T>) => {\n const {\n children,\n menuItemClassName,\n onSelect,\n enableVirtualization,\n itemHeight,\n size,\n overscan = 1,\n 'data-test-id': testId = 'menu',\n } = props;\n\n const focusManager = useFocusManager();\n\n const handleArrowDown = useCallback(() => {\n focusManager?.focusNext({ wrap: true });\n }, [focusManager]);\n\n const handleArrowUp = useCallback(() => {\n focusManager?.focusPrevious({ wrap: true });\n }, [focusManager]);\n\n const reduceItems = useMemo(() => {\n const childrenProps = Children.toArray(children);\n if (enableVirtualization) {\n // the virtualized menu has its own handlers and props\n let searchElem = null;\n let elements: ReactElement[] = [];\n (childrenProps as ReactElement[]).forEach((child: ReactElement) => {\n switch (child.type) {\n case MenuSearch:\n searchElem = child;\n break;\n case MenuItem:\n case MenuDivider:\n elements = elements.concat(child);\n break;\n default:\n break;\n }\n });\n return { items: elements, searchElement: searchElem };\n }\n\n return (childrenProps as ReactElement[]).reduce(\n (\n { items, searchElement }: { items: ReactElement[]; searchElement: null | ReactElement },\n child\n ) => {\n switch (child.type) {\n case MenuSearch:\n return {\n items,\n searchElement: cloneElement(child, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n }),\n };\n case MenuItem:\n return {\n items: items.concat(\n child.props.disabled\n ? cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n onClick: () => undefined,\n onKeyDown: () => undefined,\n tabIndex: -1,\n disabled: true,\n })\n : cloneElement(child, {\n className: cx(child.props.className, menuItemClassName),\n item: child.props.item ?? items.length,\n // set focus on the first menu item if there is no search input, and set in the tab order\n onClick: chainEventHandlers(child.props.onClick, () => {\n onSelect?.(child.props.item ?? items.length);\n }),\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardInteractions(e, {\n handleDown: handleArrowDown,\n handleUp: handleArrowUp,\n }),\n })\n ),\n searchElement,\n };\n case MenuDivider:\n return { items: items.concat(child), searchElement };\n default:\n return { items, searchElement };\n }\n },\n { items: [], searchElement: null }\n );\n }, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);\n\n if (enableVirtualization) {\n return (\n <MenuBase data-test-id={testId} isVirtual size={size}>\n <ItemVirtualizer<T>\n items={Children.toArray(reduceItems.items) as ReactElement[]}\n searchElement={reduceItems.searchElement}\n overscan={overscan}\n menuItemClassName={menuItemClassName}\n onSelect={onSelect}\n itemHeight={itemHeight}\n focusManager={focusManager}\n />\n </MenuBase>\n );\n }\n\n return (\n <MenuBase data-test-id={testId} size={size}>\n {reduceItems.searchElement}\n <MenuItemList role=\"presentation\">{reduceItems.items}</MenuItemList>\n </MenuBase>\n );\n};\n\ntype ItemVirtualizerProps<T> = Omit<ControlledMenuProps<T>, 'children'> & {\n items: ReactElement[] | null;\n searchElement?: ReactElement | null;\n focusManager?: FocusManager;\n};\n\nconst ItemVirtualizer = <T extends number | string>(props: ItemVirtualizerProps<T>) => {\n const {\n overscan,\n searchElement,\n itemHeight = 31.5,\n menuItemClassName,\n items: items,\n focusManager,\n onSelect,\n } = props;\n\n const menuId = useRef(`menu-ctrl-${useId()}`);\n\n const focusedItemIndex = useRef<number | null>(null);\n const parentRef = useRef<HTMLDivElement | null>(null);\n const searchRef = useRef<HTMLInputElement>();\n\n const [nextFocusValue, setNextFocusValue] = useState<number | null>(null);\n\n const hasSearch = !!searchElement;\n\n const lastVirtualItemIndex = items ? items.length - 1 : 0;\n\n const rowVirtualizer = useVirtual({\n size: items !== null ? items.length : 0,\n parentRef,\n estimateSize: useCallback(() => itemHeight, [itemHeight]),\n overscan,\n });\n\n const focusSearchBar = useCallback(() => {\n rowVirtualizer.scrollToIndex(0);\n searchRef.current?.focus?.();\n }, [rowVirtualizer]);\n\n /**\n * Scrolls to the menu item with the index provided and\n * then manually focuses it using a side effect in useEffect\n */\n const focusMenuItem = useCallback(\n (index: number) => {\n rowVirtualizer.scrollToIndex(index);\n setNextFocusValue(index);\n },\n [rowVirtualizer]\n );\n\n const handleKeyboardFocusInteraction = useCallback(\n (direction: 'next' | 'previous') => {\n if (focusedItemIndex.current === null || focusedItemIndex.current === undefined) {\n return;\n }\n const nextIndex =\n direction === 'next' ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;\n const shouldWrap =\n (direction === 'next' && focusedItemIndex.current === lastVirtualItemIndex) ||\n (direction === 'previous' && focusedItemIndex.current === 0);\n if (shouldWrap) {\n // we are at the end of the list so we will\n // scroll back to the beginning of the list\n if (hasSearch) {\n focusSearchBar();\n } else {\n // if at end, wrap to beginning, else focus last item\n focusMenuItem(direction === 'next' ? 0 : lastVirtualItemIndex);\n }\n return;\n }\n switch (direction) {\n case 'next':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager?.focusNext();\n break;\n case 'previous':\n rowVirtualizer.scrollToIndex(nextIndex);\n focusManager?.focusPrevious();\n break;\n default:\n break;\n }\n },\n [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]\n );\n\n const getItemProps = useCallback(\n (itemElem: ReactElement, index: number) => {\n const childProps = itemElem.props as MenuItemProps<T>;\n switch (itemElem.type) {\n case MenuItem:\n return {\n className: cx(childProps.className, menuItemClassName),\n // set focus on the first menu item if there is no search input, and set in the tab order\n onKeyDown: childProps.disabled\n ? () => undefined\n : (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: handleKeyboardFocusInteraction,\n handleFocusForward: handleKeyboardFocusInteraction,\n }),\n onFocus: chainEventHandlers(childProps.onFocus, () => {\n focusedItemIndex.current = index;\n }),\n id: createItemId(index, menuId.current),\n onBlur: chainEventHandlers(childProps.onBlur, () => {\n focusedItemIndex.current = null;\n }),\n onClick: childProps.disabled\n ? () => undefined\n : chainEventHandlers(childProps.onClick, () => {\n onSelect?.(childProps.item as T);\n }),\n } as MenuItemProps<T>;\n default:\n return {};\n }\n },\n [handleKeyboardFocusInteraction, menuItemClassName, onSelect]\n );\n\n useEffect(() => {\n if (nextFocusValue !== null) {\n requestAnimationFrame(() => {\n const element = getNodeForIndex(nextFocusValue, menuId.current);\n element?.focus();\n });\n setNextFocusValue(null);\n }\n }, [nextFocusValue]);\n\n /**\n * Calls handleFocusForward when the user is attempting to focus forward using\n * tab or arrow keys. Calls handleFocusBackward when the users wants to move backward.\n */\n const handleKeyboardFocusKeydown = (\n e: KeyboardEvent,\n callbacks: Record<\n 'handleFocusForward' | 'handleFocusBackward',\n (direction: 'next' | 'previous') => void\n >\n ) => {\n const keyOps = ['Tab', 'ArrowUp', 'ArrowDown'];\n if (keyOps.includes(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n if ((e.key === 'Tab' && e.shiftKey) || e.key === 'ArrowUp') {\n callbacks.handleFocusBackward?.('previous');\n } else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n callbacks.handleFocusForward?.('next');\n }\n }\n };\n\n const renderSearch = useMemo(\n () =>\n searchElement\n ? cloneElement(searchElement, {\n onKeyDown: (e: KeyboardEvent) =>\n handleKeyboardFocusKeydown(e, {\n handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),\n handleFocusForward: () => focusMenuItem(0),\n }),\n ref: searchRef,\n })\n : null,\n [searchElement, lastVirtualItemIndex, focusMenuItem]\n );\n\n const renderItems = useMemo(\n () =>\n rowVirtualizer.virtualItems.map((virtualRow) => {\n if (!items) {\n return null;\n }\n const elem = items[virtualRow.index];\n return (\n <div\n key={virtualRow.index}\n ref={virtualRow.measureRef}\n role=\"presentation\"\n className={cx('VirtualMenu-item')}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {cloneElement(elem, getItemProps(elem, virtualRow.index))}\n </div>\n );\n }),\n [rowVirtualizer.virtualItems, items, getItemProps]\n );\n\n return (\n <>\n {renderSearch}\n <MenuItemList ref={parentRef} role=\"presentation\">\n <div\n role=\"presentation\"\n className=\"VirtualMenu-item-list\"\n style={{\n height: `${rowVirtualizer.totalSize}px`,\n }}\n >\n {renderItems}\n </div>\n </MenuItemList>\n </>\n );\n};\n\nexport { Menu, ItemVirtualizer };\nexport type { MenuProps, ItemVirtualizerProps };\n"],"names":["forwardRef","cx","jsx","useSeparator","tooltip","Slot","cloneElement","FocusRing","jsxs","Fragment","Tooltip","TextField","useFocusManager","useCallback","useMemo","Children","useRef","useId","useState","useVirtual","useEffect"],"mappings":"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"}
package/dist/style.css CHANGED
@@ -1,64 +1,84 @@
1
- ._Menu-item_dlpdi_1 {
2
- background-color: transparent;
3
- border-radius: var(--lp-border-radius-regular);
4
- border-width: var(--lp-border-width-100);
5
- color: var(--lp-color-text-ui-primary-base);
6
- cursor: pointer;
1
+ .Menu-item {
7
2
  display: block;
8
- font: var(--lp-label-1-medium);
9
- outline: none;
10
- overflow: hidden;
11
- padding-left: var(--lp-spacing-300);
12
- padding-right: var(--lp-spacing-300);
13
- padding-top: var(--lp-spacing-200);
14
- padding-bottom: var(--lp-spacing-200);
15
3
  position: relative;
16
- text-align: left;
4
+ color: var(--lp-color-text-ui-primary-base);
5
+ background: var(--lp-color-bg-overlay-primary);
17
6
  -webkit-text-decoration: none;
18
7
  text-decoration: none;
8
+ cursor: pointer;
9
+ outline: none;
10
+ padding: 0.375rem 1.5625rem;
11
+ text-align: left;
12
+ font-family: inherit;
13
+ font-size: 0.8125rem;
14
+ overflow: hidden;
19
15
  text-overflow: ellipsis;
16
+ white-space: nowrap;
20
17
  -webkit-user-select: none;
21
18
  -moz-user-select: none;
22
19
  user-select: none;
23
- white-space: nowrap;
20
+ line-height: inherit;
21
+ border-width: var(--lp-border-width-100);
24
22
  width: 100%;
25
23
  }
26
24
 
27
- ._Menu-item-list_dlpdi_22 {
28
- max-height: 55vh;
25
+ .Menu-item:first-child {
26
+ border-top-left-radius: var(--lp-border-radius-regular);
27
+ border-top-right-radius: var(--lp-border-radius-regular);
28
+ }
29
+
30
+ .Menu-item:last-child {
31
+ border-bottom-left-radius: var(--lp-border-radius-regular);
32
+ border-bottom-right-radius: var(--lp-border-radius-regular);
33
+ }
34
+
35
+ .Menu-item-list {
29
36
  min-width: 7.5rem;
30
37
  overflow: auto;
31
- padding: var(--lp-spacing-200);
38
+ max-height: 55vh;
32
39
  }
33
40
 
34
- ._Menu_dlpdi_1 ._Menu-item_dlpdi_1:not([disabled]):not([aria-disabled]):not(._Menu-item--header_dlpdi_29):active {
41
+ .Menu-item-list > .Menu-item:last-child {
42
+ border-bottom-left-radius: var(--lp-border-radius-regular);
43
+ border-bottom-right-radius: var(--lp-border-radius-regular);
44
+ }
45
+
46
+ .Menu .Menu-item:not([disabled]):not([aria-disabled]):active {
35
47
  -webkit-text-decoration: none;
36
48
  text-decoration: none;
37
- background-color: var(--lp-color-bg-interactive-secondary-active);
49
+ box-shadow: none;
50
+ background-color: var(--lp-color-blue-200);
51
+ color: var(--lp-color-blue-600);
38
52
  }
39
53
 
40
- ._Menu_dlpdi_1 ._Menu-item_dlpdi_1:not([disabled]):not([aria-disabled]):not(._Menu-item--header_dlpdi_29):hover:not(:active):not(._has-focus_dlpdi_35) {
54
+ .Menu .Menu-item:not([disabled]):not([aria-disabled]):hover:not(:active):not(.has-focus) {
41
55
  background-color: var(--lp-color-bg-interactive-secondary-hover);
56
+ box-shadow: inset 0 0 0 1px var(--lp-color-gray-600);
42
57
  }
43
58
 
44
- ._Menu_dlpdi_1 ._Menu-item_dlpdi_1:not([disabled]):not([aria-disabled]):not(._Menu-item--header_dlpdi_29)._has-focus_dlpdi_35 {
59
+ .Menu .Menu-item:not([disabled]):not([aria-disabled]).has-focus {
45
60
  background-color: var(--lp-color-bg-interactive-secondary-hover);
46
61
  box-shadow: inset 0 0 0 2px var(--lp-color-shadow-interactive-focus);
47
62
  }
48
63
 
49
- ._Menu_dlpdi_1 {
50
- background: var(--lp-color-bg-overlay-primary);
51
- border-radius: var(--lp-border-radius-medium);
64
+ /* stylelint-disable-next-line no-descending-specificity */
65
+
66
+ .Menu-item-list > .VirtualMenu-item-list .VirtualMenu-item:last-child .Menu-item {
67
+ border-bottom-left-radius: var(--lp-border-radius-regular);
68
+ border-bottom-right-radius: var(--lp-border-radius-regular);
69
+ }
70
+
71
+ .Menu {
52
72
  font-family: var(--lp-font-family-base);
53
73
  }
54
74
 
55
- ._Menu_dlpdi_1:focus {
75
+ .Menu:focus {
56
76
  outline: none;
57
77
  }
58
78
 
59
79
  /* Override our link styles for link component */
60
80
 
61
- ._Menu_dlpdi_1 a._Menu-item_dlpdi_1:focus:not(:hover):not(._has-focus_dlpdi_35) {
81
+ .Menu a.Menu-item:focus:not(:hover):not(.has-focus) {
62
82
  -webkit-text-decoration: none;
63
83
  text-decoration: none;
64
84
  box-shadow: none;
@@ -66,57 +86,83 @@
66
86
 
67
87
  /* Ensures that links that are disabled don't show active styles */
68
88
 
69
- ._Menu_dlpdi_1 a._Menu-item_dlpdi_1:active[disabled],
70
- ._Menu_dlpdi_1 a._Menu-item_dlpdi_1:active[aria-disabled] {
89
+ .Menu a.Menu-item:active[disabled],
90
+ .Menu a.Menu-item:active[aria-disabled] {
71
91
  -webkit-text-decoration: none;
72
92
  text-decoration: none;
73
93
  color: var(--lp-color-text-interactive-disabled);
74
94
  }
75
95
 
76
- ._Menu-item--nested_dlpdi_70 {
77
- padding-left: 2.5rem;
78
- }
96
+ /* stylelint-disable-next-line no-descending-specificity */
97
+
98
+ .Menu .Menu-item-list:first-child > .Menu-item:first-child, .Menu [hidden]:first-child + .Menu .Menu-item-list > .Menu-item:first-child {
99
+ border-top-left-radius: var(--lp-border-radius-regular);
100
+ border-top-right-radius: var(--lp-border-radius-regular);
101
+ }
79
102
 
80
- ._Menu-item--header_dlpdi_29 {
81
- font: var(--lp-small-1-regular);
82
- color: var(--lp-color-text-ui-tertiary);
103
+ .Menu .Menu-item-list:first-child > .VirtualMenu-item-list .VirtualMenu-item:first-child .Menu-item, .Menu [hidden]:first-child + .Menu .Menu-item-list > .VirtualMenu-item-list .VirtualMenu-item:first-child .Menu-item {
104
+ border-top-left-radius: var(--lp-border-radius-regular);
105
+ border-top-right-radius: var(--lp-border-radius-regular);
106
+ }
107
+
108
+ .Menu-item--nested {
109
+ padding-left: 2.5rem;
83
110
  }
84
111
 
85
- ._Menu-item-icon_dlpdi_79 {
86
- margin-right: var(--lp-spacing-300);
112
+ .Menu-item--header {
113
+ font-weight: var(--lp-font-weight-medium);
87
114
  }
88
115
 
89
- ._Menu-item_dlpdi_1 .Gravatar {
116
+ .Menu-item .Gravatar {
90
117
  margin-right: 0.3125rem;
91
118
  }
92
119
 
93
- ._Menu-item_dlpdi_1._is-highlighted_dlpdi_87 {
120
+ .Menu-item.is-highlighted {
94
121
  background-color: var(--lp-color-bg-interactive-secondary-hover);
122
+ box-shadow: inset 0 0 0 1px var(--lp-color-gray-600);
95
123
  }
96
124
 
97
- ._Menu-item_dlpdi_1[aria-disabled],
98
- ._Menu-item_dlpdi_1[disabled] {
125
+ .Menu-item.is-highlighted:active {
126
+ background-color: var(--lp-color-blue-200);
127
+ color: var(--lp-color-blue-600);
128
+ box-shadow: none;
129
+ }
130
+
131
+ .Menu-item[aria-disabled],
132
+ .Menu-item[disabled] {
99
133
  color: var(--lp-color-text-interactive-disabled);
100
134
  cursor: not-allowed;
101
135
  }
102
136
 
103
- ._Menu-divider_dlpdi_97 {
137
+ .Menu-item-icon {
138
+ position: absolute;
139
+ left: 0.3125rem;
140
+ top: 50%;
141
+ transform: translateY(-50%);
142
+ }
143
+
144
+ .Menu-divider {
104
145
  border-top: 1px solid var(--lp-color-border-ui-secondary);
105
- margin: var(--lp-spacing-200) 0;
106
146
  }
107
147
 
108
- ._Menu-search_dlpdi_102 {
109
- border-bottom: 1px solid var(--lp-color-border-ui-secondary);
110
- padding: var(--lp-spacing-300);
148
+ .Menu-search {
149
+ padding: 0.625rem;
150
+ font-size: 0.8125rem;
151
+ border-bottom: 1px solid var(--lp-color-border-ui-primary);
152
+ }
153
+
154
+ .Menu-search:first-child {
155
+ border-top-left-radius: var(--lp-border-radius-regular);
156
+ border-top-right-radius: var(--lp-border-radius-regular);
111
157
  }
112
158
 
113
- [class^='_Popover-content_'] ._Menu-search_dlpdi_102 {
159
+ [class^='_Popover-content_'] .Menu-search {
114
160
  width: 100%;
115
161
  }
116
162
 
117
163
  /* Removing anything that could give it some height */
118
164
 
119
- [class^='_Popover-content_'] ._Menu-search_dlpdi_102 ._Menu-search-hidden-placeholder_dlpdi_111 {
165
+ [class^='_Popover-content_'] .Menu-search .Menu-search-hidden-placeholder {
120
166
  padding-top: 0;
121
167
  padding-bottom: 0;
122
168
  height: 0;
@@ -124,34 +170,34 @@
124
170
  visibility: hidden;
125
171
  }
126
172
 
127
- ._Menu--isVirtual_dlpdi_120 {
173
+ .Menu--isVirtual {
128
174
  display: flex;
129
175
  align-items: stretch;
130
176
  flex-direction: column;
131
177
  }
132
178
 
133
- ._MenuSize--xl_dlpdi_126 {
179
+ .MenuSize--xl {
134
180
  width: 20rem;
135
181
  }
136
182
 
137
- ._MenuSize--lg_dlpdi_130 {
183
+ .MenuSize--lg {
138
184
  width: 15rem;
139
185
  }
140
186
 
141
- ._MenuSize--md_dlpdi_134 {
187
+ .MenuSize--md {
142
188
  width: 10rem;
143
189
  }
144
190
 
145
- ._MenuSize--sm_dlpdi_138 {
191
+ .MenuSize--sm {
146
192
  width: 7.5rem;
147
193
  }
148
194
 
149
- ._VirtualMenu-item-list_dlpdi_142 {
195
+ .VirtualMenu-item-list {
150
196
  width: 100%;
151
197
  position: relative;
152
198
  }
153
199
 
154
- ._VirtualMenu-item_dlpdi_142 {
200
+ .VirtualMenu-item {
155
201
  position: absolute;
156
202
  top: 0;
157
203
  left: 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@launchpad-ui/menu",
3
- "version": "0.12.5-alpha.0",
3
+ "version": "0.12.5",
4
4
  "status": "beta",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -26,16 +26,16 @@
26
26
  },
27
27
  "source": "src/index.ts",
28
28
  "dependencies": {
29
- "@radix-ui/react-slot": "^1.0.0",
30
- "@react-aria/focus": "3.14.3",
31
- "@react-aria/separator": "3.3.7",
29
+ "@radix-ui/react-slot": "1.0.2",
30
+ "@react-aria/focus": "3.15.0",
31
+ "@react-aria/separator": "3.3.8",
32
32
  "classix": "2.1.17",
33
33
  "react-virtual": "2.10.4",
34
- "@launchpad-ui/form": "~0.10.5-alpha.0",
35
- "@launchpad-ui/icons": "~0.14.5-alpha.0",
36
- "@launchpad-ui/popover": "~0.11.3-alpha.1",
37
- "@launchpad-ui/tokens": "~0.9.0-alpha.2",
38
- "@launchpad-ui/tooltip": "~0.8.3-alpha.1"
34
+ "@launchpad-ui/form": "~0.10.5",
35
+ "@launchpad-ui/icons": "~0.14.4",
36
+ "@launchpad-ui/popover": "~0.11.4",
37
+ "@launchpad-ui/tokens": "~0.8.2",
38
+ "@launchpad-ui/tooltip": "~0.8.4"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "react": "18.2.0",