@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
@@ -538,6 +538,7 @@ const CheckboxRadioGroupProps = {
538
538
  ...ModifiersProps,
539
539
  ...LabelProps,
540
540
  ...LoadingProps,
541
+ ...RequiredProps,
541
542
  /**
542
543
  * Input value
543
544
  */
@@ -3225,6 +3226,7 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
3225
3226
  computed(() => ({
3226
3227
  disabled: disabled.value,
3227
3228
  readonly: readonly.value,
3229
+ required: props.required,
3228
3230
  horizontal: !vertical.value,
3229
3231
  valid: valid.value,
3230
3232
  invalid: invalid.value
@@ -3235,7 +3237,8 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
3235
3237
  id: `${props.name}_opt${index}`,
3236
3238
  name: props.name,
3237
3239
  label: getOptionLabel(option),
3238
- value: getOptionValue(option)
3240
+ value: getOptionValue(option),
3241
+ required: props.required
3239
3242
  };
3240
3243
  }
3241
3244
  const { HintSlot, hintSlotScope } = HintSlotFactory(propsDefaults, slots);
@@ -3316,6 +3319,181 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
3316
3319
  };
3317
3320
  }
3318
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
+ }
3319
3497
  const VvDropdownProps = {
3320
3498
  ...IdProps,
3321
3499
  ...DropdownProps,
@@ -4056,7 +4234,7 @@ const _hoisted_4$5 = { class: "vv-select__inner" };
4056
4234
  const _hoisted_5$4 = ["id"];
4057
4235
  const _hoisted_6$4 = ["disabled", "hidden"];
4058
4236
  const _hoisted_7$4 = ["disabled", "value"];
4059
- const _hoisted_8$3 = ["disabled", "label"];
4237
+ const _hoisted_8$4 = ["disabled", "label"];
4060
4238
  const _hoisted_9$2 = ["disabled", "value"];
4061
4239
  const _hoisted_10$1 = {
4062
4240
  key: 1,
@@ -4268,7 +4446,7 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
4268
4446
  128
4269
4447
  /* KEYED_FRAGMENT */
4270
4448
  ))
4271
- ], 8, _hoisted_8$3))
4449
+ ], 8, _hoisted_8$4))
4272
4450
  ],
4273
4451
  64
4274
4452
  /* STABLE_FRAGMENT */
@@ -4335,181 +4513,6 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
4335
4513
  };
4336
4514
  }
4337
4515
  });
4338
- const VvComboboxProps = {
4339
- ...IdNameProps,
4340
- ...TabindexProps,
4341
- ...ValidProps,
4342
- ...InvalidProps,
4343
- ...HintProps,
4344
- ...LoadingProps,
4345
- ...DisabledProps,
4346
- ...ReadonlyProps,
4347
- ...ModifiersProps,
4348
- ...OptionsProps,
4349
- ...IconProps,
4350
- ...FloatingLabelProps,
4351
- ...DropdownProps,
4352
- ...LabelProps,
4353
- ...RequiredProps,
4354
- /**
4355
- * Dropdown show / hide transition name
4356
- */
4357
- transitionName: {
4358
- type: String,
4359
- default: "vv-dropdown--mobile-fade-block"
4360
- },
4361
- /**
4362
- * modelValue can be a string, number, boolean, object or array of string, number, boolean, object
4363
- */
4364
- modelValue: {
4365
- type: [String, Number, Boolean, Object, Array],
4366
- default: void 0
4367
- },
4368
- /**
4369
- * Label for no search results
4370
- */
4371
- noResultsLabel: { type: String, default: "No results" },
4372
- /**
4373
- * Label for no options available
4374
- */
4375
- noOptionsLabel: { type: String, default: "No options available" },
4376
- /**
4377
- * Label for selected option hint
4378
- */
4379
- selectedHintLabel: { type: String, default: "Selected" },
4380
- /**
4381
- * Label for deselect action button
4382
- */
4383
- deselectActionLabel: { type: String, default: "Deselect" },
4384
- /**
4385
- * Label for select option hint
4386
- */
4387
- selectHintLabel: { type: String, default: "Press enter to select" },
4388
- /**
4389
- * Label for deselected option hint
4390
- */
4391
- deselectHintLabel: { type: String, default: "Press enter to remove" },
4392
- /**
4393
- * Label close button
4394
- */
4395
- closeLabel: { type: String, default: "Close" },
4396
- /**
4397
- * Select input placeholder
4398
- */
4399
- placeholder: String,
4400
- /**
4401
- * Use input text to search on options
4402
- */
4403
- searchable: Boolean,
4404
- /**
4405
- * Search function to filter options
4406
- */
4407
- searchFunction: {
4408
- type: Function,
4409
- default: void 0
4410
- },
4411
- /**
4412
- * On searchable select is the input search placeholder
4413
- */
4414
- searchPlaceholder: {
4415
- type: String,
4416
- default: "Search..."
4417
- },
4418
- /**
4419
- * The input search debounce time in ms
4420
- */
4421
- debounceSearch: {
4422
- type: [Number, String],
4423
- default: 0
4424
- },
4425
- /**
4426
- * Manage modelValue as string[] or object[]
4427
- */
4428
- multiple: Boolean,
4429
- /**
4430
- * The min number of selected values
4431
- */
4432
- minValues: {
4433
- type: [Number, String],
4434
- default: 0
4435
- },
4436
- /**
4437
- * The max number of selected values
4438
- */
4439
- maxValues: [Number, String],
4440
- /**
4441
- * If true the input will be unselectable
4442
- * @deprecated use minValues instead
4443
- */
4444
- unselectable: { type: Boolean, default: true },
4445
- /**
4446
- * The select label separator visible to the user
4447
- */
4448
- separator: { type: String, default: ", " },
4449
- /**
4450
- * Show native select
4451
- */
4452
- native: Boolean,
4453
- /**
4454
- * Show badges
4455
- */
4456
- badges: Boolean,
4457
- /**
4458
- * Badge modifiers
4459
- */
4460
- badgeModifiers: {
4461
- type: [String, Array],
4462
- default: "action sm"
4463
- },
4464
- /**
4465
- * Set dropdown width to the same as the trigger
4466
- */
4467
- triggerWidth: {
4468
- ...DropdownProps.triggerWidth,
4469
- default: true
4470
- },
4471
- /**
4472
- * Dropdown modifiers
4473
- */
4474
- dropdownModifiers: {
4475
- type: [String, Array],
4476
- default: "mobile"
4477
- },
4478
- /**
4479
- * Open dropdown on focus
4480
- */
4481
- autoOpen: {
4482
- type: Boolean,
4483
- default: false
4484
- },
4485
- /**
4486
- * Select first option automatically
4487
- */
4488
- autoselectFirst: {
4489
- type: Boolean,
4490
- default: false
4491
- },
4492
- /**
4493
- * Keep open dropdown on single select
4494
- */
4495
- keepOpen: {
4496
- type: Boolean,
4497
- default: false
4498
- }
4499
- };
4500
- function useVvComboboxProps() {
4501
- return {
4502
- ...VvComboboxProps,
4503
- options: {
4504
- ...VvComboboxProps.options,
4505
- type: Array
4506
- },
4507
- searchFunction: {
4508
- ...VvComboboxProps.searchFunction,
4509
- type: Function
4510
- }
4511
- };
4512
- }
4513
4516
  const _hoisted_1$8 = ["id"];
4514
4517
  const _hoisted_2$6 = ["id", "for"];
4515
4518
  const _hoisted_3$4 = ["id", "aria-controls", "placeholder"];
@@ -4523,7 +4526,7 @@ const _hoisted_7$3 = {
4523
4526
  key: 0,
4524
4527
  class: "vv-select__value"
4525
4528
  };
4526
- const _hoisted_8$2 = ["aria-label", "onClick"];
4529
+ const _hoisted_8$3 = ["aria-label", "onClick"];
4527
4530
  const _hoisted_9$1 = {
4528
4531
  key: 1,
4529
4532
  class: "vv-select__input-after"
@@ -4945,7 +4948,7 @@ const _sfc_main$d = /* @__PURE__ */ defineComponent({
4945
4948
  onClick: withModifiers(($event) => onInput(option), ["stop"])
4946
4949
  }, [
4947
4950
  createVNode(_sfc_main$u, { name: "close" })
4948
- ], 8, _hoisted_8$2)) : createCommentVNode("v-if", true)
4951
+ ], 8, _hoisted_8$3)) : createCommentVNode("v-if", true)
4949
4952
  ]),
4950
4953
  _: 2
4951
4954
  /* DYNAMIC */
@@ -5471,6 +5474,7 @@ const VvInputFileProps = {
5471
5474
  ...LoadingProps,
5472
5475
  ...ReadonlyProps,
5473
5476
  ...DisabledProps,
5477
+ ...RequiredProps,
5474
5478
  ...IconProps,
5475
5479
  /**
5476
5480
  * Input value
@@ -5581,10 +5585,10 @@ const _hoisted_1$6 = ["for"];
5581
5585
  const _hoisted_2$4 = { class: "vv-input-file__preview" };
5582
5586
  const _hoisted_3$2 = ["src", "alt"];
5583
5587
  const _hoisted_4$2 = { class: "vv-input-file__wrapper" };
5584
- const _hoisted_5$2 = ["id", "readonly", "disabled", "placeholder", "aria-describedby", "aria-invalid", "aria-errormessage", "multiple", "accept", "capture", "name"];
5588
+ const _hoisted_5$2 = ["id", "readonly", "disabled", "required", "placeholder", "aria-describedby", "aria-invalid", "aria-errormessage", "multiple", "accept", "capture", "name"];
5585
5589
  const _hoisted_6$2 = ["value"];
5586
5590
  const _hoisted_7$2 = ["onClick"];
5587
- const _hoisted_8$1 = ["title", "onClick"];
5591
+ const _hoisted_8$2 = ["title", "onClick"];
5588
5592
  const _hoisted_9 = { class: "vv-input-file__item-name" };
5589
5593
  const _hoisted_10 = { class: "vv-input-file__item-info" };
5590
5594
  const _hoisted_11 = ["title", "disabled", "onClick"];
@@ -5620,10 +5624,13 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
5620
5624
  "vv-input-file",
5621
5625
  modifiers,
5622
5626
  computed(() => ({
5623
- "dragging": isDragging.value,
5624
- "loading": props.loading && !hasProgress.value,
5625
5627
  "valid": props.valid === true,
5626
5628
  "invalid": props.invalid === true,
5629
+ "loading": props.loading && !hasProgress.value,
5630
+ "disabled": props.disabled,
5631
+ "required": props.required,
5632
+ "readonly": props.readonly,
5633
+ "dragging": isDragging.value,
5627
5634
  "icon-before": !!hasIconBefore.value,
5628
5635
  "icon-after": !!hasIconAfter.value,
5629
5636
  "drop-area": hasDropArea.value
@@ -5886,6 +5893,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
5886
5893
  type: "file",
5887
5894
  readonly: unref(readonly),
5888
5895
  disabled: unref(disabled),
5896
+ required: _ctx.required,
5889
5897
  placeholder: _ctx.placeholder,
5890
5898
  "aria-describedby": unref(hasHintLabelOrSlot) ? hasHintId.value : void 0,
5891
5899
  "aria-invalid": _ctx.invalid,
@@ -5941,7 +5949,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
5941
5949
  16
5942
5950
  /* FULL_PROPS */
5943
5951
  )
5944
- ], 8, _hoisted_8$1)) : createCommentVNode("v-if", true),
5952
+ ], 8, _hoisted_8$2)) : createCommentVNode("v-if", true),
5945
5953
  createElementVNode(
5946
5954
  "div",
5947
5955
  _hoisted_9,
@@ -6525,7 +6533,7 @@ const _hoisted_6$1 = {
6525
6533
  class: "vv-input-text__limit"
6526
6534
  };
6527
6535
  const _hoisted_7$1 = { class: "flex-1" };
6528
- const _hoisted_8 = ["title", "onClick"];
6536
+ const _hoisted_8$1 = ["title", "onClick"];
6529
6537
  const __default__$8 = {
6530
6538
  name: "VvInputText"
6531
6539
  };
@@ -6667,7 +6675,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6667
6675
  );
6668
6676
  function updateMaskValue(newValue) {
6669
6677
  var _a;
6670
- if (newValue === void 0) {
6678
+ if (newValue === void 0 || newValue === null) {
6671
6679
  typed.value = "";
6672
6680
  unmasked.value = "";
6673
6681
  return;
@@ -6705,34 +6713,32 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6705
6713
  const inputEl = el;
6706
6714
  const innerEl = ref();
6707
6715
  const wrapperEl = ref();
6708
- const dropdownEl = ref();
6716
+ const suggestionsDropdownEl = ref();
6709
6717
  __expose({ $inner: innerEl });
6710
6718
  const { focused } = useComponentFocus(inputEl, emit);
6711
6719
  const isFocused = computed(
6712
6720
  () => focused.value && !props.disabled && !props.readonly
6713
6721
  );
6714
6722
  watch(isFocused, (newValue) => {
6715
- var _a;
6723
+ var _a, _b;
6716
6724
  if (newValue && propsDefaults.value.selectOnFocus && inputEl.value) {
6717
6725
  inputEl.value.select();
6718
6726
  }
6719
- if (newValue) {
6720
- (_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();
6721
6729
  return;
6722
6730
  }
6723
- setTimeout(() => {
6724
- if (isDirty.value && suggestions.value) {
6725
- const suggestionsLimit = props.maxSuggestions - 1;
6726
- if (suggestions.value.size > suggestionsLimit && !suggestions.value.has(localModelValue.value)) {
6727
- suggestions.value = new Set(
6728
- [...suggestions.value].slice(
6729
- suggestions.value.size - suggestionsLimit
6730
- )
6731
- );
6732
- }
6733
- 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
+ );
6734
6739
  }
6735
- }, 300);
6740
+ suggestions.value.add(localModelValue.value);
6741
+ }
6736
6742
  });
6737
6743
  const isVisible = useElementVisibility(inputEl);
6738
6744
  watch(isVisible, (newValue) => {
@@ -6830,7 +6836,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6830
6836
  function onSuggestionSelect(suggestion) {
6831
6837
  var _a;
6832
6838
  localModelValue.value = suggestion;
6833
- (_a = dropdownEl.value) == null ? void 0 : _a.hide();
6839
+ (_a = suggestionsDropdownEl.value) == null ? void 0 : _a.hide();
6834
6840
  }
6835
6841
  function onSuggestionRemove(suggestion) {
6836
6842
  var _a;
@@ -7092,8 +7098,8 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7092
7098
  ]), 1032, ["id"]),
7093
7099
  unref(hasSuggestions) ? (openBlock(), createBlock(_sfc_main$i, {
7094
7100
  key: 1,
7095
- ref_key: "dropdownEl",
7096
- ref: dropdownEl,
7101
+ ref_key: "suggestionsDropdownEl",
7102
+ ref: suggestionsDropdownEl,
7097
7103
  reference: unref(wrapperEl),
7098
7104
  "autofocus-first": false,
7099
7105
  "trigger-width": true
@@ -7132,7 +7138,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7132
7138
  16
7133
7139
  /* FULL_PROPS */
7134
7140
  )
7135
- ], 8, _hoisted_8)) : createCommentVNode("v-if", true)
7141
+ ], 8, _hoisted_8$1)) : createCommentVNode("v-if", true)
7136
7142
  ]),
7137
7143
  _: 2
7138
7144
  /* DYNAMIC */
@@ -7538,6 +7544,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
7538
7544
  computed(() => ({
7539
7545
  disabled: disabled.value,
7540
7546
  readonly: readonly.value,
7547
+ required: props.required,
7541
7548
  horizontal: !vertical.value,
7542
7549
  valid: valid.value,
7543
7550
  invalid: invalid.value
@@ -7548,7 +7555,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
7548
7555
  id: `${props.name}_opt${index}`,
7549
7556
  name: props.name,
7550
7557
  label: getOptionLabel(option),
7551
- value: getOptionValue(option)
7558
+ value: getOptionValue(option),
7559
+ required: props.required
7552
7560
  };
7553
7561
  }
7554
7562
  const { HintSlot, hintSlotScope } = HintSlotFactory(propsDefaults, slots);
@@ -7763,6 +7771,7 @@ const SPELLCHECK = {
7763
7771
  const VvTextareaEvents = ["update:modelValue", "focus", "blur", "keyup"];
7764
7772
  const VvTextareaProps = {
7765
7773
  ...InputTextareaProps,
7774
+ ...StorageProps,
7766
7775
  /**
7767
7776
  * Textarea value
7768
7777
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#value
@@ -7788,27 +7797,57 @@ const VvTextareaProps = {
7788
7797
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#wrap
7789
7798
  */
7790
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
+ },
7791
7829
  /**
7792
7830
  * If true, the textarea will be resizable
7793
7831
  */
7794
7832
  resizable: Boolean
7795
7833
  };
7796
7834
  const _hoisted_1 = ["for"];
7797
- const _hoisted_2 = { class: "vv-textarea__wrapper" };
7798
- const _hoisted_3 = {
7835
+ const _hoisted_2 = {
7799
7836
  key: 0,
7800
7837
  class: "vv-textarea__input-before"
7801
7838
  };
7802
- const _hoisted_4 = { class: "vv-textarea__inner" };
7803
- const _hoisted_5 = ["id"];
7804
- const _hoisted_6 = {
7839
+ const _hoisted_3 = { class: "vv-textarea__inner" };
7840
+ const _hoisted_4 = ["id"];
7841
+ const _hoisted_5 = {
7805
7842
  key: 1,
7806
7843
  class: "vv-textarea__input-after"
7807
7844
  };
7808
- const _hoisted_7 = {
7845
+ const _hoisted_6 = {
7809
7846
  key: 2,
7810
7847
  class: "vv-textarea__limit"
7811
7848
  };
7849
+ const _hoisted_7 = { class: "flex-1" };
7850
+ const _hoisted_8 = ["title", "onClick"];
7812
7851
  const __default__$1 = {
7813
7852
  name: "VvTextarea"
7814
7853
  };
@@ -7825,11 +7864,15 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7825
7864
  VvTextareaProps,
7826
7865
  props
7827
7866
  );
7828
- const textarea = ref();
7867
+ const textareaEl = ref();
7868
+ const wrapperEl = ref();
7869
+ const suggestionsDropdownEl = ref();
7829
7870
  const {
7830
7871
  id,
7831
7872
  icon,
7832
7873
  iconPosition,
7874
+ iconRemoveSuggestion,
7875
+ labelRemoveSuggestion,
7833
7876
  label,
7834
7877
  modelValue,
7835
7878
  count,
@@ -7839,7 +7882,9 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7839
7882
  modifiers,
7840
7883
  debounce,
7841
7884
  minlength,
7842
- maxlength
7885
+ maxlength,
7886
+ storageKey,
7887
+ storageType
7843
7888
  } = toRefs(props);
7844
7889
  const hasId = useUniqueId(id);
7845
7890
  const hasHintId = computed(() => `${hasId.value}-hint`);
@@ -7848,8 +7893,33 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7848
7893
  );
7849
7894
  const localModelValue = useDebouncedInput(modelValue, emit, debounce == null ? void 0 : debounce.value);
7850
7895
  const { hasIconBefore, hasIconAfter } = useComponentIcon(icon, iconPosition);
7851
- const { focused } = useComponentFocus(textarea, emit);
7852
- 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);
7853
7923
  watch(isVisible, (newValue) => {
7854
7924
  if (newValue && props.autofocus) {
7855
7925
  focused.value = true;
@@ -7874,6 +7944,31 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7874
7944
  }
7875
7945
  return void 0;
7876
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
+ }
7877
7972
  const {
7878
7973
  HintSlot,
7879
7974
  hasHintLabelOrSlot,
@@ -7942,49 +8037,59 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7942
8037
  for: unref(hasId),
7943
8038
  class: "vv-textarea__label"
7944
8039
  }, toDisplayString(unref(label)), 9, _hoisted_1)) : createCommentVNode("v-if", true),
7945
- createElementVNode("div", _hoisted_2, [
7946
- _ctx.$slots.before ? (openBlock(), createElementBlock("div", _hoisted_3, [
7947
- renderSlot(_ctx.$slots, "before", normalizeProps(guardReactiveProps(unref(slotProps))))
7948
- ])) : createCommentVNode("v-if", true),
7949
- createElementVNode("div", _hoisted_4, [
7950
- unref(hasIconBefore) ? (openBlock(), createBlock(
7951
- _sfc_main$u,
7952
- mergeProps({ key: 0 }, unref(hasIconBefore), { class: "vv-textarea__icon" }),
7953
- null,
7954
- 16
7955
- /* FULL_PROPS */
7956
- )) : createCommentVNode("v-if", true),
7957
- withDirectives(createElementVNode("textarea", mergeProps({
7958
- id: unref(hasId),
7959
- ref_key: "textarea",
7960
- ref: textarea,
7961
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(localModelValue) ? localModelValue.value = $event : null)
7962
- }, unref(hasAttrs), {
7963
- onKeyup: _cache[1] || (_cache[1] = ($event) => emit("keyup", $event))
7964
- }), null, 16, _hoisted_5), [
7965
- [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)
7966
8076
  ]),
7967
- unref(hasIconAfter) ? (openBlock(), createBlock(
7968
- _sfc_main$u,
7969
- mergeProps({ key: 1 }, unref(hasIconAfter), { class: "vv-textarea__icon vv-textarea__icon-after" }),
7970
- null,
7971
- 16
7972
- /* FULL_PROPS */
7973
- )) : createCommentVNode("v-if", true)
7974
- ]),
7975
- _ctx.$slots.after ? (openBlock(), createElementBlock("div", _hoisted_6, [
7976
- renderSlot(_ctx.$slots, "after", normalizeProps(guardReactiveProps(unref(slotProps))))
7977
- ])) : createCommentVNode("v-if", true),
7978
- unref(count) ? (openBlock(), createElementBlock("span", _hoisted_7, [
7979
- renderSlot(_ctx.$slots, "count", normalizeProps(guardReactiveProps(unref(slotProps))), () => [
7980
- createTextVNode(
7981
- toDisplayString(unref(countFormatted)),
7982
- 1
7983
- /* TEXT */
7984
- )
7985
- ])
7986
- ])) : createCommentVNode("v-if", true)
7987
- ]),
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
+ ),
7988
8093
  createVNode(unref(HintSlot), {
7989
8094
  id: unref(hasHintId),
7990
8095
  class: "vv-textarea__hint"
@@ -8020,7 +8125,62 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
8020
8125
  ]),
8021
8126
  key: "3"
8022
8127
  } : void 0
8023
- ]), 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)
8024
8184
  ],
8025
8185
  2
8026
8186
  /* CLASS */