@gridui/dropdown-menu 1.1.7 → 2.0.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 +27 -6
- package/dist/context-menu/context-menu.d.ts +3 -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.d.ts +0 -3
- package/dist/index.js +105 -47
- package/dist/index.js.map +4 -4
- package/dist/shared/menu-content-options.d.ts +12 -0
- package/dist/styles.css +38 -70
- package/docs/catalog.json +2 -17
- package/docs/context-menu.md +12 -2
- package/package.json +5 -5
- package/dist/dropdown-menu-label/style.d.ts +0 -7
- package/dist/dropdown-menu-radio-item/style.d.ts +0 -7
- package/dist/shared/style.d.ts +0 -7
package/README.md
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
# @gridui/dropdown-menu
|
|
2
2
|
|
|
3
|
-
Core family. Public API: `ContextMenu`, `ContextMenuProps`, `DropdownMenu`, `DropdownMenuContent`, `DropdownMenuContentProps`, `DropdownMenuItem`, `DropdownMenuItemProps`, `DropdownMenuLabel`, `DropdownMenuLabelProps`, `DropdownMenuProps`, `DropdownMenuRadioGroup`, `DropdownMenuRadioGroupProps`, `DropdownMenuRadioItem`, `DropdownMenuRadioItemProps`, `DropdownMenuTrigger`, `DropdownMenuTriggerProps`, `dropdownContentStyles
|
|
3
|
+
Core family. Public API: `ContextMenu`, `ContextMenuProps`, `DropdownMenu`, `DropdownMenuContent`, `DropdownMenuContentProps`, `DropdownMenuItem`, `DropdownMenuItemProps`, `DropdownMenuLabel`, `DropdownMenuLabelProps`, `DropdownMenuProps`, `DropdownMenuRadioGroup`, `DropdownMenuRadioGroupProps`, `DropdownMenuRadioItem`, `DropdownMenuRadioItemProps`, `DropdownMenuTrigger`, `DropdownMenuTriggerProps`, `dropdownContentStyles`.
|
|
4
4
|
|
|
5
|
-
Import components from `@gridui/dropdown-menu` and load
|
|
6
|
-
|
|
5
|
+
Import components from `@gridui/dropdown-menu` and load these styles in order:
|
|
6
|
+
|
|
7
|
+
```css
|
|
8
|
+
@import "@gridui/theme/styles.css";
|
|
9
|
+
@import "@gridui/overlay/styles.css";
|
|
10
|
+
@import "@gridui/dropdown-menu/styles.css";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Overlay supplies popup surfaces, option rows, group labels, and selection
|
|
14
|
+
indicators. Applications own routes, labels, state persistence, and branding.
|
|
7
15
|
|
|
8
16
|
See [component ownership](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/docs/component-ownership.md) and [release history](https://github.com/sudo-ui/GridUI-React-Monorepo/tree/main/packages-core/dropdown-menu/.changeset/history).
|
|
9
17
|
|
|
@@ -13,7 +21,8 @@ Import `Button`, `ButtonLink`, `buttonClass`, and `useAsyncAction`
|
|
|
13
21
|
from [`@gridui/button`](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/button/README.md). Load that package's `styles.css`
|
|
14
22
|
for standalone buttons and composed actions. The Button package owns
|
|
15
23
|
native semantics, variants, sizes, icons, loading, and action lifecycle behavior.
|
|
16
|
-
|
|
24
|
+
Compose a styled trigger with `<DropdownMenuTrigger asChild>` and `Button`,
|
|
25
|
+
loading Button’s stylesheet when used. DropdownMenu does not require Button.
|
|
17
26
|
|
|
18
27
|
`@gridui/dropdown-menu` wraps Radix Dropdown Menu.
|
|
19
28
|
It exports the root, trigger, portalled content, items, label, radio
|
|
@@ -22,8 +31,7 @@ its separate `styles.css` export. Radix owns keyboard navigation, focus return,
|
|
|
22
31
|
Escape dismissal, and viewport collisions. The portal avoids clipped grid
|
|
23
32
|
boundaries.
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
Surface motion uses `@gridui/overlay`; load `@gridui/overlay/styles.css` after Theme and before this family.
|
|
34
|
+
Surface motion also uses `@gridui/overlay`.
|
|
27
35
|
|
|
28
36
|
Menu options use Theme's outward hover, pressed, and focus outlines. Overlay
|
|
29
37
|
mirrors their resolved outlines beyond the menu's scrolling boundary, including
|
|
@@ -33,3 +41,16 @@ and dismissal; the decorative outline layer cannot receive pointer input.
|
|
|
33
41
|
The menu surface has no padding by default: option hit areas reach its inner
|
|
34
42
|
border, and each option owns its text padding. Caller classes can add deliberate
|
|
35
43
|
surface padding. Native scrolling uses Theme's shared scrollbar appearance.
|
|
44
|
+
|
|
45
|
+
Menus, context menus, and selection lists share `overlayListStyles()` from Overlay
|
|
46
|
+
and its `overlayListItemStyles()`, `overlayListLabelStyles()`, and
|
|
47
|
+
`overlayListIndicatorStyles()` helpers. Selectable rows reserve
|
|
48
|
+
a trailing 16px check slot in both selected and unselected states. Icons and text
|
|
49
|
+
precede the check; RTL mirrors the order. Labels wrap within the available width.
|
|
50
|
+
|
|
51
|
+
Set `morph` on `DropdownMenuContent` to expand the menu from its trigger
|
|
52
|
+
when opening. `respectReducedMotion` defaults to `true`. Set it to `false`
|
|
53
|
+
to play the expansion even when the system requests reduced motion.
|
|
54
|
+
|
|
55
|
+
`ContextMenu` accepts `dir="ltr" | "rtl"` and forwards it to the menu root,
|
|
56
|
+
so portal positioning and keyboard navigation use the same direction as its rows.
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* @namespace ContextMenu
|
|
5
5
|
* @description Context Menu
|
|
6
6
|
*/
|
|
7
|
-
import { type
|
|
7
|
+
import { type DropdownMenuProps } from "../dropdown-menu/dropdown-menu";
|
|
8
|
+
import type { MenuContentOptions } from "../shared/menu-content-options";
|
|
8
9
|
import { type FC, type ReactNode } from "react";
|
|
9
|
-
export type ContextMenuProps = Omit<
|
|
10
|
+
export type ContextMenuProps = Omit<MenuContentOptions, "children"> & Pick<DropdownMenuProps, "dir"> & {
|
|
10
11
|
readonly x: number;
|
|
11
12
|
readonly y: number;
|
|
12
13
|
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.d.ts
CHANGED
|
@@ -15,12 +15,9 @@ export type { DropdownMenuItemProps } from "./dropdown-menu-item/dropdown-menu-i
|
|
|
15
15
|
export { DropdownMenuItem } from "./dropdown-menu-item/dropdown-menu-item";
|
|
16
16
|
export type { DropdownMenuLabelProps } from "./dropdown-menu-label/dropdown-menu-label";
|
|
17
17
|
export { DropdownMenuLabel } from "./dropdown-menu-label/dropdown-menu-label";
|
|
18
|
-
export { dropdownLabelStyles } from "./dropdown-menu-label/style";
|
|
19
18
|
export type { DropdownMenuRadioGroupProps } from "./dropdown-menu-radio-group/dropdown-menu-radio-group";
|
|
20
19
|
export { DropdownMenuRadioGroup } from "./dropdown-menu-radio-group/dropdown-menu-radio-group";
|
|
21
20
|
export type { DropdownMenuRadioItemProps } from "./dropdown-menu-radio-item/dropdown-menu-radio-item";
|
|
22
21
|
export { DropdownMenuRadioItem } from "./dropdown-menu-radio-item/dropdown-menu-radio-item";
|
|
23
|
-
export { dropdownIndicatorStyles } from "./dropdown-menu-radio-item/style";
|
|
24
22
|
export type { DropdownMenuTriggerProps } from "./dropdown-menu-trigger/dropdown-menu-trigger";
|
|
25
23
|
export { DropdownMenuTrigger } from "./dropdown-menu-trigger/dropdown-menu-trigger";
|
|
26
|
-
export { dropdownItemStyles } from "./shared/style";
|
package/dist/index.js
CHANGED
|
@@ -20,19 +20,72 @@ var DropdownMenu = (props) => {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
// src/dropdown-menu-content/style.ts
|
|
23
|
-
import {
|
|
23
|
+
import { overlayListStyles } from "@gridui/overlay";
|
|
24
24
|
import { cn } from "@gridui/style-utils";
|
|
25
25
|
import { cva } from "class-variance-authority";
|
|
26
26
|
var dropdownContentStyles = cva(cn(
|
|
27
|
-
|
|
27
|
+
overlayListStyles(),
|
|
28
28
|
"gridui-dropdown-content",
|
|
29
|
-
"gridui-u-
|
|
29
|
+
"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"
|
|
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
|
-
const { x, y, label, children, onClose, onCloseAutoFocus, onKeyDown, onPointerUpCapture, ...contentProps } = props;
|
|
90
|
-
const [returnFocus] =
|
|
166
|
+
const { x, y, label, dir, children, onClose, onCloseAutoFocus, onKeyDown, onPointerUpCapture, ...contentProps } = props;
|
|
167
|
+
const [returnFocus] = useState2(() => {
|
|
91
168
|
return typeof document === "undefined" ? null : document.activeElement;
|
|
92
169
|
});
|
|
93
170
|
useEffect(() => {
|
|
@@ -109,6 +186,7 @@ var ContextMenu = (props) => {
|
|
|
109
186
|
{
|
|
110
187
|
open: true,
|
|
111
188
|
modal: false,
|
|
189
|
+
dir,
|
|
112
190
|
onOpenChange: (open) => {
|
|
113
191
|
if (!open) {
|
|
114
192
|
onClose();
|
|
@@ -181,18 +259,9 @@ var ContextMenu = (props) => {
|
|
|
181
259
|
), document.body);
|
|
182
260
|
};
|
|
183
261
|
|
|
184
|
-
// src/shared/style.ts
|
|
185
|
-
import { cn as cn3 } from "@gridui/style-utils";
|
|
186
|
-
import { cva as cva2 } from "class-variance-authority";
|
|
187
|
-
var dropdownItemStyles = cva2(cn3(
|
|
188
|
-
"gridui-dropdown-item",
|
|
189
|
-
"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",
|
|
190
|
-
"gridui-u-data-[state=checked]:bg-brand-tint gridui-u-aria-selected:bg-brand-tint",
|
|
191
|
-
"gridui-u-data-disabled:opacity-50 gridui-u-data-disabled:pointer-events-none"
|
|
192
|
-
));
|
|
193
|
-
|
|
194
262
|
// src/dropdown-menu-item/dropdown-menu-item.tsx
|
|
195
|
-
import {
|
|
263
|
+
import { overlayListItemStyles } from "@gridui/overlay";
|
|
264
|
+
import { cn as cn3 } from "@gridui/style-utils";
|
|
196
265
|
import * as Primitive4 from "@radix-ui/react-dropdown-menu";
|
|
197
266
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
198
267
|
var DropdownMenuItem = (props) => {
|
|
@@ -204,21 +273,14 @@ var DropdownMenuItem = (props) => {
|
|
|
204
273
|
Primitive4.Item,
|
|
205
274
|
{
|
|
206
275
|
...restProps,
|
|
207
|
-
className:
|
|
276
|
+
className: cn3(overlayListItemStyles(), className)
|
|
208
277
|
}
|
|
209
278
|
);
|
|
210
279
|
};
|
|
211
280
|
|
|
212
|
-
// src/dropdown-menu-label/style.ts
|
|
213
|
-
import { cn as cn5 } from "@gridui/style-utils";
|
|
214
|
-
import { cva as cva3 } from "class-variance-authority";
|
|
215
|
-
var dropdownLabelStyles = cva3(cn5(
|
|
216
|
-
"gridui-dropdown-label",
|
|
217
|
-
"gridui-u-p-gridui-8 gridui-u-text-muted gridui-u-type-caption"
|
|
218
|
-
));
|
|
219
|
-
|
|
220
281
|
// src/dropdown-menu-label/dropdown-menu-label.tsx
|
|
221
|
-
import {
|
|
282
|
+
import { overlayListLabelStyles } from "@gridui/overlay";
|
|
283
|
+
import { cn as cn4 } from "@gridui/style-utils";
|
|
222
284
|
import * as Primitive5 from "@radix-ui/react-dropdown-menu";
|
|
223
285
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
224
286
|
var DropdownMenuLabel = (props) => {
|
|
@@ -230,7 +292,7 @@ var DropdownMenuLabel = (props) => {
|
|
|
230
292
|
Primitive5.Label,
|
|
231
293
|
{
|
|
232
294
|
...restProps,
|
|
233
|
-
className:
|
|
295
|
+
className: cn4(overlayListLabelStyles(), className)
|
|
234
296
|
}
|
|
235
297
|
);
|
|
236
298
|
};
|
|
@@ -247,16 +309,9 @@ var DropdownMenuRadioGroup = (props) => {
|
|
|
247
309
|
);
|
|
248
310
|
};
|
|
249
311
|
|
|
250
|
-
// src/dropdown-menu-radio-item/style.ts
|
|
251
|
-
import { cn as cn7 } from "@gridui/style-utils";
|
|
252
|
-
import { cva as cva4 } from "class-variance-authority";
|
|
253
|
-
var dropdownIndicatorStyles = cva4(cn7(
|
|
254
|
-
"gridui-dropdown-indicator",
|
|
255
|
-
"gridui-u-w-gridui-16 gridui-u-shrink-0 gridui-u-text-foreground"
|
|
256
|
-
));
|
|
257
|
-
|
|
258
312
|
// src/dropdown-menu-radio-item/dropdown-menu-radio-item.tsx
|
|
259
|
-
import {
|
|
313
|
+
import { overlayListIndicatorStyles, overlayListItemStyles as overlayListItemStyles2 } from "@gridui/overlay";
|
|
314
|
+
import { cn as cn5 } from "@gridui/style-utils";
|
|
260
315
|
import * as Primitive7 from "@radix-ui/react-dropdown-menu";
|
|
261
316
|
import { Check } from "lucide-react";
|
|
262
317
|
import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -270,12 +325,19 @@ var DropdownMenuRadioItem = (props) => {
|
|
|
270
325
|
Primitive7.RadioItem,
|
|
271
326
|
{
|
|
272
327
|
...restProps,
|
|
273
|
-
className:
|
|
328
|
+
className: cn5(overlayListItemStyles2(), className),
|
|
274
329
|
children: [
|
|
275
330
|
/* @__PURE__ */ jsx8(
|
|
276
331
|
"span",
|
|
277
332
|
{
|
|
278
|
-
className:
|
|
333
|
+
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",
|
|
334
|
+
children
|
|
335
|
+
}
|
|
336
|
+
),
|
|
337
|
+
/* @__PURE__ */ jsx8(
|
|
338
|
+
"span",
|
|
339
|
+
{
|
|
340
|
+
className: cn5(overlayListIndicatorStyles()),
|
|
279
341
|
"aria-hidden": "true",
|
|
280
342
|
children: /* @__PURE__ */ jsx8(Primitive7.ItemIndicator, { children: /* @__PURE__ */ jsx8(
|
|
281
343
|
Check,
|
|
@@ -285,8 +347,7 @@ var DropdownMenuRadioItem = (props) => {
|
|
|
285
347
|
}
|
|
286
348
|
) })
|
|
287
349
|
}
|
|
288
|
-
)
|
|
289
|
-
children
|
|
350
|
+
)
|
|
290
351
|
]
|
|
291
352
|
}
|
|
292
353
|
);
|
|
@@ -300,9 +361,6 @@ export {
|
|
|
300
361
|
DropdownMenuRadioGroup,
|
|
301
362
|
DropdownMenuRadioItem,
|
|
302
363
|
DropdownMenuTrigger,
|
|
303
|
-
dropdownContentStyles
|
|
304
|
-
dropdownIndicatorStyles,
|
|
305
|
-
dropdownItemStyles,
|
|
306
|
-
dropdownLabelStyles
|
|
364
|
+
dropdownContentStyles
|
|
307
365
|
};
|
|
308
366
|
//# sourceMappingURL=index.js.map
|
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/
|
|
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,
|
|
6
|
-
"names": ["
|
|
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"]
|
|
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 {
|
|
@@ -6,93 +6,61 @@
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
@layer utilities {
|
|
9
|
-
.gridui-u-
|
|
10
|
-
z-index: var(--gridui-z-popover);
|
|
11
|
-
}
|
|
12
|
-
.gridui-u-flex {
|
|
9
|
+
.gridui-u-dropdown-menu--flex {
|
|
13
10
|
display: flex;
|
|
14
11
|
}
|
|
15
|
-
.gridui-u-max-h-\(--radix-dropdown-menu-content-available-height\) {
|
|
12
|
+
.gridui-u-dropdown-menu--max-h-\(--radix-dropdown-menu-content-available-height\) {
|
|
16
13
|
max-height: var(--radix-dropdown-menu-content-available-height);
|
|
17
14
|
}
|
|
18
|
-
.gridui-u-
|
|
19
|
-
min-height: calc(var(--spacing) * 10);
|
|
20
|
-
}
|
|
21
|
-
.gridui-u-w-gridui-16 {
|
|
22
|
-
width: var(--gridui-space-16);
|
|
23
|
-
}
|
|
24
|
-
.gridui-u-max-w-\[calc\(100vw-2\*var\(--gridui-page-gutter\)\)\] {
|
|
15
|
+
.gridui-u-dropdown-menu--max-w-\[calc\(100vw-2\*var\(--gridui-page-gutter\)\)\] {
|
|
25
16
|
max-width: calc(100vw - 2 * var(--gridui-page-gutter));
|
|
26
17
|
}
|
|
27
|
-
.gridui-u-min-w-
|
|
28
|
-
min-width:
|
|
18
|
+
.gridui-u-dropdown-menu--min-w-0 {
|
|
19
|
+
min-width: 0px;
|
|
29
20
|
}
|
|
30
|
-
.gridui-u-
|
|
31
|
-
|
|
21
|
+
.gridui-u-dropdown-menu--min-w-44 {
|
|
22
|
+
min-width: calc(var(--spacing) * 44);
|
|
32
23
|
}
|
|
33
|
-
.gridui-u-
|
|
34
|
-
|
|
24
|
+
.gridui-u-dropdown-menu--flex-1 {
|
|
25
|
+
flex: 1;
|
|
35
26
|
}
|
|
36
|
-
.gridui-u-items-center {
|
|
27
|
+
.gridui-u-dropdown-menu--items-center {
|
|
37
28
|
align-items: center;
|
|
38
29
|
}
|
|
39
|
-
.gridui-u-gap-gridui-8 {
|
|
30
|
+
.gridui-u-dropdown-menu--gap-gridui-8 {
|
|
40
31
|
gap: var(--gridui-space-8);
|
|
41
32
|
}
|
|
42
|
-
.gridui-u-overflow-y-auto {
|
|
33
|
+
.gridui-u-dropdown-menu--overflow-y-auto {
|
|
43
34
|
overflow-y: auto;
|
|
44
35
|
}
|
|
45
|
-
.gridui-u-rounded-control {
|
|
46
|
-
border-radius: var(--gridui-control-radius);
|
|
47
|
-
}
|
|
48
|
-
.gridui-u-p-0 {
|
|
49
|
-
padding: 0px;
|
|
50
|
-
}
|
|
51
|
-
.gridui-u-p-gridui-8 {
|
|
52
|
-
padding: var(--gridui-space-8);
|
|
53
|
-
}
|
|
54
|
-
.gridui-u-px-gridui-8 {
|
|
55
|
-
padding-inline: var(--gridui-space-8);
|
|
56
|
-
}
|
|
57
|
-
.gridui-u-py-gridui-8 {
|
|
58
|
-
padding-block: var(--gridui-space-8);
|
|
59
|
-
}
|
|
60
|
-
.gridui-u-type-data {
|
|
61
|
-
font: var(--gridui-type-data);
|
|
62
|
-
letter-spacing: normal;
|
|
63
|
-
font-variant-numeric: tabular-nums;
|
|
64
|
-
}
|
|
65
|
-
.gridui-u-type-caption {
|
|
66
|
-
font: var(--gridui-type-caption);
|
|
67
|
-
letter-spacing: normal;
|
|
68
|
-
}
|
|
69
|
-
.gridui-u-text-foreground {
|
|
70
|
-
color: var(--gridui-foreground);
|
|
71
|
-
}
|
|
72
|
-
.gridui-u-text-inherit {
|
|
73
|
-
color: inherit;
|
|
74
|
-
}
|
|
75
|
-
.gridui-u-text-muted {
|
|
76
|
-
color: var(--gridui-muted);
|
|
77
|
-
}
|
|
78
|
-
.gridui-u-no-underline {
|
|
79
|
-
text-decoration-line: none;
|
|
80
|
-
}
|
|
81
|
-
.gridui-u-aria-selected\:bg-brand-tint[aria-selected="true"] {
|
|
82
|
-
background-color: var(--gridui-brand-tint);
|
|
83
|
-
}
|
|
84
|
-
.gridui-u-data-disabled\:pointer-events-none[data-disabled] {
|
|
85
|
-
pointer-events: none;
|
|
86
|
-
}
|
|
87
|
-
.gridui-u-data-disabled\:opacity-50[data-disabled] {
|
|
88
|
-
opacity: 50%;
|
|
89
|
-
}
|
|
90
|
-
.gridui-u-data-\[state\=checked\]\:bg-brand-tint[data-state="checked"] {
|
|
91
|
-
background-color: var(--gridui-brand-tint);
|
|
92
|
-
}
|
|
93
36
|
}
|
|
94
37
|
@layer components {
|
|
95
38
|
.gridui-dropdown-content {
|
|
96
39
|
--gridui-overlay-origin: var(--radix-dropdown-menu-content-transform-origin);
|
|
97
40
|
}
|
|
41
|
+
.gridui-dropdown-content[data-morph-measuring][data-state="open"] {
|
|
42
|
+
animation: none;
|
|
43
|
+
}
|
|
44
|
+
@supports (clip-path: inset(0)) {
|
|
45
|
+
.gridui-dropdown-content[data-morph-ready][data-state="open"] {
|
|
46
|
+
animation: gridui-menu-morph var(--gridui-motion-duration-normal) var(--gridui-motion-ease-out);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
@media (prefers-reduced-motion: reduce) {
|
|
50
|
+
.gridui-dropdown-content[data-morph-ready][data-state="open"]:not([data-morph-ignore-reduced-motion]) {
|
|
51
|
+
animation: none;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
@keyframes gridui-menu-morph {
|
|
55
|
+
from {
|
|
56
|
+
clip-path: var(--gridui-menu-morph-clip);
|
|
57
|
+
opacity: 0.6;
|
|
58
|
+
transform: translate(var(--gridui-menu-morph-offset));
|
|
59
|
+
}
|
|
60
|
+
to {
|
|
61
|
+
clip-path: inset(0);
|
|
62
|
+
opacity: 1;
|
|
63
|
+
transform: translate(0, 0);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
98
66
|
}
|
package/docs/catalog.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"name": "@gridui/dropdown-menu",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"category": "core",
|
|
6
6
|
"description": "GridUI React dropdown menu",
|
|
7
|
-
"usage": "
|
|
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
10
|
"docs/context-menu.md"
|
|
@@ -25,21 +25,6 @@
|
|
|
25
25
|
"kind": "value",
|
|
26
26
|
"importPath": "@gridui/dropdown-menu"
|
|
27
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
28
|
{
|
|
44
29
|
"name": "DropdownMenu",
|
|
45
30
|
"kind": "component",
|
package/docs/context-menu.md
CHANGED
|
@@ -2,13 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
Import `ContextMenu`, `ContextMenuProps`, and the existing `DropdownMenuItem`,
|
|
4
4
|
`DropdownMenuRadioGroup`, `DropdownMenuRadioItem`, and `DropdownMenuLabel` from
|
|
5
|
-
`@gridui/dropdown-menu`. Load
|
|
5
|
+
`@gridui/dropdown-menu`. Load these styles in order:
|
|
6
|
+
|
|
7
|
+
```css
|
|
8
|
+
@import "@gridui/theme/styles.css";
|
|
9
|
+
@import "@gridui/overlay/styles.css";
|
|
10
|
+
@import "@gridui/dropdown-menu/styles.css";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Overlay supplies the shared menu surface, option rows, labels, and indicators.
|
|
6
14
|
|
|
7
15
|
Render `ContextMenu` only while open. Pass viewport `x` / `y` coordinates (for
|
|
8
16
|
example, `clientX` / `clientY`), an accessible `label`, menu children, and `onClose`
|
|
9
17
|
to clear the owner's open state. The owner decides which pointer or keyboard
|
|
10
18
|
interaction opens the menu and what each action does. For keyboard opening,
|
|
11
|
-
anchor to the invoking element's bounding rectangle.
|
|
19
|
+
anchor to the invoking element's bounding rectangle. Pass `dir="rtl"` for a
|
|
20
|
+
right-to-left menu; direction is forwarded to the menu root for positioning,
|
|
21
|
+
row layout, and keyboard behavior.
|
|
12
22
|
|
|
13
23
|
The menu reuses dropdown keyboard navigation, disabled-item semantics, collision
|
|
14
24
|
handling, and item selection. It is nonmodal, closes on Escape, Tab, outside
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridui/dropdown-menu",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "GridUI React dropdown menu",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"react-dom": "^19.2.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@gridui/overlay": "^
|
|
31
|
-
"@gridui/style-utils": "^
|
|
30
|
+
"@gridui/overlay": "^2.0.0",
|
|
31
|
+
"@gridui/style-utils": "^3.0.0",
|
|
32
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": "
|
|
39
|
+
"@gridui/button": "4.0.0",
|
|
40
40
|
"@jest/globals": "30.5.2",
|
|
41
41
|
"@storybook/react-vite": "10.6.6",
|
|
42
42
|
"@types/jest": "30.0.0",
|