@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,242 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import './ds-status-border.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Components/StatusBorder',
|
|
6
|
+
component: 'ds-status-border',
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
argTypes: {
|
|
9
|
+
status: {
|
|
10
|
+
control: { type: 'select' },
|
|
11
|
+
options: [
|
|
12
|
+
'critical', 'danger', 'fail',
|
|
13
|
+
'warning-major', 'warning-minor',
|
|
14
|
+
'success', 'info', 'inprogress',
|
|
15
|
+
'pending', 'neutral', 'new'
|
|
16
|
+
],
|
|
17
|
+
description: 'Status type'
|
|
18
|
+
},
|
|
19
|
+
orientation: {
|
|
20
|
+
control: { type: 'select' },
|
|
21
|
+
options: ['vertical', 'horizontal'],
|
|
22
|
+
description: 'Border orientation'
|
|
23
|
+
},
|
|
24
|
+
selected: {
|
|
25
|
+
control: 'boolean',
|
|
26
|
+
description: 'Increases thickness from 2px to 4px'
|
|
27
|
+
},
|
|
28
|
+
disabled: {
|
|
29
|
+
control: 'boolean',
|
|
30
|
+
description: 'Visually disables the border (opacity: 0.5)'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// ─── Playground ───
|
|
36
|
+
export const Playground = {
|
|
37
|
+
args: {
|
|
38
|
+
status: 'critical',
|
|
39
|
+
orientation: 'vertical',
|
|
40
|
+
selected: false,
|
|
41
|
+
disabled: false
|
|
42
|
+
},
|
|
43
|
+
render: (args) => html`
|
|
44
|
+
<div style="position: relative; width: 200px; height: 100px; border: 1px solid var(--ds-color-border-default); border-radius: var(--ds-radius-container);">
|
|
45
|
+
<ds-status-border
|
|
46
|
+
status="${args.status}"
|
|
47
|
+
orientation="${args.orientation}"
|
|
48
|
+
?selected="${args.selected}"
|
|
49
|
+
?disabled="${args.disabled}"
|
|
50
|
+
style="position: absolute; left: 0; top: 0; ${args.orientation === 'vertical' ? 'bottom: 0;' : 'right: 0;'}"
|
|
51
|
+
></ds-status-border>
|
|
52
|
+
<div style="padding: var(--ds-space-md); font: var(--ds-typo-content-body-regular);">
|
|
53
|
+
Status: <strong>${args.status}</strong>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
`
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// ─── All Statuses ───
|
|
60
|
+
export const AllStatuses = {
|
|
61
|
+
render: () => {
|
|
62
|
+
const statuses = [
|
|
63
|
+
'critical', 'danger', 'fail',
|
|
64
|
+
'warning-major', 'warning-minor',
|
|
65
|
+
'success', 'info', 'inprogress',
|
|
66
|
+
'pending', 'neutral', 'new'
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
return html`
|
|
70
|
+
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px;">
|
|
71
|
+
${statuses.map(status => html`
|
|
72
|
+
<div style="position: relative; height: 80px; border: 1px solid var(--ds-color-border-default); border-radius: var(--ds-radius-container);">
|
|
73
|
+
<ds-status-border
|
|
74
|
+
status="${status}"
|
|
75
|
+
style="position: absolute; left: 0; top: 0; bottom: 0;"
|
|
76
|
+
></ds-status-border>
|
|
77
|
+
<div style="padding: var(--ds-space-md); font: var(--ds-typo-content-caption-bold);">
|
|
78
|
+
${status}
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
`)}
|
|
82
|
+
</div>
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// ─── Orientations ───
|
|
88
|
+
export const Orientations = {
|
|
89
|
+
render: () => html`
|
|
90
|
+
<div style="display: flex; gap: 24px; flex-direction: column;">
|
|
91
|
+
<div>
|
|
92
|
+
<p style="font: var(--ds-typo-content-caption-bold); color: var(--ds-color-text-secondary); margin: 0 0 8px;">Vertical</p>
|
|
93
|
+
<div style="position: relative; width: 200px; height: 100px; border: 1px solid var(--ds-color-border-default); border-radius: var(--ds-radius-container);">
|
|
94
|
+
<ds-status-border
|
|
95
|
+
status="critical"
|
|
96
|
+
orientation="vertical"
|
|
97
|
+
style="position: absolute; left: 0; top: 0; bottom: 0;"
|
|
98
|
+
></ds-status-border>
|
|
99
|
+
<div style="padding: var(--ds-space-md); font: var(--ds-typo-content-body-regular);">
|
|
100
|
+
Vertical border
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<div>
|
|
106
|
+
<p style="font: var(--ds-typo-content-caption-bold); color: var(--ds-color-text-secondary); margin: 0 0 8px;">Horizontal</p>
|
|
107
|
+
<div style="position: relative; width: 200px; height: 100px; border: 1px solid var(--ds-color-border-default); border-radius: var(--ds-radius-container);">
|
|
108
|
+
<ds-status-border
|
|
109
|
+
status="success"
|
|
110
|
+
orientation="horizontal"
|
|
111
|
+
style="position: absolute; left: 0; top: 0; right: 0;"
|
|
112
|
+
></ds-status-border>
|
|
113
|
+
<div style="padding: var(--ds-space-md); padding-top: calc(var(--ds-space-md) + 8px); font: var(--ds-typo-content-body-regular);">
|
|
114
|
+
Horizontal border
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
`
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// ─── Selected State ───
|
|
123
|
+
export const SelectedState = {
|
|
124
|
+
render: () => html`
|
|
125
|
+
<div style="display: flex; gap: 24px;">
|
|
126
|
+
<div>
|
|
127
|
+
<p style="font: var(--ds-typo-content-caption-bold); color: var(--ds-color-text-secondary); margin: 0 0 8px;">Normal (2px)</p>
|
|
128
|
+
<div style="position: relative; width: 200px; height: 100px; border: 1px solid var(--ds-color-border-default); border-radius: var(--ds-radius-container);">
|
|
129
|
+
<ds-status-border
|
|
130
|
+
status="warning-major"
|
|
131
|
+
style="position: absolute; left: 0; top: 0; bottom: 0;"
|
|
132
|
+
></ds-status-border>
|
|
133
|
+
<div style="padding: var(--ds-space-md); font: var(--ds-typo-content-body-regular);">
|
|
134
|
+
Default thickness
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<div>
|
|
140
|
+
<p style="font: var(--ds-typo-content-caption-bold); color: var(--ds-color-text-secondary); margin: 0 0 8px;">Selected (4px)</p>
|
|
141
|
+
<div style="position: relative; width: 200px; height: 100px; border: 1px solid var(--ds-color-border-default); border-radius: var(--ds-radius-container);">
|
|
142
|
+
<ds-status-border
|
|
143
|
+
status="warning-major"
|
|
144
|
+
selected
|
|
145
|
+
style="position: absolute; left: 0; top: 0; bottom: 0;"
|
|
146
|
+
></ds-status-border>
|
|
147
|
+
<div style="padding: var(--ds-space-md); font: var(--ds-typo-content-body-regular);">
|
|
148
|
+
Selected thickness
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
`
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// ─── Composed in Card ───
|
|
157
|
+
export const ComposedInCard = {
|
|
158
|
+
render: () => html`
|
|
159
|
+
<style>
|
|
160
|
+
.demo-card {
|
|
161
|
+
position: relative;
|
|
162
|
+
width: 300px;
|
|
163
|
+
min-height: 120px;
|
|
164
|
+
padding: var(--ds-space-md);
|
|
165
|
+
border: 1px solid var(--ds-color-border-default);
|
|
166
|
+
border-radius: var(--ds-radius-container);
|
|
167
|
+
background: var(--ds-color-bg-default);
|
|
168
|
+
}
|
|
169
|
+
.demo-card h3 {
|
|
170
|
+
margin: 0 0 var(--ds-space-sm);
|
|
171
|
+
font: var(--ds-typo-content-body-bold);
|
|
172
|
+
color: var(--ds-color-text-default);
|
|
173
|
+
}
|
|
174
|
+
.demo-card p {
|
|
175
|
+
margin: 0;
|
|
176
|
+
font: var(--ds-typo-content-body-regular);
|
|
177
|
+
color: var(--ds-color-text-secondary);
|
|
178
|
+
}
|
|
179
|
+
</style>
|
|
180
|
+
|
|
181
|
+
<div style="display: flex; gap: 16px; flex-direction: column;">
|
|
182
|
+
<div class="demo-card">
|
|
183
|
+
<ds-status-border status="critical" style="position: absolute; left: 0; top: 0; bottom: 0;"></ds-status-border>
|
|
184
|
+
<h3>Critical Alert</h3>
|
|
185
|
+
<p>System failure detected in production environment.</p>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
<div class="demo-card">
|
|
189
|
+
<ds-status-border status="warning-major" style="position: absolute; left: 0; top: 0; bottom: 0;"></ds-status-border>
|
|
190
|
+
<h3>Warning</h3>
|
|
191
|
+
<p>High memory usage in container cluster.</p>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div class="demo-card">
|
|
195
|
+
<ds-status-border status="success" style="position: absolute; left: 0; top: 0; bottom: 0;"></ds-status-border>
|
|
196
|
+
<h3>Deployment Successful</h3>
|
|
197
|
+
<p>All services running smoothly.</p>
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<div class="demo-card">
|
|
201
|
+
<ds-status-border status="inprogress" style="position: absolute; left: 0; top: 0; bottom: 0;"></ds-status-border>
|
|
202
|
+
<h3>Build in Progress</h3>
|
|
203
|
+
<p>Compiling assets and running tests.</p>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
`
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// ─── Disabled State ───
|
|
210
|
+
export const DisabledState = {
|
|
211
|
+
render: () => html`
|
|
212
|
+
<div style="display: flex; gap: 24px;">
|
|
213
|
+
<div>
|
|
214
|
+
<p style="font: var(--ds-typo-content-caption-bold); color: var(--ds-color-text-secondary); margin: 0 0 8px;">Normal</p>
|
|
215
|
+
<div style="position: relative; width: 200px; height: 100px; border: 1px solid var(--ds-color-border-default); border-radius: var(--ds-radius-container);">
|
|
216
|
+
<ds-status-border
|
|
217
|
+
status="critical"
|
|
218
|
+
style="position: absolute; left: 0; top: 0; bottom: 0;"
|
|
219
|
+
></ds-status-border>
|
|
220
|
+
<div style="padding: var(--ds-space-md); font: var(--ds-typo-content-body-regular);">
|
|
221
|
+
Active border
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<div>
|
|
227
|
+
<p style="font: var(--ds-typo-content-caption-bold); color: var(--ds-color-text-secondary); margin: 0 0 8px;">Disabled</p>
|
|
228
|
+
<div style="position: relative; width: 200px; height: 100px; border: 1px solid var(--ds-color-border-default); border-radius: var(--ds-radius-container);">
|
|
229
|
+
<ds-status-border
|
|
230
|
+
status="critical"
|
|
231
|
+
disabled
|
|
232
|
+
style="position: absolute; left: 0; top: 0; bottom: 0;"
|
|
233
|
+
></ds-status-border>
|
|
234
|
+
<div style="padding: var(--ds-space-md); font: var(--ds-typo-content-body-regular); opacity: 0.5;">
|
|
235
|
+
Disabled border
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
`
|
|
241
|
+
};
|
|
242
|
+
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import './ds-status-border.js';
|
|
3
|
+
|
|
4
|
+
describe('ds-status-border', () => {
|
|
5
|
+
let container;
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
container = document.createElement('div');
|
|
9
|
+
document.body.appendChild(container);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
container.remove();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
async function createStatusBorder(attrs = {}) {
|
|
17
|
+
const attrStr = Object.entries(attrs)
|
|
18
|
+
.map(([k, v]) => {
|
|
19
|
+
if (typeof v === 'boolean') return v ? k : '';
|
|
20
|
+
return `${k}="${v}"`;
|
|
21
|
+
})
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
.join(' ');
|
|
24
|
+
container.innerHTML = `<ds-status-border ${attrStr}></ds-status-border>`;
|
|
25
|
+
const el = container.querySelector('ds-status-border');
|
|
26
|
+
await el.updateComplete;
|
|
27
|
+
return el;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ─── Rendering ───
|
|
31
|
+
|
|
32
|
+
it('renders with default props', async () => {
|
|
33
|
+
const el = await createStatusBorder();
|
|
34
|
+
expect(el).toBeTruthy();
|
|
35
|
+
expect(el.status).toBe('neutral');
|
|
36
|
+
expect(el.orientation).toBe('vertical');
|
|
37
|
+
expect(el.selected).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('renders border element', async () => {
|
|
41
|
+
const el = await createStatusBorder();
|
|
42
|
+
const border = el.shadowRoot.querySelector('.border');
|
|
43
|
+
expect(border).toBeTruthy();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// ─── Status Mapping ───
|
|
47
|
+
|
|
48
|
+
it('sets status attribute', async () => {
|
|
49
|
+
const el = await createStatusBorder({ status: 'critical' });
|
|
50
|
+
expect(el.getAttribute('status')).toBe('critical');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('supports all status values', async () => {
|
|
54
|
+
const statuses = [
|
|
55
|
+
'critical', 'danger', 'fail',
|
|
56
|
+
'warning-major', 'warning-minor',
|
|
57
|
+
'success', 'info', 'inprogress',
|
|
58
|
+
'pending', 'neutral', 'new'
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
for (const status of statuses) {
|
|
62
|
+
const el = await createStatusBorder({ status });
|
|
63
|
+
expect(el.getAttribute('status')).toBe(status);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// ─── Orientation ───
|
|
68
|
+
|
|
69
|
+
it('defaults to vertical orientation', async () => {
|
|
70
|
+
const el = await createStatusBorder();
|
|
71
|
+
expect(el.orientation).toBe('vertical');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('supports horizontal orientation', async () => {
|
|
75
|
+
const el = await createStatusBorder({ orientation: 'horizontal' });
|
|
76
|
+
expect(el.getAttribute('orientation')).toBe('horizontal');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('applies correct width for vertical orientation', async () => {
|
|
80
|
+
const el = await createStatusBorder({ orientation: 'vertical' });
|
|
81
|
+
const style = getComputedStyle(el);
|
|
82
|
+
expect(style.width).toBe('2px');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('applies correct height for horizontal orientation', async () => {
|
|
86
|
+
const el = await createStatusBorder({ orientation: 'horizontal' });
|
|
87
|
+
const style = getComputedStyle(el);
|
|
88
|
+
expect(style.height).toBe('2px');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// ─── Selected State ───
|
|
92
|
+
|
|
93
|
+
it('applies selected attribute', async () => {
|
|
94
|
+
const el = await createStatusBorder({ selected: true });
|
|
95
|
+
expect(el.hasAttribute('selected')).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('applies 4px width when selected (vertical)', async () => {
|
|
99
|
+
const el = await createStatusBorder({ orientation: 'vertical', selected: true });
|
|
100
|
+
const style = getComputedStyle(el);
|
|
101
|
+
expect(style.width).toBe('4px');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('applies 4px height when selected (horizontal)', async () => {
|
|
105
|
+
const el = await createStatusBorder({ orientation: 'horizontal', selected: true });
|
|
106
|
+
const style = getComputedStyle(el);
|
|
107
|
+
expect(style.height).toBe('4px');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// ─── Property Changes ───
|
|
111
|
+
|
|
112
|
+
it('updates status dynamically', async () => {
|
|
113
|
+
const el = await createStatusBorder({ status: 'neutral' });
|
|
114
|
+
expect(el.status).toBe('neutral');
|
|
115
|
+
|
|
116
|
+
el.status = 'critical';
|
|
117
|
+
await el.updateComplete;
|
|
118
|
+
expect(el.getAttribute('status')).toBe('critical');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('updates orientation dynamically', async () => {
|
|
122
|
+
const el = await createStatusBorder({ orientation: 'vertical' });
|
|
123
|
+
expect(el.orientation).toBe('vertical');
|
|
124
|
+
|
|
125
|
+
el.orientation = 'horizontal';
|
|
126
|
+
await el.updateComplete;
|
|
127
|
+
expect(el.getAttribute('orientation')).toBe('horizontal');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('updates selected state dynamically', async () => {
|
|
131
|
+
const el = await createStatusBorder({ selected: false });
|
|
132
|
+
expect(el.selected).toBe(false);
|
|
133
|
+
|
|
134
|
+
el.selected = true;
|
|
135
|
+
await el.updateComplete;
|
|
136
|
+
expect(el.hasAttribute('selected')).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// ─── Disabled State ───
|
|
140
|
+
|
|
141
|
+
it('applies disabled attribute', async () => {
|
|
142
|
+
const el = await createStatusBorder({ disabled: true });
|
|
143
|
+
expect(el.hasAttribute('disabled')).toBe(true);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('applies opacity when disabled', async () => {
|
|
147
|
+
const el = await createStatusBorder({ disabled: true });
|
|
148
|
+
const style = getComputedStyle(el);
|
|
149
|
+
expect(style.opacity).toBe('0.5');
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('updates disabled state dynamically', async () => {
|
|
153
|
+
const el = await createStatusBorder({ disabled: false });
|
|
154
|
+
expect(el.disabled).toBe(false);
|
|
155
|
+
|
|
156
|
+
el.disabled = true;
|
|
157
|
+
await el.updateComplete;
|
|
158
|
+
expect(el.hasAttribute('disabled')).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// ─── CSS Parts ───
|
|
162
|
+
|
|
163
|
+
it('exposes border part', async () => {
|
|
164
|
+
const el = await createStatusBorder();
|
|
165
|
+
const part = el.shadowRoot.querySelector('[part="border"]');
|
|
166
|
+
expect(part).toBeTruthy();
|
|
167
|
+
});
|
|
168
|
+
});
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import './ds-stepper.js';
|
|
3
|
+
import '../ds-stepper-item/ds-stepper-item.js';
|
|
4
|
+
|
|
5
|
+
const wait = (ms = 50) => new Promise(resolve => setTimeout(resolve, ms));
|
|
6
|
+
|
|
7
|
+
describe('ds-stepper a11y', () => {
|
|
8
|
+
let container;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
container = document.createElement('div');
|
|
12
|
+
document.body.appendChild(container);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
container.remove();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('has role="group" on stepper container', async () => {
|
|
20
|
+
container.innerHTML = `
|
|
21
|
+
<ds-stepper>
|
|
22
|
+
<ds-stepper-item>Step 1</ds-stepper-item>
|
|
23
|
+
</ds-stepper>
|
|
24
|
+
`;
|
|
25
|
+
const el = container.querySelector('ds-stepper');
|
|
26
|
+
await wait();
|
|
27
|
+
|
|
28
|
+
expect(el.getAttribute('role')).toBe('group');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('has default aria-label "Progress"', async () => {
|
|
32
|
+
container.innerHTML = `
|
|
33
|
+
<ds-stepper>
|
|
34
|
+
<ds-stepper-item>Step 1</ds-stepper-item>
|
|
35
|
+
</ds-stepper>
|
|
36
|
+
`;
|
|
37
|
+
const el = container.querySelector('ds-stepper');
|
|
38
|
+
await wait();
|
|
39
|
+
|
|
40
|
+
expect(el.getAttribute('aria-label')).toBe('Progress');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('supports custom aria-label via label prop', async () => {
|
|
44
|
+
container.innerHTML = `
|
|
45
|
+
<ds-stepper label="Checkout Progress">
|
|
46
|
+
<ds-stepper-item>Step 1</ds-stepper-item>
|
|
47
|
+
</ds-stepper>
|
|
48
|
+
`;
|
|
49
|
+
const el = container.querySelector('ds-stepper');
|
|
50
|
+
await wait();
|
|
51
|
+
|
|
52
|
+
expect(el.getAttribute('aria-label')).toBe('Checkout Progress');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('sets aria-current="step" on the current step', async () => {
|
|
56
|
+
container.innerHTML = `
|
|
57
|
+
<ds-stepper active-step="1">
|
|
58
|
+
<ds-stepper-item>Step 1</ds-stepper-item>
|
|
59
|
+
<ds-stepper-item>Step 2</ds-stepper-item>
|
|
60
|
+
<ds-stepper-item>Step 3</ds-stepper-item>
|
|
61
|
+
</ds-stepper>
|
|
62
|
+
`;
|
|
63
|
+
await wait();
|
|
64
|
+
|
|
65
|
+
const items = container.querySelectorAll('ds-stepper-item');
|
|
66
|
+
expect(items[0].getAttribute('aria-current')).toBeNull();
|
|
67
|
+
expect(items[1].getAttribute('aria-current')).toBe('step');
|
|
68
|
+
expect(items[2].getAttribute('aria-current')).toBeNull();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('indicator has role="button" and tabindex when interactive', async () => {
|
|
72
|
+
container.innerHTML = `
|
|
73
|
+
<ds-stepper>
|
|
74
|
+
<ds-stepper-item>Step 1</ds-stepper-item>
|
|
75
|
+
</ds-stepper>
|
|
76
|
+
`;
|
|
77
|
+
await wait();
|
|
78
|
+
|
|
79
|
+
const item = container.querySelector('ds-stepper-item');
|
|
80
|
+
const indicator = item.shadowRoot.querySelector('.indicator');
|
|
81
|
+
|
|
82
|
+
expect(indicator.getAttribute('role')).toBe('button');
|
|
83
|
+
expect(indicator.getAttribute('tabindex')).toBe('0');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('indicator has role="presentation" and tabindex=-1 when disabled', async () => {
|
|
87
|
+
container.innerHTML = `
|
|
88
|
+
<ds-stepper>
|
|
89
|
+
<ds-stepper-item disabled>Step 1</ds-stepper-item>
|
|
90
|
+
</ds-stepper>
|
|
91
|
+
`;
|
|
92
|
+
await wait();
|
|
93
|
+
|
|
94
|
+
const item = container.querySelector('ds-stepper-item');
|
|
95
|
+
const indicator = item.shadowRoot.querySelector('.indicator');
|
|
96
|
+
|
|
97
|
+
expect(indicator.getAttribute('role')).toBe('presentation');
|
|
98
|
+
expect(indicator.getAttribute('tabindex')).toBe('-1');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('indicator has aria-label with step count', async () => {
|
|
102
|
+
container.innerHTML = `
|
|
103
|
+
<ds-stepper>
|
|
104
|
+
<ds-stepper-item>Step 1</ds-stepper-item>
|
|
105
|
+
<ds-stepper-item>Step 2</ds-stepper-item>
|
|
106
|
+
<ds-stepper-item>Step 3</ds-stepper-item>
|
|
107
|
+
</ds-stepper>
|
|
108
|
+
`;
|
|
109
|
+
await wait();
|
|
110
|
+
|
|
111
|
+
const items = container.querySelectorAll('ds-stepper-item');
|
|
112
|
+
const indicator = items[1].shadowRoot.querySelector('.indicator');
|
|
113
|
+
|
|
114
|
+
expect(indicator.getAttribute('aria-label')).toBe('Step 2 of 3');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('indicator has aria-disabled for disabled steps', async () => {
|
|
118
|
+
container.innerHTML = `
|
|
119
|
+
<ds-stepper>
|
|
120
|
+
<ds-stepper-item disabled>Step 1</ds-stepper-item>
|
|
121
|
+
</ds-stepper>
|
|
122
|
+
`;
|
|
123
|
+
await wait();
|
|
124
|
+
|
|
125
|
+
const item = container.querySelector('ds-stepper-item');
|
|
126
|
+
const indicator = item.shadowRoot.querySelector('.indicator');
|
|
127
|
+
|
|
128
|
+
expect(indicator.getAttribute('aria-disabled')).toBe('true');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('supports keyboard Enter on interactive step', async () => {
|
|
132
|
+
container.innerHTML = `
|
|
133
|
+
<ds-stepper>
|
|
134
|
+
<ds-stepper-item>Step 1</ds-stepper-item>
|
|
135
|
+
<ds-stepper-item>Step 2</ds-stepper-item>
|
|
136
|
+
</ds-stepper>
|
|
137
|
+
`;
|
|
138
|
+
await wait();
|
|
139
|
+
|
|
140
|
+
const el = container.querySelector('ds-stepper');
|
|
141
|
+
const items = container.querySelectorAll('ds-stepper-item');
|
|
142
|
+
|
|
143
|
+
let eventDetail = null;
|
|
144
|
+
el.addEventListener('ds-change', (e) => {
|
|
145
|
+
eventDetail = e.detail;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const indicator = items[1].shadowRoot.querySelector('.indicator');
|
|
149
|
+
indicator.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, composed: true }));
|
|
150
|
+
await wait();
|
|
151
|
+
|
|
152
|
+
expect(eventDetail).not.toBeNull();
|
|
153
|
+
expect(eventDetail.currentStep).toBe(1);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('supports keyboard Space on interactive step', async () => {
|
|
157
|
+
container.innerHTML = `
|
|
158
|
+
<ds-stepper>
|
|
159
|
+
<ds-stepper-item>Step 1</ds-stepper-item>
|
|
160
|
+
<ds-stepper-item>Step 2</ds-stepper-item>
|
|
161
|
+
</ds-stepper>
|
|
162
|
+
`;
|
|
163
|
+
await wait();
|
|
164
|
+
|
|
165
|
+
const el = container.querySelector('ds-stepper');
|
|
166
|
+
const items = container.querySelectorAll('ds-stepper-item');
|
|
167
|
+
|
|
168
|
+
let eventDetail = null;
|
|
169
|
+
el.addEventListener('ds-change', (e) => {
|
|
170
|
+
eventDetail = e.detail;
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const indicator = items[1].shadowRoot.querySelector('.indicator');
|
|
174
|
+
indicator.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true, composed: true }));
|
|
175
|
+
await wait();
|
|
176
|
+
|
|
177
|
+
expect(eventDetail).not.toBeNull();
|
|
178
|
+
expect(eventDetail.currentStep).toBe(1);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('linear-locked steps are not interactive', async () => {
|
|
182
|
+
container.innerHTML = `
|
|
183
|
+
<ds-stepper linear active-step="0">
|
|
184
|
+
<ds-stepper-item>Step 1</ds-stepper-item>
|
|
185
|
+
<ds-stepper-item>Step 2</ds-stepper-item>
|
|
186
|
+
<ds-stepper-item>Step 3</ds-stepper-item>
|
|
187
|
+
</ds-stepper>
|
|
188
|
+
`;
|
|
189
|
+
await wait();
|
|
190
|
+
|
|
191
|
+
const items = container.querySelectorAll('ds-stepper-item');
|
|
192
|
+
// Step 3 should be locked (not completed, not current)
|
|
193
|
+
const indicator3 = items[2].shadowRoot.querySelector('.indicator');
|
|
194
|
+
|
|
195
|
+
expect(indicator3.getAttribute('role')).toBe('presentation');
|
|
196
|
+
expect(indicator3.getAttribute('tabindex')).toBe('-1');
|
|
197
|
+
});
|
|
198
|
+
});
|