@rotki/ui-library 2.20.2 → 2.21.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/dist/__test__/options.d.ts +7 -0
- package/dist/components/calendar/RuiCalendarMenu.js.map +1 -1
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +12 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +137 -51
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.js +7 -0
- package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -0
- package/dist/components/forms/file-upload/RuiFileUpload.vue.d.ts +61 -0
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +269 -0
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/forms/select/RuiMenuSelect.js.map +1 -1
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +7 -1
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/index.d.ts +3 -2
- package/dist/components/index.js +2 -1
- package/dist/components/overlays/menu/RuiMenu.js.map +1 -1
- package/dist/components/overlays/menu/RuiMenu.vue.d.ts +6 -0
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/composables/dropdown-menu.d.ts +12 -1
- package/dist/composables/dropdown-menu.js +46 -7
- package/dist/composables/dropdown-menu.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/library-icons.json +2 -0
- package/dist/style.css +48 -0
- package/dist/utils/helpers.d.ts +4 -0
- package/dist/utils/helpers.js +21 -1
- package/dist/utils/helpers.js.map +1 -1
- package/dist/web-types.json +262 -1
- package/package.json +1 -1
package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -3,6 +3,7 @@ import RuiIcon_default from "../../icons/RuiIcon.js";
|
|
|
3
3
|
import RuiProgress_default from "../../progress/RuiProgress.js";
|
|
4
4
|
import RuiButton_default from "../../buttons/button/RuiButton.js";
|
|
5
5
|
import { useFormTextDetail } from "../../../utils/form-text-detail.js";
|
|
6
|
+
import { Placement } from "../../../composables/floating.js";
|
|
6
7
|
import RuiMenu_default from "../../overlays/menu/RuiMenu.js";
|
|
7
8
|
import RuiChip_default from "../../chips/RuiChip.js";
|
|
8
9
|
import { getNonRootAttrs, getRootAttrs, getTextToken } from "../../../utils/helpers.js";
|
|
@@ -27,18 +28,33 @@ var _hoisted_1 = [
|
|
|
27
28
|
"aria-invalid",
|
|
28
29
|
"tabindex"
|
|
29
30
|
];
|
|
30
|
-
var _hoisted_2 = {
|
|
31
|
-
|
|
31
|
+
var _hoisted_2 = {
|
|
32
|
+
key: 0,
|
|
33
|
+
"data-id": "placeholder",
|
|
34
|
+
class: "flex-1 min-w-0 pointer-events-none"
|
|
35
|
+
};
|
|
36
|
+
var _hoisted_3 = { class: "flex" };
|
|
37
|
+
var _hoisted_4 = [
|
|
32
38
|
"disabled",
|
|
33
39
|
"value",
|
|
34
40
|
"placeholder",
|
|
35
41
|
"aria-invalid"
|
|
36
42
|
];
|
|
37
|
-
var
|
|
43
|
+
var _hoisted_5 = {
|
|
44
|
+
class: "sticky top-0 z-10 bg-white dark:bg-rui-grey-900",
|
|
45
|
+
"data-id": "group-header"
|
|
46
|
+
};
|
|
47
|
+
var _hoisted_6 = { class: "px-3 py-1 text-xs uppercase tracking-wide text-rui-text-secondary" };
|
|
48
|
+
var _hoisted_7 = {
|
|
38
49
|
key: 0,
|
|
39
50
|
class: "p-4",
|
|
40
51
|
"data-id": "no-data"
|
|
41
52
|
};
|
|
53
|
+
var _hoisted_8 = {
|
|
54
|
+
key: 2,
|
|
55
|
+
class: "bg-white dark:bg-rui-grey-900 border-t border-black/[0.12] dark:border-white/[0.12] pr-[var(--rui-scrollbar-gutter,15px)] -mb-2",
|
|
56
|
+
"data-id": "footer"
|
|
57
|
+
};
|
|
42
58
|
var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
43
59
|
name: "RuiAutoComplete",
|
|
44
60
|
inheritAttrs: false,
|
|
@@ -129,7 +145,9 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
129
145
|
hideSelectionWrapper: {
|
|
130
146
|
type: Boolean,
|
|
131
147
|
default: false
|
|
132
|
-
}
|
|
148
|
+
},
|
|
149
|
+
groupBy: { type: Function },
|
|
150
|
+
itemDisabled: { type: Function }
|
|
133
151
|
}, {
|
|
134
152
|
"modelValue": { required: true },
|
|
135
153
|
"modelModifiers": {},
|
|
@@ -180,7 +198,7 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
180
198
|
updateInternalSearch
|
|
181
199
|
});
|
|
182
200
|
const resolvedItemHeight = __props.itemHeight ?? (__props.dense ? 30 : 48);
|
|
183
|
-
const { containerProps, wrapperProps, renderedData, menuWidth, isActiveItem, itemIndexInValue, highlightedIndex, moveHighlight, applyHighlighted, optionsWithSelectedHidden, userNavigated } = useDropdownMenu({
|
|
201
|
+
const { containerProps, wrapperProps, renderedData, menuWidth, isActiveItem, itemIndexInValue, highlightedIndex, moveHighlight, applyHighlighted, optionsWithSelectedHidden, userNavigated, groupedOptions, isGrouped, isItemDisabled } = useDropdownMenu({
|
|
184
202
|
itemHeight: resolvedItemHeight,
|
|
185
203
|
keyAttr: __props.keyAttr,
|
|
186
204
|
textAttr: __props.textAttr,
|
|
@@ -193,7 +211,9 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
193
211
|
hideSelected: __props.hideSelected,
|
|
194
212
|
isOpen,
|
|
195
213
|
getText,
|
|
196
|
-
getIdentifier
|
|
214
|
+
getIdentifier,
|
|
215
|
+
groupBy: () => __props.groupBy,
|
|
216
|
+
itemDisabled: () => __props.itemDisabled
|
|
197
217
|
});
|
|
198
218
|
const { focusedValueIndex, moveSelectedValueHighlight, onEnter, onInputDeletePressed, onTab, setValueFocus } = useAutoCompleteKeyboardNavigation({
|
|
199
219
|
chips: () => __props.chips,
|
|
@@ -236,6 +256,7 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
236
256
|
const menuMinHeight = computed(() => Math.min(5, get$1(optionsWithSelectedHidden).length) * resolvedItemHeight);
|
|
237
257
|
const { hasError, hasSuccess } = useFormTextDetail(() => __props.errorMessages, () => __props.successMessages);
|
|
238
258
|
const valueSet = computed(() => get$1(value).length > 0);
|
|
259
|
+
const placeholderSlotActive = computed(() => Boolean(slots.placeholder) && !get$1(valueSet) && !get$1(searchInputFocused));
|
|
239
260
|
const usedPlaceholder = computed(() => {
|
|
240
261
|
if (get$1(searchInputFocused)) return __props.placeholder;
|
|
241
262
|
return "";
|
|
@@ -342,6 +363,10 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
342
363
|
if (isEqual(curr, old)) return;
|
|
343
364
|
setSelected(get$1(value));
|
|
344
365
|
});
|
|
366
|
+
const menuFloatingOptions = computed(() => ({
|
|
367
|
+
placement: Placement.bottomStart,
|
|
368
|
+
...__props.menuOptions?.options
|
|
369
|
+
}));
|
|
345
370
|
__expose({
|
|
346
371
|
closeMenu,
|
|
347
372
|
focus: focusSetInputFocus,
|
|
@@ -357,7 +382,7 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
357
382
|
...__props.menuOptions
|
|
358
383
|
}, {
|
|
359
384
|
class: unref(ui).wrapper({ class: unref(cn)(_ctx.$attrs.class) }),
|
|
360
|
-
|
|
385
|
+
options: unref(menuFloatingOptions),
|
|
361
386
|
"close-on-content-click": false,
|
|
362
387
|
"full-width": true,
|
|
363
388
|
"persist-on-activator-click": true,
|
|
@@ -411,7 +436,7 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
411
436
|
_cache[16] || (_cache[16] = withKeys(withModifiers(($event) => highlightedIndex.value = unref(optionsWithSelectedHidden).length - 1, ["prevent"]), ["end"]))
|
|
412
437
|
]
|
|
413
438
|
}), [
|
|
414
|
-
unref(outlined) || !unref(valueSet) && !unref(searchInputFocused) ? (openBlock(), createElementBlock("span", {
|
|
439
|
+
(unref(outlined) || !unref(valueSet) && !unref(searchInputFocused)) && !unref(placeholderSlotActive) ? (openBlock(), createElementBlock("span", {
|
|
415
440
|
key: 0,
|
|
416
441
|
class: normalizeClass([unref(ui).label(), { "pr-2": !unref(valueSet) && !open && unref(outlined) }])
|
|
417
442
|
}, [renderSlot(_ctx.$slots, "activator.label", normalizeProps(guardReactiveProps({ value: unref(value) })), () => [createTextVNode(toDisplayString(__props.label), 1)]), __props.required ? (openBlock(), createElementBlock("span", {
|
|
@@ -421,44 +446,51 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
421
446
|
createElementVNode("div", {
|
|
422
447
|
"data-id": "value",
|
|
423
448
|
class: normalizeClass(unref(ui).value())
|
|
424
|
-
}, [
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
449
|
+
}, [
|
|
450
|
+
!unref(valueSet) && !unref(searchInputFocused) && slots.placeholder ? (openBlock(), createElementBlock("div", _hoisted_2, [renderSlot(_ctx.$slots, "placeholder", normalizeProps(guardReactiveProps({
|
|
451
|
+
disabled: __props.disabled,
|
|
452
|
+
readOnly: __props.readOnly
|
|
453
|
+
})))])) : createCommentVNode("", true),
|
|
454
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(value), (item, i) => {
|
|
455
|
+
return openBlock(), createElementBlock(Fragment, { key: unref(getIdentifier)(item) }, [__props.chips ? (openBlock(), createBlock(RuiChip_default, mergeProps({
|
|
456
|
+
key: unref(getTextToken)(unref(getIdentifier)(item)),
|
|
457
|
+
tabindex: "-1",
|
|
458
|
+
size: __props.dense ? "sm" : "md",
|
|
459
|
+
closeable: "",
|
|
460
|
+
class: { "leading-3": __props.dense },
|
|
461
|
+
clickable: ""
|
|
462
|
+
}, { ref_for: true }, chipAttrs(item, i)), {
|
|
463
|
+
default: withCtx(() => [createElementVNode("div", _hoisted_3, [renderSlot(_ctx.$slots, "selection.prepend", mergeProps({ index: i }, { ref_for: true }, { item })), renderSlot(_ctx.$slots, "selection", mergeProps({ index: i }, { ref_for: true }, {
|
|
464
|
+
item,
|
|
465
|
+
chipAttrs: chipAttrs(item, i)
|
|
466
|
+
}), () => [createTextVNode(toDisplayString(unref(getText)(item)), 1)])])]),
|
|
467
|
+
_: 2
|
|
468
|
+
}, 1040, ["size", "class"])) : unref(multiple) || !unref(searchInputFocused) && (slots["selection.prepend"] || slots.selection) ? (openBlock(), createElementBlock("div", {
|
|
469
|
+
key: 1,
|
|
470
|
+
class: normalizeClass(__props.hideSelectionWrapper ? "contents" : "flex")
|
|
471
|
+
}, [renderSlot(_ctx.$slots, "selection.prepend", mergeProps({ index: i }, { ref_for: true }, { item })), unref(multiple) || slots.selection ? renderSlot(_ctx.$slots, "selection", mergeProps({
|
|
472
|
+
key: 0,
|
|
473
|
+
index: i
|
|
474
|
+
}, { ref_for: true }, {
|
|
434
475
|
item,
|
|
435
476
|
chipAttrs: chipAttrs(item, i)
|
|
436
|
-
}), () => [createTextVNode(toDisplayString(unref(getText)(item)), 1)])])])
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
class: normalizeClass(["bg-transparent outline-none", [unref(focusInputClass), { hidden: __props.hideSearchInput }]]),
|
|
454
|
-
type: "text",
|
|
455
|
-
placeholder: unref(usedPlaceholder),
|
|
456
|
-
"aria-invalid": unref(hasError),
|
|
457
|
-
"aria-autocomplete": "list",
|
|
458
|
-
onKeydown: _cache[0] || (_cache[0] = withKeys(($event) => unref(onInputDeletePressed)(), ["delete"])),
|
|
459
|
-
onInput: _cache[1] || (_cache[1] = withModifiers(($event) => updateSearchInput($event), ["stop"])),
|
|
460
|
-
onFocus: _cache[2] || (_cache[2] = ($event) => unref(focusOnInputFocused)())
|
|
461
|
-
}, null, 42, _hoisted_3)], 2),
|
|
477
|
+
}), () => [createTextVNode(toDisplayString(unref(getText)(item)), 1)]) : createCommentVNode("", true)], 2)) : createCommentVNode("", true)], 64);
|
|
478
|
+
}), 128)),
|
|
479
|
+
createElementVNode("input", {
|
|
480
|
+
ref_key: "textInput",
|
|
481
|
+
ref: textInput,
|
|
482
|
+
disabled: __props.disabled,
|
|
483
|
+
value: unref(internalSearch),
|
|
484
|
+
class: normalizeClass(["bg-transparent outline-none", [unref(focusInputClass), { hidden: __props.hideSearchInput }]]),
|
|
485
|
+
type: "text",
|
|
486
|
+
placeholder: unref(usedPlaceholder),
|
|
487
|
+
"aria-invalid": unref(hasError),
|
|
488
|
+
"aria-autocomplete": "list",
|
|
489
|
+
onKeydown: _cache[0] || (_cache[0] = withKeys(($event) => unref(onInputDeletePressed)(), ["delete"])),
|
|
490
|
+
onInput: _cache[1] || (_cache[1] = withModifiers(($event) => updateSearchInput($event), ["stop"])),
|
|
491
|
+
onFocus: _cache[2] || (_cache[2] = ($event) => unref(focusOnInputFocused)())
|
|
492
|
+
}, null, 42, _hoisted_4)
|
|
493
|
+
], 2),
|
|
462
494
|
__props.clearable && unref(valueSet) && !__props.disabled ? (openBlock(), createBlock(RuiButton_default, {
|
|
463
495
|
key: 1,
|
|
464
496
|
variant: "text",
|
|
@@ -513,7 +545,56 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
513
545
|
}]),
|
|
514
546
|
onScroll: _cache[17] || (_cache[17] = (...args) => unref(containerProps).onScroll && unref(containerProps).onScroll(...args)),
|
|
515
547
|
onKeydown: [_cache[18] || (_cache[18] = withKeys(withModifiers(($event) => unref(moveHighlight)(true), ["prevent"]), ["up"])), _cache[19] || (_cache[19] = withKeys(withModifiers(($event) => unref(moveHighlight)(false), ["prevent"]), ["down"]))]
|
|
516
|
-
}, [
|
|
548
|
+
}, [unref(isGrouped) ? (openBlock(), createElementBlock("div", {
|
|
549
|
+
key: 0,
|
|
550
|
+
ref_key: "menuRef",
|
|
551
|
+
ref: menuRef
|
|
552
|
+
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(groupedOptions), (bucket, bucketIndex) => {
|
|
553
|
+
return openBlock(), createElementBlock(Fragment, { key: bucket.group || `group-${bucketIndex}` }, [createElementVNode("div", _hoisted_5, [renderSlot(_ctx.$slots, "group-header", mergeProps({ ref_for: true }, {
|
|
554
|
+
group: bucket.group,
|
|
555
|
+
items: bucket.items
|
|
556
|
+
}), () => [createElementVNode("div", _hoisted_6, toDisplayString(bucket.group), 1)])]), (openBlock(true), createElementBlock(Fragment, null, renderList(bucket.items, (item) => {
|
|
557
|
+
return openBlock(), createBlock(RuiButton_default, {
|
|
558
|
+
key: unref(getIdentifier)(item)?.toString(),
|
|
559
|
+
active: unref(isActiveItem)(item),
|
|
560
|
+
"aria-selected": unref(isActiveItem)(item),
|
|
561
|
+
size: __props.dense ? "sm" : void 0,
|
|
562
|
+
disabled: unref(isItemDisabled)(item),
|
|
563
|
+
tabindex: "0",
|
|
564
|
+
variant: "list",
|
|
565
|
+
"data-highlighted": unref(optionsWithSelectedHidden).indexOf(item) === unref(highlightedIndex),
|
|
566
|
+
"data-disabled": unref(isItemDisabled)(item) || void 0,
|
|
567
|
+
class: normalizeClass({ [unref(highlightedClass)]: !unref(isActiveItem)(item) && unref(optionsWithSelectedHidden).indexOf(item) === unref(highlightedIndex) }),
|
|
568
|
+
onClick: ($event) => !unref(isItemDisabled)(item) && setValue(item)
|
|
569
|
+
}, {
|
|
570
|
+
prepend: withCtx(() => [renderSlot(_ctx.$slots, "item.prepend", mergeProps({ ref_for: true }, {
|
|
571
|
+
disabled: unref(isItemDisabled)(item),
|
|
572
|
+
item,
|
|
573
|
+
active: unref(isActiveItem)(item)
|
|
574
|
+
}))]),
|
|
575
|
+
append: withCtx(() => [renderSlot(_ctx.$slots, "item.append", mergeProps({ ref_for: true }, {
|
|
576
|
+
disabled: unref(isItemDisabled)(item),
|
|
577
|
+
item,
|
|
578
|
+
active: unref(isActiveItem)(item)
|
|
579
|
+
}))]),
|
|
580
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "item", mergeProps({ ref_for: true }, {
|
|
581
|
+
disabled: unref(isItemDisabled)(item),
|
|
582
|
+
item,
|
|
583
|
+
active: unref(isActiveItem)(item)
|
|
584
|
+
}), () => [createTextVNode(toDisplayString(unref(getText)(item)), 1)])]),
|
|
585
|
+
_: 2
|
|
586
|
+
}, 1032, [
|
|
587
|
+
"active",
|
|
588
|
+
"aria-selected",
|
|
589
|
+
"size",
|
|
590
|
+
"disabled",
|
|
591
|
+
"data-highlighted",
|
|
592
|
+
"data-disabled",
|
|
593
|
+
"class",
|
|
594
|
+
"onClick"
|
|
595
|
+
]);
|
|
596
|
+
}), 128))], 64);
|
|
597
|
+
}), 128))], 512)) : (openBlock(), createElementBlock("div", mergeProps({ key: 1 }, unref(wrapperProps), {
|
|
517
598
|
ref_key: "menuRef",
|
|
518
599
|
ref: menuRef
|
|
519
600
|
}), [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(renderedData), ({ item, _index }) => {
|
|
@@ -522,24 +603,26 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
522
603
|
active: unref(isActiveItem)(item),
|
|
523
604
|
"aria-selected": unref(isActiveItem)(item),
|
|
524
605
|
size: __props.dense ? "sm" : void 0,
|
|
606
|
+
disabled: unref(isItemDisabled)(item),
|
|
525
607
|
tabindex: "0",
|
|
526
608
|
variant: "list",
|
|
527
609
|
"data-highlighted": unref(highlightedIndex) === _index,
|
|
610
|
+
"data-disabled": unref(isItemDisabled)(item) || void 0,
|
|
528
611
|
class: normalizeClass({ [unref(highlightedClass)]: !unref(isActiveItem)(item) && unref(highlightedIndex) === _index }),
|
|
529
|
-
onClick: ($event) => setValue(item)
|
|
612
|
+
onClick: ($event) => !unref(isItemDisabled)(item) && setValue(item)
|
|
530
613
|
}, {
|
|
531
614
|
prepend: withCtx(() => [renderSlot(_ctx.$slots, "item.prepend", mergeProps({ ref_for: true }, {
|
|
532
|
-
disabled:
|
|
615
|
+
disabled: unref(isItemDisabled)(item),
|
|
533
616
|
item,
|
|
534
617
|
active: unref(isActiveItem)(item)
|
|
535
618
|
}))]),
|
|
536
619
|
append: withCtx(() => [renderSlot(_ctx.$slots, "item.append", mergeProps({ ref_for: true }, {
|
|
537
|
-
disabled:
|
|
620
|
+
disabled: unref(isItemDisabled)(item),
|
|
538
621
|
item,
|
|
539
622
|
active: unref(isActiveItem)(item)
|
|
540
623
|
}))]),
|
|
541
624
|
default: withCtx(() => [renderSlot(_ctx.$slots, "item", mergeProps({ ref_for: true }, {
|
|
542
|
-
disabled:
|
|
625
|
+
disabled: unref(isItemDisabled)(item),
|
|
543
626
|
item,
|
|
544
627
|
active: unref(isActiveItem)(item)
|
|
545
628
|
}), () => [createTextVNode(toDisplayString(unref(getText)(item)), 1)])]),
|
|
@@ -548,22 +631,25 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
548
631
|
"active",
|
|
549
632
|
"aria-selected",
|
|
550
633
|
"size",
|
|
634
|
+
"disabled",
|
|
551
635
|
"data-highlighted",
|
|
636
|
+
"data-disabled",
|
|
552
637
|
"class",
|
|
553
638
|
"onClick"
|
|
554
639
|
]);
|
|
555
|
-
}), 128))], 16)], 38)) : !__props.hideNoData ? (openBlock(), createElementBlock("div", {
|
|
640
|
+
}), 128))], 16))], 38)) : !__props.hideNoData ? (openBlock(), createElementBlock("div", {
|
|
556
641
|
key: 1,
|
|
557
642
|
style: normalizeStyle({
|
|
558
643
|
width: `${width}px`,
|
|
559
644
|
minWidth: unref(menuWidth)
|
|
560
645
|
}),
|
|
561
646
|
class: normalizeClass(__props.classNames?.menu ?? __props.menuClass)
|
|
562
|
-
}, [renderSlot(_ctx.$slots, "no-data", {}, () => [!__props.customValue ? (openBlock(), createElementBlock("div",
|
|
647
|
+
}, [renderSlot(_ctx.$slots, "no-data", {}, () => [!__props.customValue ? (openBlock(), createElementBlock("div", _hoisted_7, toDisplayString(__props.noDataText), 1)) : createCommentVNode("", true)])], 6)) : createCommentVNode("", true), slots.footer ? (openBlock(), createElementBlock("div", _hoisted_8, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true)], 512)]),
|
|
563
648
|
_: 3
|
|
564
649
|
}, 16, [
|
|
565
650
|
"modelValue",
|
|
566
651
|
"class",
|
|
652
|
+
"options",
|
|
567
653
|
"menu-class",
|
|
568
654
|
"error-messages",
|
|
569
655
|
"success-messages",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiAutoComplete.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../../src/components/forms/auto-complete/RuiAutoComplete.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue, TItem\">\nimport type { VueClassValue } from '@/types/class-value';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiChip from '@/components/chips/RuiChip.vue';\nimport { autoCompleteStyles, type AutoCompleteVariant } from '@/components/forms/auto-complete/auto-complete-styles';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiMenu, { type MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport {\n type KeyOfType,\n useDropdownMenu,\n useDropdownOptionProperty,\n} from '@/composables/dropdown-menu';\nimport {\n useAutoCompleteFocus,\n useAutoCompleteKeyboardNavigation,\n useAutoCompleteSearch,\n useAutoCompleteValue,\n} from '@/composables/forms/auto-complete';\nimport { useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs, getTextToken } from '@/utils/helpers';\nimport { isEqual } from '@/utils/is-equal';\nimport { cn } from '@/utils/tv';\n\nexport type AutoCompleteModelValue<TValue> =\n TValue extends Array<infer U> ? U[] : TValue | undefined;\n\nexport interface RuiAutoCompleteClassNames {\n root?: VueClassValue;\n label?: VueClassValue;\n menu?: VueClassValue;\n}\n\nexport interface AutoCompleteProps<TValue, TItem> {\n options?: TItem[];\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem;\n disabled?: boolean;\n loading?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n menuOptions?: MenuProps;\n classNames?: RuiAutoCompleteClassNames;\n /** @deprecated Use `classNames.label` instead */\n labelClass?: string;\n /** @deprecated Use `classNames.menu` instead */\n menuClass?: string;\n prependWidth?: number;\n appendWidth?: number;\n itemHeight?: number;\n variant?: AutoCompleteVariant;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n hideDetails?: boolean;\n autoSelectFirst?: boolean;\n chips?: boolean;\n noFilter?: boolean;\n hideNoData?: boolean;\n noDataText?: string;\n filter?: (item: TItem, queryText: string) => boolean;\n hideSelected?: boolean;\n placeholder?: string;\n returnObject?: boolean;\n customValue?: boolean;\n hideCustomValue?: boolean;\n required?: boolean;\n hideSearchInput?: boolean;\n hideSelectionWrapper?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAutoComplete',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<AutoCompleteModelValue<TValue>>({ required: true });\n\nconst searchInputModel = defineModel<string>('searchInput', { default: '' });\n\nconst {\n options = [],\n disabled = false,\n loading = false,\n readOnly = false,\n dense = false,\n clearable = false,\n hideDetails = false,\n chips = false,\n label = 'Select',\n menuOptions,\n classNames,\n labelClass,\n menuClass,\n variant = 'default',\n hint,\n keyAttr,\n textAttr,\n itemHeight,\n errorMessages = [],\n successMessages = [],\n autoSelectFirst = false,\n noFilter = false,\n hideNoData = false,\n noDataText = 'No data available',\n filter,\n hideSelected = false,\n placeholder = '',\n returnObject = false,\n customValue = false,\n hideCustomValue = false,\n required = false,\n hideSearchInput = false,\n hideSelectionWrapper = false,\n} = defineProps<AutoCompleteProps<TValue, TItem>>();\n\nconst slots = defineSlots<{\n 'activator'?: (props: {\n disabled: boolean;\n value: TItem[];\n variant: string;\n readOnly: boolean;\n attrs: Record<string, unknown>;\n open: boolean;\n hasError: boolean;\n hasSuccess: boolean;\n }) => any;\n 'activator.label'?: (props: { value: TItem[] }) => any;\n 'selection.prepend'?: (props: { index: number; item: TItem }) => any;\n 'selection'?: (props: { index: number; item: TItem; chipAttrs: Record<string, unknown> }) => any;\n 'item.prepend'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item.append'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'no-data'?: () => any;\n}>();\n\nconst { getText, getIdentifier } = useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n});\n\nconst textInput = useTemplateRef<HTMLInputElement>('textInput');\nconst activator = useTemplateRef<HTMLDivElement>('activator');\nconst menuRef = useTemplateRef<HTMLDivElement>('menuRef');\nconst menuWrapperRef = useTemplateRef<HTMLDivElement>('menuWrapperRef');\n\nconst { focused: activatorFocusedWithin } = useFocusWithin(activator);\nconst { focused: menuWrapperFocusedWithin } = useFocusWithin(menuWrapperRef);\nconst { focused: searchInputFocused } = useFocus(textInput);\nconst { focused: activatorFocused } = useFocus(activator);\n\nconst {\n internalSearch,\n filteredOptions,\n justOpened,\n updateInternalSearch,\n textValueToProperValue,\n} = useAutoCompleteSearch<TItem>(\n () => options,\n searchInputModel,\n {\n keyAttr: () => keyAttr,\n textAttr: () => textAttr,\n noFilter: () => noFilter,\n filter: () => filter,\n customValue: () => customValue,\n hideCustomValue: () => hideCustomValue,\n returnObject: () => returnObject,\n },\n);\n\nconst isOpen = ref<boolean>(false);\nconst isHovered = ref<boolean>(false);\n\n// Calculate multiple from modelValue directly to avoid circular dependency\nconst multiple = computed<boolean>(() => Array.isArray(get(modelValue)));\n\nconst shouldApplyValueAsSearch = computed<boolean>(\n () => !(slots.selection || get(multiple) || chips),\n);\n\nconst { value, setSelected } = useAutoCompleteValue<AutoCompleteModelValue<TValue>, TItem>(\n modelValue,\n () => options,\n {\n keyAttr: () => keyAttr,\n returnObject: () => returnObject,\n customValue: () => customValue,\n },\n {\n getIdentifier,\n getText,\n textValueToProperValue,\n shouldApplyValueAsSearch,\n isOpen,\n multiple,\n updateInternalSearch,\n },\n);\n\nconst resolvedItemHeight = itemHeight ?? (dense ? 30 : 48);\n\nconst {\n containerProps,\n wrapperProps,\n renderedData,\n menuWidth,\n isActiveItem,\n itemIndexInValue,\n highlightedIndex,\n moveHighlight,\n applyHighlighted,\n optionsWithSelectedHidden,\n userNavigated,\n} = useDropdownMenu<TValue, TItem>({\n itemHeight: resolvedItemHeight,\n keyAttr,\n textAttr,\n options: filteredOptions,\n dense: () => dense,\n value,\n menuRef,\n setValue,\n autoSelectFirst,\n hideSelected,\n isOpen,\n getText,\n getIdentifier,\n});\n\nconst {\n focusedValueIndex,\n moveSelectedValueHighlight,\n onEnter,\n onInputDeletePressed,\n onTab,\n setValueFocus,\n} = useAutoCompleteKeyboardNavigation<TItem>(\n {\n chips: () => chips,\n customValue: () => customValue,\n multiple,\n },\n {\n activator,\n applyHighlighted,\n clear,\n filteredOptions,\n getText,\n highlightedIndex,\n internalSearch,\n isOpen,\n removeValue: (item: TItem): void => { setValue(item); },\n searchInputFocused,\n setSearchAsValue,\n userNavigated,\n value,\n },\n);\n\nconst {\n anyFocused: focusAnyFocused,\n inputClass: focusInputClass,\n onActivatorFocused: focusOnActivatorFocused,\n onInputFocused: focusOnInputFocused,\n setInputFocus: focusSetInputFocus,\n} = useAutoCompleteFocus(\n {\n customValue: () => customValue,\n disabled: () => disabled,\n shouldApplyValueAsSearch,\n },\n {\n activatorFocused,\n activatorFocusedWithin,\n focusedValueIndex,\n internalSearch,\n isOpen,\n justOpened,\n menuWrapperFocusedWithin,\n searchInputFocused,\n setSearchAsValue,\n textInput,\n updateInternalSearch,\n },\n);\n\nconst menuMinHeight = computed<number>(\n () => Math.min(5, get(optionsWithSelectedHidden).length) * resolvedItemHeight,\n);\n\nconst { hasError, hasSuccess } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\n\nconst valueSet = computed<boolean>(() => get(value).length > 0);\n\nconst usedPlaceholder = computed<string>(() => {\n if (get(searchInputFocused))\n return placeholder;\n return '';\n});\n\nconst outlined = computed<boolean>(() => variant === 'outlined');\nconst float = computed<boolean>(() => (get(isOpen) || get(valueSet) || get(searchInputFocused)) && get(outlined));\n\nconst legendText = computed<string>(() => {\n if (!get(float) || !label)\n return '';\n return required ? `${label} ﹡` : label;\n});\n\nconst ui = computed<ReturnType<typeof autoCompleteStyles>>(() => autoCompleteStyles({\n filled: variant === 'filled',\n outlined: get(outlined),\n float: get(float),\n opened: get(isOpen),\n hovered: get(isHovered),\n dense,\n disabled,\n readonly: readOnly,\n hasError: get(hasError),\n hasSuccess: get(hasSuccess) && !get(hasError),\n}));\n\nconst highlightedClass = autoCompleteStyles({}).highlighted();\n\nfunction updateSearchInput(event: Event): void {\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n\n const value = target.value;\n set(isOpen, true);\n updateInternalSearch(value);\n set(justOpened, false);\n}\n\nasync function setValue(val: TItem, skipRefocused = false): Promise<void> {\n const isMultiple = get(multiple);\n\n if (isMultiple) {\n const newValue = [...get(value)];\n const indexInValue = itemIndexInValue(val);\n if (indexInValue === -1) {\n updateInternalSearch();\n newValue.push(val);\n }\n else {\n newValue.splice(indexInValue, 1);\n }\n set(value, newValue);\n }\n else {\n if (get(shouldApplyValueAsSearch))\n updateInternalSearch(getText(val));\n else updateInternalSearch();\n\n set(value, [val]);\n }\n\n if (!isMultiple) {\n if (!skipRefocused) {\n set(activatorFocused, true);\n get(activator)?.focus();\n await nextTick(() => {\n set(isOpen, false);\n });\n }\n else {\n set(isOpen, false);\n }\n }\n else if (!skipRefocused) {\n set(searchInputFocused, true);\n }\n}\n\nfunction setSearchAsValue(): void {\n const searchToBeValue = get(internalSearch);\n if (!searchToBeValue)\n return;\n\n const newValue: TItem = textValueToProperValue(searchToBeValue);\n setValue(newValue, true);\n}\n\nfunction clear(): void {\n updateInternalSearch();\n set(modelValue, (Array.isArray(get(modelValue)) ? [] : undefined) as AutoCompleteModelValue<TValue>);\n}\n\nfunction chipAttrs(item: TItem, index: number): Record<string, unknown> {\n return {\n 'data-index': index,\n 'data-value': getIdentifier(item),\n 'onKeydown': (event: KeyboardEvent): void => {\n const { key } = event;\n if (['Backspace', 'Delete'].includes(key)) {\n event.stopPropagation();\n event.preventDefault();\n setValue(item);\n }\n },\n 'onClick': (e: MouseEvent): void => {\n e.stopPropagation();\n setValueFocus(index);\n },\n 'onClick:close': (): void => {\n setValue(item);\n },\n };\n}\n\nfunction setSelectionRange(start: number, end: number): void {\n set(searchInputFocused, true);\n get(textInput)?.setSelectionRange?.(start, end);\n}\n\nfunction arrowClicked(event: MouseEvent): void {\n if (get(isOpen)) {\n set(isOpen, false);\n event.stopPropagation();\n }\n}\n\nfunction openMenu(): void {\n set(isOpen, true);\n}\n\nfunction closeMenu(): void {\n set(isOpen, false);\n}\n\n// Optimize options watcher with shallow comparison first\nwatch(() => options, (curr, old) => {\n if (curr === old || customValue)\n return;\n\n // Only do deep comparison if reference changed\n if (isEqual(curr, old))\n return;\n\n setSelected(get(value));\n});\n\ndefineExpose({\n closeMenu,\n focus: focusSetInputFocus,\n openMenu,\n setSelectionRange,\n});\n</script>\n\n<template>\n <RuiMenu\n v-model=\"isOpen\"\n v-bind=\"{ ...getRootAttrs($attrs, []), ...menuOptions }\"\n :class=\"ui.wrapper({ class: cn($attrs.class) })\"\n placement=\"bottom-start\"\n :close-on-content-click=\"false\"\n :full-width=\"true\"\n :persist-on-activator-click=\"true\"\n :menu-class=\"[\n { hidden: optionsWithSelectedHidden.length === 0 && customValue && !slots['no-data'] },\n menuOptions?.menuClass,\n ]\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n :dense=\"dense\"\n :show-details=\"!hideDetails\"\n :disabled=\"disabled\"\n disable-auto-focus\n >\n <template #activator=\"{ attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\">\n <slot\n name=\"activator\"\n v-bind=\"{ disabled, value, variant, readOnly, attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\"\n >\n <div\n ref=\"activator\"\n :class=\"ui.activator({ class: cn(classNames?.label) ?? labelClass })\"\n v-bind=\"{\n ...getNonRootAttrs($attrs, ['onClick', 'class']),\n ...(readOnly ? {} : attrs),\n }\"\n role=\"combobox\"\n :aria-expanded=\"open\"\n :aria-disabled=\"disabled || undefined\"\n :aria-readonly=\"readOnly || undefined\"\n :aria-required=\"required || undefined\"\n :aria-busy=\"loading || undefined\"\n data-id=\"activator\"\n :aria-invalid=\"hasError\"\n :tabindex=\"disabled || readOnly ? -1 : 0\"\n @mouseenter=\"isHovered = true\"\n @mouseleave=\"isHovered = false\"\n @click=\"focusSetInputFocus()\"\n @focus=\"focusOnActivatorFocused()\"\n @keydown.enter=\"onEnter($event)\"\n @keydown.tab=\"onTab($event)\"\n @keydown.left=\"moveSelectedValueHighlight($event, false)\"\n @keydown.right=\"moveSelectedValueHighlight($event, true)\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n @keydown.home.prevent=\"highlightedIndex = 0\"\n @keydown.end.prevent=\"highlightedIndex = optionsWithSelectedHidden.length - 1\"\n >\n <span\n v-if=\"outlined || (!valueSet && !searchInputFocused)\"\n :class=\"[\n ui.label(),\n { 'pr-2': !valueSet && !open && outlined },\n ]\"\n >\n <slot\n name=\"activator.label\"\n v-bind=\"{ value }\"\n >\n {{ label }}\n </slot>\n <span\n v-if=\"required\"\n :class=\"ui.required()\"\n >\n ﹡\n </span>\n </span>\n <div\n data-id=\"value\"\n :class=\"ui.value()\"\n >\n <template\n v-for=\"(item, i) in value\"\n :key=\"getIdentifier(item)\"\n >\n <RuiChip\n v-if=\"chips\"\n :key=\"getTextToken(getIdentifier(item))\"\n tabindex=\"-1\"\n :size=\"dense ? 'sm' : 'md'\"\n closeable\n :class=\"{ 'leading-3': dense }\"\n clickable\n v-bind=\"chipAttrs(item, i)\"\n >\n <div class=\"flex\">\n <slot\n name=\"selection.prepend\"\n :index=\"i\"\n v-bind=\"{ item }\"\n />\n <slot\n :index=\"i\"\n name=\"selection\"\n v-bind=\"{ item, chipAttrs: chipAttrs(item, i) }\"\n >\n {{ getText(item) }}\n </slot>\n </div>\n </RuiChip>\n <div\n v-else-if=\"\n multiple\n || (!searchInputFocused && (slots['selection.prepend'] || slots.selection))\n \"\n :class=\"hideSelectionWrapper ? 'contents' : 'flex'\"\n >\n <slot\n name=\"selection.prepend\"\n :index=\"i\"\n v-bind=\"{ item }\"\n />\n <slot\n v-if=\"multiple || slots.selection\"\n :index=\"i\"\n name=\"selection\"\n v-bind=\"{ item, chipAttrs: chipAttrs(item, i) }\"\n >\n {{ getText(item) }}\n </slot>\n </div>\n </template>\n <input\n ref=\"textInput\"\n :disabled=\"disabled\"\n :value=\"internalSearch\"\n class=\"bg-transparent outline-none\"\n type=\"text\"\n :placeholder=\"usedPlaceholder\"\n :class=\"[focusInputClass, { hidden: hideSearchInput }]\"\n :aria-invalid=\"hasError\"\n aria-autocomplete=\"list\"\n @keydown.delete=\"onInputDeletePressed()\"\n @input.stop=\"updateSearchInput($event)\"\n @focus=\"focusOnInputFocused()\"\n />\n </div>\n\n <RuiButton\n v-if=\"clearable && valueSet && !disabled\"\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n color=\"error\"\n data-id=\"clear\"\n :class=\"[\n ui.clear(),\n focusAnyFocused && '!visible',\n { 'mr-2': !dense },\n ]\"\n @click.stop.prevent=\"clear()\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"18\"\n />\n </RuiButton>\n\n <span\n :class=\"ui.iconWrapper()\"\n @click=\"arrowClicked($event)\"\n >\n <RuiIcon\n :class=\"ui.icon()\"\n :size=\"dense ? 16 : 24\"\n name=\"lu-chevron-down\"\n />\n </span>\n\n <RuiProgress\n v-if=\"loading\"\n :class=\"ui.progress()\"\n color=\"primary\"\n thickness=\"3\"\n variant=\"indeterminate\"\n />\n </div>\n <fieldset\n v-if=\"outlined\"\n :class=\"ui.fieldset()\"\n >\n <legend :class=\"ui.legend()\">\n {{ legendText }}\n </legend>\n </fieldset>\n </slot>\n </template>\n <template #default=\"{ width }\">\n <div ref=\"menuWrapperRef\">\n <div\n v-if=\"optionsWithSelectedHidden.length > 0\"\n :ref=\"containerProps.ref\"\n :class=\"ui.menu({ class: cn(classNames?.menu) ?? menuClass })\"\n :style=\"[containerProps.style, { width: `${width}px`, minWidth: menuWidth, minHeight: `${menuMinHeight}px` }]\"\n @scroll=\"containerProps.onScroll\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n >\n <div\n v-bind=\"wrapperProps\"\n ref=\"menuRef\"\n >\n <RuiButton\n v-for=\"{ item, _index } in renderedData\"\n :key=\"getIdentifier(item)?.toString()\"\n :active=\"isActiveItem(item)\"\n :aria-selected=\"isActiveItem(item)\"\n :size=\"dense ? 'sm' : undefined\"\n tabindex=\"0\"\n variant=\"list\"\n :data-highlighted=\"highlightedIndex === _index\"\n :class=\"{\n [highlightedClass]: !isActiveItem(item) && highlightedIndex === _index,\n }\"\n @click=\"setValue(item)\"\n >\n <template #prepend>\n <slot\n name=\"item.prepend\"\n v-bind=\"{ disabled, item, active: isActiveItem(item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ disabled, item, active: isActiveItem(item) }\"\n >\n {{ getText(item) }}\n </slot>\n <template #append>\n <slot\n name=\"item.append\"\n v-bind=\"{ disabled, item, active: isActiveItem(item) }\"\n />\n </template>\n </RuiButton>\n </div>\n </div>\n\n <div\n v-else-if=\"!hideNoData\"\n :style=\"{ width: `${width}px`, minWidth: menuWidth }\"\n :class=\"classNames?.menu ?? menuClass\"\n >\n <slot name=\"no-data\">\n <div\n v-if=\"!customValue\"\n class=\"p-4\"\n data-id=\"no-data\"\n >\n {{ noDataText }}\n </div>\n </slot>\n </div>\n </div>\n </template>\n </RuiMenu>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8EA,MAAM,aAAa,SAA2C,SAAA,aAAoB;EAElF,MAAM,mBAAmB,SAAmB,SAAC,cAA+B;EAsC5E,MAAM,QAAQ,UAkBV;EAEJ,MAAM,EAAE,SAAS,kBAAkB,0BAAyC;GAC1E,SAAM,QAAA;GACN,UAAO,QAAA;GACR,CAAC;EAEF,MAAM,YAAY,eAAiC,YAAY;EAC/D,MAAM,YAAY,eAA+B,YAAY;EAC7D,MAAM,UAAU,eAA+B,UAAU;EACzD,MAAM,iBAAiB,eAA+B,iBAAiB;EAEvE,MAAM,EAAE,SAAS,2BAA2B,eAAe,UAAU;EACrE,MAAM,EAAE,SAAS,6BAA6B,eAAe,eAAe;EAC5E,MAAM,EAAE,SAAS,uBAAuB,SAAS,UAAU;EAC3D,MAAM,EAAE,SAAS,qBAAqB,SAAS,UAAU;EAEzD,MAAM,EACJ,gBACA,iBACA,YACA,sBACA,2BACE,4BACI,QAAA,SACN,kBACA;GACE,eAAe,QAAA;GACf,gBAAgB,QAAA;GAChB,gBAAgB,QAAA;GAChB,cAAc,QAAA;GACd,mBAAmB,QAAA;GACnB,uBAAuB,QAAA;GACvB,oBAAoB,QAAA;GACrB,CACF;EAED,MAAM,SAAS,IAAa,MAAM;EAClC,MAAM,YAAY,IAAa,MAAM;EAGrC,MAAM,WAAW,eAAwB,MAAM,QAAQ,MAAI,WAAW,CAAC,CAAC;EAExE,MAAM,2BAA2B,eACzB,EAAE,MAAM,aAAa,MAAI,SAAS,IAAI,QAAA,OAC7C;EAED,MAAM,EAAE,OAAO,gBAAgB,qBAC7B,kBACM,QAAA,SACN;GACE,eAAe,QAAA;GACf,oBAAoB,QAAA;GACpB,mBAAmB,QAAA;GACpB,EACD;GACE;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CACF;EAED,MAAM,qBAAqB,QAAA,eAAe,QAAA,QAAQ,KAAK;EAEvD,MAAM,EACJ,gBACA,cACA,cACA,WACA,cACA,kBACA,kBACA,eACA,kBACA,2BACA,kBACE,gBAA+B;GACjC,YAAY;GACZ,SAAM,QAAA;GACN,UAAO,QAAA;GACP,SAAS;GACT,aAAa,QAAA;GACb;GACA;GACA;GACA,iBAAc,QAAA;GACd,cAAW,QAAA;GACX;GACA;GACA;GACD,CAAC;EAEF,MAAM,EACJ,mBACA,4BACA,SACA,sBACA,OACA,kBACE,kCACF;GACE,aAAa,QAAA;GACb,mBAAmB,QAAA;GACnB;GACD,EACD;GACE;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,cAAc,SAAsB;AAAE,aAAS,KAAK;;GACpD;GACA;GACA;GACA;GACD,CACF;EAED,MAAM,EACJ,YAAY,iBACZ,YAAY,iBACZ,oBAAoB,yBACpB,gBAAgB,qBAChB,eAAe,uBACb,qBACF;GACE,mBAAmB,QAAA;GACnB,gBAAgB,QAAA;GAChB;GACD,EACD;GACE;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CACF;EAED,MAAM,gBAAgB,eACd,KAAK,IAAI,GAAG,MAAI,0BAA0B,CAAC,OAAO,GAAG,mBAC5D;EAED,MAAM,EAAE,UAAU,eAAe,wBACzB,QAAA,qBACA,QAAA,gBACP;EAED,MAAM,WAAW,eAAwB,MAAI,MAAM,CAAC,SAAS,EAAE;EAE/D,MAAM,kBAAkB,eAAuB;AAC7C,OAAI,MAAI,mBAAmB,CACzB,QAAO,QAAA;AACT,UAAO;IACP;EAEF,MAAM,WAAW,eAAwB,QAAA,YAAY,WAAW;EAChE,MAAM,QAAQ,gBAAyB,MAAI,OAAO,IAAI,MAAI,SAAS,IAAI,MAAI,mBAAmB,KAAK,MAAI,SAAS,CAAC;EAEjH,MAAM,aAAa,eAAuB;AACxC,OAAI,CAAC,MAAI,MAAM,IAAI,CAAC,QAAA,MAClB,QAAO;AACT,UAAO,QAAA,WAAW,GAAG,QAAA,MAAM,MAAM,QAAA;IACjC;EAEF,MAAM,KAAK,eAAsD,mBAAmB;GAClF,QAAQ,QAAA,YAAY;GACpB,UAAU,MAAI,SAAS;GACvB,OAAO,MAAI,MAAM;GACjB,QAAQ,MAAI,OAAO;GACnB,SAAS,MAAI,UAAU;GACvB,OAAI,QAAA;GACJ,UAAO,QAAA;GACP,UAAU,QAAA;GACV,UAAU,MAAI,SAAS;GACvB,YAAY,MAAI,WAAW,IAAI,CAAC,MAAI,SAAA;GACrC,CAAC,CAAC;EAEH,MAAM,mBAAmB,mBAAmB,EAAE,CAAC,CAAC,aAAa;EAE7D,SAAS,kBAAkB,OAAoB;GAC7C,MAAM,SAAS,MAAM;AACrB,OAAI,EAAE,kBAAkB,kBACtB;GAEF,MAAM,QAAQ,OAAO;AACrB,SAAI,QAAQ,KAAK;AACjB,wBAAqB,MAAM;AAC3B,SAAI,YAAY,MAAM;;EAGxB,eAAe,SAAS,KAAY,gBAAgB,OAAsB;GACxE,MAAM,aAAa,MAAI,SAAS;AAEhC,OAAI,YAAY;IACd,MAAM,WAAW,CAAC,GAAG,MAAI,MAAM,CAAC;IAChC,MAAM,eAAe,iBAAiB,IAAI;AAC1C,QAAI,iBAAiB,IAAI;AACvB,2BAAsB;AACtB,cAAS,KAAK,IAAI;UAGlB,UAAS,OAAO,cAAc,EAAE;AAElC,UAAI,OAAO,SAAS;UAEjB;AACH,QAAI,MAAI,yBAAyB,CAC/B,sBAAqB,QAAQ,IAAI,CAAC;QAC/B,uBAAsB;AAE3B,UAAI,OAAO,CAAC,IAAI,CAAC;;AAGnB,OAAI,CAAC,WACH,KAAI,CAAC,eAAe;AAClB,UAAI,kBAAkB,KAAK;AAC3B,UAAI,UAAU,EAAE,OAAO;AACvB,UAAM,eAAe;AACnB,WAAI,QAAQ,MAAM;MAClB;SAGF,OAAI,QAAQ,MAAM;YAGb,CAAC,cACR,OAAI,oBAAoB,KAAK;;EAIjC,SAAS,mBAAyB;GAChC,MAAM,kBAAkB,MAAI,eAAe;AAC3C,OAAI,CAAC,gBACH;AAGF,YADwB,uBAAuB,gBAAgB,EAC5C,KAAK;;EAG1B,SAAS,QAAc;AACrB,yBAAsB;AACtB,SAAI,YAAa,MAAM,QAAQ,MAAI,WAAW,CAAC,GAAG,EAAE,GAAG,KAAA,EAA6C;;EAGtG,SAAS,UAAU,MAAa,OAAwC;AACtE,UAAO;IACL,cAAc;IACd,cAAc,cAAc,KAAK;IACjC,cAAc,UAA+B;KAC3C,MAAM,EAAE,QAAQ;AAChB,SAAI,CAAC,aAAa,SAAS,CAAC,SAAS,IAAI,EAAE;AACzC,YAAM,iBAAiB;AACvB,YAAM,gBAAgB;AACtB,eAAS,KAAK;;;IAGlB,YAAY,MAAwB;AAClC,OAAE,iBAAiB;AACnB,mBAAc,MAAM;;IAEtB,uBAA6B;AAC3B,cAAS,KAAK;;IAEjB;;EAGH,SAAS,kBAAkB,OAAe,KAAmB;AAC3D,SAAI,oBAAoB,KAAK;AAC7B,SAAI,UAAU,EAAE,oBAAoB,OAAO,IAAI;;EAGjD,SAAS,aAAa,OAAyB;AAC7C,OAAI,MAAI,OAAO,EAAE;AACf,UAAI,QAAQ,MAAM;AAClB,UAAM,iBAAiB;;;EAI3B,SAAS,WAAiB;AACxB,SAAI,QAAQ,KAAK;;EAGnB,SAAS,YAAkB;AACzB,SAAI,QAAQ,MAAM;;AAIpB,cAAY,QAAA,UAAU,MAAM,QAAQ;AAClC,OAAI,SAAS,OAAO,QAAA,YAClB;AAGF,OAAI,QAAQ,MAAM,IAAI,CACpB;AAEF,eAAY,MAAI,MAAM,CAAC;IACvB;AAEF,WAAa;GACX;GACA,OAAO;GACP;GACA;GACD,CAAC;;uBAIA,YAuQU,iBAvQV,WAuQU;gBAtQC,MAAA,OAAM;0FAAA,QAAA,SAAA;;OACF,MAAA,aAAY,CAACA,KAAAA,QAAM,EAAA,CAAA;IAAA,GAAU,QAAA;IAAW,EAAA;IACpD,OAAO,MAAA,GAAE,CAAC,QAAO,EAAA,OAAU,MAAA,GAAE,CAACA,KAAAA,OAAO,MAAK,EAAA,CAAA;IAC3C,WAAU;IACT,0BAAwB;IACxB,cAAY;IACZ,8BAA4B;IAC5B,cAAU,CAAA,EAAA,QAAoB,MAAA,0BAAyB,CAAC,WAAM,KAAU,QAAA,eAAW,CAAK,MAAK,YAAA,EAAqB,QAAA,aAAa,UAAA;IAI/H,kBAAgB,QAAA;IAChB,oBAAkB,QAAA;IAClB,MAAM,QAAA;IACN,OAAO,QAAA;IACP,gBAAY,CAAG,QAAA;IACf,UAAU,QAAA;IACX,sBAAA;;IAEW,WAAS,SA6KX,EA7Ke,OAAO,MAAI,UAAY,cAAY,YAAc,qBAAc,CACrF,WA4KO,KAAA,QAAA,aAAA,eAAA,mBAAA;KAAA,UA1KK,QAAA;KAAQ,OAAE,MAAA,MAAK;KAAA,SAAE,QAAA;KAAO,UAAE,QAAA;KAAU;KAAO;KAAI,UAAY;KAAY,YAAc;KAAc,CAAA,CAAA,QA0KxG,CAxKL,mBA+JM,OA/JN,WA+JM;cA9JA;KAAJ,KAAI;KACH,OAAO,MAAA,GAAE,CAAC,UAAS,EAAA,OAAU,MAAA,GAAE,CAAC,QAAA,YAAY,MAAK,IAAK,QAAA,YAAU,CAAA;;QACxC,MAAA,gBAAe,CAACA,KAAAA,QAAM,CAAA,WAAA,QAAA,CAAA;QAAyC,QAAA,WAAQ,EAAA,GAAQ;;KAIxG,MAAK;KACJ,iBAAe;KACf,iBAAe,QAAA,YAAY,KAAA;KAC3B,iBAAe,QAAA,YAAY,KAAA;KAC3B,iBAAe,QAAA,YAAY,KAAA;KAC3B,aAAW,QAAA,WAAW,KAAA;KACvB,WAAQ;KACP,gBAAc,MAAA,SAAQ;KACtB,UAAU,QAAA,YAAY,QAAA,WAAQ,KAAA;KAC9B,cAAU,OAAA,OAAA,OAAA,MAAA,WAAE,UAAA,QAAS;KACrB,cAAU,OAAA,OAAA,OAAA,MAAA,WAAE,UAAA,QAAS;KACrB,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,mBAAkB,EAAA;KACzB,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,wBAAuB,EAAA;KAC9B,WAAO;qDAAQ,MAAA,QAAO,CAAC,OAAM,EAAA,CAAA,QAAA,CAAA;uDAChB,MAAA,MAAK,CAAC,OAAM,EAAA,CAAA,MAAA,CAAA;uDACX,MAAA,2BAA0B,CAAC,QAAM,MAAA,EAAA,CAAA,OAAA,CAAA;uDAChC,MAAA,2BAA0B,CAAC,QAAM,KAAA,EAAA,CAAA,QAAA,CAAA;qEAC5B,MAAA,cAAa,CAAA,KAAA,EAAA,CAAA,UAAA,CAAA,EAAA,CAAA,KAAA,CAAA;qEACX,MAAA,cAAa,CAAA,MAAA,EAAA,CAAA,UAAA,CAAA,EAAA,CAAA,OAAA,CAAA;qEACb,iBAAA,QAAgB,GAAA,CAAA,UAAA,CAAA,EAAA,CAAA,OAAA,CAAA;qEACjB,iBAAA,QAAmB,MAAA,0BAAyB,CAAC,SAAM,GAAA,CAAA,UAAA,CAAA,EAAA,CAAA,MAAA,CAAA;;;KAGjE,MAAA,SAAQ,IAAA,CAAM,MAAA,SAAQ,IAAA,CAAK,MAAA,mBAAkB,IAAA,WAAA,EADrD,mBAmBO,QAAA;;MAjBJ,OAAK,eAAA,CAAkB,MAAA,GAAE,CAAC,OAAK,EAAA,EAAA,QAAA,CAA6B,MAAA,SAAQ,IAAA,CAAK,QAAQ,MAAA,SAAQ,EAAA,CAAA,CAAA;SAK1F,WAKO,KAAA,QAAA,mBAAA,eAAA,mBAAA,EAAA,OAHK,MAAA,MAAK,EAAA,CAAA,CAAA,QAGV,CAAA,gBAAA,gBADF,QAAA,MAAK,EAAA,EAAA,CAAA,CAAA,EAGF,QAAA,YAAA,WAAA,EADR,mBAKO,QAAA;;MAHJ,OAAK,eAAE,MAAA,GAAE,CAAC,UAAQ,CAAA;QACpB,OAED,EAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA;KAEF,mBAqEM,OAAA;MApEJ,WAAQ;MACP,OAAK,eAAE,MAAA,GAAE,CAAC,OAAK,CAAA;2BAEhB,mBAkDW,UAAA,MAAA,WAjDW,MAAA,MAAK,GAAjB,MAAM,MAAC;8DACT,MAAA,cAAa,CAAC,KAAI,EAAA,EAAA,CAGhB,QAAA,SAAA,WAAA,EADR,YAwBU,iBAxBV,WAwBU;OAtBP,KAAK,MAAA,aAAY,CAAC,MAAA,cAAa,CAAC,KAAI,CAAA;OACrC,UAAS;OACR,MAAM,QAAA,QAAK,OAAA;OACZ,WAAA;OACC,OAAK,EAAA,aAAiB,QAAA,OAAK;OAC5B,WAAA;4BACQ,UAAU,MAAM,EAAC,CAAA,EAAA;8BAenB,CAbN,mBAaM,OAbN,YAaM,CAZJ,WAIE,KAAA,QAAA,qBAJF,WAIE,EAFC,OAAO,GAAC,EAAA,EAAA,SAAA,MAAA,EAAA,EACC,MAAI,CAAA,CAAA,EAEhB,WAMO,KAAA,QAAA,aANP,WAMO,EALJ,OAAO,GAAC,EAAA,EAAA,SAAA,MAAA,EAAA;QAEC;QAAI,WAAa,UAAU,MAAM,EAAA;QAAC,CAAA,QAGvC,CAAA,gBAAA,gBADF,MAAA,QAAO,CAAC,KAAI,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;qCAKW,MAAA,SAAQ,IAAA,CAA0B,MAAA,mBAAkB,KAAK,MAAK,wBAAyB,MAAM,cAAA,WAAA,EAD7H,mBAoBM,OAAA;;OAfH,OAAK,eAAE,QAAA,uBAAoB,aAAA,OAAA;UAE5B,WAIE,KAAA,QAAA,qBAJF,WAIE,EAFC,OAAO,GAAC,EAAA,EAAA,SAAA,MAAA,EAAA,EACC,MAAI,CAAA,CAAA,EAGR,MAAA,SAAQ,IAAI,MAAM,YAD1B,WAOO,KAAA,QAAA,aAPP,WAOO;;OALJ,OAAO;;OAEE;OAAI,WAAa,UAAU,MAAM,EAAA;OAAC,CAAA,QAGvC,CAAA,gBAAA,gBADF,MAAA,QAAO,CAAC,KAAI,CAAA,EAAA,EAAA,CAAA,CAAA,GAAA,mBAAA,IAAA,KAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,EAAA,GAAA;gBAIrB,mBAaE,SAAA;eAZI;MAAJ,KAAI;MACH,UAAU,QAAA;MACV,OAAO,MAAA,eAAc;MACtB,OAAK,eAAA,CAAC,+BAA6B,CAG1B,MAAA,gBAAe,EAAA,EAAA,QAAY,QAAA,iBAAe,CAAA,CAAA,CAAA;MAFnD,MAAK;MACJ,aAAa,MAAA,gBAAe;MAE5B,gBAAc,MAAA,SAAQ;MACvB,qBAAkB;MACjB,WAAO,OAAA,OAAA,OAAA,KAAA,UAAA,WAAS,MAAA,qBAAoB,EAAA,EAAA,CAAA,SAAA,CAAA;MACpC,SAAK,OAAA,OAAA,OAAA,KAAA,eAAA,WAAO,kBAAkB,OAAM,EAAA,CAAA,OAAA,CAAA;MACpC,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,oBAAmB,EAAA;;KAKvB,QAAA,aAAa,MAAA,SAAQ,IAAA,CAAK,QAAA,YAAA,WAAA,EADlC,YAmBY,mBAAA;;MAjBV,SAAQ;MACR,MAAA;MACA,MAAK;MACL,UAAS;MACT,OAAM;MACN,WAAQ;MACP,OAAK,eAAA;OAAkB,MAAA,GAAE,CAAC,OAAK;OAAkB,MAAA,gBAAe,IAAA;kBAAyC,QAAA,OAAA;;MAKzG,SAAK,OAAA,OAAA,OAAA,KAAA,eAAA,WAAe,OAAK,EAAA,CAAA,QAAA,UAAA,CAAA;;6BAKxB,CAHF,YAGE,iBAAA;OAFA,MAAK;OACL,MAAK;;;;KAIT,mBASO,QAAA;MARJ,OAAK,eAAE,MAAA,GAAE,CAAC,aAAW,CAAA;MACrB,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,aAAa,OAAM;SAE3B,YAIE,iBAAA;MAHC,OAAK,eAAE,MAAA,GAAE,CAAC,MAAI,CAAA;MACd,MAAM,QAAA,QAAK,KAAA;MACZ,MAAK;;KAKD,QAAA,WAAA,WAAA,EADR,YAME,qBAAA;;MAJC,OAAK,eAAE,MAAA,GAAE,CAAC,UAAQ,CAAA;MACnB,OAAM;MACN,WAAU;MACV,SAAQ;;wBAIJ,MAAA,SAAQ,IAAA,WAAA,EADhB,mBAOW,YAAA;;KALR,OAAK,eAAE,MAAA,GAAE,CAAC,UAAQ,CAAA;QAEnB,mBAES,UAAA,EAFA,OAAK,eAAE,MAAA,GAAE,CAAC,QAAM,CAAA,EAAA,EAAA,gBACpB,MAAA,WAAU,CAAA,EAAA,EAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA,CAAA,CAAA;IAKV,SAAO,SAkEV,EAlEc,YAAK,CACzB,mBAiEM,OAAA;cAjEG;KAAJ,KAAI;QAEC,MAAA,0BAAyB,CAAC,SAAM,KAAA,WAAA,EADxC,mBA+CM,OAAA;;KA7CH,KAAK,MAAA,eAAc,CAAC;KACpB,OAAK,eAAE,MAAA,GAAE,CAAC,KAAI,EAAA,OAAU,MAAA,GAAE,CAAC,QAAA,YAAY,KAAI,IAAK,QAAA,WAAS,CAAA,CAAA;KACzD,OAAK,eAAA,CAAG,MAAA,eAAc,CAAC,OAAK;MAAA,OAAA,GAAc,MAAK;MAAA,UAAgB,MAAA,UAAS;MAAA,WAAA,GAAgB,MAAA,cAAa,CAAA;MAAA,CAAA,CAAA;KACrG,UAAM,OAAA,QAAA,OAAA,OAAA,GAAA,SAAE,MAAA,eAAc,CAAC,YAAf,MAAA,eAAc,CAAC,SAAQ,GAAA,KAAA;KAC/B,WAAO,CAAA,OAAA,QAAA,OAAA,MAAA,SAAA,eAAA,WAAa,MAAA,cAAa,CAAA,KAAA,EAAA,CAAA,UAAA,CAAA,EAAA,CAAA,KAAA,CAAA,GAAA,OAAA,QAAA,OAAA,MAAA,SAAA,eAAA,WACX,MAAA,cAAa,CAAA,MAAA,EAAA,CAAA,UAAA,CAAA,EAAA,CAAA,OAAA,CAAA,EAAA;QAEpC,mBAqCM,OArCN,WACU,MAoCJ,aApCgB,EAAA;cAChB;KAAJ,KAAI;2BAEJ,mBAgCY,UAAA,MAAA,WA/BiB,MAAA,aAAY,GAAA,EAA9B,MAAM,aAAM;yBADvB,YAgCY,mBAAA;MA9BT,KAAK,MAAA,cAAa,CAAC,KAAI,EAAG,UAAQ;MAClC,QAAQ,MAAA,aAAY,CAAC,KAAI;MACzB,iBAAe,MAAA,aAAY,CAAC,KAAI;MAChC,MAAM,QAAA,QAAK,OAAU,KAAA;MACtB,UAAS;MACT,SAAQ;MACP,oBAAkB,MAAA,iBAAgB,KAAK;MACvC,OAAK,eAAA,GAAqB,MAAA,iBAAgB,GAAA,CAAI,MAAA,aAAY,CAAC,KAAI,IAAK,MAAA,iBAAgB,KAAK,QAAA,CAAA;MAGzF,UAAK,WAAE,SAAS,KAAA;;MAEN,SAAO,cAId,CAHF,WAGE,KAAA,QAAA,gBAHF,WAGE,EAAA,SAAA,MAAA,EAAA;OAAA,UADU,QAAA;OAAU;OAAI,QAAU,MAAA,aAAY,CAAC,KAAA;OAAI,CAAA,CAAA,CAAA,CAAA;MAS5C,QAAM,cAIb,CAHF,WAGE,KAAA,QAAA,eAHF,WAGE,EAAA,SAAA,MAAA,EAAA;OAAA,UADU,QAAA;OAAU;OAAI,QAAU,MAAA,aAAY,CAAC,KAAA;OAAI,CAAA,CAAA,CAAA,CAAA;6BAJhD,CALP,WAKO,KAAA,QAAA,QALP,WAKO,EAAA,SAAA,MAAA,EAAA;OAAA,UAHK,QAAA;OAAU;OAAI,QAAU,MAAA,aAAY,CAAC,KAAA;OAAI,CAAA,QAG9C,CAAA,gBAAA,gBADF,MAAA,QAAO,CAAC,KAAI,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA;;;;;;;;;;8BAaT,QAAA,cAAA,WAAA,EADd,mBAcM,OAAA;;KAZH,OAAK,eAAA;MAAA,OAAA,GAAc,MAAK;MAAA,UAAgB,MAAA,UAAA;MAAS,CAAA;KACjD,OAAK,eAAE,QAAA,YAAY,QAAQ,QAAA,UAAA;QAE5B,WAQO,KAAA,QAAA,WAAA,EAAA,QAAA,CAAA,CANI,QAAA,eAAA,WAAA,EADT,mBAMM,OANN,YAMM,gBADD,QAAA,WAAU,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,EAAA,IAAA,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"RuiAutoComplete.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../../src/components/forms/auto-complete/RuiAutoComplete.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue, TItem\">\nimport type { VueClassValue } from '@/types/class-value';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiChip from '@/components/chips/RuiChip.vue';\nimport { autoCompleteStyles, type AutoCompleteVariant } from '@/components/forms/auto-complete/auto-complete-styles';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiMenu, { type MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport {\n type GroupBy,\n type ItemDisabled,\n type KeyOfType,\n useDropdownMenu,\n useDropdownOptionProperty,\n} from '@/composables/dropdown-menu';\nimport { type FloatingOptions, Placement } from '@/composables/floating';\nimport {\n useAutoCompleteFocus,\n useAutoCompleteKeyboardNavigation,\n useAutoCompleteSearch,\n useAutoCompleteValue,\n} from '@/composables/forms/auto-complete';\nimport { useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs, getTextToken } from '@/utils/helpers';\nimport { isEqual } from '@/utils/is-equal';\nimport { cn } from '@/utils/tv';\n\nexport type AutoCompleteModelValue<TValue> =\n TValue extends Array<infer U> ? U[] : TValue | undefined;\n\nexport interface RuiAutoCompleteClassNames {\n root?: VueClassValue;\n label?: VueClassValue;\n menu?: VueClassValue;\n}\n\nexport interface AutoCompleteProps<TValue, TItem> {\n options?: TItem[];\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem;\n disabled?: boolean;\n loading?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n menuOptions?: MenuProps;\n classNames?: RuiAutoCompleteClassNames;\n /** @deprecated Use `classNames.label` instead */\n labelClass?: string;\n /** @deprecated Use `classNames.menu` instead */\n menuClass?: string;\n prependWidth?: number;\n appendWidth?: number;\n itemHeight?: number;\n variant?: AutoCompleteVariant;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n hideDetails?: boolean;\n autoSelectFirst?: boolean;\n chips?: boolean;\n noFilter?: boolean;\n hideNoData?: boolean;\n noDataText?: string;\n filter?: (item: TItem, queryText: string) => boolean;\n hideSelected?: boolean;\n placeholder?: string;\n returnObject?: boolean;\n customValue?: boolean;\n hideCustomValue?: boolean;\n required?: boolean;\n hideSearchInput?: boolean;\n hideSelectionWrapper?: boolean;\n groupBy?: GroupBy<TItem>;\n itemDisabled?: ItemDisabled<TItem>;\n}\n\ndefineOptions({\n name: 'RuiAutoComplete',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<AutoCompleteModelValue<TValue>>({ required: true });\n\nconst searchInputModel = defineModel<string>('searchInput', { default: '' });\n\nconst {\n options = [],\n disabled = false,\n loading = false,\n readOnly = false,\n dense = false,\n clearable = false,\n hideDetails = false,\n chips = false,\n label = 'Select',\n menuOptions,\n classNames,\n labelClass,\n menuClass,\n variant = 'default',\n hint,\n keyAttr,\n textAttr,\n itemHeight,\n errorMessages = [],\n successMessages = [],\n autoSelectFirst = false,\n noFilter = false,\n hideNoData = false,\n noDataText = 'No data available',\n filter,\n hideSelected = false,\n placeholder = '',\n returnObject = false,\n customValue = false,\n hideCustomValue = false,\n required = false,\n hideSearchInput = false,\n hideSelectionWrapper = false,\n groupBy,\n itemDisabled,\n} = defineProps<AutoCompleteProps<TValue, TItem>>();\n\nconst slots = defineSlots<{\n 'activator'?: (props: {\n disabled: boolean;\n value: TItem[];\n variant: string;\n readOnly: boolean;\n attrs: Record<string, unknown>;\n open: boolean;\n hasError: boolean;\n hasSuccess: boolean;\n }) => any;\n 'activator.label'?: (props: { value: TItem[] }) => any;\n 'selection.prepend'?: (props: { index: number; item: TItem }) => any;\n 'selection'?: (props: { index: number; item: TItem; chipAttrs: Record<string, unknown> }) => any;\n 'item.prepend'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item.append'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'group-header'?: (props: { group: string; items: TItem[] }) => any;\n 'no-data'?: () => any;\n 'placeholder'?: (props: { disabled: boolean; readOnly: boolean }) => any;\n 'footer'?: () => any;\n}>();\n\nconst { getText, getIdentifier } = useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n});\n\nconst textInput = useTemplateRef<HTMLInputElement>('textInput');\nconst activator = useTemplateRef<HTMLDivElement>('activator');\nconst menuRef = useTemplateRef<HTMLDivElement>('menuRef');\nconst menuWrapperRef = useTemplateRef<HTMLDivElement>('menuWrapperRef');\n\nconst { focused: activatorFocusedWithin } = useFocusWithin(activator);\nconst { focused: menuWrapperFocusedWithin } = useFocusWithin(menuWrapperRef);\nconst { focused: searchInputFocused } = useFocus(textInput);\nconst { focused: activatorFocused } = useFocus(activator);\n\nconst {\n internalSearch,\n filteredOptions,\n justOpened,\n updateInternalSearch,\n textValueToProperValue,\n} = useAutoCompleteSearch<TItem>(\n () => options,\n searchInputModel,\n {\n keyAttr: () => keyAttr,\n textAttr: () => textAttr,\n noFilter: () => noFilter,\n filter: () => filter,\n customValue: () => customValue,\n hideCustomValue: () => hideCustomValue,\n returnObject: () => returnObject,\n },\n);\n\nconst isOpen = ref<boolean>(false);\nconst isHovered = ref<boolean>(false);\n\n// Calculate multiple from modelValue directly to avoid circular dependency\nconst multiple = computed<boolean>(() => Array.isArray(get(modelValue)));\n\nconst shouldApplyValueAsSearch = computed<boolean>(\n () => !(slots.selection || get(multiple) || chips),\n);\n\nconst { value, setSelected } = useAutoCompleteValue<AutoCompleteModelValue<TValue>, TItem>(\n modelValue,\n () => options,\n {\n keyAttr: () => keyAttr,\n returnObject: () => returnObject,\n customValue: () => customValue,\n },\n {\n getIdentifier,\n getText,\n textValueToProperValue,\n shouldApplyValueAsSearch,\n isOpen,\n multiple,\n updateInternalSearch,\n },\n);\n\nconst resolvedItemHeight = itemHeight ?? (dense ? 30 : 48);\n\nconst {\n containerProps,\n wrapperProps,\n renderedData,\n menuWidth,\n isActiveItem,\n itemIndexInValue,\n highlightedIndex,\n moveHighlight,\n applyHighlighted,\n optionsWithSelectedHidden,\n userNavigated,\n groupedOptions,\n isGrouped,\n isItemDisabled,\n} = useDropdownMenu<TValue, TItem>({\n itemHeight: resolvedItemHeight,\n keyAttr,\n textAttr,\n options: filteredOptions,\n dense: () => dense,\n value,\n menuRef,\n setValue,\n autoSelectFirst,\n hideSelected,\n isOpen,\n getText,\n getIdentifier,\n groupBy: () => groupBy,\n itemDisabled: () => itemDisabled,\n});\n\nconst {\n focusedValueIndex,\n moveSelectedValueHighlight,\n onEnter,\n onInputDeletePressed,\n onTab,\n setValueFocus,\n} = useAutoCompleteKeyboardNavigation<TItem>(\n {\n chips: () => chips,\n customValue: () => customValue,\n multiple,\n },\n {\n activator,\n applyHighlighted,\n clear,\n filteredOptions,\n getText,\n highlightedIndex,\n internalSearch,\n isOpen,\n removeValue: (item: TItem): void => { setValue(item); },\n searchInputFocused,\n setSearchAsValue,\n userNavigated,\n value,\n },\n);\n\nconst {\n anyFocused: focusAnyFocused,\n inputClass: focusInputClass,\n onActivatorFocused: focusOnActivatorFocused,\n onInputFocused: focusOnInputFocused,\n setInputFocus: focusSetInputFocus,\n} = useAutoCompleteFocus(\n {\n customValue: () => customValue,\n disabled: () => disabled,\n shouldApplyValueAsSearch,\n },\n {\n activatorFocused,\n activatorFocusedWithin,\n focusedValueIndex,\n internalSearch,\n isOpen,\n justOpened,\n menuWrapperFocusedWithin,\n searchInputFocused,\n setSearchAsValue,\n textInput,\n updateInternalSearch,\n },\n);\n\nconst menuMinHeight = computed<number>(\n () => Math.min(5, get(optionsWithSelectedHidden).length) * resolvedItemHeight,\n);\n\nconst { hasError, hasSuccess } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\n\nconst valueSet = computed<boolean>(() => get(value).length > 0);\n\n// True when the consumer's #placeholder slot is taking over the resting\n// content area, so the outlined/resting label must hide to avoid overlapping\n// the slot content.\nconst placeholderSlotActive = computed<boolean>(() => Boolean(slots.placeholder) && !get(valueSet) && !get(searchInputFocused));\n\nconst usedPlaceholder = computed<string>(() => {\n if (get(searchInputFocused))\n return placeholder;\n return '';\n});\n\nconst outlined = computed<boolean>(() => variant === 'outlined');\nconst float = computed<boolean>(() => (get(isOpen) || get(valueSet) || get(searchInputFocused)) && get(outlined));\n\nconst legendText = computed<string>(() => {\n if (!get(float) || !label)\n return '';\n return required ? `${label} ﹡` : label;\n});\n\nconst ui = computed<ReturnType<typeof autoCompleteStyles>>(() => autoCompleteStyles({\n filled: variant === 'filled',\n outlined: get(outlined),\n float: get(float),\n opened: get(isOpen),\n hovered: get(isHovered),\n dense,\n disabled,\n readonly: readOnly,\n hasError: get(hasError),\n hasSuccess: get(hasSuccess) && !get(hasError),\n}));\n\nconst highlightedClass = autoCompleteStyles({}).highlighted();\n\nfunction updateSearchInput(event: Event): void {\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n\n const value = target.value;\n set(isOpen, true);\n updateInternalSearch(value);\n set(justOpened, false);\n}\n\nasync function setValue(val: TItem, skipRefocused = false): Promise<void> {\n const isMultiple = get(multiple);\n\n if (isMultiple) {\n const newValue = [...get(value)];\n const indexInValue = itemIndexInValue(val);\n if (indexInValue === -1) {\n updateInternalSearch();\n newValue.push(val);\n }\n else {\n newValue.splice(indexInValue, 1);\n }\n set(value, newValue);\n }\n else {\n if (get(shouldApplyValueAsSearch))\n updateInternalSearch(getText(val));\n else updateInternalSearch();\n\n set(value, [val]);\n }\n\n if (!isMultiple) {\n if (!skipRefocused) {\n set(activatorFocused, true);\n get(activator)?.focus();\n await nextTick(() => {\n set(isOpen, false);\n });\n }\n else {\n set(isOpen, false);\n }\n }\n else if (!skipRefocused) {\n set(searchInputFocused, true);\n }\n}\n\nfunction setSearchAsValue(): void {\n const searchToBeValue = get(internalSearch);\n if (!searchToBeValue)\n return;\n\n const newValue: TItem = textValueToProperValue(searchToBeValue);\n setValue(newValue, true);\n}\n\nfunction clear(): void {\n updateInternalSearch();\n set(modelValue, (Array.isArray(get(modelValue)) ? [] : undefined) as AutoCompleteModelValue<TValue>);\n}\n\nfunction chipAttrs(item: TItem, index: number): Record<string, unknown> {\n return {\n 'data-index': index,\n 'data-value': getIdentifier(item),\n 'onKeydown': (event: KeyboardEvent): void => {\n const { key } = event;\n if (['Backspace', 'Delete'].includes(key)) {\n event.stopPropagation();\n event.preventDefault();\n setValue(item);\n }\n },\n 'onClick': (e: MouseEvent): void => {\n e.stopPropagation();\n setValueFocus(index);\n },\n 'onClick:close': (): void => {\n setValue(item);\n },\n };\n}\n\nfunction setSelectionRange(start: number, end: number): void {\n set(searchInputFocused, true);\n get(textInput)?.setSelectionRange?.(start, end);\n}\n\nfunction arrowClicked(event: MouseEvent): void {\n if (get(isOpen)) {\n set(isOpen, false);\n event.stopPropagation();\n }\n}\n\nfunction openMenu(): void {\n set(isOpen, true);\n}\n\nfunction closeMenu(): void {\n set(isOpen, false);\n}\n\n// Optimize options watcher with shallow comparison first\nwatch(() => options, (curr, old) => {\n if (curr === old || customValue)\n return;\n\n // Only do deep comparison if reference changed\n if (isEqual(curr, old))\n return;\n\n setSelected(get(value));\n});\n\nconst menuFloatingOptions = computed<FloatingOptions>(() => ({\n placement: Placement.bottomStart,\n ...menuOptions?.options,\n}));\n\ndefineExpose({\n closeMenu,\n focus: focusSetInputFocus,\n openMenu,\n setSelectionRange,\n});\n</script>\n\n<template>\n <RuiMenu\n v-model=\"isOpen\"\n v-bind=\"{ ...getRootAttrs($attrs, []), ...menuOptions }\"\n :class=\"ui.wrapper({ class: cn($attrs.class) })\"\n :options=\"menuFloatingOptions\"\n :close-on-content-click=\"false\"\n :full-width=\"true\"\n :persist-on-activator-click=\"true\"\n :menu-class=\"[\n { hidden: optionsWithSelectedHidden.length === 0 && customValue && !slots['no-data'] },\n menuOptions?.menuClass,\n ]\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n :dense=\"dense\"\n :show-details=\"!hideDetails\"\n :disabled=\"disabled\"\n disable-auto-focus\n >\n <template #activator=\"{ attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\">\n <slot\n name=\"activator\"\n v-bind=\"{ disabled, value, variant, readOnly, attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\"\n >\n <div\n ref=\"activator\"\n :class=\"ui.activator({ class: cn(classNames?.label) ?? labelClass })\"\n v-bind=\"{\n ...getNonRootAttrs($attrs, ['onClick', 'class']),\n ...(readOnly ? {} : attrs),\n }\"\n role=\"combobox\"\n :aria-expanded=\"open\"\n :aria-disabled=\"disabled || undefined\"\n :aria-readonly=\"readOnly || undefined\"\n :aria-required=\"required || undefined\"\n :aria-busy=\"loading || undefined\"\n data-id=\"activator\"\n :aria-invalid=\"hasError\"\n :tabindex=\"disabled || readOnly ? -1 : 0\"\n @mouseenter=\"isHovered = true\"\n @mouseleave=\"isHovered = false\"\n @click=\"focusSetInputFocus()\"\n @focus=\"focusOnActivatorFocused()\"\n @keydown.enter=\"onEnter($event)\"\n @keydown.tab=\"onTab($event)\"\n @keydown.left=\"moveSelectedValueHighlight($event, false)\"\n @keydown.right=\"moveSelectedValueHighlight($event, true)\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n @keydown.home.prevent=\"highlightedIndex = 0\"\n @keydown.end.prevent=\"highlightedIndex = optionsWithSelectedHidden.length - 1\"\n >\n <span\n v-if=\"(outlined || (!valueSet && !searchInputFocused)) && !placeholderSlotActive\"\n :class=\"[\n ui.label(),\n { 'pr-2': !valueSet && !open && outlined },\n ]\"\n >\n <slot\n name=\"activator.label\"\n v-bind=\"{ value }\"\n >\n {{ label }}\n </slot>\n <span\n v-if=\"required\"\n :class=\"ui.required()\"\n >\n ﹡\n </span>\n </span>\n <div\n data-id=\"value\"\n :class=\"ui.value()\"\n >\n <!--\n Placeholder slot occupies the same flex space the input takes\n when focused, so transitioning into the focused state doesn't\n shift the activator's content. pointer-events-none is required\n so clicks pass through to the activator (otherwise the slot\n swallows the first click and the menu needs two taps to open).\n -->\n <div\n v-if=\"!valueSet && !searchInputFocused && slots.placeholder\"\n data-id=\"placeholder\"\n class=\"flex-1 min-w-0 pointer-events-none\"\n >\n <slot\n name=\"placeholder\"\n v-bind=\"{ disabled, readOnly }\"\n />\n </div>\n <template\n v-for=\"(item, i) in value\"\n :key=\"getIdentifier(item)\"\n >\n <RuiChip\n v-if=\"chips\"\n :key=\"getTextToken(getIdentifier(item))\"\n tabindex=\"-1\"\n :size=\"dense ? 'sm' : 'md'\"\n closeable\n :class=\"{ 'leading-3': dense }\"\n clickable\n v-bind=\"chipAttrs(item, i)\"\n >\n <div class=\"flex\">\n <slot\n name=\"selection.prepend\"\n :index=\"i\"\n v-bind=\"{ item }\"\n />\n <slot\n :index=\"i\"\n name=\"selection\"\n v-bind=\"{ item, chipAttrs: chipAttrs(item, i) }\"\n >\n {{ getText(item) }}\n </slot>\n </div>\n </RuiChip>\n <div\n v-else-if=\"\n multiple\n || (!searchInputFocused && (slots['selection.prepend'] || slots.selection))\n \"\n :class=\"hideSelectionWrapper ? 'contents' : 'flex'\"\n >\n <slot\n name=\"selection.prepend\"\n :index=\"i\"\n v-bind=\"{ item }\"\n />\n <slot\n v-if=\"multiple || slots.selection\"\n :index=\"i\"\n name=\"selection\"\n v-bind=\"{ item, chipAttrs: chipAttrs(item, i) }\"\n >\n {{ getText(item) }}\n </slot>\n </div>\n </template>\n <input\n ref=\"textInput\"\n :disabled=\"disabled\"\n :value=\"internalSearch\"\n class=\"bg-transparent outline-none\"\n type=\"text\"\n :placeholder=\"usedPlaceholder\"\n :class=\"[focusInputClass, { hidden: hideSearchInput }]\"\n :aria-invalid=\"hasError\"\n aria-autocomplete=\"list\"\n @keydown.delete=\"onInputDeletePressed()\"\n @input.stop=\"updateSearchInput($event)\"\n @focus=\"focusOnInputFocused()\"\n />\n </div>\n\n <RuiButton\n v-if=\"clearable && valueSet && !disabled\"\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n color=\"error\"\n data-id=\"clear\"\n :class=\"[\n ui.clear(),\n focusAnyFocused && '!visible',\n { 'mr-2': !dense },\n ]\"\n @click.stop.prevent=\"clear()\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"18\"\n />\n </RuiButton>\n\n <span\n :class=\"ui.iconWrapper()\"\n @click=\"arrowClicked($event)\"\n >\n <RuiIcon\n :class=\"ui.icon()\"\n :size=\"dense ? 16 : 24\"\n name=\"lu-chevron-down\"\n />\n </span>\n\n <RuiProgress\n v-if=\"loading\"\n :class=\"ui.progress()\"\n color=\"primary\"\n thickness=\"3\"\n variant=\"indeterminate\"\n />\n </div>\n <fieldset\n v-if=\"outlined\"\n :class=\"ui.fieldset()\"\n >\n <legend :class=\"ui.legend()\">\n {{ legendText }}\n </legend>\n </fieldset>\n </slot>\n </template>\n <template #default=\"{ width }\">\n <div ref=\"menuWrapperRef\">\n <div\n v-if=\"optionsWithSelectedHidden.length > 0\"\n :ref=\"containerProps.ref\"\n :class=\"ui.menu({ class: cn(classNames?.menu) ?? menuClass })\"\n :style=\"[containerProps.style, { width: `${width}px`, minWidth: menuWidth, minHeight: `${menuMinHeight}px` }]\"\n @scroll=\"containerProps.onScroll\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n >\n <div\n v-if=\"isGrouped\"\n ref=\"menuRef\"\n >\n <template\n v-for=\"(bucket, bucketIndex) in groupedOptions\"\n :key=\"bucket.group || `group-${bucketIndex}`\"\n >\n <div\n class=\"sticky top-0 z-10 bg-white dark:bg-rui-grey-900\"\n data-id=\"group-header\"\n >\n <slot\n name=\"group-header\"\n v-bind=\"{ group: bucket.group, items: bucket.items }\"\n >\n <div class=\"px-3 py-1 text-xs uppercase tracking-wide text-rui-text-secondary\">\n {{ bucket.group }}\n </div>\n </slot>\n </div>\n <RuiButton\n v-for=\"item in bucket.items\"\n :key=\"getIdentifier(item)?.toString()\"\n :active=\"isActiveItem(item)\"\n :aria-selected=\"isActiveItem(item)\"\n :size=\"dense ? 'sm' : undefined\"\n :disabled=\"isItemDisabled(item)\"\n tabindex=\"0\"\n variant=\"list\"\n :data-highlighted=\"optionsWithSelectedHidden.indexOf(item) === highlightedIndex\"\n :data-disabled=\"isItemDisabled(item) || undefined\"\n :class=\"{\n [highlightedClass]: !isActiveItem(item) && optionsWithSelectedHidden.indexOf(item) === highlightedIndex,\n }\"\n @click=\"!isItemDisabled(item) && setValue(item)\"\n >\n <template #prepend>\n <slot\n name=\"item.prepend\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n >\n {{ getText(item) }}\n </slot>\n <template #append>\n <slot\n name=\"item.append\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n </RuiButton>\n </template>\n </div>\n <div\n v-else\n v-bind=\"wrapperProps\"\n ref=\"menuRef\"\n >\n <RuiButton\n v-for=\"{ item, _index } in renderedData\"\n :key=\"getIdentifier(item)?.toString()\"\n :active=\"isActiveItem(item)\"\n :aria-selected=\"isActiveItem(item)\"\n :size=\"dense ? 'sm' : undefined\"\n :disabled=\"isItemDisabled(item)\"\n tabindex=\"0\"\n variant=\"list\"\n :data-highlighted=\"highlightedIndex === _index\"\n :data-disabled=\"isItemDisabled(item) || undefined\"\n :class=\"{\n [highlightedClass]: !isActiveItem(item) && highlightedIndex === _index,\n }\"\n @click=\"!isItemDisabled(item) && setValue(item)\"\n >\n <template #prepend>\n <slot\n name=\"item.prepend\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n >\n {{ getText(item) }}\n </slot>\n <template #append>\n <slot\n name=\"item.append\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n </RuiButton>\n </div>\n </div>\n\n <div\n v-else-if=\"!hideNoData\"\n :style=\"{ width: `${width}px`, minWidth: menuWidth }\"\n :class=\"classNames?.menu ?? menuClass\"\n >\n <slot name=\"no-data\">\n <div\n v-if=\"!customValue\"\n class=\"p-4\"\n data-id=\"no-data\"\n >\n {{ noDataText }}\n </div>\n </slot>\n </div>\n <!--\n The scroll container above reserves ~15px on the right for the\n scrollbar gutter. We render an equivalent right-padding here so the\n footer's content aligns with the option rows' content rather than\n the menu's outer edge. `pr-[var(--rui-scrollbar-gutter,15px)]`\n lets consumers override if their theme reserves a different width.\n -->\n <div\n v-if=\"slots.footer\"\n class=\"bg-white dark:bg-rui-grey-900 border-t border-black/[0.12] dark:border-white/[0.12] pr-[var(--rui-scrollbar-gutter,15px)] -mb-2\"\n data-id=\"footer\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </template>\n </RuiMenu>\n</template>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import RuiFileUpload_vue_vue_type_script_setup_true_lang_default from "./RuiFileUpload.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/components/forms/file-upload/RuiFileUpload.vue
|
|
3
|
+
var RuiFileUpload_default = RuiFileUpload_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { RuiFileUpload_default as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=RuiFileUpload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RuiFileUpload.js","names":[],"sources":["../../../../src/components/forms/file-upload/RuiFileUpload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { useFormTextDetail } from '@/utils/form-text-detail';\nimport { formatFileSize, getNonRootAttrs, getRootAttrs } from '@/utils/helpers';\n\nexport interface FileUploadProps {\n /** File type filter (HTML accept attribute syntax). e.g. '.csv', 'image/*', '.png,.jpg' */\n accept?: string;\n /** Allow multiple file selection. */\n multiple?: boolean;\n disabled?: boolean;\n /** Shows a loading overlay (consumer-driven, e.g. while uploading). */\n loading?: boolean;\n /** Upload progress 0-100. When provided alongside `loading`, the overlay shows a determinate progress bar with percentage. */\n progress?: number;\n /** Renders the success state border/icon. Consumer toggles back to false. */\n uploaded?: boolean;\n /** Optional max size per file in bytes; failures emit `error` and set internal error state. */\n maxSize?: number;\n /** External error messages (e.g. from Vuelidate). Shown via the standard form detail block. */\n errorMessages?: string | string[];\n /** Hint text below the dropzone. */\n hint?: string;\n /** Disable drag-and-drop; the dropzone becomes click-only (matches rotki.com use case). */\n noDrop?: boolean;\n /** Replace the default \"Drag and drop or {button}\" copy. */\n uploadText?: string;\n /** Label shown on the inline button when no file is selected. */\n clickToUploadText?: string;\n /** Label shown on the inline button when one or more files are already selected. */\n replaceText?: string;\n /** Hide the bottom hint/error details strip. */\n hideDetails?: boolean;\n}\n\ndefineOptions({\n name: 'RuiFileUpload',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<File | File[] | undefined>({ required: true });\n\nconst {\n accept = '*',\n multiple = false,\n disabled = false,\n loading = false,\n progress = undefined,\n uploaded = false,\n maxSize = undefined,\n errorMessages = [],\n hint = '',\n noDrop = false,\n uploadText = 'Drag and drop or',\n clickToUploadText = 'click to upload',\n replaceText = 'replace file',\n hideDetails = false,\n} = defineProps<FileUploadProps>();\n\nconst emit = defineEmits<{\n error: [message: string];\n}>();\n\ndefineSlots<{\n preview?: (props: { files: File[]; remove: () => void }) => any;\n icon?: () => any;\n description?: () => any;\n}>();\n\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst input = useTemplateRef<HTMLInputElement>('input');\nconst internalError = ref<string>('');\n\nconst files = computed<File[]>(() => {\n const value = get(modelValue);\n if (!value)\n return [];\n return Array.isArray(value) ? value : [value];\n});\n\nconst hasFiles = computed<boolean>(() => get(files).length > 0);\n\nconst progressLabel = computed<string | undefined>(() => {\n const value = progress;\n return value === undefined ? undefined : `${Math.round(value)}%`;\n});\n\nconst combinedErrorMessages = computed<string[]>(() => {\n const external = Array.isArray(errorMessages) ? errorMessages : [errorMessages];\n const internal = get(internalError);\n return [...external.filter(Boolean), ...(internal ? [internal] : [])];\n});\n\nconst { hasError } = useFormTextDetail(combinedErrorMessages, () => []);\n\nfunction matchesAccept(file: File, acceptString: string): boolean {\n if (!acceptString || acceptString === '*' || acceptString === '*/*')\n return true;\n\n const fileName = file.name.toLowerCase();\n const fileExtension = fileName.includes('.') ? fileName.slice(fileName.lastIndexOf('.')) : '';\n const fileType = file.type.toLowerCase();\n const acceptTypes = acceptString.split(',').map(value => value.trim().toLowerCase()).filter(Boolean);\n\n return acceptTypes.some((type) => {\n if (type.startsWith('.'))\n return type === fileExtension;\n if (type.endsWith('/*'))\n return fileType.startsWith(type.slice(0, -1));\n return type === fileType;\n });\n}\n\nfunction reportError(message: string): void {\n set(internalError, message);\n emit('error', message);\n}\n\nfunction clearInternalError(): void {\n set(internalError, '');\n}\n\nfunction validate(candidates: File[]): File[] | undefined {\n if (candidates.length === 0)\n return undefined;\n\n if (!multiple && candidates.length > 1) {\n reportError('Only one file can be uploaded');\n return undefined;\n }\n\n for (const file of candidates) {\n if (!matchesAccept(file, accept)) {\n reportError(`Only ${accept} files are allowed`);\n return undefined;\n }\n if (maxSize !== undefined && file.size > maxSize) {\n reportError(`${file.name} exceeds the maximum size of ${formatFileSize(maxSize)}`);\n return undefined;\n }\n }\n\n return candidates;\n}\n\nfunction setFiles(candidates: File[]): void {\n const validated = validate(candidates);\n if (!validated)\n return;\n clearInternalError();\n set(modelValue, multiple ? validated : validated[0]);\n}\n\nfunction removeFile(target?: File): void {\n clearInternalError();\n const inputEl = get(input);\n if (inputEl)\n inputEl.value = '';\n\n if (!target || !multiple) {\n set(modelValue, multiple ? [] : undefined);\n return;\n }\n\n const remaining = get(files).filter(file => file !== target);\n set(modelValue, remaining);\n}\n\nfunction onSelect(event: Event): void {\n const target = event.target as HTMLInputElement;\n if (!target?.files)\n return;\n setFiles(Array.from(target.files));\n}\n\nfunction onDrop(dropped: File[] | null): void {\n if (disabled || noDrop || !dropped || dropped.length === 0)\n return;\n setFiles(dropped);\n}\n\nconst { isOverDropZone } = useDropZone(wrapper, {\n onDrop,\n});\n\nfunction openPicker(): void {\n if (disabled)\n return;\n get(input)?.click();\n}\n\nwatch(() => errorMessages, () => clearInternalError());\n\ndefineExpose({\n removeFile: () => removeFile(),\n openPicker,\n});\n</script>\n\n<template>\n <div v-bind=\"getRootAttrs($attrs)\">\n <div\n ref=\"wrapper\"\n class=\"p-4 border border-rui-grey-300 dark:border-rui-grey-800 rounded-md w-full relative border-dashed transition\"\n :class=\"{\n '!border-rui-primary bg-rui-primary/[0.08]': isOverDropZone && !disabled && !noDrop,\n '!border-rui-error !border-solid bg-rui-error/[0.08]': hasError,\n '!border-rui-success !border-solid bg-rui-success/[0.08]': uploaded,\n 'opacity-60 pointer-events-none': disabled,\n }\"\n :data-disabled=\"disabled || undefined\"\n :data-uploaded=\"uploaded || undefined\"\n :data-error=\"hasError ? '' : undefined\"\n :data-drop-active=\"isOverDropZone || undefined\"\n >\n <div\n class=\"flex flex-col items-center justify-center gap-3\"\n :class=\"{ 'opacity-0': loading }\"\n >\n <slot\n name=\"preview\"\n :files=\"files\"\n :remove=\"() => removeFile()\"\n >\n <div\n v-if=\"hasFiles\"\n class=\"flex flex-col gap-1 w-full\"\n data-id=\"file-list\"\n >\n <div\n v-for=\"file in files\"\n :key=\"`${file.name}-${file.lastModified}`\"\n class=\"flex items-center gap-2 bg-rui-primary/[0.08] rounded-full pl-3 pr-1 py-1\"\n data-id=\"file-item\"\n >\n <RuiIcon\n name=\"lu-file\"\n color=\"primary\"\n size=\"20\"\n />\n <div class=\"flex-1 overflow-hidden min-w-0\">\n <div\n class=\"text-sm leading-5 truncate\"\n :title=\"file.name\"\n >\n {{ file.name }}\n </div>\n <div class=\"text-rui-text-secondary text-xs leading-3\">\n {{ formatFileSize(file.size) }}\n </div>\n </div>\n <button\n type=\"button\"\n class=\"p-1 rounded-full hover:bg-rui-primary/[0.16] transition\"\n :disabled=\"disabled\"\n :aria-label=\"`Remove ${file.name}`\"\n data-id=\"remove-file\"\n @click=\"removeFile(file)\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"16\"\n />\n </button>\n </div>\n </div>\n <div\n v-else\n class=\"h-10 w-10 rounded-full flex items-center justify-center\"\n :class=\"uploaded ? 'bg-rui-success/[0.12]' : 'bg-rui-primary/[0.12]'\"\n >\n <slot name=\"icon\">\n <RuiIcon\n :name=\"uploaded ? 'lu-circle-check' : 'lu-file-up'\"\n :color=\"uploaded ? 'success' : 'primary'\"\n />\n </slot>\n </div>\n </slot>\n\n <div class=\"text-center text-sm\">\n <slot name=\"description\">\n <div class=\"flex items-center justify-center gap-1 flex-wrap\">\n <span>{{ uploadText }}</span>\n <button\n type=\"button\"\n class=\"text-rui-primary underline disabled:no-underline disabled:text-rui-text-disabled\"\n :disabled=\"disabled\"\n data-id=\"open-picker\"\n @click=\"openPicker()\"\n >\n {{ hasFiles ? replaceText : clickToUploadText }}\n </button>\n </div>\n </slot>\n </div>\n\n <input\n ref=\"input\"\n type=\"file\"\n :accept=\"accept\"\n :multiple=\"multiple\"\n :disabled=\"disabled\"\n hidden\n data-id=\"file-input\"\n v-bind=\"getNonRootAttrs($attrs, ['class', 'onChange'])\"\n @change=\"onSelect($event)\"\n />\n </div>\n\n <div\n v-if=\"loading\"\n class=\"flex flex-col items-center justify-center absolute h-full w-full top-0 left-0 gap-2\"\n data-id=\"loading\"\n >\n <RuiProgress\n circular\n :variant=\"progress === undefined ? 'indeterminate' : 'determinate'\"\n :value=\"progress\"\n color=\"primary\"\n size=\"40\"\n />\n <div\n v-if=\"progressLabel\"\n v-text=\"progressLabel\"\n class=\"text-xs text-rui-text-secondary\"\n data-id=\"progress-label\"\n />\n </div>\n </div>\n <RuiFormTextDetail\n v-if=\"!hideDetails\"\n :error-messages=\"combinedErrorMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export interface FileUploadProps {
|
|
2
|
+
/** File type filter (HTML accept attribute syntax). e.g. '.csv', 'image/*', '.png,.jpg' */
|
|
3
|
+
accept?: string;
|
|
4
|
+
/** Allow multiple file selection. */
|
|
5
|
+
multiple?: boolean;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
/** Shows a loading overlay (consumer-driven, e.g. while uploading). */
|
|
8
|
+
loading?: boolean;
|
|
9
|
+
/** Upload progress 0-100. When provided alongside `loading`, the overlay shows a determinate progress bar with percentage. */
|
|
10
|
+
progress?: number;
|
|
11
|
+
/** Renders the success state border/icon. Consumer toggles back to false. */
|
|
12
|
+
uploaded?: boolean;
|
|
13
|
+
/** Optional max size per file in bytes; failures emit `error` and set internal error state. */
|
|
14
|
+
maxSize?: number;
|
|
15
|
+
/** External error messages (e.g. from Vuelidate). Shown via the standard form detail block. */
|
|
16
|
+
errorMessages?: string | string[];
|
|
17
|
+
/** Hint text below the dropzone. */
|
|
18
|
+
hint?: string;
|
|
19
|
+
/** Disable drag-and-drop; the dropzone becomes click-only (matches rotki.com use case). */
|
|
20
|
+
noDrop?: boolean;
|
|
21
|
+
/** Replace the default "Drag and drop or {button}" copy. */
|
|
22
|
+
uploadText?: string;
|
|
23
|
+
/** Label shown on the inline button when no file is selected. */
|
|
24
|
+
clickToUploadText?: string;
|
|
25
|
+
/** Label shown on the inline button when one or more files are already selected. */
|
|
26
|
+
replaceText?: string;
|
|
27
|
+
/** Hide the bottom hint/error details strip. */
|
|
28
|
+
hideDetails?: boolean;
|
|
29
|
+
}
|
|
30
|
+
type __VLS_Props = FileUploadProps;
|
|
31
|
+
type __VLS_Slots = {
|
|
32
|
+
preview?: (props: {
|
|
33
|
+
files: File[];
|
|
34
|
+
remove: () => void;
|
|
35
|
+
}) => any;
|
|
36
|
+
icon?: () => any;
|
|
37
|
+
description?: () => any;
|
|
38
|
+
};
|
|
39
|
+
declare function openPicker(): void;
|
|
40
|
+
type __VLS_ModelProps = {
|
|
41
|
+
modelValue: File | File[] | undefined;
|
|
42
|
+
};
|
|
43
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
44
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
45
|
+
removeFile: () => void;
|
|
46
|
+
openPicker: typeof openPicker;
|
|
47
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
48
|
+
error: (message: string) => any;
|
|
49
|
+
"update:modelValue": (value: File | File[] | undefined) => any;
|
|
50
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
51
|
+
onError?: ((message: string) => any) | undefined;
|
|
52
|
+
"onUpdate:modelValue"?: ((value: File | File[] | undefined) => any) | undefined;
|
|
53
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
54
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
55
|
+
declare const _default: typeof __VLS_export;
|
|
56
|
+
export default _default;
|
|
57
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
58
|
+
new (): {
|
|
59
|
+
$slots: S;
|
|
60
|
+
};
|
|
61
|
+
};
|