@volverjs/ui-vue 0.0.10-beta.40 → 0.0.10-beta.42

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 (35) hide show
  1. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.es.js +12 -3
  2. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
  3. package/dist/components/VvCombobox/VvCombobox.es.js +185 -124
  4. package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
  5. package/dist/components/VvCombobox/VvCombobox.vue.d.ts +6 -0
  6. package/dist/components/VvCombobox/index.d.ts +54 -22
  7. package/dist/components/VvRadioGroup/VvRadioGroup.es.js +12 -3
  8. package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
  9. package/dist/components/VvSelect/VvSelect.es.js +79 -46
  10. package/dist/components/VvSelect/VvSelect.umd.js +1 -1
  11. package/dist/components/VvSelect/VvSelect.vue.d.ts +3 -0
  12. package/dist/components/VvSelect/index.d.ts +14 -0
  13. package/dist/components/index.es.js +185 -121
  14. package/dist/components/index.umd.js +1 -1
  15. package/dist/icons.es.js +3 -3
  16. package/dist/icons.umd.js +1 -1
  17. package/dist/stories/Combobox/Combobox.stories.d.ts +1 -0
  18. package/dist/stories/Combobox/ComboboxMultiple.stories.d.ts +1 -0
  19. package/dist/stories/Select/Select.stories.d.ts +1 -0
  20. package/package.json +18 -18
  21. package/src/assets/icons/detailed.json +1 -1
  22. package/src/assets/icons/normal.json +1 -1
  23. package/src/assets/icons/simple.json +1 -1
  24. package/src/components/VvCombobox/VvCombobox.vue +107 -96
  25. package/src/components/VvCombobox/index.ts +19 -2
  26. package/src/components/VvSelect/VvSelect.vue +66 -46
  27. package/src/components/VvSelect/index.ts +8 -1
  28. package/src/composables/useOptions.ts +12 -11
  29. package/src/stories/Combobox/Combobox.settings.ts +18 -3
  30. package/src/stories/Combobox/Combobox.stories.ts +8 -0
  31. package/src/stories/Combobox/Combobox.test.ts +6 -4
  32. package/src/stories/Combobox/ComboboxMultiple.stories.ts +9 -0
  33. package/src/stories/Combobox/ComboboxOptions.stories.ts +9 -13
  34. package/src/stories/Select/Select.stories.ts +8 -0
  35. package/src/stories/Select/Select.test.ts +5 -3
@@ -27,13 +27,11 @@ const propsDefaults = useDefaults<typeof VvComboboxProps>(
27
27
  props,
28
28
  )
29
29
 
30
- // Grouped options
31
- function isGroup(option: T) {
32
- if (typeof option === 'string') {
33
- return false
34
- }
35
- return option.options?.length
36
- }
30
+ // template ref
31
+ const inputEl: Ref<HTMLElement | null> = ref(null)
32
+ const inputSearchEl: Ref<HTMLElement | null> = ref(null)
33
+ const wrapperEl: Ref<HTMLElement | null> = ref(null)
34
+ const dropdownEl = ref<typeof VvDropdown | null>(null)
37
35
 
38
36
  // hint slot
39
37
  const {
@@ -43,11 +41,6 @@ const {
43
41
  hintSlotScope,
44
42
  } = HintSlotFactory(propsDefaults, slots)
45
43
 
46
- // template ref
47
- const inputEl: Ref<HTMLElement | null> = ref(null)
48
- const inputSearchEl: Ref<HTMLElement | null> = ref(null)
49
- const wrapperEl: Ref<HTMLElement | null> = ref(null)
50
-
51
44
  // focus
52
45
  const { focused } = useComponentFocus(inputEl, emit)
53
46
  const { focused: focusedWithin } = useFocusWithin(wrapperEl)
@@ -87,17 +80,17 @@ watch(debouncedSearchText, () => {
87
80
  // expanded
88
81
  const expanded = ref(false)
89
82
  function toggleExpanded() {
90
- if (props.disabled || props.readonly)
83
+ if (isDisabledOrReadonly.value)
91
84
  return
92
85
  expanded.value = !expanded.value
93
86
  }
94
87
  function expand() {
95
- if (props.disabled || props.readonly || expanded.value)
88
+ if (isDisabledOrReadonly.value || expanded.value)
96
89
  return
97
90
  expanded.value = true
98
91
  }
99
92
  function collapse() {
100
- if (props.disabled || props.readonly || !expanded.value)
93
+ if (isDisabledOrReadonly.value || !expanded.value)
101
94
  return
102
95
  expanded.value = false
103
96
  }
@@ -116,6 +109,14 @@ function onAfterCollapse() {
116
109
  }
117
110
  }
118
111
 
112
+ // group
113
+ function isGroup(option: T) {
114
+ if (typeof option === 'string') {
115
+ return false
116
+ }
117
+ return option.options?.length
118
+ }
119
+
119
120
  // data
120
121
  const {
121
122
  id,
@@ -135,24 +136,62 @@ const hasDropdownId = computed(() => `${hasId.value}-dropdown`)
135
136
  const hasSearchId = computed(() => `${hasId.value}-search`)
136
137
  const hasLabelId = computed(() => `${hasId.value}-label`)
137
138
 
139
+ // tabindex
140
+ const isDisabledOrReadonly = computed(() => props.disabled || props.readonly)
141
+ const hasTabindex = computed(() => {
142
+ return isDisabledOrReadonly.value ? -1 : props.tabindex
143
+ })
144
+
145
+ // modelValue
146
+ const localModelValue = computed({
147
+ get: () => {
148
+ if (Array.isArray(props.modelValue)) {
149
+ return new Set(props.modelValue)
150
+ }
151
+ return props.modelValue !== undefined && props.modelValue !== null ? new Set([props.modelValue]) : new Set()
152
+ },
153
+ set: (value: Set<unknown>) => {
154
+ emit('update:modelValue', props.multiple || Array.isArray(props.modelValue) ? [...value] : [...value].pop())
155
+ },
156
+ })
157
+ const sizeOfModelValue = computed(() => localModelValue.value.size)
158
+ const isDirty = computed(() => sizeOfModelValue.value > 0)
159
+ const hasMaxValues = computed(() => {
160
+ if (!props.multiple) {
161
+ return 1
162
+ }
163
+ if (props.maxValues === undefined) {
164
+ return Infinity
165
+ }
166
+ return Number(props.maxValues)
167
+ })
168
+ const isUnselectable = computed(() => {
169
+ if (isDisabledOrReadonly.value) {
170
+ return false
171
+ }
172
+ // DEPRECATED: Must be removed in the future
173
+ if (!props.unselectable) {
174
+ return false
175
+ }
176
+ return sizeOfModelValue.value > Number(props.minValues)
177
+ })
178
+ const isSelectable = computed(() => {
179
+ if (isDisabledOrReadonly.value) {
180
+ return false
181
+ }
182
+ if (!props.multiple) {
183
+ return true
184
+ }
185
+ return sizeOfModelValue.value < hasMaxValues.value
186
+ })
187
+
138
188
  // loading
139
189
  const localLoading = ref(false)
140
190
  const isLoading = computed(() => localLoading.value || loading.value)
141
191
 
142
- // ref
143
- const dropdownEl = ref()
144
-
145
192
  // icons
146
193
  const { hasIconBefore, hasIconAfter } = useComponentIcon(icon, iconPosition)
147
194
 
148
- // dirty
149
- const isDirty = computed(() => !isEmpty(props.modelValue))
150
-
151
- // tabindex
152
- const hasTabindex = computed(() => {
153
- return disabled.value || readonly.value ? -1 : props.tabindex
154
- })
155
-
156
195
  // styles
157
196
  const bemCssClasses = useModifiers(
158
197
  'vv-select',
@@ -172,6 +211,7 @@ const bemCssClasses = useModifiers(
172
211
  })),
173
212
  )
174
213
 
214
+ // options
175
215
  const {
176
216
  getOptionLabel,
177
217
  getOptionValue,
@@ -179,7 +219,10 @@ const {
179
219
  isOptionDisabled,
180
220
  } = useOptions(props)
181
221
 
182
- // options filtered by search text
222
+ function isOptionDisabledOrNotSelectable(option: T) {
223
+ return isOptionDisabled(option) || (!isSelectable.value && !isOptionSelected(option))
224
+ }
225
+
183
226
  const filteredOptions = computedAsync(async () => {
184
227
  if (propsDefaults.value.searchFunction) {
185
228
  localLoading.value = true
@@ -200,22 +243,11 @@ const filteredOptions = computedAsync(async () => {
200
243
  })
201
244
 
202
245
  /**
203
- * Check if an option exist into modelValue array (multiple) or is equal to modelValue (single)
246
+ * Check if an option is selected
204
247
  * @param {T} option
205
248
  */
206
249
  function isOptionSelected(option: T) {
207
- if (Array.isArray(props.modelValue)) {
208
- // check if contain whole option or option value
209
- return (
210
- contains(option, props.modelValue)
211
- || contains(getOptionValue(option), props.modelValue)
212
- )
213
- }
214
- // check if modelValue is equal to option or option value
215
- return (
216
- equals(option, props.modelValue)
217
- || equals(getOptionValue(option), props.modelValue)
218
- )
250
+ return localModelValue.value.has(getOptionValue(option))
219
251
  }
220
252
 
221
253
  /**
@@ -251,60 +283,40 @@ function onClickInput() {
251
283
  }
252
284
 
253
285
  /**
254
- * Function triggered on input of checkbox or radio (multple or single mode)
286
+ * Function triggered on option click
255
287
  * @param option {T} option value
256
288
  */
257
289
  function onInput(option: T) {
258
- if (props.disabled || props.readonly) {
259
- return
290
+ const isSelected = isOptionSelected(option)
291
+ if (isSelected && isUnselectable.value) {
292
+ localModelValue.value.delete(getOptionValue(option))
260
293
  }
261
-
262
- // get option value
263
- const value = getOptionValue(option)
264
- let toReturn = value
265
-
266
- // check multiple prop, override value with array and remove or add the value
267
- if (props.multiple) {
268
- // check max-values prop and block check new values
269
- if (Array.isArray(props.modelValue)) {
270
- const maxValues = Number(props.maxValues)
271
- if (
272
- props.maxValues !== undefined
273
- && maxValues >= 0
274
- && props.modelValue?.length >= maxValues
275
- ) {
276
- if (!contains(value, props.modelValue)) {
277
- // maxValues reached
278
- return
279
- }
280
- }
281
- toReturn = contains(value, props.modelValue)
282
- ? removeFromList(value, props.modelValue)
283
- : [...props.modelValue, value]
284
- }
285
- else {
286
- toReturn = [value]
294
+ else if (!isSelected && isSelectable.value) {
295
+ if (!props.multiple) {
296
+ localModelValue.value.clear()
287
297
  }
298
+ localModelValue.value.add(getOptionValue(option))
288
299
  }
289
- else {
290
- if (!props.keepOpen) {
291
- collapse()
292
- }
293
- if (Array.isArray(props.modelValue)) {
294
- if (props.unselectable && props.modelValue.includes(value)) {
295
- toReturn = []
296
- }
297
- else {
298
- toReturn = [value]
299
- }
300
- }
301
- else if (props.unselectable && value === props.modelValue) {
302
- toReturn = undefined
303
- }
300
+ // force reactivity
301
+ localModelValue.value = new Set(localModelValue.value)
302
+ if (!props.multiple && !props.keepOpen) {
303
+ collapse()
304
304
  }
305
- emit('update:modelValue', toReturn)
306
305
  }
307
306
 
307
+ /**
308
+ * Auto select the first option if autoOpen is enabled
309
+ */
310
+ watch(
311
+ () => props.options,
312
+ (newValue) => {
313
+ if (newValue?.length && props.autoselectFirst && !isDirty.value) {
314
+ onInput(newValue[0])
315
+ }
316
+ },
317
+ { immediate: true },
318
+ )
319
+
308
320
  const selectProps = computed(() => ({
309
321
  id: hasId.value,
310
322
  name: props.name,
@@ -325,7 +337,8 @@ const selectProps = computed(() => ({
325
337
  icon: propsDefaults.value.icon,
326
338
  iconPosition: propsDefaults.value.iconPosition,
327
339
  floating: propsDefaults.value.floating,
328
- unselectable: propsDefaults.value.unselectable,
340
+ unselectable: isUnselectable.value,
341
+ autoselectFirst: propsDefaults.value.autoselectFirst,
329
342
  multiple: propsDefaults.value.multiple,
330
343
  label: propsDefaults.value.label,
331
344
  placeholder: propsDefaults.value.placeholder,
@@ -357,7 +370,7 @@ const slotProps = computed(() => ({
357
370
  modelValue: props.modelValue,
358
371
  }))
359
372
 
360
- // computed
373
+ // keyboard
361
374
  onKeyStroke(
362
375
  [' ', 'Enter'],
363
376
  (e) => {
@@ -478,9 +491,7 @@ export default {
478
491
  {{ getOptionLabel(option) }}
479
492
  <button
480
493
  v-if="
481
- unselectable
482
- && !readonly
483
- && !disabled
494
+ isUnselectable
484
495
  "
485
496
  :aria-label="
486
497
  propsDefaults.deselectActionLabel
@@ -524,8 +535,8 @@ export default {
524
535
  )"
525
536
  v-bind="{
526
537
  selected: isOptionSelected(item),
527
- disabled: isOptionDisabled(item),
528
- unselectable,
538
+ disabled: isOptionDisabledOrNotSelectable(item),
539
+ unselectable: isUnselectable,
529
540
  deselectHintLabel:
530
541
  propsDefaults.deselectHintLabel,
531
542
  selectHintLabel:
@@ -545,7 +556,7 @@ export default {
545
556
  option,
546
557
  selectedOptions,
547
558
  selected: isOptionSelected(item),
548
- disabled: isOptionDisabled(item),
559
+ disabled: isOptionDisabledOrNotSelectable(item),
549
560
  }"
550
561
  >
551
562
  {{ getOptionLabel(item) }}
@@ -556,8 +567,8 @@ export default {
556
567
  v-else
557
568
  v-bind="{
558
569
  selected: isOptionSelected(option),
559
- disabled: isOptionDisabled(option),
560
- unselectable,
570
+ disabled: isOptionDisabledOrNotSelectable(option),
571
+ unselectable: isUnselectable,
561
572
  deselectHintLabel:
562
573
  propsDefaults.deselectHintLabel,
563
574
  selectHintLabel:
@@ -576,7 +587,7 @@ export default {
576
587
  option,
577
588
  selectedOptions,
578
589
  selected: isOptionSelected(option),
579
- disabled: isOptionDisabled(option),
590
+ disabled: isOptionDisabledOrNotSelectable(option),
580
591
  }"
581
592
  >
582
593
  {{ getOptionLabel(option) }}
@@ -12,7 +12,6 @@ import {
12
12
  IconProps,
13
13
  TabindexProps,
14
14
  FloatingLabelProps,
15
- UnselectableProps,
16
15
  IdNameProps,
17
16
  DropdownProps,
18
17
  LabelProps,
@@ -43,7 +42,6 @@ export const VvComboboxProps = {
43
42
  ...OptionsProps,
44
43
  ...IconProps,
45
44
  ...FloatingLabelProps,
46
- ...UnselectableProps,
47
45
  ...DropdownProps,
48
46
  ...LabelProps,
49
47
  /**
@@ -126,10 +124,22 @@ export const VvComboboxProps = {
126
124
  * Manage modelValue as string[] or object[]
127
125
  */
128
126
  multiple: Boolean,
127
+ /**
128
+ * The min number of selected values
129
+ */
130
+ minValues: {
131
+ type: [Number, String],
132
+ default: 0,
133
+ },
129
134
  /**
130
135
  * The max number of selected values
131
136
  */
132
137
  maxValues: [Number, String],
138
+ /**
139
+ * If true the input will be unselectable
140
+ * @deprecated use minValues instead
141
+ */
142
+ unselectable: { type: Boolean, default: true },
133
143
  /**
134
144
  * The select label separator visible to the user
135
145
  */
@@ -170,6 +180,13 @@ export const VvComboboxProps = {
170
180
  type: Boolean,
171
181
  default: false,
172
182
  },
183
+ /**
184
+ * Select first option automatically
185
+ */
186
+ autoselectFirst: {
187
+ type: Boolean,
188
+ default: false,
189
+ },
173
190
  /**
174
191
  * Keep open dropdown on single select
175
192
  */
@@ -20,7 +20,7 @@ const propsDefaults = useDefaults<typeof VvSelectProps>(
20
20
  )
21
21
 
22
22
  // template refs
23
- const select = ref()
23
+ const selectEl = ref()
24
24
 
25
25
  // hint
26
26
  const {
@@ -30,6 +30,17 @@ const {
30
30
  hintSlotScope,
31
31
  } = HintSlotFactory(propsDefaults, slots)
32
32
 
33
+ // focus
34
+ const { focused } = useComponentFocus(selectEl, emit)
35
+
36
+ // group
37
+ function isGroup(option: T) {
38
+ if (typeof option === 'string') {
39
+ return false
40
+ }
41
+ return option.options?.length
42
+ }
43
+
33
44
  // data
34
45
  const {
35
46
  id,
@@ -44,34 +55,48 @@ const {
44
55
  floating,
45
56
  multiple,
46
57
  } = toRefs(props)
47
-
48
- // computed
49
58
  const hasId = useUniqueId(id)
50
59
  const hasHintId = computed(() => `${hasId.value}-hint`)
51
60
 
52
- // focus
53
- const { focused } = useComponentFocus(select, emit)
61
+ // tabindex
62
+ const isDisabledOrReadonly = computed(() => props.disabled || props.readonly)
63
+ const hasTabindex = computed(() => {
64
+ return isDisabledOrReadonly.value ? -1 : props.tabindex
65
+ })
66
+
67
+ // modelValue
68
+ const localModelValue = computed({
69
+ get: () => {
70
+ return props.modelValue
71
+ },
72
+ set: (newValue) => {
73
+ if (Array.isArray(newValue)) {
74
+ newValue = newValue.filter(item => item !== undefined)
75
+ if (newValue.length === 0 && !props.unselectable) {
76
+ selectEl.value.value = props.modelValue
77
+ return
78
+ }
79
+ }
80
+ emit('update:modelValue', newValue)
81
+ },
82
+ })
83
+ const isDirty = computed(() => {
84
+ if (Array.isArray(localModelValue.value)) {
85
+ return localModelValue.value.length > 0
86
+ }
87
+ return localModelValue.value !== undefined && localModelValue.value !== null
88
+ })
54
89
 
55
90
  // visibility
56
- const isVisible = useElementVisibility(select)
91
+ const isVisible = useElementVisibility(selectEl)
57
92
  watch(isVisible, (newValue) => {
58
93
  if (newValue && props.autofocus) {
59
94
  focused.value = true
60
95
  }
61
96
  })
62
-
63
97
  // icons
64
98
  const { hasIconBefore, hasIconAfter } = useComponentIcon(icon, iconPosition)
65
99
 
66
- // dirty
67
- const isDirty = computed(() => !isEmpty(props.modelValue))
68
-
69
- // disabled
70
- const isDisabled = computed(() => props.disabled || props.readonly)
71
- const hasTabindex = computed(() => {
72
- return isDisabled.value ? -1 : props.tabindex
73
- })
74
-
75
100
  // invalid
76
101
  const isInvalid = computed(() => {
77
102
  if (props.invalid === true) {
@@ -102,12 +127,34 @@ const bemCssClasses = useModifiers(
102
127
  })),
103
128
  )
104
129
 
130
+ // options
131
+ const {
132
+ getOptionLabel,
133
+ getOptionValue,
134
+ isOptionDisabled,
135
+ getOptionGrouped,
136
+ } = useOptions(props)
137
+
138
+ /**
139
+ * Auto select the first option if autoOpen is enabled
140
+ */
141
+ watch(
142
+ () => props.options,
143
+ (newValue) => {
144
+ if (newValue?.length && props.autoselectFirst && !isDirty.value) {
145
+ const firstOptionValue = getOptionValue(newValue[0])
146
+ localModelValue.value = props.multiple ? [firstOptionValue] : firstOptionValue
147
+ }
148
+ },
149
+ { immediate: true },
150
+ )
151
+
105
152
  // attrs
106
153
  const hasAttrs: SelectHTMLAttributes = computed(() => {
107
154
  return {
108
155
  'name': props.name,
109
156
  'tabindex': hasTabindex.value,
110
- 'disabled': isDisabled.value,
157
+ 'disabled': isDisabledOrReadonly.value,
111
158
  'required': props.required,
112
159
  'size': props.size,
113
160
  'autocomplete': props.autocomplete,
@@ -128,33 +175,6 @@ const slotProps = computed(() => ({
128
175
  invalid: props.invalid,
129
176
  modelValue: props.modelValue,
130
177
  }))
131
-
132
- const {
133
- getOptionLabel,
134
- getOptionValue,
135
- isOptionDisabled,
136
- getOptionGrouped,
137
- } = useOptions(props)
138
-
139
- const localModelValue = computed({
140
- get: () => {
141
- return props.modelValue
142
- },
143
- set: (newValue) => {
144
- if (Array.isArray(newValue)) {
145
- newValue = newValue.filter(item => item !== undefined)
146
- }
147
- emit('update:modelValue', newValue)
148
- },
149
- })
150
-
151
- // Grouped options
152
- function isGroup(option: T) {
153
- if (typeof option === 'string') {
154
- return false
155
- }
156
- return option.options?.length
157
- }
158
178
  </script>
159
179
 
160
180
  <script lang="ts">
@@ -180,9 +200,9 @@ export default {
180
200
  />
181
201
  <select
182
202
  :id="hasId"
183
- ref="select"
184
- v-model="localModelValue"
203
+ ref="selectEl"
185
204
  v-bind="hasAttrs"
205
+ v-model="localModelValue"
186
206
  >
187
207
  <option
188
208
  v-if="placeholder"
@@ -12,10 +12,10 @@ import {
12
12
  IconProps,
13
13
  IdNameProps,
14
14
  FloatingLabelProps,
15
- UnselectableProps,
16
15
  AutofocusProps,
17
16
  AutocompleteProps,
18
17
  LabelProps,
18
+ UnselectableProps,
19
19
  } from '../../props'
20
20
  import type { Option } from '../../types/generic'
21
21
 
@@ -68,6 +68,13 @@ export const VvSelectProps = {
68
68
  type: [String, Number, Boolean, Object, Array],
69
69
  default: undefined,
70
70
  },
71
+ /**
72
+ * Select first option automatically
73
+ */
74
+ autoselectFirst: {
75
+ type: Boolean,
76
+ default: false,
77
+ },
71
78
  /**
72
79
  * Select placeholder
73
80
  */
@@ -8,10 +8,11 @@ export function useOptions(props: any) {
8
8
  if (typeof option === 'string') {
9
9
  return option
10
10
  }
11
+ if (typeof labelKey.value === 'function') {
12
+ return labelKey.value(option)
13
+ }
11
14
  return String(
12
- typeof labelKey.value === 'function'
13
- ? labelKey.value(option)
14
- : get(option as object, labelKey.value),
15
+ labelKey.value ? get(option as object, labelKey.value) : option,
15
16
  )
16
17
  }
17
18
 
@@ -19,20 +20,20 @@ export function useOptions(props: any) {
19
20
  if (typeof option === 'string') {
20
21
  return option
21
22
  }
22
-
23
- return typeof valueKey.value === 'function'
24
- ? valueKey.value(option)
25
- : get(option as object, valueKey.value)
23
+ if (typeof valueKey.value === 'function') {
24
+ return valueKey.value(option)
25
+ }
26
+ return valueKey.value ? get(option as object, valueKey.value) : option
26
27
  }
27
28
 
28
29
  const isOptionDisabled = <T extends string | Option>(option: T): boolean => {
29
30
  if (typeof option === 'string') {
30
31
  return false
31
32
  }
32
-
33
- return typeof disabledKey.value === 'function'
34
- ? disabledKey.value(option)
35
- : get(option as object, disabledKey.value)
33
+ if (typeof disabledKey.value === 'function') {
34
+ return disabledKey.value(option)
35
+ }
36
+ return disabledKey.value ? get(option as object, disabledKey.value) : false
36
37
  }
37
38
 
38
39
  const getOptionGrouped = <T extends string | Option>(option: T) => {
@@ -60,8 +60,8 @@ export const argTypes: ArgTypes = {
60
60
  ...OptionsArgTypes,
61
61
  ...IconArgTypes,
62
62
  ...FloatingLabelArgTypes,
63
- ...UnselectableArgTypes,
64
63
  ...DropdownArgTypes,
64
+ ...UnselectableArgTypes,
65
65
  'triggerWidth': {
66
66
  ...DropdownArgTypes.triggerWidth,
67
67
  table: {
@@ -215,9 +215,24 @@ export const argTypes: ArgTypes = {
215
215
  },
216
216
  'maxValues': {
217
217
  description: 'Max number of selected values',
218
-
219
218
  control: {
220
- type: 'text',
219
+ type: 'number',
220
+ },
221
+ table: {
222
+ type: {
223
+ summary: 'number',
224
+ },
225
+ },
226
+ },
227
+ 'minValues': {
228
+ description: 'Min number of selected values',
229
+ control: {
230
+ type: 'number',
231
+ },
232
+ table: {
233
+ type: {
234
+ summary: 'number',
235
+ },
221
236
  },
222
237
  },
223
238
  'separator': {
@@ -161,6 +161,14 @@ export const KeepOpen: Story = {
161
161
  },
162
162
  }
163
163
 
164
+ export const autoselectFirst: Story = {
165
+ ...Default,
166
+ args: {
167
+ ...defaultArgs,
168
+ autoselectFirst: true,
169
+ },
170
+ }
171
+
164
172
  export const Size: Story = {
165
173
  ...Default,
166
174
  args: {