ajo-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +126 -0
  3. package/dist/accordion.js +130 -0
  4. package/dist/avatar.js +54 -0
  5. package/dist/calendar.js +2 -0
  6. package/dist/carousel.js +239 -0
  7. package/dist/chart.js +790 -0
  8. package/dist/checkbox-group.js +70 -0
  9. package/dist/checkbox.js +77 -0
  10. package/dist/chunks/bar-CVafh6C1.js +99 -0
  11. package/dist/chunks/calendar-q8jZ8Cxr.js +1923 -0
  12. package/dist/chunks/collection-DtRB63U4.js +111 -0
  13. package/dist/chunks/data-table-DpkWv4y4.js +1039 -0
  14. package/dist/chunks/menu-B45IyHHC.js +704 -0
  15. package/dist/chunks/native-BJdhd9XJ.js +20 -0
  16. package/dist/chunks/popup-C8Bb3l_g.js +459 -0
  17. package/dist/chunks/popup-surface-BDCgtVU0.js +18 -0
  18. package/dist/chunks/position-D6_i_SRn.js +434 -0
  19. package/dist/chunks/virtual-list-B7hjGkjk.js +413 -0
  20. package/dist/collapsible.js +106 -0
  21. package/dist/command.js +263 -0
  22. package/dist/context-menu.js +112 -0
  23. package/dist/data-table.js +5 -0
  24. package/dist/dialog.js +207 -0
  25. package/dist/direction.js +22 -0
  26. package/dist/drawer.js +139 -0
  27. package/dist/field.js +26 -0
  28. package/dist/index.js +38 -0
  29. package/dist/input-date.js +994 -0
  30. package/dist/input-group.js +52 -0
  31. package/dist/input-otp.js +179 -0
  32. package/dist/menu.js +2 -0
  33. package/dist/menubar.js +236 -0
  34. package/dist/message-scroller.js +446 -0
  35. package/dist/navigation-menu.js +330 -0
  36. package/dist/popover.js +307 -0
  37. package/dist/progress.js +39 -0
  38. package/dist/radio-group.js +107 -0
  39. package/dist/resizable.js +172 -0
  40. package/dist/select.js +961 -0
  41. package/dist/sidebar.js +343 -0
  42. package/dist/slider.js +259 -0
  43. package/dist/switch.js +53 -0
  44. package/dist/tabs.js +182 -0
  45. package/dist/toast.js +492 -0
  46. package/dist/toggle-group.js +111 -0
  47. package/dist/toggle.js +52 -0
  48. package/dist/toolbar.js +127 -0
  49. package/dist/tooltip.js +196 -0
  50. package/dist/utils.js +104 -0
  51. package/dist/virtual-list.js +2 -0
  52. package/package.json +250 -0
  53. package/src/accordion.tsx +261 -0
  54. package/src/availability.ts +261 -0
  55. package/src/avatar.tsx +99 -0
  56. package/src/bar.ts +156 -0
  57. package/src/calendar.tsx +1441 -0
  58. package/src/carousel.tsx +424 -0
  59. package/src/chart.tsx +1194 -0
  60. package/src/checkbox-group.tsx +132 -0
  61. package/src/checkbox.tsx +130 -0
  62. package/src/collapsible.tsx +188 -0
  63. package/src/collection.ts +154 -0
  64. package/src/command.tsx +511 -0
  65. package/src/context-menu.tsx +233 -0
  66. package/src/data-table-contract.ts +143 -0
  67. package/src/data-table-model.ts +760 -0
  68. package/src/data-table.tsx +475 -0
  69. package/src/dialog.tsx +393 -0
  70. package/src/direction.tsx +45 -0
  71. package/src/drawer.tsx +251 -0
  72. package/src/field.tsx +61 -0
  73. package/src/index.ts +37 -0
  74. package/src/input-date.tsx +1539 -0
  75. package/src/input-group.tsx +142 -0
  76. package/src/input-otp.tsx +324 -0
  77. package/src/menu-cluster.ts +124 -0
  78. package/src/menu.tsx +1095 -0
  79. package/src/menubar.tsx +459 -0
  80. package/src/message-scroller.tsx +732 -0
  81. package/src/native.ts +26 -0
  82. package/src/navigation-menu.tsx +578 -0
  83. package/src/popover.tsx +519 -0
  84. package/src/popup-surface.tsx +31 -0
  85. package/src/popup.ts +569 -0
  86. package/src/position.ts +523 -0
  87. package/src/progress.tsx +70 -0
  88. package/src/radio-group.tsx +186 -0
  89. package/src/resizable.tsx +310 -0
  90. package/src/segments.ts +922 -0
  91. package/src/select.tsx +1501 -0
  92. package/src/sidebar.tsx +683 -0
  93. package/src/slider.tsx +424 -0
  94. package/src/switch.tsx +104 -0
  95. package/src/tabs.tsx +314 -0
  96. package/src/toast.tsx +923 -0
  97. package/src/toggle-group.tsx +249 -0
  98. package/src/toggle.tsx +91 -0
  99. package/src/toolbar.tsx +212 -0
  100. package/src/tooltip.tsx +359 -0
  101. package/src/utils.ts +204 -0
  102. package/src/virtual-list.tsx +205 -0
  103. package/src/virtual.ts +385 -0
@@ -0,0 +1,52 @@
1
+ import { callHandler } from "ajo-cloves";
2
+ import { jsx } from "ajo/jsx-runtime";
3
+ //#region packages/ajo-ui/src/input-group.tsx
4
+ /** Unstyled host that groups a control with addons and actions. */
5
+ var InputGroup = ({ children, disabled, role = "group", ...attrs }) => /* @__PURE__ */ jsx("div", {
6
+ ...attrs,
7
+ "data-disabled": disabled ? "true" : void 0,
8
+ "data-slot": "input-group",
9
+ role,
10
+ children
11
+ });
12
+ /** Unstyled addon that forwards non-button clicks to the grouped control. */
13
+ var InputGroupAddon = ({ align = "inline-start", children, role = "group", "set:onclick": onclick, ...attrs }) => /* @__PURE__ */ jsx("div", {
14
+ ...attrs,
15
+ "data-align": align,
16
+ "data-slot": "input-group-addon",
17
+ role,
18
+ "set:onclick": (event) => {
19
+ callHandler(onclick, event);
20
+ if (event.target.closest("button")) return;
21
+ const parent = event.currentTarget.parentElement;
22
+ (parent?.querySelector("[data-slot=\"input-group-control\"]") ?? parent?.querySelector("input,textarea"))?.focus();
23
+ },
24
+ children
25
+ });
26
+ /** Unstyled button rendered inside an InputGroup. */
27
+ var InputGroupButton = ({ children, "data-slot": slot = "input-group-button", type = "button", ...attrs }) => /* @__PURE__ */ jsx("button", {
28
+ ...attrs,
29
+ "data-slot": slot,
30
+ type,
31
+ children
32
+ });
33
+ /** Unstyled supporting text rendered inside an InputGroup. */
34
+ var InputGroupText = ({ children, ...attrs }) => /* @__PURE__ */ jsx("span", {
35
+ ...attrs,
36
+ "data-slot": "input-group-text",
37
+ children
38
+ });
39
+ /** Unstyled native input carrying the InputGroup control slot. */
40
+ var InputGroupInput = ({ "data-slot": slot = "input-group-control", type = "text", ...attrs }) => /* @__PURE__ */ jsx("input", {
41
+ ...attrs,
42
+ "data-slot": slot,
43
+ type
44
+ });
45
+ /** Unstyled native textarea carrying the InputGroup control slot. */
46
+ var InputGroupTextarea = ({ children, "data-slot": slot = "input-group-control", ...attrs }) => /* @__PURE__ */ jsx("textarea", {
47
+ ...attrs,
48
+ "data-slot": slot,
49
+ children
50
+ });
51
+ //#endregion
52
+ export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea };
@@ -0,0 +1,179 @@
1
+ import { callHandler, callRef, clamp, controlled, dom } from "ajo-cloves";
2
+ import { context } from "ajo/context";
3
+ import { Fragment, jsx, jsxs } from "ajo/jsx-runtime";
4
+ //#region packages/ajo-ui/src/input-otp.tsx
5
+ /** Built-in InputOTP pattern accepting one or more ASCII digits. */
6
+ var REGEXP_ONLY_DIGITS = /^[0-9]+$/;
7
+ /** Built-in InputOTP pattern accepting one or more ASCII letters or digits. */
8
+ var REGEXP_ONLY_DIGITS_AND_CHARS = /^[a-zA-Z0-9]+$/;
9
+ var InputOTPContext = context(null);
10
+ var isRegExp = (value) => Object.prototype.toString.call(value) === "[object RegExp]";
11
+ var accepts = (pattern, char) => {
12
+ if (!pattern) return true;
13
+ if (isRegExp(pattern)) {
14
+ pattern.lastIndex = 0;
15
+ return pattern.test(char);
16
+ }
17
+ return new RegExp(pattern).test(char);
18
+ };
19
+ var clean = (value, maxLength, pattern) => String(value ?? "").split("").filter((char) => accepts(pattern, char)).slice(0, Math.max(1, maxLength)).join("");
20
+ var inputPattern = (pattern) => isRegExp(pattern) ? pattern.source : pattern;
21
+ var nextSelection = (input, fallback) => Math.min(input?.selectionStart ?? fallback, Math.max(0, input?.value.length ?? fallback));
22
+ var completionState = (value, maxLength) => value.length === maxLength ? "complete" : "incomplete";
23
+ var InputOTPRoot = function* ({ defaultValue = "", maxLength = 6, pattern, value }) {
24
+ let input = null;
25
+ const initial = clean(value ?? defaultValue, maxLength, pattern);
26
+ let active = Math.min(initial.length, Math.max(0, maxLength - 1));
27
+ let onValueChange;
28
+ let onComplete;
29
+ let previousComplete = initial.length === maxLength ? initial : "";
30
+ const emit = (next, event) => {
31
+ onValueChange?.(next, event);
32
+ if (next.length === maxLength && next !== previousComplete) {
33
+ previousComplete = next;
34
+ onComplete?.(next, event);
35
+ } else if (next.length !== maxLength) previousComplete = "";
36
+ };
37
+ const state = controlled(this, {
38
+ fallback: initial,
39
+ onChange: (next, event) => emit(next, event)
40
+ });
41
+ const setValue = (next, args, nextActive = next.length, event) => {
42
+ const length = args.maxLength ?? maxLength;
43
+ const parsed = clean(next, length, args.pattern);
44
+ active = Math.min(nextActive, Math.max(0, length - 1));
45
+ if (input) input.value = parsed;
46
+ state.accept(parsed, event);
47
+ };
48
+ const focus = (index) => {
49
+ active = clamp(index, 0, Math.max(0, maxLength - 1));
50
+ input?.focus();
51
+ input?.setSelectionRange(active, active);
52
+ this.next();
53
+ };
54
+ for (const args of this) {
55
+ const { children, class: _class, defaultValue: _defaultValue, inputClass, inputRef, maxLength: _maxLength, onValueChange: change, onComplete: complete, pattern, value, "set:onblur": onBlur, "set:onfocus": onFocus, "set:oninput": onInput, "set:onkeyup": onKeyUp, "set:onpaste": onPaste, ...inputAttrs } = args;
56
+ maxLength = _maxLength ?? 6;
57
+ onValueChange = change;
58
+ onComplete = complete;
59
+ state.sync(value != null ? clean(value, maxLength, pattern) : void 0);
60
+ if (!state.controlled) {
61
+ const parsed = clean(state.value, maxLength, pattern);
62
+ if (parsed !== state.value) state.init(parsed);
63
+ }
64
+ active = Math.min(active, Math.max(0, maxLength - 1));
65
+ if (dom(this)) this.dataset.state = completionState(state.value, maxLength);
66
+ InputOTPContext({
67
+ active,
68
+ disabled: Boolean(inputAttrs.disabled),
69
+ focus,
70
+ maxLength,
71
+ value: state.value
72
+ });
73
+ yield /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("input", {
74
+ ...inputAttrs,
75
+ "aria-label": inputAttrs["aria-label"] ?? "One-time password",
76
+ autocomplete: inputAttrs.autocomplete ?? "one-time-code",
77
+ class: inputClass,
78
+ "data-slot": "input-otp-input",
79
+ "data-state": completionState(state.value, maxLength),
80
+ inputmode: inputAttrs.inputmode ?? "numeric",
81
+ maxLength,
82
+ pattern: inputPattern(pattern),
83
+ ref: (element) => {
84
+ input = element;
85
+ callRef(inputRef, element);
86
+ },
87
+ type: inputAttrs.type ?? "text",
88
+ "set:onblur": (event) => {
89
+ callHandler(onBlur, event);
90
+ this.next(() => active = -1);
91
+ },
92
+ "set:onfocus": (event) => {
93
+ callHandler(onFocus, event);
94
+ this.next(() => active = Math.min(state.value.length, Math.max(0, maxLength - 1)));
95
+ },
96
+ "set:oninput": (event) => {
97
+ callHandler(onInput, event);
98
+ const control = event.currentTarget;
99
+ setValue(control.value, args, nextSelection(control, control.value.length), event);
100
+ },
101
+ "set:onkeyup": (event) => {
102
+ callHandler(onKeyUp, event);
103
+ this.next(() => {
104
+ active = nextSelection(event.currentTarget, active);
105
+ });
106
+ },
107
+ "set:onpaste": (event) => {
108
+ callHandler(onPaste, event);
109
+ if (event.defaultPrevented) return;
110
+ const pasted = event.clipboardData?.getData("text") ?? "";
111
+ if (!pasted) return;
112
+ event.preventDefault();
113
+ setValue(pasted, args, pasted.length, event);
114
+ },
115
+ "set:value": state.value
116
+ }), children] });
117
+ }
118
+ };
119
+ /** Unstyled one-time password input with visible slot context. */
120
+ var InputOTP = ({ children, class: classes, disabled, ref, ...attrs }) => {
121
+ const maxLength = attrs.maxLength ?? 6;
122
+ const state = completionState(clean(attrs.value ?? attrs.defaultValue, maxLength, attrs.pattern), maxLength);
123
+ return /* @__PURE__ */ jsx(InputOTPRoot, {
124
+ ...attrs,
125
+ disabled,
126
+ inputRef: ref,
127
+ "attr:class": classes,
128
+ "attr:data-disabled": disabled ? "true" : void 0,
129
+ "attr:data-slot": "input-otp",
130
+ "attr:data-state": state,
131
+ children
132
+ });
133
+ };
134
+ /** Unstyled visual group for adjacent OTP slots. */
135
+ var InputOTPGroup = ({ children, "data-slot": slot = "input-otp-group", ...attrs }) => /* @__PURE__ */ jsx("div", {
136
+ ...attrs,
137
+ "data-slot": slot,
138
+ children
139
+ });
140
+ /** Unstyled OTP slot synchronized with the nearest OTP input. */
141
+ var InputOTPSlot = ({ caretClass, caretMarkClass, children, index, role = "presentation", "set:onclick": onClick, ...attrs }) => {
142
+ const context = InputOTPContext();
143
+ if (!context) throw new Error("InputOTPSlot must be used within an <InputOTP />");
144
+ const char = context.value[index];
145
+ const active = context.active === index;
146
+ const caret = active && !char && !context.disabled;
147
+ const state = active ? "active" : "inactive";
148
+ return /* @__PURE__ */ jsxs("div", {
149
+ ...attrs,
150
+ "aria-hidden": "true",
151
+ "data-active": active ? "true" : "false",
152
+ "data-disabled": context.disabled ? "true" : void 0,
153
+ "data-slot": "input-otp-slot",
154
+ "data-state": state,
155
+ role,
156
+ "set:onclick": (event) => {
157
+ callHandler(onClick, event);
158
+ if (!event.defaultPrevented && !context.disabled) context.focus(index);
159
+ },
160
+ children: [children ?? char, caret && /* @__PURE__ */ jsx("div", {
161
+ "aria-hidden": "true",
162
+ class: caretClass,
163
+ "data-slot": "input-otp-caret",
164
+ children: /* @__PURE__ */ jsx("div", {
165
+ class: caretMarkClass,
166
+ "data-slot": "input-otp-caret-mark"
167
+ })
168
+ })]
169
+ });
170
+ };
171
+ /** Unstyled separator between OTP slot groups. */
172
+ var InputOTPSeparator = ({ children, role = "separator", "data-slot": slot = "input-otp-separator", ...attrs }) => /* @__PURE__ */ jsx("div", {
173
+ ...attrs,
174
+ "data-slot": slot,
175
+ role,
176
+ children
177
+ });
178
+ //#endregion
179
+ export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS };
package/dist/menu.js ADDED
@@ -0,0 +1,2 @@
1
+ import { a as MenuItem, c as MenuRadioItem, d as MenuSub, f as MenuSubContent, i as MenuGroup, l as MenuSeparator, m as MenuTrigger, n as MenuCheckboxItem, o as MenuLabel, p as MenuSubTrigger, r as MenuContent, s as MenuRadioGroup, t as Menu, u as MenuShortcut } from "./chunks/menu-B45IyHHC.js";
2
+ export { Menu, MenuCheckboxItem, MenuContent, MenuGroup, MenuItem, MenuLabel, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, MenuSub, MenuSubContent, MenuSubTrigger, MenuTrigger };
@@ -0,0 +1,236 @@
1
+ import { text, withSlot } from "./utils.js";
2
+ import { a as MenuItem, c as MenuRadioItem, d as MenuSub, f as MenuSubContent, i as MenuGroup, l as MenuSeparator, m as MenuTrigger, n as MenuCheckboxItem, o as MenuLabel, p as MenuSubTrigger, r as MenuContent, s as MenuRadioGroup, t as Menu, u as MenuShortcut, v as provideMenubarComposition } from "./chunks/menu-B45IyHHC.js";
3
+ import { t as bar } from "./chunks/bar-CVafh6C1.js";
4
+ import { callHandler, callRef, id, listen, statefulRootAttrs } from "ajo-cloves";
5
+ import { context } from "ajo/context";
6
+ import { Fragment, jsx } from "ajo/jsx-runtime";
7
+ //#region packages/ajo-ui/src/menubar.tsx
8
+ var MenubarContext = context(null);
9
+ var MenubarMenuContext = context(null);
10
+ var order = (root) => Array.from(root.querySelectorAll("[data-menubar-trigger=\"true\"]")).filter((trigger) => !trigger.disabled && trigger.offsetParent !== null && trigger.closest("[data-slot=\"menubar\"]") === root);
11
+ var MenubarRoot = function* ({ defaultValue, value }) {
12
+ const triggers = /* @__PURE__ */ new Map();
13
+ let disabled = false;
14
+ let entering = false;
15
+ let loop = true;
16
+ let onValueChange;
17
+ let pendingFocus = "";
18
+ let queued = false;
19
+ const state = bar(this, {
20
+ triggers: () => order(this),
21
+ initialValue: String(value ?? defaultValue ?? ""),
22
+ disabled: () => disabled,
23
+ loop: () => loop,
24
+ onValueChange: (next, event) => onValueChange?.(next, event)
25
+ });
26
+ const rerender = () => {
27
+ if (queued) return;
28
+ queued = true;
29
+ queueMicrotask(() => {
30
+ queued = false;
31
+ this.next();
32
+ });
33
+ };
34
+ const register = (itemValue, element) => {
35
+ if (element) {
36
+ if (triggers.get(itemValue) === element) return;
37
+ triggers.set(itemValue, element);
38
+ rerender();
39
+ } else if (triggers.delete(itemValue)) {
40
+ if (state.focused === itemValue) state.adopt("");
41
+ rerender();
42
+ }
43
+ };
44
+ const close = (event) => {
45
+ pendingFocus = "";
46
+ state.close(event);
47
+ };
48
+ const focus = (next, event) => {
49
+ if (!entering) pendingFocus = "";
50
+ state.focus(next, event);
51
+ };
52
+ const follow = (next, event) => {
53
+ if (!entering) pendingFocus = "";
54
+ state.follow(next, event);
55
+ };
56
+ const open = (next, event) => {
57
+ pendingFocus = "";
58
+ state.setValue(next, event);
59
+ };
60
+ const enter = (next, event) => {
61
+ pendingFocus = next;
62
+ entering = true;
63
+ try {
64
+ state.follow(next, event);
65
+ } finally {
66
+ entering = false;
67
+ }
68
+ };
69
+ const ackFocus = (next) => {
70
+ if (!next || pendingFocus !== next) return false;
71
+ pendingFocus = "";
72
+ return true;
73
+ };
74
+ listen(this, "keydown", (event) => {
75
+ if (event.defaultPrevented) return;
76
+ const target = event.target;
77
+ if (target?.closest("[data-slot=\"menubar\"]") !== this) return;
78
+ if (event.key === "Tab") {
79
+ close(event);
80
+ return;
81
+ }
82
+ if (target?.closest("[data-menubar-trigger=\"true\"]")) {
83
+ if (event.key === "Escape") pendingFocus = "";
84
+ const transfer = Boolean(pendingFocus);
85
+ if (transfer) entering = true;
86
+ try {
87
+ if (state.handle(event) && transfer) pendingFocus = state.value;
88
+ } finally {
89
+ if (transfer) entering = false;
90
+ }
91
+ return;
92
+ }
93
+ if (state.value && (event.key === "ArrowLeft" || event.key === "ArrowRight") && target?.closest("[data-menu-content=\"true\"]")) {
94
+ if (event.key === "ArrowRight" && target.closest("[data-menu-sub-trigger=\"true\"]")) return;
95
+ if (target.closest("[data-menu-sub-content=\"true\"]")) return;
96
+ const row = order(this);
97
+ const index = row.findIndex((trigger) => trigger.dataset.value === state.value);
98
+ if (index < 0) return;
99
+ const step = event.key === "ArrowRight" ? 1 : -1;
100
+ const next = row[index + step] ?? (loop ? row[(index + step + row.length) % row.length] : void 0);
101
+ if (!next || next === row[index]) return;
102
+ event.preventDefault();
103
+ enter(next.dataset.value ?? "", event);
104
+ }
105
+ });
106
+ for (const args of this) {
107
+ disabled = Boolean(args.disabled);
108
+ loop = args.loop !== false;
109
+ onValueChange = args.onValueChange;
110
+ state.sync(args.value != null ? String(args.value ?? "") : void 0);
111
+ MenubarContext({
112
+ ackFocus,
113
+ close,
114
+ disabled,
115
+ focus,
116
+ follow,
117
+ gap: args.gap,
118
+ isTabbable: state.isTabbable,
119
+ open,
120
+ placement: args.placement,
121
+ register,
122
+ value: state.value
123
+ });
124
+ yield /* @__PURE__ */ jsx(Fragment, { children: args.children });
125
+ }
126
+ };
127
+ /** Persistent horizontal menu bar. */
128
+ var Menubar = ({ children, class: classes, defaultValue, disabled, gap, loop, onValueChange, placement, value, ...attrs }) => /* @__PURE__ */ jsx(MenubarRoot, {
129
+ ...statefulRootAttrs(attrs),
130
+ defaultValue,
131
+ disabled,
132
+ gap,
133
+ loop,
134
+ onValueChange,
135
+ placement,
136
+ value,
137
+ "attr:aria-orientation": "horizontal",
138
+ "attr:class": classes,
139
+ "attr:data-slot": "menubar",
140
+ "attr:role": "menubar",
141
+ children
142
+ });
143
+ var MenubarMenuRoot = function* ({ value }) {
144
+ const fallback = id("menubar-menu");
145
+ let bar = null;
146
+ let itemValue = String(value ?? fallback);
147
+ const ackFocus = () => bar?.ackFocus(itemValue) ?? false;
148
+ for (const args of this) {
149
+ bar = MenubarContext();
150
+ itemValue = String(args.value ?? value ?? fallback);
151
+ const disabled = Boolean(args.disabled ?? bar?.disabled);
152
+ MenubarMenuContext({
153
+ disabled,
154
+ value: itemValue
155
+ });
156
+ if (bar) provideMenubarComposition(ackFocus);
157
+ yield /* @__PURE__ */ jsx(Menu, {
158
+ disabled,
159
+ gap: bar?.gap,
160
+ onOpenChange: (open, event) => open ? bar?.open(itemValue, event) : bar?.close(event),
161
+ open: bar ? bar.value === itemValue : void 0,
162
+ placement: bar?.placement,
163
+ children: args.children
164
+ });
165
+ }
166
+ };
167
+ /** Top-level Menubar menu. */
168
+ var MenubarMenu = ({ children, class: classes, disabled, value, ...attrs }) => /* @__PURE__ */ jsx(MenubarMenuRoot, {
169
+ ...statefulRootAttrs(attrs),
170
+ disabled,
171
+ value,
172
+ "attr:class": classes,
173
+ "attr:data-slot": "menubar-menu",
174
+ children
175
+ });
176
+ /** Top-level trigger inside a Menubar. */
177
+ var MenubarTrigger = ({ children, class: classes, disabled, ref, textValue, "set:onfocus": onFocus, "set:onmouseenter": onMouseEnter, ...attrs }) => {
178
+ const bar = MenubarContext();
179
+ const menu = MenubarMenuContext();
180
+ const itemValue = menu?.value ?? "";
181
+ const disabledFlag = Boolean(disabled ?? menu?.disabled ?? bar?.disabled);
182
+ const label = textValue ?? text(children);
183
+ const reference = (element) => {
184
+ if (itemValue) bar?.register(itemValue, element);
185
+ callRef(ref, element);
186
+ };
187
+ return /* @__PURE__ */ jsx(MenuTrigger, {
188
+ ...attrs,
189
+ class: classes,
190
+ "data-label": bar ? label : void 0,
191
+ "data-menubar-trigger": bar ? "true" : void 0,
192
+ "data-slot": "menubar-trigger",
193
+ "data-value": bar ? itemValue : void 0,
194
+ disabled: disabledFlag,
195
+ ref: reference,
196
+ role: bar ? "menuitem" : void 0,
197
+ "set:onfocus": (event) => {
198
+ callHandler(onFocus, event);
199
+ if (event.defaultPrevented || disabledFlag) return;
200
+ bar?.focus(itemValue, event);
201
+ },
202
+ "set:onmouseenter": (event) => {
203
+ callHandler(onMouseEnter, event);
204
+ if (event.defaultPrevented || disabledFlag) return;
205
+ bar?.follow(itemValue, event);
206
+ },
207
+ tabindex: bar ? bar.isTabbable(itemValue) ? 0 : -1 : void 0,
208
+ children
209
+ });
210
+ };
211
+ /** Popover content for a top-level Menubar menu. */
212
+ var MenubarContent = withSlot(MenuContent, "menubar-content");
213
+ /** Standard menubar action item. */
214
+ var MenubarItem = withSlot(MenuItem, "menubar-item");
215
+ /** Checkable menubar item. */
216
+ var MenubarCheckboxItem = withSlot(MenuCheckboxItem, "menubar-checkbox-item");
217
+ /** Radio group inside a menubar menu. */
218
+ var MenubarRadioGroup = withSlot(MenuRadioGroup, "menubar-radio-group");
219
+ /** Radio item inside a menubar radio group. */
220
+ var MenubarRadioItem = withSlot(MenuRadioItem, "menubar-radio-item");
221
+ /** Group of menubar items. */
222
+ var MenubarGroup = withSlot(MenuGroup, "menubar-group");
223
+ /** Non-interactive label inside a menubar menu. */
224
+ var MenubarLabel = withSlot(MenuLabel, "menubar-label");
225
+ /** Visual separator between menubar groups. */
226
+ var MenubarSeparator = withSlot(MenuSeparator, "menubar-separator");
227
+ /** Right-aligned shortcut hint inside a menubar item. */
228
+ var MenubarShortcut = withSlot(MenuShortcut, "menubar-shortcut");
229
+ /** Root provider for a menubar submenu. */
230
+ var MenubarSub = withSlot(MenuSub, "menubar-sub");
231
+ /** Trigger item that opens a menubar submenu. */
232
+ var MenubarSubTrigger = withSlot(MenuSubTrigger, "menubar-sub-trigger");
233
+ /** Content for a menubar submenu. */
234
+ var MenubarSubContent = withSlot(MenuSubContent, "menubar-sub-content");
235
+ //#endregion
236
+ export { Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger };