@wow-two-beta/ui 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-3KGYKBW6.js +697 -0
- package/dist/chunk-3KGYKBW6.js.map +1 -0
- package/dist/{chunk-7SGLT2LM.js → chunk-55Y2JOBV.js} +3 -3
- package/dist/{chunk-7SGLT2LM.js.map → chunk-55Y2JOBV.js.map} +1 -1
- package/dist/{chunk-SL5YJADS.js → chunk-CZ6FQILQ.js} +30 -5
- package/dist/chunk-CZ6FQILQ.js.map +1 -0
- package/dist/{chunk-X2LTOZ7F.js → chunk-SBVWECJP.js} +921 -6
- package/dist/chunk-SBVWECJP.js.map +1 -0
- package/dist/display/index.js +2 -3
- package/dist/forms/combobox/Combobox.d.ts +55 -0
- package/dist/forms/combobox/Combobox.d.ts.map +1 -0
- package/dist/forms/combobox/index.d.ts +2 -0
- package/dist/forms/combobox/index.d.ts.map +1 -0
- package/dist/forms/index.d.ts +4 -0
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +3 -2
- package/dist/forms/listbox/Listbox.d.ts +44 -0
- package/dist/forms/listbox/Listbox.d.ts.map +1 -0
- package/dist/forms/listbox/Listbox.variants.d.ts +58 -0
- package/dist/forms/listbox/Listbox.variants.d.ts.map +1 -0
- package/dist/forms/listbox/index.d.ts +2 -0
- package/dist/forms/listbox/index.d.ts.map +1 -0
- package/dist/forms/multiSelect/MultiSelect.d.ts +47 -0
- package/dist/forms/multiSelect/MultiSelect.d.ts.map +1 -0
- package/dist/forms/multiSelect/index.d.ts +2 -0
- package/dist/forms/multiSelect/index.d.ts.map +1 -0
- package/dist/forms/select/Select.d.ts +55 -0
- package/dist/forms/select/Select.d.ts.map +1 -0
- package/dist/forms/select/Select.variants.d.ts +74 -0
- package/dist/forms/select/Select.variants.d.ts.map +1 -0
- package/dist/forms/select/index.d.ts +2 -0
- package/dist/forms/select/index.d.ts.map +1 -0
- package/dist/index.js +4 -5
- package/dist/nav/contextMenu/ContextMenu.d.ts +31 -0
- package/dist/nav/contextMenu/ContextMenu.d.ts.map +1 -0
- package/dist/nav/contextMenu/index.d.ts +2 -0
- package/dist/nav/contextMenu/index.d.ts.map +1 -0
- package/dist/nav/dropdownMenu/DropdownMenu.d.ts +34 -0
- package/dist/nav/dropdownMenu/DropdownMenu.d.ts.map +1 -0
- package/dist/nav/dropdownMenu/index.d.ts +2 -0
- package/dist/nav/dropdownMenu/index.d.ts.map +1 -0
- package/dist/nav/index.d.ts +4 -0
- package/dist/nav/index.d.ts.map +1 -1
- package/dist/nav/index.js +3 -3
- package/dist/nav/menu/Menu.d.ts +38 -0
- package/dist/nav/menu/Menu.d.ts.map +1 -0
- package/dist/nav/menu/Menu.variants.d.ts +50 -0
- package/dist/nav/menu/Menu.variants.d.ts.map +1 -0
- package/dist/nav/menu/index.d.ts +3 -0
- package/dist/nav/menu/index.d.ts.map +1 -0
- package/dist/nav/menubar/Menubar.d.ts +40 -0
- package/dist/nav/menubar/Menubar.d.ts.map +1 -0
- package/dist/nav/menubar/Menubar.variants.d.ts +5 -0
- package/dist/nav/menubar/Menubar.variants.d.ts.map +1 -0
- package/dist/nav/menubar/index.d.ts +2 -0
- package/dist/nav/menubar/index.d.ts.map +1 -0
- package/dist/primitives/index.js +1 -2
- package/package.json +1 -1
- package/dist/chunk-L32PXXQL.js +0 -126
- package/dist/chunk-L32PXXQL.js.map +0 -1
- package/dist/chunk-SL5YJADS.js.map +0 -1
- package/dist/chunk-WEM32VIJ.js +0 -34
- package/dist/chunk-WEM32VIJ.js.map +0 -1
- package/dist/chunk-X2LTOZ7F.js.map +0 -1
|
@@ -0,0 +1,697 @@
|
|
|
1
|
+
import { Portal, AnchoredPositioner, DismissableLayer } from './chunk-CZ6FQILQ.js';
|
|
2
|
+
import { useControlled } from './chunk-4P2TFUVW.js';
|
|
3
|
+
import { Slot } from './chunk-33IOXQYO.js';
|
|
4
|
+
import { dataAttr, tv } from './chunk-BMBIZLO4.js';
|
|
5
|
+
import { Icon } from './chunk-TDX22OWF.js';
|
|
6
|
+
import { composeRefs } from './chunk-DN7WBRIV.js';
|
|
7
|
+
import { cn } from './chunk-KZ4VFY2T.js';
|
|
8
|
+
import { forwardRef, Fragment, createContext, useId, useRef, useEffect, useCallback, useMemo, useContext, useState } from 'react';
|
|
9
|
+
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
10
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
11
|
+
import { FocusScope } from '@radix-ui/react-focus-scope';
|
|
12
|
+
|
|
13
|
+
var Breadcrumb = forwardRef(
|
|
14
|
+
({ items, separator, className, ...props }, ref) => {
|
|
15
|
+
const sep = separator ?? /* @__PURE__ */ jsx(Icon, { icon: ChevronRight, size: 14 });
|
|
16
|
+
return /* @__PURE__ */ jsx("nav", { ref, "aria-label": "Breadcrumb", className: cn("text-sm", className), ...props, children: /* @__PURE__ */ jsx("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, i) => {
|
|
17
|
+
const isLast = i === items.length - 1;
|
|
18
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19
|
+
/* @__PURE__ */ jsx("li", { children: item.href && !isLast ? /* @__PURE__ */ jsx(
|
|
20
|
+
"a",
|
|
21
|
+
{
|
|
22
|
+
href: item.href,
|
|
23
|
+
className: "text-muted-foreground hover:text-foreground hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-sm",
|
|
24
|
+
children: item.label
|
|
25
|
+
}
|
|
26
|
+
) : /* @__PURE__ */ jsx("span", { "aria-current": isLast ? "page" : void 0, className: "text-foreground", children: item.label }) }),
|
|
27
|
+
!isLast && /* @__PURE__ */ jsx("li", { "aria-hidden": "true", className: "text-subtle-foreground", children: sep })
|
|
28
|
+
] }, i);
|
|
29
|
+
}) }) });
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
Breadcrumb.displayName = "Breadcrumb";
|
|
33
|
+
function range(start, end) {
|
|
34
|
+
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
35
|
+
}
|
|
36
|
+
function buildPages(total, page, siblings) {
|
|
37
|
+
if (total <= 1) return [1];
|
|
38
|
+
const left = Math.max(2, page - siblings);
|
|
39
|
+
const right = Math.min(total - 1, page + siblings);
|
|
40
|
+
const pages = [1];
|
|
41
|
+
if (left > 2) pages.push("ellipsis");
|
|
42
|
+
pages.push(...range(left, right));
|
|
43
|
+
if (right < total - 1) pages.push("ellipsis");
|
|
44
|
+
if (total > 1) pages.push(total);
|
|
45
|
+
return pages;
|
|
46
|
+
}
|
|
47
|
+
var Pagination = forwardRef(
|
|
48
|
+
({ total, page, onPageChange, siblings = 1, className, ...props }, ref) => {
|
|
49
|
+
const pages = buildPages(total, page, siblings);
|
|
50
|
+
const go = (p) => onPageChange(Math.min(total, Math.max(1, p)));
|
|
51
|
+
const baseBtn = "inline-flex h-8 min-w-8 items-center justify-center rounded-md border border-transparent px-2 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50";
|
|
52
|
+
return /* @__PURE__ */ jsxs("nav", { ref, "aria-label": "Pagination", className: cn("inline-flex items-center gap-1", className), ...props, children: [
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
"button",
|
|
55
|
+
{
|
|
56
|
+
type: "button",
|
|
57
|
+
"aria-label": "Previous page",
|
|
58
|
+
disabled: page <= 1,
|
|
59
|
+
onClick: () => go(page - 1),
|
|
60
|
+
className: cn(baseBtn, "hover:bg-muted"),
|
|
61
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: ChevronLeft, size: 16 })
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
pages.map(
|
|
65
|
+
(p, i) => p === "ellipsis" ? /* @__PURE__ */ jsx("span", { className: "px-1 text-muted-foreground", children: "\u2026" }, `e-${i}`) : /* @__PURE__ */ jsx(
|
|
66
|
+
"button",
|
|
67
|
+
{
|
|
68
|
+
type: "button",
|
|
69
|
+
"aria-current": p === page ? "page" : void 0,
|
|
70
|
+
onClick: () => go(p),
|
|
71
|
+
className: cn(
|
|
72
|
+
baseBtn,
|
|
73
|
+
p === page ? "border-primary bg-primary text-primary-foreground" : "hover:bg-muted"
|
|
74
|
+
),
|
|
75
|
+
children: p
|
|
76
|
+
},
|
|
77
|
+
p
|
|
78
|
+
)
|
|
79
|
+
),
|
|
80
|
+
/* @__PURE__ */ jsx(
|
|
81
|
+
"button",
|
|
82
|
+
{
|
|
83
|
+
type: "button",
|
|
84
|
+
"aria-label": "Next page",
|
|
85
|
+
disabled: page >= total,
|
|
86
|
+
onClick: () => go(page + 1),
|
|
87
|
+
className: cn(baseBtn, "hover:bg-muted"),
|
|
88
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: ChevronRight, size: 16 })
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
] });
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
Pagination.displayName = "Pagination";
|
|
95
|
+
var SIZE = {
|
|
96
|
+
sm: "h-8 px-2 text-sm gap-2",
|
|
97
|
+
md: "h-9 px-2.5 text-sm gap-2.5",
|
|
98
|
+
lg: "h-11 px-3 text-base gap-3"
|
|
99
|
+
};
|
|
100
|
+
var NavItem = forwardRef(
|
|
101
|
+
({ asChild, icon, children, trailing, isActive, size = "md", className, ...props }, ref) => {
|
|
102
|
+
const Comp = asChild ? Slot : "a";
|
|
103
|
+
return /* @__PURE__ */ jsxs(
|
|
104
|
+
Comp,
|
|
105
|
+
{
|
|
106
|
+
ref,
|
|
107
|
+
"aria-current": isActive ? "page" : void 0,
|
|
108
|
+
"data-active": dataAttr(isActive),
|
|
109
|
+
className: cn(
|
|
110
|
+
"group inline-flex w-full items-center rounded-md font-medium text-foreground transition-colors",
|
|
111
|
+
"hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
112
|
+
"data-[active]:bg-primary-soft data-[active]:text-primary-soft-foreground",
|
|
113
|
+
SIZE[size],
|
|
114
|
+
className
|
|
115
|
+
),
|
|
116
|
+
...props,
|
|
117
|
+
children: [
|
|
118
|
+
icon && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground group-data-[active]:text-current", children: icon }),
|
|
119
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-left", children }),
|
|
120
|
+
trailing && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: trailing })
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
NavItem.displayName = "NavItem";
|
|
127
|
+
|
|
128
|
+
// src/nav/menu/Menu.variants.ts
|
|
129
|
+
var menuVariants = tv({
|
|
130
|
+
base: "flex min-w-[8rem] flex-col gap-0.5 rounded-md border border-border bg-popover p-1 text-sm text-popover-foreground shadow-md outline-none"
|
|
131
|
+
});
|
|
132
|
+
var menuItemVariants = tv({
|
|
133
|
+
base: "relative flex w-full cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none transition-colors focus:bg-muted focus:text-foreground hover:bg-muted hover:text-foreground",
|
|
134
|
+
variants: {
|
|
135
|
+
state: {
|
|
136
|
+
default: "text-popover-foreground",
|
|
137
|
+
destructive: "text-destructive focus:bg-destructive-soft hover:bg-destructive-soft",
|
|
138
|
+
disabled: "pointer-events-none opacity-50"
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
defaultVariants: { state: "default" }
|
|
142
|
+
});
|
|
143
|
+
var menuLabelVariants = tv({
|
|
144
|
+
base: "px-2 py-1.5 text-xs font-semibold text-muted-foreground"
|
|
145
|
+
});
|
|
146
|
+
var menuSeparatorVariants = tv({
|
|
147
|
+
base: "-mx-1 my-1 h-px bg-border"
|
|
148
|
+
});
|
|
149
|
+
var MenuContext = createContext(null);
|
|
150
|
+
function useMenuContext() {
|
|
151
|
+
const ctx = useContext(MenuContext);
|
|
152
|
+
if (!ctx) throw new Error("Menu.Item / Group / Label / Separator must be used inside <Menu>");
|
|
153
|
+
return ctx;
|
|
154
|
+
}
|
|
155
|
+
function Menu({
|
|
156
|
+
open,
|
|
157
|
+
anchor,
|
|
158
|
+
onClose,
|
|
159
|
+
placement = "bottom-start",
|
|
160
|
+
offset = 6,
|
|
161
|
+
"aria-label": ariaLabel,
|
|
162
|
+
className,
|
|
163
|
+
children
|
|
164
|
+
}) {
|
|
165
|
+
const itemsRef = useRef([]);
|
|
166
|
+
const registerItem = useCallback((entry) => {
|
|
167
|
+
const idx = itemsRef.current.findIndex((i) => i.id === entry.id);
|
|
168
|
+
if (idx >= 0) itemsRef.current[idx] = entry;
|
|
169
|
+
else itemsRef.current.push(entry);
|
|
170
|
+
}, []);
|
|
171
|
+
const unregisterItem = useCallback((id) => {
|
|
172
|
+
itemsRef.current = itemsRef.current.filter((i) => i.id !== id);
|
|
173
|
+
}, []);
|
|
174
|
+
const ctx = useMemo(
|
|
175
|
+
() => ({ registerItem, unregisterItem, itemsRef, onClose }),
|
|
176
|
+
[registerItem, unregisterItem, onClose]
|
|
177
|
+
);
|
|
178
|
+
if (!open) return null;
|
|
179
|
+
return /* @__PURE__ */ jsx(MenuContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(AnchoredPositioner, { anchor, placement, offset, children: /* @__PURE__ */ jsx(FocusScope, { asChild: true, trapped: true, loop: true, children: /* @__PURE__ */ jsx(
|
|
180
|
+
DismissableLayer,
|
|
181
|
+
{
|
|
182
|
+
onEscape: onClose,
|
|
183
|
+
onOutsidePointerDown: (e) => {
|
|
184
|
+
if (anchor?.contains(e.target)) return;
|
|
185
|
+
onClose();
|
|
186
|
+
},
|
|
187
|
+
children: /* @__PURE__ */ jsx(
|
|
188
|
+
"div",
|
|
189
|
+
{
|
|
190
|
+
role: "menu",
|
|
191
|
+
"aria-label": ariaLabel,
|
|
192
|
+
className: cn(menuVariants(), className),
|
|
193
|
+
onKeyDown: (e) => {
|
|
194
|
+
if (e.key === "Tab") {
|
|
195
|
+
e.preventDefault();
|
|
196
|
+
onClose();
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
children
|
|
200
|
+
}
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
) }) }) }) });
|
|
204
|
+
}
|
|
205
|
+
var MenuItem = forwardRef(function MenuItem2({ onSelect, disabled = false, state, className, onClick, onKeyDown, children, ...rest }, forwardedRef) {
|
|
206
|
+
const ctx = useMenuContext();
|
|
207
|
+
const id = useId();
|
|
208
|
+
const ref = useRef(null);
|
|
209
|
+
useEffect(() => {
|
|
210
|
+
ctx.registerItem({ id, ref: ref.current, disabled });
|
|
211
|
+
return () => ctx.unregisterItem(id);
|
|
212
|
+
}, [ctx, id, disabled]);
|
|
213
|
+
const moveFocus = useCallback(
|
|
214
|
+
(direction, jump = 1) => {
|
|
215
|
+
const list = ctx.itemsRef.current.filter((i) => !i.disabled);
|
|
216
|
+
if (list.length === 0) return;
|
|
217
|
+
const idx = list.findIndex((i) => i.id === id);
|
|
218
|
+
let nextIdx = idx + direction * jump;
|
|
219
|
+
if (idx === -1) nextIdx = direction === 1 ? 0 : list.length - 1;
|
|
220
|
+
if (nextIdx < 0) nextIdx = list.length - 1;
|
|
221
|
+
if (nextIdx >= list.length) nextIdx = 0;
|
|
222
|
+
list[nextIdx]?.ref?.focus();
|
|
223
|
+
},
|
|
224
|
+
[ctx, id]
|
|
225
|
+
);
|
|
226
|
+
const handleKeyDown = (e) => {
|
|
227
|
+
onKeyDown?.(e);
|
|
228
|
+
if (e.defaultPrevented || disabled) return;
|
|
229
|
+
switch (e.key) {
|
|
230
|
+
case "ArrowDown":
|
|
231
|
+
e.preventDefault();
|
|
232
|
+
moveFocus(1);
|
|
233
|
+
break;
|
|
234
|
+
case "ArrowUp":
|
|
235
|
+
e.preventDefault();
|
|
236
|
+
moveFocus(-1);
|
|
237
|
+
break;
|
|
238
|
+
case "Home":
|
|
239
|
+
e.preventDefault();
|
|
240
|
+
moveFocus(-1, ctx.itemsRef.current.length);
|
|
241
|
+
break;
|
|
242
|
+
case "End":
|
|
243
|
+
e.preventDefault();
|
|
244
|
+
moveFocus(1, ctx.itemsRef.current.length);
|
|
245
|
+
break;
|
|
246
|
+
case "Enter":
|
|
247
|
+
case " ":
|
|
248
|
+
e.preventDefault();
|
|
249
|
+
onSelect?.();
|
|
250
|
+
ctx.onClose();
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
const itemState = state ?? (disabled ? "disabled" : "default");
|
|
255
|
+
return /* @__PURE__ */ jsx(
|
|
256
|
+
"button",
|
|
257
|
+
{
|
|
258
|
+
ref: composeRefs(forwardedRef, ref),
|
|
259
|
+
type: "button",
|
|
260
|
+
role: "menuitem",
|
|
261
|
+
disabled,
|
|
262
|
+
"aria-disabled": disabled || void 0,
|
|
263
|
+
"data-disabled": disabled ? "" : void 0,
|
|
264
|
+
onClick: (e) => {
|
|
265
|
+
onClick?.(e);
|
|
266
|
+
if (e.defaultPrevented || disabled) return;
|
|
267
|
+
onSelect?.();
|
|
268
|
+
ctx.onClose();
|
|
269
|
+
},
|
|
270
|
+
onKeyDown: handleKeyDown,
|
|
271
|
+
className: cn(menuItemVariants({ state: itemState }), className),
|
|
272
|
+
...rest,
|
|
273
|
+
children
|
|
274
|
+
}
|
|
275
|
+
);
|
|
276
|
+
});
|
|
277
|
+
function MenuGroup({ label, children, className, ...rest }) {
|
|
278
|
+
const labelId = useId();
|
|
279
|
+
return /* @__PURE__ */ jsxs(
|
|
280
|
+
"div",
|
|
281
|
+
{
|
|
282
|
+
role: "group",
|
|
283
|
+
"aria-labelledby": label ? labelId : void 0,
|
|
284
|
+
className,
|
|
285
|
+
...rest,
|
|
286
|
+
children: [
|
|
287
|
+
label && /* @__PURE__ */ jsx("div", { id: labelId, className: menuLabelVariants(), children: label }),
|
|
288
|
+
children
|
|
289
|
+
]
|
|
290
|
+
}
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
function MenuLabel({
|
|
294
|
+
children,
|
|
295
|
+
className,
|
|
296
|
+
...rest
|
|
297
|
+
}) {
|
|
298
|
+
return /* @__PURE__ */ jsx("div", { className: cn(menuLabelVariants(), className), ...rest, children });
|
|
299
|
+
}
|
|
300
|
+
function MenuSeparator(props) {
|
|
301
|
+
return /* @__PURE__ */ jsx("div", { role: "separator", className: menuSeparatorVariants(), ...props });
|
|
302
|
+
}
|
|
303
|
+
Menu.Item = MenuItem;
|
|
304
|
+
Menu.Group = MenuGroup;
|
|
305
|
+
Menu.Label = MenuLabel;
|
|
306
|
+
Menu.Separator = MenuSeparator;
|
|
307
|
+
var DropdownMenuContext = createContext(null);
|
|
308
|
+
function useDropdownMenuContext() {
|
|
309
|
+
const ctx = useContext(DropdownMenuContext);
|
|
310
|
+
if (!ctx) throw new Error("DropdownMenu.* must be used inside <DropdownMenu>");
|
|
311
|
+
return ctx;
|
|
312
|
+
}
|
|
313
|
+
function DropdownMenu({
|
|
314
|
+
open: openProp,
|
|
315
|
+
defaultOpen = false,
|
|
316
|
+
onOpenChange,
|
|
317
|
+
placement = "bottom-start",
|
|
318
|
+
offset = 6,
|
|
319
|
+
children
|
|
320
|
+
}) {
|
|
321
|
+
const [open, setOpen] = useControlled({
|
|
322
|
+
controlled: openProp,
|
|
323
|
+
default: defaultOpen,
|
|
324
|
+
onChange: onOpenChange
|
|
325
|
+
});
|
|
326
|
+
const triggerRef = useRef(null);
|
|
327
|
+
const ctx = useMemo(
|
|
328
|
+
() => ({ open, setOpen, triggerRef, placement, offset }),
|
|
329
|
+
[open, setOpen, placement, offset]
|
|
330
|
+
);
|
|
331
|
+
return /* @__PURE__ */ jsx(DropdownMenuContext.Provider, { value: ctx, children });
|
|
332
|
+
}
|
|
333
|
+
var DropdownMenuTrigger = forwardRef(
|
|
334
|
+
function DropdownMenuTrigger2({ asChild, onClick, onKeyDown, children, ...rest }, forwardedRef) {
|
|
335
|
+
const ctx = useDropdownMenuContext();
|
|
336
|
+
const Component = asChild ? Slot : "button";
|
|
337
|
+
const handleClick = useCallback(
|
|
338
|
+
(e) => {
|
|
339
|
+
onClick?.(e);
|
|
340
|
+
if (e.defaultPrevented) return;
|
|
341
|
+
ctx.setOpen(!ctx.open);
|
|
342
|
+
},
|
|
343
|
+
[ctx, onClick]
|
|
344
|
+
);
|
|
345
|
+
const handleKeyDown = useCallback(
|
|
346
|
+
(e) => {
|
|
347
|
+
onKeyDown?.(e);
|
|
348
|
+
if (e.defaultPrevented) return;
|
|
349
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "Enter" || e.key === " ") {
|
|
350
|
+
e.preventDefault();
|
|
351
|
+
ctx.setOpen(true);
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
[ctx, onKeyDown]
|
|
355
|
+
);
|
|
356
|
+
return /* @__PURE__ */ jsx(
|
|
357
|
+
Component,
|
|
358
|
+
{
|
|
359
|
+
ref: composeRefs(forwardedRef, ctx.triggerRef),
|
|
360
|
+
type: "button",
|
|
361
|
+
"aria-haspopup": "menu",
|
|
362
|
+
"aria-expanded": ctx.open,
|
|
363
|
+
"data-state": ctx.open ? "open" : "closed",
|
|
364
|
+
onClick: handleClick,
|
|
365
|
+
onKeyDown: handleKeyDown,
|
|
366
|
+
...rest,
|
|
367
|
+
children
|
|
368
|
+
}
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
);
|
|
372
|
+
function DropdownMenuContent({
|
|
373
|
+
className,
|
|
374
|
+
"aria-label": ariaLabel,
|
|
375
|
+
children
|
|
376
|
+
}) {
|
|
377
|
+
const ctx = useDropdownMenuContext();
|
|
378
|
+
return /* @__PURE__ */ jsx(
|
|
379
|
+
Menu,
|
|
380
|
+
{
|
|
381
|
+
open: ctx.open,
|
|
382
|
+
anchor: ctx.triggerRef.current,
|
|
383
|
+
onClose: () => {
|
|
384
|
+
ctx.setOpen(false);
|
|
385
|
+
requestAnimationFrame(() => ctx.triggerRef.current?.focus());
|
|
386
|
+
},
|
|
387
|
+
placement: ctx.placement,
|
|
388
|
+
offset: ctx.offset,
|
|
389
|
+
"aria-label": ariaLabel,
|
|
390
|
+
className,
|
|
391
|
+
children
|
|
392
|
+
}
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
DropdownMenu.Trigger = DropdownMenuTrigger;
|
|
396
|
+
DropdownMenu.Content = DropdownMenuContent;
|
|
397
|
+
DropdownMenu.Item = MenuItem;
|
|
398
|
+
DropdownMenu.Group = MenuGroup;
|
|
399
|
+
DropdownMenu.Label = MenuLabel;
|
|
400
|
+
DropdownMenu.Separator = MenuSeparator;
|
|
401
|
+
var ContextMenuContext = createContext(null);
|
|
402
|
+
function useContextMenuContext() {
|
|
403
|
+
const ctx = useContext(ContextMenuContext);
|
|
404
|
+
if (!ctx) throw new Error("ContextMenu.* must be used inside <ContextMenu>");
|
|
405
|
+
return ctx;
|
|
406
|
+
}
|
|
407
|
+
function makeVirtualAnchor(x, y) {
|
|
408
|
+
const el = document.createElement("div");
|
|
409
|
+
el.style.position = "fixed";
|
|
410
|
+
el.style.left = `${x}px`;
|
|
411
|
+
el.style.top = `${y}px`;
|
|
412
|
+
el.style.width = "0px";
|
|
413
|
+
el.style.height = "0px";
|
|
414
|
+
el.style.pointerEvents = "none";
|
|
415
|
+
document.body.appendChild(el);
|
|
416
|
+
return el;
|
|
417
|
+
}
|
|
418
|
+
function ContextMenu({ children }) {
|
|
419
|
+
const [open, setOpen] = useState(false);
|
|
420
|
+
const [anchor, setAnchorState] = useState(null);
|
|
421
|
+
const triggerRef = useRef(null);
|
|
422
|
+
const setAnchor = useCallback((el) => {
|
|
423
|
+
setAnchorState((prev) => {
|
|
424
|
+
if (prev && prev.parentNode === document.body) prev.remove();
|
|
425
|
+
return el;
|
|
426
|
+
});
|
|
427
|
+
}, []);
|
|
428
|
+
const handleSetOpen = useCallback(
|
|
429
|
+
(next) => {
|
|
430
|
+
setOpen(next);
|
|
431
|
+
if (!next) setAnchor(null);
|
|
432
|
+
},
|
|
433
|
+
[setAnchor]
|
|
434
|
+
);
|
|
435
|
+
const ctx = useMemo(
|
|
436
|
+
() => ({ open, setOpen: handleSetOpen, anchor, setAnchor, triggerRef }),
|
|
437
|
+
[open, handleSetOpen, anchor, setAnchor]
|
|
438
|
+
);
|
|
439
|
+
return /* @__PURE__ */ jsx(ContextMenuContext.Provider, { value: ctx, children });
|
|
440
|
+
}
|
|
441
|
+
var ContextMenuTrigger = forwardRef(
|
|
442
|
+
function ContextMenuTrigger2({ asChild, disabled, onContextMenu, onPointerDown, onPointerCancel, onPointerUp, children, ...rest }, forwardedRef) {
|
|
443
|
+
const ctx = useContextMenuContext();
|
|
444
|
+
const longPressTimer = useRef(null);
|
|
445
|
+
const Component = asChild ? Slot : "div";
|
|
446
|
+
const handleContextMenu = useCallback(
|
|
447
|
+
(e) => {
|
|
448
|
+
onContextMenu?.(e);
|
|
449
|
+
if (e.defaultPrevented || disabled) return;
|
|
450
|
+
e.preventDefault();
|
|
451
|
+
ctx.setAnchor(makeVirtualAnchor(e.clientX, e.clientY));
|
|
452
|
+
ctx.setOpen(true);
|
|
453
|
+
},
|
|
454
|
+
[ctx, disabled, onContextMenu]
|
|
455
|
+
);
|
|
456
|
+
const clearLongPress = useCallback(() => {
|
|
457
|
+
if (longPressTimer.current) clearTimeout(longPressTimer.current);
|
|
458
|
+
longPressTimer.current = null;
|
|
459
|
+
}, []);
|
|
460
|
+
return /* @__PURE__ */ jsx(
|
|
461
|
+
Component,
|
|
462
|
+
{
|
|
463
|
+
ref: composeRefs(forwardedRef, ctx.triggerRef),
|
|
464
|
+
onContextMenu: handleContextMenu,
|
|
465
|
+
onPointerDown: (e) => {
|
|
466
|
+
onPointerDown?.(e);
|
|
467
|
+
if (e.defaultPrevented || disabled || e.pointerType !== "touch") return;
|
|
468
|
+
const x = e.clientX;
|
|
469
|
+
const y = e.clientY;
|
|
470
|
+
longPressTimer.current = setTimeout(() => {
|
|
471
|
+
ctx.setAnchor(makeVirtualAnchor(x, y));
|
|
472
|
+
ctx.setOpen(true);
|
|
473
|
+
}, 600);
|
|
474
|
+
},
|
|
475
|
+
onPointerUp: (e) => {
|
|
476
|
+
onPointerUp?.(e);
|
|
477
|
+
clearLongPress();
|
|
478
|
+
},
|
|
479
|
+
onPointerCancel: (e) => {
|
|
480
|
+
onPointerCancel?.(e);
|
|
481
|
+
clearLongPress();
|
|
482
|
+
},
|
|
483
|
+
...rest,
|
|
484
|
+
children
|
|
485
|
+
}
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
);
|
|
489
|
+
function ContextMenuContent({
|
|
490
|
+
className,
|
|
491
|
+
placement = "bottom-start",
|
|
492
|
+
offset = 2,
|
|
493
|
+
"aria-label": ariaLabel,
|
|
494
|
+
children
|
|
495
|
+
}) {
|
|
496
|
+
const ctx = useContextMenuContext();
|
|
497
|
+
return /* @__PURE__ */ jsx(
|
|
498
|
+
Menu,
|
|
499
|
+
{
|
|
500
|
+
open: ctx.open,
|
|
501
|
+
anchor: ctx.anchor,
|
|
502
|
+
onClose: () => ctx.setOpen(false),
|
|
503
|
+
placement,
|
|
504
|
+
offset,
|
|
505
|
+
"aria-label": ariaLabel,
|
|
506
|
+
className,
|
|
507
|
+
children
|
|
508
|
+
}
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
ContextMenu.Trigger = ContextMenuTrigger;
|
|
512
|
+
ContextMenu.Content = ContextMenuContent;
|
|
513
|
+
ContextMenu.Item = MenuItem;
|
|
514
|
+
ContextMenu.Group = MenuGroup;
|
|
515
|
+
ContextMenu.Label = MenuLabel;
|
|
516
|
+
ContextMenu.Separator = MenuSeparator;
|
|
517
|
+
|
|
518
|
+
// src/nav/menubar/Menubar.variants.ts
|
|
519
|
+
var menubarVariants = tv({
|
|
520
|
+
base: "flex items-center gap-1 rounded-md border border-border bg-background p-1"
|
|
521
|
+
});
|
|
522
|
+
var menubarTriggerVariants = tv({
|
|
523
|
+
base: "inline-flex select-none items-center rounded-sm px-3 py-1 text-sm font-medium text-foreground outline-none transition-colors hover:bg-muted focus-visible:bg-muted data-[state=open]:bg-muted"
|
|
524
|
+
});
|
|
525
|
+
var MenubarContext = createContext(null);
|
|
526
|
+
function useMenubarContext() {
|
|
527
|
+
const ctx = useContext(MenubarContext);
|
|
528
|
+
if (!ctx) throw new Error("Menubar.* must be used inside <Menubar>");
|
|
529
|
+
return ctx;
|
|
530
|
+
}
|
|
531
|
+
var MenubarMenuContext = createContext(null);
|
|
532
|
+
function useMenubarMenuContext() {
|
|
533
|
+
const ctx = useContext(MenubarMenuContext);
|
|
534
|
+
if (!ctx) throw new Error("Menubar.Trigger / Content must be used inside <Menubar.Menu>");
|
|
535
|
+
return ctx;
|
|
536
|
+
}
|
|
537
|
+
var Menubar = forwardRef(function Menubar2({ value, defaultValue = null, onValueChange, className, children, ...rest }, ref) {
|
|
538
|
+
const [activeId, setActiveId] = useControlled({
|
|
539
|
+
controlled: value,
|
|
540
|
+
default: defaultValue,
|
|
541
|
+
onChange: onValueChange
|
|
542
|
+
});
|
|
543
|
+
const triggersRef = useRef([]);
|
|
544
|
+
const registerTrigger = useCallback((id, triggerRef) => {
|
|
545
|
+
const idx = triggersRef.current.findIndex((t) => t.id === id);
|
|
546
|
+
if (idx >= 0) triggersRef.current[idx] = { id, ref: triggerRef };
|
|
547
|
+
else triggersRef.current.push({ id, ref: triggerRef });
|
|
548
|
+
}, []);
|
|
549
|
+
const unregisterTrigger = useCallback((id) => {
|
|
550
|
+
triggersRef.current = triggersRef.current.filter((t) => t.id !== id);
|
|
551
|
+
}, []);
|
|
552
|
+
const ctx = useMemo(
|
|
553
|
+
() => ({ activeId, setActiveId, registerTrigger, unregisterTrigger, triggersRef }),
|
|
554
|
+
[activeId, setActiveId, registerTrigger, unregisterTrigger]
|
|
555
|
+
);
|
|
556
|
+
return /* @__PURE__ */ jsx(MenubarContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
|
|
557
|
+
"div",
|
|
558
|
+
{
|
|
559
|
+
ref,
|
|
560
|
+
role: "menubar",
|
|
561
|
+
className: cn(menubarVariants(), className),
|
|
562
|
+
...rest,
|
|
563
|
+
children
|
|
564
|
+
}
|
|
565
|
+
) });
|
|
566
|
+
});
|
|
567
|
+
function MenubarMenu({ value, children }) {
|
|
568
|
+
const ctx = useMenubarContext();
|
|
569
|
+
const triggerRef = useRef(null);
|
|
570
|
+
const open = ctx.activeId === value;
|
|
571
|
+
const setOpen = useCallback(
|
|
572
|
+
(next) => {
|
|
573
|
+
ctx.setActiveId(next ? value : null);
|
|
574
|
+
},
|
|
575
|
+
[ctx, value]
|
|
576
|
+
);
|
|
577
|
+
const menuCtx = useMemo(
|
|
578
|
+
() => ({ id: value, open, setOpen, triggerRef }),
|
|
579
|
+
[value, open, setOpen]
|
|
580
|
+
);
|
|
581
|
+
return /* @__PURE__ */ jsx(MenubarMenuContext.Provider, { value: menuCtx, children });
|
|
582
|
+
}
|
|
583
|
+
var MenubarTrigger = forwardRef(
|
|
584
|
+
function MenubarTrigger2({ className, onClick, onKeyDown, onPointerEnter, children, ...rest }, forwardedRef) {
|
|
585
|
+
const bar = useMenubarContext();
|
|
586
|
+
const menu = useMenubarMenuContext();
|
|
587
|
+
useEffect(() => {
|
|
588
|
+
bar.registerTrigger(menu.id, menu.triggerRef.current);
|
|
589
|
+
return () => bar.unregisterTrigger(menu.id);
|
|
590
|
+
}, [bar, menu.id, menu.triggerRef]);
|
|
591
|
+
const moveAcross = useCallback(
|
|
592
|
+
(direction) => {
|
|
593
|
+
const list = bar.triggersRef.current;
|
|
594
|
+
const idx = list.findIndex((t) => t.id === menu.id);
|
|
595
|
+
if (idx === -1) return;
|
|
596
|
+
let nextIdx = idx + direction;
|
|
597
|
+
if (nextIdx < 0) nextIdx = list.length - 1;
|
|
598
|
+
if (nextIdx >= list.length) nextIdx = 0;
|
|
599
|
+
const next = list[nextIdx];
|
|
600
|
+
next?.ref?.focus();
|
|
601
|
+
if (bar.activeId !== null && next) bar.setActiveId(next.id);
|
|
602
|
+
},
|
|
603
|
+
[bar, menu.id]
|
|
604
|
+
);
|
|
605
|
+
return /* @__PURE__ */ jsx(
|
|
606
|
+
"button",
|
|
607
|
+
{
|
|
608
|
+
ref: composeRefs(forwardedRef, menu.triggerRef),
|
|
609
|
+
type: "button",
|
|
610
|
+
role: "menuitem",
|
|
611
|
+
"aria-haspopup": "menu",
|
|
612
|
+
"aria-expanded": menu.open,
|
|
613
|
+
"data-state": menu.open ? "open" : "closed",
|
|
614
|
+
onClick: (e) => {
|
|
615
|
+
onClick?.(e);
|
|
616
|
+
if (e.defaultPrevented) return;
|
|
617
|
+
menu.setOpen(!menu.open);
|
|
618
|
+
},
|
|
619
|
+
onPointerEnter: (e) => {
|
|
620
|
+
onPointerEnter?.(e);
|
|
621
|
+
if (bar.activeId !== null && bar.activeId !== menu.id) {
|
|
622
|
+
bar.setActiveId(menu.id);
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
onKeyDown: (e) => {
|
|
626
|
+
onKeyDown?.(e);
|
|
627
|
+
if (e.defaultPrevented) return;
|
|
628
|
+
switch (e.key) {
|
|
629
|
+
case "ArrowRight":
|
|
630
|
+
e.preventDefault();
|
|
631
|
+
moveAcross(1);
|
|
632
|
+
break;
|
|
633
|
+
case "ArrowLeft":
|
|
634
|
+
e.preventDefault();
|
|
635
|
+
moveAcross(-1);
|
|
636
|
+
break;
|
|
637
|
+
case "ArrowDown":
|
|
638
|
+
case "Enter":
|
|
639
|
+
case " ":
|
|
640
|
+
e.preventDefault();
|
|
641
|
+
menu.setOpen(true);
|
|
642
|
+
break;
|
|
643
|
+
case "Home":
|
|
644
|
+
e.preventDefault();
|
|
645
|
+
bar.triggersRef.current[0]?.ref?.focus();
|
|
646
|
+
break;
|
|
647
|
+
case "End": {
|
|
648
|
+
e.preventDefault();
|
|
649
|
+
const list = bar.triggersRef.current;
|
|
650
|
+
list[list.length - 1]?.ref?.focus();
|
|
651
|
+
break;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
className: cn(menubarTriggerVariants(), className),
|
|
656
|
+
...rest,
|
|
657
|
+
children
|
|
658
|
+
}
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
);
|
|
662
|
+
function MenubarContent({
|
|
663
|
+
className,
|
|
664
|
+
placement = "bottom-start",
|
|
665
|
+
offset = 4,
|
|
666
|
+
"aria-label": ariaLabel,
|
|
667
|
+
children
|
|
668
|
+
}) {
|
|
669
|
+
const menu = useMenubarMenuContext();
|
|
670
|
+
return /* @__PURE__ */ jsx(
|
|
671
|
+
Menu,
|
|
672
|
+
{
|
|
673
|
+
open: menu.open,
|
|
674
|
+
anchor: menu.triggerRef.current,
|
|
675
|
+
onClose: () => {
|
|
676
|
+
menu.setOpen(false);
|
|
677
|
+
requestAnimationFrame(() => menu.triggerRef.current?.focus());
|
|
678
|
+
},
|
|
679
|
+
placement,
|
|
680
|
+
offset,
|
|
681
|
+
"aria-label": ariaLabel,
|
|
682
|
+
className,
|
|
683
|
+
children
|
|
684
|
+
}
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
Menubar.Menu = MenubarMenu;
|
|
688
|
+
Menubar.Trigger = MenubarTrigger;
|
|
689
|
+
Menubar.Content = MenubarContent;
|
|
690
|
+
Menubar.Item = MenuItem;
|
|
691
|
+
Menubar.Group = MenuGroup;
|
|
692
|
+
Menubar.Label = MenuLabel;
|
|
693
|
+
Menubar.Separator = MenuSeparator;
|
|
694
|
+
|
|
695
|
+
export { Breadcrumb, ContextMenu, ContextMenuContent, ContextMenuTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, Menu, MenuGroup, MenuItem, MenuLabel, MenuSeparator, Menubar, MenubarContent, MenubarMenu, MenubarTrigger, NavItem, Pagination, menuItemVariants, menuLabelVariants, menuSeparatorVariants, menuVariants };
|
|
696
|
+
//# sourceMappingURL=chunk-3KGYKBW6.js.map
|
|
697
|
+
//# sourceMappingURL=chunk-3KGYKBW6.js.map
|