@sprawlify/primitives 0.0.97 → 0.0.98

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 (107) hide show
  1. package/dist/{collection-DZeodezM.cjs → collection-BBgC8xCb.cjs} +22 -7
  2. package/dist/{collection-CcsrqDFY.mjs → collection-DgzidRvr.mjs} +22 -7
  3. package/dist/collection.cjs +1 -1
  4. package/dist/collection.d.cts +3 -3
  5. package/dist/collection.d.mts +3 -3
  6. package/dist/collection.mjs +1 -1
  7. package/dist/dom-query.d.cts +1 -1
  8. package/dist/dom-query.d.mts +1 -1
  9. package/dist/{i18n-utils-DHGN_KCY.mjs → i18n-utils-BsXTdcWB.mjs} +52 -1
  10. package/dist/{i18n-utils-Dm8cGCol.cjs → i18n-utils-bHwTSOWi.cjs} +57 -0
  11. package/dist/i18n-utils.cjs +2 -1
  12. package/dist/i18n-utils.d.cts +14 -1
  13. package/dist/i18n-utils.d.mts +14 -1
  14. package/dist/i18n-utils.mjs +2 -2
  15. package/dist/{list-collection-DkRA5LOq.d.mts → list-collection-AgReIMJ0.d.mts} +1 -1
  16. package/dist/{list-collection-B_8BN0XB.d.cts → list-collection-C0swT4Wu.d.cts} +1 -1
  17. package/dist/machines/accordion/index.d.cts +1 -1
  18. package/dist/machines/accordion/index.d.mts +1 -1
  19. package/dist/machines/angle-slider/index.d.cts +1 -1
  20. package/dist/machines/angle-slider/index.d.mts +1 -1
  21. package/dist/machines/bottom-sheet/index.d.cts +1 -1
  22. package/dist/machines/bottom-sheet/index.d.mts +1 -1
  23. package/dist/machines/carousel/index.d.cts +1 -1
  24. package/dist/machines/carousel/index.d.mts +1 -1
  25. package/dist/machines/cascade-select/index.cjs +1367 -0
  26. package/dist/machines/cascade-select/index.d.cts +164 -0
  27. package/dist/machines/cascade-select/index.d.mts +164 -0
  28. package/dist/machines/cascade-select/index.mjs +1360 -0
  29. package/dist/machines/clipboard/index.d.cts +1 -1
  30. package/dist/machines/clipboard/index.d.mts +1 -1
  31. package/dist/machines/collapsible/index.d.cts +1 -1
  32. package/dist/machines/collapsible/index.d.mts +1 -1
  33. package/dist/machines/color-picker/index.d.cts +1 -1
  34. package/dist/machines/color-picker/index.d.mts +1 -1
  35. package/dist/machines/combobox/index.cjs +2 -2
  36. package/dist/machines/combobox/index.d.cts +2 -2
  37. package/dist/machines/combobox/index.d.mts +2 -2
  38. package/dist/machines/combobox/index.mjs +2 -2
  39. package/dist/machines/date-picker/index.d.cts +1 -1
  40. package/dist/machines/date-picker/index.d.mts +1 -1
  41. package/dist/machines/dialog/index.d.cts +1 -1
  42. package/dist/machines/dialog/index.d.mts +1 -1
  43. package/dist/machines/dropdown-menu/index.d.cts +1 -1
  44. package/dist/machines/dropdown-menu/index.d.mts +1 -1
  45. package/dist/machines/editable/index.d.cts +1 -1
  46. package/dist/machines/editable/index.d.mts +1 -1
  47. package/dist/machines/file-upload/index.cjs +1 -1
  48. package/dist/machines/file-upload/index.d.cts +1 -1
  49. package/dist/machines/file-upload/index.d.mts +1 -1
  50. package/dist/machines/file-upload/index.mjs +1 -1
  51. package/dist/machines/floating-panel/index.d.cts +1 -1
  52. package/dist/machines/floating-panel/index.d.mts +1 -1
  53. package/dist/machines/hover-card/index.d.cts +1 -1
  54. package/dist/machines/hover-card/index.d.mts +1 -1
  55. package/dist/machines/listbox/index.cjs +1 -1
  56. package/dist/machines/listbox/index.d.cts +3 -3
  57. package/dist/machines/listbox/index.d.mts +3 -3
  58. package/dist/machines/listbox/index.mjs +1 -1
  59. package/dist/machines/marquee/index.d.cts +3 -3
  60. package/dist/machines/marquee/index.d.mts +3 -3
  61. package/dist/machines/navigation-menu/index.d.cts +1 -1
  62. package/dist/machines/navigation-menu/index.d.mts +1 -1
  63. package/dist/machines/number-input/index.d.cts +1 -1
  64. package/dist/machines/number-input/index.d.mts +1 -1
  65. package/dist/machines/password-input/index.d.cts +1 -1
  66. package/dist/machines/password-input/index.d.mts +1 -1
  67. package/dist/machines/pin-input/index.d.cts +1 -1
  68. package/dist/machines/pin-input/index.d.mts +1 -1
  69. package/dist/machines/popover/index.d.cts +1 -1
  70. package/dist/machines/popover/index.d.mts +1 -1
  71. package/dist/machines/progress/index.d.cts +1 -1
  72. package/dist/machines/progress/index.d.mts +1 -1
  73. package/dist/machines/radio-group/index.d.cts +1 -1
  74. package/dist/machines/radio-group/index.d.mts +1 -1
  75. package/dist/machines/rating-group/index.d.cts +1 -1
  76. package/dist/machines/rating-group/index.d.mts +1 -1
  77. package/dist/machines/scroll-area/index.d.cts +1 -1
  78. package/dist/machines/scroll-area/index.d.mts +1 -1
  79. package/dist/machines/select/index.cjs +1 -1
  80. package/dist/machines/select/index.d.cts +2 -2
  81. package/dist/machines/select/index.d.mts +2 -2
  82. package/dist/machines/select/index.mjs +1 -1
  83. package/dist/machines/slider/index.d.cts +1 -1
  84. package/dist/machines/slider/index.d.mts +1 -1
  85. package/dist/machines/steps/index.d.cts +1 -1
  86. package/dist/machines/steps/index.d.mts +1 -1
  87. package/dist/machines/tabs/index.d.cts +1 -1
  88. package/dist/machines/tabs/index.d.mts +1 -1
  89. package/dist/machines/tags-input/index.d.cts +1 -1
  90. package/dist/machines/tags-input/index.d.mts +1 -1
  91. package/dist/machines/timer/index.d.cts +1 -1
  92. package/dist/machines/timer/index.d.mts +1 -1
  93. package/dist/machines/toast/index.d.cts +1 -1
  94. package/dist/machines/toast/index.d.mts +1 -1
  95. package/dist/machines/tooltip/index.d.cts +1 -1
  96. package/dist/machines/tooltip/index.d.mts +1 -1
  97. package/dist/machines/tour/index.d.cts +1 -1
  98. package/dist/machines/tour/index.d.mts +1 -1
  99. package/dist/machines/tree-view/index.cjs +1 -1
  100. package/dist/machines/tree-view/index.d.cts +2 -2
  101. package/dist/machines/tree-view/index.d.mts +2 -2
  102. package/dist/machines/tree-view/index.mjs +1 -1
  103. package/dist/{selection-DdNvrKbj.d.mts → selection-aObDFAzS.d.mts} +1 -1
  104. package/dist/{selection-Bb_ZSVxe.d.cts → selection-k8FM_y4w.d.cts} +1 -1
  105. package/dist/{tree-collection-DlBCued7.d.mts → tree-collection-Dlf9EUrT.d.mts} +2 -1
  106. package/dist/{tree-collection-DjtppzYh.d.cts → tree-collection-DlqV5kYO.d.cts} +2 -1
  107. package/package.json +11 -1
@@ -0,0 +1,1360 @@
1
+ import { t as createAnatomy } from "../../create-anatomy-Dr0evdYy.mjs";
2
+ import { C as queryAll, I as scrollIntoView, K as isValidTabEvent, W as raf, cn as isEditableElement, it as dispatchInputValueEvent, ot as setElementValue, p as createScope, st as trackFormControl, ut as getEventKey, vn as ariaAttr, wt as isSelfTarget, yn as dataAttr, z as observeAttributes } from "../../dom-query-dX8Dakb4.mjs";
3
+ import { Ct as isEmpty, ft as isEqual, u as createSplitProps, wt as last } from "../../utils-VVoZ_v29.mjs";
4
+ import { t as TreeCollection } from "../../collection-DgzidRvr.mjs";
5
+ import { a as createMachine, i as createGuards } from "../../core-DfVajPnu.mjs";
6
+ import "../../interact-outside-C-8lOhpV.mjs";
7
+ import { n as trackDismissableElement } from "../../dismissable-BAYaXwxZ.mjs";
8
+ import { n as getPlacement, t as getPlacementStyles } from "../../popper-CfOHZlHP.mjs";
9
+ import { B as getRectCorners, D as closestSideToPoint, L as createPoint, R as createRect, i as isPointInPolygon } from "../../rect-utils-B5xqFvKC.mjs";
10
+ import { t as createProps } from "../../create-props-DFW8DUsC.mjs";
11
+ //#region src/machines/cascade-select/cascade-select.anatomy.ts
12
+ const anatomy = createAnatomy("cascade-select").parts("root", "label", "control", "trigger", "indicator", "valueText", "clearTrigger", "positioner", "content", "list", "item", "itemText", "itemIndicator");
13
+ const parts = anatomy.build();
14
+ //#endregion
15
+ //#region src/machines/cascade-select/cascade-select.collection.ts
16
+ const collection = (options) => {
17
+ return new TreeCollection(options);
18
+ };
19
+ collection.empty = () => {
20
+ return new TreeCollection({ rootNode: {
21
+ value: "ROOT",
22
+ children: []
23
+ } });
24
+ };
25
+ //#endregion
26
+ //#region src/machines/cascade-select/cascade-select.dom.ts
27
+ const dom = createScope({
28
+ getRootId: (ctx) => ctx.ids?.root ?? `cascade-select:${ctx.id}`,
29
+ getLabelId: (ctx) => ctx.ids?.label ?? `cascade-select:${ctx.id}:label`,
30
+ getControlId: (ctx) => ctx.ids?.control ?? `cascade-select:${ctx.id}:control`,
31
+ getTriggerId: (ctx) => ctx.ids?.trigger ?? `cascade-select:${ctx.id}:trigger`,
32
+ getIndicatorId: (ctx) => ctx.ids?.indicator ?? `cascade-select:${ctx.id}:indicator`,
33
+ getClearTriggerId: (ctx) => ctx.ids?.clearTrigger ?? `cascade-select:${ctx.id}:clear-trigger`,
34
+ getPositionerId: (ctx) => ctx.ids?.positioner ?? `cascade-select:${ctx.id}:positioner`,
35
+ getContentId: (ctx) => ctx.ids?.content ?? `cascade-select:${ctx.id}:content`,
36
+ getHiddenInputId: (ctx) => ctx.ids?.hiddenInput ?? `cascade-select:${ctx.id}:hidden-input`,
37
+ getListId: (ctx, value) => ctx.ids?.list?.(value) ?? `cascade-select:${ctx.id}:list:${value}`,
38
+ getItemId: (ctx, value) => ctx.ids?.item?.(value) ?? `cascade-select:${ctx.id}:item:${value}`,
39
+ getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
40
+ getLabelEl: (ctx) => dom.getById(ctx, dom.getLabelId(ctx)),
41
+ getControlEl: (ctx) => dom.getById(ctx, dom.getControlId(ctx)),
42
+ getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
43
+ getIndicatorEl: (ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),
44
+ getClearTriggerEl: (ctx) => dom.getById(ctx, dom.getClearTriggerId(ctx)),
45
+ getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
46
+ getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
47
+ getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx)),
48
+ getListEl: (ctx, value) => dom.getById(ctx, dom.getListId(ctx, value)),
49
+ getListEls: (ctx) => queryAll(dom.getContentEl(ctx), `[data-part="list"]`),
50
+ getItemEl: (ctx, value) => dom.getById(ctx, dom.getItemId(ctx, value)),
51
+ dispatchInputEvent: (ctx, value) => {
52
+ const inputEl = dom.getHiddenInputEl(ctx);
53
+ if (!inputEl) return;
54
+ dispatchInputValueEvent(inputEl, { value });
55
+ }
56
+ });
57
+ //#endregion
58
+ //#region src/machines/cascade-select/cascade-select.connect.ts
59
+ function connect(service, normalize) {
60
+ const { send, context, prop, scope, computed, state } = service;
61
+ const collection = prop("collection");
62
+ const value = context.get("value");
63
+ const open = state.hasTag("open");
64
+ const focused = state.matches("focused");
65
+ const highlightedIndexPath = context.get("highlightedIndexPath");
66
+ const highlightedValue = context.get("highlightedValue");
67
+ const currentPlacement = context.get("currentPlacement");
68
+ const disabled = prop("disabled") || context.get("fieldsetDisabled");
69
+ const interactive = computed("isInteractive");
70
+ const valueAsString = computed("valueAsString");
71
+ const highlightedItem = context.get("highlightedItem");
72
+ const selectedItems = context.get("selectedItems");
73
+ const popperStyles = getPlacementStyles({
74
+ ...prop("positioning"),
75
+ placement: currentPlacement
76
+ });
77
+ const getItemState = (props) => {
78
+ const { item, indexPath, value: itemValue } = props;
79
+ const depth = indexPath ? indexPath.length : 0;
80
+ const highlighted = itemValue.every((v, i) => v === highlightedValue[i]);
81
+ const selected = value.some((v) => isEqual(v, itemValue));
82
+ const highlightedChild = collection.getNodeChildren(collection.at(indexPath))[highlightedIndexPath[depth]];
83
+ const highlightedIndex = highlightedIndexPath[depth];
84
+ return {
85
+ value: itemValue,
86
+ disabled: collection.getNodeDisabled(item),
87
+ highlighted,
88
+ selected,
89
+ hasChildren: collection.isBranchNode(item),
90
+ depth,
91
+ highlightedChild,
92
+ highlightedIndex
93
+ };
94
+ };
95
+ const hasSelectedItems = value.length > 0;
96
+ return {
97
+ collection,
98
+ open,
99
+ focused,
100
+ multiple: !!prop("multiple"),
101
+ disabled,
102
+ value,
103
+ highlightedValue,
104
+ highlightedItem,
105
+ selectedItems,
106
+ hasSelectedItems,
107
+ valueAsString,
108
+ reposition(options = {}) {
109
+ send({
110
+ type: "POSITIONING.SET",
111
+ options
112
+ });
113
+ },
114
+ focus() {
115
+ dom.getTriggerEl(scope)?.focus({ preventScroll: true });
116
+ },
117
+ setOpen(nextOpen) {
118
+ if (nextOpen === open) return;
119
+ send({ type: nextOpen ? "OPEN" : "CLOSE" });
120
+ },
121
+ highlightValue(value) {
122
+ send({
123
+ type: "HIGHLIGHTED_VALUE.SET",
124
+ value
125
+ });
126
+ },
127
+ setValue(value) {
128
+ send({
129
+ type: "VALUE.SET",
130
+ value
131
+ });
132
+ },
133
+ selectValue(value) {
134
+ send({
135
+ type: "ITEM.SELECT",
136
+ value
137
+ });
138
+ },
139
+ clearValue(value) {
140
+ if (value) send({
141
+ type: "ITEM.CLEAR",
142
+ value
143
+ });
144
+ else send({ type: "VALUE.CLEAR" });
145
+ },
146
+ getItemState,
147
+ getRootProps() {
148
+ return normalize.element({
149
+ ...parts.root.attrs,
150
+ id: dom.getRootId(scope),
151
+ dir: prop("dir"),
152
+ "data-disabled": dataAttr(disabled),
153
+ "data-readonly": dataAttr(prop("readOnly")),
154
+ "data-invalid": dataAttr(prop("invalid")),
155
+ "data-state": open ? "open" : "closed"
156
+ });
157
+ },
158
+ getLabelProps() {
159
+ return normalize.label({
160
+ ...parts.label.attrs,
161
+ id: dom.getLabelId(scope),
162
+ dir: prop("dir"),
163
+ htmlFor: dom.getHiddenInputId(scope),
164
+ "data-disabled": dataAttr(disabled),
165
+ "data-readonly": dataAttr(prop("readOnly")),
166
+ "data-invalid": dataAttr(prop("invalid")),
167
+ onClick(event) {
168
+ if (event.defaultPrevented) return;
169
+ if (disabled) return;
170
+ dom.getTriggerEl(scope)?.focus({ preventScroll: true });
171
+ }
172
+ });
173
+ },
174
+ getControlProps() {
175
+ return normalize.element({
176
+ ...parts.control.attrs,
177
+ dir: prop("dir"),
178
+ id: dom.getControlId(scope),
179
+ "data-disabled": dataAttr(disabled),
180
+ "data-focused": dataAttr(focused),
181
+ "data-readonly": dataAttr(prop("readOnly")),
182
+ "data-invalid": dataAttr(prop("invalid")),
183
+ "data-state": open ? "open" : "closed"
184
+ });
185
+ },
186
+ getTriggerProps() {
187
+ return normalize.button({
188
+ ...parts.trigger.attrs,
189
+ dir: prop("dir"),
190
+ id: dom.getTriggerId(scope),
191
+ type: "button",
192
+ role: "combobox",
193
+ "aria-controls": dom.getContentId(scope),
194
+ "aria-expanded": open,
195
+ "aria-haspopup": "listbox",
196
+ "aria-labelledby": dom.getLabelId(scope),
197
+ "data-state": open ? "open" : "closed",
198
+ "data-disabled": dataAttr(disabled),
199
+ "data-readonly": dataAttr(prop("readOnly")),
200
+ "data-invalid": dataAttr(prop("invalid")),
201
+ "data-focused": dataAttr(focused),
202
+ "data-placement": currentPlacement,
203
+ disabled,
204
+ onClick(event) {
205
+ if (event.defaultPrevented) return;
206
+ if (!interactive) return;
207
+ send({ type: "TRIGGER.CLICK" });
208
+ },
209
+ onFocus() {
210
+ send({ type: "TRIGGER.FOCUS" });
211
+ },
212
+ onBlur() {
213
+ send({ type: "TRIGGER.BLUR" });
214
+ },
215
+ onKeyDown(event) {
216
+ if (event.defaultPrevented) return;
217
+ if (!interactive) return;
218
+ const exec = {
219
+ ArrowUp() {
220
+ send({ type: "TRIGGER.ARROW_UP" });
221
+ },
222
+ ArrowDown(event) {
223
+ send({ type: event.altKey ? "OPEN" : "TRIGGER.ARROW_DOWN" });
224
+ },
225
+ ArrowLeft() {
226
+ send({ type: "TRIGGER.ARROW_LEFT" });
227
+ },
228
+ ArrowRight() {
229
+ send({ type: "TRIGGER.ARROW_RIGHT" });
230
+ },
231
+ Enter() {
232
+ send({ type: "TRIGGER.ENTER" });
233
+ },
234
+ Space() {
235
+ send({ type: "TRIGGER.ENTER" });
236
+ }
237
+ }[getEventKey(event, { dir: prop("dir") })];
238
+ if (exec) {
239
+ exec(event);
240
+ event.preventDefault();
241
+ }
242
+ }
243
+ });
244
+ },
245
+ getClearTriggerProps() {
246
+ return normalize.button({
247
+ ...parts.clearTrigger.attrs,
248
+ dir: prop("dir"),
249
+ id: dom.getClearTriggerId(scope),
250
+ type: "button",
251
+ "aria-label": "Clear value",
252
+ hidden: !hasSelectedItems,
253
+ "data-disabled": dataAttr(disabled),
254
+ "data-readonly": dataAttr(prop("readOnly")),
255
+ "data-invalid": dataAttr(prop("invalid")),
256
+ disabled,
257
+ onClick(event) {
258
+ if (event.defaultPrevented) return;
259
+ send({ type: "CLEAR_TRIGGER.CLICK" });
260
+ }
261
+ });
262
+ },
263
+ getPositionerProps() {
264
+ return normalize.element({
265
+ ...parts.positioner.attrs,
266
+ dir: prop("dir"),
267
+ id: dom.getPositionerId(scope),
268
+ style: popperStyles.floating
269
+ });
270
+ },
271
+ getContentProps() {
272
+ const highlightedItemId = highlightedValue ? dom.getItemId(scope, highlightedValue.toString()) : void 0;
273
+ return normalize.element({
274
+ ...parts.content.attrs,
275
+ id: dom.getContentId(scope),
276
+ role: "listbox",
277
+ "aria-labelledby": dom.getLabelId(scope),
278
+ "aria-activedescendant": highlightedItemId,
279
+ "data-activedescendant": highlightedItemId,
280
+ "data-state": open ? "open" : "closed",
281
+ "aria-multiselectable": prop("multiple"),
282
+ "aria-required": prop("required"),
283
+ "aria-readonly": prop("readOnly"),
284
+ hidden: !open,
285
+ tabIndex: 0,
286
+ onKeyDown(event) {
287
+ if (!interactive) return;
288
+ if (!isSelfTarget(event)) return;
289
+ if (event.key === "Tab") {
290
+ if (!isValidTabEvent(event)) {
291
+ event.preventDefault();
292
+ return;
293
+ }
294
+ }
295
+ const exec = {
296
+ ArrowDown() {
297
+ send({ type: "CONTENT.ARROW_DOWN" });
298
+ },
299
+ ArrowUp() {
300
+ send({ type: "CONTENT.ARROW_UP" });
301
+ },
302
+ ArrowRight() {
303
+ send({ type: "CONTENT.ARROW_RIGHT" });
304
+ },
305
+ ArrowLeft() {
306
+ send({ type: "CONTENT.ARROW_LEFT" });
307
+ },
308
+ Home() {
309
+ send({ type: "CONTENT.HOME" });
310
+ },
311
+ End() {
312
+ send({ type: "CONTENT.END" });
313
+ },
314
+ Enter() {
315
+ send({ type: "CONTENT.ENTER" });
316
+ },
317
+ " "() {
318
+ send({ type: "CONTENT.ENTER" });
319
+ }
320
+ }[getEventKey(event, { dir: prop("dir") })];
321
+ if (exec) {
322
+ exec();
323
+ event.preventDefault();
324
+ return;
325
+ }
326
+ if (isEditableElement(event.target)) return;
327
+ },
328
+ onPointerMove(event) {
329
+ if (!interactive) return;
330
+ send({
331
+ type: "POINTER_MOVE",
332
+ clientX: event.clientX,
333
+ clientY: event.clientY,
334
+ target: event.target
335
+ });
336
+ }
337
+ });
338
+ },
339
+ getListProps(props) {
340
+ const itemState = getItemState(props);
341
+ return normalize.element({
342
+ ...parts.list.attrs,
343
+ id: dom.getListId(scope, itemState.value.toString()),
344
+ dir: prop("dir"),
345
+ "data-depth": itemState.depth,
346
+ "aria-level": itemState.depth,
347
+ role: "group"
348
+ });
349
+ },
350
+ getIndicatorProps() {
351
+ return normalize.element({
352
+ ...parts.indicator.attrs,
353
+ id: dom.getIndicatorId(scope),
354
+ dir: prop("dir"),
355
+ "aria-hidden": true,
356
+ "data-state": open ? "open" : "closed",
357
+ "data-disabled": dataAttr(disabled),
358
+ "data-readonly": dataAttr(prop("readOnly")),
359
+ "data-invalid": dataAttr(prop("invalid"))
360
+ });
361
+ },
362
+ getItemProps(props) {
363
+ const { indexPath } = props;
364
+ const itemState = getItemState(props);
365
+ return normalize.element({
366
+ ...parts.item.attrs,
367
+ id: dom.getItemId(scope, itemState.value.toString()),
368
+ dir: prop("dir"),
369
+ role: "treeitem",
370
+ "aria-haspopup": itemState.hasChildren ? "menu" : void 0,
371
+ "aria-expanded": itemState.hasChildren ? itemState.highlighted : false,
372
+ "aria-controls": itemState.hasChildren ? dom.getListId(scope, itemState.value.toString()) : void 0,
373
+ "aria-owns": itemState.hasChildren ? dom.getListId(scope, itemState.value.toString()) : void 0,
374
+ "aria-disabled": ariaAttr(itemState.disabled),
375
+ "data-value": itemState.value.toString(),
376
+ "data-disabled": dataAttr(itemState.disabled),
377
+ "data-highlighted": dataAttr(itemState.highlighted),
378
+ "data-selected": dataAttr(itemState.selected),
379
+ "data-depth": itemState.depth,
380
+ "data-state": itemState.selected ? "checked" : "unchecked",
381
+ "data-type": itemState.hasChildren ? "branch" : "leaf",
382
+ "data-index-path": indexPath.toString(),
383
+ onDoubleClick() {
384
+ if (itemState.disabled) return;
385
+ send({ type: "CLOSE" });
386
+ },
387
+ onClick(event) {
388
+ if (event.defaultPrevented) return;
389
+ if (!interactive) return;
390
+ if (itemState.disabled) return;
391
+ send({
392
+ type: "ITEM.CLICK",
393
+ value: itemState.value,
394
+ indexPath
395
+ });
396
+ },
397
+ onPointerEnter(event) {
398
+ if (!interactive) return;
399
+ if (itemState.disabled) return;
400
+ send({
401
+ type: "ITEM.POINTER_ENTER",
402
+ value: itemState.value,
403
+ indexPath,
404
+ clientX: event.clientX,
405
+ clientY: event.clientY
406
+ });
407
+ },
408
+ onPointerLeave(event) {
409
+ if (!interactive) return;
410
+ if (itemState.disabled) return;
411
+ if (event.pointerType !== "mouse") return;
412
+ if (!service.event.previous()?.type.includes("POINTER")) return;
413
+ send({
414
+ type: "ITEM.POINTER_LEAVE",
415
+ value: itemState.value,
416
+ indexPath,
417
+ clientX: event.clientX,
418
+ clientY: event.clientY
419
+ });
420
+ }
421
+ });
422
+ },
423
+ getItemTextProps(props) {
424
+ const { item } = props;
425
+ const itemValue = collection.getNodeValue(item);
426
+ const itemState = getItemState(props);
427
+ return normalize.element({
428
+ dir: prop("dir"),
429
+ ...parts.itemText.attrs,
430
+ "data-value": itemValue,
431
+ "data-highlighted": dataAttr(itemState.highlighted),
432
+ "data-state": itemState.selected ? "checked" : "unchecked",
433
+ "data-disabled": dataAttr(itemState.disabled)
434
+ });
435
+ },
436
+ getItemIndicatorProps(props) {
437
+ const { item } = props;
438
+ const itemValue = collection.getNodeValue(item);
439
+ const itemState = getItemState(props);
440
+ return normalize.element({
441
+ ...parts.itemIndicator.attrs,
442
+ dir: prop("dir"),
443
+ "data-value": itemValue,
444
+ "data-highlighted": dataAttr(itemState.highlighted),
445
+ "data-type": itemState.hasChildren ? "branch" : "leaf",
446
+ "data-state": itemState.selected ? "checked" : "unchecked",
447
+ hidden: !itemState.selected
448
+ });
449
+ },
450
+ getHiddenInputProps() {
451
+ const defaultValue = context.hash("value");
452
+ return normalize.input({
453
+ name: prop("name"),
454
+ form: prop("form"),
455
+ disabled,
456
+ multiple: prop("multiple"),
457
+ required: prop("required"),
458
+ readOnly: prop("readOnly"),
459
+ hidden: true,
460
+ "aria-hidden": true,
461
+ id: dom.getHiddenInputId(scope),
462
+ defaultValue,
463
+ "aria-labelledby": dom.getLabelId(scope)
464
+ });
465
+ }
466
+ };
467
+ }
468
+ //#endregion
469
+ //#region src/machines/cascade-select/cascade-select.utils.ts
470
+ function createGraceArea(exitPoint, triggerRect, targetRect, options = {}) {
471
+ const { padding = 5 } = options;
472
+ const paddedExitPoints = getPaddedExitPoints(exitPoint, closestSideToPoint(createRect({
473
+ x: triggerRect.left,
474
+ y: triggerRect.top,
475
+ width: triggerRect.width,
476
+ height: triggerRect.height
477
+ }), exitPoint), padding);
478
+ const targetPoints = domRectToPoints(targetRect);
479
+ return getConvexHull([...paddedExitPoints, ...targetPoints]);
480
+ }
481
+ function isPointerInGraceArea(point, graceArea) {
482
+ return isPointInPolygon(graceArea, point);
483
+ }
484
+ function getPaddedExitPoints(exitPoint, exitSide, padding) {
485
+ const { x, y } = exitPoint;
486
+ switch (exitSide) {
487
+ case "top": return [createPoint(x - padding, y + padding), createPoint(x + padding, y + padding)];
488
+ case "bottom": return [createPoint(x - padding, y - padding), createPoint(x + padding, y - padding)];
489
+ case "left": return [createPoint(x + padding, y - padding), createPoint(x + padding, y + padding)];
490
+ case "right": return [createPoint(x - padding, y - padding), createPoint(x - padding, y + padding)];
491
+ default: return [];
492
+ }
493
+ }
494
+ function domRectToPoints(rect) {
495
+ const corners = getRectCorners(createRect({
496
+ x: rect.left,
497
+ y: rect.top,
498
+ width: rect.width,
499
+ height: rect.height
500
+ }));
501
+ return [
502
+ corners.top,
503
+ corners.right,
504
+ corners.bottom,
505
+ corners.left
506
+ ];
507
+ }
508
+ function getConvexHull(points) {
509
+ if (points.length <= 1) return points.slice();
510
+ const sortedPoints = points.slice().sort((a, b) => {
511
+ if (a.x !== b.x) return a.x - b.x;
512
+ return a.y - b.y;
513
+ });
514
+ const lower = [];
515
+ for (const point of sortedPoints) {
516
+ while (lower.length >= 2 && crossProduct(lower[lower.length - 2], lower[lower.length - 1], point) <= 0) lower.pop();
517
+ lower.push(point);
518
+ }
519
+ const upper = [];
520
+ for (let i = sortedPoints.length - 1; i >= 0; i--) {
521
+ const point = sortedPoints[i];
522
+ while (upper.length >= 2 && crossProduct(upper[upper.length - 2], upper[upper.length - 1], point) <= 0) upper.pop();
523
+ upper.push(point);
524
+ }
525
+ lower.pop();
526
+ upper.pop();
527
+ return lower.concat(upper);
528
+ }
529
+ function crossProduct(o, a, b) {
530
+ return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
531
+ }
532
+ //#endregion
533
+ //#region src/machines/cascade-select/cascade-select.machine.ts
534
+ const { or, and, not } = createGuards();
535
+ const machine = createMachine({
536
+ props({ props }) {
537
+ return {
538
+ closeOnSelect: true,
539
+ loopFocus: false,
540
+ defaultValue: [],
541
+ defaultHighlightedValue: [],
542
+ defaultOpen: false,
543
+ multiple: false,
544
+ highlightTrigger: "click",
545
+ allowParentSelection: false,
546
+ positioning: {
547
+ placement: "bottom-start",
548
+ gutter: 8,
549
+ ...props.positioning
550
+ },
551
+ ...props,
552
+ collection: props.collection ?? collection.empty()
553
+ };
554
+ },
555
+ context({ prop, bindable }) {
556
+ return {
557
+ value: bindable(() => ({
558
+ defaultValue: prop("defaultValue"),
559
+ value: prop("value"),
560
+ isEqual,
561
+ hash(value) {
562
+ return value.join(", ");
563
+ }
564
+ })),
565
+ highlightedValue: bindable(() => ({
566
+ defaultValue: prop("defaultHighlightedValue"),
567
+ value: prop("highlightedValue"),
568
+ isEqual
569
+ })),
570
+ valueIndexPath: bindable(() => {
571
+ return { defaultValue: (prop("value") ?? prop("defaultValue") ?? []).map((v) => prop("collection").getIndexPath(v)) };
572
+ }),
573
+ highlightedIndexPath: bindable(() => {
574
+ const value = prop("highlightedValue") ?? prop("defaultHighlightedValue") ?? null;
575
+ return { defaultValue: value ? prop("collection").getIndexPath(value) : [] };
576
+ }),
577
+ highlightedItem: bindable(() => ({ defaultValue: null })),
578
+ selectedItems: bindable(() => ({ defaultValue: [] })),
579
+ currentPlacement: bindable(() => ({ defaultValue: void 0 })),
580
+ fieldsetDisabled: bindable(() => ({ defaultValue: false })),
581
+ graceArea: bindable(() => ({ defaultValue: null })),
582
+ isPointerInTransit: bindable(() => ({ defaultValue: false }))
583
+ };
584
+ },
585
+ computed: {
586
+ isInteractive: ({ prop }) => !(prop("disabled") || prop("readOnly")),
587
+ valueAsString: ({ prop, context }) => {
588
+ const collection = prop("collection");
589
+ const items = context.get("selectedItems");
590
+ const multiple = prop("multiple");
591
+ const formatMultipleMode = (items) => collection.stringifyNode(items.at(-1)) ?? collection.getNodeValue(items.at(-1));
592
+ const formatSingleMode = (items) => {
593
+ return items.map((item) => {
594
+ return collection.stringifyNode(item) ?? collection.getNodeValue(item);
595
+ }).join(" / ");
596
+ };
597
+ const defaultFormatValue = (items) => items.map(multiple ? formatMultipleMode : formatSingleMode).join(", ");
598
+ return (prop("formatValue") ?? defaultFormatValue)(items);
599
+ }
600
+ },
601
+ initialState({ prop }) {
602
+ return prop("open") || prop("defaultOpen") ? "open" : "idle";
603
+ },
604
+ watch({ context, prop, track, action }) {
605
+ track([() => context.get("value")?.toString()], () => {
606
+ action(["syncInputValue", "dispatchChangeEvent"]);
607
+ });
608
+ track([() => prop("open")], () => {
609
+ action(["toggleVisibility"]);
610
+ });
611
+ },
612
+ on: {
613
+ "VALUE.SET": { actions: ["setValue"] },
614
+ "VALUE.CLEAR": { actions: ["clearValue"] },
615
+ "CLEAR_TRIGGER.CLICK": { actions: ["clearValue", "focusTriggerEl"] },
616
+ "HIGHLIGHTED_VALUE.SET": { actions: ["setHighlightedValue"] },
617
+ "ITEM.SELECT": { actions: ["selectItem"] },
618
+ "ITEM.CLEAR": { actions: ["clearItem"] }
619
+ },
620
+ effects: ["trackFormControlState"],
621
+ states: {
622
+ idle: {
623
+ tags: ["closed"],
624
+ on: {
625
+ "CONTROLLED.OPEN": [{
626
+ guard: "isTriggerClickEvent",
627
+ target: "open",
628
+ actions: ["setInitialFocus", "highlightFirstSelectedItem"]
629
+ }, {
630
+ target: "open",
631
+ actions: ["setInitialFocus"]
632
+ }],
633
+ "TRIGGER.CLICK": [{
634
+ guard: "isOpenControlled",
635
+ actions: ["invokeOnOpen"]
636
+ }, {
637
+ target: "open",
638
+ actions: [
639
+ "invokeOnOpen",
640
+ "setInitialFocus",
641
+ "highlightFirstSelectedItem"
642
+ ]
643
+ }],
644
+ "TRIGGER.FOCUS": { target: "focused" },
645
+ OPEN: [{
646
+ guard: "isOpenControlled",
647
+ actions: ["invokeOnOpen"]
648
+ }, {
649
+ target: "open",
650
+ actions: ["setInitialFocus", "invokeOnOpen"]
651
+ }]
652
+ }
653
+ },
654
+ focused: {
655
+ tags: ["closed"],
656
+ on: {
657
+ "CONTROLLED.OPEN": [
658
+ {
659
+ guard: "isTriggerClickEvent",
660
+ target: "open",
661
+ actions: ["setInitialFocus", "highlightFirstSelectedItem"]
662
+ },
663
+ {
664
+ guard: "isTriggerArrowUpEvent",
665
+ target: "open",
666
+ actions: ["setInitialFocus", "highlightLastItem"]
667
+ },
668
+ {
669
+ guard: or("isTriggerArrowDownEvent", "isTriggerEnterEvent", ""),
670
+ target: "open",
671
+ actions: ["setInitialFocus", "highlightFirstItem"]
672
+ },
673
+ {
674
+ target: "open",
675
+ actions: ["setInitialFocus"]
676
+ }
677
+ ],
678
+ OPEN: [{
679
+ guard: "isOpenControlled",
680
+ actions: ["invokeOnOpen"]
681
+ }, {
682
+ target: "open",
683
+ actions: ["setInitialFocus", "invokeOnOpen"]
684
+ }],
685
+ "TRIGGER.BLUR": { target: "idle" },
686
+ "TRIGGER.CLICK": [{
687
+ guard: "isOpenControlled",
688
+ actions: ["invokeOnOpen"]
689
+ }, {
690
+ target: "open",
691
+ actions: [
692
+ "setInitialFocus",
693
+ "invokeOnOpen",
694
+ "highlightFirstSelectedItem"
695
+ ]
696
+ }],
697
+ "TRIGGER.ENTER": [{
698
+ guard: "isOpenControlled",
699
+ actions: ["invokeOnOpen"]
700
+ }, {
701
+ target: "open",
702
+ actions: [
703
+ "setInitialFocus",
704
+ "invokeOnOpen",
705
+ "highlightFirstItem"
706
+ ]
707
+ }],
708
+ "TRIGGER.ARROW_UP": [{
709
+ guard: "isOpenControlled",
710
+ actions: ["invokeOnOpen"]
711
+ }, {
712
+ target: "open",
713
+ actions: [
714
+ "setInitialFocus",
715
+ "invokeOnOpen",
716
+ "highlightLastItem"
717
+ ]
718
+ }],
719
+ "TRIGGER.ARROW_DOWN": [{
720
+ guard: "isOpenControlled",
721
+ actions: ["invokeOnOpen"]
722
+ }, {
723
+ target: "open",
724
+ actions: [
725
+ "setInitialFocus",
726
+ "invokeOnOpen",
727
+ "highlightFirstItem"
728
+ ]
729
+ }],
730
+ "TRIGGER.ARROW_LEFT": [{
731
+ guard: "isOpenControlled",
732
+ actions: ["invokeOnOpen"]
733
+ }, {
734
+ target: "open",
735
+ actions: ["invokeOnOpen"]
736
+ }],
737
+ "TRIGGER.ARROW_RIGHT": [{
738
+ guard: "isOpenControlled",
739
+ actions: ["invokeOnOpen"]
740
+ }, {
741
+ target: "open",
742
+ actions: ["invokeOnOpen", "highlightFirstItem"]
743
+ }]
744
+ }
745
+ },
746
+ open: {
747
+ tags: ["open"],
748
+ exit: ["clearHighlightedValue", "scrollContentToTop"],
749
+ effects: [
750
+ "trackDismissableElement",
751
+ "computePlacement",
752
+ "scrollToHighlightedItems"
753
+ ],
754
+ on: {
755
+ "CONTROLLED.CLOSE": [{
756
+ guard: "restoreFocus",
757
+ target: "focused",
758
+ actions: ["focusTriggerEl"]
759
+ }, { target: "idle" }],
760
+ CLOSE: [
761
+ {
762
+ guard: "isOpenControlled",
763
+ actions: ["invokeOnClose"]
764
+ },
765
+ {
766
+ guard: "restoreFocus",
767
+ target: "focused",
768
+ actions: ["invokeOnClose", "focusTriggerEl"]
769
+ },
770
+ {
771
+ target: "idle",
772
+ actions: ["invokeOnClose"]
773
+ }
774
+ ],
775
+ "TRIGGER.CLICK": [{
776
+ guard: "isOpenControlled",
777
+ actions: ["invokeOnClose"]
778
+ }, {
779
+ target: "focused",
780
+ actions: ["invokeOnClose", "focusTriggerEl"]
781
+ }],
782
+ "ITEM.CLICK": [
783
+ {
784
+ guard: and("canSelectItem", and("shouldCloseOnSelect", not("multiple")), "isOpenControlled"),
785
+ actions: ["selectItem", "invokeOnClose"]
786
+ },
787
+ {
788
+ guard: and("canSelectItem", and("shouldCloseOnSelect", not("multiple"))),
789
+ target: "focused",
790
+ actions: [
791
+ "selectItem",
792
+ "invokeOnClose",
793
+ "focusTriggerEl"
794
+ ]
795
+ },
796
+ {
797
+ guard: "canSelectItem",
798
+ actions: ["selectItem"]
799
+ },
800
+ { actions: ["setHighlightedValue"] }
801
+ ],
802
+ "ITEM.POINTER_ENTER": [{
803
+ guard: "isHoverHighlight",
804
+ actions: ["setHighlightingForHoveredItem"]
805
+ }],
806
+ "ITEM.POINTER_LEAVE": [{
807
+ guard: and("isHoverHighlight", "shouldHighlightOnHover"),
808
+ actions: ["createGraceArea"]
809
+ }],
810
+ POINTER_MOVE: [{
811
+ guard: and("isHoverHighlight", "hasGraceArea", "isPointerOutsideGraceArea", "isPointerNotInAnyItem", "hasHighlightedValue"),
812
+ actions: ["clearGraceArea"]
813
+ }],
814
+ "GRACE_AREA.CLEAR": [{
815
+ guard: "isHoverHighlight",
816
+ actions: ["clearGraceArea"]
817
+ }],
818
+ "CONTENT.HOME": { actions: ["highlightFirstItem"] },
819
+ "CONTENT.END": { actions: ["highlightLastItem"] },
820
+ "CONTENT.ARROW_DOWN": [{
821
+ guard: or(not("hasHighlightedValue"), and("loop", "isHighlightedLastItem")),
822
+ actions: ["highlightFirstItem"]
823
+ }, { actions: ["highlightNextItem"] }],
824
+ "CONTENT.ARROW_UP": [{
825
+ guard: or(not("hasHighlightedValue"), and("loop", "isHighlightedFirstItem")),
826
+ actions: ["highlightLastItem"]
827
+ }, { actions: ["highlightPreviousItem"] }],
828
+ "CONTENT.ARROW_RIGHT": [{
829
+ guard: "canNavigateToChild",
830
+ actions: ["highlightFirstChild"]
831
+ }],
832
+ "CONTENT.ARROW_LEFT": [
833
+ {
834
+ guard: and("isAtRootLevel", "isOpenControlled"),
835
+ actions: ["invokeOnClose", "focusTriggerEl"]
836
+ },
837
+ {
838
+ guard: and("isAtRootLevel", "restoreFocus"),
839
+ target: "focused",
840
+ actions: ["invokeOnClose", "focusTriggerEl"]
841
+ },
842
+ {
843
+ guard: "isAtRootLevel",
844
+ target: "idle",
845
+ actions: ["invokeOnClose"]
846
+ },
847
+ {
848
+ guard: "canNavigateToParent",
849
+ actions: ["highlightParent"]
850
+ }
851
+ ],
852
+ "CONTENT.ENTER": [
853
+ {
854
+ guard: and("canSelectHighlightedItem", and("shouldCloseOnSelectHighlighted", not("multiple")), "isOpenControlled"),
855
+ actions: ["selectHighlightedItem", "invokeOnClose"]
856
+ },
857
+ {
858
+ guard: and("canSelectHighlightedItem", and("shouldCloseOnSelectHighlighted", not("multiple"))),
859
+ target: "focused",
860
+ actions: [
861
+ "selectHighlightedItem",
862
+ "invokeOnClose",
863
+ "focusTriggerEl"
864
+ ]
865
+ },
866
+ {
867
+ guard: "canSelectHighlightedItem",
868
+ actions: ["selectHighlightedItem"]
869
+ }
870
+ ],
871
+ "POSITIONING.SET": { actions: ["reposition"] }
872
+ }
873
+ }
874
+ },
875
+ implementations: {
876
+ guards: {
877
+ restoreFocus: ({ event }) => restoreFocusFn(event),
878
+ multiple: ({ prop }) => !!prop("multiple"),
879
+ loop: ({ prop }) => !!prop("loopFocus"),
880
+ isOpenControlled: ({ prop }) => !!prop("open"),
881
+ isTriggerClickEvent: ({ event }) => event.previousEvent?.type === "TRIGGER.CLICK",
882
+ isTriggerArrowUpEvent: ({ event }) => event.previousEvent?.type === "TRIGGER.ARROW_UP",
883
+ isTriggerArrowDownEvent: ({ event }) => event.previousEvent?.type === "TRIGGER.ARROW_DOWN",
884
+ isTriggerEnterEvent: ({ event }) => event.previousEvent?.type === "TRIGGER.ENTER",
885
+ isTriggerArrowRightEvent: ({ event }) => event.previousEvent?.type === "TRIGGER.ARROW_RIGHT",
886
+ hasHighlightedValue: ({ context }) => context.get("highlightedValue").length > 0,
887
+ isHighlightedFirstItem: ({ context }) => context.get("highlightedIndexPath").at(-1) === 0,
888
+ isHighlightedLastItem: ({ prop, context }) => {
889
+ const path = context.get("highlightedIndexPath");
890
+ const itemIndex = path.at(-1);
891
+ if (!itemIndex && itemIndex !== 0) return false;
892
+ const parentIndexPath = path.slice(0, -1);
893
+ return !prop("collection").at([...parentIndexPath, itemIndex + 1]);
894
+ },
895
+ shouldCloseOnSelect: ({ prop, event }) => {
896
+ const collection = prop("collection");
897
+ const node = collection.at(event.indexPath);
898
+ return prop("closeOnSelect") && node && !collection.isBranchNode(node);
899
+ },
900
+ shouldCloseOnSelectHighlighted: ({ prop, context }) => {
901
+ const collection = prop("collection");
902
+ const node = context.get("highlightedItem");
903
+ return prop("closeOnSelect") && !collection.isBranchNode(node);
904
+ },
905
+ canSelectItem: ({ prop, event }) => {
906
+ const collection = prop("collection");
907
+ const node = collection.at(event.indexPath);
908
+ if (!node) return false;
909
+ return prop("allowParentSelection") || !collection.isBranchNode(node);
910
+ },
911
+ canSelectHighlightedItem: ({ prop, context }) => {
912
+ const collection = prop("collection");
913
+ const node = collection.at(context.get("highlightedIndexPath"));
914
+ if (!node) return false;
915
+ return prop("allowParentSelection") || !collection.isBranchNode(node);
916
+ },
917
+ canNavigateToChild: ({ prop, context }) => {
918
+ const highlightedIndexPath = context.get("highlightedIndexPath");
919
+ if (!highlightedIndexPath.length) return false;
920
+ const collection = prop("collection");
921
+ const node = collection.at(highlightedIndexPath);
922
+ return node && collection.isBranchNode(node);
923
+ },
924
+ canNavigateToParent: ({ context }) => context.get("highlightedIndexPath").length > 1,
925
+ isAtRootLevel: ({ context }) => context.get("highlightedIndexPath").length <= 1,
926
+ isHoverHighlight: ({ prop }) => prop("highlightTrigger") === "hover",
927
+ shouldHighlightOnHover: ({ prop, event }) => {
928
+ const collection = prop("collection");
929
+ const node = collection.at(event.indexPath);
930
+ return node && collection.isBranchNode(node);
931
+ },
932
+ shouldUpdateHighlightedIndexPath: ({ prop, context, event }) => {
933
+ const collection = prop("collection");
934
+ const currentHighlightedIndexPath = context.get("highlightedIndexPath");
935
+ if (!currentHighlightedIndexPath || currentHighlightedIndexPath.length === 0) return false;
936
+ const node = collection.at(event.indexPath);
937
+ if (!node || collection.isBranchNode(node)) return false;
938
+ const indexPath = event.indexPath;
939
+ if (!indexPath) return false;
940
+ const minLength = Math.min(indexPath.length, currentHighlightedIndexPath.length);
941
+ let commonPrefixLength = 0;
942
+ for (let i = 0; i < minLength; i++) if (indexPath[i] === currentHighlightedIndexPath[i]) commonPrefixLength = i + 1;
943
+ else break;
944
+ return commonPrefixLength > 0 && (commonPrefixLength < currentHighlightedIndexPath.length || commonPrefixLength < indexPath.length);
945
+ },
946
+ hasGraceArea: ({ context }) => {
947
+ return context.get("graceArea") != null;
948
+ },
949
+ isPointerOutsideGraceArea: ({ context, event }) => {
950
+ const graceArea = context.get("graceArea");
951
+ if (!graceArea) return false;
952
+ return !isPointerInGraceArea({
953
+ x: event.clientX,
954
+ y: event.clientY
955
+ }, graceArea);
956
+ },
957
+ isPointerNotInAnyItem: ({ event }) => {
958
+ const target = event.target;
959
+ const itemElement = target.closest("[data-part=\"item\"]");
960
+ const contentElement = target.closest("[data-part=\"content\"]");
961
+ return !contentElement || !itemElement && !!contentElement;
962
+ }
963
+ },
964
+ effects: {
965
+ trackFormControlState({ context, scope, prop }) {
966
+ return trackFormControl(dom.getTriggerEl(scope), {
967
+ onFieldsetDisabledChange(disabled) {
968
+ context.set("fieldsetDisabled", disabled);
969
+ },
970
+ onFormReset() {
971
+ context.set("value", prop("defaultValue") ?? []);
972
+ }
973
+ });
974
+ },
975
+ trackDismissableElement({ scope, send, prop }) {
976
+ const contentEl = () => dom.getContentEl(scope);
977
+ let restoreFocus = true;
978
+ return trackDismissableElement(contentEl, {
979
+ defer: true,
980
+ exclude: [dom.getTriggerEl(scope), dom.getClearTriggerEl(scope)],
981
+ onFocusOutside: prop("onFocusOutside"),
982
+ onPointerDownOutside: prop("onPointerDownOutside"),
983
+ onInteractOutside(event) {
984
+ prop("onInteractOutside")?.(event);
985
+ restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
986
+ },
987
+ onDismiss() {
988
+ send({
989
+ type: "CLOSE",
990
+ src: "interact-outside",
991
+ restoreFocus
992
+ });
993
+ }
994
+ });
995
+ },
996
+ computePlacement({ context, prop, scope }) {
997
+ const triggerEl = () => dom.getTriggerEl(scope);
998
+ const positionerEl = () => dom.getPositionerEl(scope);
999
+ return getPlacement(triggerEl, positionerEl, {
1000
+ ...prop("positioning"),
1001
+ onComplete(data) {
1002
+ context.set("currentPlacement", data.placement);
1003
+ }
1004
+ });
1005
+ },
1006
+ scrollToHighlightedItems({ context, prop, scope, event }) {
1007
+ let cleanups = [];
1008
+ const exec = (immediate) => {
1009
+ const highlightedValue = context.get("highlightedValue");
1010
+ const highlightedIndexPath = context.get("highlightedIndexPath");
1011
+ if (!highlightedIndexPath.length) return;
1012
+ if (event.current().type.includes("POINTER")) return;
1013
+ dom.getListEls(scope).forEach((listEl, index) => {
1014
+ const itemPath = highlightedIndexPath.slice(0, index + 1);
1015
+ const itemEl = dom.getItemEl(scope, highlightedValue.toString());
1016
+ const scrollToIndexFn = prop("scrollToIndexFn");
1017
+ if (scrollToIndexFn) {
1018
+ const itemIndexInList = itemPath[itemPath.length - 1];
1019
+ scrollToIndexFn({
1020
+ index: itemIndexInList,
1021
+ immediate,
1022
+ depth: index
1023
+ });
1024
+ return;
1025
+ }
1026
+ const raf_cleanup = raf(() => {
1027
+ scrollIntoView(itemEl, {
1028
+ rootEl: listEl,
1029
+ block: "nearest"
1030
+ });
1031
+ });
1032
+ cleanups.push(raf_cleanup);
1033
+ });
1034
+ };
1035
+ raf(() => exec(true));
1036
+ const rafCleanup = raf(() => exec(true));
1037
+ cleanups.push(rafCleanup);
1038
+ const observerCleanup = observeAttributes(dom.getContentEl(scope), {
1039
+ attributes: ["data-activedescendant"],
1040
+ callback: () => exec(false)
1041
+ });
1042
+ cleanups.push(observerCleanup);
1043
+ return () => {
1044
+ cleanups.forEach((cleanup) => cleanup());
1045
+ };
1046
+ }
1047
+ },
1048
+ actions: {
1049
+ setValue(params) {
1050
+ set.value(params, params.event.value);
1051
+ },
1052
+ clearValue(params) {
1053
+ set.value(params, []);
1054
+ },
1055
+ setHighlightedValue(params) {
1056
+ const { event } = params;
1057
+ set.highlightedValue(params, event.value);
1058
+ },
1059
+ clearHighlightedValue(params) {
1060
+ set.highlightedValue(params, []);
1061
+ },
1062
+ reposition({ context, prop, scope, event }) {
1063
+ const positionerEl = () => dom.getPositionerEl(scope);
1064
+ getPlacement(dom.getTriggerEl(scope), positionerEl, {
1065
+ ...prop("positioning"),
1066
+ ...event.options,
1067
+ defer: true,
1068
+ listeners: false,
1069
+ onComplete(data) {
1070
+ context.set("currentPlacement", data.placement);
1071
+ }
1072
+ });
1073
+ },
1074
+ selectItem(params) {
1075
+ const { context, prop, event } = params;
1076
+ const collection = prop("collection");
1077
+ const multiple = prop("multiple");
1078
+ const value = context.get("value");
1079
+ const itemValue = event.value;
1080
+ const indexPath = event.indexPath ?? collection.getIndexPath(itemValue);
1081
+ const node = collection.at(indexPath);
1082
+ const hasChildren = collection.isBranchNode(node);
1083
+ if (prop("allowParentSelection")) {
1084
+ if (multiple) {
1085
+ const filteredValue = value.filter((v) => {
1086
+ const shortPath = v.length < itemValue.length ? v : itemValue;
1087
+ return !(v.length < itemValue.length ? itemValue : v).slice(0, shortPath.length).every((val, i) => val === shortPath[i]) && !isEqual(v, itemValue);
1088
+ });
1089
+ set.value(params, [...filteredValue, itemValue]);
1090
+ } else set.value(params, [itemValue]);
1091
+ if (hasChildren) set.highlightedValue(params, itemValue);
1092
+ } else if (hasChildren) {
1093
+ if (multiple && value.length > 0) set.value(params, [...value.slice(0, -1), itemValue]);
1094
+ else set.value(params, [itemValue]);
1095
+ set.highlightedValue(params, itemValue);
1096
+ } else if (multiple) {
1097
+ const existingIndex = value.findIndex((path) => isEqual(path, itemValue));
1098
+ if (existingIndex >= 0) {
1099
+ const newValues = [...value];
1100
+ newValues.splice(existingIndex, 1);
1101
+ set.value(params, newValues);
1102
+ } else set.value(params, [...value, itemValue]);
1103
+ } else set.value(params, [itemValue]);
1104
+ },
1105
+ clearItem(params) {
1106
+ const { context, event } = params;
1107
+ const newValue = context.get("value").filter((v) => !isEqual(v, event.value));
1108
+ set.value(params, newValue);
1109
+ },
1110
+ selectHighlightedItem({ context, send }) {
1111
+ const indexPath = context.get("highlightedIndexPath");
1112
+ const value = context.get("highlightedValue");
1113
+ if (value) send({
1114
+ type: "ITEM.SELECT",
1115
+ value,
1116
+ indexPath
1117
+ });
1118
+ },
1119
+ highlightFirstItem(params) {
1120
+ const { context, prop } = params;
1121
+ const collection = prop("collection");
1122
+ const highlightedValue = context.get("highlightedValue");
1123
+ let parentNode;
1124
+ if (!highlightedValue.length) parentNode = collection.rootNode;
1125
+ else {
1126
+ const indexPath = context.get("highlightedIndexPath");
1127
+ parentNode = collection.getParentNode(indexPath) ?? collection.rootNode;
1128
+ }
1129
+ const firstChild = collection.getNodeChildren(parentNode).find((child) => !collection.getNodeDisabled(child));
1130
+ if (!firstChild) return;
1131
+ const firstValue = collection.getNodeValue(firstChild);
1132
+ if (!highlightedValue.length) set.highlightedValue(params, [firstValue]);
1133
+ else {
1134
+ const parentPath = highlightedValue.slice(0, -1);
1135
+ set.highlightedValue(params, [...parentPath, firstValue]);
1136
+ }
1137
+ },
1138
+ highlightLastItem(params) {
1139
+ const { context, prop } = params;
1140
+ const collection = prop("collection");
1141
+ const highlightedValue = context.get("highlightedValue");
1142
+ let parentNode;
1143
+ if (!highlightedValue.length) parentNode = collection.rootNode;
1144
+ else {
1145
+ const indexPath = context.get("highlightedIndexPath");
1146
+ parentNode = collection.getParentNode(indexPath) ?? collection.rootNode;
1147
+ }
1148
+ const lastChild = collection.getNodeChildren(parentNode).findLast((child) => !collection.getNodeDisabled(child));
1149
+ if (!lastChild) return;
1150
+ const lastValue = collection.getNodeValue(lastChild);
1151
+ if (!highlightedValue.length) set.highlightedValue(params, [lastValue]);
1152
+ else {
1153
+ const parentPath = highlightedValue.slice(0, -1);
1154
+ set.highlightedValue(params, [...parentPath, lastValue]);
1155
+ }
1156
+ },
1157
+ highlightNextItem(params) {
1158
+ const { context, prop } = params;
1159
+ const collection = prop("collection");
1160
+ const highlightedValue = context.get("highlightedValue");
1161
+ if (!highlightedValue.length) return;
1162
+ const indexPath = context.get("highlightedIndexPath");
1163
+ const nextSibling = collection.getNextSibling(indexPath);
1164
+ if (!nextSibling) return;
1165
+ const nextValue = collection.getNodeValue(nextSibling);
1166
+ if (highlightedValue.length === 1) set.highlightedValue(params, [nextValue]);
1167
+ else {
1168
+ const parentPath = highlightedValue.slice(0, -1);
1169
+ set.highlightedValue(params, [...parentPath, nextValue]);
1170
+ }
1171
+ },
1172
+ highlightPreviousItem(params) {
1173
+ const { context, prop } = params;
1174
+ const collection = prop("collection");
1175
+ const highlightedValue = context.get("highlightedValue");
1176
+ if (!highlightedValue.length) return;
1177
+ const indexPath = context.get("highlightedIndexPath");
1178
+ const previousSibling = collection.getPreviousSibling(indexPath);
1179
+ if (!previousSibling) return;
1180
+ const prevValue = collection.getNodeValue(previousSibling);
1181
+ if (highlightedValue.length === 1) set.highlightedValue(params, [prevValue]);
1182
+ else {
1183
+ const parentPath = highlightedValue.slice(0, -1);
1184
+ set.highlightedValue(params, [...parentPath, prevValue]);
1185
+ }
1186
+ },
1187
+ highlightFirstChild(params) {
1188
+ const { context, prop } = params;
1189
+ const collection = prop("collection");
1190
+ const highlightedValue = context.get("highlightedValue");
1191
+ if (!highlightedValue.length) return;
1192
+ const indexPath = context.get("highlightedIndexPath");
1193
+ const node = collection.getFirstNode(collection.at(indexPath));
1194
+ if (!node) return;
1195
+ const childValue = collection.getNodeValue(node);
1196
+ set.highlightedValue(params, [...highlightedValue, childValue]);
1197
+ },
1198
+ highlightParent(params) {
1199
+ const { context } = params;
1200
+ const highlightedValue = context.get("highlightedValue");
1201
+ if (!highlightedValue.length) return;
1202
+ const parentPath = highlightedValue.slice(0, -1);
1203
+ set.highlightedValue(params, parentPath);
1204
+ },
1205
+ setInitialFocus({ scope }) {
1206
+ raf(() => {
1207
+ dom.getContentEl(scope)?.focus({ preventScroll: true });
1208
+ });
1209
+ },
1210
+ focusTriggerEl({ event, scope }) {
1211
+ if (!restoreFocusFn(event)) return;
1212
+ raf(() => {
1213
+ dom.getTriggerEl(scope)?.focus({ preventScroll: true });
1214
+ });
1215
+ },
1216
+ invokeOnOpen({ prop }) {
1217
+ prop("onOpenChange")?.({ open: true });
1218
+ },
1219
+ invokeOnClose({ prop }) {
1220
+ prop("onOpenChange")?.({ open: false });
1221
+ },
1222
+ toggleVisibility({ send, prop }) {
1223
+ if (prop("open") != null) send({ type: prop("open") ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE" });
1224
+ },
1225
+ highlightFirstSelectedItem(params) {
1226
+ const { context } = params;
1227
+ const value = context.get("value");
1228
+ if (isEmpty(value)) return;
1229
+ const mostRecentSelection = last(value);
1230
+ if (mostRecentSelection) set.highlightedValue(params, mostRecentSelection);
1231
+ },
1232
+ createGraceArea({ context, event, scope }) {
1233
+ const value = event.value.toString();
1234
+ const triggerElement = dom.getItemEl(scope, value);
1235
+ if (!triggerElement) return;
1236
+ const exitPoint = {
1237
+ x: event.clientX,
1238
+ y: event.clientY
1239
+ };
1240
+ const triggerRect = triggerElement.getBoundingClientRect();
1241
+ const nextLevelEl = dom.getListEl(scope, value);
1242
+ if (!nextLevelEl) return;
1243
+ const graceArea = createGraceArea(exitPoint, triggerRect, nextLevelEl.getBoundingClientRect());
1244
+ context.set("graceArea", graceArea);
1245
+ setTimeout(() => {
1246
+ context.set("graceArea", null);
1247
+ }, 300);
1248
+ },
1249
+ clearGraceArea({ context }) {
1250
+ context.set("graceArea", null);
1251
+ },
1252
+ setHighlightingForHoveredItem(params) {
1253
+ const { prop, event } = params;
1254
+ const collection = prop("collection");
1255
+ const node = collection.at(event.indexPath);
1256
+ let newHighlightedValue;
1257
+ if (node && collection.isBranchNode(node)) newHighlightedValue = event.value;
1258
+ else newHighlightedValue = event.value.slice(0, -1);
1259
+ set.highlightedValue(params, newHighlightedValue);
1260
+ },
1261
+ syncInputValue({ context, scope }) {
1262
+ const inputEl = dom.getHiddenInputEl(scope);
1263
+ if (!inputEl) return;
1264
+ setElementValue(inputEl, context.hash("value"));
1265
+ },
1266
+ dispatchChangeEvent({ scope, context }) {
1267
+ dispatchInputValueEvent(dom.getHiddenInputEl(scope), { value: context.hash("value") });
1268
+ },
1269
+ scrollContentToTop({ scope, prop }) {
1270
+ const scrollToIndexFn = prop("scrollToIndexFn");
1271
+ raf(() => {
1272
+ (dom.getContentEl(scope)?.querySelectorAll("[data-part=\"list\"]"))?.forEach((listEl, index) => {
1273
+ if (scrollToIndexFn) scrollToIndexFn({
1274
+ index: 0,
1275
+ immediate: true,
1276
+ depth: index
1277
+ });
1278
+ else listEl.scrollTop = 0;
1279
+ });
1280
+ });
1281
+ }
1282
+ }
1283
+ }
1284
+ });
1285
+ const set = {
1286
+ value({ context, prop }, value) {
1287
+ const collection = prop("collection");
1288
+ context.set("value", value);
1289
+ const valueIndexPath = value.map((v) => collection.getIndexPath(v));
1290
+ context.set("valueIndexPath", valueIndexPath);
1291
+ const selectedItems = valueIndexPath.map((indexPath) => {
1292
+ return indexPath.map((_, index) => {
1293
+ const partialPath = indexPath.slice(0, index + 1);
1294
+ return collection.at(partialPath);
1295
+ });
1296
+ });
1297
+ context.set("selectedItems", selectedItems);
1298
+ prop("onValueChange")?.({
1299
+ value,
1300
+ items: selectedItems
1301
+ });
1302
+ },
1303
+ highlightedValue({ context, prop }, value) {
1304
+ const collection = prop("collection");
1305
+ context.set("highlightedValue", value);
1306
+ const highlightedIndexPath = value == null ? [] : collection.getIndexPath(value);
1307
+ context.set("highlightedIndexPath", highlightedIndexPath);
1308
+ const highlightedItem = highlightedIndexPath.map((_, index) => {
1309
+ const partialPath = highlightedIndexPath.slice(0, index + 1);
1310
+ return collection.at(partialPath);
1311
+ });
1312
+ context.set("highlightedItem", highlightedItem);
1313
+ prop("onHighlightChange")?.({
1314
+ value,
1315
+ items: highlightedItem
1316
+ });
1317
+ }
1318
+ };
1319
+ function restoreFocusFn(event) {
1320
+ const v = event.restoreFocus ?? event.previousEvent?.restoreFocus;
1321
+ return v == null || !!v;
1322
+ }
1323
+ //#endregion
1324
+ //#region src/machines/cascade-select/cascade-select.props.ts
1325
+ const props = createProps()([
1326
+ "allowParentSelection",
1327
+ "closeOnSelect",
1328
+ "collection",
1329
+ "defaultOpen",
1330
+ "defaultValue",
1331
+ "defaultHighlightedValue",
1332
+ "dir",
1333
+ "disabled",
1334
+ "formatValue",
1335
+ "form",
1336
+ "getRootNode",
1337
+ "highlightedValue",
1338
+ "highlightTrigger",
1339
+ "id",
1340
+ "ids",
1341
+ "invalid",
1342
+ "loopFocus",
1343
+ "multiple",
1344
+ "name",
1345
+ "onFocusOutside",
1346
+ "onHighlightChange",
1347
+ "onInteractOutside",
1348
+ "onOpenChange",
1349
+ "onPointerDownOutside",
1350
+ "onValueChange",
1351
+ "open",
1352
+ "positioning",
1353
+ "readOnly",
1354
+ "required",
1355
+ "scrollToIndexFn",
1356
+ "value"
1357
+ ]);
1358
+ const splitProps = createSplitProps(props);
1359
+ //#endregion
1360
+ export { anatomy, collection, connect, machine, parts, props, splitProps };