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,434 @@
1
+ import { dom } from "ajo-cloves";
2
+ import { arrow, autoPlacement, autoUpdate, computePosition, flip, hide, inline, limitShift, offset, shift, size } from "@floating-ui/dom";
3
+ //#region packages/ajo-ui/src/position.ts
4
+ /** Private zero-area virtual reference shared by point-positioned families. */
5
+ var pointReference = (contextElement, point) => ({
6
+ get contextElement() {
7
+ return typeof contextElement === "function" ? contextElement() : contextElement;
8
+ },
9
+ getBoundingClientRect: () => {
10
+ const { x, y } = point();
11
+ return {
12
+ x,
13
+ y,
14
+ top: y,
15
+ right: x,
16
+ bottom: y,
17
+ left: x,
18
+ width: 0,
19
+ height: 0
20
+ };
21
+ }
22
+ });
23
+ var policies = {
24
+ popover: {
25
+ placement: "bottom",
26
+ gap: 4,
27
+ padding: 8,
28
+ inline: true,
29
+ size: "both",
30
+ hidden: true
31
+ },
32
+ tooltip: {
33
+ placement: "top",
34
+ gap: 8,
35
+ padding: 8,
36
+ inline: true,
37
+ size: "width",
38
+ hidden: true,
39
+ fallbackAxisSideDirection: "start"
40
+ },
41
+ menu: {
42
+ placement: "bottom-start",
43
+ gap: 4,
44
+ padding: 4,
45
+ size: "both",
46
+ hidden: true
47
+ },
48
+ submenu: {
49
+ placement: "right-start",
50
+ gap: 4,
51
+ padding: 4,
52
+ size: "both",
53
+ hidden: true,
54
+ fallbackPlacements: ["left-start"]
55
+ },
56
+ select: {
57
+ placement: "bottom-start",
58
+ gap: 6,
59
+ padding: 8,
60
+ size: "both",
61
+ hidden: true
62
+ },
63
+ date: {
64
+ placement: "bottom-start",
65
+ gap: 6,
66
+ padding: 8,
67
+ size: "both",
68
+ hidden: true
69
+ },
70
+ navigation: {
71
+ placement: "bottom",
72
+ gap: 8,
73
+ padding: 8,
74
+ size: "both",
75
+ hidden: true
76
+ },
77
+ context: {
78
+ placement: "bottom-start",
79
+ gap: 2,
80
+ padding: 4,
81
+ size: "both",
82
+ hidden: true
83
+ },
84
+ menubar: {
85
+ placement: "bottom-start",
86
+ gap: 8,
87
+ padding: 4,
88
+ size: "both",
89
+ hidden: true,
90
+ crossAxis: -4
91
+ },
92
+ chart: {
93
+ placement: "right",
94
+ gap: 12,
95
+ padding: 8,
96
+ flipFirst: true,
97
+ writer: "transform"
98
+ }
99
+ };
100
+ var inactive = () => ({
101
+ start: async () => false,
102
+ update: async () => false,
103
+ stop() {}
104
+ });
105
+ var connected = (reference) => {
106
+ if (dom(reference)) return reference.isConnected;
107
+ return !reference.contextElement || reference.contextElement.isConnected;
108
+ };
109
+ var finite = (value, fallback) => Number.isFinite(value) ? Number(value) : fallback;
110
+ var round = (value, target) => {
111
+ const ratio = target.ownerDocument.defaultView?.devicePixelRatio || 1;
112
+ return Math.round(value * ratio) / ratio;
113
+ };
114
+ var parts = (placement) => {
115
+ const [side, align = "center"] = placement.split("-");
116
+ return {
117
+ side,
118
+ align
119
+ };
120
+ };
121
+ var overflow$1 = (padding, boundary) => ({
122
+ padding,
123
+ ...boundary ? { boundary } : {}
124
+ });
125
+ var middleware = (policy, preferred, gap, boundary, referenceBoundary, arrow$1, applySize) => {
126
+ const detect = overflow$1(policy.padding, boundary);
127
+ const aligned = (preferred === "auto" ? policy.placement : preferred).includes("-");
128
+ const move = shift({
129
+ ...detect,
130
+ limiter: limitShift()
131
+ });
132
+ const fallback = flip({
133
+ ...detect,
134
+ fallbackAxisSideDirection: policy.fallbackAxisSideDirection ?? "end",
135
+ ...policy.fallbackPlacements ? { fallbackPlacements: policy.fallbackPlacements } : {}
136
+ });
137
+ const collision = preferred === "auto" ? [autoPlacement(detect), move] : aligned || policy.flipFirst ? [fallback, move] : [move, fallback];
138
+ const result = [];
139
+ if (policy.inline) result.push(inline());
140
+ result.push(offset({
141
+ mainAxis: gap,
142
+ crossAxis: policy.crossAxis ?? 0
143
+ }));
144
+ result.push(...collision);
145
+ if (policy.size) result.push(size({
146
+ ...detect,
147
+ apply({ availableHeight, availableWidth, elements, rects }) {
148
+ applySize(availableHeight, availableWidth, elements.floating, rects.reference.height, rects.reference.width);
149
+ }
150
+ }));
151
+ if (arrow$1) result.push(arrow({
152
+ element: arrow$1,
153
+ padding: 8
154
+ }));
155
+ if (policy.hidden) {
156
+ result.push(hide(overflow$1(policy.padding, referenceBoundary ?? boundary)));
157
+ result.push(hide({
158
+ ...detect,
159
+ strategy: "escaped"
160
+ }));
161
+ }
162
+ return result;
163
+ };
164
+ var clearArrow = (arrow) => {
165
+ if (!arrow) return;
166
+ arrow.style.left = "";
167
+ arrow.style.right = "";
168
+ arrow.style.top = "";
169
+ arrow.style.bottom = "";
170
+ delete arrow.dataset.arrowUncentered;
171
+ };
172
+ var deactivateFloating = (floating, profile) => {
173
+ if (profile === "chart") {
174
+ delete floating.dataset.positioned;
175
+ floating.style.transform = "";
176
+ }
177
+ floating.style.willChange = "";
178
+ };
179
+ var resetFloating = (floating, profile) => {
180
+ deactivateFloating(floating, profile);
181
+ floating.style.position = "";
182
+ floating.style.left = "";
183
+ floating.style.top = "";
184
+ floating.style.transformOrigin = "";
185
+ floating.style.boxSizing = "";
186
+ floating.style.maxWidth = "";
187
+ floating.style.maxHeight = "";
188
+ floating.style.removeProperty("--reference-width");
189
+ floating.style.removeProperty("--reference-height");
190
+ floating.style.removeProperty("--available-width");
191
+ floating.style.removeProperty("--available-height");
192
+ floating.style.removeProperty("--popup-arrow-center");
193
+ delete floating.dataset.placement;
194
+ delete floating.dataset.side;
195
+ delete floating.dataset.align;
196
+ delete floating.dataset.referenceHidden;
197
+ delete floating.dataset.escaped;
198
+ };
199
+ var sizeState = (element) => ({
200
+ boxSizing: element.style.boxSizing,
201
+ maxWidth: element.style.maxWidth,
202
+ maxHeight: element.style.maxHeight,
203
+ referenceWidth: element.style.getPropertyValue("--reference-width"),
204
+ referenceHeight: element.style.getPropertyValue("--reference-height"),
205
+ availableWidth: element.style.getPropertyValue("--available-width"),
206
+ availableHeight: element.style.getPropertyValue("--available-height")
207
+ });
208
+ var restoreSize = (element, state) => {
209
+ element.style.boxSizing = state.boxSizing;
210
+ element.style.maxWidth = state.maxWidth;
211
+ element.style.maxHeight = state.maxHeight;
212
+ element.style.setProperty("--reference-width", state.referenceWidth);
213
+ element.style.setProperty("--reference-height", state.referenceHeight);
214
+ element.style.setProperty("--available-width", state.availableWidth);
215
+ element.style.setProperty("--available-height", state.availableHeight);
216
+ };
217
+ var origin = (target, side, align) => {
218
+ const rtl = (side === "top" || side === "bottom") && target.ownerDocument.defaultView?.getComputedStyle(target).direction === "rtl";
219
+ const cross = align === "center" ? "50%" : align === "start" ? rtl ? "100%" : "0%" : rtl ? "0%" : "100%";
220
+ return side === "top" ? `${cross} 100%` : side === "right" ? `0% ${cross}` : side === "bottom" ? `${cross} 0%` : `100% ${cross}`;
221
+ };
222
+ /** Private Floating UI Adapter shared by popup families and Chart. */
223
+ var position = (host, options) => {
224
+ if (!dom(host) || !host.ownerDocument.defaultView) return inactive();
225
+ const policy = policies[options.profile];
226
+ let active = false;
227
+ let cleanup;
228
+ let current;
229
+ let generation = 0;
230
+ let hidden;
231
+ let pending;
232
+ let pendingGeneration = -1;
233
+ let requested = 0;
234
+ let sizeGeneration = -1;
235
+ let sizeRestore;
236
+ const rollbackSize = (scope = sizeGeneration) => {
237
+ if (scope !== sizeGeneration) return;
238
+ const restore = sizeRestore;
239
+ sizeGeneration = -1;
240
+ sizeRestore = void 0;
241
+ restore?.();
242
+ };
243
+ const commitSize = (scope) => {
244
+ if (scope !== sizeGeneration) return;
245
+ sizeGeneration = -1;
246
+ sizeRestore = void 0;
247
+ };
248
+ const stopScope = () => {
249
+ const dispose = cleanup;
250
+ active = false;
251
+ generation++;
252
+ requested++;
253
+ cleanup = void 0;
254
+ pending = void 0;
255
+ pendingGeneration = -1;
256
+ rollbackSize();
257
+ if (current?.floating) deactivateFloating(current.floating, options.profile);
258
+ try {
259
+ dispose?.();
260
+ } catch (error) {
261
+ host.throw(error);
262
+ }
263
+ };
264
+ const valid = (version, elements) => active && version === generation && current?.reference === elements.reference && current.floating === elements.floating && current.arrow === elements.arrow && !host.signal.aborted && Boolean(elements.floating?.isConnected) && Boolean(elements.reference && connected(elements.reference));
265
+ const currentRequest = (scope, request, elements) => request === requested && valid(scope, elements);
266
+ const commit = (elements, result) => {
267
+ const target = elements.floating;
268
+ const { side, align } = parts(result.placement);
269
+ const x = round(result.x, target);
270
+ const y = round(result.y, target);
271
+ if (policy.writer === "transform") {
272
+ target.style.position = "absolute";
273
+ target.style.left = "0px";
274
+ target.style.top = "0px";
275
+ target.style.transform = `translate(${x}px, ${y}px)`;
276
+ target.style.willChange = "transform";
277
+ if (target.dataset.positioned !== "true") {
278
+ target.getBoundingClientRect();
279
+ target.dataset.positioned = "true";
280
+ }
281
+ } else {
282
+ target.style.position = "fixed";
283
+ target.style.left = `${x}px`;
284
+ target.style.top = `${y}px`;
285
+ }
286
+ target.dataset.placement = result.placement;
287
+ target.dataset.side = side;
288
+ target.dataset.align = align;
289
+ const hiddenData = result.middlewareData.hide;
290
+ const referenceHidden = Boolean(hiddenData?.referenceHidden);
291
+ const escaped = Boolean(hiddenData?.escaped);
292
+ if (referenceHidden) target.dataset.referenceHidden = "true";
293
+ else delete target.dataset.referenceHidden;
294
+ if (escaped) target.dataset.escaped = "true";
295
+ else delete target.dataset.escaped;
296
+ const notifyHidden = hidden !== referenceHidden;
297
+ hidden = referenceHidden;
298
+ const arrow = elements.arrow;
299
+ const arrowData = result.middlewareData.arrow;
300
+ clearArrow(arrow);
301
+ target.style.removeProperty("--popup-arrow-center");
302
+ if (policy.writer === "transform") target.style.transformOrigin = "";
303
+ else if (arrow && arrowData) {
304
+ if (arrowData.x != null) arrow.style.left = `${round(arrowData.x, target)}px`;
305
+ if (arrowData.y != null) arrow.style.top = `${round(arrowData.y, target)}px`;
306
+ const staticSide = side === "top" ? "bottom" : side === "right" ? "left" : side === "bottom" ? "top" : "right";
307
+ const arrowSize = side === "top" || side === "bottom" ? arrow.offsetHeight : arrow.offsetWidth;
308
+ arrow.style[staticSide] = `${round(-arrowSize / 2, target)}px`;
309
+ if (arrowData.centerOffset !== 0) arrow.dataset.arrowUncentered = "true";
310
+ const center = side === "top" || side === "bottom" ? `${round((arrowData.x ?? 0) + arrow.offsetWidth / 2, target)}px` : `${round((arrowData.y ?? 0) + arrow.offsetHeight / 2, target)}px`;
311
+ target.style.setProperty("--popup-arrow-center", center);
312
+ target.style.transformOrigin = side === "top" ? `${center} bottom` : side === "right" ? `left ${center}` : side === "bottom" ? `${center} top` : `right ${center}`;
313
+ } else target.style.transformOrigin = origin(target, side, align);
314
+ return notifyHidden ? referenceHidden : void 0;
315
+ };
316
+ const calculate = async (scope, request) => {
317
+ const elements = current;
318
+ if (!elements?.reference || !elements.floating) return false;
319
+ const initialSize = sizeState(elements.floating);
320
+ const preferred = options.placement?.() ?? policy.placement;
321
+ const placement = preferred === "auto" ? policy.placement : preferred;
322
+ try {
323
+ const result = await computePosition(elements.reference, elements.floating, {
324
+ placement,
325
+ strategy: policy.writer === "transform" ? "absolute" : "fixed",
326
+ middleware: middleware(policy, preferred, finite(options.gap?.(), policy.gap), options.boundary?.() ?? null, options.referenceBoundary?.() ?? null, elements.arrow, (availableHeight, availableWidth, target, referenceHeight, referenceWidth) => {
327
+ if (!currentRequest(scope, request, elements) || target !== elements.floating) return;
328
+ if (sizeGeneration !== scope) {
329
+ rollbackSize();
330
+ sizeGeneration = scope;
331
+ sizeRestore = () => restoreSize(target, initialSize);
332
+ }
333
+ const height = Math.max(0, availableHeight);
334
+ const width = Math.max(0, availableWidth);
335
+ target.style.boxSizing = "border-box";
336
+ target.style.maxWidth = `${width}px`;
337
+ if (policy.size === "both") target.style.maxHeight = `${height}px`;
338
+ target.style.setProperty("--reference-width", `${referenceWidth}px`);
339
+ target.style.setProperty("--reference-height", `${referenceHeight}px`);
340
+ target.style.setProperty("--available-width", `${width}px`);
341
+ target.style.setProperty("--available-height", `${height}px`);
342
+ })
343
+ });
344
+ if (!currentRequest(scope, request, elements)) {
345
+ rollbackSize(scope);
346
+ return false;
347
+ }
348
+ const referenceHidden = commit(elements, result);
349
+ commitSize(scope);
350
+ if (referenceHidden !== void 0) options.referenceHidden?.(referenceHidden);
351
+ return true;
352
+ } catch (error) {
353
+ rollbackSize(scope);
354
+ if (!currentRequest(scope, request, elements)) return false;
355
+ throw error;
356
+ }
357
+ };
358
+ const drain = async (scope) => {
359
+ let committed = false;
360
+ while (active && generation === scope) {
361
+ const expected = requested;
362
+ committed = await calculate(scope, expected);
363
+ if (expected === requested) break;
364
+ }
365
+ return committed;
366
+ };
367
+ const update = () => {
368
+ if (!active) return Promise.resolve(false);
369
+ requested++;
370
+ const scope = generation;
371
+ if (pending && pendingGeneration === scope) {
372
+ rollbackSize(scope);
373
+ return pending;
374
+ }
375
+ const task = drain(scope);
376
+ pending = task;
377
+ pendingGeneration = scope;
378
+ const clear = () => {
379
+ if (pending !== task) return;
380
+ pending = void 0;
381
+ pendingGeneration = -1;
382
+ };
383
+ task.then(clear, clear);
384
+ return task;
385
+ };
386
+ const fail = (error) => {
387
+ if (host.signal.aborted) return;
388
+ queueMicrotask(() => {
389
+ if (!host.signal.aborted) host.throw(error);
390
+ });
391
+ };
392
+ const stop = () => {
393
+ stopScope();
394
+ hidden = void 0;
395
+ };
396
+ const start = async () => {
397
+ if (host.signal.aborted) {
398
+ stop();
399
+ return false;
400
+ }
401
+ const next = options.elements();
402
+ if (!next.reference || !next.floating || !next.floating.isConnected || !connected(next.reference)) {
403
+ stop();
404
+ return false;
405
+ }
406
+ const previous = current;
407
+ stopScope();
408
+ if (previous?.arrow !== next.arrow) clearArrow(previous?.arrow ?? null);
409
+ if (previous?.floating && previous.floating !== next.floating) resetFloating(previous.floating, options.profile);
410
+ current = next;
411
+ active = true;
412
+ hidden = void 0;
413
+ requested = 0;
414
+ try {
415
+ let starting = true;
416
+ cleanup = autoUpdate(next.reference, next.floating, () => {
417
+ if (!starting) update().catch(fail);
418
+ });
419
+ starting = false;
420
+ return await update();
421
+ } catch (error) {
422
+ stop();
423
+ throw error;
424
+ }
425
+ };
426
+ host.signal.addEventListener("abort", stop, { once: true });
427
+ return {
428
+ start,
429
+ stop,
430
+ update
431
+ };
432
+ };
433
+ //#endregion
434
+ export { position as n, pointReference as t };