@gridui/dropdown-menu 1.1.5 → 1.2.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 +4 -0
- package/dist/context-menu/context-menu.d.ts +2 -2
- package/dist/dropdown-menu-content/dropdown-menu-content.d.ts +3 -3
- package/dist/dropdown-menu-content/use-menu-morph.d.ts +7 -0
- package/dist/index.js +81 -4
- package/dist/index.js.map +4 -4
- package/dist/shared/menu-content-options.d.ts +12 -0
- package/dist/styles.css +26 -1
- package/docs/catalog.json +123 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -33,3 +33,7 @@ and dismissal; the decorative outline layer cannot receive pointer input.
|
|
|
33
33
|
The menu surface has no padding by default: option hit areas reach its inner
|
|
34
34
|
border, and each option owns its text padding. Caller classes can add deliberate
|
|
35
35
|
surface padding. Native scrolling uses Theme's shared scrollbar appearance.
|
|
36
|
+
|
|
37
|
+
Set `morph` on `DropdownMenuContent` to expand the menu from its trigger
|
|
38
|
+
when opening. `respectReducedMotion` defaults to `true`. Set it to `false`
|
|
39
|
+
to play the expansion even when the system requests reduced motion.
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* @namespace ContextMenu
|
|
5
5
|
* @description Context Menu
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import type { MenuContentOptions } from "../shared/menu-content-options";
|
|
8
8
|
import { type FC, type ReactNode } from "react";
|
|
9
|
-
export type ContextMenuProps = Omit<
|
|
9
|
+
export type ContextMenuProps = Omit<MenuContentOptions, "children"> & {
|
|
10
10
|
readonly x: number;
|
|
11
11
|
readonly y: number;
|
|
12
12
|
readonly label: string;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @namespace DropdownMenuContent
|
|
5
5
|
* @description Dropdown Menu Content
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
8
|
-
import type {
|
|
9
|
-
export type DropdownMenuContentProps =
|
|
7
|
+
import type { MenuContentOptions } from "../shared/menu-content-options";
|
|
8
|
+
import type { FC } from "react";
|
|
9
|
+
export type DropdownMenuContentProps = MenuContentOptions;
|
|
10
10
|
export declare const DropdownMenuContent: FC<DropdownMenuContentProps>;
|
package/dist/index.js
CHANGED
|
@@ -29,10 +29,63 @@ var dropdownContentStyles = cva(cn(
|
|
|
29
29
|
"gridui-u-z-(--gridui-z-popover) gridui-u-min-w-44 gridui-u-max-w-[calc(100vw-2*var(--gridui-page-gutter))] gridui-u-max-h-(--radix-dropdown-menu-content-available-height) gridui-u-overflow-y-auto gridui-u-p-0 gridui-u-type-data"
|
|
30
30
|
));
|
|
31
31
|
|
|
32
|
+
// src/dropdown-menu-content/use-menu-morph.ts
|
|
33
|
+
import { useLayoutEffect } from "react";
|
|
34
|
+
var useMenuMorph = (element, enabled) => {
|
|
35
|
+
useLayoutEffect(() => {
|
|
36
|
+
if (!element || !enabled) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const place = () => {
|
|
40
|
+
if (element.style.animation === "none") {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
observer.disconnect();
|
|
44
|
+
const document2 = element.ownerDocument;
|
|
45
|
+
const trigger = document2.getElementById(element.getAttribute("aria-labelledby") ?? "");
|
|
46
|
+
if (!trigger) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
element.setAttribute("data-morph-measuring", "");
|
|
50
|
+
const menu = element.getBoundingClientRect();
|
|
51
|
+
element.removeAttribute("data-morph-measuring");
|
|
52
|
+
const anchor = trigger.getBoundingClientRect();
|
|
53
|
+
const width = Math.min(menu.width, anchor.width);
|
|
54
|
+
const height = Math.min(menu.height, anchor.height);
|
|
55
|
+
if (!width || !height) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const x = anchor.left + (anchor.width - width) / 2 - menu.left;
|
|
59
|
+
const y = anchor.top + (anchor.height - height) / 2 - menu.top;
|
|
60
|
+
const left = Math.max(0, Math.min(x, menu.width - width));
|
|
61
|
+
const top = Math.max(0, Math.min(y, menu.height - height));
|
|
62
|
+
element.style.setProperty("--gridui-menu-morph-clip", `inset(${top}px ${menu.width - width - left}px ${menu.height - height - top}px ${left}px)`);
|
|
63
|
+
element.style.setProperty("--gridui-menu-morph-offset", `${x - left}px, ${y - top}px`);
|
|
64
|
+
element.setAttribute("data-morph-ready", "");
|
|
65
|
+
};
|
|
66
|
+
const observer = new MutationObserver(place);
|
|
67
|
+
observer.observe(element, {
|
|
68
|
+
attributes: true,
|
|
69
|
+
attributeFilter: ["style"]
|
|
70
|
+
});
|
|
71
|
+
place();
|
|
72
|
+
return () => {
|
|
73
|
+
observer.disconnect();
|
|
74
|
+
element.removeAttribute("data-morph-ready");
|
|
75
|
+
element.style.removeProperty("--gridui-menu-morph-clip");
|
|
76
|
+
element.style.removeProperty("--gridui-menu-morph-offset");
|
|
77
|
+
};
|
|
78
|
+
}, [
|
|
79
|
+
element,
|
|
80
|
+
enabled
|
|
81
|
+
]);
|
|
82
|
+
};
|
|
83
|
+
|
|
32
84
|
// src/dropdown-menu-content/dropdown-menu-content.tsx
|
|
33
|
-
import { interactionLayerProps, RetainedLayer, useInteractionOutline, useScrollbars } from "@gridui/overlay";
|
|
85
|
+
import { interactionLayerProps, OverlayOpen as OverlayOpen2, RetainedLayer, useInteractionOutline, useScrollbars } from "@gridui/overlay";
|
|
34
86
|
import { cn as cn2 } from "@gridui/style-utils";
|
|
35
87
|
import * as Primitive2 from "@radix-ui/react-dropdown-menu";
|
|
88
|
+
import { useCallback, useContext, useState } from "react";
|
|
36
89
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
37
90
|
var DropdownMenuContent = (props) => {
|
|
38
91
|
const {
|
|
@@ -41,9 +94,32 @@ var DropdownMenuContent = (props) => {
|
|
|
41
94
|
forceMount,
|
|
42
95
|
sideOffset = 8,
|
|
43
96
|
align = "end",
|
|
97
|
+
morph = false,
|
|
98
|
+
respectReducedMotion = true,
|
|
44
99
|
...restProps
|
|
45
100
|
} = props;
|
|
46
|
-
const
|
|
101
|
+
const open = useContext(OverlayOpen2);
|
|
102
|
+
const [
|
|
103
|
+
element,
|
|
104
|
+
setElement
|
|
105
|
+
] = useState(null);
|
|
106
|
+
const morphRef = useCallback((node) => {
|
|
107
|
+
setElement(node);
|
|
108
|
+
if (typeof forwardedRef === "function") {
|
|
109
|
+
const cleanup = forwardedRef(node);
|
|
110
|
+
if (cleanup) {
|
|
111
|
+
return () => {
|
|
112
|
+
setElement(null);
|
|
113
|
+
cleanup();
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
} else if (forwardedRef) {
|
|
117
|
+
forwardedRef.current = node;
|
|
118
|
+
}
|
|
119
|
+
return void 0;
|
|
120
|
+
}, [forwardedRef]);
|
|
121
|
+
useMenuMorph(element, morph && open === true);
|
|
122
|
+
const scrollbarRef = useScrollbars({ ref: morph ? morphRef : forwardedRef });
|
|
47
123
|
const ref = useInteractionOutline({
|
|
48
124
|
ref: scrollbarRef,
|
|
49
125
|
selector: '[role^="menuitem"]'
|
|
@@ -57,6 +133,7 @@ var DropdownMenuContent = (props) => {
|
|
|
57
133
|
forceMount,
|
|
58
134
|
align,
|
|
59
135
|
sideOffset,
|
|
136
|
+
"data-morph-ignore-reduced-motion": !respectReducedMotion || void 0,
|
|
60
137
|
className: cn2(dropdownContentStyles(), className)
|
|
61
138
|
}
|
|
62
139
|
);
|
|
@@ -82,12 +159,12 @@ var DropdownMenuTrigger = (props) => {
|
|
|
82
159
|
};
|
|
83
160
|
|
|
84
161
|
// src/context-menu/context-menu.tsx
|
|
85
|
-
import { useEffect, useState } from "react";
|
|
162
|
+
import { useEffect, useState as useState2 } from "react";
|
|
86
163
|
import { createPortal } from "react-dom";
|
|
87
164
|
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
88
165
|
var ContextMenu = (props) => {
|
|
89
166
|
const { x, y, label, children, onClose, onCloseAutoFocus, onKeyDown, onPointerUpCapture, ...contentProps } = props;
|
|
90
|
-
const [returnFocus] =
|
|
167
|
+
const [returnFocus] = useState2(() => {
|
|
91
168
|
return typeof document === "undefined" ? null : document.activeElement;
|
|
92
169
|
});
|
|
93
170
|
useEffect(() => {
|
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/dropdown-menu-content.tsx", "../src/dropdown-menu-trigger/dropdown-menu-trigger.tsx", "../src/context-menu/context-menu.tsx", "../src/shared/style.ts", "../src/dropdown-menu-item/dropdown-menu-item.tsx", "../src/dropdown-menu-label/style.ts", "../src/dropdown-menu-label/dropdown-menu-label.tsx", "../src/dropdown-menu-radio-group/dropdown-menu-radio-group.tsx", "../src/dropdown-menu-radio-item/style.ts", "../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 { overlaySurfaceStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownContentStyles = cva(cn(\n overlaySurfaceStyles(),\n \"gridui-dropdown-content\",\n \"gridui-u-z-(--gridui-z-popover) gridui-u-min-w-44 gridui-u-max-w-[calc(100vw-2*var(--gridui-page-gutter))] gridui-u-max-h-(--radix-dropdown-menu-content-available-height) gridui-u-overflow-y-auto gridui-u-p-0 gridui-u-type-data\",\n));\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuContent\n * @description Dropdown Menu Content\n */\n\nimport { dropdownContentStyles } from \"./style\";\nimport { interactionLayerProps, RetainedLayer, useInteractionOutline, useScrollbars } 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 DropdownMenuContentProps = ComponentPropsWithRef<typeof Primitive.Content>;\n\nexport const DropdownMenuContent: FC<DropdownMenuContentProps> = (props: DropdownMenuContentProps) => {\n const {\n className,\n ref: forwardedRef,\n forceMount,\n sideOffset = 8,\n align = \"end\",\n ...restProps\n } = props;\n const scrollbarRef = useScrollbars({ ref: 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 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 } from \"../dropdown-menu/dropdown-menu\";\nimport { DropdownMenuContent, type DropdownMenuContentProps } from \"../dropdown-menu-content/dropdown-menu-content\";\nimport { DropdownMenuTrigger } from \"../dropdown-menu-trigger/dropdown-menu-trigger\";\nimport { type FC, type ReactNode, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nexport type ContextMenuProps = Omit<DropdownMenuContentProps, \"children\"> & {\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, 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 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 Shared\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownItemStyles = cva(cn(\n \"gridui-dropdown-item\",\n \"gridui-u-flex gridui-u-min-h-10 gridui-u-items-center gridui-u-gap-gridui-8 gridui-u-px-gridui-8 gridui-u-py-gridui-8 gridui-u-rounded-control gridui-u-text-inherit gridui-u-no-underline gridui-u-cursor-pointer\",\n \"gridui-u-data-[state=checked]:bg-brand-tint gridui-u-aria-selected:bg-brand-tint\",\n \"gridui-u-data-disabled:opacity-50 gridui-u-data-disabled:pointer-events-none\",\n));\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuItem\n * @description Dropdown Menu Item\n */\n\nimport { dropdownItemStyles } from \"../shared/style\";\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(dropdownItemStyles(), className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuLabel\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownLabelStyles = cva(cn(\n \"gridui-dropdown-label\",\n \"gridui-u-p-gridui-8 gridui-u-text-muted gridui-u-type-caption\",\n));\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuLabel\n * @description Dropdown Menu Label\n */\n\nimport { dropdownLabelStyles } from \"./style\";\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(dropdownLabelStyles(), 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 Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownIndicatorStyles = cva(cn(\n \"gridui-dropdown-indicator\",\n \"gridui-u-w-gridui-16 gridui-u-shrink-0 gridui-u-text-foreground\",\n));\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuRadioItem\n * @description Dropdown Menu Radio Item\n */\n\nimport { dropdownItemStyles } from \"../shared/style\";\nimport { dropdownIndicatorStyles } from \"./style\";\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(dropdownItemStyles(), className)}\n >\n <span\n className={cn(dropdownIndicatorStyles())}\n aria-hidden=\"true\"\n >\n <Primitive.ItemIndicator>\n <Check\n size={16}\n aria-hidden=\"true\"\n />\n </Primitive.ItemIndicator>\n </span>\n {children}\n </Primitive.RadioItem>);\n};\n"],
|
|
5
|
-
"mappings": ";AAOA,SAAS,aAAa,uBAAuB;AAC7C,YAAY,eAAe;AAUnB;AALD,IAAM,eAAsC,CAAC,UAA6B;AAC7E,QAAM,QAAQ,gBAAgB,KAAK;AACnC,SAAQ;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACL,OAAO,MAAM;AAAA,MAEb;AAAA,QAAW;AAAA,QAAV;AAAA,UACI,GAAG;AAAA,UACH,GAAG;AAAA;AAAA,MACR;AAAA;AAAA,EACJ;AACJ;;;AChBA,SAAS,4BAA4B;AACrC,SAAS,UAAU;AACnB,SAAS,WAAW;AAEb,IAAM,wBAAwB,IAAI;AAAA,EACrC,qBAAqB;AAAA,EACrB;AAAA,EACA;AACJ,CAAC;;;
|
|
6
|
-
"names": ["cn", "Primitive", "jsx", "Primitive", "jsx", "jsx", "cn", "cva", "cn", "Primitive", "jsx", "cn", "cva", "cn", "Primitive", "jsx", "Primitive", "jsx", "cn", "cva", "cn", "Primitive", "jsx", "jsxs"]
|
|
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/shared/style.ts", "../src/dropdown-menu-item/dropdown-menu-item.tsx", "../src/dropdown-menu-label/style.ts", "../src/dropdown-menu-label/dropdown-menu-label.tsx", "../src/dropdown-menu-radio-group/dropdown-menu-radio-group.tsx", "../src/dropdown-menu-radio-item/style.ts", "../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 { overlaySurfaceStyles } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownContentStyles = cva(cn(\n overlaySurfaceStyles(),\n \"gridui-dropdown-content\",\n \"gridui-u-z-(--gridui-z-popover) gridui-u-min-w-44 gridui-u-max-w-[calc(100vw-2*var(--gridui-page-gutter))] gridui-u-max-h-(--radix-dropdown-menu-content-available-height) gridui-u-overflow-y-auto gridui-u-p-0 gridui-u-type-data\",\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 } 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\"> & {\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, 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 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 Shared\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownItemStyles = cva(cn(\n \"gridui-dropdown-item\",\n \"gridui-u-flex gridui-u-min-h-10 gridui-u-items-center gridui-u-gap-gridui-8 gridui-u-px-gridui-8 gridui-u-py-gridui-8 gridui-u-rounded-control gridui-u-text-inherit gridui-u-no-underline gridui-u-cursor-pointer\",\n \"gridui-u-data-[state=checked]:bg-brand-tint gridui-u-aria-selected:bg-brand-tint\",\n \"gridui-u-data-disabled:opacity-50 gridui-u-data-disabled:pointer-events-none\",\n));\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuItem\n * @description Dropdown Menu Item\n */\n\nimport { dropdownItemStyles } from \"../shared/style\";\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(dropdownItemStyles(), className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuLabel\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownLabelStyles = cva(cn(\n \"gridui-dropdown-label\",\n \"gridui-u-p-gridui-8 gridui-u-text-muted gridui-u-type-caption\",\n));\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuLabel\n * @description Dropdown Menu Label\n */\n\nimport { dropdownLabelStyles } from \"./style\";\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(dropdownLabelStyles(), 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 Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const dropdownIndicatorStyles = cva(cn(\n \"gridui-dropdown-indicator\",\n \"gridui-u-w-gridui-16 gridui-u-shrink-0 gridui-u-text-foreground\",\n));\n", "/**\n * @author WMXPY\n * @package Dropdown Menu\n * @namespace DropdownMenuRadioItem\n * @description Dropdown Menu Radio Item\n */\n\nimport { dropdownItemStyles } from \"../shared/style\";\nimport { dropdownIndicatorStyles } from \"./style\";\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(dropdownItemStyles(), className)}\n >\n <span\n className={cn(dropdownIndicatorStyles())}\n aria-hidden=\"true\"\n >\n <Primitive.ItemIndicator>\n <Check\n size={16}\n aria-hidden=\"true\"\n />\n </Primitive.ItemIndicator>\n </span>\n {children}\n </Primitive.RadioItem>);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["document", "OverlayOpen", "cn", "Primitive", "jsx", "Primitive", "jsx", "useState", "jsx", "cn", "cva", "cn", "Primitive", "jsx", "cn", "cva", "cn", "Primitive", "jsx", "Primitive", "jsx", "cn", "cva", "cn", "Primitive", "jsx", "jsxs"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Dropdown Menu
|
|
4
|
+
* @namespace Shared
|
|
5
|
+
* @description Menu Content Options
|
|
6
|
+
*/
|
|
7
|
+
import type * as Primitive from "@radix-ui/react-dropdown-menu";
|
|
8
|
+
import type { ComponentPropsWithRef } from "react";
|
|
9
|
+
export type MenuContentOptions = ComponentPropsWithRef<typeof Primitive.Content> & {
|
|
10
|
+
readonly morph?: boolean | undefined;
|
|
11
|
+
readonly respectReducedMotion?: boolean | undefined;
|
|
12
|
+
};
|
package/dist/styles.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! tailwindcss v4.3.
|
|
1
|
+
/*! tailwindcss v4.3.5 | MIT License | https://tailwindcss.com */
|
|
2
2
|
@layer theme, base, components, utilities;
|
|
3
3
|
@layer theme {
|
|
4
4
|
:root, :host {
|
|
@@ -95,4 +95,29 @@
|
|
|
95
95
|
.gridui-dropdown-content {
|
|
96
96
|
--gridui-overlay-origin: var(--radix-dropdown-menu-content-transform-origin);
|
|
97
97
|
}
|
|
98
|
+
.gridui-dropdown-content[data-morph-measuring][data-state="open"] {
|
|
99
|
+
animation: none;
|
|
100
|
+
}
|
|
101
|
+
@supports (clip-path: inset(0)) {
|
|
102
|
+
.gridui-dropdown-content[data-morph-ready][data-state="open"] {
|
|
103
|
+
animation: gridui-menu-morph var(--gridui-motion-duration-normal) var(--gridui-motion-ease-out);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
@media (prefers-reduced-motion: reduce) {
|
|
107
|
+
.gridui-dropdown-content[data-morph-ready][data-state="open"]:not([data-morph-ignore-reduced-motion]) {
|
|
108
|
+
animation: none;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
@keyframes gridui-menu-morph {
|
|
112
|
+
from {
|
|
113
|
+
clip-path: var(--gridui-menu-morph-clip);
|
|
114
|
+
opacity: 0.6;
|
|
115
|
+
transform: translate(var(--gridui-menu-morph-offset));
|
|
116
|
+
}
|
|
117
|
+
to {
|
|
118
|
+
clip-path: inset(0);
|
|
119
|
+
opacity: 1;
|
|
120
|
+
transform: translate(0, 0);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
98
123
|
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"name": "@gridui/dropdown-menu",
|
|
4
|
+
"version": "1.2.0",
|
|
5
|
+
"category": "core",
|
|
6
|
+
"description": "GridUI React dropdown menu",
|
|
7
|
+
"usage": "`@gridui/dropdown-menu` wraps Radix Dropdown Menu. It exports the root, trigger, portalled content, items, label, radio group, and radio item. Native primitive props and refs remain available. Load its separate `styles.css` export. Radix owns keyboard navigation, focus return, Escape dismissal, and viewport collisions. The portal avoids clipped grid boundaries.",
|
|
8
|
+
"documentation": [
|
|
9
|
+
"README.md",
|
|
10
|
+
"docs/context-menu.md"
|
|
11
|
+
],
|
|
12
|
+
"exports": [
|
|
13
|
+
{
|
|
14
|
+
"name": "ContextMenu",
|
|
15
|
+
"kind": "component",
|
|
16
|
+
"importPath": "@gridui/dropdown-menu"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "ContextMenuProps",
|
|
20
|
+
"kind": "type",
|
|
21
|
+
"importPath": "@gridui/dropdown-menu"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "dropdownContentStyles",
|
|
25
|
+
"kind": "value",
|
|
26
|
+
"importPath": "@gridui/dropdown-menu"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "dropdownIndicatorStyles",
|
|
30
|
+
"kind": "value",
|
|
31
|
+
"importPath": "@gridui/dropdown-menu"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "dropdownItemStyles",
|
|
35
|
+
"kind": "value",
|
|
36
|
+
"importPath": "@gridui/dropdown-menu"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "dropdownLabelStyles",
|
|
40
|
+
"kind": "value",
|
|
41
|
+
"importPath": "@gridui/dropdown-menu"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "DropdownMenu",
|
|
45
|
+
"kind": "component",
|
|
46
|
+
"importPath": "@gridui/dropdown-menu"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "DropdownMenuContent",
|
|
50
|
+
"kind": "component",
|
|
51
|
+
"importPath": "@gridui/dropdown-menu"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "DropdownMenuContentProps",
|
|
55
|
+
"kind": "type",
|
|
56
|
+
"importPath": "@gridui/dropdown-menu"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "DropdownMenuItem",
|
|
60
|
+
"kind": "component",
|
|
61
|
+
"importPath": "@gridui/dropdown-menu"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "DropdownMenuItemProps",
|
|
65
|
+
"kind": "type",
|
|
66
|
+
"importPath": "@gridui/dropdown-menu"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "DropdownMenuLabel",
|
|
70
|
+
"kind": "component",
|
|
71
|
+
"importPath": "@gridui/dropdown-menu"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"name": "DropdownMenuLabelProps",
|
|
75
|
+
"kind": "type",
|
|
76
|
+
"importPath": "@gridui/dropdown-menu"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "DropdownMenuProps",
|
|
80
|
+
"kind": "type",
|
|
81
|
+
"importPath": "@gridui/dropdown-menu"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "DropdownMenuRadioGroup",
|
|
85
|
+
"kind": "component",
|
|
86
|
+
"importPath": "@gridui/dropdown-menu"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "DropdownMenuRadioGroupProps",
|
|
90
|
+
"kind": "type",
|
|
91
|
+
"importPath": "@gridui/dropdown-menu"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "DropdownMenuRadioItem",
|
|
95
|
+
"kind": "component",
|
|
96
|
+
"importPath": "@gridui/dropdown-menu"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "DropdownMenuRadioItemProps",
|
|
100
|
+
"kind": "type",
|
|
101
|
+
"importPath": "@gridui/dropdown-menu"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"name": "DropdownMenuTrigger",
|
|
105
|
+
"kind": "component",
|
|
106
|
+
"importPath": "@gridui/dropdown-menu"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "DropdownMenuTriggerProps",
|
|
110
|
+
"kind": "type",
|
|
111
|
+
"importPath": "@gridui/dropdown-menu"
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"styles": [
|
|
115
|
+
"@gridui/theme/styles.css",
|
|
116
|
+
"@gridui/overlay/styles.css",
|
|
117
|
+
"@gridui/dropdown-menu/styles.css"
|
|
118
|
+
],
|
|
119
|
+
"examples": [
|
|
120
|
+
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/context-menu.stories.tsx",
|
|
121
|
+
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/dropdown-menu/stories/dropdown-menu.stories.tsx"
|
|
122
|
+
]
|
|
123
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridui/dropdown-menu",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.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": "^1.2.
|
|
31
|
-
"@gridui/style-utils": "^2.2.
|
|
32
|
-
"@gridui/theme": "^2.5.
|
|
30
|
+
"@gridui/overlay": "^1.2.2",
|
|
31
|
+
"@gridui/style-utils": "^2.2.2",
|
|
32
|
+
"@gridui/theme": "^2.5.3",
|
|
33
33
|
"@radix-ui/react-dropdown-menu": "2.2.1",
|
|
34
34
|
"class-variance-authority": "0.7.1",
|
|
35
|
-
"lucide-react": "1.
|
|
35
|
+
"lucide-react": "1.70.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@gridui-internal/configuration": "0.0.0-internal",
|
|
39
|
-
"@gridui/button": "3.1.
|
|
39
|
+
"@gridui/button": "3.1.2",
|
|
40
40
|
"@jest/globals": "30.5.2",
|
|
41
|
-
"@storybook/react-vite": "10.6.
|
|
41
|
+
"@storybook/react-vite": "10.6.6",
|
|
42
42
|
"@types/jest": "30.0.0",
|
|
43
43
|
"@types/node": "26.6.6",
|
|
44
44
|
"@types/react": "19.3.0",
|