@gridui/dropdown-menu 2.0.1 → 2.1.0

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/README.md CHANGED
@@ -48,6 +48,13 @@ and its `overlayListItemStyles()`, `overlayListLabelStyles()`, and
48
48
  a trailing 16px check slot in both selected and unselected states. Icons and text
49
49
  precede the check; RTL mirrors the order. Labels wrap within the available width.
50
50
 
51
+ Set `selectionAppearance` on `DropdownMenuContent` or `ContextMenu` to
52
+ `"filled"` (default) for a selected background plus the existing indicator, or
53
+ `"indicator"` for the indicator alone. The setting applies to every item in that
54
+ menu, including radio items with `data-state="checked"` and current-page links
55
+ with `aria-current="page"`. Links keep native navigation semantics and callers
56
+ supply their check indicator. Hover and keyboard-focus outlines are unchanged.
57
+
51
58
  Set `morph` on `DropdownMenuContent` to expand the menu from its trigger
52
59
  when opening. `respectReducedMotion` defaults to `true`. Set it to `false`
53
60
  to play the expansion even when the system requests reduced motion.
package/dist/index.js CHANGED
@@ -19,6 +19,10 @@ var DropdownMenu = (props) => {
19
19
  );
20
20
  };
21
21
 
22
+ // src/shared/selection-appearance.ts
23
+ import { createContext } from "react";
24
+ var MenuSelectionAppearance = createContext("filled");
25
+
22
26
  // src/dropdown-menu-content/style.ts
23
27
  import { overlayListStyles } from "@gridui/overlay";
24
28
  import { cn } from "@gridui/style-utils";
@@ -94,6 +98,7 @@ var DropdownMenuContent = (props) => {
94
98
  forceMount,
95
99
  sideOffset = 8,
96
100
  align = "end",
101
+ selectionAppearance = "filled",
97
102
  morph = false,
98
103
  respectReducedMotion = true,
99
104
  ...restProps
@@ -138,10 +143,16 @@ var DropdownMenuContent = (props) => {
138
143
  }
139
144
  );
140
145
  return /* @__PURE__ */ jsx2(
141
- Primitive2.Portal,
146
+ MenuSelectionAppearance,
142
147
  {
143
- forceMount,
144
- children: forceMount ? /* @__PURE__ */ jsx2(RetainedLayer, { children: content }) : content
148
+ value: selectionAppearance,
149
+ children: /* @__PURE__ */ jsx2(
150
+ Primitive2.Portal,
151
+ {
152
+ forceMount,
153
+ children: forceMount ? /* @__PURE__ */ jsx2(RetainedLayer, { children: content }) : content
154
+ }
155
+ )
145
156
  }
146
157
  );
147
158
  };
@@ -263,17 +274,19 @@ var ContextMenu = (props) => {
263
274
  import { overlayListItemStyles } from "@gridui/overlay";
264
275
  import { cn as cn3 } from "@gridui/style-utils";
265
276
  import * as Primitive4 from "@radix-ui/react-dropdown-menu";
277
+ import { useContext as useContext2 } from "react";
266
278
  import { jsx as jsx5 } from "react/jsx-runtime";
267
279
  var DropdownMenuItem = (props) => {
268
280
  const {
269
281
  className,
270
282
  ...restProps
271
283
  } = props;
284
+ const selectionAppearance = useContext2(MenuSelectionAppearance);
272
285
  return /* @__PURE__ */ jsx5(
273
286
  Primitive4.Item,
274
287
  {
275
288
  ...restProps,
276
- className: cn3(overlayListItemStyles(), className)
289
+ className: cn3(overlayListItemStyles({ selectionAppearance }), className)
277
290
  }
278
291
  );
279
292
  };
@@ -314,6 +327,7 @@ import { overlayListIndicatorStyles, overlayListItemStyles as overlayListItemSty
314
327
  import { cn as cn5 } from "@gridui/style-utils";
315
328
  import * as Primitive7 from "@radix-ui/react-dropdown-menu";
316
329
  import { Check } from "lucide-react";
330
+ import { useContext as useContext3 } from "react";
317
331
  import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
318
332
  var DropdownMenuRadioItem = (props) => {
319
333
  const {
@@ -321,11 +335,12 @@ var DropdownMenuRadioItem = (props) => {
321
335
  children,
322
336
  ...restProps
323
337
  } = props;
338
+ const selectionAppearance = useContext3(MenuSelectionAppearance);
324
339
  return /* @__PURE__ */ jsxs2(
325
340
  Primitive7.RadioItem,
326
341
  {
327
342
  ...restProps,
328
- className: cn5(overlayListItemStyles2(), className),
343
+ className: cn5(overlayListItemStyles2({ selectionAppearance }), className),
329
344
  children: [
330
345
  /* @__PURE__ */ jsx8(
331
346
  "span",
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/dropdown-menu/dropdown-menu.tsx", "../src/dropdown-menu-content/style.ts", "../src/dropdown-menu-content/use-menu-morph.ts", "../src/dropdown-menu-content/dropdown-menu-content.tsx", "../src/dropdown-menu-trigger/dropdown-menu-trigger.tsx", "../src/context-menu/context-menu.tsx", "../src/dropdown-menu-item/dropdown-menu-item.tsx", "../src/dropdown-menu-label/dropdown-menu-label.tsx", "../src/dropdown-menu-radio-group/dropdown-menu-radio-group.tsx", "../src/dropdown-menu-radio-item/dropdown-menu-radio-item.tsx"],
4
- "sourcesContent": ["/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenu\n * @description Dropdown Menu\n */\n\nimport { OverlayOpen, useOverlayState } from \"@gridui/overlay\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuProps = ComponentPropsWithRef<typeof Primitive.Root>;\n\nexport const DropdownMenu: FC<DropdownMenuProps> = (props: DropdownMenuProps) => {\n const state = useOverlayState(props);\n return (<OverlayOpen.Provider\n value={state.open}\n >\n <Primitive.Root\n {...props}\n {...state}\n />\n </OverlayOpen.Provider>);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuContent\n * @description Style\n */\n\nimport { overlayListStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownContentStyles = cva(cn(\n overlayListStyles(),\n \"gridui-dropdown-content\",\n \"gridui-u-dropdown-menu--min-w-44 gridui-u-dropdown-menu--max-w-[calc(100vw-2*var(--gridui-page-gutter))] gridui-u-dropdown-menu--max-h-(--radix-dropdown-menu-content-available-height) gridui-u-dropdown-menu--overflow-y-auto\",\n));\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuContent\n * @description Use Menu Morph\n */\n\nimport { useLayoutEffect } from \"react\";\n\nexport const useMenuMorph = (element: HTMLDivElement | null, enabled: boolean): void => {\n useLayoutEffect(() => {\n if (!element || !enabled) {\n return;\n }\n const place = () => {\n // Radix suppresses entrance animations until the menu has been positioned.\n if (element.style.animation === \"none\") {\n return;\n }\n observer.disconnect();\n const document = element.ownerDocument;\n const trigger = document.getElementById(element.getAttribute(\"aria-labelledby\") ?? \"\");\n if (!trigger) {\n return;\n }\n element.setAttribute(\"data-morph-measuring\", \"\");\n const menu = element.getBoundingClientRect();\n element.removeAttribute(\"data-morph-measuring\");\n const anchor = trigger.getBoundingClientRect();\n const width = Math.min(menu.width, anchor.width);\n const height = Math.min(menu.height, anchor.height);\n if (!width || !height) {\n return;\n }\n const x = anchor.left + (anchor.width - width) / 2 - menu.left;\n const y = anchor.top + (anchor.height - height) / 2 - menu.top;\n const left = Math.max(0, Math.min(x, menu.width - width));\n const top = Math.max(0, Math.min(y, menu.height - height));\n element.style.setProperty(\"--gridui-menu-morph-clip\", `inset(${top}px ${menu.width - width - left}px ${menu.height - height - top}px ${left}px)`);\n element.style.setProperty(\"--gridui-menu-morph-offset\", `${x - left}px, ${y - top}px`);\n element.setAttribute(\"data-morph-ready\", \"\");\n };\n const observer = new MutationObserver(place);\n observer.observe(element, {\n attributes: true,\n attributeFilter: [\"style\"],\n });\n place();\n return () => {\n observer.disconnect();\n element.removeAttribute(\"data-morph-ready\");\n element.style.removeProperty(\"--gridui-menu-morph-clip\");\n element.style.removeProperty(\"--gridui-menu-morph-offset\");\n };\n }, [\n element,\n enabled,\n ]);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuContent\n * @description Dropdown Menu Content\n */\n\nimport type { MenuContentOptions } from \"../shared/menu-content-options\";\nimport { dropdownContentStyles } from \"./style\";\nimport { useMenuMorph } from \"./use-menu-morph\";\nimport { interactionLayerProps, OverlayOpen, RetainedLayer, useInteractionOutline, useScrollbars } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { FC } from \"react\";\nimport { useCallback, useContext, useState } from \"react\";\n\nexport type DropdownMenuContentProps = MenuContentOptions;\n\nexport const DropdownMenuContent: FC<DropdownMenuContentProps> = (props: DropdownMenuContentProps) => {\n const {\n className,\n ref: forwardedRef,\n forceMount,\n sideOffset = 8,\n align = \"end\",\n morph = false,\n respectReducedMotion = true,\n ...restProps\n } = props;\n const open = useContext(OverlayOpen);\n const [\n element,\n setElement,\n ] = useState<HTMLDivElement | null>(null);\n const morphRef = useCallback((node: HTMLDivElement | null) => {\n setElement(node);\n if (typeof forwardedRef === \"function\") {\n const cleanup = forwardedRef(node);\n if (cleanup) {\n return () => {\n setElement(null);\n cleanup();\n };\n }\n } else if (forwardedRef) {\n forwardedRef.current = node;\n }\n return undefined;\n }, [forwardedRef]);\n useMenuMorph(element, morph && open === true);\n const scrollbarRef = useScrollbars({ ref: morph ? morphRef : forwardedRef });\n const ref = useInteractionOutline({\n ref: scrollbarRef,\n selector: '[role^=\"menuitem\"]',\n });\n const content = (<Primitive.Content\n {...interactionLayerProps}\n {...restProps}\n ref={ref}\n forceMount={forceMount}\n align={align}\n sideOffset={sideOffset}\n data-morph-ignore-reduced-motion={!respectReducedMotion || undefined}\n className={cn(dropdownContentStyles(), className)}\n />);\n return (<Primitive.Portal\n forceMount={forceMount}\n >\n {forceMount ? (<RetainedLayer>\n {content}\n </RetainedLayer>) : content}\n </Primitive.Portal>);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuTrigger\n * @description Dropdown Menu Trigger\n */\n\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuTriggerProps = ComponentPropsWithRef<typeof Primitive.Trigger>;\n\nexport const DropdownMenuTrigger: FC<DropdownMenuTriggerProps> = (props: DropdownMenuTriggerProps) => {\n return (<Primitive.Trigger\n {...props}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace ContextMenu\n * @description Context Menu\n */\n\nimport { DropdownMenu, type DropdownMenuProps } from \"../dropdown-menu/dropdown-menu\";\nimport { DropdownMenuContent } from \"../dropdown-menu-content/dropdown-menu-content\";\nimport { DropdownMenuTrigger } from \"../dropdown-menu-trigger/dropdown-menu-trigger\";\nimport type { MenuContentOptions } from \"../shared/menu-content-options\";\nimport { type FC, type ReactNode, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nexport type ContextMenuProps = Omit<MenuContentOptions, \"children\"> & Pick<DropdownMenuProps, \"dir\"> & {\n readonly x: number;\n readonly y: number;\n readonly label: string;\n readonly children: ReactNode;\n readonly onClose: () => void;\n};\n\n/** Uses the same menu semantics and presentation as trigger-based dropdowns. */\nexport const ContextMenu: FC<ContextMenuProps> = (props: ContextMenuProps) => {\n const { x, y, label, dir, children, onClose, onCloseAutoFocus, onKeyDown, onPointerUpCapture, ...contentProps } = props;\n\n const [returnFocus] = useState(() => {\n return typeof document === \"undefined\" ? null : document.activeElement;\n });\n useEffect(() => {\n\n const dismissWhenInactive = () => {\n\n if (!document.hasFocus()) {\n onClose();\n }\n };\n window.addEventListener(\"blur\", dismissWhenInactive);\n\n return () => {\n\n window.removeEventListener(\"blur\", dismissWhenInactive);\n };\n }, [onClose]);\n\n if (typeof document === \"undefined\") {\n return null;\n }\n return createPortal((<DropdownMenu\n key={`${x}:${y}`}\n open\n modal={false}\n dir={dir}\n onOpenChange={open => {\n\n if (!open) {\n onClose();\n }\n }}\n >\n <DropdownMenuTrigger\n asChild\n >\n <button\n type=\"button\"\n tabIndex={-1}\n aria-hidden=\"true\"\n style={{\n position: \"fixed\",\n left: x,\n top: y,\n width: 0,\n height: 0,\n padding: 0,\n border: 0,\n opacity: 0,\n pointerEvents: \"none\",\n }}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent\n aria-label={label}\n side=\"bottom\"\n align=\"start\"\n sideOffset={0}\n collisionPadding={8}\n {...contentProps}\n onPointerUpCapture={event => {\n onPointerUpCapture?.(event);\n // The release that opens a flush context menu must not select its first item.\n if (event.button !== 0 || event.ctrlKey) {\n event.preventDefault();\n }\n }}\n onCloseAutoFocus={event => {\n onCloseAutoFocus?.(event);\n if (event.defaultPrevented) {\n return;\n }\n event.preventDefault();\n if (document.activeElement === document.body\n && returnFocus instanceof HTMLElement\n && returnFocus.isConnected) {\n returnFocus.focus();\n }\n }}\n onKeyDown={event => {\n\n onKeyDown?.(event);\n if (!event.defaultPrevented && event.key === \"Tab\") {\n event.preventDefault();\n onClose();\n }\n }}\n >\n {children}\n </DropdownMenuContent>\n </DropdownMenu>), document.body);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuItem\n * @description Dropdown Menu Item\n */\n\nimport { overlayListItemStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuItemProps = ComponentPropsWithRef<typeof Primitive.Item>;\n\nexport const DropdownMenuItem: FC<DropdownMenuItemProps> = (props: DropdownMenuItemProps) => {\n const {\n className,\n ...restProps\n } = props;\n return (<Primitive.Item\n {...restProps}\n className={cn(overlayListItemStyles(), className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuLabel\n * @description Dropdown Menu Label\n */\n\nimport { overlayListLabelStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuLabelProps = ComponentPropsWithRef<typeof Primitive.Label>;\n\nexport const DropdownMenuLabel: FC<DropdownMenuLabelProps> = (props: DropdownMenuLabelProps) => {\n const {\n className,\n ...restProps\n } = props;\n return (<Primitive.Label\n {...restProps}\n className={cn(overlayListLabelStyles(), className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuRadioGroup\n * @description Dropdown Menu Radio Group\n */\n\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuRadioGroupProps = ComponentPropsWithRef<typeof Primitive.RadioGroup>;\n\nexport const DropdownMenuRadioGroup: FC<DropdownMenuRadioGroupProps> = (props: DropdownMenuRadioGroupProps) => {\n return (<Primitive.RadioGroup\n {...props}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuRadioItem\n * @description Dropdown Menu Radio Item\n */\n\nimport { overlayListIndicatorStyles, overlayListItemStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport { Check } from \"lucide-react\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuRadioItemProps = ComponentPropsWithRef<typeof Primitive.RadioItem>;\n\nexport const DropdownMenuRadioItem: FC<DropdownMenuRadioItemProps> = (props: DropdownMenuRadioItemProps) => {\n const {\n className,\n children,\n ...restProps\n } = props;\n return (<Primitive.RadioItem\n {...restProps}\n className={cn(overlayListItemStyles(), className)}\n >\n <span\n className=\"gridui-u-dropdown-menu--flex gridui-u-dropdown-menu--min-w-0 gridui-u-dropdown-menu--flex-1 gridui-u-dropdown-menu--items-center gridui-u-dropdown-menu--gap-gridui-8\"\n >\n {children}\n </span>\n <span\n className={cn(overlayListIndicatorStyles())}\n aria-hidden=\"true\"\n >\n <Primitive.ItemIndicator>\n <Check\n size={16}\n aria-hidden=\"true\"\n />\n </Primitive.ItemIndicator>\n </span>\n </Primitive.RadioItem>);\n};\n"],
5
- "mappings": "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",
6
- "names": ["document", "OverlayOpen", "cn", "Primitive", "jsx", "Primitive", "jsx", "useState", "jsx", "cn", "Primitive", "jsx", "cn", "Primitive", "jsx", "Primitive", "jsx", "overlayListItemStyles", "cn", "Primitive", "jsx", "jsxs"]
3
+ "sources": ["../src/dropdown-menu/dropdown-menu.tsx", "../src/shared/selection-appearance.ts", "../src/dropdown-menu-content/style.ts", "../src/dropdown-menu-content/use-menu-morph.ts", "../src/dropdown-menu-content/dropdown-menu-content.tsx", "../src/dropdown-menu-trigger/dropdown-menu-trigger.tsx", "../src/context-menu/context-menu.tsx", "../src/dropdown-menu-item/dropdown-menu-item.tsx", "../src/dropdown-menu-label/dropdown-menu-label.tsx", "../src/dropdown-menu-radio-group/dropdown-menu-radio-group.tsx", "../src/dropdown-menu-radio-item/dropdown-menu-radio-item.tsx"],
4
+ "sourcesContent": ["/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenu\n * @description Dropdown Menu\n */\n\nimport { OverlayOpen, useOverlayState } from \"@gridui/overlay\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuProps = ComponentPropsWithRef<typeof Primitive.Root>;\n\nexport const DropdownMenu: FC<DropdownMenuProps> = (props: DropdownMenuProps) => {\n const state = useOverlayState(props);\n return (<OverlayOpen.Provider\n value={state.open}\n >\n <Primitive.Root\n {...props}\n {...state}\n />\n </OverlayOpen.Provider>);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace Shared\n * @description Selection Appearance\n */\n\nimport type { overlayListItemStyles } from \"@gridui/overlay\";\nimport type { VariantProps } from \"class-variance-authority\";\nimport { createContext } from \"react\";\n\nexport type SelectionAppearance = NonNullable<VariantProps<typeof overlayListItemStyles>[\"selectionAppearance\"]>;\n\nexport const MenuSelectionAppearance = createContext<SelectionAppearance>(\"filled\");\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuContent\n * @description Style\n */\n\nimport { overlayListStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownContentStyles = cva(cn(\n overlayListStyles(),\n \"gridui-dropdown-content\",\n \"gridui-u-dropdown-menu--min-w-44 gridui-u-dropdown-menu--max-w-[calc(100vw-2*var(--gridui-page-gutter))] gridui-u-dropdown-menu--max-h-(--radix-dropdown-menu-content-available-height) gridui-u-dropdown-menu--overflow-y-auto\",\n));\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuContent\n * @description Use Menu Morph\n */\n\nimport { useLayoutEffect } from \"react\";\n\nexport const useMenuMorph = (element: HTMLDivElement | null, enabled: boolean): void => {\n useLayoutEffect(() => {\n if (!element || !enabled) {\n return;\n }\n const place = () => {\n // Radix suppresses entrance animations until the menu has been positioned.\n if (element.style.animation === \"none\") {\n return;\n }\n observer.disconnect();\n const document = element.ownerDocument;\n const trigger = document.getElementById(element.getAttribute(\"aria-labelledby\") ?? \"\");\n if (!trigger) {\n return;\n }\n element.setAttribute(\"data-morph-measuring\", \"\");\n const menu = element.getBoundingClientRect();\n element.removeAttribute(\"data-morph-measuring\");\n const anchor = trigger.getBoundingClientRect();\n const width = Math.min(menu.width, anchor.width);\n const height = Math.min(menu.height, anchor.height);\n if (!width || !height) {\n return;\n }\n const x = anchor.left + (anchor.width - width) / 2 - menu.left;\n const y = anchor.top + (anchor.height - height) / 2 - menu.top;\n const left = Math.max(0, Math.min(x, menu.width - width));\n const top = Math.max(0, Math.min(y, menu.height - height));\n element.style.setProperty(\"--gridui-menu-morph-clip\", `inset(${top}px ${menu.width - width - left}px ${menu.height - height - top}px ${left}px)`);\n element.style.setProperty(\"--gridui-menu-morph-offset\", `${x - left}px, ${y - top}px`);\n element.setAttribute(\"data-morph-ready\", \"\");\n };\n const observer = new MutationObserver(place);\n observer.observe(element, {\n attributes: true,\n attributeFilter: [\"style\"],\n });\n place();\n return () => {\n observer.disconnect();\n element.removeAttribute(\"data-morph-ready\");\n element.style.removeProperty(\"--gridui-menu-morph-clip\");\n element.style.removeProperty(\"--gridui-menu-morph-offset\");\n };\n }, [\n element,\n enabled,\n ]);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuContent\n * @description Dropdown Menu Content\n */\n\nimport type { MenuContentOptions } from \"../shared/menu-content-options\";\nimport { MenuSelectionAppearance } from \"../shared/selection-appearance\";\nimport { dropdownContentStyles } from \"./style\";\nimport { useMenuMorph } from \"./use-menu-morph\";\nimport { interactionLayerProps, OverlayOpen, RetainedLayer, useInteractionOutline, useScrollbars } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { FC } from \"react\";\nimport { useCallback, useContext, useState } from \"react\";\n\nexport type DropdownMenuContentProps = MenuContentOptions;\n\nexport const DropdownMenuContent: FC<DropdownMenuContentProps> = (props: DropdownMenuContentProps) => {\n const {\n className,\n ref: forwardedRef,\n forceMount,\n sideOffset = 8,\n align = \"end\",\n selectionAppearance = \"filled\",\n morph = false,\n respectReducedMotion = true,\n ...restProps\n } = props;\n const open = useContext(OverlayOpen);\n const [\n element,\n setElement,\n ] = useState<HTMLDivElement | null>(null);\n const morphRef = useCallback((node: HTMLDivElement | null) => {\n setElement(node);\n if (typeof forwardedRef === \"function\") {\n const cleanup = forwardedRef(node);\n if (cleanup) {\n return () => {\n setElement(null);\n cleanup();\n };\n }\n } else if (forwardedRef) {\n forwardedRef.current = node;\n }\n return undefined;\n }, [forwardedRef]);\n useMenuMorph(element, morph && open === true);\n const scrollbarRef = useScrollbars({ ref: morph ? morphRef : forwardedRef });\n const ref = useInteractionOutline({\n ref: scrollbarRef,\n selector: '[role^=\"menuitem\"]',\n });\n const content = (<Primitive.Content\n {...interactionLayerProps}\n {...restProps}\n ref={ref}\n forceMount={forceMount}\n align={align}\n sideOffset={sideOffset}\n data-morph-ignore-reduced-motion={!respectReducedMotion || undefined}\n className={cn(dropdownContentStyles(), className)}\n />);\n return (<MenuSelectionAppearance\n value={selectionAppearance}\n >\n <Primitive.Portal\n forceMount={forceMount}\n >\n {forceMount ? (<RetainedLayer>\n {content}\n </RetainedLayer>) : content}\n </Primitive.Portal>\n </MenuSelectionAppearance>);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuTrigger\n * @description Dropdown Menu Trigger\n */\n\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuTriggerProps = ComponentPropsWithRef<typeof Primitive.Trigger>;\n\nexport const DropdownMenuTrigger: FC<DropdownMenuTriggerProps> = (props: DropdownMenuTriggerProps) => {\n return (<Primitive.Trigger\n {...props}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace ContextMenu\n * @description Context Menu\n */\n\nimport { DropdownMenu, type DropdownMenuProps } from \"../dropdown-menu/dropdown-menu\";\nimport { DropdownMenuContent } from \"../dropdown-menu-content/dropdown-menu-content\";\nimport { DropdownMenuTrigger } from \"../dropdown-menu-trigger/dropdown-menu-trigger\";\nimport type { MenuContentOptions } from \"../shared/menu-content-options\";\nimport { type FC, type ReactNode, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nexport type ContextMenuProps = Omit<MenuContentOptions, \"children\"> & Pick<DropdownMenuProps, \"dir\"> & {\n readonly x: number;\n readonly y: number;\n readonly label: string;\n readonly children: ReactNode;\n readonly onClose: () => void;\n};\n\n/** Uses the same menu semantics and presentation as trigger-based dropdowns. */\nexport const ContextMenu: FC<ContextMenuProps> = (props: ContextMenuProps) => {\n const { x, y, label, dir, children, onClose, onCloseAutoFocus, onKeyDown, onPointerUpCapture, ...contentProps } = props;\n\n const [returnFocus] = useState(() => {\n return typeof document === \"undefined\" ? null : document.activeElement;\n });\n useEffect(() => {\n\n const dismissWhenInactive = () => {\n\n if (!document.hasFocus()) {\n onClose();\n }\n };\n window.addEventListener(\"blur\", dismissWhenInactive);\n\n return () => {\n\n window.removeEventListener(\"blur\", dismissWhenInactive);\n };\n }, [onClose]);\n\n if (typeof document === \"undefined\") {\n return null;\n }\n return createPortal((<DropdownMenu\n key={`${x}:${y}`}\n open\n modal={false}\n dir={dir}\n onOpenChange={open => {\n\n if (!open) {\n onClose();\n }\n }}\n >\n <DropdownMenuTrigger\n asChild\n >\n <button\n type=\"button\"\n tabIndex={-1}\n aria-hidden=\"true\"\n style={{\n position: \"fixed\",\n left: x,\n top: y,\n width: 0,\n height: 0,\n padding: 0,\n border: 0,\n opacity: 0,\n pointerEvents: \"none\",\n }}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent\n aria-label={label}\n side=\"bottom\"\n align=\"start\"\n sideOffset={0}\n collisionPadding={8}\n {...contentProps}\n onPointerUpCapture={event => {\n onPointerUpCapture?.(event);\n // The release that opens a flush context menu must not select its first item.\n if (event.button !== 0 || event.ctrlKey) {\n event.preventDefault();\n }\n }}\n onCloseAutoFocus={event => {\n onCloseAutoFocus?.(event);\n if (event.defaultPrevented) {\n return;\n }\n event.preventDefault();\n if (document.activeElement === document.body\n && returnFocus instanceof HTMLElement\n && returnFocus.isConnected) {\n returnFocus.focus();\n }\n }}\n onKeyDown={event => {\n\n onKeyDown?.(event);\n if (!event.defaultPrevented && event.key === \"Tab\") {\n event.preventDefault();\n onClose();\n }\n }}\n >\n {children}\n </DropdownMenuContent>\n </DropdownMenu>), document.body);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuItem\n * @description Dropdown Menu Item\n */\n\nimport { MenuSelectionAppearance } from \"../shared/selection-appearance\";\nimport { overlayListItemStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\nimport { useContext } from \"react\";\n\nexport type DropdownMenuItemProps = ComponentPropsWithRef<typeof Primitive.Item>;\n\nexport const DropdownMenuItem: FC<DropdownMenuItemProps> = (props: DropdownMenuItemProps) => {\n const {\n className,\n ...restProps\n } = props;\n const selectionAppearance = useContext(MenuSelectionAppearance);\n return (<Primitive.Item\n {...restProps}\n className={cn(overlayListItemStyles({ selectionAppearance }), className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuLabel\n * @description Dropdown Menu Label\n */\n\nimport { overlayListLabelStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuLabelProps = ComponentPropsWithRef<typeof Primitive.Label>;\n\nexport const DropdownMenuLabel: FC<DropdownMenuLabelProps> = (props: DropdownMenuLabelProps) => {\n const {\n className,\n ...restProps\n } = props;\n return (<Primitive.Label\n {...restProps}\n className={cn(overlayListLabelStyles(), className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuRadioGroup\n * @description Dropdown Menu Radio Group\n */\n\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type DropdownMenuRadioGroupProps = ComponentPropsWithRef<typeof Primitive.RadioGroup>;\n\nexport const DropdownMenuRadioGroup: FC<DropdownMenuRadioGroupProps> = (props: DropdownMenuRadioGroupProps) => {\n return (<Primitive.RadioGroup\n {...props}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuRadioItem\n * @description Dropdown Menu Radio Item\n */\n\nimport { MenuSelectionAppearance } from \"../shared/selection-appearance\";\nimport { overlayListIndicatorStyles, overlayListItemStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport * as Primitive from \"@radix-ui/react-dropdown-menu\";\nimport { Check } from \"lucide-react\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\nimport { useContext } from \"react\";\n\nexport type DropdownMenuRadioItemProps = ComponentPropsWithRef<typeof Primitive.RadioItem>;\n\nexport const DropdownMenuRadioItem: FC<DropdownMenuRadioItemProps> = (props: DropdownMenuRadioItemProps) => {\n const {\n className,\n children,\n ...restProps\n } = props;\n const selectionAppearance = useContext(MenuSelectionAppearance);\n return (<Primitive.RadioItem\n {...restProps}\n className={cn(overlayListItemStyles({ selectionAppearance }), className)}\n >\n <span\n className=\"gridui-u-dropdown-menu--flex gridui-u-dropdown-menu--min-w-0 gridui-u-dropdown-menu--flex-1 gridui-u-dropdown-menu--items-center gridui-u-dropdown-menu--gap-gridui-8\"\n >\n {children}\n </span>\n <span\n className={cn(overlayListIndicatorStyles())}\n aria-hidden=\"true\"\n >\n <Primitive.ItemIndicator>\n <Check\n size={16}\n aria-hidden=\"true\"\n />\n </Primitive.ItemIndicator>\n </span>\n </Primitive.RadioItem>);\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["document", "OverlayOpen", "cn", "Primitive", "jsx", "Primitive", "jsx", "useState", "jsx", "cn", "Primitive", "useContext", "jsx", "cn", "Primitive", "jsx", "Primitive", "jsx", "overlayListItemStyles", "cn", "Primitive", "useContext", "jsx", "jsxs"]
7
7
  }
@@ -4,9 +4,11 @@
4
4
  * @namespace Shared
5
5
  * @description Menu Content Options
6
6
  */
7
+ import type { SelectionAppearance } from "./selection-appearance";
7
8
  import type * as Primitive from "@radix-ui/react-dropdown-menu";
8
9
  import type { ComponentPropsWithRef } from "react";
9
10
  export type MenuContentOptions = ComponentPropsWithRef<typeof Primitive.Content> & {
11
+ readonly selectionAppearance?: SelectionAppearance | undefined;
10
12
  readonly morph?: boolean | undefined;
11
13
  readonly respectReducedMotion?: boolean | undefined;
12
14
  };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Dropdown Menu
4
+ * @namespace Shared
5
+ * @description Selection Appearance
6
+ */
7
+ import type { overlayListItemStyles } from "@gridui/overlay";
8
+ import type { VariantProps } from "class-variance-authority";
9
+ export type SelectionAppearance = NonNullable<VariantProps<typeof overlayListItemStyles>["selectionAppearance"]>;
10
+ export declare const MenuSelectionAppearance: import("react").Context<SelectionAppearance>;
package/docs/catalog.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "name": "@gridui/dropdown-menu",
4
- "version": "2.0.1",
4
+ "version": "2.1.0",
5
5
  "category": "core",
6
6
  "description": "GridUI React dropdown menu",
7
7
  "usage": "Overlay supplies popup surfaces, option rows, group labels, and selection indicators. Applications own routes, labels, state persistence, and branding.",
@@ -113,6 +113,7 @@
113
113
  "examples": [
114
114
  "https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/action-menus.mdx",
115
115
  "https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/context-menus.mdx",
116
+ "https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/getting-started.mdx",
116
117
  "https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/context-menu.stories.tsx",
117
118
  "https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/dropdown-menu.stories.tsx"
118
119
  ]
@@ -99,7 +99,7 @@ Whether keyboard navigation should loop around
99
99
 
100
100
  ### side
101
101
 
102
- ``"left" | "right" | "top" | "bottom" | undefined`` · Optional
102
+ ``"top" | "right" | "bottom" | "left" | undefined`` · Optional
103
103
 
104
104
  ### sideOffset
105
105
 
@@ -107,7 +107,7 @@ Whether keyboard navigation should loop around
107
107
 
108
108
  ### align
109
109
 
110
- ``"center" | "start" | "end" | undefined`` · Optional
110
+ ``"center" | "end" | "start" | undefined`` · Optional
111
111
 
112
112
  ### alignOffset
113
113
 
@@ -127,7 +127,7 @@ Whether keyboard navigation should loop around
127
127
 
128
128
  ### collisionPadding
129
129
 
130
- ``number | Partial<Record<"left" | "right" | "top" | "bottom", number>> | undefined`` · Optional
130
+ ``number | Partial<Record<"top" | "right" | "bottom" | "left", number>> | undefined`` · Optional
131
131
 
132
132
  ### sticky
133
133
 
@@ -141,6 +141,10 @@ Whether keyboard navigation should loop around
141
141
 
142
142
  ``("always" | "optimized") | undefined`` · Optional
143
143
 
144
+ ### selectionAppearance
145
+
146
+ ``SelectionAppearance | undefined`` · Optional
147
+
144
148
  ### morph
145
149
 
146
150
  ``boolean | undefined`` · Optional
@@ -105,7 +105,7 @@ Whether keyboard navigation should loop around
105
105
 
106
106
  ### side
107
107
 
108
- ``"left" | "right" | "top" | "bottom" | undefined`` · Optional
108
+ ``"top" | "right" | "bottom" | "left" | undefined`` · Optional
109
109
 
110
110
  ### sideOffset
111
111
 
@@ -115,7 +115,7 @@ Default: ``8``
115
115
 
116
116
  ### align
117
117
 
118
- ``"center" | "start" | "end" | undefined`` · Optional
118
+ ``"center" | "end" | "start" | undefined`` · Optional
119
119
 
120
120
  Default: ``"end"``
121
121
 
@@ -137,7 +137,7 @@ Default: ``"end"``
137
137
 
138
138
  ### collisionPadding
139
139
 
140
- ``number | Partial<Record<"left" | "right" | "top" | "bottom", number>> | undefined`` · Optional
140
+ ``number | Partial<Record<"top" | "right" | "bottom" | "left", number>> | undefined`` · Optional
141
141
 
142
142
  ### sticky
143
143
 
@@ -151,6 +151,12 @@ Default: ``"end"``
151
151
 
152
152
  ``("always" | "optimized") | undefined`` · Optional
153
153
 
154
+ ### selectionAppearance
155
+
156
+ ``SelectionAppearance | undefined`` · Optional
157
+
158
+ Default: ``"filled"``
159
+
154
160
  ### morph
155
161
 
156
162
  ``boolean | undefined`` · Optional
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gridui/dropdown-menu",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "GridUI React dropdown menu",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -27,18 +27,18 @@
27
27
  "react-dom": "^19.2.0"
28
28
  },
29
29
  "dependencies": {
30
- "@gridui/overlay": "^2.0.0",
30
+ "@gridui/overlay": "^2.2.0",
31
31
  "@gridui/style-utils": "^4.0.0",
32
- "@gridui/theme": "^2.5.3",
32
+ "@gridui/theme": "^2.6.0",
33
33
  "@radix-ui/react-dropdown-menu": "2.2.1",
34
34
  "class-variance-authority": "0.7.1",
35
- "lucide-react": "1.70.0"
35
+ "lucide-react": "1.72.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@gridui-internal/configuration": "0.0.0-internal",
39
- "@gridui/button": "4.1.0",
39
+ "@gridui/button": "5.0.1",
40
40
  "@jest/globals": "30.5.2",
41
- "@storybook/react-vite": "10.6.6",
41
+ "@storybook/react-vite": "10.6.7",
42
42
  "@types/jest": "30.0.0",
43
43
  "@types/node": "26.6.6",
44
44
  "@types/react": "19.3.0",