@volverjs/ui-vue 0.0.10-beta.54 → 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.
@@ -3319,6 +3319,181 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
3319
3319
  };
3320
3320
  }
3321
3321
  });
3322
+ const VvComboboxProps = {
3323
+ ...IdNameProps,
3324
+ ...TabindexProps,
3325
+ ...ValidProps,
3326
+ ...InvalidProps,
3327
+ ...HintProps,
3328
+ ...LoadingProps,
3329
+ ...DisabledProps,
3330
+ ...ReadonlyProps,
3331
+ ...ModifiersProps,
3332
+ ...OptionsProps,
3333
+ ...IconProps,
3334
+ ...FloatingLabelProps,
3335
+ ...DropdownProps,
3336
+ ...LabelProps,
3337
+ ...RequiredProps,
3338
+ /**
3339
+ * Dropdown show / hide transition name
3340
+ */
3341
+ transitionName: {
3342
+ type: String,
3343
+ default: "vv-dropdown--mobile-fade-block"
3344
+ },
3345
+ /**
3346
+ * modelValue can be a string, number, boolean, object or array of string, number, boolean, object
3347
+ */
3348
+ modelValue: {
3349
+ type: [String, Number, Boolean, Object, Array],
3350
+ default: void 0
3351
+ },
3352
+ /**
3353
+ * Label for no search results
3354
+ */
3355
+ noResultsLabel: { type: String, default: "No results" },
3356
+ /**
3357
+ * Label for no options available
3358
+ */
3359
+ noOptionsLabel: { type: String, default: "No options available" },
3360
+ /**
3361
+ * Label for selected option hint
3362
+ */
3363
+ selectedHintLabel: { type: String, default: "Selected" },
3364
+ /**
3365
+ * Label for deselect action button
3366
+ */
3367
+ deselectActionLabel: { type: String, default: "Deselect" },
3368
+ /**
3369
+ * Label for select option hint
3370
+ */
3371
+ selectHintLabel: { type: String, default: "Press enter to select" },
3372
+ /**
3373
+ * Label for deselected option hint
3374
+ */
3375
+ deselectHintLabel: { type: String, default: "Press enter to remove" },
3376
+ /**
3377
+ * Label close button
3378
+ */
3379
+ closeLabel: { type: String, default: "Close" },
3380
+ /**
3381
+ * Select input placeholder
3382
+ */
3383
+ placeholder: String,
3384
+ /**
3385
+ * Use input text to search on options
3386
+ */
3387
+ searchable: Boolean,
3388
+ /**
3389
+ * Search function to filter options
3390
+ */
3391
+ searchFunction: {
3392
+ type: Function,
3393
+ default: void 0
3394
+ },
3395
+ /**
3396
+ * On searchable select is the input search placeholder
3397
+ */
3398
+ searchPlaceholder: {
3399
+ type: String,
3400
+ default: "Search..."
3401
+ },
3402
+ /**
3403
+ * The input search debounce time in ms
3404
+ */
3405
+ debounceSearch: {
3406
+ type: [Number, String],
3407
+ default: 0
3408
+ },
3409
+ /**
3410
+ * Manage modelValue as string[] or object[]
3411
+ */
3412
+ multiple: Boolean,
3413
+ /**
3414
+ * The min number of selected values
3415
+ */
3416
+ minValues: {
3417
+ type: [Number, String],
3418
+ default: 0
3419
+ },
3420
+ /**
3421
+ * The max number of selected values
3422
+ */
3423
+ maxValues: [Number, String],
3424
+ /**
3425
+ * If true the input will be unselectable
3426
+ * @deprecated use minValues instead
3427
+ */
3428
+ unselectable: { type: Boolean, default: true },
3429
+ /**
3430
+ * The select label separator visible to the user
3431
+ */
3432
+ separator: { type: String, default: ", " },
3433
+ /**
3434
+ * Show native select
3435
+ */
3436
+ native: Boolean,
3437
+ /**
3438
+ * Show badges
3439
+ */
3440
+ badges: Boolean,
3441
+ /**
3442
+ * Badge modifiers
3443
+ */
3444
+ badgeModifiers: {
3445
+ type: [String, Array],
3446
+ default: "action sm"
3447
+ },
3448
+ /**
3449
+ * Set dropdown width to the same as the trigger
3450
+ */
3451
+ triggerWidth: {
3452
+ ...DropdownProps.triggerWidth,
3453
+ default: true
3454
+ },
3455
+ /**
3456
+ * Dropdown modifiers
3457
+ */
3458
+ dropdownModifiers: {
3459
+ type: [String, Array],
3460
+ default: "mobile"
3461
+ },
3462
+ /**
3463
+ * Open dropdown on focus
3464
+ */
3465
+ autoOpen: {
3466
+ type: Boolean,
3467
+ default: false
3468
+ },
3469
+ /**
3470
+ * Select first option automatically
3471
+ */
3472
+ autoselectFirst: {
3473
+ type: Boolean,
3474
+ default: false
3475
+ },
3476
+ /**
3477
+ * Keep open dropdown on single select
3478
+ */
3479
+ keepOpen: {
3480
+ type: Boolean,
3481
+ default: false
3482
+ }
3483
+ };
3484
+ function useVvComboboxProps() {
3485
+ return {
3486
+ ...VvComboboxProps,
3487
+ options: {
3488
+ ...VvComboboxProps.options,
3489
+ type: Array
3490
+ },
3491
+ searchFunction: {
3492
+ ...VvComboboxProps.searchFunction,
3493
+ type: Function
3494
+ }
3495
+ };
3496
+ }
3322
3497
  const VvDropdownProps = {
3323
3498
  ...IdProps,
3324
3499
  ...DropdownProps,
@@ -4059,7 +4234,7 @@ const _hoisted_4$5 = { class: "vv-select__inner" };
4059
4234
  const _hoisted_5$4 = ["id"];
4060
4235
  const _hoisted_6$4 = ["disabled", "hidden"];
4061
4236
  const _hoisted_7$4 = ["disabled", "value"];
4062
- const _hoisted_8$3 = ["disabled", "label"];
4237
+ const _hoisted_8$4 = ["disabled", "label"];
4063
4238
  const _hoisted_9$2 = ["disabled", "value"];
4064
4239
  const _hoisted_10$1 = {
4065
4240
  key: 1,
@@ -4271,7 +4446,7 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
4271
4446
  128
4272
4447
  /* KEYED_FRAGMENT */
4273
4448
  ))
4274
- ], 8, _hoisted_8$3))
4449
+ ], 8, _hoisted_8$4))
4275
4450
  ],
4276
4451
  64
4277
4452
  /* STABLE_FRAGMENT */
@@ -4297,222 +4472,47 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
4297
4472
  ]),
4298
4473
  createVNode(unref(HintSlot), {
4299
4474
  id: unref(hasHintId),
4300
- class: "vv-select__hint"
4301
- }, createSlots({
4302
- _: 2
4303
- /* DYNAMIC */
4304
- }, [
4305
- _ctx.$slots.hint ? {
4306
- name: "hint",
4307
- fn: withCtx(() => [
4308
- renderSlot(_ctx.$slots, "hint", normalizeProps(guardReactiveProps(unref(hintSlotScope))))
4309
- ]),
4310
- key: "0"
4311
- } : void 0,
4312
- _ctx.$slots.loading ? {
4313
- name: "loading",
4314
- fn: withCtx(() => [
4315
- renderSlot(_ctx.$slots, "loading", normalizeProps(guardReactiveProps(unref(hintSlotScope))))
4316
- ]),
4317
- key: "1"
4318
- } : void 0,
4319
- _ctx.$slots.valid ? {
4320
- name: "valid",
4321
- fn: withCtx(() => [
4322
- renderSlot(_ctx.$slots, "valid", normalizeProps(guardReactiveProps(unref(hintSlotScope))))
4323
- ]),
4324
- key: "2"
4325
- } : void 0,
4326
- _ctx.$slots.invalid ? {
4327
- name: "invalid",
4328
- fn: withCtx(() => [
4329
- renderSlot(_ctx.$slots, "invalid", normalizeProps(guardReactiveProps(unref(hintSlotScope))))
4330
- ]),
4331
- key: "3"
4332
- } : void 0
4333
- ]), 1032, ["id"])
4334
- ],
4335
- 2
4336
- /* CLASS */
4337
- );
4338
- };
4339
- }
4340
- });
4341
- const VvComboboxProps = {
4342
- ...IdNameProps,
4343
- ...TabindexProps,
4344
- ...ValidProps,
4345
- ...InvalidProps,
4346
- ...HintProps,
4347
- ...LoadingProps,
4348
- ...DisabledProps,
4349
- ...ReadonlyProps,
4350
- ...ModifiersProps,
4351
- ...OptionsProps,
4352
- ...IconProps,
4353
- ...FloatingLabelProps,
4354
- ...DropdownProps,
4355
- ...LabelProps,
4356
- ...RequiredProps,
4357
- /**
4358
- * Dropdown show / hide transition name
4359
- */
4360
- transitionName: {
4361
- type: String,
4362
- default: "vv-dropdown--mobile-fade-block"
4363
- },
4364
- /**
4365
- * modelValue can be a string, number, boolean, object or array of string, number, boolean, object
4366
- */
4367
- modelValue: {
4368
- type: [String, Number, Boolean, Object, Array],
4369
- default: void 0
4370
- },
4371
- /**
4372
- * Label for no search results
4373
- */
4374
- noResultsLabel: { type: String, default: "No results" },
4375
- /**
4376
- * Label for no options available
4377
- */
4378
- noOptionsLabel: { type: String, default: "No options available" },
4379
- /**
4380
- * Label for selected option hint
4381
- */
4382
- selectedHintLabel: { type: String, default: "Selected" },
4383
- /**
4384
- * Label for deselect action button
4385
- */
4386
- deselectActionLabel: { type: String, default: "Deselect" },
4387
- /**
4388
- * Label for select option hint
4389
- */
4390
- selectHintLabel: { type: String, default: "Press enter to select" },
4391
- /**
4392
- * Label for deselected option hint
4393
- */
4394
- deselectHintLabel: { type: String, default: "Press enter to remove" },
4395
- /**
4396
- * Label close button
4397
- */
4398
- closeLabel: { type: String, default: "Close" },
4399
- /**
4400
- * Select input placeholder
4401
- */
4402
- placeholder: String,
4403
- /**
4404
- * Use input text to search on options
4405
- */
4406
- searchable: Boolean,
4407
- /**
4408
- * Search function to filter options
4409
- */
4410
- searchFunction: {
4411
- type: Function,
4412
- default: void 0
4413
- },
4414
- /**
4415
- * On searchable select is the input search placeholder
4416
- */
4417
- searchPlaceholder: {
4418
- type: String,
4419
- default: "Search..."
4420
- },
4421
- /**
4422
- * The input search debounce time in ms
4423
- */
4424
- debounceSearch: {
4425
- type: [Number, String],
4426
- default: 0
4427
- },
4428
- /**
4429
- * Manage modelValue as string[] or object[]
4430
- */
4431
- multiple: Boolean,
4432
- /**
4433
- * The min number of selected values
4434
- */
4435
- minValues: {
4436
- type: [Number, String],
4437
- default: 0
4438
- },
4439
- /**
4440
- * The max number of selected values
4441
- */
4442
- maxValues: [Number, String],
4443
- /**
4444
- * If true the input will be unselectable
4445
- * @deprecated use minValues instead
4446
- */
4447
- unselectable: { type: Boolean, default: true },
4448
- /**
4449
- * The select label separator visible to the user
4450
- */
4451
- separator: { type: String, default: ", " },
4452
- /**
4453
- * Show native select
4454
- */
4455
- native: Boolean,
4456
- /**
4457
- * Show badges
4458
- */
4459
- badges: Boolean,
4460
- /**
4461
- * Badge modifiers
4462
- */
4463
- badgeModifiers: {
4464
- type: [String, Array],
4465
- default: "action sm"
4466
- },
4467
- /**
4468
- * Set dropdown width to the same as the trigger
4469
- */
4470
- triggerWidth: {
4471
- ...DropdownProps.triggerWidth,
4472
- default: true
4473
- },
4474
- /**
4475
- * Dropdown modifiers
4476
- */
4477
- dropdownModifiers: {
4478
- type: [String, Array],
4479
- default: "mobile"
4480
- },
4481
- /**
4482
- * Open dropdown on focus
4483
- */
4484
- autoOpen: {
4485
- type: Boolean,
4486
- default: false
4487
- },
4488
- /**
4489
- * Select first option automatically
4490
- */
4491
- autoselectFirst: {
4492
- type: Boolean,
4493
- default: false
4494
- },
4495
- /**
4496
- * Keep open dropdown on single select
4497
- */
4498
- keepOpen: {
4499
- type: Boolean,
4500
- default: false
4475
+ class: "vv-select__hint"
4476
+ }, createSlots({
4477
+ _: 2
4478
+ /* DYNAMIC */
4479
+ }, [
4480
+ _ctx.$slots.hint ? {
4481
+ name: "hint",
4482
+ fn: withCtx(() => [
4483
+ renderSlot(_ctx.$slots, "hint", normalizeProps(guardReactiveProps(unref(hintSlotScope))))
4484
+ ]),
4485
+ key: "0"
4486
+ } : void 0,
4487
+ _ctx.$slots.loading ? {
4488
+ name: "loading",
4489
+ fn: withCtx(() => [
4490
+ renderSlot(_ctx.$slots, "loading", normalizeProps(guardReactiveProps(unref(hintSlotScope))))
4491
+ ]),
4492
+ key: "1"
4493
+ } : void 0,
4494
+ _ctx.$slots.valid ? {
4495
+ name: "valid",
4496
+ fn: withCtx(() => [
4497
+ renderSlot(_ctx.$slots, "valid", normalizeProps(guardReactiveProps(unref(hintSlotScope))))
4498
+ ]),
4499
+ key: "2"
4500
+ } : void 0,
4501
+ _ctx.$slots.invalid ? {
4502
+ name: "invalid",
4503
+ fn: withCtx(() => [
4504
+ renderSlot(_ctx.$slots, "invalid", normalizeProps(guardReactiveProps(unref(hintSlotScope))))
4505
+ ]),
4506
+ key: "3"
4507
+ } : void 0
4508
+ ]), 1032, ["id"])
4509
+ ],
4510
+ 2
4511
+ /* CLASS */
4512
+ );
4513
+ };
4501
4514
  }
4502
- };
4503
- function useVvComboboxProps() {
4504
- return {
4505
- ...VvComboboxProps,
4506
- options: {
4507
- ...VvComboboxProps.options,
4508
- type: Array
4509
- },
4510
- searchFunction: {
4511
- ...VvComboboxProps.searchFunction,
4512
- type: Function
4513
- }
4514
- };
4515
- }
4515
+ });
4516
4516
  const _hoisted_1$8 = ["id"];
4517
4517
  const _hoisted_2$6 = ["id", "for"];
4518
4518
  const _hoisted_3$4 = ["id", "aria-controls", "placeholder"];
@@ -4526,7 +4526,7 @@ const _hoisted_7$3 = {
4526
4526
  key: 0,
4527
4527
  class: "vv-select__value"
4528
4528
  };
4529
- const _hoisted_8$2 = ["aria-label", "onClick"];
4529
+ const _hoisted_8$3 = ["aria-label", "onClick"];
4530
4530
  const _hoisted_9$1 = {
4531
4531
  key: 1,
4532
4532
  class: "vv-select__input-after"
@@ -4948,7 +4948,7 @@ const _sfc_main$d = /* @__PURE__ */ defineComponent({
4948
4948
  onClick: withModifiers(($event) => onInput(option), ["stop"])
4949
4949
  }, [
4950
4950
  createVNode(_sfc_main$u, { name: "close" })
4951
- ], 8, _hoisted_8$2)) : createCommentVNode("v-if", true)
4951
+ ], 8, _hoisted_8$3)) : createCommentVNode("v-if", true)
4952
4952
  ]),
4953
4953
  _: 2
4954
4954
  /* DYNAMIC */
@@ -5588,7 +5588,7 @@ const _hoisted_4$2 = { class: "vv-input-file__wrapper" };
5588
5588
  const _hoisted_5$2 = ["id", "readonly", "disabled", "required", "placeholder", "aria-describedby", "aria-invalid", "aria-errormessage", "multiple", "accept", "capture", "name"];
5589
5589
  const _hoisted_6$2 = ["value"];
5590
5590
  const _hoisted_7$2 = ["onClick"];
5591
- const _hoisted_8$1 = ["title", "onClick"];
5591
+ const _hoisted_8$2 = ["title", "onClick"];
5592
5592
  const _hoisted_9 = { class: "vv-input-file__item-name" };
5593
5593
  const _hoisted_10 = { class: "vv-input-file__item-info" };
5594
5594
  const _hoisted_11 = ["title", "disabled", "onClick"];
@@ -5949,7 +5949,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
5949
5949
  16
5950
5950
  /* FULL_PROPS */
5951
5951
  )
5952
- ], 8, _hoisted_8$1)) : createCommentVNode("v-if", true),
5952
+ ], 8, _hoisted_8$2)) : createCommentVNode("v-if", true),
5953
5953
  createElementVNode(
5954
5954
  "div",
5955
5955
  _hoisted_9,
@@ -6533,7 +6533,7 @@ const _hoisted_6$1 = {
6533
6533
  class: "vv-input-text__limit"
6534
6534
  };
6535
6535
  const _hoisted_7$1 = { class: "flex-1" };
6536
- const _hoisted_8 = ["title", "onClick"];
6536
+ const _hoisted_8$1 = ["title", "onClick"];
6537
6537
  const __default__$8 = {
6538
6538
  name: "VvInputText"
6539
6539
  };
@@ -6713,34 +6713,32 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6713
6713
  const inputEl = el;
6714
6714
  const innerEl = ref();
6715
6715
  const wrapperEl = ref();
6716
- const dropdownEl = ref();
6716
+ const suggestionsDropdownEl = ref();
6717
6717
  __expose({ $inner: innerEl });
6718
6718
  const { focused } = useComponentFocus(inputEl, emit);
6719
6719
  const isFocused = computed(
6720
6720
  () => focused.value && !props.disabled && !props.readonly
6721
6721
  );
6722
6722
  watch(isFocused, (newValue) => {
6723
- var _a;
6723
+ var _a, _b;
6724
6724
  if (newValue && propsDefaults.value.selectOnFocus && inputEl.value) {
6725
6725
  inputEl.value.select();
6726
6726
  }
6727
- if (newValue) {
6728
- (_a = dropdownEl.value) == null ? void 0 : _a.show();
6727
+ if (newValue && ((_a = suggestions.value) == null ? void 0 : _a.size)) {
6728
+ (_b = suggestionsDropdownEl.value) == null ? void 0 : _b.show();
6729
6729
  return;
6730
6730
  }
6731
- setTimeout(() => {
6732
- if (isDirty.value && suggestions.value) {
6733
- const suggestionsLimit = props.maxSuggestions - 1;
6734
- if (suggestions.value.size > suggestionsLimit && !suggestions.value.has(localModelValue.value)) {
6735
- suggestions.value = new Set(
6736
- [...suggestions.value].slice(
6737
- suggestions.value.size - suggestionsLimit
6738
- )
6739
- );
6740
- }
6741
- suggestions.value.add(localModelValue.value);
6731
+ if (isDirty.value && suggestions.value) {
6732
+ const suggestionsLimit = props.maxSuggestions;
6733
+ if (suggestions.value.size >= suggestionsLimit && !suggestions.value.has(localModelValue.value)) {
6734
+ suggestions.value = new Set(
6735
+ [...suggestions.value].slice(
6736
+ suggestions.value.size - suggestionsLimit + 1
6737
+ )
6738
+ );
6742
6739
  }
6743
- }, 300);
6740
+ suggestions.value.add(localModelValue.value);
6741
+ }
6744
6742
  });
6745
6743
  const isVisible = useElementVisibility(inputEl);
6746
6744
  watch(isVisible, (newValue) => {
@@ -6838,7 +6836,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6838
6836
  function onSuggestionSelect(suggestion) {
6839
6837
  var _a;
6840
6838
  localModelValue.value = suggestion;
6841
- (_a = dropdownEl.value) == null ? void 0 : _a.hide();
6839
+ (_a = suggestionsDropdownEl.value) == null ? void 0 : _a.hide();
6842
6840
  }
6843
6841
  function onSuggestionRemove(suggestion) {
6844
6842
  var _a;
@@ -7100,8 +7098,8 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7100
7098
  ]), 1032, ["id"]),
7101
7099
  unref(hasSuggestions) ? (openBlock(), createBlock(_sfc_main$i, {
7102
7100
  key: 1,
7103
- ref_key: "dropdownEl",
7104
- ref: dropdownEl,
7101
+ ref_key: "suggestionsDropdownEl",
7102
+ ref: suggestionsDropdownEl,
7105
7103
  reference: unref(wrapperEl),
7106
7104
  "autofocus-first": false,
7107
7105
  "trigger-width": true
@@ -7140,7 +7138,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7140
7138
  16
7141
7139
  /* FULL_PROPS */
7142
7140
  )
7143
- ], 8, _hoisted_8)) : createCommentVNode("v-if", true)
7141
+ ], 8, _hoisted_8$1)) : createCommentVNode("v-if", true)
7144
7142
  ]),
7145
7143
  _: 2
7146
7144
  /* DYNAMIC */
@@ -7773,6 +7771,7 @@ const SPELLCHECK = {
7773
7771
  const VvTextareaEvents = ["update:modelValue", "focus", "blur", "keyup"];
7774
7772
  const VvTextareaProps = {
7775
7773
  ...InputTextareaProps,
7774
+ ...StorageProps,
7776
7775
  /**
7777
7776
  * Textarea value
7778
7777
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#value
@@ -7798,27 +7797,57 @@ const VvTextareaProps = {
7798
7797
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#wrap
7799
7798
  */
7800
7799
  spellcheck: { type: [Boolean, String], default: SPELLCHECK.default },
7800
+ /**
7801
+ * VvIcon name for remove suggestion button
7802
+ * @see VVIcon
7803
+ */
7804
+ iconRemoveSuggestion: {
7805
+ type: [String, Object],
7806
+ default: ACTION_ICONS.remove
7807
+ },
7808
+ /**
7809
+ * Label for remove suggestion button
7810
+ */
7811
+ labelRemoveSuggestion: {
7812
+ type: String,
7813
+ default: "Remove suggestion"
7814
+ },
7815
+ /**
7816
+ * Maximum number of suggestions
7817
+ */
7818
+ maxSuggestions: {
7819
+ type: Number,
7820
+ default: 5
7821
+ },
7822
+ /**
7823
+ * Select input text on focus
7824
+ */
7825
+ selectOnFocus: {
7826
+ type: Boolean,
7827
+ default: false
7828
+ },
7801
7829
  /**
7802
7830
  * If true, the textarea will be resizable
7803
7831
  */
7804
7832
  resizable: Boolean
7805
7833
  };
7806
7834
  const _hoisted_1 = ["for"];
7807
- const _hoisted_2 = { class: "vv-textarea__wrapper" };
7808
- const _hoisted_3 = {
7835
+ const _hoisted_2 = {
7809
7836
  key: 0,
7810
7837
  class: "vv-textarea__input-before"
7811
7838
  };
7812
- const _hoisted_4 = { class: "vv-textarea__inner" };
7813
- const _hoisted_5 = ["id"];
7814
- const _hoisted_6 = {
7839
+ const _hoisted_3 = { class: "vv-textarea__inner" };
7840
+ const _hoisted_4 = ["id"];
7841
+ const _hoisted_5 = {
7815
7842
  key: 1,
7816
7843
  class: "vv-textarea__input-after"
7817
7844
  };
7818
- const _hoisted_7 = {
7845
+ const _hoisted_6 = {
7819
7846
  key: 2,
7820
7847
  class: "vv-textarea__limit"
7821
7848
  };
7849
+ const _hoisted_7 = { class: "flex-1" };
7850
+ const _hoisted_8 = ["title", "onClick"];
7822
7851
  const __default__$1 = {
7823
7852
  name: "VvTextarea"
7824
7853
  };
@@ -7835,11 +7864,15 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7835
7864
  VvTextareaProps,
7836
7865
  props
7837
7866
  );
7838
- const textarea = ref();
7867
+ const textareaEl = ref();
7868
+ const wrapperEl = ref();
7869
+ const suggestionsDropdownEl = ref();
7839
7870
  const {
7840
7871
  id,
7841
7872
  icon,
7842
7873
  iconPosition,
7874
+ iconRemoveSuggestion,
7875
+ labelRemoveSuggestion,
7843
7876
  label,
7844
7877
  modelValue,
7845
7878
  count,
@@ -7849,7 +7882,9 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7849
7882
  modifiers,
7850
7883
  debounce,
7851
7884
  minlength,
7852
- maxlength
7885
+ maxlength,
7886
+ storageKey,
7887
+ storageType
7853
7888
  } = toRefs(props);
7854
7889
  const hasId = useUniqueId(id);
7855
7890
  const hasHintId = computed(() => `${hasId.value}-hint`);
@@ -7858,8 +7893,33 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7858
7893
  );
7859
7894
  const localModelValue = useDebouncedInput(modelValue, emit, debounce == null ? void 0 : debounce.value);
7860
7895
  const { hasIconBefore, hasIconAfter } = useComponentIcon(icon, iconPosition);
7861
- const { focused } = useComponentFocus(textarea, emit);
7862
- const isVisible = useElementVisibility(textarea);
7896
+ const { hasIcon: hasIconRemoveSuggestion } = useComponentIcon(iconRemoveSuggestion);
7897
+ const { focused } = useComponentFocus(textareaEl, emit);
7898
+ const isFocused = computed(
7899
+ () => focused.value && !props.disabled && !props.readonly
7900
+ );
7901
+ watch(isFocused, (newValue) => {
7902
+ var _a, _b;
7903
+ if (newValue && propsDefaults.value.selectOnFocus && textareaEl.value) {
7904
+ textareaEl.value.select();
7905
+ }
7906
+ if (newValue && ((_a = suggestions.value) == null ? void 0 : _a.size)) {
7907
+ (_b = suggestionsDropdownEl.value) == null ? void 0 : _b.show();
7908
+ return;
7909
+ }
7910
+ if (isDirty.value && suggestions.value) {
7911
+ const suggestionsLimit = props.maxSuggestions;
7912
+ if (suggestions.value.size >= suggestionsLimit && !suggestions.value.has(localModelValue.value)) {
7913
+ suggestions.value = new Set(
7914
+ [...suggestions.value].slice(
7915
+ suggestions.value.size - suggestionsLimit + 1
7916
+ )
7917
+ );
7918
+ }
7919
+ suggestions.value.add(localModelValue.value);
7920
+ }
7921
+ });
7922
+ const isVisible = useElementVisibility(textareaEl);
7863
7923
  watch(isVisible, (newValue) => {
7864
7924
  if (newValue && props.autofocus) {
7865
7925
  focused.value = true;
@@ -7884,6 +7944,31 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7884
7944
  }
7885
7945
  return void 0;
7886
7946
  });
7947
+ const suggestions = usePersistence(
7948
+ storageKey,
7949
+ storageType,
7950
+ /* @__PURE__ */ new Set()
7951
+ );
7952
+ const filteredSuggestions = computed(() => {
7953
+ if (!suggestions.value) {
7954
+ return [];
7955
+ }
7956
+ return [...suggestions.value].filter(
7957
+ (suggestion) => isEmpty(localModelValue.value) || `${suggestion}`.toLowerCase().includes(`${localModelValue.value}`.toLowerCase()) && suggestion !== localModelValue.value
7958
+ ).reverse();
7959
+ });
7960
+ const hasSuggestions = computed(
7961
+ () => (storageKey == null ? void 0 : storageKey.value) && suggestions.value && suggestions.value.size > 0
7962
+ );
7963
+ function onSuggestionSelect(suggestion) {
7964
+ var _a;
7965
+ localModelValue.value = suggestion;
7966
+ (_a = suggestionsDropdownEl.value) == null ? void 0 : _a.hide();
7967
+ }
7968
+ function onSuggestionRemove(suggestion) {
7969
+ var _a;
7970
+ (_a = suggestions.value) == null ? void 0 : _a.delete(suggestion);
7971
+ }
7887
7972
  const {
7888
7973
  HintSlot,
7889
7974
  hasHintLabelOrSlot,
@@ -7952,49 +8037,59 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7952
8037
  for: unref(hasId),
7953
8038
  class: "vv-textarea__label"
7954
8039
  }, toDisplayString(unref(label)), 9, _hoisted_1)) : createCommentVNode("v-if", true),
7955
- createElementVNode("div", _hoisted_2, [
7956
- _ctx.$slots.before ? (openBlock(), createElementBlock("div", _hoisted_3, [
7957
- renderSlot(_ctx.$slots, "before", normalizeProps(guardReactiveProps(unref(slotProps))))
7958
- ])) : createCommentVNode("v-if", true),
7959
- createElementVNode("div", _hoisted_4, [
7960
- unref(hasIconBefore) ? (openBlock(), createBlock(
7961
- _sfc_main$u,
7962
- mergeProps({ key: 0 }, unref(hasIconBefore), { class: "vv-textarea__icon" }),
7963
- null,
7964
- 16
7965
- /* FULL_PROPS */
7966
- )) : createCommentVNode("v-if", true),
7967
- withDirectives(createElementVNode("textarea", mergeProps({
7968
- id: unref(hasId),
7969
- ref_key: "textarea",
7970
- ref: textarea,
7971
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(localModelValue) ? localModelValue.value = $event : null)
7972
- }, unref(hasAttrs), {
7973
- onKeyup: _cache[1] || (_cache[1] = ($event) => emit("keyup", $event))
7974
- }), null, 16, _hoisted_5), [
7975
- [vModelText, unref(localModelValue)]
8040
+ createElementVNode(
8041
+ "div",
8042
+ {
8043
+ ref_key: "wrapperEl",
8044
+ ref: wrapperEl,
8045
+ class: "vv-textarea__wrapper"
8046
+ },
8047
+ [
8048
+ _ctx.$slots.before ? (openBlock(), createElementBlock("div", _hoisted_2, [
8049
+ renderSlot(_ctx.$slots, "before", normalizeProps(guardReactiveProps(unref(slotProps))))
8050
+ ])) : createCommentVNode("v-if", true),
8051
+ createElementVNode("div", _hoisted_3, [
8052
+ unref(hasIconBefore) ? (openBlock(), createBlock(
8053
+ _sfc_main$u,
8054
+ mergeProps({ key: 0 }, unref(hasIconBefore), { class: "vv-textarea__icon" }),
8055
+ null,
8056
+ 16
8057
+ /* FULL_PROPS */
8058
+ )) : createCommentVNode("v-if", true),
8059
+ withDirectives(createElementVNode("textarea", mergeProps({
8060
+ id: unref(hasId),
8061
+ ref_key: "textareaEl",
8062
+ ref: textareaEl,
8063
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(localModelValue) ? localModelValue.value = $event : null)
8064
+ }, unref(hasAttrs), {
8065
+ onKeyup: _cache[1] || (_cache[1] = ($event) => emit("keyup", $event))
8066
+ }), null, 16, _hoisted_4), [
8067
+ [vModelText, unref(localModelValue)]
8068
+ ]),
8069
+ unref(hasIconAfter) ? (openBlock(), createBlock(
8070
+ _sfc_main$u,
8071
+ mergeProps({ key: 1 }, unref(hasIconAfter), { class: "vv-textarea__icon vv-textarea__icon-after" }),
8072
+ null,
8073
+ 16
8074
+ /* FULL_PROPS */
8075
+ )) : createCommentVNode("v-if", true)
7976
8076
  ]),
7977
- unref(hasIconAfter) ? (openBlock(), createBlock(
7978
- _sfc_main$u,
7979
- mergeProps({ key: 1 }, unref(hasIconAfter), { class: "vv-textarea__icon vv-textarea__icon-after" }),
7980
- null,
7981
- 16
7982
- /* FULL_PROPS */
7983
- )) : createCommentVNode("v-if", true)
7984
- ]),
7985
- _ctx.$slots.after ? (openBlock(), createElementBlock("div", _hoisted_6, [
7986
- renderSlot(_ctx.$slots, "after", normalizeProps(guardReactiveProps(unref(slotProps))))
7987
- ])) : createCommentVNode("v-if", true),
7988
- unref(count) ? (openBlock(), createElementBlock("span", _hoisted_7, [
7989
- renderSlot(_ctx.$slots, "count", normalizeProps(guardReactiveProps(unref(slotProps))), () => [
7990
- createTextVNode(
7991
- toDisplayString(unref(countFormatted)),
7992
- 1
7993
- /* TEXT */
7994
- )
7995
- ])
7996
- ])) : createCommentVNode("v-if", true)
7997
- ]),
8077
+ _ctx.$slots.after ? (openBlock(), createElementBlock("div", _hoisted_5, [
8078
+ renderSlot(_ctx.$slots, "after", normalizeProps(guardReactiveProps(unref(slotProps))))
8079
+ ])) : createCommentVNode("v-if", true),
8080
+ unref(count) ? (openBlock(), createElementBlock("span", _hoisted_6, [
8081
+ renderSlot(_ctx.$slots, "count", normalizeProps(guardReactiveProps(unref(slotProps))), () => [
8082
+ createTextVNode(
8083
+ toDisplayString(unref(countFormatted)),
8084
+ 1
8085
+ /* TEXT */
8086
+ )
8087
+ ])
8088
+ ])) : createCommentVNode("v-if", true)
8089
+ ],
8090
+ 512
8091
+ /* NEED_PATCH */
8092
+ ),
7998
8093
  createVNode(unref(HintSlot), {
7999
8094
  id: unref(hasHintId),
8000
8095
  class: "vv-textarea__hint"
@@ -8030,7 +8125,62 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
8030
8125
  ]),
8031
8126
  key: "3"
8032
8127
  } : void 0
8033
- ]), 1032, ["id"])
8128
+ ]), 1032, ["id"]),
8129
+ unref(hasSuggestions) ? (openBlock(), createBlock(_sfc_main$i, {
8130
+ key: 1,
8131
+ ref_key: "suggestionsDropdownEl",
8132
+ ref: suggestionsDropdownEl,
8133
+ reference: unref(wrapperEl),
8134
+ "autofocus-first": false,
8135
+ "trigger-width": true
8136
+ }, {
8137
+ items: withCtx(() => [
8138
+ (openBlock(true), createElementBlock(
8139
+ Fragment,
8140
+ null,
8141
+ renderList(unref(filteredSuggestions), (value) => {
8142
+ return openBlock(), createBlock(_sfc_main$f, {
8143
+ key: value,
8144
+ onClick: withModifiers(($event) => onSuggestionSelect(value), ["stop"])
8145
+ }, {
8146
+ default: withCtx(() => [
8147
+ createElementVNode("div", _hoisted_7, [
8148
+ renderSlot(_ctx.$slots, "suggestion", mergeProps({ ref_for: true }, { value }), () => [
8149
+ createTextVNode(
8150
+ toDisplayString(value),
8151
+ 1
8152
+ /* TEXT */
8153
+ )
8154
+ ])
8155
+ ]),
8156
+ unref(suggestions) && unref(hasIconRemoveSuggestion) ? (openBlock(), createElementBlock("button", {
8157
+ key: 0,
8158
+ type: "button",
8159
+ tabindex: "-1",
8160
+ class: "cursor-pointer",
8161
+ title: unref(labelRemoveSuggestion),
8162
+ onClick: withModifiers(($event) => onSuggestionRemove(value), ["stop"])
8163
+ }, [
8164
+ createVNode(
8165
+ _sfc_main$u,
8166
+ mergeProps({ ref_for: true }, unref(hasIconRemoveSuggestion)),
8167
+ null,
8168
+ 16
8169
+ /* FULL_PROPS */
8170
+ )
8171
+ ], 8, _hoisted_8)) : createCommentVNode("v-if", true)
8172
+ ]),
8173
+ _: 2
8174
+ /* DYNAMIC */
8175
+ }, 1032, ["onClick"]);
8176
+ }),
8177
+ 128
8178
+ /* KEYED_FRAGMENT */
8179
+ ))
8180
+ ]),
8181
+ _: 3
8182
+ /* FORWARDED */
8183
+ }, 8, ["reference"])) : createCommentVNode("v-if", true)
8034
8184
  ],
8035
8185
  2
8036
8186
  /* CLASS */