@volverjs/ui-vue 0.0.7 → 0.0.8-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/auto-imports.d.ts +1 -0
- package/dist/components/VvAlert/VvAlert.es.js +27 -18
- package/dist/components/VvAlert/VvAlert.umd.js +1 -1
- package/dist/components/VvAlert/VvAlert.vue.d.ts +4 -0
- package/dist/components/VvAlertGroup/VvAlertGroup.es.js +27 -18
- package/dist/components/VvAlertGroup/VvAlertGroup.umd.js +1 -1
- package/dist/components/VvCheckboxGroup/VvCheckboxGroup.es.js +4 -3
- package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
- package/dist/components/VvCombobox/VvCombobox.es.js +555 -106
- package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
- package/dist/components/VvCombobox/VvCombobox.vue.d.ts +3 -0
- package/dist/components/VvCombobox/index.d.ts +1 -0
- package/dist/components/VvDropdown/VvDropdown.es.js +56 -28
- package/dist/components/VvDropdown/VvDropdown.umd.js +1 -1
- package/dist/components/VvDropdown/VvDropdown.vue.d.ts +11 -2
- package/dist/components/VvDropdown/index.d.ts +7 -1
- package/dist/components/VvRadioGroup/VvRadioGroup.es.js +4 -3
- package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
- package/dist/components/VvSelect/VvSelect.es.js +4 -3
- package/dist/components/VvSelect/VvSelect.umd.js +1 -1
- package/dist/components/index.es.js +110 -58
- package/dist/components/index.umd.js +1 -1
- package/dist/icons.es.js +3 -3
- package/dist/icons.umd.js +1 -1
- package/dist/stories/Alert/Alert.settings.d.ts +10 -0
- package/dist/stories/Combobox/ComboboxOptions.stories.d.ts +1 -0
- package/package.json +37 -33
- package/src/assets/icons/detailed.json +1 -1
- package/src/assets/icons/normal.json +1 -1
- package/src/assets/icons/simple.json +1 -1
- package/src/components/VvAlert/VvAlert.vue +29 -11
- package/src/components/VvCombobox/VvCombobox.vue +48 -26
- package/src/components/VvCombobox/index.ts +1 -0
- package/src/components/VvDropdown/VvDropdown.vue +59 -26
- package/src/components/VvDropdown/index.ts +8 -2
- package/src/composables/useOptions.ts +4 -3
- package/src/stories/Alert/Alert.settings.ts +10 -0
- package/src/stories/Alert/Alert.test.ts +8 -4
- package/src/stories/Combobox/Combobox.settings.ts +22 -1
- package/src/stories/Combobox/Combobox.test.ts +5 -6
- package/src/stories/Combobox/ComboboxOptions.stories.ts +18 -0
- package/src/stories/Select/Select.test.ts +3 -3
- package/src/stories/Tooltip/Tooltip.test.ts +3 -1
|
@@ -16,27 +16,45 @@
|
|
|
16
16
|
|
|
17
17
|
<template>
|
|
18
18
|
<div v-bind="hasProps">
|
|
19
|
-
<div
|
|
19
|
+
<div
|
|
20
|
+
v-if="
|
|
21
|
+
$slots.header ||
|
|
22
|
+
$slots.title ||
|
|
23
|
+
$slots.close ||
|
|
24
|
+
$slots['title::before'] ||
|
|
25
|
+
$slots['title::after'] ||
|
|
26
|
+
title ||
|
|
27
|
+
dismissable ||
|
|
28
|
+
autoClose
|
|
29
|
+
"
|
|
30
|
+
class="vv-alert__header"
|
|
31
|
+
>
|
|
20
32
|
<VvIcon v-if="hasIcon" v-bind="hasIcon" class="vv-alert__icon" />
|
|
21
33
|
<!-- @slot Header slot -->
|
|
22
34
|
<slot name="header">
|
|
23
35
|
<!-- @slot Before title slot -->
|
|
24
36
|
<slot name="title::before" />
|
|
25
37
|
<strong :id="hasTitleId" class="vv-alert__title">
|
|
26
|
-
|
|
38
|
+
<!-- @slot Title slot -->
|
|
39
|
+
<slot name="title">
|
|
40
|
+
{{ title }}
|
|
41
|
+
</slot>
|
|
27
42
|
</strong>
|
|
28
43
|
<!-- @slot After title slot -->
|
|
29
44
|
<slot name="title::after" />
|
|
30
45
|
</slot>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
<!-- @slot Close button slot -->
|
|
47
|
+
<slot name="close" v-bind="{ close }">
|
|
48
|
+
<button
|
|
49
|
+
v-if="dismissable || autoClose"
|
|
50
|
+
class="vv-alert__close"
|
|
51
|
+
type="button"
|
|
52
|
+
:aria-label="closeLabel"
|
|
53
|
+
@click.stop="close"
|
|
54
|
+
>
|
|
55
|
+
<div class="vv-alert__close-mask"></div>
|
|
56
|
+
</button>
|
|
57
|
+
</slot>
|
|
40
58
|
</div>
|
|
41
59
|
<div v-if="$slots.default || content" class="vv-alert__content">
|
|
42
60
|
<!-- @slot Content slot -->
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
export default {
|
|
3
3
|
name: 'VvCombobox',
|
|
4
|
-
components: {
|
|
4
|
+
components: {
|
|
5
|
+
VvDropdown,
|
|
6
|
+
VvDropdownOption,
|
|
7
|
+
VvDropdownOptgroup,
|
|
8
|
+
VvButton,
|
|
9
|
+
},
|
|
5
10
|
}
|
|
6
11
|
</script>
|
|
7
12
|
|
|
@@ -14,6 +19,7 @@
|
|
|
14
19
|
import VvDropdownOptgroup from '../VvDropdown/VvDropdownOptgroup.vue'
|
|
15
20
|
import VvSelect from '../VvSelect/VvSelect.vue'
|
|
16
21
|
import VvBadge from '../VvBadge/VvBadge.vue'
|
|
22
|
+
import VvButton from '../VvButton/VvButton.vue'
|
|
17
23
|
import HintSlotFactory from '../common/HintSlot'
|
|
18
24
|
import type { Option } from '../../types/generic'
|
|
19
25
|
import { DropdownRole } from '../../constants'
|
|
@@ -101,7 +107,9 @@
|
|
|
101
107
|
const onAfterExpand = () => {
|
|
102
108
|
if (searchable.value) {
|
|
103
109
|
if (inputSearchEl.value) {
|
|
104
|
-
inputSearchEl.value.focus(
|
|
110
|
+
inputSearchEl.value.focus({
|
|
111
|
+
preventScroll: true,
|
|
112
|
+
})
|
|
105
113
|
}
|
|
106
114
|
}
|
|
107
115
|
}
|
|
@@ -131,6 +139,9 @@
|
|
|
131
139
|
const hasSearchId = computed(() => `${hasId.value}-search`)
|
|
132
140
|
const hasLabelId = computed(() => `${hasId.value}-label`)
|
|
133
141
|
|
|
142
|
+
// ref
|
|
143
|
+
const dropdownEl = ref()
|
|
144
|
+
|
|
134
145
|
// icons
|
|
135
146
|
const { hasIcon, hasIconBefore, hasIconAfter } = useComponentIcon(
|
|
136
147
|
icon,
|
|
@@ -297,34 +308,36 @@
|
|
|
297
308
|
loadingLabel: propsDefaults.value.loadingLabel,
|
|
298
309
|
disabled: disabled.value,
|
|
299
310
|
readonly: readonly.value,
|
|
300
|
-
modifiers:
|
|
301
|
-
options:
|
|
302
|
-
labelKey:
|
|
303
|
-
valueKey:
|
|
304
|
-
icon:
|
|
305
|
-
iconPosition:
|
|
306
|
-
floating:
|
|
307
|
-
unselectable:
|
|
308
|
-
multiple:
|
|
309
|
-
label:
|
|
310
|
-
placeholder:
|
|
311
|
+
modifiers: propsDefaults.value.modifiers,
|
|
312
|
+
options: propsDefaults.value.options,
|
|
313
|
+
labelKey: propsDefaults.value.labelKey,
|
|
314
|
+
valueKey: propsDefaults.value.valueKey,
|
|
315
|
+
icon: propsDefaults.value.icon,
|
|
316
|
+
iconPosition: propsDefaults.value.iconPosition,
|
|
317
|
+
floating: propsDefaults.value.floating,
|
|
318
|
+
unselectable: propsDefaults.value.unselectable,
|
|
319
|
+
multiple: propsDefaults.value.multiple,
|
|
320
|
+
label: propsDefaults.value.label,
|
|
321
|
+
placeholder: propsDefaults.value.placeholder,
|
|
311
322
|
modelValue: props.modelValue,
|
|
312
323
|
}))
|
|
313
324
|
|
|
314
325
|
const dropdownProps = computed(() => ({
|
|
315
326
|
id: hasDropdownId.value,
|
|
316
327
|
reference: wrapperEl.value,
|
|
317
|
-
placement:
|
|
318
|
-
strategy:
|
|
319
|
-
transitionName:
|
|
320
|
-
offset:
|
|
321
|
-
shift:
|
|
322
|
-
flip:
|
|
323
|
-
autoPlacement:
|
|
324
|
-
arrow:
|
|
325
|
-
autofocusFirst: searchable.value
|
|
326
|
-
|
|
327
|
-
|
|
328
|
+
placement: propsDefaults.value.placement,
|
|
329
|
+
strategy: propsDefaults.value.strategy,
|
|
330
|
+
transitionName: propsDefaults.value.transitionName,
|
|
331
|
+
offset: propsDefaults.value.offset,
|
|
332
|
+
shift: propsDefaults.value.shift,
|
|
333
|
+
flip: propsDefaults.value.flip,
|
|
334
|
+
autoPlacement: propsDefaults.value.autoPlacement,
|
|
335
|
+
arrow: propsDefaults.value.arrow,
|
|
336
|
+
autofocusFirst: searchable.value
|
|
337
|
+
? false
|
|
338
|
+
: propsDefaults.value.autofocusFirst,
|
|
339
|
+
triggerWidth: propsDefaults.value.triggerWidth,
|
|
340
|
+
modifiers: propsDefaults.value.dropdownModifiers,
|
|
328
341
|
}))
|
|
329
342
|
|
|
330
343
|
// slots
|
|
@@ -362,6 +375,7 @@
|
|
|
362
375
|
</label>
|
|
363
376
|
<div ref="wrapperEl" class="vv-select__wrapper">
|
|
364
377
|
<VvDropdown
|
|
378
|
+
ref="dropdownEl"
|
|
365
379
|
v-model="expanded"
|
|
366
380
|
v-bind="dropdownProps"
|
|
367
381
|
:role="DropdownRole.listbox"
|
|
@@ -559,9 +573,17 @@
|
|
|
559
573
|
</slot>
|
|
560
574
|
</VvDropdownOption>
|
|
561
575
|
</template>
|
|
562
|
-
<template
|
|
576
|
+
<template #after>
|
|
563
577
|
<!-- @slot Slot after dropdown items -->
|
|
564
|
-
<slot name="dropdown::after"
|
|
578
|
+
<slot name="dropdown::after">
|
|
579
|
+
<!-- Close button if dropdown custom position is enabled and floating-ui disabled -->
|
|
580
|
+
<VvButton
|
|
581
|
+
v-if="dropdownEl?.dropdownCustomPosition === 'true'"
|
|
582
|
+
label="Close"
|
|
583
|
+
modifiers="secondary"
|
|
584
|
+
@click="dropdownEl.hide()"
|
|
585
|
+
/>
|
|
586
|
+
</slot>
|
|
565
587
|
</template>
|
|
566
588
|
</VvDropdown>
|
|
567
589
|
</div>
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
|
|
44
44
|
// template elements
|
|
45
45
|
const localReferenceEl = ref<HTMLElement | null>(null)
|
|
46
|
-
const floatingEl: Ref
|
|
46
|
+
const floatingEl: Ref = ref()
|
|
47
47
|
const arrowEl = ref<HTMLElement | null>(null)
|
|
48
48
|
const listEl = ref<HTMLUListElement | null>(null)
|
|
49
49
|
const referenceEl = computed({
|
|
@@ -53,6 +53,25 @@
|
|
|
53
53
|
},
|
|
54
54
|
})
|
|
55
55
|
|
|
56
|
+
// ref to store the value of css-var "--dropdown-custom-position"
|
|
57
|
+
const dropdownCustomPosition = ref()
|
|
58
|
+
|
|
59
|
+
// set dropdownCustomPosition value from css-var "--dropdown-custom-position"
|
|
60
|
+
const onChangeDropdownCustomPosition = () => {
|
|
61
|
+
dropdownCustomPosition.value = window
|
|
62
|
+
.getComputedStyle(floatingEl.value)
|
|
63
|
+
.getPropertyValue('--dropdown-custom-position')
|
|
64
|
+
?.trim()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// observe dropdown style for "--dropdown-custom-position" css var to disable floating-ui
|
|
68
|
+
onMounted(() => {
|
|
69
|
+
useMutationObserver(floatingEl.value, onChangeDropdownCustomPosition, {
|
|
70
|
+
attributeFilter: ['style'],
|
|
71
|
+
window,
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
|
|
56
75
|
// floating ui
|
|
57
76
|
const middleware = computed(() => {
|
|
58
77
|
const toReturn = []
|
|
@@ -138,17 +157,22 @@
|
|
|
138
157
|
middleware,
|
|
139
158
|
},
|
|
140
159
|
)
|
|
141
|
-
const dropdownPlacement = computed(() =>
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
160
|
+
const dropdownPlacement = computed(() => {
|
|
161
|
+
if (dropdownCustomPosition?.value === 'true') {
|
|
162
|
+
return {}
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
position: strategy.value,
|
|
166
|
+
top: `${y.value ?? 0}px`,
|
|
167
|
+
left: `${x.value ?? 0}px`,
|
|
168
|
+
maxWidth: maxWidth.value,
|
|
169
|
+
maxHeight: maxHeight.value,
|
|
170
|
+
width:
|
|
171
|
+
props.triggerWidth && referenceEl.value
|
|
172
|
+
? `${referenceEl.value.offsetWidth}px`
|
|
173
|
+
: undefined,
|
|
174
|
+
}
|
|
175
|
+
})
|
|
152
176
|
|
|
153
177
|
// placement
|
|
154
178
|
const side = computed(() => placement.value.split('-')[0])
|
|
@@ -162,6 +186,9 @@
|
|
|
162
186
|
}[side.value] ?? 'bottom'),
|
|
163
187
|
)
|
|
164
188
|
const arrowPlacement = computed(() => {
|
|
189
|
+
if (dropdownCustomPosition?.value === 'true') {
|
|
190
|
+
return {}
|
|
191
|
+
}
|
|
165
192
|
if (['bottom', 'top'].includes(staticSide.value)) {
|
|
166
193
|
return {
|
|
167
194
|
right: `${middlewareData.value.arrow?.x ?? 0}px`,
|
|
@@ -201,7 +228,7 @@
|
|
|
201
228
|
const init = (el: HTMLElement) => {
|
|
202
229
|
referenceEl.value = el
|
|
203
230
|
}
|
|
204
|
-
defineExpose({ toggle, show, hide, init })
|
|
231
|
+
defineExpose({ toggle, show, hide, init, dropdownCustomPosition })
|
|
205
232
|
watch(expanded, (newValue) => {
|
|
206
233
|
if (newValue && props.autofocusFirst) {
|
|
207
234
|
nextTick(() => {
|
|
@@ -210,7 +237,9 @@
|
|
|
210
237
|
floatingEl.value,
|
|
211
238
|
)
|
|
212
239
|
if (focusableElements.length > 0) {
|
|
213
|
-
focusableElements[0].focus(
|
|
240
|
+
focusableElements[0].focus({
|
|
241
|
+
preventScroll: true,
|
|
242
|
+
})
|
|
214
243
|
}
|
|
215
244
|
})
|
|
216
245
|
}
|
|
@@ -286,9 +315,13 @@
|
|
|
286
315
|
document.activeElement as HTMLElement,
|
|
287
316
|
)
|
|
288
317
|
if (activeElementIndex < focusableElements.length - 1) {
|
|
289
|
-
focusableElements[activeElementIndex + 1].focus(
|
|
318
|
+
focusableElements[activeElementIndex + 1].focus({
|
|
319
|
+
preventScroll: true,
|
|
320
|
+
})
|
|
290
321
|
} else {
|
|
291
|
-
focusableElements[0].focus(
|
|
322
|
+
focusableElements[0].focus({
|
|
323
|
+
preventScroll: true,
|
|
324
|
+
})
|
|
292
325
|
}
|
|
293
326
|
}
|
|
294
327
|
})
|
|
@@ -306,9 +339,13 @@
|
|
|
306
339
|
document.activeElement as HTMLElement,
|
|
307
340
|
)
|
|
308
341
|
if (activeElementIndex > 0) {
|
|
309
|
-
focusableElements[activeElementIndex - 1].focus(
|
|
342
|
+
focusableElements[activeElementIndex - 1].focus({
|
|
343
|
+
preventScroll: true,
|
|
344
|
+
})
|
|
310
345
|
} else {
|
|
311
|
-
focusableElements[focusableElements.length - 1].focus(
|
|
346
|
+
focusableElements[focusableElements.length - 1].focus({
|
|
347
|
+
preventScroll: true,
|
|
348
|
+
})
|
|
312
349
|
}
|
|
313
350
|
}
|
|
314
351
|
})
|
|
@@ -334,14 +371,10 @@
|
|
|
334
371
|
}
|
|
335
372
|
})
|
|
336
373
|
onKeyStroke([' ', 'Enter'], (e) => {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
) {
|
|
342
|
-
e.preventDefault()
|
|
343
|
-
const activeElement = document.activeElement as HTMLElement
|
|
344
|
-
activeElement.click()
|
|
374
|
+
const htmlEl = e.target as HTMLElement
|
|
375
|
+
|
|
376
|
+
if (expanded.value && focused.value && htmlEl) {
|
|
377
|
+
htmlEl?.click()
|
|
345
378
|
}
|
|
346
379
|
})
|
|
347
380
|
const onTransitionBeforeEnter = () => {
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import type { PropType } from 'vue'
|
|
2
|
-
import { DropdownProps, IdProps
|
|
2
|
+
import { DropdownProps, IdProps } from '../../props'
|
|
3
3
|
import { DropdownRole } from '../../constants'
|
|
4
4
|
|
|
5
5
|
export const VvDropdownProps = {
|
|
6
6
|
...IdProps,
|
|
7
|
-
...ModifiersProps,
|
|
8
7
|
...DropdownProps,
|
|
8
|
+
/**
|
|
9
|
+
* Component BEM modifiers
|
|
10
|
+
*/
|
|
11
|
+
modifiers: {
|
|
12
|
+
type: [String, Array] as PropType<string | string[]>,
|
|
13
|
+
default: 'mobile',
|
|
14
|
+
},
|
|
9
15
|
/**
|
|
10
16
|
* Show / hide dropdown programmatically
|
|
11
17
|
*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Option } from '../types/generic'
|
|
2
|
+
import { get } from 'ts-dot-prop'
|
|
2
3
|
|
|
3
4
|
// eslint-disable-next-line
|
|
4
5
|
export function useOptions(props: any) {
|
|
@@ -11,7 +12,7 @@ export function useOptions(props: any) {
|
|
|
11
12
|
return String(
|
|
12
13
|
typeof labelKey.value === 'function'
|
|
13
14
|
? labelKey.value(option)
|
|
14
|
-
: option
|
|
15
|
+
: get(option, labelKey.value),
|
|
15
16
|
)
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -20,7 +21,7 @@ export function useOptions(props: any) {
|
|
|
20
21
|
|
|
21
22
|
return typeof valueKey.value === 'function'
|
|
22
23
|
? valueKey.value(option)
|
|
23
|
-
: option
|
|
24
|
+
: get(option, valueKey.value)
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
const getOptionDisabled = (option: string | Option): boolean => {
|
|
@@ -28,7 +29,7 @@ export function useOptions(props: any) {
|
|
|
28
29
|
|
|
29
30
|
return typeof disabledKey.value === 'function'
|
|
30
31
|
? disabledKey.value(option)
|
|
31
|
-
: option
|
|
32
|
+
: get(option, disabledKey.value)
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
const getOptionGrouped = (option: string | Option) => {
|
|
@@ -16,7 +16,7 @@ export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
|
16
16
|
|
|
17
17
|
const alertHeaderEl =
|
|
18
18
|
element.getElementsByClassName('vv-alert__header')?.[0]
|
|
19
|
-
const
|
|
19
|
+
const closeButtonEl = element.getElementsByClassName('vv-alert__close')?.[0]
|
|
20
20
|
const alertContentEl =
|
|
21
21
|
element.getElementsByClassName('vv-alert__content')?.[0]
|
|
22
22
|
const alertFooterEl =
|
|
@@ -32,14 +32,18 @@ export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
|
32
32
|
// dismissable
|
|
33
33
|
if (args.dismissable) {
|
|
34
34
|
expect(element).toHaveClass('vv-alert--dismissable')
|
|
35
|
-
expect(
|
|
35
|
+
expect(closeButtonEl).not.toBeUndefined()
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// autoclose
|
|
39
39
|
if (args.autoClose) {
|
|
40
40
|
expect(element).toHaveClass('vv-alert--auto-close')
|
|
41
|
-
expect(
|
|
42
|
-
expect(
|
|
41
|
+
expect(closeButtonEl).not.toBeUndefined()
|
|
42
|
+
expect(closeButtonEl.firstChild).toHaveClass('vv-alert__close-mask')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!args.autoClose && !args.dismissable) {
|
|
46
|
+
expect(closeButtonEl).toBeUndefined()
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
// icon
|
|
@@ -19,7 +19,28 @@ export const defaultArgs = {
|
|
|
19
19
|
...propsToObject(VvComboboxProps),
|
|
20
20
|
name: 'vv-combobox',
|
|
21
21
|
maxValues: undefined,
|
|
22
|
-
options: [
|
|
22
|
+
options: [
|
|
23
|
+
'Option 1',
|
|
24
|
+
'Option 2',
|
|
25
|
+
'Option 3',
|
|
26
|
+
'Option 4',
|
|
27
|
+
'Option 5',
|
|
28
|
+
'Option 6',
|
|
29
|
+
'Option 7',
|
|
30
|
+
'Option 8',
|
|
31
|
+
'Option 9',
|
|
32
|
+
'Option 10',
|
|
33
|
+
'Option 11',
|
|
34
|
+
'Option 12',
|
|
35
|
+
'Option 13',
|
|
36
|
+
'Option 14',
|
|
37
|
+
'Option 15',
|
|
38
|
+
'Option 16',
|
|
39
|
+
'Option 17',
|
|
40
|
+
'Option 18',
|
|
41
|
+
'Option 19',
|
|
42
|
+
'Option 20',
|
|
43
|
+
],
|
|
23
44
|
placeholder: 'Select an option',
|
|
24
45
|
label: 'Combobox label',
|
|
25
46
|
}
|
|
@@ -2,7 +2,6 @@ import type { PlayAttributes } from '@/test/types'
|
|
|
2
2
|
import { expect } from '@/test/expect'
|
|
3
3
|
import { within } from '@storybook/testing-library'
|
|
4
4
|
import { sleep } from '@/test/sleep'
|
|
5
|
-
import { getOptionValue } from '@/test/options'
|
|
6
5
|
import { defaultTest as selectDefaultTest } from '@/stories/Select/Select.test'
|
|
7
6
|
|
|
8
7
|
export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
@@ -49,11 +48,12 @@ export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
|
49
48
|
// select first value
|
|
50
49
|
await expect(dropdownFirstItem).toBeClicked()
|
|
51
50
|
await sleep()
|
|
51
|
+
|
|
52
|
+
const { getOptionValue } = useOptions(args)
|
|
53
|
+
|
|
52
54
|
const firstValue = getOptionValue(
|
|
53
|
-
args.options[0].options
|
|
54
|
-
0,
|
|
55
|
+
args.options[0].options?.[0] ?? args.options[0],
|
|
55
56
|
)
|
|
56
|
-
|
|
57
57
|
// in grouped options the first element is not selectable
|
|
58
58
|
if (args.multiple) {
|
|
59
59
|
await expect(JSON.parse(value.innerHTML)).toEqual([firstValue])
|
|
@@ -66,8 +66,7 @@ export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
|
66
66
|
await expect(dropdownSecondItem).toBeClicked()
|
|
67
67
|
await sleep()
|
|
68
68
|
const secondValue = getOptionValue(
|
|
69
|
-
args.options[0].options
|
|
70
|
-
1,
|
|
69
|
+
args.options[0].options?.[1] ?? args.options[1],
|
|
71
70
|
)
|
|
72
71
|
if (args.multiple) {
|
|
73
72
|
await expect(JSON.parse(value.innerHTML)).toEqual([
|
|
@@ -76,3 +76,21 @@ export const GroupedOptions: Story = {
|
|
|
76
76
|
],
|
|
77
77
|
},
|
|
78
78
|
}
|
|
79
|
+
|
|
80
|
+
export const DotPathOptions: Story = {
|
|
81
|
+
...Default,
|
|
82
|
+
args: {
|
|
83
|
+
...Default.args,
|
|
84
|
+
valueKey: 'value.val',
|
|
85
|
+
labelKey: 'label.en',
|
|
86
|
+
options: [
|
|
87
|
+
{ value: { val: 'first' }, label: { it: 'Primo', en: 'First' } },
|
|
88
|
+
{
|
|
89
|
+
value: { val: 'second' },
|
|
90
|
+
label: { it: 'Secondo', en: 'Second' },
|
|
91
|
+
},
|
|
92
|
+
{ value: { val: 'third' }, label: { it: 'Terzo', en: 'Third' } },
|
|
93
|
+
{ value: { val: 'fourth' }, label: { it: 'Quarto', en: 'Fourth' } },
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
}
|
|
@@ -2,7 +2,6 @@ import type { PlayAttributes } from '@/test/types'
|
|
|
2
2
|
import { within } from '@storybook/testing-library'
|
|
3
3
|
import { expect } from '@/test/expect'
|
|
4
4
|
import { sleep } from '@/test/sleep'
|
|
5
|
-
import { getOptionValue } from '@/test/options'
|
|
6
5
|
|
|
7
6
|
export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
8
7
|
const element = (await within(canvasElement).findByTestId(
|
|
@@ -16,6 +15,8 @@ export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
|
16
15
|
)[0] as HTMLSelectElement
|
|
17
16
|
const hint = element.getElementsByClassName('vv-select__hint')[0]
|
|
18
17
|
|
|
18
|
+
const { getOptionValue } = useOptions(args)
|
|
19
|
+
|
|
19
20
|
if (
|
|
20
21
|
!args.invalid &&
|
|
21
22
|
!args.disabled &&
|
|
@@ -25,8 +26,7 @@ export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
|
25
26
|
) {
|
|
26
27
|
// select first value
|
|
27
28
|
const firstValue = getOptionValue(
|
|
28
|
-
args.options[0].options
|
|
29
|
-
0,
|
|
29
|
+
args.options[0].options?.[0] ?? args.options[0],
|
|
30
30
|
)
|
|
31
31
|
select.value = firstValue
|
|
32
32
|
select.dispatchEvent(new Event('change'))
|
|
@@ -18,7 +18,9 @@ export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// check if tooltip is visible after focus
|
|
21
|
-
await parentElement.focus(
|
|
21
|
+
await parentElement.focus({
|
|
22
|
+
preventScroll: true,
|
|
23
|
+
})
|
|
22
24
|
await sleep(1200)
|
|
23
25
|
await expect(window.getComputedStyle(element)).toHaveProperty(
|
|
24
26
|
'opacity',
|