@volverjs/ui-vue 0.0.10-beta.53 → 0.0.10-beta.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.es.js +13 -1
  2. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
  3. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.vue.d.ts +9 -0
  4. package/dist/components/VvCheckboxGroup/index.d.ts +4 -0
  5. package/dist/components/VvCombobox/VvCombobox.es.js +357 -357
  6. package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
  7. package/dist/components/VvInputFile/VvInputFile.es.js +17 -3
  8. package/dist/components/VvInputFile/VvInputFile.umd.js +1 -1
  9. package/dist/components/VvInputFile/VvInputFile.vue.d.ts +9 -0
  10. package/dist/components/VvInputFile/index.d.ts +4 -0
  11. package/dist/components/VvInputText/VvInputText.es.js +18 -20
  12. package/dist/components/VvInputText/VvInputText.umd.js +1 -1
  13. package/dist/components/VvRadioGroup/VvRadioGroup.es.js +13 -1
  14. package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
  15. package/dist/components/VvRadioGroup/VvRadioGroup.vue.d.ts +9 -0
  16. package/dist/components/VvRadioGroup/index.d.ts +4 -0
  17. package/dist/components/VvTextarea/VvTextarea.es.js +1296 -397
  18. package/dist/components/VvTextarea/VvTextarea.umd.js +1 -1
  19. package/dist/components/VvTextarea/VvTextarea.vue.d.ts +52 -0
  20. package/dist/components/VvTextarea/index.d.ts +37 -1
  21. package/dist/components/index.es.js +421 -261
  22. package/dist/components/index.umd.js +1 -1
  23. package/dist/icons.es.js +3 -3
  24. package/dist/icons.umd.js +1 -1
  25. package/dist/props/index.d.ts +8 -1
  26. package/dist/stories/InputText/InputText.stories.d.ts +2 -0
  27. package/dist/stories/InputText/InputText.test.d.ts +2 -0
  28. package/package.json +23 -23
  29. package/src/assets/icons/detailed.json +1 -1
  30. package/src/assets/icons/normal.json +1 -1
  31. package/src/assets/icons/simple.json +1 -1
  32. package/src/components/VvCheckbox/VvCheckbox.vue +2 -2
  33. package/src/components/VvCheckboxGroup/VvCheckboxGroup.vue +2 -0
  34. package/src/components/VvCombobox/VvCombobox.vue +3 -3
  35. package/src/components/VvInputFile/VvInputFile.vue +12 -8
  36. package/src/components/VvInputFile/index.ts +2 -0
  37. package/src/components/VvInputText/VvInputText.vue +20 -22
  38. package/src/components/VvRadio/VvRadio.vue +2 -2
  39. package/src/components/VvRadioGroup/VvRadioGroup.vue +2 -0
  40. package/src/components/VvTextarea/VvTextarea.vue +109 -6
  41. package/src/components/VvTextarea/index.ts +32 -1
  42. package/src/props/index.ts +2 -1
  43. package/src/stories/InputText/InputText.stories.ts +37 -1
  44. package/src/stories/InputText/InputText.test.ts +18 -0
  45. package/src/stories/Textarea/Textarea.stories.ts +1 -1
@@ -1,134 +1,8 @@
1
- import { unref, computed, isRef, defineComponent, h, inject, mergeDefaults, ref, toRefs, openBlock, createBlock, mergeProps, createCommentVNode, useId, watch, useSlots, createElementBlock, normalizeClass, toDisplayString, createElementVNode, renderSlot, normalizeProps, guardReactiveProps, withDirectives, vModelText, createTextVNode, createVNode, createSlots, withCtx } from "vue";
1
+ import { unref, computed, isRef, defineComponent, h, useId, provide, Fragment, ref, toRefs, useAttrs, onMounted, watch, nextTick, openBlock, createElementBlock, createVNode, withCtx, renderSlot, normalizeProps, guardReactiveProps, Transition, mergeProps, toHandlers, withDirectives, createElementVNode, normalizeStyle, normalizeClass, createCommentVNode, vShow, inject, createBlock, createTextVNode, toDisplayString, mergeDefaults, useSlots, vModelText, createSlots, renderList, withModifiers } from "vue";
2
+ import { autoPlacement, flip, shift, size, offset, arrow, useFloating, autoUpdate } from "@floating-ui/vue";
3
+ import { useMutationObserver, useVModel, onClickOutside, useFocusWithin, useElementHover, onKeyStroke, useFocus, useStorage, useElementVisibility } from "@vueuse/core";
4
+ import mitt from "mitt";
2
5
  import { iconExists, Icon, addIcon } from "@iconify/vue";
3
- import { useFocus, useElementVisibility } from "@vueuse/core";
4
- function isEmpty(value) {
5
- return ((value2) => value2 === null || value2 === void 0 || value2 === "" || Array.isArray(value2) && value2.length === 0 || !(value2 instanceof Date) && typeof value2 === "object" && Object.keys(value2).length === 0)(unref(value));
6
- }
7
- function isString(value) {
8
- return typeof value === "string" || value instanceof String;
9
- }
10
- function joinLines(items) {
11
- if (Array.isArray(items)) {
12
- return items.filter((item) => isString(item)).join(" ");
13
- }
14
- return items;
15
- }
16
- function HintSlotFactory(propsOrRef, slots) {
17
- const props = computed(() => {
18
- if (isRef(propsOrRef)) {
19
- return propsOrRef.value;
20
- }
21
- return propsOrRef;
22
- });
23
- const invalidLabel = computed(() => joinLines(props.value.invalidLabel));
24
- const validLabel = computed(() => joinLines(props.value.validLabel));
25
- const loadingLabel = computed(() => props.value.loadingLabel);
26
- const hintLabel = computed(() => props.value.hintLabel);
27
- const hasLoadingLabelOrSlot = computed(
28
- () => Boolean(props.value.loading && (slots.loading || loadingLabel.value))
29
- );
30
- const hasInvalidLabelOrSlot = computed(
31
- () => !hasLoadingLabelOrSlot.value && Boolean(
32
- props.value.invalid && (slots.invalid || invalidLabel.value)
33
- )
34
- );
35
- const hasValidLabelOrSlot = computed(
36
- () => !hasLoadingLabelOrSlot.value && !hasInvalidLabelOrSlot.value && Boolean(props.value.valid && (slots.valid || validLabel.value))
37
- );
38
- const hasHintLabelOrSlot = computed(
39
- () => !hasLoadingLabelOrSlot.value && !hasInvalidLabelOrSlot.value && !hasValidLabelOrSlot.value && Boolean(slots.hint || hintLabel.value)
40
- );
41
- const isVisible = computed(
42
- () => hasInvalidLabelOrSlot.value || hasValidLabelOrSlot.value || hasLoadingLabelOrSlot.value || hasHintLabelOrSlot.value
43
- );
44
- const hintSlotScope = computed(() => ({
45
- modelValue: props.value.modelValue,
46
- valid: props.value.valid,
47
- invalid: props.value.invalid,
48
- loading: props.value.loading
49
- }));
50
- const HintSlot = defineComponent({
51
- name: "HintSlot",
52
- props: {
53
- tag: {
54
- type: String,
55
- default: "small"
56
- }
57
- },
58
- setup() {
59
- return {
60
- isVisible,
61
- invalidLabel,
62
- validLabel,
63
- loadingLabel,
64
- hintLabel,
65
- hasInvalidLabelOrSlot,
66
- hasValidLabelOrSlot,
67
- hasLoadingLabelOrSlot,
68
- hasHintLabelOrSlot
69
- };
70
- },
71
- render() {
72
- var _a, _b, _c, _d, _e, _f, _g, _h;
73
- if (this.isVisible) {
74
- let role;
75
- if (this.hasInvalidLabelOrSlot) {
76
- role = "alert";
77
- }
78
- if (this.hasValidLabelOrSlot) {
79
- role = "status";
80
- }
81
- if (this.hasLoadingLabelOrSlot) {
82
- return h(
83
- this.tag,
84
- {
85
- role
86
- },
87
- ((_b = (_a = this.$slots).loading) == null ? void 0 : _b.call(_a)) ?? this.loadingLabel
88
- );
89
- }
90
- if (this.hasInvalidLabelOrSlot) {
91
- return h(
92
- this.tag,
93
- {
94
- role
95
- },
96
- ((_d = (_c = this.$slots).invalid) == null ? void 0 : _d.call(_c)) ?? this.$slots.invalid ?? this.invalidLabel
97
- );
98
- }
99
- if (this.hasValidLabelOrSlot) {
100
- return h(
101
- this.tag,
102
- {
103
- role
104
- },
105
- ((_f = (_e = this.$slots).valid) == null ? void 0 : _f.call(_e)) ?? this.validLabel
106
- );
107
- }
108
- return h(
109
- this.tag,
110
- {
111
- role
112
- },
113
- ((_h = (_g = this.$slots).hint) == null ? void 0 : _h.call(_g)) ?? this.$slots.hint ?? this.hintLabel
114
- );
115
- }
116
- return null;
117
- }
118
- });
119
- return {
120
- hasInvalidLabelOrSlot,
121
- hasHintLabelOrSlot,
122
- hasValidLabelOrSlot,
123
- hasLoadingLabelOrSlot,
124
- hintSlotScope,
125
- HintSlot
126
- };
127
- }
128
- const VvIconPropsDefaults = {
129
- prefix: "normal"
130
- /* normal */
131
- };
132
6
  var StorageType = /* @__PURE__ */ ((StorageType2) => {
133
7
  StorageType2["local"] = "local";
134
8
  StorageType2["session"] = "session";
@@ -175,169 +49,55 @@ var ActionTag = /* @__PURE__ */ ((ActionTag2) => {
175
49
  ActionTag2["button"] = "button";
176
50
  return ActionTag2;
177
51
  })(ActionTag || {});
52
+ var ActionRoles = /* @__PURE__ */ ((ActionRoles2) => {
53
+ ActionRoles2["button"] = "button";
54
+ ActionRoles2["link"] = "link";
55
+ ActionRoles2["menuitem"] = "menuitem";
56
+ return ActionRoles2;
57
+ })(ActionRoles || {});
58
+ var DropdownRole = /* @__PURE__ */ ((DropdownRole2) => {
59
+ DropdownRole2["listbox"] = "listbox";
60
+ DropdownRole2["menu"] = "menu";
61
+ return DropdownRole2;
62
+ })(DropdownRole || {});
63
+ var DropdownItemRole = /* @__PURE__ */ ((DropdownItemRole2) => {
64
+ DropdownItemRole2["option"] = "option";
65
+ DropdownItemRole2["presentation"] = "presentation";
66
+ return DropdownItemRole2;
67
+ })(DropdownItemRole || {});
178
68
  const INJECTION_KEY_VOLVER = Symbol.for("volver");
179
- function useVolver() {
180
- return inject(INJECTION_KEY_VOLVER);
181
- }
182
- function useModifiers(prefix, modifiers, others) {
183
- return computed(() => {
184
- const toReturn = {
185
- [prefix]: true
186
- };
187
- const modifiersArray = typeof (modifiers == null ? void 0 : modifiers.value) === "string" ? modifiers.value.split(" ") : modifiers == null ? void 0 : modifiers.value;
188
- if (modifiersArray) {
189
- if (Array.isArray(modifiersArray)) {
190
- modifiersArray.forEach((modifier) => {
191
- if (modifier) {
192
- toReturn[`${prefix}--${modifier}`] = true;
193
- }
194
- });
195
- }
196
- }
197
- if (others) {
198
- Object.keys(others.value).forEach((key) => {
199
- toReturn[`${prefix}--${key}`] = unref(others.value[key]);
200
- });
201
- }
202
- return toReturn;
203
- });
204
- }
205
- const __default__$1 = {
206
- name: "VvIcon"
207
- };
208
- const _sfc_main$1 = /* @__PURE__ */ defineComponent({
209
- ...__default__$1,
210
- props: /* @__PURE__ */ mergeDefaults({
211
- name: {},
212
- color: {},
213
- width: {},
214
- height: {},
215
- provider: {},
216
- prefix: {},
217
- src: {},
218
- horizontalFlip: { type: Boolean },
219
- verticalFlip: { type: Boolean },
220
- flip: {},
221
- mode: {},
222
- inline: { type: Boolean },
223
- rotate: {},
224
- onLoad: { type: Function },
225
- svg: {},
226
- modifiers: {}
227
- }, VvIconPropsDefaults),
228
- setup(__props) {
229
- const props = __props;
230
- const hasRotate = computed(() => {
231
- if (typeof props.rotate === "string") {
232
- return Number.parseFloat(props.rotate);
233
- }
234
- return props.rotate;
235
- });
236
- const show = ref(true);
237
- const volver = useVolver();
238
- const { modifiers } = toRefs(props);
239
- const bemCssClasses = useModifiers("vv-icon", modifiers);
240
- const provider = computed(() => {
241
- return props.provider || (volver == null ? void 0 : volver.iconsProvider);
242
- });
243
- const icon = computed(() => {
244
- const name = props.name ?? "";
245
- const iconName = `@${provider.value}:${props.prefix}:${name}`;
246
- if (iconExists(iconName)) {
247
- return iconName;
248
- }
249
- const iconsCollection = volver == null ? void 0 : volver.iconsCollections.find(
250
- (iconsCollection2) => {
251
- const icon2 = `@${provider.value}:${iconsCollection2.prefix}:${name}`;
252
- return iconExists(icon2);
253
- }
254
- );
255
- if (iconsCollection) {
256
- return `@${provider.value}:${iconsCollection.prefix}:${name}`;
257
- }
258
- return name;
259
- });
260
- function getSvgContent(svg) {
261
- let dom;
262
- if (typeof window === "undefined") {
263
- const { JSDOM } = require("jsdom");
264
- dom = new JSDOM().window;
265
- }
266
- const domParser = dom ? new dom.DOMParser() : new window.DOMParser();
267
- const svgDomString = domParser.parseFromString(svg, "text/html");
268
- const svgEl = svgDomString.querySelector("svg");
269
- return svgEl;
270
- }
271
- function addIconFromSvg(svg) {
272
- const svgContentEl = getSvgContent(svg);
273
- const svgContent = (svgContentEl == null ? void 0 : svgContentEl.innerHTML.trim()) || "";
274
- if (svgContentEl && svgContent) {
275
- addIcon(`@${provider.value}:${props.prefix}:${props.name}`, {
276
- body: svgContent,
277
- // Set height and width from svg content
278
- height: svgContentEl.viewBox.baseVal.height,
279
- width: svgContentEl.viewBox.baseVal.width
280
- });
281
- }
282
- }
283
- if (volver) {
284
- if (props.src && !iconExists(`@${provider.value}:${props.prefix}:${props.name}`)) {
285
- show.value = false;
286
- volver.fetchIcon(props.src).then((svg) => {
287
- if (svg) {
288
- addIconFromSvg(svg);
289
- show.value = true;
290
- }
291
- }).catch((e) => {
292
- throw new Error(`Error during fetch icon: ${e == null ? void 0 : e.message}`);
293
- });
294
- }
295
- }
296
- if (props.svg) {
297
- addIconFromSvg(props.svg);
298
- }
299
- return (_ctx, _cache) => {
300
- return unref(show) ? (openBlock(), createBlock(unref(Icon), mergeProps({
301
- key: 0,
302
- class: unref(bemCssClasses)
303
- }, {
304
- inline: _ctx.inline,
305
- width: _ctx.width,
306
- height: _ctx.height,
307
- horizontalFlip: _ctx.horizontalFlip,
308
- verticalFlip: _ctx.verticalFlip,
309
- flip: _ctx.flip,
310
- rotate: unref(hasRotate),
311
- color: _ctx.color,
312
- onLoad: _ctx.onLoad,
313
- icon: unref(icon)
314
- }), null, 16, ["class"])) : createCommentVNode("v-if", true);
315
- };
316
- }
317
- });
318
- const LinkProps = {
319
- /**
320
- * The router-link/nuxt-link property, if it is defined the button is rendered as a ruouter-link or nuxt-link.
321
- * @see Documentation of [router-link](https://router.vuejs.org/api/#router-link) and [nuxt-link](https://nuxtjs.org/api/components-nuxt-link/)
322
- */
323
- to: {
324
- type: [String, Object]
325
- },
326
- /**
327
- * Anchor href
328
- */
329
- href: String,
330
- /**
331
- * Anchor target
332
- */
333
- target: String,
334
- /**
335
- * Anchor rel
336
- */
337
- rel: {
338
- type: String,
339
- default: "noopener noreferrer"
340
- }
69
+ const INJECTION_KEY_DROPDOWN_TRIGGER = Symbol.for(
70
+ "dropdownTrigger"
71
+ );
72
+ const INJECTION_KEY_DROPDOWN_ITEM = Symbol.for(
73
+ "dropdownItem"
74
+ );
75
+ const INJECTION_KEY_DROPDOWN_ACTION = Symbol.for(
76
+ "dropdownAction"
77
+ );
78
+ const LinkProps = {
79
+ /**
80
+ * The router-link/nuxt-link property, if it is defined the button is rendered as a ruouter-link or nuxt-link.
81
+ * @see Documentation of [router-link](https://router.vuejs.org/api/#router-link) and [nuxt-link](https://nuxtjs.org/api/components-nuxt-link/)
82
+ */
83
+ to: {
84
+ type: [String, Object]
85
+ },
86
+ /**
87
+ * Anchor href
88
+ */
89
+ href: String,
90
+ /**
91
+ * Anchor target
92
+ */
93
+ target: String,
94
+ /**
95
+ * Anchor rel
96
+ */
97
+ rel: {
98
+ type: String,
99
+ default: "noopener noreferrer"
100
+ }
341
101
  };
342
102
  const ValidProps = {
343
103
  /**
@@ -396,6 +156,15 @@ const RequiredProps = {
396
156
  default: false
397
157
  }
398
158
  };
159
+ const SelectedProps = {
160
+ /**
161
+ * Whether the item is selected
162
+ */
163
+ selected: {
164
+ type: Boolean,
165
+ default: false
166
+ }
167
+ };
399
168
  const ActiveProps = {
400
169
  /**
401
170
  * Whether the item is active
@@ -506,6 +275,12 @@ const FloatingLabelProps = {
506
275
  default: false
507
276
  }
508
277
  };
278
+ const UnselectableProps = {
279
+ /**
280
+ * If true the input will be unselectable
281
+ */
282
+ unselectable: { type: Boolean, default: true }
283
+ };
509
284
  const IdProps = {
510
285
  /**
511
286
  * Global attribute id
@@ -513,7 +288,7 @@ const IdProps = {
513
288
  */
514
289
  id: [String, Number]
515
290
  };
516
- ({
291
+ const DropdownProps = {
517
292
  /**
518
293
  * Dropdown placement
519
294
  */
@@ -606,7 +381,7 @@ const IdProps = {
606
381
  type: Boolean,
607
382
  default: false
608
383
  }
609
- });
384
+ };
610
385
  const IdNameProps = {
611
386
  ...IdProps,
612
387
  /**
@@ -712,56 +487,1001 @@ const InputTextareaProps = {
712
487
  default: ActionTag.button
713
488
  }
714
489
  });
715
- ({
716
- storageType: {
717
- type: String,
718
- default: StorageType.local,
719
- validator: (value) => Object.values(StorageType).includes(value)
720
- },
721
- storageKey: String
722
- });
723
- const WRAP = {
724
- hard: "hard",
725
- soft: "soft"
490
+ const StorageProps = {
491
+ storageType: {
492
+ type: String,
493
+ default: StorageType.local,
494
+ validator: (value) => Object.values(StorageType).includes(value)
495
+ },
496
+ storageKey: String
497
+ };
498
+ const ACTION_ICONS = {
499
+ showPassword: "eye-on",
500
+ hidePassword: "eye-off",
501
+ showDatePicker: "calendar",
502
+ showTimePicker: "time",
503
+ showColorPicker: "color",
504
+ clear: "close",
505
+ add: "add",
506
+ remove: "trash",
507
+ edit: "edit",
508
+ download: "download"
509
+ };
510
+ const VvIconPropsDefaults = {
511
+ prefix: "normal"
512
+ /* normal */
513
+ };
514
+ const WRAP = {
515
+ hard: "hard",
516
+ soft: "soft"
517
+ };
518
+ const SPELLCHECK = {
519
+ true: true,
520
+ false: false,
521
+ default: "default"
522
+ };
523
+ const VvTextareaEvents = ["update:modelValue", "focus", "blur", "keyup"];
524
+ const VvTextareaProps = {
525
+ ...InputTextareaProps,
526
+ ...StorageProps,
527
+ /**
528
+ * Textarea value
529
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#value
530
+ */
531
+ modelValue: String,
532
+ /**
533
+ * The visible width of the text control, in average character widths. If it is specified, it must be a positive integer. If it is not specified, the default value is 20.
534
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#cols
535
+ */
536
+ cols: { type: [String, Number], default: 20 },
537
+ /**
538
+ * The number of visible text lines for the control. If it is specified, it must be a positive integer. If it is not specified, the default value is 2.
539
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#rows
540
+ */
541
+ rows: { type: [String, Number], default: 2 },
542
+ /**
543
+ * Indicates how the control should wrap the value for form submission.
544
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#wrap
545
+ */
546
+ wrap: { type: String, default: WRAP.soft },
547
+ /**
548
+ * Specifies whether the <textarea> is subject to spell checking by the underlying browser/OS.
549
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#wrap
550
+ */
551
+ spellcheck: { type: [Boolean, String], default: SPELLCHECK.default },
552
+ /**
553
+ * VvIcon name for remove suggestion button
554
+ * @see VVIcon
555
+ */
556
+ iconRemoveSuggestion: {
557
+ type: [String, Object],
558
+ default: ACTION_ICONS.remove
559
+ },
560
+ /**
561
+ * Label for remove suggestion button
562
+ */
563
+ labelRemoveSuggestion: {
564
+ type: String,
565
+ default: "Remove suggestion"
566
+ },
567
+ /**
568
+ * Maximum number of suggestions
569
+ */
570
+ maxSuggestions: {
571
+ type: Number,
572
+ default: 5
573
+ },
574
+ /**
575
+ * Select input text on focus
576
+ */
577
+ selectOnFocus: {
578
+ type: Boolean,
579
+ default: false
580
+ },
581
+ /**
582
+ * If true, the textarea will be resizable
583
+ */
584
+ resizable: Boolean
585
+ };
586
+ function isEmpty(value) {
587
+ return ((value2) => value2 === null || value2 === void 0 || value2 === "" || Array.isArray(value2) && value2.length === 0 || !(value2 instanceof Date) && typeof value2 === "object" && Object.keys(value2).length === 0)(unref(value));
588
+ }
589
+ function isString(value) {
590
+ return typeof value === "string" || value instanceof String;
591
+ }
592
+ function joinLines(items) {
593
+ if (Array.isArray(items)) {
594
+ return items.filter((item) => isString(item)).join(" ");
595
+ }
596
+ return items;
597
+ }
598
+ function HintSlotFactory(propsOrRef, slots) {
599
+ const props = computed(() => {
600
+ if (isRef(propsOrRef)) {
601
+ return propsOrRef.value;
602
+ }
603
+ return propsOrRef;
604
+ });
605
+ const invalidLabel = computed(() => joinLines(props.value.invalidLabel));
606
+ const validLabel = computed(() => joinLines(props.value.validLabel));
607
+ const loadingLabel = computed(() => props.value.loadingLabel);
608
+ const hintLabel = computed(() => props.value.hintLabel);
609
+ const hasLoadingLabelOrSlot = computed(
610
+ () => Boolean(props.value.loading && (slots.loading || loadingLabel.value))
611
+ );
612
+ const hasInvalidLabelOrSlot = computed(
613
+ () => !hasLoadingLabelOrSlot.value && Boolean(
614
+ props.value.invalid && (slots.invalid || invalidLabel.value)
615
+ )
616
+ );
617
+ const hasValidLabelOrSlot = computed(
618
+ () => !hasLoadingLabelOrSlot.value && !hasInvalidLabelOrSlot.value && Boolean(props.value.valid && (slots.valid || validLabel.value))
619
+ );
620
+ const hasHintLabelOrSlot = computed(
621
+ () => !hasLoadingLabelOrSlot.value && !hasInvalidLabelOrSlot.value && !hasValidLabelOrSlot.value && Boolean(slots.hint || hintLabel.value)
622
+ );
623
+ const isVisible = computed(
624
+ () => hasInvalidLabelOrSlot.value || hasValidLabelOrSlot.value || hasLoadingLabelOrSlot.value || hasHintLabelOrSlot.value
625
+ );
626
+ const hintSlotScope = computed(() => ({
627
+ modelValue: props.value.modelValue,
628
+ valid: props.value.valid,
629
+ invalid: props.value.invalid,
630
+ loading: props.value.loading
631
+ }));
632
+ const HintSlot = defineComponent({
633
+ name: "HintSlot",
634
+ props: {
635
+ tag: {
636
+ type: String,
637
+ default: "small"
638
+ }
639
+ },
640
+ setup() {
641
+ return {
642
+ isVisible,
643
+ invalidLabel,
644
+ validLabel,
645
+ loadingLabel,
646
+ hintLabel,
647
+ hasInvalidLabelOrSlot,
648
+ hasValidLabelOrSlot,
649
+ hasLoadingLabelOrSlot,
650
+ hasHintLabelOrSlot
651
+ };
652
+ },
653
+ render() {
654
+ var _a, _b, _c, _d, _e, _f, _g, _h;
655
+ if (this.isVisible) {
656
+ let role;
657
+ if (this.hasInvalidLabelOrSlot) {
658
+ role = "alert";
659
+ }
660
+ if (this.hasValidLabelOrSlot) {
661
+ role = "status";
662
+ }
663
+ if (this.hasLoadingLabelOrSlot) {
664
+ return h(
665
+ this.tag,
666
+ {
667
+ role
668
+ },
669
+ ((_b = (_a = this.$slots).loading) == null ? void 0 : _b.call(_a)) ?? this.loadingLabel
670
+ );
671
+ }
672
+ if (this.hasInvalidLabelOrSlot) {
673
+ return h(
674
+ this.tag,
675
+ {
676
+ role
677
+ },
678
+ ((_d = (_c = this.$slots).invalid) == null ? void 0 : _d.call(_c)) ?? this.$slots.invalid ?? this.invalidLabel
679
+ );
680
+ }
681
+ if (this.hasValidLabelOrSlot) {
682
+ return h(
683
+ this.tag,
684
+ {
685
+ role
686
+ },
687
+ ((_f = (_e = this.$slots).valid) == null ? void 0 : _f.call(_e)) ?? this.validLabel
688
+ );
689
+ }
690
+ return h(
691
+ this.tag,
692
+ {
693
+ role
694
+ },
695
+ ((_h = (_g = this.$slots).hint) == null ? void 0 : _h.call(_g)) ?? this.$slots.hint ?? this.hintLabel
696
+ );
697
+ }
698
+ return null;
699
+ }
700
+ });
701
+ return {
702
+ hasInvalidLabelOrSlot,
703
+ hasHintLabelOrSlot,
704
+ hasValidLabelOrSlot,
705
+ hasLoadingLabelOrSlot,
706
+ hintSlotScope,
707
+ HintSlot
708
+ };
709
+ }
710
+ const VvDropdownProps = {
711
+ ...IdProps,
712
+ ...DropdownProps,
713
+ ...ModifiersProps,
714
+ /**
715
+ * Show / hide dropdown programmatically
716
+ */
717
+ modelValue: {
718
+ type: Boolean,
719
+ default: void 0
720
+ },
721
+ /**
722
+ * Dropdown trigger element
723
+ */
724
+ reference: {
725
+ type: Object,
726
+ default: null
727
+ },
728
+ /**
729
+ * Dropdown role
730
+ */
731
+ role: {
732
+ type: String,
733
+ default: DropdownRole.menu,
734
+ validator: (value) => Object.values(DropdownRole).includes(value)
735
+ }
736
+ };
737
+ const VvDropdownItemProps = {
738
+ focusOnHover: {
739
+ type: Boolean,
740
+ default: false
741
+ }
742
+ };
743
+ const VvDropdownOptionProps = {
744
+ ...DisabledProps,
745
+ ...SelectedProps,
746
+ ...UnselectableProps,
747
+ ...ModifiersProps,
748
+ deselectHintLabel: {
749
+ type: String
750
+ },
751
+ selectHintLabel: {
752
+ type: String
753
+ },
754
+ selectedHintLabel: {
755
+ type: String
756
+ },
757
+ focusOnHover: {
758
+ type: Boolean,
759
+ default: false
760
+ }
761
+ };
762
+ function useUniqueId(id) {
763
+ return computed(() => String((id == null ? void 0 : id.value) || useId()));
764
+ }
765
+ function useDropdownProvideTrigger({
766
+ reference,
767
+ id,
768
+ expanded,
769
+ aria
770
+ }) {
771
+ const bus = mitt();
772
+ const component = defineComponent({
773
+ name: "VvDropdownTriggerProvider",
774
+ setup() {
775
+ provide(INJECTION_KEY_DROPDOWN_TRIGGER, {
776
+ reference,
777
+ id,
778
+ expanded,
779
+ aria,
780
+ bus
781
+ });
782
+ },
783
+ render() {
784
+ var _a, _b;
785
+ return h(Fragment, {}, (_b = (_a = this.$slots).default) == null ? void 0 : _b.call(_a));
786
+ }
787
+ });
788
+ return {
789
+ bus,
790
+ component
791
+ };
792
+ }
793
+ function useDropdownProvideItem({
794
+ role,
795
+ ...others
796
+ }) {
797
+ const itemRole = computed(
798
+ () => role.value === DropdownRole.listbox ? DropdownItemRole.option : DropdownItemRole.presentation
799
+ );
800
+ provide(INJECTION_KEY_DROPDOWN_ITEM, {
801
+ role: itemRole,
802
+ ...others
803
+ });
804
+ return { itemRole };
805
+ }
806
+ function useDropdownProvideAction({
807
+ expanded
808
+ }) {
809
+ provide(INJECTION_KEY_DROPDOWN_ACTION, {
810
+ role: ref(ActionRoles.menuitem),
811
+ expanded
812
+ });
813
+ }
814
+ function useModifiers(prefix, modifiers, others) {
815
+ return computed(() => {
816
+ const toReturn = {
817
+ [prefix]: true
818
+ };
819
+ const modifiersArray = typeof (modifiers == null ? void 0 : modifiers.value) === "string" ? modifiers.value.split(" ") : modifiers == null ? void 0 : modifiers.value;
820
+ if (modifiersArray) {
821
+ if (Array.isArray(modifiersArray)) {
822
+ modifiersArray.forEach((modifier) => {
823
+ if (modifier) {
824
+ toReturn[`${prefix}--${modifier}`] = true;
825
+ }
826
+ });
827
+ }
828
+ }
829
+ if (others) {
830
+ Object.keys(others.value).forEach((key) => {
831
+ toReturn[`${prefix}--${key}`] = unref(others.value[key]);
832
+ });
833
+ }
834
+ return toReturn;
835
+ });
836
+ }
837
+ const _hoisted_1$2 = ["id", "tabindex", "role", "aria-labelledby"];
838
+ const __default__$4 = {
839
+ name: "VvDropdown",
840
+ inheritAttrs: false
841
+ };
842
+ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
843
+ ...__default__$4,
844
+ props: VvDropdownProps,
845
+ emits: [
846
+ "update:modelValue",
847
+ "beforeEnter",
848
+ "afterLeave",
849
+ "beforeExpand",
850
+ "beforeCollapse",
851
+ "afterExpand",
852
+ "afterCollapse",
853
+ "before-enter",
854
+ "after-leave",
855
+ "enter",
856
+ "afterEnter",
857
+ "enterCancelled",
858
+ "beforeLeave",
859
+ "leave",
860
+ "leaveCancelled"
861
+ ],
862
+ setup(__props, { expose: __expose, emit: __emit }) {
863
+ const props = __props;
864
+ const emit = __emit;
865
+ const { id } = toRefs(props);
866
+ const hasId = useUniqueId(id);
867
+ const attrs = useAttrs();
868
+ const maxWidth = ref("auto");
869
+ const maxHeight = ref("auto");
870
+ const localReferenceEl = ref();
871
+ const floatingEl = ref();
872
+ const arrowEl = ref();
873
+ const listEl = ref();
874
+ const referenceEl = computed({
875
+ get: () => props.reference ?? localReferenceEl.value,
876
+ set: (newValue) => {
877
+ localReferenceEl.value = newValue;
878
+ }
879
+ });
880
+ const hasCustomPosition = ref(false);
881
+ onMounted(() => {
882
+ useMutationObserver(
883
+ floatingEl.value,
884
+ () => {
885
+ var _a;
886
+ hasCustomPosition.value = ((_a = window.getComputedStyle(floatingEl.value).getPropertyValue("--dropdown-custom-position")) == null ? void 0 : _a.trim()) === "true";
887
+ },
888
+ {
889
+ attributeFilter: ["style"],
890
+ window
891
+ }
892
+ );
893
+ });
894
+ const middleware = computed(() => {
895
+ const toReturn = [];
896
+ if (props.autoPlacement) {
897
+ if (typeof props.autoPlacement === "boolean") {
898
+ toReturn.push(autoPlacement());
899
+ } else {
900
+ toReturn.push(
901
+ autoPlacement(props.autoPlacement)
902
+ );
903
+ }
904
+ } else if (props.flip) {
905
+ if (typeof props.flip === "boolean") {
906
+ toReturn.push(flip({ fallbackStrategy: "initialPlacement" }));
907
+ } else {
908
+ toReturn.push(flip(props.flip));
909
+ }
910
+ }
911
+ if (props.shift) {
912
+ if (typeof props.shift === "boolean") {
913
+ toReturn.push(shift());
914
+ } else {
915
+ toReturn.push(shift(props.shift));
916
+ }
917
+ }
918
+ if (props.size) {
919
+ const apply = ({
920
+ availableWidth,
921
+ availableHeight
922
+ }) => {
923
+ maxWidth.value = `${availableWidth}px`;
924
+ maxHeight.value = `${availableHeight}px`;
925
+ };
926
+ if (typeof props.size === "boolean") {
927
+ toReturn.push(
928
+ size({
929
+ apply
930
+ })
931
+ );
932
+ } else {
933
+ toReturn.push(
934
+ size({
935
+ ...props.size,
936
+ apply
937
+ })
938
+ );
939
+ }
940
+ }
941
+ if (props.offset) {
942
+ toReturn.push(offset(Number(props.offset)));
943
+ if (["string", "number"].includes(typeof props.offset)) {
944
+ toReturn.push(offset(Number(props.offset)));
945
+ } else {
946
+ toReturn.push(offset(props.offset));
947
+ }
948
+ }
949
+ if (props.arrow) {
950
+ toReturn.push(
951
+ arrow({
952
+ element: arrowEl
953
+ })
954
+ );
955
+ }
956
+ return toReturn;
957
+ });
958
+ const { x, y, middlewareData, placement, strategy } = useFloating(
959
+ referenceEl,
960
+ floatingEl,
961
+ {
962
+ whileElementsMounted: (...args) => {
963
+ return autoUpdate(...args, {
964
+ animationFrame: props.strategy === Strategy.fixed
965
+ });
966
+ },
967
+ placement: computed(() => props.placement),
968
+ strategy: computed(() => props.strategy),
969
+ middleware
970
+ }
971
+ );
972
+ const dropdownPlacement = computed(() => {
973
+ var _a;
974
+ if (hasCustomPosition.value) {
975
+ return void 0;
976
+ }
977
+ const width = props.triggerWidth && referenceEl.value ? `${(_a = referenceEl.value) == null ? void 0 : _a.offsetWidth}px` : void 0;
978
+ return {
979
+ position: strategy.value,
980
+ top: `${y.value ?? 0}px`,
981
+ left: `${x.value ?? 0}px`,
982
+ maxWidth: width ? void 0 : maxWidth.value,
983
+ maxHeight: maxHeight.value,
984
+ width
985
+ };
986
+ });
987
+ const side = computed(
988
+ () => placement.value.split("-")[0]
989
+ );
990
+ const arrowPlacement = computed(() => {
991
+ var _a, _b, _c, _d, _e;
992
+ if (hasCustomPosition.value) {
993
+ return void 0;
994
+ }
995
+ const staticSide = {
996
+ [Side.top]: Side.bottom,
997
+ [Side.right]: Side.left,
998
+ [Side.bottom]: Side.top,
999
+ [Side.left]: Side.right
1000
+ }[side.value];
1001
+ return {
1002
+ left: ((_a = middlewareData.value.arrow) == null ? void 0 : _a.x) !== void 0 ? `${(_b = middlewareData.value.arrow) == null ? void 0 : _b.x}px` : void 0,
1003
+ top: ((_c = middlewareData.value.arrow) == null ? void 0 : _c.y) !== void 0 ? `${(_d = middlewareData.value.arrow) == null ? void 0 : _d.y}px` : void 0,
1004
+ [staticSide]: `${-(((_e = arrowEl.value) == null ? void 0 : _e.offsetWidth) ?? 0) / 2}px`
1005
+ };
1006
+ });
1007
+ const modelValue = useVModel(props, "modelValue", emit);
1008
+ const localModelValue = ref(false);
1009
+ const expanded = computed({
1010
+ get: () => modelValue.value ?? localModelValue.value,
1011
+ set: (newValue) => {
1012
+ if (modelValue.value === void 0) {
1013
+ localModelValue.value = newValue;
1014
+ return;
1015
+ }
1016
+ modelValue.value = newValue;
1017
+ }
1018
+ });
1019
+ function show() {
1020
+ expanded.value = true;
1021
+ }
1022
+ function hide() {
1023
+ expanded.value = false;
1024
+ }
1025
+ function toggle() {
1026
+ expanded.value = !expanded.value;
1027
+ }
1028
+ function init(el) {
1029
+ referenceEl.value = el;
1030
+ }
1031
+ __expose({
1032
+ toggle,
1033
+ show,
1034
+ hide,
1035
+ init,
1036
+ customPosition: hasCustomPosition
1037
+ });
1038
+ watch(expanded, (newValue) => {
1039
+ if (newValue && props.autofocusFirst) {
1040
+ nextTick(() => {
1041
+ const focusableElements = getKeyboardFocusableElements(
1042
+ floatingEl.value
1043
+ );
1044
+ if (focusableElements.length > 0) {
1045
+ focusableElements[0].focus({
1046
+ preventScroll: true
1047
+ });
1048
+ }
1049
+ });
1050
+ }
1051
+ });
1052
+ onClickOutside(
1053
+ floatingEl,
1054
+ () => {
1055
+ if (!props.keepOpen && expanded.value) {
1056
+ expanded.value = false;
1057
+ }
1058
+ },
1059
+ { ignore: [referenceEl] }
1060
+ );
1061
+ const hasAriaLabelledby = computed(() => {
1062
+ var _a, _b;
1063
+ return ((_b = (_a = referenceEl.value) == null ? void 0 : _a.getAttribute) == null ? void 0 : _b.call(_a, "id")) ?? void 0;
1064
+ });
1065
+ const referenceAria = computed(() => ({
1066
+ "aria-controls": hasId.value,
1067
+ "aria-haspopup": true,
1068
+ "aria-expanded": expanded.value
1069
+ }));
1070
+ const { component: VvDropdownTriggerProvider, bus } = useDropdownProvideTrigger({
1071
+ reference: referenceEl,
1072
+ id: hasId,
1073
+ expanded,
1074
+ aria: referenceAria
1075
+ });
1076
+ bus.on("click", toggle);
1077
+ const { role, modifiers } = toRefs(props);
1078
+ const bemCssClasses = useModifiers(
1079
+ "vv-dropdown",
1080
+ modifiers,
1081
+ computed(() => ({
1082
+ arrow: props.arrow
1083
+ }))
1084
+ );
1085
+ const { focused } = useFocusWithin(floatingEl);
1086
+ function getKeyboardFocusableElements(element) {
1087
+ if (!element) {
1088
+ return [];
1089
+ }
1090
+ return [
1091
+ ...element.querySelectorAll(
1092
+ 'a[href], button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'
1093
+ )
1094
+ ].filter(
1095
+ (el) => !el.hasAttribute("disabled") && !el.getAttribute("aria-hidden")
1096
+ );
1097
+ }
1098
+ function focusNext() {
1099
+ nextTick(() => {
1100
+ if (focused.value) {
1101
+ const focusableElements = getKeyboardFocusableElements(
1102
+ floatingEl.value
1103
+ );
1104
+ if (focusableElements.length === 0 || !document.activeElement) {
1105
+ return;
1106
+ }
1107
+ const activeElementIndex = focusableElements.indexOf(
1108
+ document.activeElement
1109
+ );
1110
+ if (activeElementIndex < focusableElements.length - 1) {
1111
+ focusableElements[activeElementIndex + 1].focus({
1112
+ preventScroll: true
1113
+ });
1114
+ } else {
1115
+ focusableElements[0].focus({
1116
+ preventScroll: true
1117
+ });
1118
+ }
1119
+ }
1120
+ });
1121
+ }
1122
+ function focusPrev() {
1123
+ nextTick(() => {
1124
+ if (focused.value) {
1125
+ const focusableElements = getKeyboardFocusableElements(
1126
+ floatingEl.value
1127
+ );
1128
+ if (focusableElements.length === 0 || !document.activeElement) {
1129
+ return;
1130
+ }
1131
+ const activeElementIndex = focusableElements.indexOf(
1132
+ document.activeElement
1133
+ );
1134
+ if (activeElementIndex > 0) {
1135
+ focusableElements[activeElementIndex - 1].focus({
1136
+ preventScroll: true
1137
+ });
1138
+ } else {
1139
+ focusableElements[focusableElements.length - 1].focus({
1140
+ preventScroll: true
1141
+ });
1142
+ }
1143
+ }
1144
+ });
1145
+ }
1146
+ const hovered = useElementHover(floatingEl);
1147
+ const { itemRole } = useDropdownProvideItem({
1148
+ role,
1149
+ expanded,
1150
+ focused,
1151
+ hovered
1152
+ });
1153
+ onKeyStroke("Escape", (e) => {
1154
+ if (expanded.value) {
1155
+ e.preventDefault();
1156
+ hide();
1157
+ }
1158
+ });
1159
+ onKeyStroke("ArrowDown", (e) => {
1160
+ if (expanded.value && focused.value) {
1161
+ e.preventDefault();
1162
+ focusNext();
1163
+ }
1164
+ });
1165
+ onKeyStroke("ArrowUp", (e) => {
1166
+ if (expanded.value && focused.value) {
1167
+ e.preventDefault();
1168
+ focusPrev();
1169
+ }
1170
+ });
1171
+ onKeyStroke([" ", "Enter"], (e) => {
1172
+ const htmlEl = e.target;
1173
+ if (expanded.value && focused.value && htmlEl) {
1174
+ htmlEl == null ? void 0 : htmlEl.click();
1175
+ }
1176
+ });
1177
+ const dropdownTransitionHandlers = {
1178
+ "before-enter": () => {
1179
+ emit(expanded.value ? "beforeExpand" : "beforeCollapse");
1180
+ emit("beforeEnter");
1181
+ },
1182
+ "after-leave": () => {
1183
+ emit(expanded.value ? "afterExpand" : "afterCollapse");
1184
+ emit("afterLeave");
1185
+ },
1186
+ "enter": () => {
1187
+ emit("enter");
1188
+ },
1189
+ "after-enter": () => {
1190
+ emit("afterEnter");
1191
+ },
1192
+ "enter-cancelled": () => {
1193
+ emit("enterCancelled");
1194
+ },
1195
+ "before-leave": () => {
1196
+ emit("beforeLeave");
1197
+ },
1198
+ "leave": () => {
1199
+ emit("leave");
1200
+ },
1201
+ "leave-cancelled": () => {
1202
+ emit("leaveCancelled");
1203
+ }
1204
+ };
1205
+ return (_ctx, _cache) => {
1206
+ return openBlock(), createElementBlock(
1207
+ Fragment,
1208
+ null,
1209
+ [
1210
+ createVNode(unref(VvDropdownTriggerProvider), null, {
1211
+ default: withCtx(() => [
1212
+ renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps({ init, show, hide, toggle, expanded: unref(expanded), aria: unref(referenceAria) })))
1213
+ ]),
1214
+ _: 3
1215
+ /* FORWARDED */
1216
+ }),
1217
+ createVNode(Transition, mergeProps({ name: _ctx.transitionName }, toHandlers(dropdownTransitionHandlers), { persisted: "" }), {
1218
+ default: withCtx(() => [
1219
+ withDirectives(createElementVNode(
1220
+ "div",
1221
+ {
1222
+ ref_key: "floatingEl",
1223
+ ref: floatingEl,
1224
+ style: normalizeStyle(unref(dropdownPlacement)),
1225
+ class: normalizeClass(unref(bemCssClasses))
1226
+ },
1227
+ [
1228
+ props.arrow ? (openBlock(), createElementBlock(
1229
+ "div",
1230
+ {
1231
+ key: 0,
1232
+ ref_key: "arrowEl",
1233
+ ref: arrowEl,
1234
+ style: normalizeStyle(unref(arrowPlacement)),
1235
+ class: "vv-dropdown__arrow"
1236
+ },
1237
+ null,
1238
+ 4
1239
+ /* STYLE */
1240
+ )) : createCommentVNode("v-if", true),
1241
+ renderSlot(_ctx.$slots, "before", normalizeProps(guardReactiveProps({ expanded: unref(expanded) }))),
1242
+ createElementVNode("div", mergeProps(unref(attrs), {
1243
+ id: unref(hasId),
1244
+ ref_key: "listEl",
1245
+ ref: listEl,
1246
+ tabindex: !unref(expanded) ? -1 : void 0,
1247
+ role: unref(role),
1248
+ "aria-labelledby": unref(hasAriaLabelledby),
1249
+ class: "vv-dropdown__list"
1250
+ }), [
1251
+ renderSlot(_ctx.$slots, "items", normalizeProps(guardReactiveProps({
1252
+ role: unref(itemRole)
1253
+ })))
1254
+ ], 16, _hoisted_1$2),
1255
+ renderSlot(_ctx.$slots, "after", normalizeProps(guardReactiveProps({ expanded: unref(expanded) })))
1256
+ ],
1257
+ 6
1258
+ /* CLASS, STYLE */
1259
+ ), [
1260
+ [vShow, unref(expanded)]
1261
+ ])
1262
+ ]),
1263
+ _: 3
1264
+ /* FORWARDED */
1265
+ }, 16, ["name"])
1266
+ ],
1267
+ 64
1268
+ /* STABLE_FRAGMENT */
1269
+ );
1270
+ };
1271
+ }
1272
+ });
1273
+ function useInjectedDropdownItem() {
1274
+ return inject(INJECTION_KEY_DROPDOWN_ITEM, {});
1275
+ }
1276
+ const __default__$3 = {
1277
+ name: "VvDropdownItem"
726
1278
  };
727
- const SPELLCHECK = {
728
- true: true,
729
- false: false,
730
- default: "default"
1279
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
1280
+ ...__default__$3,
1281
+ props: VvDropdownItemProps,
1282
+ setup(__props) {
1283
+ const props = __props;
1284
+ const { role, expanded } = useInjectedDropdownItem();
1285
+ const element = ref(null);
1286
+ useDropdownProvideAction({ expanded });
1287
+ const hovered = useElementHover(element);
1288
+ const { focused } = useFocus(element);
1289
+ const { focused: focusedWithin } = useFocusWithin(element);
1290
+ watch(hovered, (newValue) => {
1291
+ if (newValue && props.focusOnHover) {
1292
+ focused.value = true;
1293
+ }
1294
+ });
1295
+ return (_ctx, _cache) => {
1296
+ return openBlock(), createElementBlock(
1297
+ "div",
1298
+ mergeProps({ role: unref(role) }, {
1299
+ ref_key: "element",
1300
+ ref: element,
1301
+ class: ["vv-dropdown__item", { "focus-visible": unref(focused) || unref(focusedWithin) }]
1302
+ }),
1303
+ [
1304
+ renderSlot(_ctx.$slots, "default")
1305
+ ],
1306
+ 16
1307
+ /* FULL_PROPS */
1308
+ );
1309
+ };
1310
+ }
1311
+ });
1312
+ const _hoisted_1$1 = ["title"];
1313
+ const __default__$2 = {
1314
+ name: "VvDropdownOption"
731
1315
  };
732
- const VvTextareaEvents = ["update:modelValue", "focus", "blur", "keyup"];
733
- const VvTextareaProps = {
734
- ...InputTextareaProps,
735
- /**
736
- * Textarea value
737
- * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#value
738
- */
739
- modelValue: String,
740
- /**
741
- * The visible width of the text control, in average character widths. If it is specified, it must be a positive integer. If it is not specified, the default value is 20.
742
- * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#cols
743
- */
744
- cols: { type: [String, Number], default: 20 },
745
- /**
746
- * The number of visible text lines for the control. If it is specified, it must be a positive integer. If it is not specified, the default value is 2.
747
- * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#rows
748
- */
749
- rows: { type: [String, Number], default: 2 },
750
- /**
751
- * Indicates how the control should wrap the value for form submission.
752
- * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#wrap
753
- */
754
- wrap: { type: String, default: WRAP.soft },
755
- /**
756
- * Specifies whether the <textarea> is subject to spell checking by the underlying browser/OS.
757
- * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#wrap
758
- */
759
- spellcheck: { type: [Boolean, String], default: SPELLCHECK.default },
760
- /**
761
- * If true, the textarea will be resizable
762
- */
763
- resizable: Boolean
1316
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
1317
+ ...__default__$2,
1318
+ props: VvDropdownOptionProps,
1319
+ setup(__props) {
1320
+ const props = __props;
1321
+ const { modifiers } = toRefs(props);
1322
+ const bemCssClasses = useModifiers(
1323
+ "vv-dropdown-option",
1324
+ modifiers,
1325
+ computed(() => ({
1326
+ disabled: props.disabled,
1327
+ selected: props.selected,
1328
+ unselectable: props.unselectable && props.selected
1329
+ }))
1330
+ );
1331
+ const hintLabel = computed(() => {
1332
+ if (props.selected) {
1333
+ return props.unselectable ? props.deselectHintLabel : props.selectedHintLabel;
1334
+ }
1335
+ if (!props.disabled) {
1336
+ return props.selectHintLabel;
1337
+ }
1338
+ return "";
1339
+ });
1340
+ return (_ctx, _cache) => {
1341
+ return openBlock(), createBlock(_sfc_main$3, {
1342
+ class: normalizeClass(unref(bemCssClasses)),
1343
+ tabindex: _ctx.disabled ? -1 : 0,
1344
+ "aria-selected": _ctx.selected,
1345
+ "aria-disabled": _ctx.disabled,
1346
+ "focus-on-hover": _ctx.focusOnHover
1347
+ }, {
1348
+ default: withCtx(() => [
1349
+ renderSlot(_ctx.$slots, "default"),
1350
+ createElementVNode("span", {
1351
+ class: "vv-dropdown-option__hint",
1352
+ title: unref(hintLabel)
1353
+ }, [
1354
+ renderSlot(_ctx.$slots, "hint", normalizeProps(guardReactiveProps({ disabled: _ctx.disabled, selected: _ctx.selected, unselectable: _ctx.unselectable })), () => [
1355
+ createTextVNode(
1356
+ toDisplayString(unref(hintLabel)),
1357
+ 1
1358
+ /* TEXT */
1359
+ )
1360
+ ])
1361
+ ], 8, _hoisted_1$1)
1362
+ ]),
1363
+ _: 3
1364
+ /* FORWARDED */
1365
+ }, 8, ["class", "tabindex", "aria-selected", "aria-disabled", "focus-on-hover"]);
1366
+ };
1367
+ }
1368
+ });
1369
+ function useVolver() {
1370
+ return inject(INJECTION_KEY_VOLVER);
1371
+ }
1372
+ const __default__$1 = {
1373
+ name: "VvIcon"
764
1374
  };
1375
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1376
+ ...__default__$1,
1377
+ props: /* @__PURE__ */ mergeDefaults({
1378
+ name: {},
1379
+ color: {},
1380
+ width: {},
1381
+ height: {},
1382
+ provider: {},
1383
+ prefix: {},
1384
+ src: {},
1385
+ horizontalFlip: { type: Boolean },
1386
+ verticalFlip: { type: Boolean },
1387
+ flip: {},
1388
+ mode: {},
1389
+ inline: { type: Boolean },
1390
+ rotate: {},
1391
+ onLoad: { type: Function },
1392
+ svg: {},
1393
+ modifiers: {}
1394
+ }, VvIconPropsDefaults),
1395
+ setup(__props) {
1396
+ const props = __props;
1397
+ const hasRotate = computed(() => {
1398
+ if (typeof props.rotate === "string") {
1399
+ return Number.parseFloat(props.rotate);
1400
+ }
1401
+ return props.rotate;
1402
+ });
1403
+ const show = ref(true);
1404
+ const volver = useVolver();
1405
+ const { modifiers } = toRefs(props);
1406
+ const bemCssClasses = useModifiers("vv-icon", modifiers);
1407
+ const provider = computed(() => {
1408
+ return props.provider || (volver == null ? void 0 : volver.iconsProvider);
1409
+ });
1410
+ const icon = computed(() => {
1411
+ const name = props.name ?? "";
1412
+ const iconName = `@${provider.value}:${props.prefix}:${name}`;
1413
+ if (iconExists(iconName)) {
1414
+ return iconName;
1415
+ }
1416
+ const iconsCollection = volver == null ? void 0 : volver.iconsCollections.find(
1417
+ (iconsCollection2) => {
1418
+ const icon2 = `@${provider.value}:${iconsCollection2.prefix}:${name}`;
1419
+ return iconExists(icon2);
1420
+ }
1421
+ );
1422
+ if (iconsCollection) {
1423
+ return `@${provider.value}:${iconsCollection.prefix}:${name}`;
1424
+ }
1425
+ return name;
1426
+ });
1427
+ function getSvgContent(svg) {
1428
+ let dom;
1429
+ if (typeof window === "undefined") {
1430
+ const { JSDOM } = require("jsdom");
1431
+ dom = new JSDOM().window;
1432
+ }
1433
+ const domParser = dom ? new dom.DOMParser() : new window.DOMParser();
1434
+ const svgDomString = domParser.parseFromString(svg, "text/html");
1435
+ const svgEl = svgDomString.querySelector("svg");
1436
+ return svgEl;
1437
+ }
1438
+ function addIconFromSvg(svg) {
1439
+ const svgContentEl = getSvgContent(svg);
1440
+ const svgContent = (svgContentEl == null ? void 0 : svgContentEl.innerHTML.trim()) || "";
1441
+ if (svgContentEl && svgContent) {
1442
+ addIcon(`@${provider.value}:${props.prefix}:${props.name}`, {
1443
+ body: svgContent,
1444
+ // Set height and width from svg content
1445
+ height: svgContentEl.viewBox.baseVal.height,
1446
+ width: svgContentEl.viewBox.baseVal.width
1447
+ });
1448
+ }
1449
+ }
1450
+ if (volver) {
1451
+ if (props.src && !iconExists(`@${provider.value}:${props.prefix}:${props.name}`)) {
1452
+ show.value = false;
1453
+ volver.fetchIcon(props.src).then((svg) => {
1454
+ if (svg) {
1455
+ addIconFromSvg(svg);
1456
+ show.value = true;
1457
+ }
1458
+ }).catch((e) => {
1459
+ throw new Error(`Error during fetch icon: ${e == null ? void 0 : e.message}`);
1460
+ });
1461
+ }
1462
+ }
1463
+ if (props.svg) {
1464
+ addIconFromSvg(props.svg);
1465
+ }
1466
+ return (_ctx, _cache) => {
1467
+ return unref(show) ? (openBlock(), createBlock(unref(Icon), mergeProps({
1468
+ key: 0,
1469
+ class: unref(bemCssClasses)
1470
+ }, {
1471
+ inline: _ctx.inline,
1472
+ width: _ctx.width,
1473
+ height: _ctx.height,
1474
+ horizontalFlip: _ctx.horizontalFlip,
1475
+ verticalFlip: _ctx.verticalFlip,
1476
+ flip: _ctx.flip,
1477
+ rotate: unref(hasRotate),
1478
+ color: _ctx.color,
1479
+ onLoad: _ctx.onLoad,
1480
+ icon: unref(icon)
1481
+ }), null, 16, ["class"])) : createCommentVNode("v-if", true);
1482
+ };
1483
+ }
1484
+ });
765
1485
  function useDefaults(componentName, propsDefinition, props) {
766
1486
  const volver = useVolver();
767
1487
  const volverComponentDefaults = computed(() => {
@@ -815,9 +1535,6 @@ function useDefaults(componentName, propsDefinition, props) {
815
1535
  }, {});
816
1536
  });
817
1537
  }
818
- function useUniqueId(id) {
819
- return computed(() => String((id == null ? void 0 : id.value) || useId()));
820
- }
821
1538
  function useDebouncedInput(modelValue, emit, ms = 0, {
822
1539
  getter = (value) => value,
823
1540
  setter = (value) => value
@@ -916,22 +1633,83 @@ function useTextCount(text, options) {
916
1633
  formatted
917
1634
  };
918
1635
  }
1636
+ function usePersistence(storageKey, storageType = StorageType.local, defaultValue) {
1637
+ const localValue = ref();
1638
+ if (defaultValue) {
1639
+ localValue.value = defaultValue;
1640
+ }
1641
+ let storageValue;
1642
+ if (storageKey) {
1643
+ watch(
1644
+ storageKey,
1645
+ (newKey, oldKey) => {
1646
+ const storage = unref(storageType) === StorageType.session ? sessionStorage : localStorage;
1647
+ if (oldKey && oldKey !== newKey) {
1648
+ storage.removeItem(oldKey);
1649
+ }
1650
+ if (newKey) {
1651
+ storageValue = useStorage(
1652
+ newKey,
1653
+ (storageValue == null ? void 0 : storageValue.value) ?? localValue.value,
1654
+ storage
1655
+ );
1656
+ return;
1657
+ }
1658
+ storageValue = void 0;
1659
+ },
1660
+ {
1661
+ immediate: true
1662
+ }
1663
+ );
1664
+ }
1665
+ if (isRef(storageType)) {
1666
+ watch(storageType, (newType, oldType) => {
1667
+ if (storageKey == null ? void 0 : storageKey.value) {
1668
+ if (newType) {
1669
+ const storage = newType === StorageType.session ? sessionStorage : localStorage;
1670
+ storageValue = useStorage(
1671
+ storageKey.value,
1672
+ (storageValue == null ? void 0 : storageValue.value) ?? localValue.value,
1673
+ storage
1674
+ );
1675
+ }
1676
+ if (oldType && oldType !== newType) {
1677
+ const oldStorage = oldType === StorageType.session ? sessionStorage : localStorage;
1678
+ oldStorage.removeItem(storageKey.value);
1679
+ }
1680
+ }
1681
+ });
1682
+ }
1683
+ return computed({
1684
+ get: () => {
1685
+ return (storageValue == null ? void 0 : storageValue.value) ?? localValue.value;
1686
+ },
1687
+ set: (value) => {
1688
+ if (storageValue) {
1689
+ storageValue.value = value;
1690
+ return;
1691
+ }
1692
+ localValue.value = value;
1693
+ }
1694
+ });
1695
+ }
919
1696
  const _hoisted_1 = ["for"];
920
- const _hoisted_2 = { class: "vv-textarea__wrapper" };
921
- const _hoisted_3 = {
1697
+ const _hoisted_2 = {
922
1698
  key: 0,
923
1699
  class: "vv-textarea__input-before"
924
1700
  };
925
- const _hoisted_4 = { class: "vv-textarea__inner" };
926
- const _hoisted_5 = ["id"];
927
- const _hoisted_6 = {
1701
+ const _hoisted_3 = { class: "vv-textarea__inner" };
1702
+ const _hoisted_4 = ["id"];
1703
+ const _hoisted_5 = {
928
1704
  key: 1,
929
1705
  class: "vv-textarea__input-after"
930
1706
  };
931
- const _hoisted_7 = {
1707
+ const _hoisted_6 = {
932
1708
  key: 2,
933
1709
  class: "vv-textarea__limit"
934
1710
  };
1711
+ const _hoisted_7 = { class: "flex-1" };
1712
+ const _hoisted_8 = ["title", "onClick"];
935
1713
  const __default__ = {
936
1714
  name: "VvTextarea"
937
1715
  };
@@ -948,11 +1726,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
948
1726
  VvTextareaProps,
949
1727
  props
950
1728
  );
951
- const textarea = ref();
1729
+ const textareaEl = ref();
1730
+ const wrapperEl = ref();
1731
+ const suggestionsDropdownEl = ref();
952
1732
  const {
953
1733
  id,
954
1734
  icon,
955
1735
  iconPosition,
1736
+ iconRemoveSuggestion,
1737
+ labelRemoveSuggestion,
956
1738
  label,
957
1739
  modelValue,
958
1740
  count,
@@ -962,7 +1744,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
962
1744
  modifiers,
963
1745
  debounce,
964
1746
  minlength,
965
- maxlength
1747
+ maxlength,
1748
+ storageKey,
1749
+ storageType
966
1750
  } = toRefs(props);
967
1751
  const hasId = useUniqueId(id);
968
1752
  const hasHintId = computed(() => `${hasId.value}-hint`);
@@ -971,8 +1755,33 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
971
1755
  );
972
1756
  const localModelValue = useDebouncedInput(modelValue, emit, debounce == null ? void 0 : debounce.value);
973
1757
  const { hasIconBefore, hasIconAfter } = useComponentIcon(icon, iconPosition);
974
- const { focused } = useComponentFocus(textarea, emit);
975
- const isVisible = useElementVisibility(textarea);
1758
+ const { hasIcon: hasIconRemoveSuggestion } = useComponentIcon(iconRemoveSuggestion);
1759
+ const { focused } = useComponentFocus(textareaEl, emit);
1760
+ const isFocused = computed(
1761
+ () => focused.value && !props.disabled && !props.readonly
1762
+ );
1763
+ watch(isFocused, (newValue) => {
1764
+ var _a, _b;
1765
+ if (newValue && propsDefaults.value.selectOnFocus && textareaEl.value) {
1766
+ textareaEl.value.select();
1767
+ }
1768
+ if (newValue && ((_a = suggestions.value) == null ? void 0 : _a.size)) {
1769
+ (_b = suggestionsDropdownEl.value) == null ? void 0 : _b.show();
1770
+ return;
1771
+ }
1772
+ if (isDirty.value && suggestions.value) {
1773
+ const suggestionsLimit = props.maxSuggestions;
1774
+ if (suggestions.value.size >= suggestionsLimit && !suggestions.value.has(localModelValue.value)) {
1775
+ suggestions.value = new Set(
1776
+ [...suggestions.value].slice(
1777
+ suggestions.value.size - suggestionsLimit + 1
1778
+ )
1779
+ );
1780
+ }
1781
+ suggestions.value.add(localModelValue.value);
1782
+ }
1783
+ });
1784
+ const isVisible = useElementVisibility(textareaEl);
976
1785
  watch(isVisible, (newValue) => {
977
1786
  if (newValue && props.autofocus) {
978
1787
  focused.value = true;
@@ -997,6 +1806,31 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
997
1806
  }
998
1807
  return void 0;
999
1808
  });
1809
+ const suggestions = usePersistence(
1810
+ storageKey,
1811
+ storageType,
1812
+ /* @__PURE__ */ new Set()
1813
+ );
1814
+ const filteredSuggestions = computed(() => {
1815
+ if (!suggestions.value) {
1816
+ return [];
1817
+ }
1818
+ return [...suggestions.value].filter(
1819
+ (suggestion) => isEmpty(localModelValue.value) || `${suggestion}`.toLowerCase().includes(`${localModelValue.value}`.toLowerCase()) && suggestion !== localModelValue.value
1820
+ ).reverse();
1821
+ });
1822
+ const hasSuggestions = computed(
1823
+ () => (storageKey == null ? void 0 : storageKey.value) && suggestions.value && suggestions.value.size > 0
1824
+ );
1825
+ function onSuggestionSelect(suggestion) {
1826
+ var _a;
1827
+ localModelValue.value = suggestion;
1828
+ (_a = suggestionsDropdownEl.value) == null ? void 0 : _a.hide();
1829
+ }
1830
+ function onSuggestionRemove(suggestion) {
1831
+ var _a;
1832
+ (_a = suggestions.value) == null ? void 0 : _a.delete(suggestion);
1833
+ }
1000
1834
  const {
1001
1835
  HintSlot,
1002
1836
  hasHintLabelOrSlot,
@@ -1065,49 +1899,59 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1065
1899
  for: unref(hasId),
1066
1900
  class: "vv-textarea__label"
1067
1901
  }, toDisplayString(unref(label)), 9, _hoisted_1)) : createCommentVNode("v-if", true),
1068
- createElementVNode("div", _hoisted_2, [
1069
- _ctx.$slots.before ? (openBlock(), createElementBlock("div", _hoisted_3, [
1070
- renderSlot(_ctx.$slots, "before", normalizeProps(guardReactiveProps(unref(slotProps))))
1071
- ])) : createCommentVNode("v-if", true),
1072
- createElementVNode("div", _hoisted_4, [
1073
- unref(hasIconBefore) ? (openBlock(), createBlock(
1074
- _sfc_main$1,
1075
- mergeProps({ key: 0 }, unref(hasIconBefore), { class: "vv-textarea__icon" }),
1076
- null,
1077
- 16
1078
- /* FULL_PROPS */
1079
- )) : createCommentVNode("v-if", true),
1080
- withDirectives(createElementVNode("textarea", mergeProps({
1081
- id: unref(hasId),
1082
- ref_key: "textarea",
1083
- ref: textarea,
1084
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(localModelValue) ? localModelValue.value = $event : null)
1085
- }, unref(hasAttrs), {
1086
- onKeyup: _cache[1] || (_cache[1] = ($event) => emit("keyup", $event))
1087
- }), null, 16, _hoisted_5), [
1088
- [vModelText, unref(localModelValue)]
1902
+ createElementVNode(
1903
+ "div",
1904
+ {
1905
+ ref_key: "wrapperEl",
1906
+ ref: wrapperEl,
1907
+ class: "vv-textarea__wrapper"
1908
+ },
1909
+ [
1910
+ _ctx.$slots.before ? (openBlock(), createElementBlock("div", _hoisted_2, [
1911
+ renderSlot(_ctx.$slots, "before", normalizeProps(guardReactiveProps(unref(slotProps))))
1912
+ ])) : createCommentVNode("v-if", true),
1913
+ createElementVNode("div", _hoisted_3, [
1914
+ unref(hasIconBefore) ? (openBlock(), createBlock(
1915
+ _sfc_main$1,
1916
+ mergeProps({ key: 0 }, unref(hasIconBefore), { class: "vv-textarea__icon" }),
1917
+ null,
1918
+ 16
1919
+ /* FULL_PROPS */
1920
+ )) : createCommentVNode("v-if", true),
1921
+ withDirectives(createElementVNode("textarea", mergeProps({
1922
+ id: unref(hasId),
1923
+ ref_key: "textareaEl",
1924
+ ref: textareaEl,
1925
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(localModelValue) ? localModelValue.value = $event : null)
1926
+ }, unref(hasAttrs), {
1927
+ onKeyup: _cache[1] || (_cache[1] = ($event) => emit("keyup", $event))
1928
+ }), null, 16, _hoisted_4), [
1929
+ [vModelText, unref(localModelValue)]
1930
+ ]),
1931
+ unref(hasIconAfter) ? (openBlock(), createBlock(
1932
+ _sfc_main$1,
1933
+ mergeProps({ key: 1 }, unref(hasIconAfter), { class: "vv-textarea__icon vv-textarea__icon-after" }),
1934
+ null,
1935
+ 16
1936
+ /* FULL_PROPS */
1937
+ )) : createCommentVNode("v-if", true)
1089
1938
  ]),
1090
- unref(hasIconAfter) ? (openBlock(), createBlock(
1091
- _sfc_main$1,
1092
- mergeProps({ key: 1 }, unref(hasIconAfter), { class: "vv-textarea__icon vv-textarea__icon-after" }),
1093
- null,
1094
- 16
1095
- /* FULL_PROPS */
1096
- )) : createCommentVNode("v-if", true)
1097
- ]),
1098
- _ctx.$slots.after ? (openBlock(), createElementBlock("div", _hoisted_6, [
1099
- renderSlot(_ctx.$slots, "after", normalizeProps(guardReactiveProps(unref(slotProps))))
1100
- ])) : createCommentVNode("v-if", true),
1101
- unref(count) ? (openBlock(), createElementBlock("span", _hoisted_7, [
1102
- renderSlot(_ctx.$slots, "count", normalizeProps(guardReactiveProps(unref(slotProps))), () => [
1103
- createTextVNode(
1104
- toDisplayString(unref(countFormatted)),
1105
- 1
1106
- /* TEXT */
1107
- )
1108
- ])
1109
- ])) : createCommentVNode("v-if", true)
1110
- ]),
1939
+ _ctx.$slots.after ? (openBlock(), createElementBlock("div", _hoisted_5, [
1940
+ renderSlot(_ctx.$slots, "after", normalizeProps(guardReactiveProps(unref(slotProps))))
1941
+ ])) : createCommentVNode("v-if", true),
1942
+ unref(count) ? (openBlock(), createElementBlock("span", _hoisted_6, [
1943
+ renderSlot(_ctx.$slots, "count", normalizeProps(guardReactiveProps(unref(slotProps))), () => [
1944
+ createTextVNode(
1945
+ toDisplayString(unref(countFormatted)),
1946
+ 1
1947
+ /* TEXT */
1948
+ )
1949
+ ])
1950
+ ])) : createCommentVNode("v-if", true)
1951
+ ],
1952
+ 512
1953
+ /* NEED_PATCH */
1954
+ ),
1111
1955
  createVNode(unref(HintSlot), {
1112
1956
  id: unref(hasHintId),
1113
1957
  class: "vv-textarea__hint"
@@ -1143,7 +1987,62 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1143
1987
  ]),
1144
1988
  key: "3"
1145
1989
  } : void 0
1146
- ]), 1032, ["id"])
1990
+ ]), 1032, ["id"]),
1991
+ unref(hasSuggestions) ? (openBlock(), createBlock(_sfc_main$4, {
1992
+ key: 1,
1993
+ ref_key: "suggestionsDropdownEl",
1994
+ ref: suggestionsDropdownEl,
1995
+ reference: unref(wrapperEl),
1996
+ "autofocus-first": false,
1997
+ "trigger-width": true
1998
+ }, {
1999
+ items: withCtx(() => [
2000
+ (openBlock(true), createElementBlock(
2001
+ Fragment,
2002
+ null,
2003
+ renderList(unref(filteredSuggestions), (value) => {
2004
+ return openBlock(), createBlock(_sfc_main$2, {
2005
+ key: value,
2006
+ onClick: withModifiers(($event) => onSuggestionSelect(value), ["stop"])
2007
+ }, {
2008
+ default: withCtx(() => [
2009
+ createElementVNode("div", _hoisted_7, [
2010
+ renderSlot(_ctx.$slots, "suggestion", mergeProps({ ref_for: true }, { value }), () => [
2011
+ createTextVNode(
2012
+ toDisplayString(value),
2013
+ 1
2014
+ /* TEXT */
2015
+ )
2016
+ ])
2017
+ ]),
2018
+ unref(suggestions) && unref(hasIconRemoveSuggestion) ? (openBlock(), createElementBlock("button", {
2019
+ key: 0,
2020
+ type: "button",
2021
+ tabindex: "-1",
2022
+ class: "cursor-pointer",
2023
+ title: unref(labelRemoveSuggestion),
2024
+ onClick: withModifiers(($event) => onSuggestionRemove(value), ["stop"])
2025
+ }, [
2026
+ createVNode(
2027
+ _sfc_main$1,
2028
+ mergeProps({ ref_for: true }, unref(hasIconRemoveSuggestion)),
2029
+ null,
2030
+ 16
2031
+ /* FULL_PROPS */
2032
+ )
2033
+ ], 8, _hoisted_8)) : createCommentVNode("v-if", true)
2034
+ ]),
2035
+ _: 2
2036
+ /* DYNAMIC */
2037
+ }, 1032, ["onClick"]);
2038
+ }),
2039
+ 128
2040
+ /* KEYED_FRAGMENT */
2041
+ ))
2042
+ ]),
2043
+ _: 3
2044
+ /* FORWARDED */
2045
+ }, 8, ["reference"])) : createCommentVNode("v-if", true)
1147
2046
  ],
1148
2047
  2
1149
2048
  /* CLASS */