@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.
Files changed (43) hide show
  1. package/auto-imports.d.ts +1 -0
  2. package/dist/components/VvAlert/VvAlert.es.js +27 -18
  3. package/dist/components/VvAlert/VvAlert.umd.js +1 -1
  4. package/dist/components/VvAlert/VvAlert.vue.d.ts +4 -0
  5. package/dist/components/VvAlertGroup/VvAlertGroup.es.js +27 -18
  6. package/dist/components/VvAlertGroup/VvAlertGroup.umd.js +1 -1
  7. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.es.js +4 -3
  8. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
  9. package/dist/components/VvCombobox/VvCombobox.es.js +555 -106
  10. package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
  11. package/dist/components/VvCombobox/VvCombobox.vue.d.ts +3 -0
  12. package/dist/components/VvCombobox/index.d.ts +1 -0
  13. package/dist/components/VvDropdown/VvDropdown.es.js +56 -28
  14. package/dist/components/VvDropdown/VvDropdown.umd.js +1 -1
  15. package/dist/components/VvDropdown/VvDropdown.vue.d.ts +11 -2
  16. package/dist/components/VvDropdown/index.d.ts +7 -1
  17. package/dist/components/VvRadioGroup/VvRadioGroup.es.js +4 -3
  18. package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
  19. package/dist/components/VvSelect/VvSelect.es.js +4 -3
  20. package/dist/components/VvSelect/VvSelect.umd.js +1 -1
  21. package/dist/components/index.es.js +110 -58
  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/stories/Alert/Alert.settings.d.ts +10 -0
  26. package/dist/stories/Combobox/ComboboxOptions.stories.d.ts +1 -0
  27. package/package.json +37 -33
  28. package/src/assets/icons/detailed.json +1 -1
  29. package/src/assets/icons/normal.json +1 -1
  30. package/src/assets/icons/simple.json +1 -1
  31. package/src/components/VvAlert/VvAlert.vue +29 -11
  32. package/src/components/VvCombobox/VvCombobox.vue +48 -26
  33. package/src/components/VvCombobox/index.ts +1 -0
  34. package/src/components/VvDropdown/VvDropdown.vue +59 -26
  35. package/src/components/VvDropdown/index.ts +8 -2
  36. package/src/composables/useOptions.ts +4 -3
  37. package/src/stories/Alert/Alert.settings.ts +10 -0
  38. package/src/stories/Alert/Alert.test.ts +8 -4
  39. package/src/stories/Combobox/Combobox.settings.ts +22 -1
  40. package/src/stories/Combobox/Combobox.test.ts +5 -6
  41. package/src/stories/Combobox/ComboboxOptions.stories.ts +18 -0
  42. package/src/stories/Select/Select.test.ts +3 -3
  43. 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 class="vv-alert__header">
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
- {{ title }}
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
- <button
32
- v-if="dismissable || autoClose"
33
- class="vv-alert__close"
34
- type="button"
35
- :aria-label="closeLabel"
36
- @click.stop="close"
37
- >
38
- <div class="vv-alert__close-mask"></div>
39
- </button>
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: { VvDropdown, VvDropdownOption, VvDropdownOptgroup },
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: props.modifiers,
301
- options: props.options,
302
- labelKey: props.labelKey,
303
- valueKey: props.valueKey,
304
- icon: props.icon,
305
- iconPosition: props.iconPosition,
306
- floating: props.floating,
307
- unselectable: props.unselectable,
308
- multiple: props.multiple,
309
- label: props.label,
310
- placeholder: props.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: props.placement,
318
- strategy: props.strategy,
319
- transitionName: props.transitionName,
320
- offset: props.offset,
321
- shift: props.shift,
322
- flip: props.flip,
323
- autoPlacement: props.autoPlacement,
324
- arrow: props.arrow,
325
- autofocusFirst: searchable.value ? false : props.autofocusFirst,
326
- triggerWidth: props.triggerWidth,
327
- modifiers: props.dropdownModifiers,
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 v-if="$slots['dropdown::after']" #after>
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>
@@ -132,6 +132,7 @@ export const VvComboboxProps = {
132
132
  */
133
133
  dropdownModifiers: {
134
134
  type: [String, Array] as PropType<string | string[]>,
135
+ default: 'mobile',
135
136
  },
136
137
  /**
137
138
  * Open dropdown on focus
@@ -43,7 +43,7 @@
43
43
 
44
44
  // template elements
45
45
  const localReferenceEl = ref<HTMLElement | null>(null)
46
- const floatingEl: Ref<HTMLElement | null> = ref(null)
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
- position: strategy.value,
143
- top: `${y.value ?? 0}px`,
144
- left: `${x.value ?? 0}px`,
145
- maxWidth: maxWidth.value,
146
- maxHeight: maxHeight.value,
147
- width:
148
- props.triggerWidth && referenceEl.value
149
- ? `${referenceEl.value.offsetWidth}px`
150
- : undefined,
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
- if (
338
- expanded.value &&
339
- focused.value &&
340
- e.target !== document.activeElement
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, ModifiersProps } from '../../props'
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[labelKey.value],
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[valueKey.value]
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[disabledKey.value]
32
+ : get(option, disabledKey.value)
32
33
  }
33
34
 
34
35
  const getOptionGrouped = (option: string | Option) => {
@@ -87,6 +87,16 @@ export const argTypes = {
87
87
  },
88
88
  },
89
89
  },
90
+ close: {
91
+ control: {
92
+ type: 'text',
93
+ },
94
+ table: {
95
+ type: {
96
+ summary: 'html',
97
+ },
98
+ },
99
+ },
90
100
  default: {
91
101
  control: {
92
102
  type: 'text',
@@ -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 closeButton = alertHeaderEl?.lastChild as HTMLElement
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(closeButton).toHaveClass('vv-alert__close')
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(closeButton).toHaveClass('vv-alert__close')
42
- expect(closeButton.firstChild).toHaveClass('vv-alert__close-mask')
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: ['Option 1', 'Option 2', 'Option 3'],
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 ? args.options[0] : args,
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 ? args.options[0] : args,
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 ? args.options[0] : args,
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',