@gridui/dropdown-menu 2.0.0 → 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,9 +48,18 @@ 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.
54
61
 
55
62
  `ContextMenu` accepts `dir="ltr" | "rtl"` and forwards it to the menu root,
56
63
  so portal positioning and keyboard navigation use the same direction as its rows.
64
+
65
+ [Component reference](docs/reference/README.md) contains focused API pages for each public component.
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,13 +1,22 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "name": "@gridui/dropdown-menu",
4
- "version": "2.0.0",
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.",
8
8
  "documentation": [
9
9
  "README.md",
10
- "docs/context-menu.md"
10
+ "docs/context-menu.md",
11
+ "docs/reference/README.md",
12
+ "docs/reference/context-menu.md",
13
+ "docs/reference/dropdown-menu-content.md",
14
+ "docs/reference/dropdown-menu-item.md",
15
+ "docs/reference/dropdown-menu-label.md",
16
+ "docs/reference/dropdown-menu-radio-group.md",
17
+ "docs/reference/dropdown-menu-radio-item.md",
18
+ "docs/reference/dropdown-menu-trigger.md",
19
+ "docs/reference/dropdown-menu.md"
11
20
  ],
12
21
  "exports": [
13
22
  {
@@ -102,6 +111,9 @@
102
111
  "@gridui/dropdown-menu/styles.css"
103
112
  ],
104
113
  "examples": [
114
+ "https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/action-menus.mdx",
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",
105
117
  "https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/context-menu.stories.tsx",
106
118
  "https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/dropdown-menu.stories.tsx"
107
119
  ]
@@ -0,0 +1,11 @@
1
+ <!-- Generated by pnpm docs:storybook. -->
2
+ # Component reference
3
+
4
+ - [ContextMenu](context-menu.md)
5
+ - [DropdownMenu](dropdown-menu.md)
6
+ - [DropdownMenuContent](dropdown-menu-content.md)
7
+ - [DropdownMenuItem](dropdown-menu-item.md)
8
+ - [DropdownMenuLabel](dropdown-menu-label.md)
9
+ - [DropdownMenuRadioGroup](dropdown-menu-radio-group.md)
10
+ - [DropdownMenuRadioItem](dropdown-menu-radio-item.md)
11
+ - [DropdownMenuTrigger](dropdown-menu-trigger.md)
@@ -0,0 +1,183 @@
1
+ <!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
2
+ # ContextMenu
3
+
4
+ Shows contextual actions at a requested position. Use it for item-specific actions invoked by a context-menu gesture or an explicit trigger.
5
+
6
+ Import from ``@gridui/dropdown-menu`` and load Theme before this family's stylesheet.
7
+
8
+ ```tsx
9
+ import { ContextMenu } from "@gridui/dropdown-menu";
10
+ import "@gridui/theme/styles.css";
11
+ import "@gridui/dropdown-menu/styles.css";
12
+ ```
13
+
14
+ Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/README.md) for shared behavior and stylesheet dependencies.
15
+
16
+ The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/context-menu.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
17
+
18
+ ## API
19
+
20
+ The public Props type is the source of these signatures. Defaults below are explicit implementation defaults; story presets are separate. Native attributes remain available through the exported Props type.
21
+
22
+ ### onFocus
23
+
24
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
25
+
26
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
27
+
28
+ ### onBlur
29
+
30
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
31
+
32
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
33
+
34
+ ### onChange
35
+
36
+ ``(event: ChangeEvent<HTMLDivElement, Element>): void`` · Optional
37
+
38
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
39
+
40
+ ### onSubmit
41
+
42
+ ``(event: SubmitEvent<HTMLDivElement>): void`` · Optional
43
+
44
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
45
+
46
+ ### onClick
47
+
48
+ ``(event: MouseEvent<HTMLDivElement, MouseEvent>): void`` · Optional
49
+
50
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
51
+
52
+ ### asChild
53
+
54
+ ``boolean | undefined`` · Optional
55
+
56
+ ### onEscapeKeyDown
57
+
58
+ ``(event: KeyboardEvent): void`` · Optional
59
+
60
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
61
+
62
+ ### onPointerDownOutside
63
+
64
+ ``(event: CustomEvent<{ originalEvent: PointerEvent; }>): void`` · Optional
65
+
66
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
67
+
68
+ ### onFocusOutside
69
+
70
+ ``(event: CustomEvent<{ originalEvent: FocusEvent; }>): void`` · Optional
71
+
72
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
73
+
74
+ ### onInteractOutside
75
+
76
+ ``(event: CustomEvent<{ originalEvent: PointerEvent; }> | CustomEvent<{ originalEvent: FocusEvent; }>): void`` · Optional
77
+
78
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
79
+
80
+ ### onCloseAutoFocus
81
+
82
+ ``(event: Event): void`` · Optional
83
+
84
+ Event handler called when auto-focusing on close.
85
+ Can be prevented.
86
+
87
+ ### forceMount
88
+
89
+ ``true | undefined`` · Optional
90
+
91
+ Used to force mounting when more control is needed. Useful when
92
+ controlling animation with React animation libraries.
93
+
94
+ ### loop
95
+
96
+ ``boolean | undefined`` · Optional
97
+
98
+ Whether keyboard navigation should loop around
99
+
100
+ ### side
101
+
102
+ ``"top" | "right" | "bottom" | "left" | undefined`` · Optional
103
+
104
+ ### sideOffset
105
+
106
+ ``number | undefined`` · Optional
107
+
108
+ ### align
109
+
110
+ ``"center" | "end" | "start" | undefined`` · Optional
111
+
112
+ ### alignOffset
113
+
114
+ ``number | undefined`` · Optional
115
+
116
+ ### arrowPadding
117
+
118
+ ``number | undefined`` · Optional
119
+
120
+ ### avoidCollisions
121
+
122
+ ``boolean | undefined`` · Optional
123
+
124
+ ### collisionBoundary
125
+
126
+ ``(Element | null) | (Element | null)[] | undefined`` · Optional
127
+
128
+ ### collisionPadding
129
+
130
+ ``number | Partial<Record<"top" | "right" | "bottom" | "left", number>> | undefined`` · Optional
131
+
132
+ ### sticky
133
+
134
+ ``("partial" | "always") | undefined`` · Optional
135
+
136
+ ### hideWhenDetached
137
+
138
+ ``boolean | undefined`` · Optional
139
+
140
+ ### updatePositionStrategy
141
+
142
+ ``("always" | "optimized") | undefined`` · Optional
143
+
144
+ ### selectionAppearance
145
+
146
+ ``SelectionAppearance | undefined`` · Optional
147
+
148
+ ### morph
149
+
150
+ ``boolean | undefined`` · Optional
151
+
152
+ ### respectReducedMotion
153
+
154
+ ``boolean | undefined`` · Optional
155
+
156
+ ### dir
157
+
158
+ ``("ltr" | "rtl") | undefined`` · Optional
159
+
160
+ ### x
161
+
162
+ ``number`` · Required
163
+
164
+ ### y
165
+
166
+ ``number`` · Required
167
+
168
+ ### label
169
+
170
+ ``string`` · Required
171
+
172
+ ### children
173
+
174
+ ``ReactNode`` · Required
175
+
176
+ Content rendered inside the component.
177
+
178
+ ### onClose
179
+
180
+ ``(): void`` · Required
181
+
182
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
183
+
@@ -0,0 +1,171 @@
1
+ <!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
2
+ # DropdownMenuContent
3
+
4
+ Compose DropdownMenuContent with DropdownMenu inside the same @gridui/dropdown-menu component family.
5
+
6
+ Import from ``@gridui/dropdown-menu`` and load Theme before this family's stylesheet.
7
+
8
+ ```tsx
9
+ import { DropdownMenuContent } from "@gridui/dropdown-menu";
10
+ import "@gridui/theme/styles.css";
11
+ import "@gridui/dropdown-menu/styles.css";
12
+ ```
13
+
14
+ Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/README.md) for shared behavior and stylesheet dependencies.
15
+
16
+ The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/dropdown-menu.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
17
+
18
+ ## API
19
+
20
+ The public Props type is the source of these signatures. Defaults below are explicit implementation defaults; story presets are separate. Native attributes remain available through the exported Props type.
21
+
22
+ ### children
23
+
24
+ ``ReactNode`` · Optional
25
+
26
+ Content rendered inside the component.
27
+
28
+ ### onFocus
29
+
30
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
31
+
32
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
33
+
34
+ ### onBlur
35
+
36
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
37
+
38
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
39
+
40
+ ### onChange
41
+
42
+ ``(event: ChangeEvent<HTMLDivElement, Element>): void`` · Optional
43
+
44
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
45
+
46
+ ### onSubmit
47
+
48
+ ``(event: SubmitEvent<HTMLDivElement>): void`` · Optional
49
+
50
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
51
+
52
+ ### onClick
53
+
54
+ ``(event: MouseEvent<HTMLDivElement, MouseEvent>): void`` · Optional
55
+
56
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
57
+
58
+ ### asChild
59
+
60
+ ``boolean | undefined`` · Optional
61
+
62
+ ### onEscapeKeyDown
63
+
64
+ ``(event: KeyboardEvent): void`` · Optional
65
+
66
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
67
+
68
+ ### onPointerDownOutside
69
+
70
+ ``(event: CustomEvent<{ originalEvent: PointerEvent; }>): void`` · Optional
71
+
72
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
73
+
74
+ ### onFocusOutside
75
+
76
+ ``(event: CustomEvent<{ originalEvent: FocusEvent; }>): void`` · Optional
77
+
78
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
79
+
80
+ ### onInteractOutside
81
+
82
+ ``(event: CustomEvent<{ originalEvent: PointerEvent; }> | CustomEvent<{ originalEvent: FocusEvent; }>): void`` · Optional
83
+
84
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
85
+
86
+ ### onCloseAutoFocus
87
+
88
+ ``(event: Event): void`` · Optional
89
+
90
+ Event handler called when auto-focusing on close.
91
+ Can be prevented.
92
+
93
+ ### forceMount
94
+
95
+ ``true | undefined`` · Optional
96
+
97
+ Used to force mounting when more control is needed. Useful when
98
+ controlling animation with React animation libraries.
99
+
100
+ ### loop
101
+
102
+ ``boolean | undefined`` · Optional
103
+
104
+ Whether keyboard navigation should loop around
105
+
106
+ ### side
107
+
108
+ ``"top" | "right" | "bottom" | "left" | undefined`` · Optional
109
+
110
+ ### sideOffset
111
+
112
+ ``number | undefined`` · Optional
113
+
114
+ Default: ``8``
115
+
116
+ ### align
117
+
118
+ ``"center" | "end" | "start" | undefined`` · Optional
119
+
120
+ Default: ``"end"``
121
+
122
+ ### alignOffset
123
+
124
+ ``number | undefined`` · Optional
125
+
126
+ ### arrowPadding
127
+
128
+ ``number | undefined`` · Optional
129
+
130
+ ### avoidCollisions
131
+
132
+ ``boolean | undefined`` · Optional
133
+
134
+ ### collisionBoundary
135
+
136
+ ``(Element | null) | (Element | null)[] | undefined`` · Optional
137
+
138
+ ### collisionPadding
139
+
140
+ ``number | Partial<Record<"top" | "right" | "bottom" | "left", number>> | undefined`` · Optional
141
+
142
+ ### sticky
143
+
144
+ ``("partial" | "always") | undefined`` · Optional
145
+
146
+ ### hideWhenDetached
147
+
148
+ ``boolean | undefined`` · Optional
149
+
150
+ ### updatePositionStrategy
151
+
152
+ ``("always" | "optimized") | undefined`` · Optional
153
+
154
+ ### selectionAppearance
155
+
156
+ ``SelectionAppearance | undefined`` · Optional
157
+
158
+ Default: ``"filled"``
159
+
160
+ ### morph
161
+
162
+ ``boolean | undefined`` · Optional
163
+
164
+ Default: ``false``
165
+
166
+ ### respectReducedMotion
167
+
168
+ ``boolean | undefined`` · Optional
169
+
170
+ Default: ``true``
171
+
@@ -0,0 +1,77 @@
1
+ <!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
2
+ # DropdownMenuItem
3
+
4
+ Compose DropdownMenuItem with ContextMenu inside the same @gridui/dropdown-menu component family.
5
+
6
+ Import from ``@gridui/dropdown-menu`` and load Theme before this family's stylesheet.
7
+
8
+ ```tsx
9
+ import { DropdownMenuItem } from "@gridui/dropdown-menu";
10
+ import "@gridui/theme/styles.css";
11
+ import "@gridui/dropdown-menu/styles.css";
12
+ ```
13
+
14
+ Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/README.md) for shared behavior and stylesheet dependencies.
15
+
16
+ The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/context-menu.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
17
+
18
+ ## API
19
+
20
+ The public Props type is the source of these signatures. Defaults below are explicit implementation defaults; story presets are separate. Native attributes remain available through the exported Props type.
21
+
22
+ ### children
23
+
24
+ ``ReactNode`` · Optional
25
+
26
+ Content rendered inside the component.
27
+
28
+ ### onFocus
29
+
30
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
31
+
32
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
33
+
34
+ ### onBlur
35
+
36
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
37
+
38
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
39
+
40
+ ### onChange
41
+
42
+ ``(event: ChangeEvent<HTMLDivElement, Element>): void`` · Optional
43
+
44
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
45
+
46
+ ### onSubmit
47
+
48
+ ``(event: SubmitEvent<HTMLDivElement>): void`` · Optional
49
+
50
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
51
+
52
+ ### onClick
53
+
54
+ ``(event: MouseEvent<HTMLDivElement, MouseEvent>): void`` · Optional
55
+
56
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
57
+
58
+ ### onSelect
59
+
60
+ ``(event: Event): void`` · Optional
61
+
62
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
63
+
64
+ ### asChild
65
+
66
+ ``boolean | undefined`` · Optional
67
+
68
+ ### disabled
69
+
70
+ ``boolean | undefined`` · Optional
71
+
72
+ Prevents interaction when enabled.
73
+
74
+ ### textValue
75
+
76
+ ``string | undefined`` · Optional
77
+
@@ -0,0 +1,61 @@
1
+ <!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
2
+ # DropdownMenuLabel
3
+
4
+ Compose DropdownMenuLabel with DropdownMenu inside the same @gridui/dropdown-menu component family.
5
+
6
+ Import from ``@gridui/dropdown-menu`` and load Theme before this family's stylesheet.
7
+
8
+ ```tsx
9
+ import { DropdownMenuLabel } from "@gridui/dropdown-menu";
10
+ import "@gridui/theme/styles.css";
11
+ import "@gridui/dropdown-menu/styles.css";
12
+ ```
13
+
14
+ Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/README.md) for shared behavior and stylesheet dependencies.
15
+
16
+ The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/dropdown-menu.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
17
+
18
+ ## API
19
+
20
+ The public Props type is the source of these signatures. Defaults below are explicit implementation defaults; story presets are separate. Native attributes remain available through the exported Props type.
21
+
22
+ ### children
23
+
24
+ ``ReactNode`` · Optional
25
+
26
+ Content rendered inside the component.
27
+
28
+ ### onFocus
29
+
30
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
31
+
32
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
33
+
34
+ ### onBlur
35
+
36
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
37
+
38
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
39
+
40
+ ### onChange
41
+
42
+ ``(event: ChangeEvent<HTMLDivElement, Element>): void`` · Optional
43
+
44
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
45
+
46
+ ### onSubmit
47
+
48
+ ``(event: SubmitEvent<HTMLDivElement>): void`` · Optional
49
+
50
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
51
+
52
+ ### onClick
53
+
54
+ ``(event: MouseEvent<HTMLDivElement, MouseEvent>): void`` · Optional
55
+
56
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
57
+
58
+ ### asChild
59
+
60
+ ``boolean | undefined`` · Optional
61
+
@@ -0,0 +1,73 @@
1
+ <!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
2
+ # DropdownMenuRadioGroup
3
+
4
+ Compose DropdownMenuRadioGroup with DropdownMenu inside the same @gridui/dropdown-menu component family.
5
+
6
+ Import from ``@gridui/dropdown-menu`` and load Theme before this family's stylesheet.
7
+
8
+ ```tsx
9
+ import { DropdownMenuRadioGroup } from "@gridui/dropdown-menu";
10
+ import "@gridui/theme/styles.css";
11
+ import "@gridui/dropdown-menu/styles.css";
12
+ ```
13
+
14
+ Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/README.md) for shared behavior and stylesheet dependencies.
15
+
16
+ The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/dropdown-menu.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
17
+
18
+ ## API
19
+
20
+ The public Props type is the source of these signatures. Defaults below are explicit implementation defaults; story presets are separate. Native attributes remain available through the exported Props type.
21
+
22
+ ### children
23
+
24
+ ``ReactNode`` · Optional
25
+
26
+ Content rendered inside the component.
27
+
28
+ ### onFocus
29
+
30
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
31
+
32
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
33
+
34
+ ### onBlur
35
+
36
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
37
+
38
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
39
+
40
+ ### onChange
41
+
42
+ ``(event: ChangeEvent<HTMLDivElement, Element>): void`` · Optional
43
+
44
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
45
+
46
+ ### onSubmit
47
+
48
+ ``(event: SubmitEvent<HTMLDivElement>): void`` · Optional
49
+
50
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
51
+
52
+ ### onClick
53
+
54
+ ``(event: MouseEvent<HTMLDivElement, MouseEvent>): void`` · Optional
55
+
56
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
57
+
58
+ ### asChild
59
+
60
+ ``boolean | undefined`` · Optional
61
+
62
+ ### value
63
+
64
+ ``string | undefined`` · Optional
65
+
66
+ Controlled value. Pair with the corresponding change callback.
67
+
68
+ ### onValueChange
69
+
70
+ ``(value: string): void`` · Optional
71
+
72
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
73
+
@@ -0,0 +1,83 @@
1
+ <!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
2
+ # DropdownMenuRadioItem
3
+
4
+ Compose DropdownMenuRadioItem with DropdownMenu inside the same @gridui/dropdown-menu component family.
5
+
6
+ Import from ``@gridui/dropdown-menu`` and load Theme before this family's stylesheet.
7
+
8
+ ```tsx
9
+ import { DropdownMenuRadioItem } from "@gridui/dropdown-menu";
10
+ import "@gridui/theme/styles.css";
11
+ import "@gridui/dropdown-menu/styles.css";
12
+ ```
13
+
14
+ Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/README.md) for shared behavior and stylesheet dependencies.
15
+
16
+ The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/dropdown-menu.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
17
+
18
+ ## API
19
+
20
+ The public Props type is the source of these signatures. Defaults below are explicit implementation defaults; story presets are separate. Native attributes remain available through the exported Props type.
21
+
22
+ ### children
23
+
24
+ ``ReactNode`` · Optional
25
+
26
+ Content rendered inside the component.
27
+
28
+ ### onFocus
29
+
30
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
31
+
32
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
33
+
34
+ ### onBlur
35
+
36
+ ``(event: FocusEvent<HTMLDivElement, Element>): void`` · Optional
37
+
38
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
39
+
40
+ ### onChange
41
+
42
+ ``(event: ChangeEvent<HTMLDivElement, Element>): void`` · Optional
43
+
44
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
45
+
46
+ ### onSubmit
47
+
48
+ ``(event: SubmitEvent<HTMLDivElement>): void`` · Optional
49
+
50
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
51
+
52
+ ### onClick
53
+
54
+ ``(event: MouseEvent<HTMLDivElement, MouseEvent>): void`` · Optional
55
+
56
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
57
+
58
+ ### onSelect
59
+
60
+ ``(event: Event): void`` · Optional
61
+
62
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
63
+
64
+ ### asChild
65
+
66
+ ``boolean | undefined`` · Optional
67
+
68
+ ### disabled
69
+
70
+ ``boolean | undefined`` · Optional
71
+
72
+ Prevents interaction when enabled.
73
+
74
+ ### value
75
+
76
+ ``string`` · Required
77
+
78
+ Controlled value. Pair with the corresponding change callback.
79
+
80
+ ### textValue
81
+
82
+ ``string | undefined`` · Optional
83
+
@@ -0,0 +1,61 @@
1
+ <!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
2
+ # DropdownMenuTrigger
3
+
4
+ Compose DropdownMenuTrigger with DropdownMenu inside the same @gridui/dropdown-menu component family.
5
+
6
+ Import from ``@gridui/dropdown-menu`` and load Theme before this family's stylesheet.
7
+
8
+ ```tsx
9
+ import { DropdownMenuTrigger } from "@gridui/dropdown-menu";
10
+ import "@gridui/theme/styles.css";
11
+ import "@gridui/dropdown-menu/styles.css";
12
+ ```
13
+
14
+ Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/README.md) for shared behavior and stylesheet dependencies.
15
+
16
+ The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/dropdown-menu.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
17
+
18
+ ## API
19
+
20
+ The public Props type is the source of these signatures. Defaults below are explicit implementation defaults; story presets are separate. Native attributes remain available through the exported Props type.
21
+
22
+ ### children
23
+
24
+ ``ReactNode`` · Optional
25
+
26
+ Content rendered inside the component.
27
+
28
+ ### onFocus
29
+
30
+ ``(event: FocusEvent<HTMLButtonElement, Element>): void`` · Optional
31
+
32
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
33
+
34
+ ### onBlur
35
+
36
+ ``(event: FocusEvent<HTMLButtonElement, Element>): void`` · Optional
37
+
38
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
39
+
40
+ ### onChange
41
+
42
+ ``(event: ChangeEvent<HTMLButtonElement, Element>): void`` · Optional
43
+
44
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
45
+
46
+ ### onSubmit
47
+
48
+ ``(event: SubmitEvent<HTMLButtonElement>): void`` · Optional
49
+
50
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
51
+
52
+ ### onClick
53
+
54
+ ``(event: MouseEvent<HTMLButtonElement, MouseEvent>): void`` · Optional
55
+
56
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
57
+
58
+ ### asChild
59
+
60
+ ``boolean | undefined`` · Optional
61
+
@@ -0,0 +1,53 @@
1
+ <!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
2
+ # DropdownMenu
3
+
4
+ Opens a menu of actions or choices from a trigger. Use Select for choosing a form value and Popover for arbitrary interactive content.
5
+
6
+ Import from ``@gridui/dropdown-menu`` and load Theme before this family's stylesheet.
7
+
8
+ ```tsx
9
+ import { DropdownMenu } from "@gridui/dropdown-menu";
10
+ import "@gridui/theme/styles.css";
11
+ import "@gridui/dropdown-menu/styles.css";
12
+ ```
13
+
14
+ Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/README.md) for shared behavior and stylesheet dependencies.
15
+
16
+ The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/dropdown-menu.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
17
+
18
+ ## API
19
+
20
+ The public Props type is the source of these signatures. Defaults below are explicit implementation defaults; story presets are separate. Native attributes remain available through the exported Props type.
21
+
22
+ ### children
23
+
24
+ ``ReactNode`` · Optional
25
+
26
+ Content rendered inside the component.
27
+
28
+ ### dir
29
+
30
+ ``("ltr" | "rtl") | undefined`` · Optional
31
+
32
+ ### open
33
+
34
+ ``boolean | undefined`` · Optional
35
+
36
+ Controlled visibility. Pair with onOpenChange.
37
+
38
+ ### defaultOpen
39
+
40
+ ``boolean | undefined`` · Optional
41
+
42
+ Initial uncontrolled visibility. Reset the story after changing it.
43
+
44
+ ### onOpenChange
45
+
46
+ ``(open: boolean): void`` · Optional
47
+
48
+ Called when the corresponding interaction occurs; inspect the arguments in Actions.
49
+
50
+ ### modal
51
+
52
+ ``boolean | undefined`` · Optional
53
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gridui/dropdown-menu",
3
- "version": "2.0.0",
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",
31
- "@gridui/style-utils": "^3.0.0",
32
- "@gridui/theme": "^2.5.3",
30
+ "@gridui/overlay": "^2.2.0",
31
+ "@gridui/style-utils": "^4.0.0",
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.0.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",