@nuvia-ui/components 4.0.1
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/package.json +27 -0
- package/src/ds-accordion/ds-accordion-item.js +288 -0
- package/src/ds-accordion/ds-accordion-item.stories.js +82 -0
- package/src/ds-accordion/ds-accordion.a11y.test.js +92 -0
- package/src/ds-accordion/ds-accordion.js +68 -0
- package/src/ds-accordion/ds-accordion.stories.js +118 -0
- package/src/ds-accordion/ds-accordion.test.js +146 -0
- package/src/ds-accordion/index.js +2 -0
- package/src/ds-action-bar/ds-action-bar.js +116 -0
- package/src/ds-action-bar/ds-action-bar.stories.js +86 -0
- package/src/ds-action-bar/ds-action-bar.test.js +64 -0
- package/src/ds-action-bar/index.js +1 -0
- package/src/ds-alert/ds-alert.a11y.test.js +151 -0
- package/src/ds-alert/ds-alert.js +223 -0
- package/src/ds-alert/ds-alert.mdx +142 -0
- package/src/ds-alert/ds-alert.stories.js +166 -0
- package/src/ds-alert/ds-alert.test.js +256 -0
- package/src/ds-alert/index.js +1 -0
- package/src/ds-avatar/ds-avatar.a11y.test.js +45 -0
- package/src/ds-avatar/ds-avatar.js +216 -0
- package/src/ds-avatar/ds-avatar.stories.js +120 -0
- package/src/ds-avatar/ds-avatar.test.js +83 -0
- package/src/ds-avatar/index.js +1 -0
- package/src/ds-avatar-extended/ds-avatar-extended.a11y.test.js +29 -0
- package/src/ds-avatar-extended/ds-avatar-extended.js +108 -0
- package/src/ds-avatar-extended/ds-avatar-extended.stories.js +93 -0
- package/src/ds-avatar-extended/ds-avatar-extended.test.js +66 -0
- package/src/ds-avatar-extended/index.js +1 -0
- package/src/ds-banner/ds-banner.a11y.test.js +51 -0
- package/src/ds-banner/ds-banner.js +233 -0
- package/src/ds-banner/ds-banner.stories.js +185 -0
- package/src/ds-banner/ds-banner.test.js +116 -0
- package/src/ds-banner/index.js +1 -0
- package/src/ds-breadcrumb-item/ds-breadcrumb-item.js +135 -0
- package/src/ds-breadcrumb-item/ds-breadcrumb-item.stories.js +49 -0
- package/src/ds-breadcrumb-item/ds-breadcrumb-item.test.js +55 -0
- package/src/ds-breadcrumbs/ds-breadcrumbs.js +194 -0
- package/src/ds-breadcrumbs/ds-breadcrumbs.stories.js +54 -0
- package/src/ds-breadcrumbs/ds-breadcrumbs.test.js +33 -0
- package/src/ds-button/ds-button.a11y.test.js +49 -0
- package/src/ds-button/ds-button.js +205 -0
- package/src/ds-button/ds-button.mdx +141 -0
- package/src/ds-button/ds-button.stories.js +152 -0
- package/src/ds-button/ds-button.test.js +62 -0
- package/src/ds-button/index.js +1 -0
- package/src/ds-button-group/ds-button-group.js +82 -0
- package/src/ds-button-group/ds-button-group.mdx +39 -0
- package/src/ds-button-group/ds-button-group.stories.js +47 -0
- package/src/ds-button-group/ds-button-group.test.js +47 -0
- package/src/ds-button-group/index.js +1 -0
- package/src/ds-checkbox/ds-checkbox.a11y.test.js +79 -0
- package/src/ds-checkbox/ds-checkbox.js +271 -0
- package/src/ds-checkbox/ds-checkbox.stories.js +77 -0
- package/src/ds-checkbox/ds-checkbox.test.js +191 -0
- package/src/ds-checkbox/index.js +1 -0
- package/src/ds-checkbox-group/ds-checkbox-group.a11y.test.js +146 -0
- package/src/ds-checkbox-group/ds-checkbox-group.js +235 -0
- package/src/ds-checkbox-group/ds-checkbox-group.stories.js +210 -0
- package/src/ds-checkbox-group/ds-checkbox-group.test.js +150 -0
- package/src/ds-checkbox-group/index.js +1 -0
- package/src/ds-dialog/ds-dialog.js +466 -0
- package/src/ds-dialog/ds-dialog.stories.js +274 -0
- package/src/ds-dialog/ds-dialog.test.js +441 -0
- package/src/ds-dialog/index.js +1 -0
- package/src/ds-dropdown/ds-dropdown.a11y.test.js +80 -0
- package/src/ds-dropdown/ds-dropdown.js +891 -0
- package/src/ds-dropdown/ds-dropdown.stories.js +259 -0
- package/src/ds-dropdown/ds-dropdown.test.js +268 -0
- package/src/ds-dropdown/index.js +1 -0
- package/src/ds-dropdown-group/ds-dropdown-group.js +55 -0
- package/src/ds-dropdown-panel/ds-dropdown-panel.js +34 -0
- package/src/ds-file-uploaded/ds-file-uploaded.a11y.test.js +40 -0
- package/src/ds-file-uploaded/ds-file-uploaded.js +135 -0
- package/src/ds-file-uploaded/ds-file-uploaded.mdx +33 -0
- package/src/ds-file-uploaded/ds-file-uploaded.stories.js +81 -0
- package/src/ds-file-uploaded/ds-file-uploaded.test.js +85 -0
- package/src/ds-file-uploader/ds-file-uploader.a11y.test.js +61 -0
- package/src/ds-file-uploader/ds-file-uploader.js +442 -0
- package/src/ds-file-uploader/ds-file-uploader.mdx +44 -0
- package/src/ds-file-uploader/ds-file-uploader.stories.js +76 -0
- package/src/ds-file-uploader/ds-file-uploader.test.js +142 -0
- package/src/ds-header/ds-header.a11y.test.js +38 -0
- package/src/ds-header/ds-header.js +149 -0
- package/src/ds-header/ds-header.stories.js +63 -0
- package/src/ds-header/ds-header.test.js +52 -0
- package/src/ds-header/index.js +1 -0
- package/src/ds-header-nav/ds-header-nav.a11y.test.js +69 -0
- package/src/ds-header-nav/ds-header-nav.js +114 -0
- package/src/ds-header-nav/ds-header-nav.stories.js +17 -0
- package/src/ds-header-nav/ds-header-nav.test.js +93 -0
- package/src/ds-header-nav-item/ds-header-nav-item.a11y.test.js +71 -0
- package/src/ds-header-nav-item/ds-header-nav-item.js +124 -0
- package/src/ds-header-nav-item/ds-header-nav-item.stories.js +43 -0
- package/src/ds-header-nav-item/ds-header-nav-item.test.js +61 -0
- package/src/ds-icon/ds-icon.a11y.test.js +49 -0
- package/src/ds-icon/ds-icon.js +75 -0
- package/src/ds-icon/ds-icon.mdx +36 -0
- package/src/ds-icon/ds-icon.stories.js +88 -0
- package/src/ds-icon/ds-icon.test.js +97 -0
- package/src/ds-icon/index.js +1 -0
- package/src/ds-icon-button/ds-icon-button.a11y.test.js +55 -0
- package/src/ds-icon-button/ds-icon-button.js +224 -0
- package/src/ds-icon-button/ds-icon-button.mdx +131 -0
- package/src/ds-icon-button/ds-icon-button.stories.js +128 -0
- package/src/ds-icon-button/ds-icon-button.test.js +90 -0
- package/src/ds-icon-button/index.js +1 -0
- package/src/ds-input/ds-input.a11y.test.js +145 -0
- package/src/ds-input/ds-input.js +645 -0
- package/src/ds-input/ds-input.mdx +251 -0
- package/src/ds-input/ds-input.stories.js +298 -0
- package/src/ds-input/ds-input.test.js +792 -0
- package/src/ds-input/index.js +1 -0
- package/src/ds-link/ds-link.js +111 -0
- package/src/ds-link/ds-link.stories.js +56 -0
- package/src/ds-link/ds-link.test.js +74 -0
- package/src/ds-list-item/ds-list-item.a11y.test.js +39 -0
- package/src/ds-list-item/ds-list-item.js +292 -0
- package/src/ds-list-item/ds-list-item.stories.js +101 -0
- package/src/ds-list-item/ds-list-item.test.js +63 -0
- package/src/ds-menu/ds-menu.js +30 -0
- package/src/ds-menu/ds-menu.stories.js +120 -0
- package/src/ds-menu/ds-menu.test.js +123 -0
- package/src/ds-menu-group/ds-menu-group.js +101 -0
- package/src/ds-menu-group/ds-menu-group.stories.js +99 -0
- package/src/ds-nav-item/ds-nav-item.a11y.test.js +91 -0
- package/src/ds-nav-item/ds-nav-item.js +307 -0
- package/src/ds-nav-item/ds-nav-item.stories.js +99 -0
- package/src/ds-nav-item/ds-nav-item.test.js +169 -0
- package/src/ds-nav-item/index.js +1 -0
- package/src/ds-nav-vertical/ds-nav-vertical.a11y.test.js +69 -0
- package/src/ds-nav-vertical/ds-nav-vertical.js +173 -0
- package/src/ds-nav-vertical/ds-nav-vertical.stories.js +124 -0
- package/src/ds-nav-vertical/ds-nav-vertical.test.js +176 -0
- package/src/ds-nav-vertical/index.js +1 -0
- package/src/ds-pagination/ds-pagination.a11y.test.js +50 -0
- package/src/ds-pagination/ds-pagination.js +232 -0
- package/src/ds-pagination/ds-pagination.stories.js +63 -0
- package/src/ds-pagination/ds-pagination.test.js +141 -0
- package/src/ds-pagination/index.js +1 -0
- package/src/ds-progress-bar/ds-progress-bar.a11y.test.js +25 -0
- package/src/ds-progress-bar/ds-progress-bar.js +81 -0
- package/src/ds-progress-bar/ds-progress-bar.stories.js +69 -0
- package/src/ds-progress-bar/ds-progress-bar.test.js +60 -0
- package/src/ds-radio/ds-radio.a11y.test.js +69 -0
- package/src/ds-radio/ds-radio.js +240 -0
- package/src/ds-radio/ds-radio.stories.js +102 -0
- package/src/ds-radio/ds-radio.test.js +114 -0
- package/src/ds-radio/index.js +1 -0
- package/src/ds-radio-group/ds-radio-group.a11y.test.js +164 -0
- package/src/ds-radio-group/ds-radio-group.js +257 -0
- package/src/ds-radio-group/ds-radio-group.stories.js +247 -0
- package/src/ds-radio-group/ds-radio-group.test.js +194 -0
- package/src/ds-radio-group/index.js +1 -0
- package/src/ds-rich-list/ds-rich-list.js +246 -0
- package/src/ds-rich-list/ds-rich-list.stories.js +368 -0
- package/src/ds-rich-list/ds-rich-list.test.js +293 -0
- package/src/ds-rich-list-item/ds-rich-list-item.js +579 -0
- package/src/ds-rich-list-item/ds-rich-list-item.stories.js +197 -0
- package/src/ds-rich-list-item/ds-rich-list-item.test.js +434 -0
- package/src/ds-slider/ds-slider.js +399 -0
- package/src/ds-slider/ds-slider.stories.js +107 -0
- package/src/ds-slider/ds-slider.test.js +308 -0
- package/src/ds-spinner/ds-spinner.js +173 -0
- package/src/ds-spinner/ds-spinner.stories.js +52 -0
- package/src/ds-spinner/ds-spinner.test.js +50 -0
- package/src/ds-status-border/ds-status-border.js +88 -0
- package/src/ds-status-border/ds-status-border.stories.js +242 -0
- package/src/ds-status-border/ds-status-border.test.js +168 -0
- package/src/ds-stepper/ds-stepper.a11y.test.js +198 -0
- package/src/ds-stepper/ds-stepper.js +207 -0
- package/src/ds-stepper/ds-stepper.stories.js +530 -0
- package/src/ds-stepper/ds-stepper.test.js +311 -0
- package/src/ds-stepper-item/ds-stepper-item.js +485 -0
- package/src/ds-stepper-item/ds-stepper-item.stories.js +288 -0
- package/src/ds-switch/ds-switch.js +348 -0
- package/src/ds-switch/ds-switch.stories.js +145 -0
- package/src/ds-switch/ds-switch.test.js +226 -0
- package/src/ds-switch/index.js +1 -0
- package/src/ds-tab-item/ds-tab-item.js +341 -0
- package/src/ds-tab-item/ds-tab-item.stories.js +69 -0
- package/src/ds-tabs/ds-tab-panel.js +48 -0
- package/src/ds-tabs/ds-tabs.a11y.test.js +56 -0
- package/src/ds-tabs/ds-tabs.js +180 -0
- package/src/ds-tabs/ds-tabs.stories.js +152 -0
- package/src/ds-tabs/ds-tabs.test.js +306 -0
- package/src/ds-tabs/index.js +3 -0
- package/src/ds-tag-action/ds-tag-action.a11y.test.js +32 -0
- package/src/ds-tag-action/ds-tag-action.js +185 -0
- package/src/ds-tag-action/ds-tag-action.stories.js +55 -0
- package/src/ds-tag-action/ds-tag-action.test.js +44 -0
- package/src/ds-tag-removable/ds-tag-removable.a11y.test.js +24 -0
- package/src/ds-tag-removable/ds-tag-removable.js +146 -0
- package/src/ds-tag-removable/ds-tag-removable.stories.js +52 -0
- package/src/ds-tag-removable/ds-tag-removable.test.js +46 -0
- package/src/ds-tag-status/ds-tag-status.a11y.test.js +93 -0
- package/src/ds-tag-status/ds-tag-status.js +164 -0
- package/src/ds-tag-status/ds-tag-status.stories.js +200 -0
- package/src/ds-tag-status/ds-tag-status.test.js +140 -0
- package/src/ds-tag-status/index.js +1 -0
- package/src/ds-textarea/ds-textarea-clearable.test.js +89 -0
- package/src/ds-textarea/ds-textarea.a11y.test.js +66 -0
- package/src/ds-textarea/ds-textarea.js +505 -0
- package/src/ds-textarea/ds-textarea.stories.js +335 -0
- package/src/ds-textarea/ds-textarea.test.js +218 -0
- package/src/ds-textarea/index.js +1 -0
- package/src/ds-thumbnail/ds-thumbnail.js +207 -0
- package/src/ds-thumbnail/ds-thumbnail.stories.js +217 -0
- package/src/ds-thumbnail/ds-thumbnail.test.js +220 -0
- package/src/ds-toast/ds-toast-provider.js +110 -0
- package/src/ds-toast/ds-toast.a11y.test.js +34 -0
- package/src/ds-toast/ds-toast.js +243 -0
- package/src/ds-toast/ds-toast.stories.js +143 -0
- package/src/ds-toast/ds-toast.test.js +93 -0
- package/src/ds-toast/index.js +2 -0
- package/src/ds-tooltip/ds-tooltip.a11y.test.js +110 -0
- package/src/ds-tooltip/ds-tooltip.js +217 -0
- package/src/ds-tooltip/ds-tooltip.mdx +75 -0
- package/src/ds-tooltip/ds-tooltip.stories.js +72 -0
- package/src/ds-tooltip/ds-tooltip.test.js +191 -0
- package/src/ds-tooltip/index.js +1 -0
- package/src/ds-tooltip/positioner.js +117 -0
- package/src/index.js +50 -0
- package/src/mixins/field-label.mixin.js +113 -0
- package/src/mixins/field-message.mixin.js +66 -0
- package/src/token-provider/index.js +1 -0
- package/src/token-provider/token-provider.a11y.test.js +44 -0
- package/src/token-provider/token-provider.js +85 -0
- package/src/token-provider/token-provider.stories.js +105 -0
- package/src/token-provider/token-provider.test.js +134 -0
- package/src/utils/number-input.utils.js +42 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { html, nothing } from 'lit';
|
|
2
|
+
import './ds-dropdown.js';
|
|
3
|
+
import '../ds-list-item/ds-list-item.js';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Components/Dropdown',
|
|
7
|
+
component: 'ds-dropdown',
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
argTypes: {
|
|
10
|
+
label: { control: 'text' },
|
|
11
|
+
info: { control: 'text' },
|
|
12
|
+
placeholder: { control: 'text' },
|
|
13
|
+
value: { control: 'text' },
|
|
14
|
+
helper: { control: 'text' },
|
|
15
|
+
validationStatus: {
|
|
16
|
+
control: 'select',
|
|
17
|
+
options: ['', 'error', 'success']
|
|
18
|
+
},
|
|
19
|
+
validationMessage: { control: 'text' },
|
|
20
|
+
disabled: { control: 'boolean' },
|
|
21
|
+
required: { control: 'boolean' },
|
|
22
|
+
clearable: { control: 'boolean' },
|
|
23
|
+
multiple: { control: 'boolean' },
|
|
24
|
+
selectAll: { control: 'boolean' },
|
|
25
|
+
labelPosition: {
|
|
26
|
+
control: 'select',
|
|
27
|
+
options: ['top', 'inline-start']
|
|
28
|
+
},
|
|
29
|
+
labelWidth: { control: 'text' }
|
|
30
|
+
},
|
|
31
|
+
args: {
|
|
32
|
+
label: 'Country',
|
|
33
|
+
info: '',
|
|
34
|
+
placeholder: 'Select a country...',
|
|
35
|
+
value: '',
|
|
36
|
+
helper: '',
|
|
37
|
+
validationStatus: '',
|
|
38
|
+
validationMessage: '',
|
|
39
|
+
disabled: false,
|
|
40
|
+
required: false,
|
|
41
|
+
clearable: false,
|
|
42
|
+
multiple: false,
|
|
43
|
+
selectAll: false,
|
|
44
|
+
labelPosition: 'top',
|
|
45
|
+
labelWidth: ''
|
|
46
|
+
},
|
|
47
|
+
decorators: [
|
|
48
|
+
(story) => html`
|
|
49
|
+
<div style="min-height: 400px; padding: 20px;">
|
|
50
|
+
${story()}
|
|
51
|
+
</div>
|
|
52
|
+
`
|
|
53
|
+
]
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const Template = (args) => html`
|
|
57
|
+
<ds-dropdown
|
|
58
|
+
label="${args.label}"
|
|
59
|
+
info="${args.info || nothing}"
|
|
60
|
+
placeholder="${args.placeholder}"
|
|
61
|
+
value="${args.value}"
|
|
62
|
+
helper="${args.helper || nothing}"
|
|
63
|
+
validation-status="${args.validationStatus || nothing}"
|
|
64
|
+
validation-message="${args.validationMessage || nothing}"
|
|
65
|
+
?disabled="${args.disabled}"
|
|
66
|
+
?required="${args.required}"
|
|
67
|
+
?clearable="${args.clearable}"
|
|
68
|
+
?multiple="${args.multiple}"
|
|
69
|
+
?select-all="${args.selectAll}"
|
|
70
|
+
label-position="${args.labelPosition || nothing}"
|
|
71
|
+
label-width="${args.labelWidth || nothing}"
|
|
72
|
+
>
|
|
73
|
+
<ds-list-item value="pt" label="Portugal"></ds-list-item>
|
|
74
|
+
<ds-list-item value="es" label="Spain"></ds-list-item>
|
|
75
|
+
<ds-list-item value="fr" label="France"></ds-list-item>
|
|
76
|
+
<ds-list-item value="de" label="Germany"></ds-list-item>
|
|
77
|
+
<ds-list-item value="it" label="Italy"></ds-list-item>
|
|
78
|
+
</ds-dropdown>
|
|
79
|
+
`;
|
|
80
|
+
|
|
81
|
+
export const Default = {
|
|
82
|
+
render: Template
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const InlineLabel = {
|
|
86
|
+
render: Template,
|
|
87
|
+
args: {
|
|
88
|
+
label: 'Select Region',
|
|
89
|
+
labelPosition: 'inline-start',
|
|
90
|
+
labelWidth: '150px',
|
|
91
|
+
placeholder: 'Select a region...'
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const MultiSelect = {
|
|
96
|
+
render: Template,
|
|
97
|
+
args: {
|
|
98
|
+
label: 'Countries (Multi)',
|
|
99
|
+
multiple: true,
|
|
100
|
+
placeholder: 'Select countries...'
|
|
101
|
+
},
|
|
102
|
+
parameters: {
|
|
103
|
+
docs: {
|
|
104
|
+
description: {
|
|
105
|
+
story: 'Use `multiple` prop to allow selecting multiple options. The component automatically switches to checkbox variants.'
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const SelectAll = {
|
|
112
|
+
render: Template,
|
|
113
|
+
args: {
|
|
114
|
+
label: 'Countries (Select All)',
|
|
115
|
+
multiple: true,
|
|
116
|
+
selectAll: true,
|
|
117
|
+
placeholder: 'Select countries...'
|
|
118
|
+
},
|
|
119
|
+
parameters: {
|
|
120
|
+
docs: {
|
|
121
|
+
description: {
|
|
122
|
+
story: 'Use `select-all` prop in combination with `multiple` to verify easy bulk selection.'
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const WithValue = {
|
|
129
|
+
args: {
|
|
130
|
+
label: 'Language',
|
|
131
|
+
value: 'en',
|
|
132
|
+
placeholder: 'Select language...'
|
|
133
|
+
},
|
|
134
|
+
render: (args) => html`
|
|
135
|
+
<ds-dropdown
|
|
136
|
+
label="${args.label}"
|
|
137
|
+
value="${args.value}"
|
|
138
|
+
placeholder="${args.placeholder}"
|
|
139
|
+
helper="${args.helper || nothing}"
|
|
140
|
+
validation-status="${args.validationStatus || nothing}"
|
|
141
|
+
validation-message="${args.validationMessage || nothing}"
|
|
142
|
+
?disabled="${args.disabled}"
|
|
143
|
+
?required="${args.required}"
|
|
144
|
+
>
|
|
145
|
+
<ds-list-item value="pt" label="Português"></ds-list-item>
|
|
146
|
+
<ds-list-item value="en" label="English"></ds-list-item>
|
|
147
|
+
<ds-list-item value="es" label="Español"></ds-list-item>
|
|
148
|
+
<ds-list-item value="fr" label="Français"></ds-list-item>
|
|
149
|
+
</ds-dropdown>
|
|
150
|
+
`
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export const WithError = {
|
|
154
|
+
args: {
|
|
155
|
+
label: 'Priority',
|
|
156
|
+
validationStatus: 'error',
|
|
157
|
+
validationMessage: 'Please select a priority',
|
|
158
|
+
required: true
|
|
159
|
+
},
|
|
160
|
+
render: (args) => html`
|
|
161
|
+
<ds-dropdown
|
|
162
|
+
label="${args.label}"
|
|
163
|
+
validation-status="${args.validationStatus}"
|
|
164
|
+
validation-message="${args.validationMessage}"
|
|
165
|
+
helper="${args.helper || nothing}"
|
|
166
|
+
?required="${args.required}"
|
|
167
|
+
?disabled="${args.disabled}"
|
|
168
|
+
>
|
|
169
|
+
<ds-list-item value="low" label="Low"></ds-list-item>
|
|
170
|
+
<ds-list-item value="medium" label="Medium"></ds-list-item>
|
|
171
|
+
<ds-list-item value="high" label="High"></ds-list-item>
|
|
172
|
+
</ds-dropdown>
|
|
173
|
+
`
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export const Disabled = {
|
|
177
|
+
args: {
|
|
178
|
+
label: 'Status',
|
|
179
|
+
value: 'active',
|
|
180
|
+
disabled: true
|
|
181
|
+
},
|
|
182
|
+
render: (args) => html`
|
|
183
|
+
<ds-dropdown
|
|
184
|
+
label="${args.label}"
|
|
185
|
+
value="${args.value}"
|
|
186
|
+
helper="${args.helper || nothing}"
|
|
187
|
+
?disabled="${args.disabled}"
|
|
188
|
+
>
|
|
189
|
+
<ds-list-item value="active" label="Active"></ds-list-item>
|
|
190
|
+
<ds-list-item value="inactive" label="Inactive"></ds-list-item>
|
|
191
|
+
</ds-dropdown>
|
|
192
|
+
`
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export const LargeMultiSelect = {
|
|
196
|
+
args: {
|
|
197
|
+
label: 'Large Selection (60 items)',
|
|
198
|
+
multiple: true,
|
|
199
|
+
selectAll: true,
|
|
200
|
+
placeholder: 'Scroll to see all...'
|
|
201
|
+
},
|
|
202
|
+
render: (args) => html`
|
|
203
|
+
<ds-dropdown
|
|
204
|
+
label="${args.label}"
|
|
205
|
+
info="${args.info || nothing}"
|
|
206
|
+
placeholder="${args.placeholder}"
|
|
207
|
+
value="${args.value}"
|
|
208
|
+
helper="${args.helper || nothing}"
|
|
209
|
+
validation-status="${args.validationStatus || nothing}"
|
|
210
|
+
validation-message="${args.validationMessage || nothing}"
|
|
211
|
+
?disabled="${args.disabled}"
|
|
212
|
+
?required="${args.required}"
|
|
213
|
+
?clearable="${args.clearable}"
|
|
214
|
+
?multiple="${args.multiple}"
|
|
215
|
+
?select-all="${args.selectAll}"
|
|
216
|
+
>
|
|
217
|
+
${Array.from({ length: 60 }).map((_, i) => html`
|
|
218
|
+
<ds-list-item value="item-${i}" label="Option ${i + 1}"></ds-list-item>
|
|
219
|
+
`)}
|
|
220
|
+
</ds-dropdown>
|
|
221
|
+
`
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
export const LargeGrouped = {
|
|
225
|
+
args: {
|
|
226
|
+
label: 'Grouped Large Selection',
|
|
227
|
+
multiple: true,
|
|
228
|
+
selectAll: true,
|
|
229
|
+
placeholder: 'Grouped options...'
|
|
230
|
+
},
|
|
231
|
+
render: (args) => html`
|
|
232
|
+
<ds-dropdown
|
|
233
|
+
label="${args.label}"
|
|
234
|
+
info="${args.info || nothing}"
|
|
235
|
+
placeholder="${args.placeholder}"
|
|
236
|
+
value="${args.value}"
|
|
237
|
+
helper="${args.helper || nothing}"
|
|
238
|
+
validation-status="${args.validationStatus || nothing}"
|
|
239
|
+
validation-message="${args.validationMessage || nothing}"
|
|
240
|
+
?disabled="${args.disabled}"
|
|
241
|
+
?required="${args.required}"
|
|
242
|
+
?clearable="${args.clearable}"
|
|
243
|
+
?multiple="${args.multiple}"
|
|
244
|
+
?select-all="${args.selectAll}"
|
|
245
|
+
>
|
|
246
|
+
<ds-list-item variant="section" label="Primary Options"></ds-list-item>
|
|
247
|
+
${Array.from({ length: 25 }).map((_, i) => html`
|
|
248
|
+
<ds-list-item value="opt-a-${i}" label="Primary ${i + 1}"></ds-list-item>
|
|
249
|
+
`)}
|
|
250
|
+
|
|
251
|
+
<ds-list-item variant="section" label="Secondary Options"></ds-list-item>
|
|
252
|
+
${Array.from({ length: 25 }).map((_, i) => html`
|
|
253
|
+
<ds-list-item value="opt-b-${i}" label="Secondary ${i + 1}"></ds-list-item>
|
|
254
|
+
`)}
|
|
255
|
+
</ds-dropdown>
|
|
256
|
+
`
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
3
|
+
import './ds-dropdown.js';
|
|
4
|
+
|
|
5
|
+
describe('ds-dropdown', () => {
|
|
6
|
+
let container;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
container = document.createElement('div');
|
|
10
|
+
document.body.appendChild(container);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
container.remove();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders with default values', async () => {
|
|
18
|
+
container.innerHTML = '<ds-dropdown></ds-dropdown>';
|
|
19
|
+
const element = container.querySelector('ds-dropdown');
|
|
20
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
21
|
+
|
|
22
|
+
expect(element.label).toBe('');
|
|
23
|
+
expect(element.value).toBe('');
|
|
24
|
+
expect(element.placeholder).toBe('Select...'); // Changed default placeholder
|
|
25
|
+
expect(element.disabled).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('renders label when provided', async () => {
|
|
29
|
+
container.innerHTML = '<ds-dropdown label="Country"></ds-dropdown>';
|
|
30
|
+
const element = container.querySelector('ds-dropdown');
|
|
31
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
32
|
+
|
|
33
|
+
const label = element.shadowRoot.querySelector('label');
|
|
34
|
+
expect(label.textContent).toBe('Country');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('renders placeholder when no value selected', async () => {
|
|
38
|
+
container.innerHTML = '<ds-dropdown placeholder="Choose..."></ds-dropdown>';
|
|
39
|
+
const element = container.querySelector('ds-dropdown');
|
|
40
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
41
|
+
|
|
42
|
+
const valueText = element.shadowRoot.querySelector('.value-text.placeholder');
|
|
43
|
+
expect(valueText.textContent.trim()).toBe('Choose...');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('displays selected value from ds-list-item', async () => {
|
|
47
|
+
container.innerHTML = `
|
|
48
|
+
<ds-dropdown>
|
|
49
|
+
<ds-list-item value="pt" label="Portugal"></ds-list-item>
|
|
50
|
+
<ds-list-item value="es" label="Spain" selected></ds-list-item>
|
|
51
|
+
</ds-dropdown>
|
|
52
|
+
`;
|
|
53
|
+
const element = container.querySelector('ds-dropdown');
|
|
54
|
+
await new Promise(resolve => setTimeout(resolve, 100)); // Wait for slotchange and sync
|
|
55
|
+
|
|
56
|
+
expect(element.value).toBe('es');
|
|
57
|
+
const valueText = element.shadowRoot.querySelector('.value-text');
|
|
58
|
+
expect(valueText.textContent.trim()).toBe('Spain');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('dispatches change event on selection', async () => {
|
|
62
|
+
container.innerHTML = `
|
|
63
|
+
<ds-dropdown>
|
|
64
|
+
<ds-list-item value="pt" label="Portugal"></ds-list-item>
|
|
65
|
+
<ds-list-item value="es" label="Spain"></ds-list-item>
|
|
66
|
+
</ds-dropdown>
|
|
67
|
+
`;
|
|
68
|
+
const element = container.querySelector('ds-dropdown');
|
|
69
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
70
|
+
|
|
71
|
+
const changeSpy = vi.fn();
|
|
72
|
+
element.addEventListener('change', changeSpy);
|
|
73
|
+
|
|
74
|
+
// Simulate clicking an item
|
|
75
|
+
const items = element.shadowRoot.querySelector('slot').assignedElements({ flatten: true });
|
|
76
|
+
const itemToSelect = items.find(el => el.getAttribute('value') === 'pt');
|
|
77
|
+
|
|
78
|
+
// Create a mock event bubbling up from ds-list-item -> ds-menu-group -> dropdown
|
|
79
|
+
// But since logic is in ds-menu-group, we might need to simulate click on item which propagates to group
|
|
80
|
+
|
|
81
|
+
// To properly test integration, we should click the item.
|
|
82
|
+
itemToSelect.click();
|
|
83
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
84
|
+
|
|
85
|
+
expect(changeSpy).toHaveBeenCalledTimes(1);
|
|
86
|
+
expect(changeSpy.mock.calls[0][0].detail.value).toBe('pt');
|
|
87
|
+
expect(element.value).toBe('pt');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('disables trigger when disabled', async () => {
|
|
91
|
+
container.innerHTML = '<ds-dropdown disabled></ds-dropdown>';
|
|
92
|
+
const element = container.querySelector('ds-dropdown');
|
|
93
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
94
|
+
|
|
95
|
+
const trigger = element.shadowRoot.querySelector('.trigger');
|
|
96
|
+
expect(trigger.getAttribute('tabindex')).toBe('-1');
|
|
97
|
+
expect(trigger.classList.contains('disabled')).toBeFalsy(); // Trigger style depends on :host([disabled])
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('shows clear button when clearable and has value', async () => {
|
|
101
|
+
container.innerHTML = `
|
|
102
|
+
<ds-dropdown clearable>
|
|
103
|
+
<ds-list-item value="pt" label="Portugal" selected></ds-list-item>
|
|
104
|
+
</ds-dropdown>
|
|
105
|
+
`;
|
|
106
|
+
const element = container.querySelector('ds-dropdown');
|
|
107
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
108
|
+
|
|
109
|
+
// Should be shown because we have a value
|
|
110
|
+
const clearButton = element.shadowRoot.querySelector('ds-icon-button[icon="close"]');
|
|
111
|
+
expect(clearButton).toBeTruthy();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('clears value when clear button is clicked', async () => {
|
|
115
|
+
container.innerHTML = `
|
|
116
|
+
<ds-dropdown clearable>
|
|
117
|
+
<ds-list-item value="pt" label="Portugal" selected></ds-list-item>
|
|
118
|
+
</ds-dropdown>
|
|
119
|
+
`;
|
|
120
|
+
const element = container.querySelector('ds-dropdown');
|
|
121
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
122
|
+
|
|
123
|
+
const clearButton = element.shadowRoot.querySelector('ds-icon-button[icon="close"]');
|
|
124
|
+
clearButton.click();
|
|
125
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
126
|
+
|
|
127
|
+
expect(element.value).toBe('');
|
|
128
|
+
const valueText = element.shadowRoot.querySelector('.value-text.placeholder');
|
|
129
|
+
expect(valueText).toBeTruthy();
|
|
130
|
+
|
|
131
|
+
// Validate that the item is no longer selected
|
|
132
|
+
const items = element.shadowRoot.querySelector('slot').assignedElements({ flatten: true });
|
|
133
|
+
expect(items[0].hasAttribute('selected')).toBe(false);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('shows indeterminate state on select all when partially selected', async () => {
|
|
137
|
+
container.innerHTML = `
|
|
138
|
+
<ds-dropdown multiple select-all>
|
|
139
|
+
<ds-list-item value="1" label="Option 1"></ds-list-item>
|
|
140
|
+
<ds-list-item value="2" label="Option 2"></ds-list-item>
|
|
141
|
+
</ds-dropdown>
|
|
142
|
+
`;
|
|
143
|
+
const element = container.querySelector('ds-dropdown');
|
|
144
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
145
|
+
|
|
146
|
+
// Select one item
|
|
147
|
+
element.value = "1";
|
|
148
|
+
await element.updateComplete;
|
|
149
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
150
|
+
|
|
151
|
+
// Open to check visual state
|
|
152
|
+
const trigger = element.shadowRoot.querySelector('.trigger');
|
|
153
|
+
trigger.click();
|
|
154
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
155
|
+
|
|
156
|
+
// Find Select All item
|
|
157
|
+
const selectAllItem = element.shadowRoot.querySelector('ds-list-item[label="Select All"]');
|
|
158
|
+
expect(selectAllItem).toBeTruthy();
|
|
159
|
+
expect(selectAllItem.hasAttribute('indeterminate')).toBe(true);
|
|
160
|
+
expect(selectAllItem.hasAttribute('selected')).toBe(false);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
it('initializes with provided value', async () => {
|
|
165
|
+
container.innerHTML = `
|
|
166
|
+
<ds-dropdown value="es">
|
|
167
|
+
<ds-list-item value="pt" label="Portugal"></ds-list-item>
|
|
168
|
+
<ds-list-item value="es" label="Spain"></ds-list-item>
|
|
169
|
+
</ds-dropdown>
|
|
170
|
+
`;
|
|
171
|
+
const element = container.querySelector('ds-dropdown');
|
|
172
|
+
await new Promise(resolve => setTimeout(resolve, 100)); // Wait for slotchange and sync logic
|
|
173
|
+
|
|
174
|
+
const valueText = element.shadowRoot.querySelector('.value-text');
|
|
175
|
+
expect(valueText.textContent.trim()).toBe('Spain');
|
|
176
|
+
|
|
177
|
+
// Verify item selected state
|
|
178
|
+
const items = element.shadowRoot.querySelector('slot').assignedElements({ flatten: true });
|
|
179
|
+
expect(items[1].hasAttribute('selected')).toBe(true);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('updates display value when item selected via click', async () => {
|
|
183
|
+
container.innerHTML = `
|
|
184
|
+
<ds-dropdown>
|
|
185
|
+
<ds-list-item value="pt" label="Portugal"></ds-list-item>
|
|
186
|
+
<ds-list-item value="es" label="Spain"></ds-list-item>
|
|
187
|
+
</ds-dropdown>
|
|
188
|
+
`;
|
|
189
|
+
const element = container.querySelector('ds-dropdown');
|
|
190
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
191
|
+
|
|
192
|
+
const items = element.shadowRoot.querySelector('slot').assignedElements({ flatten: true });
|
|
193
|
+
items[0].click(); // Select Portugal
|
|
194
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
195
|
+
|
|
196
|
+
expect(element.value).toBe('pt');
|
|
197
|
+
const valueText = element.shadowRoot.querySelector('.value-text');
|
|
198
|
+
expect(valueText.textContent.trim()).toBe('Portugal');
|
|
199
|
+
expect(valueText.classList.contains('placeholder')).toBe(false);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
it('renders helper text', async () => {
|
|
204
|
+
container.innerHTML = '<ds-dropdown helper="Select your country"></ds-dropdown>';
|
|
205
|
+
const element = container.querySelector('ds-dropdown');
|
|
206
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
207
|
+
|
|
208
|
+
// Helper just uses base class, no specific modifier unless error
|
|
209
|
+
const message = element.shadowRoot.querySelector('.field-message');
|
|
210
|
+
expect(message.textContent.trim()).toBe('Select your country');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('renders error message and icon', async () => {
|
|
214
|
+
container.innerHTML = `
|
|
215
|
+
<ds-dropdown
|
|
216
|
+
validation-status="error"
|
|
217
|
+
validation-message="This field is required"
|
|
218
|
+
></ds-dropdown>
|
|
219
|
+
`;
|
|
220
|
+
const element = container.querySelector('ds-dropdown');
|
|
221
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
222
|
+
|
|
223
|
+
// Error adds modifier class
|
|
224
|
+
const errorMessage = element.shadowRoot.querySelector('.field-message--error');
|
|
225
|
+
expect(errorMessage).toBeTruthy();
|
|
226
|
+
expect(errorMessage.textContent.trim()).toBe('This field is required');
|
|
227
|
+
|
|
228
|
+
const errorIcon = errorMessage.querySelector('ds-icon[name="warning"]');
|
|
229
|
+
expect(errorIcon).toBeTruthy();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('opens menu on trigger click', async () => {
|
|
233
|
+
container.innerHTML = '<ds-dropdown><ds-list-item label="A"></ds-list-item></ds-dropdown>';
|
|
234
|
+
const element = container.querySelector('ds-dropdown');
|
|
235
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
236
|
+
|
|
237
|
+
const trigger = element.shadowRoot.querySelector('.trigger');
|
|
238
|
+
trigger.click();
|
|
239
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
240
|
+
|
|
241
|
+
expect(element.open).toBe(true);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('opens menu with ArrowDown key on trigger', async () => {
|
|
245
|
+
container.innerHTML = '<ds-dropdown><ds-list-item label="A"></ds-list-item></ds-dropdown>';
|
|
246
|
+
const element = container.querySelector('ds-dropdown');
|
|
247
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
248
|
+
|
|
249
|
+
const trigger = element.shadowRoot.querySelector('.trigger');
|
|
250
|
+
trigger.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
|
|
251
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
252
|
+
|
|
253
|
+
expect(element.open).toBe(true);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it('Closes menu with Escape key within menu interaction', async () => {
|
|
257
|
+
container.innerHTML = '<ds-dropdown open><ds-list-item label="A"></ds-list-item></ds-dropdown>';
|
|
258
|
+
const element = container.querySelector('ds-dropdown');
|
|
259
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
260
|
+
|
|
261
|
+
const trigger = element.shadowRoot.querySelector('.trigger');
|
|
262
|
+
// In Virtual Focus, the trigger handles key events
|
|
263
|
+
trigger.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true, composed: true }));
|
|
264
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
265
|
+
|
|
266
|
+
expect(element.open).toBe(false);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DsDropdown } from './ds-dropdown.js';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { LitElement, html, css } from 'lit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Logical grouping of dropdown items with optional label.
|
|
5
|
+
*
|
|
6
|
+
* @element ds-dropdown-group
|
|
7
|
+
* @prop {string} label - Group label text
|
|
8
|
+
* @slot - Default slot for ds-list-item elements
|
|
9
|
+
*/
|
|
10
|
+
export class DsDropdownGroup extends LitElement {
|
|
11
|
+
static properties = {
|
|
12
|
+
label: { type: String }
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
static styles = css`
|
|
16
|
+
:host {
|
|
17
|
+
display: block;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.group-label {
|
|
21
|
+
font: var(--ds-typo-content-body-bold);
|
|
22
|
+
color: var(--ds-color-text-secondary);
|
|
23
|
+
padding: 8px 16px 4px;
|
|
24
|
+
display: block;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.group-items {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Divider between groups */
|
|
33
|
+
:host(:not(:first-child)) {
|
|
34
|
+
margin-top: 8px;
|
|
35
|
+
padding-top: 8px;
|
|
36
|
+
border-top: 1px solid var(--ds-color-border-default);
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
constructor() {
|
|
41
|
+
super();
|
|
42
|
+
this.label = '';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
render() {
|
|
46
|
+
return html`
|
|
47
|
+
${this.label ? html`<span class="group-label">${this.label}</span>` : ''}
|
|
48
|
+
<div class="group-items" role="group" aria-label="${this.label || 'Item group'}">
|
|
49
|
+
<slot></slot>
|
|
50
|
+
</div>
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
customElements.define('ds-dropdown-group', DsDropdownGroup);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { LitElement, html, css } from 'lit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* specialized panel for dropdown popups.
|
|
5
|
+
* Handles scrolling, containment, and visual styling (shadow, radius).
|
|
6
|
+
*
|
|
7
|
+
* @element ds-dropdown-panel
|
|
8
|
+
* @slot - Content (Items, Headers)
|
|
9
|
+
*/
|
|
10
|
+
export class DsDropdownPanel extends LitElement {
|
|
11
|
+
static styles = css`
|
|
12
|
+
:host {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
background-color: var(--ds-color-bg-default);
|
|
16
|
+
border-radius: var(--ds-radius-container);
|
|
17
|
+
box-shadow: var(--ds-elevation-floating);
|
|
18
|
+
max-height: 300px; /* Default constraint */
|
|
19
|
+
overflow: hidden; /* Changed from auto - zones handle scroll */
|
|
20
|
+
padding: 0; /* Zones handle their own padding */
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
|
|
23
|
+
/* Scrollbar styling */
|
|
24
|
+
scrollbar-width: thin;
|
|
25
|
+
scrollbar-color: var(--ds-color-border-strong) transparent;
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
render() {
|
|
30
|
+
return html`<slot></slot>`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
customElements.define('ds-dropdown-panel', DsDropdownPanel);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import axe from 'axe-core';
|
|
3
|
+
import './ds-file-uploaded.js';
|
|
4
|
+
|
|
5
|
+
describe('DsFileUploaded A11y', () => {
|
|
6
|
+
let container;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
container = document.createElement('div');
|
|
10
|
+
document.body.appendChild(container);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
container.remove();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('default state passes axe a11y checks', async () => {
|
|
18
|
+
container.innerHTML = '<div role="list"><ds-file-uploaded filename="report.pdf" size="2 MB"></ds-file-uploaded></div>';
|
|
19
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
20
|
+
|
|
21
|
+
const results = await axe.run(container);
|
|
22
|
+
expect(results.violations).toHaveLength(0);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('loading state passes axe a11y checks', async () => {
|
|
26
|
+
container.innerHTML = '<div role="list"><ds-file-uploaded filename="report.pdf" size="2 MB" loading progress="50"></ds-file-uploaded></div>';
|
|
27
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
28
|
+
|
|
29
|
+
const results = await axe.run(container);
|
|
30
|
+
expect(results.violations).toHaveLength(0);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('error state passes axe a11y checks', async () => {
|
|
34
|
+
container.innerHTML = '<div role="list"><ds-file-uploaded filename="report.pdf" size="2 MB" error error-message="Upload failed"></ds-file-uploaded></div>';
|
|
35
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
36
|
+
|
|
37
|
+
const results = await axe.run(container);
|
|
38
|
+
expect(results.violations).toHaveLength(0);
|
|
39
|
+
});
|
|
40
|
+
});
|