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.
- package/LICENSE +15 -0
- package/README.md +126 -0
- package/dist/accordion.js +130 -0
- package/dist/avatar.js +54 -0
- package/dist/calendar.js +2 -0
- package/dist/carousel.js +239 -0
- package/dist/chart.js +790 -0
- package/dist/checkbox-group.js +70 -0
- package/dist/checkbox.js +77 -0
- package/dist/chunks/bar-CVafh6C1.js +99 -0
- package/dist/chunks/calendar-q8jZ8Cxr.js +1923 -0
- package/dist/chunks/collection-DtRB63U4.js +111 -0
- package/dist/chunks/data-table-DpkWv4y4.js +1039 -0
- package/dist/chunks/menu-B45IyHHC.js +704 -0
- package/dist/chunks/native-BJdhd9XJ.js +20 -0
- package/dist/chunks/popup-C8Bb3l_g.js +459 -0
- package/dist/chunks/popup-surface-BDCgtVU0.js +18 -0
- package/dist/chunks/position-D6_i_SRn.js +434 -0
- package/dist/chunks/virtual-list-B7hjGkjk.js +413 -0
- package/dist/collapsible.js +106 -0
- package/dist/command.js +263 -0
- package/dist/context-menu.js +112 -0
- package/dist/data-table.js +5 -0
- package/dist/dialog.js +207 -0
- package/dist/direction.js +22 -0
- package/dist/drawer.js +139 -0
- package/dist/field.js +26 -0
- package/dist/index.js +38 -0
- package/dist/input-date.js +994 -0
- package/dist/input-group.js +52 -0
- package/dist/input-otp.js +179 -0
- package/dist/menu.js +2 -0
- package/dist/menubar.js +236 -0
- package/dist/message-scroller.js +446 -0
- package/dist/navigation-menu.js +330 -0
- package/dist/popover.js +307 -0
- package/dist/progress.js +39 -0
- package/dist/radio-group.js +107 -0
- package/dist/resizable.js +172 -0
- package/dist/select.js +961 -0
- package/dist/sidebar.js +343 -0
- package/dist/slider.js +259 -0
- package/dist/switch.js +53 -0
- package/dist/tabs.js +182 -0
- package/dist/toast.js +492 -0
- package/dist/toggle-group.js +111 -0
- package/dist/toggle.js +52 -0
- package/dist/toolbar.js +127 -0
- package/dist/tooltip.js +196 -0
- package/dist/utils.js +104 -0
- package/dist/virtual-list.js +2 -0
- package/package.json +250 -0
- package/src/accordion.tsx +261 -0
- package/src/availability.ts +261 -0
- package/src/avatar.tsx +99 -0
- package/src/bar.ts +156 -0
- package/src/calendar.tsx +1441 -0
- package/src/carousel.tsx +424 -0
- package/src/chart.tsx +1194 -0
- package/src/checkbox-group.tsx +132 -0
- package/src/checkbox.tsx +130 -0
- package/src/collapsible.tsx +188 -0
- package/src/collection.ts +154 -0
- package/src/command.tsx +511 -0
- package/src/context-menu.tsx +233 -0
- package/src/data-table-contract.ts +143 -0
- package/src/data-table-model.ts +760 -0
- package/src/data-table.tsx +475 -0
- package/src/dialog.tsx +393 -0
- package/src/direction.tsx +45 -0
- package/src/drawer.tsx +251 -0
- package/src/field.tsx +61 -0
- package/src/index.ts +37 -0
- package/src/input-date.tsx +1539 -0
- package/src/input-group.tsx +142 -0
- package/src/input-otp.tsx +324 -0
- package/src/menu-cluster.ts +124 -0
- package/src/menu.tsx +1095 -0
- package/src/menubar.tsx +459 -0
- package/src/message-scroller.tsx +732 -0
- package/src/native.ts +26 -0
- package/src/navigation-menu.tsx +578 -0
- package/src/popover.tsx +519 -0
- package/src/popup-surface.tsx +31 -0
- package/src/popup.ts +569 -0
- package/src/position.ts +523 -0
- package/src/progress.tsx +70 -0
- package/src/radio-group.tsx +186 -0
- package/src/resizable.tsx +310 -0
- package/src/segments.ts +922 -0
- package/src/select.tsx +1501 -0
- package/src/sidebar.tsx +683 -0
- package/src/slider.tsx +424 -0
- package/src/switch.tsx +104 -0
- package/src/tabs.tsx +314 -0
- package/src/toast.tsx +923 -0
- package/src/toggle-group.tsx +249 -0
- package/src/toggle.tsx +91 -0
- package/src/toolbar.tsx +212 -0
- package/src/tooltip.tsx +359 -0
- package/src/utils.ts +204 -0
- package/src/virtual-list.tsx +205 -0
- package/src/virtual.ts +385 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { text, triggerAttrs } from "./utils.js";
|
|
2
|
+
import { n as popup, t as contentAttrs } from "./chunks/popup-C8Bb3l_g.js";
|
|
3
|
+
import { t as bar } from "./chunks/bar-CVafh6C1.js";
|
|
4
|
+
import { callHandler, 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/navigation-menu.tsx
|
|
8
|
+
var RootContext = context(null);
|
|
9
|
+
var ItemContext = context(null);
|
|
10
|
+
var triggers = (root) => Array.from(root.querySelectorAll("[data-navigation-menu-trigger=\"true\"]")).filter((trigger) => !trigger.disabled && trigger.offsetParent !== null && trigger.closest("[data-slot=\"navigation-menu\"]") === root);
|
|
11
|
+
var FOCUSABLE = "a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
|
|
12
|
+
var NavigationMenuRoot = function* ({ defaultValue, value }) {
|
|
13
|
+
let closeDelay = 300;
|
|
14
|
+
const closeFocus = { current: null };
|
|
15
|
+
let onValueChange;
|
|
16
|
+
let openDelay = 200;
|
|
17
|
+
let pendingFocus = "";
|
|
18
|
+
const state = bar(this, {
|
|
19
|
+
triggers: () => triggers(this),
|
|
20
|
+
initialValue: String(value ?? defaultValue ?? ""),
|
|
21
|
+
onValueChange: (next, event) => onValueChange?.(next, event)
|
|
22
|
+
});
|
|
23
|
+
const openTrigger = () => triggers(this).find((trigger) => trigger.dataset.value === state.value);
|
|
24
|
+
const focusPanel = (trigger) => {
|
|
25
|
+
const contentId = trigger.getAttribute("aria-controls");
|
|
26
|
+
(contentId ? document.getElementById(contentId) : null)?.querySelector(FOCUSABLE)?.focus();
|
|
27
|
+
};
|
|
28
|
+
const close = (event, focus) => {
|
|
29
|
+
pendingFocus = "";
|
|
30
|
+
closeFocus.current = focus ?? null;
|
|
31
|
+
state.close(event);
|
|
32
|
+
};
|
|
33
|
+
listen(this, "keydown", (event) => {
|
|
34
|
+
if (event.defaultPrevented) return;
|
|
35
|
+
const target = event.target;
|
|
36
|
+
if (target?.closest("[data-slot=\"navigation-menu\"]") !== this) return;
|
|
37
|
+
const trigger = target?.closest("[data-navigation-menu-trigger=\"true\"]");
|
|
38
|
+
if (!trigger) {
|
|
39
|
+
if (event.key === "Escape" && state.value) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
close(event, openTrigger());
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (state.handle(event)) return;
|
|
46
|
+
if (event.key === "ArrowDown" || event.key === "Enter" || event.key === " ") {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
const next = trigger.dataset.value ?? "";
|
|
49
|
+
if (state.value === next) if (event.key === "ArrowDown") focusPanel(trigger);
|
|
50
|
+
else close(event);
|
|
51
|
+
else {
|
|
52
|
+
pendingFocus = next;
|
|
53
|
+
state.setValue(next, event);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
listen(this, "focusout", (event) => {
|
|
58
|
+
if (!state.value) return;
|
|
59
|
+
const next = event.relatedTarget;
|
|
60
|
+
if (next && this.contains(next)) return;
|
|
61
|
+
if (!next && this.contains(document.activeElement)) return;
|
|
62
|
+
close(event);
|
|
63
|
+
});
|
|
64
|
+
for (const args of this) {
|
|
65
|
+
closeDelay = Math.max(0, Number(args.closeDelay ?? 300));
|
|
66
|
+
onValueChange = args.onValueChange;
|
|
67
|
+
openDelay = Math.max(0, Number(args.openDelay ?? 200));
|
|
68
|
+
state.sync(args.value != null ? String(args.value ?? "") : void 0);
|
|
69
|
+
if (pendingFocus && pendingFocus !== state.value) pendingFocus = "";
|
|
70
|
+
if (closeFocus.current) {
|
|
71
|
+
const target = closeFocus.current;
|
|
72
|
+
closeFocus.current = null;
|
|
73
|
+
if (!state.value) queueMicrotask(() => {
|
|
74
|
+
if (!state.value) target.focus();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
RootContext({
|
|
78
|
+
close,
|
|
79
|
+
closeDelay,
|
|
80
|
+
follow: (next, event) => {
|
|
81
|
+
pendingFocus = "";
|
|
82
|
+
state.follow(next, event);
|
|
83
|
+
},
|
|
84
|
+
gap: args.gap,
|
|
85
|
+
open: (next, event) => {
|
|
86
|
+
if (pendingFocus !== next) pendingFocus = "";
|
|
87
|
+
state.setValue(next, event);
|
|
88
|
+
},
|
|
89
|
+
openDelay,
|
|
90
|
+
placement: args.placement,
|
|
91
|
+
takeFocus: (value) => {
|
|
92
|
+
if (!value || pendingFocus !== value) return false;
|
|
93
|
+
pendingFocus = "";
|
|
94
|
+
return true;
|
|
95
|
+
},
|
|
96
|
+
value: state.value
|
|
97
|
+
});
|
|
98
|
+
yield /* @__PURE__ */ jsx(Fragment, { children: args.children });
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
NavigationMenuRoot.is = "nav";
|
|
102
|
+
/** Unstyled root landmark and state provider for a navigation menu. */
|
|
103
|
+
var NavigationMenu = ({ children, class: classes, closeDelay, defaultValue, gap, onValueChange, openDelay, placement, value, ...attrs }) => /* @__PURE__ */ jsx(NavigationMenuRoot, {
|
|
104
|
+
...statefulRootAttrs(attrs),
|
|
105
|
+
closeDelay,
|
|
106
|
+
defaultValue,
|
|
107
|
+
gap,
|
|
108
|
+
onValueChange,
|
|
109
|
+
openDelay,
|
|
110
|
+
placement,
|
|
111
|
+
value,
|
|
112
|
+
"attr:class": classes,
|
|
113
|
+
"attr:data-slot": "navigation-menu",
|
|
114
|
+
children
|
|
115
|
+
});
|
|
116
|
+
/** Unstyled horizontal list of navigation menu items. */
|
|
117
|
+
var NavigationMenuList = ({ children, class: classes, ...attrs }) => /* @__PURE__ */ jsx("ul", {
|
|
118
|
+
...attrs,
|
|
119
|
+
class: classes,
|
|
120
|
+
"data-slot": "navigation-menu-list",
|
|
121
|
+
children
|
|
122
|
+
});
|
|
123
|
+
var NavigationMenuItemRoot = function* ({ value }) {
|
|
124
|
+
const fallback = value ?? id("navigation-menu-item");
|
|
125
|
+
let disabled = false;
|
|
126
|
+
let itemValue = String(fallback);
|
|
127
|
+
let root = null;
|
|
128
|
+
let item;
|
|
129
|
+
item = popup(this, {
|
|
130
|
+
prefix: "navigation-menu",
|
|
131
|
+
profile: "navigation",
|
|
132
|
+
initialOpen: false,
|
|
133
|
+
disabled: () => disabled,
|
|
134
|
+
hover: {
|
|
135
|
+
openDelay: () => root?.openDelay ?? 200,
|
|
136
|
+
closeDelay: () => root?.closeDelay ?? 300
|
|
137
|
+
},
|
|
138
|
+
onOpenChange: (next, event) => {
|
|
139
|
+
if (next) root?.open(itemValue, event);
|
|
140
|
+
else if (root?.value === itemValue) root.close(event);
|
|
141
|
+
},
|
|
142
|
+
reference: (view) => view.trigger,
|
|
143
|
+
source: (view) => view.trigger,
|
|
144
|
+
referenceHidden: "close",
|
|
145
|
+
dismiss: {
|
|
146
|
+
escape: false,
|
|
147
|
+
outside: true,
|
|
148
|
+
inside: (view) => [view.trigger, view.content],
|
|
149
|
+
onDismiss: (event) => closeItem(event)
|
|
150
|
+
},
|
|
151
|
+
onPosition: () => {
|
|
152
|
+
if (root?.takeFocus(itemValue)) item.content?.querySelector(FOCUSABLE)?.focus();
|
|
153
|
+
},
|
|
154
|
+
onSync: (opened) => {
|
|
155
|
+
if (!opened) cause = "";
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
let cause = "";
|
|
159
|
+
const registerTriggerHover = (hovering, event) => {
|
|
160
|
+
if (hovering) {
|
|
161
|
+
if (!item.open) cause = "hover";
|
|
162
|
+
item.hold("trigger", event);
|
|
163
|
+
if (!disabled) root?.follow(itemValue, event);
|
|
164
|
+
} else {
|
|
165
|
+
if (!item.open && cause === "hover") cause = "";
|
|
166
|
+
item.release("trigger", event);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
const registerContentHover = (hovering, event) => hovering ? item.hold("content", event) : item.release("content", event);
|
|
170
|
+
const registerTriggerFocus = (event) => {
|
|
171
|
+
if (!disabled) root?.follow(itemValue, event);
|
|
172
|
+
};
|
|
173
|
+
const openItem = (event) => {
|
|
174
|
+
if (disabled) return;
|
|
175
|
+
cause = "press";
|
|
176
|
+
item.cancelHover();
|
|
177
|
+
if (root) root.open(itemValue, event);
|
|
178
|
+
else item.setOpen(true, event);
|
|
179
|
+
};
|
|
180
|
+
const closeItem = (event) => root ? root.close(event) : item.close(event);
|
|
181
|
+
const clickTrigger = (event) => {
|
|
182
|
+
if (disabled) return;
|
|
183
|
+
if (!item.open) openItem(event);
|
|
184
|
+
else if (cause === "hover") {
|
|
185
|
+
cause = "press";
|
|
186
|
+
item.cancelHover();
|
|
187
|
+
} else closeItem(event);
|
|
188
|
+
};
|
|
189
|
+
for (const args of this) {
|
|
190
|
+
root = RootContext();
|
|
191
|
+
itemValue = String(args.value ?? fallback);
|
|
192
|
+
disabled = Boolean(args.disabled);
|
|
193
|
+
const opened = item.sync(root ? root.value === itemValue : null, {
|
|
194
|
+
placement: root?.placement,
|
|
195
|
+
gap: root?.gap
|
|
196
|
+
});
|
|
197
|
+
if (!opened) cause = "";
|
|
198
|
+
ItemContext({
|
|
199
|
+
adoptTriggerId: item.adoptTriggerId,
|
|
200
|
+
clickTrigger,
|
|
201
|
+
close: closeItem,
|
|
202
|
+
contentId: item.contentId,
|
|
203
|
+
contentStyle: item.contentStyle,
|
|
204
|
+
disabled,
|
|
205
|
+
open: opened,
|
|
206
|
+
registerContentHover,
|
|
207
|
+
registerTriggerFocus,
|
|
208
|
+
registerTriggerHover,
|
|
209
|
+
setContent: item.setContent,
|
|
210
|
+
setTrigger: item.setTrigger,
|
|
211
|
+
triggerId: item.triggerId,
|
|
212
|
+
value: itemValue
|
|
213
|
+
});
|
|
214
|
+
yield /* @__PURE__ */ jsx(Fragment, { children: args.children });
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
NavigationMenuItemRoot.is = "li";
|
|
218
|
+
/** Unstyled top-level item inside a NavigationMenuList. */
|
|
219
|
+
var NavigationMenuItem = ({ children, class: classes, disabled, value, ...attrs }) => /* @__PURE__ */ jsx(NavigationMenuItemRoot, {
|
|
220
|
+
...statefulRootAttrs(attrs),
|
|
221
|
+
disabled,
|
|
222
|
+
value,
|
|
223
|
+
"attr:class": classes,
|
|
224
|
+
"attr:data-disabled": disabled ? "true" : void 0,
|
|
225
|
+
"attr:data-slot": "navigation-menu-item",
|
|
226
|
+
children
|
|
227
|
+
});
|
|
228
|
+
/** Unstyled button that opens an item content panel. */
|
|
229
|
+
var NavigationMenuTrigger = ({ children, class: classes, disabled, id: idArg, ref, textValue, type = "button", "set:onclick": onClick, "set:onfocus": onFocus, "set:onmouseenter": onMouseEnter, "set:onmouseleave": onMouseLeave, ...attrs }) => {
|
|
230
|
+
const item = ItemContext();
|
|
231
|
+
const disabledFlag = Boolean(disabled ?? item?.disabled);
|
|
232
|
+
const label = textValue ?? text(children);
|
|
233
|
+
const adoptedId = item?.adoptTriggerId(idArg);
|
|
234
|
+
return /* @__PURE__ */ jsx("button", {
|
|
235
|
+
...attrs,
|
|
236
|
+
...triggerAttrs({
|
|
237
|
+
controls: item?.contentId,
|
|
238
|
+
expanded: Boolean(item?.open),
|
|
239
|
+
id: adoptedId ?? idArg,
|
|
240
|
+
open: Boolean(item?.open),
|
|
241
|
+
ref,
|
|
242
|
+
setTrigger: item?.setTrigger,
|
|
243
|
+
triggerId: item?.triggerId
|
|
244
|
+
}),
|
|
245
|
+
class: classes,
|
|
246
|
+
"data-label": label,
|
|
247
|
+
"data-navigation-menu-trigger": "true",
|
|
248
|
+
"data-slot": "navigation-menu-trigger",
|
|
249
|
+
"data-value": item?.value,
|
|
250
|
+
disabled: disabledFlag,
|
|
251
|
+
type,
|
|
252
|
+
"set:onclick": (event) => {
|
|
253
|
+
callHandler(onClick, event);
|
|
254
|
+
if (event.defaultPrevented || disabledFlag) return;
|
|
255
|
+
item?.clickTrigger(event);
|
|
256
|
+
},
|
|
257
|
+
"set:onfocus": (event) => {
|
|
258
|
+
callHandler(onFocus, event);
|
|
259
|
+
if (event.defaultPrevented || disabledFlag) return;
|
|
260
|
+
item?.registerTriggerFocus(event);
|
|
261
|
+
},
|
|
262
|
+
"set:onmouseenter": (event) => {
|
|
263
|
+
callHandler(onMouseEnter, event);
|
|
264
|
+
if (event.defaultPrevented || disabledFlag) return;
|
|
265
|
+
item?.registerTriggerHover(true, event);
|
|
266
|
+
},
|
|
267
|
+
"set:onmouseleave": (event) => {
|
|
268
|
+
callHandler(onMouseLeave, event);
|
|
269
|
+
item?.registerTriggerHover(false, event);
|
|
270
|
+
},
|
|
271
|
+
children
|
|
272
|
+
});
|
|
273
|
+
};
|
|
274
|
+
/** Unstyled popover panel for a NavigationMenuItem. */
|
|
275
|
+
var NavigationMenuContent = ({ children, class: classes, ref, style, "set:onmouseenter": onMouseEnter, "set:onmouseleave": onMouseLeave, ...attrs }) => {
|
|
276
|
+
const item = ItemContext();
|
|
277
|
+
return /* @__PURE__ */ jsx("div", {
|
|
278
|
+
...attrs,
|
|
279
|
+
...contentAttrs({
|
|
280
|
+
id: item?.contentId,
|
|
281
|
+
open: Boolean(item?.open),
|
|
282
|
+
ref,
|
|
283
|
+
setContent: item?.setContent,
|
|
284
|
+
style: item?.contentStyle(style),
|
|
285
|
+
tabindex: "-1"
|
|
286
|
+
}),
|
|
287
|
+
"aria-labelledby": item?.triggerId,
|
|
288
|
+
class: classes,
|
|
289
|
+
"data-slot": "navigation-menu-content",
|
|
290
|
+
"set:onmouseenter": (event) => {
|
|
291
|
+
callHandler(onMouseEnter, event);
|
|
292
|
+
item?.registerContentHover(true, event);
|
|
293
|
+
},
|
|
294
|
+
"set:onmouseleave": (event) => {
|
|
295
|
+
callHandler(onMouseLeave, event);
|
|
296
|
+
item?.registerContentHover(false, event);
|
|
297
|
+
},
|
|
298
|
+
children
|
|
299
|
+
});
|
|
300
|
+
};
|
|
301
|
+
/** Unstyled link for use inside or directly within a navigation menu item. */
|
|
302
|
+
var NavigationMenuLink = ({ active, as = "a", children, class: classes, type = "button", "set:onclick": onClick, ...attrs }) => {
|
|
303
|
+
const item = ItemContext();
|
|
304
|
+
const state = active ? "true" : void 0;
|
|
305
|
+
const current = active ? "page" : void 0;
|
|
306
|
+
const click = (event) => {
|
|
307
|
+
callHandler(onClick, event);
|
|
308
|
+
if (!event.defaultPrevented) item?.close(event);
|
|
309
|
+
};
|
|
310
|
+
if (as === "button") return /* @__PURE__ */ jsx("button", {
|
|
311
|
+
...attrs,
|
|
312
|
+
class: classes,
|
|
313
|
+
"data-active": state,
|
|
314
|
+
"data-slot": "navigation-menu-link",
|
|
315
|
+
type,
|
|
316
|
+
"set:onclick": click,
|
|
317
|
+
children
|
|
318
|
+
});
|
|
319
|
+
return /* @__PURE__ */ jsx("a", {
|
|
320
|
+
...attrs,
|
|
321
|
+
"aria-current": current,
|
|
322
|
+
class: classes,
|
|
323
|
+
"data-active": state,
|
|
324
|
+
"data-slot": "navigation-menu-link",
|
|
325
|
+
"set:onclick": click,
|
|
326
|
+
children
|
|
327
|
+
});
|
|
328
|
+
};
|
|
329
|
+
//#endregion
|
|
330
|
+
export { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger };
|
package/dist/popover.js
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { popupStyle, triggerAttrs } from "./utils.js";
|
|
2
|
+
import { n as popup, t as contentAttrs } from "./chunks/popup-C8Bb3l_g.js";
|
|
3
|
+
import { t as PopupSurface } from "./chunks/popup-surface-BDCgtVU0.js";
|
|
4
|
+
import { callHandler, callRef, statefulRootAttrs } from "ajo-cloves";
|
|
5
|
+
import { context } from "ajo/context";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "ajo/jsx-runtime";
|
|
7
|
+
//#region packages/ajo-ui/src/popover.tsx
|
|
8
|
+
var PopoverContext = context(null);
|
|
9
|
+
/** Shared root body for both interaction modes; the mode is fixed per host. */
|
|
10
|
+
function* popoverEngine(initial, mode) {
|
|
11
|
+
let closeDelay = 300;
|
|
12
|
+
let disabled = false;
|
|
13
|
+
let onOpenChange;
|
|
14
|
+
let openDelay = 700;
|
|
15
|
+
let popover;
|
|
16
|
+
popover = popup(this, {
|
|
17
|
+
prefix: "popover",
|
|
18
|
+
profile: "popover",
|
|
19
|
+
initialOpen: Boolean(initial.open ?? initial.defaultOpen),
|
|
20
|
+
disabled: () => disabled,
|
|
21
|
+
hover: mode === "hover" ? {
|
|
22
|
+
openDelay: () => openDelay,
|
|
23
|
+
closeDelay: () => closeDelay
|
|
24
|
+
} : void 0,
|
|
25
|
+
onOpenChange: (next, event) => onOpenChange?.(next, event),
|
|
26
|
+
reference: (view) => view.reference ?? view.trigger,
|
|
27
|
+
referenceHidden: "close",
|
|
28
|
+
dismiss: {
|
|
29
|
+
prevent: mode === "hover",
|
|
30
|
+
outside: true,
|
|
31
|
+
onDismiss: (event, view) => {
|
|
32
|
+
view.cancelHover();
|
|
33
|
+
view.setOpen(false, event);
|
|
34
|
+
if (mode === "click") queueMicrotask(() => view.trigger?.focus());
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
const close = (event) => {
|
|
39
|
+
popover.cancelHover();
|
|
40
|
+
popover.close(event);
|
|
41
|
+
};
|
|
42
|
+
const openWithDelay = (event) => popover.hold("trigger", event);
|
|
43
|
+
const registerTriggerHover = (hovering, event) => hovering ? popover.hold("trigger", event) : popover.release("trigger", event);
|
|
44
|
+
const registerContentHover = (hovering, event) => hovering ? popover.hold("content", event) : popover.release("content", event);
|
|
45
|
+
const registerTriggerFocus = (focused, event) => focused ? popover.hold("focus-trigger", event) : popover.release("focus-trigger", event);
|
|
46
|
+
const registerContentFocus = (focused, event) => focused ? popover.hold("focus-content", event) : popover.release("focus-content", event);
|
|
47
|
+
for (const args of this) {
|
|
48
|
+
closeDelay = Math.max(0, Number(args.closeDelay ?? 300));
|
|
49
|
+
disabled = Boolean(args.disabled);
|
|
50
|
+
onOpenChange = args.onOpenChange;
|
|
51
|
+
openDelay = Math.max(0, Number(args.openDelay ?? 700));
|
|
52
|
+
const opened = popover.sync(args.open == null ? null : Boolean(args.open), {
|
|
53
|
+
placement: args.placement,
|
|
54
|
+
gap: args.gap
|
|
55
|
+
});
|
|
56
|
+
PopoverContext({
|
|
57
|
+
...popover,
|
|
58
|
+
close: mode === "hover" ? close : popover.close,
|
|
59
|
+
description: args.description,
|
|
60
|
+
disabled,
|
|
61
|
+
label: args.label,
|
|
62
|
+
open: opened,
|
|
63
|
+
openOn: mode,
|
|
64
|
+
...mode === "hover" ? {
|
|
65
|
+
openWithDelay,
|
|
66
|
+
registerContentFocus,
|
|
67
|
+
registerContentHover,
|
|
68
|
+
registerTriggerFocus,
|
|
69
|
+
registerTriggerHover
|
|
70
|
+
} : {}
|
|
71
|
+
});
|
|
72
|
+
yield /* @__PURE__ */ jsx(Fragment, { children: args.children });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
var PopoverClickRoot = function* (args) {
|
|
76
|
+
yield* popoverEngine.call(this, args, "click");
|
|
77
|
+
};
|
|
78
|
+
var PopoverHoverRoot = function* (args) {
|
|
79
|
+
yield* popoverEngine.call(this, args, "hover");
|
|
80
|
+
};
|
|
81
|
+
/** Unstyled root provider for a popover. */
|
|
82
|
+
var Popover = ({ children, class: classes, "data-slot": slot = "popover", closeDelay, defaultOpen, description, disabled, gap, label, onOpenChange, open, openDelay, openOn = "click", placement, ...attrs }) => openOn === "hover" ? /* @__PURE__ */ jsx(PopoverHoverRoot, {
|
|
83
|
+
...statefulRootAttrs(attrs),
|
|
84
|
+
closeDelay,
|
|
85
|
+
defaultOpen,
|
|
86
|
+
description,
|
|
87
|
+
disabled,
|
|
88
|
+
gap,
|
|
89
|
+
label,
|
|
90
|
+
onOpenChange,
|
|
91
|
+
open,
|
|
92
|
+
openDelay,
|
|
93
|
+
placement,
|
|
94
|
+
"attr:class": classes,
|
|
95
|
+
"attr:data-slot": slot,
|
|
96
|
+
children
|
|
97
|
+
}) : /* @__PURE__ */ jsx(PopoverClickRoot, {
|
|
98
|
+
...statefulRootAttrs(attrs),
|
|
99
|
+
defaultOpen,
|
|
100
|
+
description,
|
|
101
|
+
disabled,
|
|
102
|
+
gap,
|
|
103
|
+
label,
|
|
104
|
+
onOpenChange,
|
|
105
|
+
open,
|
|
106
|
+
placement,
|
|
107
|
+
"attr:class": classes,
|
|
108
|
+
"attr:data-slot": slot,
|
|
109
|
+
children
|
|
110
|
+
});
|
|
111
|
+
/** Unstyled button that opens a Popover. */
|
|
112
|
+
var PopoverTrigger = (args) => {
|
|
113
|
+
const popover = PopoverContext();
|
|
114
|
+
const all = args;
|
|
115
|
+
if (popover?.openOn === "hover") {
|
|
116
|
+
const { as = "button", children, class: classes, "data-slot": slot = "popover-trigger", disabled, id, ref, type = "button", "set:onblur": onBlur, "set:onfocus": onFocus, "set:onkeydown": onKeydown, "set:onmouseleave": onMouseLeave, "set:onmouseenter": onMouseEnter, ...attrs } = all;
|
|
117
|
+
const disabledFlag = Boolean(disabled ?? popover.disabled);
|
|
118
|
+
const common = {
|
|
119
|
+
...attrs,
|
|
120
|
+
...triggerAttrs({
|
|
121
|
+
controls: popover.contentId,
|
|
122
|
+
expanded: popover.open,
|
|
123
|
+
haspopup: "dialog",
|
|
124
|
+
id,
|
|
125
|
+
open: popover.open,
|
|
126
|
+
ref,
|
|
127
|
+
setTrigger: popover.setTrigger,
|
|
128
|
+
triggerId: popover.triggerId
|
|
129
|
+
}),
|
|
130
|
+
class: classes,
|
|
131
|
+
"data-slot": slot,
|
|
132
|
+
"set:onblur": (event) => {
|
|
133
|
+
callHandler(onBlur, event);
|
|
134
|
+
popover.registerTriggerFocus?.(false, event);
|
|
135
|
+
},
|
|
136
|
+
"set:onfocus": (event) => {
|
|
137
|
+
callHandler(onFocus, event);
|
|
138
|
+
if (event.defaultPrevented || disabledFlag) return;
|
|
139
|
+
popover.registerTriggerFocus?.(true, event);
|
|
140
|
+
},
|
|
141
|
+
"set:onkeydown": (event) => {
|
|
142
|
+
callHandler(onKeydown, event);
|
|
143
|
+
},
|
|
144
|
+
"set:onmouseleave": (event) => {
|
|
145
|
+
callHandler(onMouseLeave, event);
|
|
146
|
+
popover.registerTriggerHover?.(false, event);
|
|
147
|
+
},
|
|
148
|
+
"set:onmouseenter": (event) => {
|
|
149
|
+
callHandler(onMouseEnter, event);
|
|
150
|
+
if (event.defaultPrevented || disabledFlag) return;
|
|
151
|
+
popover.registerTriggerHover?.(true, event);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
if (as === "a") {
|
|
155
|
+
const anchor = attrs;
|
|
156
|
+
return /* @__PURE__ */ jsx("a", {
|
|
157
|
+
...common,
|
|
158
|
+
"aria-disabled": disabledFlag ? "true" : void 0,
|
|
159
|
+
href: disabledFlag ? void 0 : anchor.href,
|
|
160
|
+
tabIndex: disabledFlag ? -1 : anchor.tabIndex,
|
|
161
|
+
children
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (as === "span") return /* @__PURE__ */ jsx("span", {
|
|
165
|
+
...common,
|
|
166
|
+
"aria-disabled": disabledFlag ? "true" : void 0,
|
|
167
|
+
children
|
|
168
|
+
});
|
|
169
|
+
return /* @__PURE__ */ jsx("button", {
|
|
170
|
+
...common,
|
|
171
|
+
disabled: disabledFlag,
|
|
172
|
+
type,
|
|
173
|
+
children
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
const { children, "data-slot": slot = "popover-trigger", disabled, id, ref, type = "button", "set:onclick": onClick, ...attrs } = all;
|
|
177
|
+
const disabledFlag = Boolean(disabled ?? popover?.disabled);
|
|
178
|
+
return /* @__PURE__ */ jsx("button", {
|
|
179
|
+
...attrs,
|
|
180
|
+
...triggerAttrs({
|
|
181
|
+
controls: popover?.contentId,
|
|
182
|
+
expanded: Boolean(popover?.open),
|
|
183
|
+
haspopup: "dialog",
|
|
184
|
+
id,
|
|
185
|
+
open: Boolean(popover?.open),
|
|
186
|
+
ref,
|
|
187
|
+
setTrigger: popover?.setTrigger,
|
|
188
|
+
triggerId: popover?.triggerId
|
|
189
|
+
}),
|
|
190
|
+
"data-slot": slot,
|
|
191
|
+
disabled: disabledFlag,
|
|
192
|
+
"set:onclick": (event) => {
|
|
193
|
+
callHandler(onClick, event);
|
|
194
|
+
if (event.defaultPrevented) return;
|
|
195
|
+
popover?.setOpen(!popover.open, event);
|
|
196
|
+
},
|
|
197
|
+
type,
|
|
198
|
+
children
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
/** Optional explicit anchor used to position PopoverContent independently of the trigger. */
|
|
202
|
+
var PopoverAnchor = ({ children, class: classes, "data-slot": slot = "popover-anchor", ref, ...attrs }) => {
|
|
203
|
+
const popover = PopoverContext();
|
|
204
|
+
const reference = (element) => {
|
|
205
|
+
popover?.setReference(element);
|
|
206
|
+
callRef(ref, element);
|
|
207
|
+
};
|
|
208
|
+
return /* @__PURE__ */ jsx("div", {
|
|
209
|
+
...attrs,
|
|
210
|
+
class: classes,
|
|
211
|
+
"data-slot": slot,
|
|
212
|
+
ref: reference,
|
|
213
|
+
children
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
/** Unstyled floating panel for a Popover. */
|
|
217
|
+
var PopoverContent = (args) => {
|
|
218
|
+
const popover = PopoverContext();
|
|
219
|
+
const titleId = popover ? `${popover.contentId}-title` : void 0;
|
|
220
|
+
const descriptionId = popover?.description ? `${popover.contentId}-description` : void 0;
|
|
221
|
+
const heading = popover ? /* @__PURE__ */ jsxs("div", {
|
|
222
|
+
"data-slot": "popover-header",
|
|
223
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
224
|
+
"data-slot": "popover-title",
|
|
225
|
+
id: titleId,
|
|
226
|
+
children: popover.label
|
|
227
|
+
}), popover.description ? /* @__PURE__ */ jsx("p", {
|
|
228
|
+
"data-slot": "popover-description",
|
|
229
|
+
id: descriptionId,
|
|
230
|
+
children: popover.description
|
|
231
|
+
}) : null]
|
|
232
|
+
}) : null;
|
|
233
|
+
if (popover?.openOn === "hover") {
|
|
234
|
+
const { arrow = false, children, class: classes, "data-slot": slot = "popover-content", ref, style, "set:onfocusin": onFocusIn, "set:onfocusout": onFocusOut, "set:onmouseleave": onMouseLeave, "set:onmouseenter": onMouseEnter, ...attrs } = args;
|
|
235
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
236
|
+
...attrs,
|
|
237
|
+
...contentAttrs({
|
|
238
|
+
id: popover.contentId,
|
|
239
|
+
open: popover.open,
|
|
240
|
+
ref,
|
|
241
|
+
setContent: popover.setContent,
|
|
242
|
+
style: popover.contentStyle(style),
|
|
243
|
+
tabindex: "-1"
|
|
244
|
+
}),
|
|
245
|
+
"aria-describedby": descriptionId,
|
|
246
|
+
"aria-labelledby": titleId,
|
|
247
|
+
class: classes,
|
|
248
|
+
"data-arrow": arrow ? "true" : void 0,
|
|
249
|
+
"data-slot": slot,
|
|
250
|
+
role: "dialog",
|
|
251
|
+
"set:onfocusout": (event) => {
|
|
252
|
+
callHandler(onFocusOut, event);
|
|
253
|
+
const next = event.relatedTarget;
|
|
254
|
+
if (next && popover.content?.contains(next)) return;
|
|
255
|
+
popover.registerContentFocus?.(false, event);
|
|
256
|
+
},
|
|
257
|
+
"set:onfocusin": (event) => {
|
|
258
|
+
callHandler(onFocusIn, event);
|
|
259
|
+
popover.registerContentFocus?.(true, event);
|
|
260
|
+
},
|
|
261
|
+
"set:onmouseleave": (event) => {
|
|
262
|
+
callHandler(onMouseLeave, event);
|
|
263
|
+
popover.registerContentHover?.(false, event);
|
|
264
|
+
},
|
|
265
|
+
"set:onmouseenter": (event) => {
|
|
266
|
+
callHandler(onMouseEnter, event);
|
|
267
|
+
popover.registerContentHover?.(true, event);
|
|
268
|
+
},
|
|
269
|
+
children: [
|
|
270
|
+
/* @__PURE__ */ jsx(PopupSurface, {
|
|
271
|
+
arrow,
|
|
272
|
+
popup: popover
|
|
273
|
+
}),
|
|
274
|
+
heading,
|
|
275
|
+
children
|
|
276
|
+
]
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
const { arrow = false, children, class: classes, "data-slot": slot = "popover-content", ref, style, ...attrs } = args;
|
|
280
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
281
|
+
...attrs,
|
|
282
|
+
...contentAttrs({
|
|
283
|
+
id: popover?.contentId,
|
|
284
|
+
open: Boolean(popover?.open),
|
|
285
|
+
ref,
|
|
286
|
+
setContent: popover?.setContent,
|
|
287
|
+
style: popover?.contentStyle(style) ?? popupStyle(style),
|
|
288
|
+
tabindex: "-1"
|
|
289
|
+
}),
|
|
290
|
+
"aria-describedby": descriptionId,
|
|
291
|
+
"aria-labelledby": titleId,
|
|
292
|
+
class: classes,
|
|
293
|
+
"data-arrow": arrow ? "true" : void 0,
|
|
294
|
+
"data-slot": slot,
|
|
295
|
+
role: "dialog",
|
|
296
|
+
children: [
|
|
297
|
+
/* @__PURE__ */ jsx(PopupSurface, {
|
|
298
|
+
arrow,
|
|
299
|
+
popup: popover
|
|
300
|
+
}),
|
|
301
|
+
heading,
|
|
302
|
+
children
|
|
303
|
+
]
|
|
304
|
+
});
|
|
305
|
+
};
|
|
306
|
+
//#endregion
|
|
307
|
+
export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger };
|
package/dist/progress.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { toNumber } from "./utils.js";
|
|
2
|
+
import { clamp } from "ajo-cloves";
|
|
3
|
+
import { jsx } from "ajo/jsx-runtime";
|
|
4
|
+
//#region packages/ajo-ui/src/progress.tsx
|
|
5
|
+
var state = (value, max) => {
|
|
6
|
+
if (value == null) return "indeterminate";
|
|
7
|
+
if (value >= max) return "complete";
|
|
8
|
+
return "loading";
|
|
9
|
+
};
|
|
10
|
+
var percent = (value, max) => value == null || max <= 0 ? 0 : clamp(value / max * 100, 0, 100);
|
|
11
|
+
/** Unstyled progress bar with determinate and indeterminate states. */
|
|
12
|
+
var Progress = ({ "aria-label": ariaLabel, "aria-valuetext": ariaValueText, getValueLabel, indicatorClass, max = 100, role = "progressbar", value = null, ...attrs }) => {
|
|
13
|
+
const maxValue = Math.max(1, toNumber(max, 100));
|
|
14
|
+
const current = value == null ? null : clamp(toNumber(value, 0), 0, maxValue);
|
|
15
|
+
const progress = percent(current, maxValue);
|
|
16
|
+
const progressState = state(current, maxValue);
|
|
17
|
+
const valueText = current == null ? ariaValueText : ariaValueText ?? getValueLabel?.(current, maxValue);
|
|
18
|
+
return /* @__PURE__ */ jsx("div", {
|
|
19
|
+
...attrs,
|
|
20
|
+
"aria-label": ariaLabel,
|
|
21
|
+
"aria-valuemax": maxValue,
|
|
22
|
+
"aria-valuemin": "0",
|
|
23
|
+
"aria-valuenow": current == null ? void 0 : current,
|
|
24
|
+
"aria-valuetext": valueText,
|
|
25
|
+
"data-max": maxValue,
|
|
26
|
+
"data-slot": "progress",
|
|
27
|
+
"data-state": progressState,
|
|
28
|
+
"data-value": current == null ? void 0 : current,
|
|
29
|
+
role,
|
|
30
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
31
|
+
"aria-hidden": "true",
|
|
32
|
+
class: indicatorClass,
|
|
33
|
+
"data-slot": "progress-indicator",
|
|
34
|
+
style: current == null ? void 0 : `transform:translateX(-${100 - progress}%)`
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
export { Progress };
|