@auronui/vue 1.0.11 → 1.0.12
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/cjs/index.cjs +514 -410
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/components/autocomplete/Autocomplete.context.js.map +1 -1
- package/dist/components/autocomplete/Autocomplete.js.map +1 -1
- package/dist/components/autocomplete/Autocomplete.vue_vue_type_script_setup_true_lang.js +119 -14
- package/dist/components/autocomplete/Autocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteCreateItem.js +7 -0
- package/dist/components/autocomplete/AutocompleteCreateItem.js.map +1 -0
- package/dist/components/autocomplete/AutocompleteCreateItem.vue_vue_type_script_setup_true_lang.js +57 -0
- package/dist/components/autocomplete/AutocompleteCreateItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/autocomplete/AutocompleteInput.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteInput.vue_vue_type_script_setup_true_lang.js +40 -9
- package/dist/components/autocomplete/AutocompleteInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteItem.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteItem.vue_vue_type_script_setup_true_lang.js +33 -5
- package/dist/components/autocomplete/AutocompleteItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteOverflowChips.js +7 -0
- package/dist/components/autocomplete/AutocompleteOverflowChips.js.map +1 -0
- package/dist/components/autocomplete/AutocompleteOverflowChips.vue_vue_type_script_setup_true_lang.js +88 -0
- package/dist/components/autocomplete/AutocompleteOverflowChips.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/select/Select.context.js.map +1 -1
- package/dist/components/select/Select.js.map +1 -1
- package/dist/components/select/Select.vue_vue_type_script_setup_true_lang.js +12 -1
- package/dist/components/select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/select/SelectOverflowChips.js +7 -0
- package/dist/components/select/SelectOverflowChips.js.map +1 -0
- package/dist/components/select/SelectOverflowChips.vue_vue_type_script_setup_true_lang.js +85 -0
- package/dist/components/select/SelectOverflowChips.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/select/SelectValue.js.map +1 -1
- package/dist/components/select/SelectValue.vue_vue_type_script_setup_true_lang.js +6 -1
- package/dist/components/select/SelectValue.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/index.d.ts +320 -419
- package/dist/index.js +2 -7
- package/package.json +4 -4
- package/dist/components/tag/Tag.js +0 -7
- package/dist/components/tag/Tag.js.map +0 -1
- package/dist/components/tag/Tag.vue_vue_type_script_setup_true_lang.js +0 -69
- package/dist/components/tag/Tag.vue_vue_type_script_setup_true_lang.js.map +0 -1
- package/dist/components/tag/TagDelete.js +0 -7
- package/dist/components/tag/TagDelete.js.map +0 -1
- package/dist/components/tag/TagDelete.vue_vue_type_script_setup_true_lang.js +0 -49
- package/dist/components/tag/TagDelete.vue_vue_type_script_setup_true_lang.js.map +0 -1
- package/dist/components/tag/TagText.js +0 -7
- package/dist/components/tag/TagText.js.map +0 -1
- package/dist/components/tag/TagText.vue_vue_type_script_setup_true_lang.js +0 -18
- package/dist/components/tag/TagText.vue_vue_type_script_setup_true_lang.js.map +0 -1
- package/dist/components/tag-group/TagGroup.context.js +0 -7
- package/dist/components/tag-group/TagGroup.context.js.map +0 -1
- package/dist/components/tag-group/TagGroup.js +0 -7
- package/dist/components/tag-group/TagGroup.js.map +0 -1
- package/dist/components/tag-group/TagGroup.vue_vue_type_script_setup_true_lang.js +0 -142
- package/dist/components/tag-group/TagGroup.vue_vue_type_script_setup_true_lang.js.map +0 -1
- package/dist/components/tag-group/TagGroupInput.js +0 -7
- package/dist/components/tag-group/TagGroupInput.js.map +0 -1
- package/dist/components/tag-group/TagGroupInput.vue_vue_type_script_setup_true_lang.js +0 -37
- package/dist/components/tag-group/TagGroupInput.vue_vue_type_script_setup_true_lang.js.map +0 -1
package/dist/components/autocomplete/AutocompleteInput.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import Spinner_default from "../spinner/Spinner.js";
|
|
2
|
+
import Chip_default from "../chip/Chip.js";
|
|
2
3
|
import { useAutocompleteInject } from "./Autocomplete.context.js";
|
|
3
|
-
import
|
|
4
|
+
import AutocompleteOverflowChips_default from "./AutocompleteOverflowChips.js";
|
|
5
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, renderList, renderSlot, toDisplayString, unref, useTemplateRef, withCtx, withModifiers } from "vue";
|
|
4
6
|
import { useFocusWithin } from "@vueuse/core";
|
|
5
7
|
import { AutocompleteAnchor, AutocompleteCancel, AutocompleteInput, AutocompleteTrigger } from "reka-ui";
|
|
6
8
|
//#region src/components/autocomplete/AutocompleteInput.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -20,6 +22,8 @@ var AutocompleteInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
20
22
|
const ctx = useAutocompleteInject();
|
|
21
23
|
const { focused: isFocused } = useFocusWithin(useTemplateRef("anchor"));
|
|
22
24
|
const showInsideLabel = computed(() => ctx.hasLabel.value && ctx.labelPlacement.value === "inside");
|
|
25
|
+
const effectivePlaceholder = computed(() => ctx.multiple.value && ctx.selectedValues.value.length > 0 ? void 0 : props.placeholder);
|
|
26
|
+
const getLabel = (v) => ctx.selectedLabels.value.find((l) => l.value === v)?.label ?? v;
|
|
23
27
|
return (_ctx, _cache) => {
|
|
24
28
|
return openBlock(), createBlock(unref(AutocompleteAnchor), {
|
|
25
29
|
ref: "anchor",
|
|
@@ -29,6 +33,7 @@ var AutocompleteInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
29
33
|
"data-invalid": unref(ctx).isInvalid.value || void 0,
|
|
30
34
|
"data-disabled": unref(ctx).isDisabled.value || void 0,
|
|
31
35
|
"data-readonly": unref(ctx).isReadonly.value || void 0,
|
|
36
|
+
"data-multiple-overflow": unref(ctx).multiple.value ? unref(ctx).multipleOverflow.value : void 0,
|
|
32
37
|
"data-slot": "trigger"
|
|
33
38
|
}, {
|
|
34
39
|
default: withCtx(() => [
|
|
@@ -42,15 +47,38 @@ var AutocompleteInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
42
47
|
class: normalizeClass(unref(ctx).slots.value.startContent()),
|
|
43
48
|
"data-slot": "start-content"
|
|
44
49
|
}, [renderSlot(_ctx.$slots, "startContent")], 2)) : createCommentVNode("", true),
|
|
50
|
+
unref(ctx).multiple.value && unref(ctx).multipleOverflow.value === "collapse" && unref(ctx).selectedValues.value.length > 0 ? (openBlock(), createBlock(AutocompleteOverflowChips_default, {
|
|
51
|
+
key: 2,
|
|
52
|
+
values: unref(ctx).selectedValues.value,
|
|
53
|
+
"get-label": getLabel,
|
|
54
|
+
"remove-value": unref(ctx).removeValue
|
|
55
|
+
}, null, 8, ["values", "remove-value"])) : unref(ctx).multiple.value && unref(ctx).multipleOverflow.value === "wrap" ? (openBlock(true), createElementBlock(Fragment, { key: 3 }, renderList(unref(ctx).selectedLabels.value, (item) => {
|
|
56
|
+
return openBlock(), createBlock(Chip_default, {
|
|
57
|
+
key: item.value,
|
|
58
|
+
size: "sm",
|
|
59
|
+
"is-closable": "",
|
|
60
|
+
"close-aria-label": `Remove ${item.label}`,
|
|
61
|
+
"data-slot": "selected-chip",
|
|
62
|
+
onClose: withModifiers(($event) => unref(ctx).removeValue(item.value), ["stop"])
|
|
63
|
+
}, {
|
|
64
|
+
default: withCtx(() => [createTextVNode(toDisplayString(item.label), 1)]),
|
|
65
|
+
_: 2
|
|
66
|
+
}, 1032, ["close-aria-label", "onClose"]);
|
|
67
|
+
}), 128)) : createCommentVNode("", true),
|
|
45
68
|
createVNode(unref(AutocompleteInput), {
|
|
46
69
|
id: unref(ctx).inputId.value,
|
|
47
|
-
placeholder:
|
|
70
|
+
placeholder: effectivePlaceholder.value,
|
|
48
71
|
disabled: unref(ctx).isDisabled.value,
|
|
49
72
|
readonly: unref(ctx).isReadonly.value,
|
|
50
73
|
required: unref(ctx).isRequired.value,
|
|
51
74
|
"aria-invalid": unref(ctx).isInvalid.value || void 0,
|
|
52
75
|
"aria-describedby": unref(ctx).ariaDescribedBy.value,
|
|
53
76
|
class: normalizeClass(unref(ctx).slots.value.input()),
|
|
77
|
+
style: normalizeStyle(unref(ctx).multiple.value && unref(ctx).multipleOverflow.value === "collapse" && unref(ctx).selectedValues.value.length > 0 ? {
|
|
78
|
+
flex: "0 0 auto",
|
|
79
|
+
minWidth: "80px",
|
|
80
|
+
width: "auto"
|
|
81
|
+
} : void 0),
|
|
54
82
|
"data-slot": "input",
|
|
55
83
|
autocomplete: "off"
|
|
56
84
|
}, null, 8, [
|
|
@@ -61,15 +89,17 @@ var AutocompleteInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
61
89
|
"required",
|
|
62
90
|
"aria-invalid",
|
|
63
91
|
"aria-describedby",
|
|
64
|
-
"class"
|
|
92
|
+
"class",
|
|
93
|
+
"style"
|
|
65
94
|
]),
|
|
66
95
|
createVNode(unref(AutocompleteCancel), {
|
|
67
96
|
class: normalizeClass(unref(ctx).slots.value.clearButton()),
|
|
68
97
|
"data-empty": !unref(ctx).isFilled.value || unref(ctx).isReadonly.value || unref(ctx).isDisabled.value ? "true" : void 0,
|
|
69
98
|
"data-slot": "clear-button",
|
|
70
|
-
"aria-label": "Clear"
|
|
99
|
+
"aria-label": "Clear",
|
|
100
|
+
onClick: _cache[0] || (_cache[0] = ($event) => unref(ctx).multiple.value ? unref(ctx).clearAll() : void 0)
|
|
71
101
|
}, {
|
|
72
|
-
default: withCtx(() => [renderSlot(_ctx.$slots, "clearIcon", {}, () => [_cache[
|
|
102
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "clearIcon", {}, () => [_cache[1] || (_cache[1] = createElementVNode("svg", {
|
|
73
103
|
xmlns: "http://www.w3.org/2000/svg",
|
|
74
104
|
width: "10",
|
|
75
105
|
height: "10",
|
|
@@ -95,19 +125,19 @@ var AutocompleteInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
95
125
|
_: 3
|
|
96
126
|
}, 8, ["class", "data-empty"]),
|
|
97
127
|
unref(ctx).isLoading.value ? (openBlock(), createElementBlock("span", {
|
|
98
|
-
key:
|
|
128
|
+
key: 4,
|
|
99
129
|
class: normalizeClass(unref(ctx).slots.value.indicator()),
|
|
100
130
|
"data-slot": "autocomplete-loading-indicator",
|
|
101
131
|
role: "status",
|
|
102
132
|
"aria-live": "polite",
|
|
103
133
|
"aria-label": "Loading suggestions"
|
|
104
134
|
}, [createVNode(Spinner_default, { size: "sm" })], 2)) : (openBlock(), createBlock(unref(AutocompleteTrigger), {
|
|
105
|
-
key:
|
|
135
|
+
key: 5,
|
|
106
136
|
class: normalizeClass(unref(ctx).slots.value.indicator()),
|
|
107
137
|
"data-slot": "autocomplete-default-indicator",
|
|
108
138
|
"aria-label": "Toggle suggestions"
|
|
109
139
|
}, {
|
|
110
|
-
default: withCtx(() => [renderSlot(_ctx.$slots, "triggerIcon", {}, () => [_cache[
|
|
140
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "triggerIcon", {}, () => [_cache[2] || (_cache[2] = createElementVNode("svg", {
|
|
111
141
|
xmlns: "http://www.w3.org/2000/svg",
|
|
112
142
|
width: "16",
|
|
113
143
|
height: "16",
|
|
@@ -129,7 +159,8 @@ var AutocompleteInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
129
159
|
"data-focused",
|
|
130
160
|
"data-invalid",
|
|
131
161
|
"data-disabled",
|
|
132
|
-
"data-readonly"
|
|
162
|
+
"data-readonly",
|
|
163
|
+
"data-multiple-overflow"
|
|
133
164
|
]);
|
|
134
165
|
};
|
|
135
166
|
}
|
package/dist/components/autocomplete/AutocompleteInput.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutocompleteInput.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/autocomplete/AutocompleteInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useTemplateRef } from 'vue'\nimport { useFocusWithin } from '@vueuse/core'\nimport { AutocompleteInput, AutocompleteTrigger, AutocompleteCancel, AutocompleteAnchor } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\nimport Spinner from '../spinner/Spinner.vue';\n\nconst props = withDefaults(defineProps<{\n placeholder?: string\n class?: string\n}>(), {\n placeholder: undefined,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n\n// Track focused state via useFocusWithin (NOT manual @focus/@blur listeners) — the\n// inner Reka <AutocompleteInput> wraps the native <input>; useFocusWithin observes\n// the actual DOM subtree of the anchor, so isFocused flips reliably regardless of\n// how Reka forwards refs/attrs.\nconst anchorRef = useTemplateRef<HTMLElement>('anchor')\nconst { focused: isFocused } = useFocusWithin(anchorRef)\n\n// Render the inside-label only when (a) a label is set and (b) labelPlacement is 'inside'\nconst showInsideLabel = computed(\n () => ctx.hasLabel.value && ctx.labelPlacement.value === 'inside',\n)\n</script>\n\n<template>\n <AutocompleteAnchor\n ref=\"anchor\"\n :class=\"ctx.slots.value.trigger()\"\n :data-filled=\"ctx.hasLabel.value ? (ctx.isFilled.value || undefined) : undefined\"\n :data-focused=\"isFocused || undefined\"\n :data-invalid=\"ctx.isInvalid.value || undefined\"\n :data-disabled=\"ctx.isDisabled.value || undefined\"\n :data-readonly=\"ctx.isReadonly.value || undefined\"\n data-slot=\"trigger\"\n >\n <label\n v-if=\"showInsideLabel\"\n :for=\"ctx.inputId.value\"\n :class=\"ctx.slots.value.label()\"\n >{{ ctx.label.value }}<span\n v-if=\"ctx.isRequired.value\"\n aria-hidden=\"true\"\n > *</span></label>\n <span\n v-if=\"$slots.startContent\"\n :class=\"ctx.slots.value.startContent()\"\n data-slot=\"start-content\"\n >\n <slot name=\"startContent\" />\n </span>\n <AutocompleteInput\n :id=\"ctx.inputId.value\"\n :placeholder=\"props.placeholder\"\n :disabled=\"ctx.isDisabled.value\"\n :readonly=\"ctx.isReadonly.value\"\n :required=\"ctx.isRequired.value\"\n :aria-invalid=\"ctx.isInvalid.value || undefined\"\n :aria-describedby=\"ctx.ariaDescribedBy.value\"\n :class=\"ctx.slots.value.input()\"\n data-slot=\"input\"\n autocomplete=\"off\"\n />\n <!-- Clear button: only shown when filled and not in a readonly/disabled state.\n Reka's AutocompleteCancel does not set data-empty itself, so we drive it here. -->\n <AutocompleteCancel\n :class=\"ctx.slots.value.clearButton()\"\n :data-empty=\"(!ctx.isFilled.value || ctx.isReadonly.value || ctx.isDisabled.value) ? 'true' : undefined\"\n data-slot=\"clear-button\"\n aria-label=\"Clear\"\n >\n <slot name=\"clearIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"autocomplete-clear-button-icon\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"18\"\n y1=\"6\"\n x2=\"6\"\n y2=\"18\"\n />\n <line\n x1=\"6\"\n y1=\"6\"\n x2=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </AutocompleteCancel>\n <!-- Inline loading spinner: replaces the dropdown indicator while loadItems is pending -->\n <span\n v-if=\"ctx.isLoading.value\"\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-loading-indicator\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Loading suggestions\"\n >\n <Spinner size=\"sm\" />\n </span>\n <!-- Dropdown trigger indicator (hidden while loading) -->\n <AutocompleteTrigger\n v-else\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-default-indicator\"\n aria-label=\"Toggle suggestions\"\n >\n <slot name=\"triggerIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </slot>\n </AutocompleteTrigger>\n </AutocompleteAnchor>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AutocompleteInput.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/autocomplete/AutocompleteInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useTemplateRef } from 'vue'\nimport { useFocusWithin } from '@vueuse/core'\nimport { AutocompleteInput, AutocompleteTrigger, AutocompleteCancel, AutocompleteAnchor } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\nimport Chip from '../chip/Chip.vue'\nimport Spinner from '../spinner/Spinner.vue'\nimport AutocompleteOverflowChips from './AutocompleteOverflowChips.vue'\n\nconst props = withDefaults(defineProps<{\n placeholder?: string\n class?: string\n}>(), {\n placeholder: undefined,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n\n// Track focused state via useFocusWithin (NOT manual @focus/@blur listeners) — the\n// inner Reka <AutocompleteInput> wraps the native <input>; useFocusWithin observes\n// the actual DOM subtree of the anchor, so isFocused flips reliably regardless of\n// how Reka forwards refs/attrs.\nconst anchorRef = useTemplateRef<HTMLElement>('anchor')\nconst { focused: isFocused } = useFocusWithin(anchorRef)\n\n// Render the inside-label only when (a) a label is set and (b) labelPlacement is 'inside'\nconst showInsideLabel = computed(\n () => ctx.hasLabel.value && ctx.labelPlacement.value === 'inside',\n)\n\n// In multiple mode, hide placeholder once chips are present\nconst effectivePlaceholder = computed(() =>\n ctx.multiple.value && ctx.selectedValues.value.length > 0 ? undefined : props.placeholder,\n)\n\nconst getLabel = (v: string) => ctx.selectedLabels.value.find(l => l.value === v)?.label ?? v\n</script>\n\n<template>\n <AutocompleteAnchor\n ref=\"anchor\"\n :class=\"ctx.slots.value.trigger()\"\n :data-filled=\"ctx.hasLabel.value ? (ctx.isFilled.value || undefined) : undefined\"\n :data-focused=\"isFocused || undefined\"\n :data-invalid=\"ctx.isInvalid.value || undefined\"\n :data-disabled=\"ctx.isDisabled.value || undefined\"\n :data-readonly=\"ctx.isReadonly.value || undefined\"\n :data-multiple-overflow=\"ctx.multiple.value ? ctx.multipleOverflow.value : undefined\"\n data-slot=\"trigger\"\n >\n <label\n v-if=\"showInsideLabel\"\n :for=\"ctx.inputId.value\"\n :class=\"ctx.slots.value.label()\"\n >{{ ctx.label.value }}<span\n v-if=\"ctx.isRequired.value\"\n aria-hidden=\"true\"\n > *</span></label>\n <span\n v-if=\"$slots.startContent\"\n :class=\"ctx.slots.value.startContent()\"\n data-slot=\"start-content\"\n >\n <slot name=\"startContent\" />\n </span>\n <!-- Multiple/collapse: overflow chip area with truncation -->\n <AutocompleteOverflowChips\n v-if=\"ctx.multiple.value && ctx.multipleOverflow.value === 'collapse' && ctx.selectedValues.value.length > 0\"\n :values=\"ctx.selectedValues.value\"\n :get-label=\"getLabel\"\n :remove-value=\"ctx.removeValue\"\n />\n <!-- Multiple/wrap: chips that wrap onto new lines -->\n <template v-else-if=\"ctx.multiple.value && ctx.multipleOverflow.value === 'wrap'\">\n <Chip\n v-for=\"item in ctx.selectedLabels.value\"\n :key=\"item.value\"\n size=\"sm\"\n is-closable\n :close-aria-label=\"`Remove ${item.label}`\"\n data-slot=\"selected-chip\"\n @close.stop=\"ctx.removeValue(item.value)\"\n >\n {{ item.label }}\n </Chip>\n </template>\n <AutocompleteInput\n :id=\"ctx.inputId.value\"\n :placeholder=\"effectivePlaceholder\"\n :disabled=\"ctx.isDisabled.value\"\n :readonly=\"ctx.isReadonly.value\"\n :required=\"ctx.isRequired.value\"\n :aria-invalid=\"ctx.isInvalid.value || undefined\"\n :aria-describedby=\"ctx.ariaDescribedBy.value\"\n :class=\"ctx.slots.value.input()\"\n :style=\"ctx.multiple.value && ctx.multipleOverflow.value === 'collapse' && ctx.selectedValues.value.length > 0\n ? { flex: '0 0 auto', minWidth: '80px', width: 'auto' }\n : undefined\"\n data-slot=\"input\"\n autocomplete=\"off\"\n />\n <!-- Clear button: only shown when filled and not in a readonly/disabled state.\n Reka's AutocompleteCancel does not set data-empty itself, so we drive it here.\n In multiple mode also clears selectedValues via ctx.clearAll(). -->\n <AutocompleteCancel\n :class=\"ctx.slots.value.clearButton()\"\n :data-empty=\"(!ctx.isFilled.value || ctx.isReadonly.value || ctx.isDisabled.value) ? 'true' : undefined\"\n data-slot=\"clear-button\"\n aria-label=\"Clear\"\n @click=\"ctx.multiple.value ? ctx.clearAll() : undefined\"\n >\n <slot name=\"clearIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"autocomplete-clear-button-icon\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"18\"\n y1=\"6\"\n x2=\"6\"\n y2=\"18\"\n />\n <line\n x1=\"6\"\n y1=\"6\"\n x2=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </AutocompleteCancel>\n <!-- Inline loading spinner: replaces the dropdown indicator while loadItems is pending -->\n <span\n v-if=\"ctx.isLoading.value\"\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-loading-indicator\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Loading suggestions\"\n >\n <Spinner size=\"sm\" />\n </span>\n <!-- Dropdown trigger indicator (hidden while loading) -->\n <AutocompleteTrigger\n v-else\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-default-indicator\"\n aria-label=\"Toggle suggestions\"\n >\n <slot name=\"triggerIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </slot>\n </AutocompleteTrigger>\n </AutocompleteAnchor>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EASA,MAAM,QAAQ;EAQd,MAAM,MAAM,uBAAsB;EAOlC,MAAM,EAAE,SAAS,cAAc,eADb,eAA4B,SAAQ,CACC;EAGvD,MAAM,kBAAkB,eAChB,IAAI,SAAS,SAAS,IAAI,eAAe,UAAU,SAC3D;EAGA,MAAM,uBAAuB,eAC3B,IAAI,SAAS,SAAS,IAAI,eAAe,MAAM,SAAS,IAAI,KAAA,IAAY,MAAM,YAChF;EAEA,MAAM,YAAY,MAAc,IAAI,eAAe,MAAM,MAAK,MAAK,EAAE,UAAU,EAAE,EAAE,SAAS;;uBAI1F,YAwIqB,MAAA,mBAAA,EAAA;IAvInB,KAAI;IACH,OAAK,eAAE,MAAA,IAAG,CAAC,MAAM,MAAM,SAAO,CAAA;IAC9B,eAAa,MAAA,IAAG,CAAC,SAAS,QAAS,MAAA,IAAG,CAAC,SAAS,SAAS,KAAA,IAAa,KAAA;IACtE,gBAAc,MAAA,UAAS,IAAI,KAAA;IAC3B,gBAAc,MAAA,IAAG,CAAC,UAAU,SAAS,KAAA;IACrC,iBAAe,MAAA,IAAG,CAAC,WAAW,SAAS,KAAA;IACvC,iBAAe,MAAA,IAAG,CAAC,WAAW,SAAS,KAAA;IACvC,0BAAwB,MAAA,IAAG,CAAC,SAAS,QAAQ,MAAA,IAAG,CAAC,iBAAiB,QAAQ,KAAA;IAC3E,aAAU;;2BASQ;KANV,gBAAA,SAAA,WAAA,EADR,mBAOkB,SAAA;;MALf,KAAK,MAAA,IAAG,CAAC,QAAQ;MACjB,OAAK,eAAE,MAAA,IAAG,CAAC,MAAM,MAAM,OAAK,CAAA;yCAC3B,MAAA,IAAG,CAAC,MAAM,MAAK,EAAA,EAAA,EACX,MAAA,IAAG,CAAC,WAAW,SAAA,WAAA,EADD,mBAGZ,QAHY,YAGrB,KAAE,IAAA,mBAAA,IAAA,KAAA,CAAA,EAAA,IAAA,WAAA,IAAA,mBAAA,IAAA,KAAA;KAEKA,KAAAA,OAAO,gBAAA,WAAA,EADf,mBAMO,QAAA;;MAJJ,OAAK,eAAE,MAAA,IAAG,CAAC,MAAM,MAAM,cAAY,CAAA;MACpC,aAAU;SAEV,WAA4B,KAAA,QAAA,eAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA;KAItB,MAAA,IAAG,CAAC,SAAS,SAAS,MAAA,IAAG,CAAC,iBAAiB,UAAK,cAAmB,MAAA,IAAG,CAAC,eAAe,MAAM,SAAM,KAAA,WAAA,EAD1G,YAKE,mCAAA;;MAHC,QAAQ,MAAA,IAAG,CAAC,eAAe;MAC3B,aAAW;MACX,gBAAc,MAAA,IAAG,CAAC;gDAGA,MAAA,IAAG,CAAC,SAAS,SAAS,MAAA,IAAG,CAAC,iBAAiB,UAAK,UAAA,UAAA,KAAA,EACnE,mBAUO,UAAA,EAAA,KAAA,GAAA,EAAA,WATU,MAAA,IAAG,CAAC,eAAe,QAA3B,SAAI;0BADb,YAUO,cAAA;OARJ,KAAK,KAAK;OACX,MAAK;OACL,eAAA;OACC,oBAAgB,UAAY,KAAK;OAClC,aAAU;OACT,SAAK,eAAA,WAAO,MAAA,IAAG,CAAC,YAAY,KAAK,MAAK,EAAA,CAAA,OAAA,CAAA;;8BAEvB,CAAA,gBAAA,gBAAb,KAAK,MAAK,EAAA,EAAA,CAAA,CAAA;;;;KAGjB,YAcE,MAAA,kBAAA,EAAA;MAbC,IAAI,MAAA,IAAG,CAAC,QAAQ;MAChB,aAAa,qBAAA;MACb,UAAU,MAAA,IAAG,CAAC,WAAW;MACzB,UAAU,MAAA,IAAG,CAAC,WAAW;MACzB,UAAU,MAAA,IAAG,CAAC,WAAW;MACzB,gBAAc,MAAA,IAAG,CAAC,UAAU,SAAS,KAAA;MACrC,oBAAkB,MAAA,IAAG,CAAC,gBAAgB;MACtC,OAAK,eAAE,MAAA,IAAG,CAAC,MAAM,MAAM,OAAK,CAAA;MAC5B,OAAK,eAAE,MAAA,IAAG,CAAC,SAAS,SAAS,MAAA,IAAG,CAAC,iBAAiB,UAAK,cAAmB,MAAA,IAAG,CAAC,eAAe,MAAM,SAAM,IAAA;;;;UAA+E,KAAA,EAAS;MAGlM,aAAU;MACV,cAAa;;;;;;;;;;;;KAKf,YAmCqB,MAAA,mBAAA,EAAA;MAlClB,OAAK,eAAE,MAAA,IAAG,CAAC,MAAM,MAAM,aAAW,CAAA;MAClC,cAAU,CAAI,MAAA,IAAG,CAAC,SAAS,SAAS,MAAA,IAAG,CAAC,WAAW,SAAS,MAAA,IAAG,CAAC,WAAW,QAAK,SAAa,KAAA;MAC9F,aAAU;MACV,cAAW;MACV,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,IAAG,CAAC,SAAS,QAAQ,MAAA,IAAG,CAAC,UAAQ,GAAK,KAAA;;6BA6BvC,CA3BP,WA2BO,KAAA,QAAA,aAAA,EAAA,QAAA,CAAA,OAAA,OAAA,OAAA,KA1BL,mBAyBM,OAAA;OAxBJ,OAAM;OACN,OAAM;OACN,QAAO;OACP,SAAQ;OACR,MAAK;OACL,QAAO;OACP,gBAAa;OACb,kBAAe;OACf,mBAAgB;OAChB,aAAU;OACV,eAAY;UAEZ,mBAKE,QAAA;OAJA,IAAG;OACH,IAAG;OACH,IAAG;OACH,IAAG;UAEL,mBAKE,QAAA;OAJA,IAAG;OACH,IAAG;OACH,IAAG;OACH,IAAG;;;;KAOH,MAAA,IAAG,CAAC,UAAU,SAAA,WAAA,EADtB,mBASO,QAAA;;MAPJ,OAAK,eAAE,MAAA,IAAG,CAAC,MAAM,MAAM,WAAS,CAAA;MACjC,aAAU;MACV,MAAK;MACL,aAAU;MACV,cAAW;SAEX,YAAqB,iBAAA,EAAZ,MAAK,MAAI,CAAA,CAAA,EAAA,EAAA,KAAA,WAAA,EAGpB,YAsBsB,MAAA,oBAAA,EAAA;;MApBnB,OAAK,eAAE,MAAA,IAAG,CAAC,MAAM,MAAM,WAAS,CAAA;MACjC,aAAU;MACV,cAAW;;6BAiBJ,CAfP,WAeO,KAAA,QAAA,eAAA,EAAA,QAAA,CAAA,OAAA,OAAA,OAAA,KAdL,mBAaM,OAAA;OAZJ,OAAM;OACN,OAAM;OACN,QAAO;OACP,SAAQ;OACR,MAAK;OACL,QAAO;OACP,gBAAa;OACb,kBAAe;OACf,mBAAgB;OAChB,eAAY;UAEZ,mBAAoC,YAAA,EAA1B,QAAO,kBAAgB,CAAA,CAAA,EAAA,GAAA,EAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutocompleteItem.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, useSlots, type Slots, type VNode } from 'vue'\nimport { AutocompleteItem, ComboboxItemIndicator } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\n\nconst props = withDefaults(defineProps<{\n value: string\n isDisabled?: boolean\n class?: string\n}>(), {\n isDisabled: false,\n class: undefined,\n})\n\nconst slots: Slots = useSlots()\nconst ctx = useAutocompleteInject()\n\
|
|
1
|
+
{"version":3,"file":"AutocompleteItem.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, useSlots, type Slots, type VNode } from 'vue'\nimport { AutocompleteItem, ComboboxItemIndicator } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\n\nconst props = withDefaults(defineProps<{\n value: string\n isDisabled?: boolean\n class?: string\n}>(), {\n isDisabled: false,\n class: undefined,\n})\n\nconst slots: Slots = useSlots()\nconst ctx = useAutocompleteInject()\n\nfunction extractText(nodes: VNode[]): string {\n return nodes.map(n => {\n if (typeof n.children === 'string') return n.children\n if (Array.isArray(n.children)) return extractText(n.children as VNode[])\n return ''\n }).join('')\n}\n\nconst displayText = computed((): string => {\n const vnodes: VNode[] | undefined = (slots.default as (() => VNode[]) | undefined)?.()\n if (!vnodes) return props.value\n return extractText(vnodes).trim() || props.value\n})\n\n// In multiple mode, track whether this item is in the selected array\nconst isChecked = computed(() => ctx.multiple.value && ctx.isSelected(props.value))\n\nonMounted(() => {\n ctx.registerItem(props.value, displayText.value)\n})\n\nonUnmounted(() => {\n ctx.unregisterItem(props.value)\n})\n\nfunction handleSelect(event: Event) {\n if (ctx.multiple.value) {\n // Prevent Reka from overwriting the combobox value with the selected item's text.\n // Without this, Reka's internal handler fires after ours and sets searchTerm = displayText.\n event.preventDefault()\n ctx.onMultipleSelect(props.value)\n }\n}\n</script>\n\n<template>\n <AutocompleteItem\n :value=\"displayText\"\n :text-value=\"displayText\"\n :disabled=\"props.isDisabled\"\n :data-item-value=\"props.value\"\n :data-selected=\"isChecked || undefined\"\n class=\"list-box-item list-box-item--default\"\n data-slot=\"list-box-item\"\n @select=\"handleSelect\"\n >\n <slot name=\"startContent\" />\n <span\n class=\"autocomplete-item__text\"\n data-slot=\"item-text\"\n ><slot /></span>\n <!-- Single mode: Reka's ComboboxItemIndicator handles the checkmark natively -->\n <ComboboxItemIndicator\n v-if=\"!ctx.multiple.value\"\n class=\"list-box-item__indicator\"\n data-slot=\"list-box-item-indicator\"\n >\n <slot name=\"selectedIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"list-box-item-indicator--checkmark\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </slot>\n </ComboboxItemIndicator>\n <!-- Multiple mode: check against our selectedValues array instead -->\n <span\n v-else-if=\"isChecked\"\n class=\"list-box-item__indicator\"\n data-slot=\"list-box-item-indicator\"\n >\n <slot name=\"selectedIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"list-box-item-indicator--checkmark\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </slot>\n </span>\n <slot name=\"endContent\" />\n </AutocompleteItem>\n</template>\n"],"mappings":""}
|
package/dist/components/autocomplete/AutocompleteItem.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { useAutocompleteInject } from "./Autocomplete.context.js";
|
|
2
|
-
import { computed, createBlock,
|
|
2
|
+
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, onMounted, onUnmounted, openBlock, renderSlot, unref, useSlots, withCtx } from "vue";
|
|
3
3
|
import { AutocompleteItem, ComboboxItemIndicator } from "reka-ui";
|
|
4
4
|
//#region src/components/autocomplete/AutocompleteItem.vue?vue&type=script&setup=true&lang.ts
|
|
5
5
|
var _hoisted_1 = {
|
|
6
6
|
class: "autocomplete-item__text",
|
|
7
7
|
"data-slot": "item-text"
|
|
8
8
|
};
|
|
9
|
+
var _hoisted_2 = {
|
|
10
|
+
key: 1,
|
|
11
|
+
class: "list-box-item__indicator",
|
|
12
|
+
"data-slot": "list-box-item-indicator"
|
|
13
|
+
};
|
|
9
14
|
var AutocompleteItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
10
15
|
__name: "AutocompleteItem",
|
|
11
16
|
props: {
|
|
@@ -32,25 +37,35 @@ var AutocompleteItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
32
37
|
if (!vnodes) return props.value;
|
|
33
38
|
return extractText(vnodes).trim() || props.value;
|
|
34
39
|
});
|
|
40
|
+
const isChecked = computed(() => ctx.multiple.value && ctx.isSelected(props.value));
|
|
35
41
|
onMounted(() => {
|
|
36
42
|
ctx.registerItem(props.value, displayText.value);
|
|
37
43
|
});
|
|
38
44
|
onUnmounted(() => {
|
|
39
45
|
ctx.unregisterItem(props.value);
|
|
40
46
|
});
|
|
47
|
+
function handleSelect(event) {
|
|
48
|
+
if (ctx.multiple.value) {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
ctx.onMultipleSelect(props.value);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
41
53
|
return (_ctx, _cache) => {
|
|
42
54
|
return openBlock(), createBlock(unref(AutocompleteItem), {
|
|
43
55
|
value: displayText.value,
|
|
44
56
|
"text-value": displayText.value,
|
|
45
57
|
disabled: props.isDisabled,
|
|
46
58
|
"data-item-value": props.value,
|
|
59
|
+
"data-selected": isChecked.value || void 0,
|
|
47
60
|
class: "list-box-item list-box-item--default",
|
|
48
|
-
"data-slot": "list-box-item"
|
|
61
|
+
"data-slot": "list-box-item",
|
|
62
|
+
onSelect: handleSelect
|
|
49
63
|
}, {
|
|
50
64
|
default: withCtx(() => [
|
|
51
65
|
renderSlot(_ctx.$slots, "startContent"),
|
|
52
66
|
createElementVNode("span", _hoisted_1, [renderSlot(_ctx.$slots, "default")]),
|
|
53
|
-
|
|
67
|
+
!unref(ctx).multiple.value ? (openBlock(), createBlock(unref(ComboboxItemIndicator), {
|
|
68
|
+
key: 0,
|
|
54
69
|
class: "list-box-item__indicator",
|
|
55
70
|
"data-slot": "list-box-item-indicator"
|
|
56
71
|
}, {
|
|
@@ -68,7 +83,19 @@ var AutocompleteItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
68
83
|
"aria-hidden": "true"
|
|
69
84
|
}, [createElementVNode("polyline", { points: "20 6 9 17 4 12" })], -1))])]),
|
|
70
85
|
_: 3
|
|
71
|
-
}),
|
|
86
|
+
})) : isChecked.value ? (openBlock(), createElementBlock("span", _hoisted_2, [renderSlot(_ctx.$slots, "selectedIcon", {}, () => [_cache[1] || (_cache[1] = createElementVNode("svg", {
|
|
87
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
88
|
+
width: "12",
|
|
89
|
+
height: "12",
|
|
90
|
+
viewBox: "0 0 24 24",
|
|
91
|
+
fill: "none",
|
|
92
|
+
stroke: "currentColor",
|
|
93
|
+
"stroke-width": "3",
|
|
94
|
+
"stroke-linecap": "round",
|
|
95
|
+
"stroke-linejoin": "round",
|
|
96
|
+
"data-slot": "list-box-item-indicator--checkmark",
|
|
97
|
+
"aria-hidden": "true"
|
|
98
|
+
}, [createElementVNode("polyline", { points: "20 6 9 17 4 12" })], -1))])])) : createCommentVNode("", true),
|
|
72
99
|
renderSlot(_ctx.$slots, "endContent")
|
|
73
100
|
]),
|
|
74
101
|
_: 3
|
|
@@ -76,7 +103,8 @@ var AutocompleteItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
76
103
|
"value",
|
|
77
104
|
"text-value",
|
|
78
105
|
"disabled",
|
|
79
|
-
"data-item-value"
|
|
106
|
+
"data-item-value",
|
|
107
|
+
"data-selected"
|
|
80
108
|
]);
|
|
81
109
|
};
|
|
82
110
|
}
|
package/dist/components/autocomplete/AutocompleteItem.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutocompleteItem.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, useSlots, type Slots, type VNode } from 'vue'\nimport { AutocompleteItem, ComboboxItemIndicator } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\n\nconst props = withDefaults(defineProps<{\n value: string\n isDisabled?: boolean\n class?: string\n}>(), {\n isDisabled: false,\n class: undefined,\n})\n\nconst slots: Slots = useSlots()\nconst ctx = useAutocompleteInject()\n\
|
|
1
|
+
{"version":3,"file":"AutocompleteItem.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, useSlots, type Slots, type VNode } from 'vue'\nimport { AutocompleteItem, ComboboxItemIndicator } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\n\nconst props = withDefaults(defineProps<{\n value: string\n isDisabled?: boolean\n class?: string\n}>(), {\n isDisabled: false,\n class: undefined,\n})\n\nconst slots: Slots = useSlots()\nconst ctx = useAutocompleteInject()\n\nfunction extractText(nodes: VNode[]): string {\n return nodes.map(n => {\n if (typeof n.children === 'string') return n.children\n if (Array.isArray(n.children)) return extractText(n.children as VNode[])\n return ''\n }).join('')\n}\n\nconst displayText = computed((): string => {\n const vnodes: VNode[] | undefined = (slots.default as (() => VNode[]) | undefined)?.()\n if (!vnodes) return props.value\n return extractText(vnodes).trim() || props.value\n})\n\n// In multiple mode, track whether this item is in the selected array\nconst isChecked = computed(() => ctx.multiple.value && ctx.isSelected(props.value))\n\nonMounted(() => {\n ctx.registerItem(props.value, displayText.value)\n})\n\nonUnmounted(() => {\n ctx.unregisterItem(props.value)\n})\n\nfunction handleSelect(event: Event) {\n if (ctx.multiple.value) {\n // Prevent Reka from overwriting the combobox value with the selected item's text.\n // Without this, Reka's internal handler fires after ours and sets searchTerm = displayText.\n event.preventDefault()\n ctx.onMultipleSelect(props.value)\n }\n}\n</script>\n\n<template>\n <AutocompleteItem\n :value=\"displayText\"\n :text-value=\"displayText\"\n :disabled=\"props.isDisabled\"\n :data-item-value=\"props.value\"\n :data-selected=\"isChecked || undefined\"\n class=\"list-box-item list-box-item--default\"\n data-slot=\"list-box-item\"\n @select=\"handleSelect\"\n >\n <slot name=\"startContent\" />\n <span\n class=\"autocomplete-item__text\"\n data-slot=\"item-text\"\n ><slot /></span>\n <!-- Single mode: Reka's ComboboxItemIndicator handles the checkmark natively -->\n <ComboboxItemIndicator\n v-if=\"!ctx.multiple.value\"\n class=\"list-box-item__indicator\"\n data-slot=\"list-box-item-indicator\"\n >\n <slot name=\"selectedIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"list-box-item-indicator--checkmark\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </slot>\n </ComboboxItemIndicator>\n <!-- Multiple mode: check against our selectedValues array instead -->\n <span\n v-else-if=\"isChecked\"\n class=\"list-box-item__indicator\"\n data-slot=\"list-box-item-indicator\"\n >\n <slot name=\"selectedIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"list-box-item-indicator--checkmark\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </slot>\n </span>\n <slot name=\"endContent\" />\n </AutocompleteItem>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;EAKA,MAAM,QAAQ;EASd,MAAM,QAAe,UAAS;EAC9B,MAAM,MAAM,uBAAsB;EAElC,SAAS,YAAY,OAAwB;AAC3C,UAAO,MAAM,KAAI,MAAK;AACpB,QAAI,OAAO,EAAE,aAAa,SAAU,QAAO,EAAE;AAC7C,QAAI,MAAM,QAAQ,EAAE,SAAS,CAAE,QAAO,YAAY,EAAE,SAAmB;AACvE,WAAO;KACP,CAAC,KAAK,GAAE;;EAGZ,MAAM,cAAc,eAAuB;GACzC,MAAM,SAA+B,MAAM,WAA0C;AACrF,OAAI,CAAC,OAAQ,QAAO,MAAM;AAC1B,UAAO,YAAY,OAAO,CAAC,MAAM,IAAI,MAAM;IAC5C;EAGD,MAAM,YAAY,eAAe,IAAI,SAAS,SAAS,IAAI,WAAW,MAAM,MAAM,CAAA;AAElF,kBAAgB;AACd,OAAI,aAAa,MAAM,OAAO,YAAY,MAAK;IAChD;AAED,oBAAkB;AAChB,OAAI,eAAe,MAAM,MAAK;IAC/B;EAED,SAAS,aAAa,OAAc;AAClC,OAAI,IAAI,SAAS,OAAO;AAGtB,UAAM,gBAAe;AACrB,QAAI,iBAAiB,MAAM,MAAK;;;;uBAMlC,YAgEmB,MAAA,iBAAA,EAAA;IA/DhB,OAAO,YAAA;IACP,cAAY,YAAA;IACZ,UAAU,MAAM;IAChB,mBAAiB,MAAM;IACvB,iBAAe,UAAA,SAAa,KAAA;IAC7B,OAAM;IACN,aAAU;IACT,UAAQ;;2BAEmB;KAA5B,WAA4B,KAAA,QAAA,eAAA;KAC5B,mBAGgB,QAHhB,YAGgB,CAAf,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA;MAGA,MAAA,IAAG,CAAC,SAAS,SAAA,WAAA,EADtB,YAsBwB,MAAA,sBAAA,EAAA;;MApBtB,OAAM;MACN,aAAU;;6BAkBH,CAhBP,WAgBO,KAAA,QAAA,gBAAA,EAAA,QAAA,CAAA,OAAA,OAAA,OAAA,KAfL,mBAcM,OAAA;OAbJ,OAAM;OACN,OAAM;OACN,QAAO;OACP,SAAQ;OACR,MAAK;OACL,QAAO;OACP,gBAAa;OACb,kBAAe;OACf,mBAAgB;OAChB,aAAU;OACV,eAAY;UAEZ,mBAAoC,YAAA,EAA1B,QAAO,kBAAgB,CAAA,CAAA,EAAA,GAAA,EAAA,CAAA,CAAA,CAAA;;WAM1B,UAAA,SAAA,WAAA,EADb,mBAsBO,QAtBP,YAsBO,CAjBL,WAgBO,KAAA,QAAA,gBAAA,EAAA,QAAA,CAAA,OAAA,OAAA,OAAA,KAfL,mBAcM,OAAA;MAbJ,OAAM;MACN,OAAM;MACN,QAAO;MACP,SAAQ;MACR,MAAK;MACL,QAAO;MACP,gBAAa;MACb,kBAAe;MACf,mBAAgB;MAChB,aAAU;MACV,eAAY;SAEZ,mBAAoC,YAAA,EAA1B,QAAO,kBAAgB,CAAA,CAAA,EAAA,GAAA,EAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA;KAIvC,WAA0B,KAAA,QAAA,aAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import AutocompleteOverflowChips_vue_vue_type_script_setup_true_lang_default from "./AutocompleteOverflowChips.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/components/autocomplete/AutocompleteOverflowChips.vue
|
|
3
|
+
var AutocompleteOverflowChips_default = AutocompleteOverflowChips_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { AutocompleteOverflowChips_default as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=AutocompleteOverflowChips.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutocompleteOverflowChips.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteOverflowChips.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, nextTick, useTemplateRef, onMounted, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport Chip from '../chip/Chip.vue'\n\nconst props = defineProps<{\n values: string[]\n getLabel: (value: string) => string\n removeValue: (value: string) => void\n}>()\n\nconst containerEl = useTemplateRef<HTMLElement>('container')\nconst visibleCount = ref(props.values.length)\nconst overflowCount = computed(() => Math.max(0, props.values.length - visibleCount.value))\n\n// Prevents re-entrant reflows while we are in the async measurement phase.\nlet measuring = false\n\nasync function reflow() {\n if (measuring) return\n measuring = true\n\n try {\n const el = containerEl.value\n if (!el) return\n\n // Phase 1: show all chips to measure their natural widths\n visibleCount.value = props.values.length\n await nextTick()\n\n const chips = [...el.querySelectorAll<HTMLElement>('[data-chip-item]')]\n if (!chips.length) return\n\n const containerW = el.offsetWidth\n if (!containerW) return\n\n // BADGE_W = estimated chip width (68px) + CSS gap before it (4px).\n const BADGE_W = 76\n\n let usedW = 0\n let n = 0\n\n for (let i = 0; i < chips.length; i++) {\n const gap = i > 0 ? 4 : 0\n const chipW = chips[i].offsetWidth\n const isLast = i === chips.length - 1\n const budget = isLast ? containerW : containerW - BADGE_W\n\n if (usedW + gap + chipW > budget) break\n usedW += gap + chipW\n n++\n }\n\n visibleCount.value = Math.max(1, n)\n } finally {\n measuring = false\n }\n}\n\nonMounted(reflow)\nuseResizeObserver(containerEl, reflow)\nwatch(\n () => props.values.join('\\x00'),\n () => reflow(),\n { flush: 'post' },\n)\n</script>\n\n<template>\n <div\n ref=\"container\"\n style=\"display: flex; flex-wrap: nowrap; align-items: center; gap: 4px; overflow: hidden; flex: 1; min-width: 0;\"\n >\n <Chip\n v-for=\"(val, i) in values\"\n :key=\"val\"\n data-chip-item\n size=\"sm\"\n is-closable\n :style=\"i >= visibleCount ? 'display: none' : undefined\"\n @close.stop=\"removeValue(val)\"\n >\n {{ getLabel(val) }}\n </Chip>\n <Chip\n v-if=\"overflowCount > 0\"\n size=\"sm\"\n color=\"default\"\n >\n +{{ overflowCount }} more\n </Chip>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import Chip_default from "../chip/Chip.js";
|
|
2
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createTextVNode, defineComponent, nextTick, normalizeStyle, onMounted, openBlock, ref, renderList, toDisplayString, useTemplateRef, watch, withCtx, withModifiers } from "vue";
|
|
3
|
+
import { useResizeObserver } from "@vueuse/core";
|
|
4
|
+
//#region src/components/autocomplete/AutocompleteOverflowChips.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
+
var _hoisted_1 = {
|
|
6
|
+
ref: "container",
|
|
7
|
+
style: {
|
|
8
|
+
"display": "flex",
|
|
9
|
+
"flex-wrap": "nowrap",
|
|
10
|
+
"align-items": "center",
|
|
11
|
+
"gap": "4px",
|
|
12
|
+
"overflow": "hidden",
|
|
13
|
+
"flex": "1",
|
|
14
|
+
"min-width": "0"
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var AutocompleteOverflowChips_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
18
|
+
__name: "AutocompleteOverflowChips",
|
|
19
|
+
props: {
|
|
20
|
+
values: {},
|
|
21
|
+
getLabel: { type: Function },
|
|
22
|
+
removeValue: { type: Function }
|
|
23
|
+
},
|
|
24
|
+
setup(__props) {
|
|
25
|
+
const props = __props;
|
|
26
|
+
const containerEl = useTemplateRef("container");
|
|
27
|
+
const visibleCount = ref(props.values.length);
|
|
28
|
+
const overflowCount = computed(() => Math.max(0, props.values.length - visibleCount.value));
|
|
29
|
+
let measuring = false;
|
|
30
|
+
async function reflow() {
|
|
31
|
+
if (measuring) return;
|
|
32
|
+
measuring = true;
|
|
33
|
+
try {
|
|
34
|
+
const el = containerEl.value;
|
|
35
|
+
if (!el) return;
|
|
36
|
+
visibleCount.value = props.values.length;
|
|
37
|
+
await nextTick();
|
|
38
|
+
const chips = [...el.querySelectorAll("[data-chip-item]")];
|
|
39
|
+
if (!chips.length) return;
|
|
40
|
+
const containerW = el.offsetWidth;
|
|
41
|
+
if (!containerW) return;
|
|
42
|
+
const BADGE_W = 76;
|
|
43
|
+
let usedW = 0;
|
|
44
|
+
let n = 0;
|
|
45
|
+
for (let i = 0; i < chips.length; i++) {
|
|
46
|
+
const gap = i > 0 ? 4 : 0;
|
|
47
|
+
const chipW = chips[i].offsetWidth;
|
|
48
|
+
const budget = i === chips.length - 1 ? containerW : containerW - BADGE_W;
|
|
49
|
+
if (usedW + gap + chipW > budget) break;
|
|
50
|
+
usedW += gap + chipW;
|
|
51
|
+
n++;
|
|
52
|
+
}
|
|
53
|
+
visibleCount.value = Math.max(1, n);
|
|
54
|
+
} finally {
|
|
55
|
+
measuring = false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
onMounted(reflow);
|
|
59
|
+
useResizeObserver(containerEl, reflow);
|
|
60
|
+
watch(() => props.values.join("\0"), () => reflow(), { flush: "post" });
|
|
61
|
+
return (_ctx, _cache) => {
|
|
62
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.values, (val, i) => {
|
|
63
|
+
return openBlock(), createBlock(Chip_default, {
|
|
64
|
+
key: val,
|
|
65
|
+
"data-chip-item": "",
|
|
66
|
+
size: "sm",
|
|
67
|
+
"is-closable": "",
|
|
68
|
+
style: normalizeStyle(i >= visibleCount.value ? "display: none" : void 0),
|
|
69
|
+
onClose: withModifiers(($event) => __props.removeValue(val), ["stop"])
|
|
70
|
+
}, {
|
|
71
|
+
default: withCtx(() => [createTextVNode(toDisplayString(__props.getLabel(val)), 1)]),
|
|
72
|
+
_: 2
|
|
73
|
+
}, 1032, ["style", "onClose"]);
|
|
74
|
+
}), 128)), overflowCount.value > 0 ? (openBlock(), createBlock(Chip_default, {
|
|
75
|
+
key: 0,
|
|
76
|
+
size: "sm",
|
|
77
|
+
color: "default"
|
|
78
|
+
}, {
|
|
79
|
+
default: withCtx(() => [createTextVNode(" +" + toDisplayString(overflowCount.value) + " more ", 1)]),
|
|
80
|
+
_: 1
|
|
81
|
+
})) : createCommentVNode("", true)], 512);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
//#endregion
|
|
86
|
+
export { AutocompleteOverflowChips_vue_vue_type_script_setup_true_lang_default as default };
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=AutocompleteOverflowChips.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutocompleteOverflowChips.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteOverflowChips.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, nextTick, useTemplateRef, onMounted, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport Chip from '../chip/Chip.vue'\n\nconst props = defineProps<{\n values: string[]\n getLabel: (value: string) => string\n removeValue: (value: string) => void\n}>()\n\nconst containerEl = useTemplateRef<HTMLElement>('container')\nconst visibleCount = ref(props.values.length)\nconst overflowCount = computed(() => Math.max(0, props.values.length - visibleCount.value))\n\n// Prevents re-entrant reflows while we are in the async measurement phase.\nlet measuring = false\n\nasync function reflow() {\n if (measuring) return\n measuring = true\n\n try {\n const el = containerEl.value\n if (!el) return\n\n // Phase 1: show all chips to measure their natural widths\n visibleCount.value = props.values.length\n await nextTick()\n\n const chips = [...el.querySelectorAll<HTMLElement>('[data-chip-item]')]\n if (!chips.length) return\n\n const containerW = el.offsetWidth\n if (!containerW) return\n\n // BADGE_W = estimated chip width (68px) + CSS gap before it (4px).\n const BADGE_W = 76\n\n let usedW = 0\n let n = 0\n\n for (let i = 0; i < chips.length; i++) {\n const gap = i > 0 ? 4 : 0\n const chipW = chips[i].offsetWidth\n const isLast = i === chips.length - 1\n const budget = isLast ? containerW : containerW - BADGE_W\n\n if (usedW + gap + chipW > budget) break\n usedW += gap + chipW\n n++\n }\n\n visibleCount.value = Math.max(1, n)\n } finally {\n measuring = false\n }\n}\n\nonMounted(reflow)\nuseResizeObserver(containerEl, reflow)\nwatch(\n () => props.values.join('\\x00'),\n () => reflow(),\n { flush: 'post' },\n)\n</script>\n\n<template>\n <div\n ref=\"container\"\n style=\"display: flex; flex-wrap: nowrap; align-items: center; gap: 4px; overflow: hidden; flex: 1; min-width: 0;\"\n >\n <Chip\n v-for=\"(val, i) in values\"\n :key=\"val\"\n data-chip-item\n size=\"sm\"\n is-closable\n :style=\"i >= visibleCount ? 'display: none' : undefined\"\n @close.stop=\"removeValue(val)\"\n >\n {{ getLabel(val) }}\n </Chip>\n <Chip\n v-if=\"overflowCount > 0\"\n size=\"sm\"\n color=\"default\"\n >\n +{{ overflowCount }} more\n </Chip>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;EAKA,MAAM,QAAQ;EAMd,MAAM,cAAc,eAA4B,YAAW;EAC3D,MAAM,eAAe,IAAI,MAAM,OAAO,OAAM;EAC5C,MAAM,gBAAgB,eAAe,KAAK,IAAI,GAAG,MAAM,OAAO,SAAS,aAAa,MAAM,CAAA;EAG1F,IAAI,YAAY;EAEhB,eAAe,SAAS;AACtB,OAAI,UAAW;AACf,eAAY;AAEZ,OAAI;IACF,MAAM,KAAK,YAAY;AACvB,QAAI,CAAC,GAAI;AAGT,iBAAa,QAAQ,MAAM,OAAO;AAClC,UAAM,UAAS;IAEf,MAAM,QAAQ,CAAC,GAAG,GAAG,iBAA8B,mBAAmB,CAAA;AACtE,QAAI,CAAC,MAAM,OAAQ;IAEnB,MAAM,aAAa,GAAG;AACtB,QAAI,CAAC,WAAY;IAGjB,MAAM,UAAU;IAEhB,IAAI,QAAQ;IACZ,IAAI,IAAI;AAER,SAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;KACrC,MAAM,MAAM,IAAI,IAAI,IAAI;KACxB,MAAM,QAAQ,MAAM,GAAG;KAEvB,MAAM,SADS,MAAM,MAAM,SAAS,IACZ,aAAa,aAAa;AAElD,SAAI,QAAQ,MAAM,QAAQ,OAAQ;AAClC,cAAS,MAAM;AACf;;AAGF,iBAAa,QAAQ,KAAK,IAAI,GAAG,EAAC;aAC1B;AACR,gBAAY;;;AAIhB,YAAU,OAAM;AAChB,oBAAkB,aAAa,OAAM;AACrC,cACQ,MAAM,OAAO,KAAK,KAAO,QACzB,QAAQ,EACd,EAAE,OAAO,QAAQ,CACnB;;uBAIE,mBAsBM,OAtBN,YAsBM,EAAA,UAAA,KAAA,EAlBJ,mBAUO,UAAA,MAAA,WATc,QAAA,SAAX,KAAK,MAAC;wBADhB,YAUO,cAAA;KARJ,KAAK;KACN,kBAAA;KACA,MAAK;KACL,eAAA;KACC,OAAK,eAAE,KAAK,aAAA,QAAY,kBAAqB,KAAA,EAAS;KACtD,SAAK,eAAA,WAAO,QAAA,YAAY,IAAG,EAAA,CAAA,OAAA,CAAA;;4BAET,CAAA,gBAAA,gBAAhB,QAAA,SAAS,IAAG,CAAA,EAAA,EAAA,CAAA,CAAA;;;cAGT,cAAA,QAAa,KAAA,WAAA,EADrB,YAMO,cAAA;;IAJL,MAAK;IACL,OAAM;;2BAEL,CAAA,gBADF,OACE,gBAAG,cAAA,MAAa,GAAG,UACtB,EAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.context.js","names":[],"sources":["../../../src/components/select/Select.context.ts"],"sourcesContent":["import { createContext } from '../../utils/context'\nimport type { ComputedRef, Ref } from 'vue'\nimport type { selectVariants } from '@auronui/styles'\n\nexport interface SelectContext {\n isDisabled: Ref<boolean>\n isInvalid: Ref<boolean>\n isReadonly: Ref<boolean>\n isRequired: Ref<boolean>\n fullWidth: Ref<boolean>\n hasLabel: Ref<boolean>\n labelPlacement: Ref<'inside' | 'outside' | 'outside-left'>\n triggerId: Ref<string>\n label: Ref<string | undefined>\n ariaDescribedBy: Ref<string | undefined>\n slots: ComputedRef<ReturnType<typeof selectVariants>>\n /**\n * Persistent registry of item value → display label. SelectItem registers\n * once on first mount and never unregisters — survives SelectContent\n * unmount so SelectValue can show the selected label while the popover\n * is closed (Reka clears its own optionsSet on unmount).\n */\n registerItem: (value: string, label: string) => void\n itemLabel: (value: string | string[] | undefined | null) => string\n}\n\nexport const {\n useProvide: useSelectProvide,\n useInject: useSelectInject,\n key: selectContextKey,\n} = createContext<SelectContext>('Select')\n"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"Select.context.js","names":[],"sources":["../../../src/components/select/Select.context.ts"],"sourcesContent":["import { createContext } from '../../utils/context'\nimport type { ComputedRef, Ref } from 'vue'\nimport type { selectVariants } from '@auronui/styles'\n\nexport interface SelectContext {\n isDisabled: Ref<boolean>\n isInvalid: Ref<boolean>\n isReadonly: Ref<boolean>\n isRequired: Ref<boolean>\n fullWidth: Ref<boolean>\n hasLabel: Ref<boolean>\n labelPlacement: Ref<'inside' | 'outside' | 'outside-left'>\n triggerId: Ref<string>\n label: Ref<string | undefined>\n ariaDescribedBy: Ref<string | undefined>\n slots: ComputedRef<ReturnType<typeof selectVariants>>\n multiple: Ref<boolean>\n /**\n * Persistent registry of item value → display label. SelectItem registers\n * once on first mount and never unregisters — survives SelectContent\n * unmount so SelectValue can show the selected label while the popover\n * is closed (Reka clears its own optionsSet on unmount).\n */\n registerItem: (value: string, label: string) => void\n itemLabel: (value: string | string[] | undefined | null) => string\n removeValue: (value: string) => void\n}\n\nexport const {\n useProvide: useSelectProvide,\n useInject: useSelectInject,\n key: selectContextKey,\n} = createContext<SelectContext>('Select')\n"],"mappings":";;AA4BA,IAAa,EACX,YAAY,kBACZ,WAAW,iBACX,KAAK,qBACH,cAA6B,SAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.js","names":[],"sources":["../../../src/components/select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, reactive, toRef, useAttrs, useId } from 'vue'\nimport { SelectRoot } from 'reka-ui'\nimport { selectVariants, type SelectVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useSelectProvide } from './Select.context'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadonly: false,\n isRequired: false,\n modelValue: undefined,\n defaultValue: undefined,\n open: undefined,\n defaultOpen: undefined,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'update:open': [value: boolean]\n}>()\n\ntype Props = {\n /** Visual style of the field. @default 'flat' */\n variant?: SelectVariants['variant']\n /** Field height. @default 'md' */\n size?: SelectVariants['size']\n /** Accent color applied to focus ring + floating label. @default 'default' */\n color?: SelectVariants['color']\n /**\n * Where the `label` is rendered relative to the field.\n * - `inside`: floats above the trigger (shrinks when focused/filled)\n * - `outside`: sits above the field, static\n * - `outside-left`: sits to the left, horizontal layout\n * @default 'inside'\n */\n labelPlacement?: SelectVariants['labelPlacement']\n /** Stretches root wrapper to 100% width. @default false */\n fullWidth?: boolean\n /** Marks the field as invalid. Triggers danger styling and enables `errorMessage`. @default false */\n isInvalid?: boolean\n /** Disables the field. @default false */\n isDisabled?: boolean\n /** Makes the field read-only. @default false */\n isReadonly?: boolean\n /** Adds a required asterisk next to the label. @default false */\n isRequired?: boolean\n /** Placeholder shown when no value is selected. */\n placeholder?: string\n /** Form field name, for native form submission. */\n name?: string\n /** Field label. When omitted, the floating-label behavior is skipped. */\n label?: string\n /** Helper text displayed below the field. Suppressed when `isInvalid && errorMessage` is shown. */\n description?: string\n /** Error text displayed below the field. Only rendered when `isInvalid` is also true. */\n errorMessage?: string\n /** Extra classes merged onto the root wrapper via `composeClassName`. */\n class?: string\n\n /* ─── Select-specific ─────────────────────────────────────── */\n /** Two-way bound selected value. */\n modelValue?: string\n /** Initial selected value (uncontrolled). */\n defaultValue?: string\n /** Controls open state of the dropdown. */\n open?: boolean\n /** Initial open state of the dropdown (uncontrolled). */\n defaultOpen?: boolean\n}\n\nconst attrs = useAttrs()\nconst generatedId = useId()\nconst triggerId = computed(() => (attrs.id as string | undefined) ?? generatedId)\n\nconst hasLabel = computed(() => !!props.label)\n\n// Helper IDs / aria wiring\nconst descriptionId = computed(() => `${triggerId.value}-description`)\nconst errorMessageId = computed(() => `${triggerId.value}-error`)\nconst showError = computed(() => props.isInvalid && !!props.errorMessage)\nconst showDescription = computed(() => !!props.description && !showError.value)\nconst hasHelper = computed(() => showError.value || showDescription.value)\nconst ariaDescribedBy = computed(() => {\n if (showError.value) return errorMessageId.value\n if (showDescription.value) return descriptionId.value\n return undefined\n})\n\nconst slotFns = computed(() =>\n selectVariants({\n variant: props.variant,\n size: props.size,\n color: props.color,\n fullWidth: props.fullWidth,\n isInvalid: props.isInvalid,\n isDisabled: props.isDisabled,\n isReadonly: props.isReadonly,\n hasLabel: hasLabel.value,\n labelPlacement: props.labelPlacement,\n }),\n)\n\nconst showOutsideLabel = computed(\n () => hasLabel.value && props.labelPlacement !== 'inside',\n)\n\n// Persistent item registry. SelectItem populates on first mount; entries\n// survive SelectContent unmount so SelectValue can render the label while\n// the popover is closed.\nconst itemRegistry = reactive(new Map<string, string>())\nconst registerItem = (value: string, label: string) => {\n itemRegistry.set(value, label)\n}\nconst itemLabel = (value: string | string[] | undefined | null): string => {\n if (value == null) return ''\n if (Array.isArray(value)) {\n return value.map(v => itemRegistry.get(v) ?? v).filter(Boolean).join(', ')\n }\n return itemRegistry.get(value) ?? value\n}\n\nuseSelectProvide({\n isDisabled: toRef(props, 'isDisabled'),\n isInvalid: toRef(props, 'isInvalid'),\n isReadonly: toRef(props, 'isReadonly'),\n isRequired: toRef(props, 'isRequired'),\n fullWidth: toRef(props, 'fullWidth'),\n hasLabel,\n labelPlacement: toRef(props, 'labelPlacement'),\n triggerId,\n label: toRef(props, 'label'),\n ariaDescribedBy,\n slots: slotFns,\n registerItem,\n itemLabel,\n})\n</script>\n\n<template>\n <div\n :class=\"composeClassName(slotFns.base(), props.class)\"\n :data-invalid=\"isInvalid || undefined\"\n :data-disabled=\"isDisabled || undefined\"\n :data-readonly=\"isReadonly || undefined\"\n :data-required=\"isRequired || undefined\"\n :data-has-label=\"hasLabel || undefined\"\n :data-has-helper=\"hasHelper || undefined\"\n >\n <label\n v-if=\"showOutsideLabel\"\n :for=\"triggerId\"\n :class=\"slotFns.label()\"\n >{{ label }}<span\n v-if=\"isRequired\"\n aria-hidden=\"true\"\n > *</span></label>\n\n <div :class=\"slotFns.mainWrapper()\">\n <SelectRoot\n :model-value=\"props.modelValue\"\n :default-value=\"props.defaultValue\"\n :open=\"props.open\"\n :default-open=\"props.defaultOpen\"\n :disabled=\"props.isDisabled\"\n :required=\"props.isRequired\"\n :name=\"props.name\"\n @update:model-value=\"emit('update:modelValue', $event as string)\"\n @update:open=\"emit('update:open', $event)\"\n >\n <slot />\n </SelectRoot>\n\n <div\n v-if=\"hasHelper\"\n :class=\"slotFns.helperWrapper()\"\n >\n <div\n v-if=\"showError\"\n :id=\"errorMessageId\"\n :class=\"slotFns.errorMessage()\"\n >\n {{ errorMessage }}\n </div>\n <div\n v-else-if=\"showDescription\"\n :id=\"descriptionId\"\n :class=\"slotFns.description()\"\n >\n {{ description }}\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Select.js","names":[],"sources":["../../../src/components/select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, reactive, toRef, useAttrs, useId } from 'vue'\nimport { SelectRoot } from 'reka-ui'\nimport { selectVariants, type SelectVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useSelectProvide } from './Select.context'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadonly: false,\n isRequired: false,\n multiple: false,\n modelValue: undefined,\n defaultValue: undefined,\n open: undefined,\n defaultOpen: undefined,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[]]\n 'update:open': [value: boolean]\n}>()\n\ntype Props = {\n /** Visual style of the field. @default 'flat' */\n variant?: SelectVariants['variant']\n /** Field height. @default 'md' */\n size?: SelectVariants['size']\n /** Accent color applied to focus ring + floating label. @default 'default' */\n color?: SelectVariants['color']\n /**\n * Where the `label` is rendered relative to the field.\n * - `inside`: floats above the trigger (shrinks when focused/filled)\n * - `outside`: sits above the field, static\n * - `outside-left`: sits to the left, horizontal layout\n * @default 'inside'\n */\n labelPlacement?: SelectVariants['labelPlacement']\n /** Stretches root wrapper to 100% width. @default false */\n fullWidth?: boolean\n /** Marks the field as invalid. Triggers danger styling and enables `errorMessage`. @default false */\n isInvalid?: boolean\n /** Disables the field. @default false */\n isDisabled?: boolean\n /** Makes the field read-only. @default false */\n isReadonly?: boolean\n /** Adds a required asterisk next to the label. @default false */\n isRequired?: boolean\n /** Placeholder shown when no value is selected. */\n placeholder?: string\n /** Form field name, for native form submission. */\n name?: string\n /** Field label. When omitted, the floating-label behavior is skipped. */\n label?: string\n /** Helper text displayed below the field. Suppressed when `isInvalid && errorMessage` is shown. */\n description?: string\n /** Error text displayed below the field. Only rendered when `isInvalid` is also true. */\n errorMessage?: string\n /** Extra classes merged onto the root wrapper via `composeClassName`. */\n class?: string\n\n /* ─── Select-specific ─────────────────────────────────────── */\n /** Two-way bound selected value. */\n modelValue?: string | string[]\n /** Initial selected value (uncontrolled). */\n defaultValue?: string | string[]\n /** Allow selecting multiple values. modelValue becomes string[]. @default false */\n multiple?: boolean\n /** Controls open state of the dropdown. */\n open?: boolean\n /** Initial open state of the dropdown (uncontrolled). */\n defaultOpen?: boolean\n}\n\nconst attrs = useAttrs()\nconst generatedId = useId()\nconst triggerId = computed(() => (attrs.id as string | undefined) ?? generatedId)\n\nconst hasLabel = computed(() => !!props.label)\n\n// Helper IDs / aria wiring\nconst descriptionId = computed(() => `${triggerId.value}-description`)\nconst errorMessageId = computed(() => `${triggerId.value}-error`)\nconst showError = computed(() => props.isInvalid && !!props.errorMessage)\nconst showDescription = computed(() => !!props.description && !showError.value)\nconst hasHelper = computed(() => showError.value || showDescription.value)\nconst ariaDescribedBy = computed(() => {\n if (showError.value) return errorMessageId.value\n if (showDescription.value) return descriptionId.value\n return undefined\n})\n\nconst slotFns = computed(() =>\n selectVariants({\n variant: props.variant,\n size: props.size,\n color: props.color,\n fullWidth: props.fullWidth,\n isInvalid: props.isInvalid,\n isDisabled: props.isDisabled,\n isReadonly: props.isReadonly,\n hasLabel: hasLabel.value,\n labelPlacement: props.labelPlacement,\n }),\n)\n\nconst showOutsideLabel = computed(\n () => hasLabel.value && props.labelPlacement !== 'inside',\n)\n\n// Persistent item registry. SelectItem populates on first mount; entries\n// survive SelectContent unmount so SelectValue can render the label while\n// the popover is closed.\nconst itemRegistry = reactive(new Map<string, string>())\nconst registerItem = (value: string, label: string) => {\n itemRegistry.set(value, label)\n}\nconst itemLabel = (value: string | string[] | undefined | null): string => {\n if (value == null) return ''\n if (Array.isArray(value)) {\n return value.map(v => itemRegistry.get(v) ?? v).filter(Boolean).join(', ')\n }\n return itemRegistry.get(value) ?? value\n}\n\nfunction removeValue(value: string) {\n const current = Array.isArray(props.modelValue) ? props.modelValue : []\n emit('update:modelValue', current.filter(v => v !== value))\n}\n\nuseSelectProvide({\n isDisabled: toRef(props, 'isDisabled'),\n isInvalid: toRef(props, 'isInvalid'),\n isReadonly: toRef(props, 'isReadonly'),\n isRequired: toRef(props, 'isRequired'),\n fullWidth: toRef(props, 'fullWidth'),\n hasLabel,\n labelPlacement: toRef(props, 'labelPlacement'),\n triggerId,\n label: toRef(props, 'label'),\n ariaDescribedBy,\n slots: slotFns,\n multiple: toRef(props, 'multiple'),\n registerItem,\n itemLabel,\n removeValue,\n})\n</script>\n\n<template>\n <div\n :class=\"composeClassName(slotFns.base(), props.class)\"\n :data-invalid=\"isInvalid || undefined\"\n :data-disabled=\"isDisabled || undefined\"\n :data-readonly=\"isReadonly || undefined\"\n :data-required=\"isRequired || undefined\"\n :data-has-label=\"hasLabel || undefined\"\n :data-has-helper=\"hasHelper || undefined\"\n >\n <label\n v-if=\"showOutsideLabel\"\n :for=\"triggerId\"\n :class=\"slotFns.label()\"\n >{{ label }}<span\n v-if=\"isRequired\"\n aria-hidden=\"true\"\n > *</span></label>\n\n <div :class=\"slotFns.mainWrapper()\">\n <SelectRoot\n :model-value=\"props.modelValue\"\n :default-value=\"props.defaultValue\"\n :multiple=\"props.multiple\"\n :open=\"props.open\"\n :default-open=\"props.defaultOpen\"\n :disabled=\"props.isDisabled\"\n :required=\"props.isRequired\"\n :name=\"props.name\"\n @update:model-value=\"emit('update:modelValue', $event as string | string[])\"\n @update:open=\"emit('update:open', $event)\"\n >\n <slot />\n </SelectRoot>\n\n <div\n v-if=\"hasHelper\"\n :class=\"slotFns.helperWrapper()\"\n >\n <div\n v-if=\"showError\"\n :id=\"errorMessageId\"\n :class=\"slotFns.errorMessage()\"\n >\n {{ errorMessage }}\n </div>\n <div\n v-else-if=\"showDescription\"\n :id=\"descriptionId\"\n :class=\"slotFns.description()\"\n >\n {{ description }}\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -55,6 +55,10 @@ var Select_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
|
|
|
55
55
|
class: {},
|
|
56
56
|
modelValue: { default: void 0 },
|
|
57
57
|
defaultValue: { default: void 0 },
|
|
58
|
+
multiple: {
|
|
59
|
+
type: Boolean,
|
|
60
|
+
default: false
|
|
61
|
+
},
|
|
58
62
|
open: {
|
|
59
63
|
type: Boolean,
|
|
60
64
|
default: void 0
|
|
@@ -102,6 +106,9 @@ var Select_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
|
|
|
102
106
|
if (Array.isArray(value)) return value.map((v) => itemRegistry.get(v) ?? v).filter(Boolean).join(", ");
|
|
103
107
|
return itemRegistry.get(value) ?? value;
|
|
104
108
|
};
|
|
109
|
+
function removeValue(value) {
|
|
110
|
+
emit("update:modelValue", (Array.isArray(props.modelValue) ? props.modelValue : []).filter((v) => v !== value));
|
|
111
|
+
}
|
|
105
112
|
useSelectProvide({
|
|
106
113
|
isDisabled: toRef(props, "isDisabled"),
|
|
107
114
|
isInvalid: toRef(props, "isInvalid"),
|
|
@@ -114,8 +121,10 @@ var Select_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
|
|
|
114
121
|
label: toRef(props, "label"),
|
|
115
122
|
ariaDescribedBy,
|
|
116
123
|
slots: slotFns,
|
|
124
|
+
multiple: toRef(props, "multiple"),
|
|
117
125
|
registerItem,
|
|
118
|
-
itemLabel
|
|
126
|
+
itemLabel,
|
|
127
|
+
removeValue
|
|
119
128
|
});
|
|
120
129
|
return (_ctx, _cache) => {
|
|
121
130
|
return openBlock(), createElementBlock("div", {
|
|
@@ -133,6 +142,7 @@ var Select_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
|
|
|
133
142
|
}, [createTextVNode(toDisplayString(__props.label), 1), __props.isRequired ? (openBlock(), createElementBlock("span", _hoisted_3, " *")) : createCommentVNode("", true)], 10, _hoisted_2)) : createCommentVNode("", true), createElementVNode("div", { class: normalizeClass(slotFns.value.mainWrapper()) }, [createVNode(unref(SelectRoot), {
|
|
134
143
|
"model-value": props.modelValue,
|
|
135
144
|
"default-value": props.defaultValue,
|
|
145
|
+
multiple: props.multiple,
|
|
136
146
|
open: props.open,
|
|
137
147
|
"default-open": props.defaultOpen,
|
|
138
148
|
disabled: props.isDisabled,
|
|
@@ -146,6 +156,7 @@ var Select_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
|
|
|
146
156
|
}, 8, [
|
|
147
157
|
"model-value",
|
|
148
158
|
"default-value",
|
|
159
|
+
"multiple",
|
|
149
160
|
"open",
|
|
150
161
|
"default-open",
|
|
151
162
|
"disabled",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, reactive, toRef, useAttrs, useId } from 'vue'\nimport { SelectRoot } from 'reka-ui'\nimport { selectVariants, type SelectVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useSelectProvide } from './Select.context'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadonly: false,\n isRequired: false,\n modelValue: undefined,\n defaultValue: undefined,\n open: undefined,\n defaultOpen: undefined,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'update:open': [value: boolean]\n}>()\n\ntype Props = {\n /** Visual style of the field. @default 'flat' */\n variant?: SelectVariants['variant']\n /** Field height. @default 'md' */\n size?: SelectVariants['size']\n /** Accent color applied to focus ring + floating label. @default 'default' */\n color?: SelectVariants['color']\n /**\n * Where the `label` is rendered relative to the field.\n * - `inside`: floats above the trigger (shrinks when focused/filled)\n * - `outside`: sits above the field, static\n * - `outside-left`: sits to the left, horizontal layout\n * @default 'inside'\n */\n labelPlacement?: SelectVariants['labelPlacement']\n /** Stretches root wrapper to 100% width. @default false */\n fullWidth?: boolean\n /** Marks the field as invalid. Triggers danger styling and enables `errorMessage`. @default false */\n isInvalid?: boolean\n /** Disables the field. @default false */\n isDisabled?: boolean\n /** Makes the field read-only. @default false */\n isReadonly?: boolean\n /** Adds a required asterisk next to the label. @default false */\n isRequired?: boolean\n /** Placeholder shown when no value is selected. */\n placeholder?: string\n /** Form field name, for native form submission. */\n name?: string\n /** Field label. When omitted, the floating-label behavior is skipped. */\n label?: string\n /** Helper text displayed below the field. Suppressed when `isInvalid && errorMessage` is shown. */\n description?: string\n /** Error text displayed below the field. Only rendered when `isInvalid` is also true. */\n errorMessage?: string\n /** Extra classes merged onto the root wrapper via `composeClassName`. */\n class?: string\n\n /* ─── Select-specific ─────────────────────────────────────── */\n /** Two-way bound selected value. */\n modelValue?: string\n /** Initial selected value (uncontrolled). */\n defaultValue?: string\n /** Controls open state of the dropdown. */\n open?: boolean\n /** Initial open state of the dropdown (uncontrolled). */\n defaultOpen?: boolean\n}\n\nconst attrs = useAttrs()\nconst generatedId = useId()\nconst triggerId = computed(() => (attrs.id as string | undefined) ?? generatedId)\n\nconst hasLabel = computed(() => !!props.label)\n\n// Helper IDs / aria wiring\nconst descriptionId = computed(() => `${triggerId.value}-description`)\nconst errorMessageId = computed(() => `${triggerId.value}-error`)\nconst showError = computed(() => props.isInvalid && !!props.errorMessage)\nconst showDescription = computed(() => !!props.description && !showError.value)\nconst hasHelper = computed(() => showError.value || showDescription.value)\nconst ariaDescribedBy = computed(() => {\n if (showError.value) return errorMessageId.value\n if (showDescription.value) return descriptionId.value\n return undefined\n})\n\nconst slotFns = computed(() =>\n selectVariants({\n variant: props.variant,\n size: props.size,\n color: props.color,\n fullWidth: props.fullWidth,\n isInvalid: props.isInvalid,\n isDisabled: props.isDisabled,\n isReadonly: props.isReadonly,\n hasLabel: hasLabel.value,\n labelPlacement: props.labelPlacement,\n }),\n)\n\nconst showOutsideLabel = computed(\n () => hasLabel.value && props.labelPlacement !== 'inside',\n)\n\n// Persistent item registry. SelectItem populates on first mount; entries\n// survive SelectContent unmount so SelectValue can render the label while\n// the popover is closed.\nconst itemRegistry = reactive(new Map<string, string>())\nconst registerItem = (value: string, label: string) => {\n itemRegistry.set(value, label)\n}\nconst itemLabel = (value: string | string[] | undefined | null): string => {\n if (value == null) return ''\n if (Array.isArray(value)) {\n return value.map(v => itemRegistry.get(v) ?? v).filter(Boolean).join(', ')\n }\n return itemRegistry.get(value) ?? value\n}\n\nuseSelectProvide({\n isDisabled: toRef(props, 'isDisabled'),\n isInvalid: toRef(props, 'isInvalid'),\n isReadonly: toRef(props, 'isReadonly'),\n isRequired: toRef(props, 'isRequired'),\n fullWidth: toRef(props, 'fullWidth'),\n hasLabel,\n labelPlacement: toRef(props, 'labelPlacement'),\n triggerId,\n label: toRef(props, 'label'),\n ariaDescribedBy,\n slots: slotFns,\n registerItem,\n itemLabel,\n})\n</script>\n\n<template>\n <div\n :class=\"composeClassName(slotFns.base(), props.class)\"\n :data-invalid=\"isInvalid || undefined\"\n :data-disabled=\"isDisabled || undefined\"\n :data-readonly=\"isReadonly || undefined\"\n :data-required=\"isRequired || undefined\"\n :data-has-label=\"hasLabel || undefined\"\n :data-has-helper=\"hasHelper || undefined\"\n >\n <label\n v-if=\"showOutsideLabel\"\n :for=\"triggerId\"\n :class=\"slotFns.label()\"\n >{{ label }}<span\n v-if=\"isRequired\"\n aria-hidden=\"true\"\n > *</span></label>\n\n <div :class=\"slotFns.mainWrapper()\">\n <SelectRoot\n :model-value=\"props.modelValue\"\n :default-value=\"props.defaultValue\"\n :open=\"props.open\"\n :default-open=\"props.defaultOpen\"\n :disabled=\"props.isDisabled\"\n :required=\"props.isRequired\"\n :name=\"props.name\"\n @update:model-value=\"emit('update:modelValue', $event as string)\"\n @update:open=\"emit('update:open', $event)\"\n >\n <slot />\n </SelectRoot>\n\n <div\n v-if=\"hasHelper\"\n :class=\"slotFns.helperWrapper()\"\n >\n <div\n v-if=\"showError\"\n :id=\"errorMessageId\"\n :class=\"slotFns.errorMessage()\"\n >\n {{ errorMessage }}\n </div>\n <div\n v-else-if=\"showDescription\"\n :id=\"descriptionId\"\n :class=\"slotFns.description()\"\n >\n {{ description }}\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Select.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, reactive, toRef, useAttrs, useId } from 'vue'\nimport { SelectRoot } from 'reka-ui'\nimport { selectVariants, type SelectVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useSelectProvide } from './Select.context'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadonly: false,\n isRequired: false,\n multiple: false,\n modelValue: undefined,\n defaultValue: undefined,\n open: undefined,\n defaultOpen: undefined,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[]]\n 'update:open': [value: boolean]\n}>()\n\ntype Props = {\n /** Visual style of the field. @default 'flat' */\n variant?: SelectVariants['variant']\n /** Field height. @default 'md' */\n size?: SelectVariants['size']\n /** Accent color applied to focus ring + floating label. @default 'default' */\n color?: SelectVariants['color']\n /**\n * Where the `label` is rendered relative to the field.\n * - `inside`: floats above the trigger (shrinks when focused/filled)\n * - `outside`: sits above the field, static\n * - `outside-left`: sits to the left, horizontal layout\n * @default 'inside'\n */\n labelPlacement?: SelectVariants['labelPlacement']\n /** Stretches root wrapper to 100% width. @default false */\n fullWidth?: boolean\n /** Marks the field as invalid. Triggers danger styling and enables `errorMessage`. @default false */\n isInvalid?: boolean\n /** Disables the field. @default false */\n isDisabled?: boolean\n /** Makes the field read-only. @default false */\n isReadonly?: boolean\n /** Adds a required asterisk next to the label. @default false */\n isRequired?: boolean\n /** Placeholder shown when no value is selected. */\n placeholder?: string\n /** Form field name, for native form submission. */\n name?: string\n /** Field label. When omitted, the floating-label behavior is skipped. */\n label?: string\n /** Helper text displayed below the field. Suppressed when `isInvalid && errorMessage` is shown. */\n description?: string\n /** Error text displayed below the field. Only rendered when `isInvalid` is also true. */\n errorMessage?: string\n /** Extra classes merged onto the root wrapper via `composeClassName`. */\n class?: string\n\n /* ─── Select-specific ─────────────────────────────────────── */\n /** Two-way bound selected value. */\n modelValue?: string | string[]\n /** Initial selected value (uncontrolled). */\n defaultValue?: string | string[]\n /** Allow selecting multiple values. modelValue becomes string[]. @default false */\n multiple?: boolean\n /** Controls open state of the dropdown. */\n open?: boolean\n /** Initial open state of the dropdown (uncontrolled). */\n defaultOpen?: boolean\n}\n\nconst attrs = useAttrs()\nconst generatedId = useId()\nconst triggerId = computed(() => (attrs.id as string | undefined) ?? generatedId)\n\nconst hasLabel = computed(() => !!props.label)\n\n// Helper IDs / aria wiring\nconst descriptionId = computed(() => `${triggerId.value}-description`)\nconst errorMessageId = computed(() => `${triggerId.value}-error`)\nconst showError = computed(() => props.isInvalid && !!props.errorMessage)\nconst showDescription = computed(() => !!props.description && !showError.value)\nconst hasHelper = computed(() => showError.value || showDescription.value)\nconst ariaDescribedBy = computed(() => {\n if (showError.value) return errorMessageId.value\n if (showDescription.value) return descriptionId.value\n return undefined\n})\n\nconst slotFns = computed(() =>\n selectVariants({\n variant: props.variant,\n size: props.size,\n color: props.color,\n fullWidth: props.fullWidth,\n isInvalid: props.isInvalid,\n isDisabled: props.isDisabled,\n isReadonly: props.isReadonly,\n hasLabel: hasLabel.value,\n labelPlacement: props.labelPlacement,\n }),\n)\n\nconst showOutsideLabel = computed(\n () => hasLabel.value && props.labelPlacement !== 'inside',\n)\n\n// Persistent item registry. SelectItem populates on first mount; entries\n// survive SelectContent unmount so SelectValue can render the label while\n// the popover is closed.\nconst itemRegistry = reactive(new Map<string, string>())\nconst registerItem = (value: string, label: string) => {\n itemRegistry.set(value, label)\n}\nconst itemLabel = (value: string | string[] | undefined | null): string => {\n if (value == null) return ''\n if (Array.isArray(value)) {\n return value.map(v => itemRegistry.get(v) ?? v).filter(Boolean).join(', ')\n }\n return itemRegistry.get(value) ?? value\n}\n\nfunction removeValue(value: string) {\n const current = Array.isArray(props.modelValue) ? props.modelValue : []\n emit('update:modelValue', current.filter(v => v !== value))\n}\n\nuseSelectProvide({\n isDisabled: toRef(props, 'isDisabled'),\n isInvalid: toRef(props, 'isInvalid'),\n isReadonly: toRef(props, 'isReadonly'),\n isRequired: toRef(props, 'isRequired'),\n fullWidth: toRef(props, 'fullWidth'),\n hasLabel,\n labelPlacement: toRef(props, 'labelPlacement'),\n triggerId,\n label: toRef(props, 'label'),\n ariaDescribedBy,\n slots: slotFns,\n multiple: toRef(props, 'multiple'),\n registerItem,\n itemLabel,\n removeValue,\n})\n</script>\n\n<template>\n <div\n :class=\"composeClassName(slotFns.base(), props.class)\"\n :data-invalid=\"isInvalid || undefined\"\n :data-disabled=\"isDisabled || undefined\"\n :data-readonly=\"isReadonly || undefined\"\n :data-required=\"isRequired || undefined\"\n :data-has-label=\"hasLabel || undefined\"\n :data-has-helper=\"hasHelper || undefined\"\n >\n <label\n v-if=\"showOutsideLabel\"\n :for=\"triggerId\"\n :class=\"slotFns.label()\"\n >{{ label }}<span\n v-if=\"isRequired\"\n aria-hidden=\"true\"\n > *</span></label>\n\n <div :class=\"slotFns.mainWrapper()\">\n <SelectRoot\n :model-value=\"props.modelValue\"\n :default-value=\"props.defaultValue\"\n :multiple=\"props.multiple\"\n :open=\"props.open\"\n :default-open=\"props.defaultOpen\"\n :disabled=\"props.isDisabled\"\n :required=\"props.isRequired\"\n :name=\"props.name\"\n @update:model-value=\"emit('update:modelValue', $event as string | string[])\"\n @update:open=\"emit('update:open', $event)\"\n >\n <slot />\n </SelectRoot>\n\n <div\n v-if=\"hasHelper\"\n :class=\"slotFns.helperWrapper()\"\n >\n <div\n v-if=\"showError\"\n :id=\"errorMessageId\"\n :class=\"slotFns.errorMessage()\"\n >\n {{ errorMessage }}\n </div>\n <div\n v-else-if=\"showDescription\"\n :id=\"descriptionId\"\n :class=\"slotFns.description()\"\n >\n {{ description }}\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import SelectOverflowChips_vue_vue_type_script_setup_true_lang_default from "./SelectOverflowChips.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/components/select/SelectOverflowChips.vue
|
|
3
|
+
var SelectOverflowChips_default = SelectOverflowChips_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { SelectOverflowChips_default as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=SelectOverflowChips.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectOverflowChips.js","names":[],"sources":["../../../src/components/select/SelectOverflowChips.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, nextTick, useTemplateRef, onMounted, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport Chip from '../chip/Chip.vue'\n\nconst props = defineProps<{\n values: string[]\n getLabel: (value: string) => string\n}>()\n\nconst containerEl = useTemplateRef<HTMLElement>('container')\nconst visibleCount = ref(props.values.length)\nconst overflowCount = computed(() => Math.max(0, props.values.length - visibleCount.value))\n\n// Prevents re-entrant reflows while we are in the async measurement phase.\nlet measuring = false\n\nasync function reflow() {\n if (measuring) return\n measuring = true\n\n try {\n const el = containerEl.value\n if (!el) return\n\n // Phase 1: show all chips to measure their natural widths\n visibleCount.value = props.values.length\n await nextTick()\n\n const chips = [...el.querySelectorAll<HTMLElement>('[data-chip-item]')]\n if (!chips.length) return\n\n const containerW = el.offsetWidth\n if (!containerW) return\n\n // BADGE_W = estimated chip width (68px) + CSS gap before it (4px).\n // The sm Chip has px-2 (16px padding) so \"+N more\" fits in ~52–68px.\n const BADGE_W = 76\n\n let usedW = 0\n let n = 0\n\n for (let i = 0; i < chips.length; i++) {\n const gap = i > 0 ? 4 : 0\n const chipW = chips[i].offsetWidth\n const isLast = i === chips.length - 1\n // Last chip: use full budget (no badge needed if everything fits).\n // Earlier chips: reserve BADGE_W so the badge has room when we do overflow.\n const budget = isLast ? containerW : containerW - BADGE_W\n\n if (usedW + gap + chipW > budget) break\n usedW += gap + chipW\n n++\n }\n\n visibleCount.value = Math.max(1, n)\n } finally {\n measuring = false\n }\n}\n\nonMounted(reflow)\nuseResizeObserver(containerEl, reflow)\n\n// Watch a comma-joined string derived from the values — Vue uses Object.is for\n// primitives, so this only fires when the selection actually changes.\n//\n// WHY NOT { deep: true }: Vue's watch fires the callback whenever the effect\n// re-runs when deep=true (because `if (deep || hasChanged)` short-circuits).\n// Reka passes a new array reference for modelValue on every internal re-render\n// (optionsSet updates, dropdown open/close), so a deep or shallow ref watch\n// fires continuously, causing the reflow loop that produces the oscillation.\nwatch(\n () => props.values.join('\\x00'),\n () => reflow(),\n { flush: 'post' },\n)\n</script>\n\n<template>\n <div\n ref=\"container\"\n style=\"display: flex; flex-wrap: nowrap; align-items: center; gap: 4px; overflow: hidden; flex: 1; min-width: 0;\"\n >\n <Chip\n v-for=\"(val, i) in values\"\n :key=\"val\"\n data-chip-item\n size=\"sm\"\n :style=\"i >= visibleCount ? 'display: none' : undefined\"\n >\n {{ getLabel(val) }}\n </Chip>\n <Chip\n v-if=\"overflowCount > 0\"\n size=\"sm\"\n color=\"default\"\n >\n +{{ overflowCount }} more\n </Chip>\n </div>\n</template>\n"],"mappings":""}
|