@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,135 @@
|
|
|
1
|
+
import { LitElement, html, css, nothing } from 'lit';
|
|
2
|
+
import '../ds-rich-list-item/ds-rich-list-item.js';
|
|
3
|
+
import '../ds-icon/ds-icon.js';
|
|
4
|
+
import '../ds-icon-button/ds-icon-button.js';
|
|
5
|
+
import '../ds-progress-bar/ds-progress-bar.js';
|
|
6
|
+
import '../ds-thumbnail/ds-thumbnail.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* File Uploaded — represents an individual file upload item.
|
|
10
|
+
*
|
|
11
|
+
* @element ds-file-uploaded
|
|
12
|
+
*
|
|
13
|
+
* @prop {string} filename - The name of the file.
|
|
14
|
+
* @prop {string} size - The size of the file (e.g., '1.2 MB').
|
|
15
|
+
* @prop {number} progress - The upload progress (0 to 100).
|
|
16
|
+
* @prop {boolean} loading - Whether the file is currently uploading.
|
|
17
|
+
* @prop {boolean} error - Whether the upload failed.
|
|
18
|
+
* @prop {string} errorMessage - The error message to display if error is true.
|
|
19
|
+
* @prop {boolean} disabled - Whether the component is disabled.
|
|
20
|
+
*
|
|
21
|
+
* @slot media - The file type icon. Defaults to a document icon.
|
|
22
|
+
*
|
|
23
|
+
* @fires ds-remove-file - Fired when the close (x) button is clicked.
|
|
24
|
+
*/
|
|
25
|
+
export class DsFileUploaded extends LitElement {
|
|
26
|
+
static properties = {
|
|
27
|
+
filename: { type: String, reflect: true },
|
|
28
|
+
size: { type: String, reflect: true },
|
|
29
|
+
progress: { type: Number, reflect: true },
|
|
30
|
+
loading: { type: Boolean, reflect: true },
|
|
31
|
+
error: { type: Boolean, reflect: true },
|
|
32
|
+
errorMessage: { type: String, attribute: 'error-message' },
|
|
33
|
+
disabled: { type: Boolean, reflect: true },
|
|
34
|
+
previewUrl: { type: String, attribute: 'preview-url' },
|
|
35
|
+
icon: { type: String }
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
static styles = css`
|
|
39
|
+
:host {
|
|
40
|
+
display: block;
|
|
41
|
+
width: 100%;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.error-text {
|
|
45
|
+
font: var(--ds-typo-content-body-regular);
|
|
46
|
+
color: var(--ds-color-text-error);
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
gap: var(--ds-space-xs);
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
text-overflow: ellipsis;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.error-icon {
|
|
56
|
+
color: var(--ds-color-icon-error);
|
|
57
|
+
flex-shrink: 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.progress-container {
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: center;
|
|
63
|
+
width: 100%;
|
|
64
|
+
min-width: 100px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
ds-rich-list-item {
|
|
68
|
+
width: 100%;
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
constructor() {
|
|
73
|
+
super();
|
|
74
|
+
this.filename = '';
|
|
75
|
+
this.size = '';
|
|
76
|
+
this.progress = 0;
|
|
77
|
+
this.loading = false;
|
|
78
|
+
this.error = false;
|
|
79
|
+
this.errorMessage = '';
|
|
80
|
+
this.disabled = false;
|
|
81
|
+
this.previewUrl = '';
|
|
82
|
+
this.icon = 'document';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
_handleRemoveClick(e) {
|
|
86
|
+
e.stopPropagation();
|
|
87
|
+
if (this.disabled) return;
|
|
88
|
+
this.dispatchEvent(new CustomEvent('ds-remove-file', {
|
|
89
|
+
bubbles: true,
|
|
90
|
+
composed: true,
|
|
91
|
+
detail: { filename: this.filename }
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
render() {
|
|
96
|
+
return html`
|
|
97
|
+
<ds-rich-list-item ?disabled=${this.disabled}>
|
|
98
|
+
<slot name="media" slot="media">
|
|
99
|
+
<ds-thumbnail src="${this.previewUrl || ''}" icon="${this.icon}"></ds-thumbnail>
|
|
100
|
+
</slot>
|
|
101
|
+
|
|
102
|
+
<span slot="title">${this.filename}</span>
|
|
103
|
+
<span slot="description">${this.size}</span>
|
|
104
|
+
|
|
105
|
+
<div slot="custom" class="custom-area">
|
|
106
|
+
${this.loading ? html`
|
|
107
|
+
<div class="progress-container">
|
|
108
|
+
<ds-progress-bar value="${this.progress}" ?disabled=${this.disabled} label="Upload progress"></ds-progress-bar>
|
|
109
|
+
</div>
|
|
110
|
+
` : nothing}
|
|
111
|
+
${this.error && !this.loading ? html`
|
|
112
|
+
<div class="error-text">
|
|
113
|
+
<ds-icon name="warning" size="sm" class="error-icon"></ds-icon>
|
|
114
|
+
<span>${this.errorMessage}</span>
|
|
115
|
+
</div>
|
|
116
|
+
` : nothing}
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<ds-icon-button
|
|
120
|
+
slot="action-group"
|
|
121
|
+
icon="close"
|
|
122
|
+
variant="action"
|
|
123
|
+
size="m"
|
|
124
|
+
aria-label="Remove file"
|
|
125
|
+
?disabled=${this.disabled}
|
|
126
|
+
@click=${this._handleRemoveClick}
|
|
127
|
+
></ds-icon-button>
|
|
128
|
+
</ds-rich-list-item>
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!customElements.get('ds-file-uploaded')) {
|
|
134
|
+
customElements.define('ds-file-uploaded', DsFileUploaded);
|
|
135
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Meta, Story, Canvas, ArgsTable, Description } from '@storybook/blocks';
|
|
2
|
+
import * as DsFileUploadedStories from './ds-file-uploaded.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={DsFileUploadedStories} />
|
|
5
|
+
|
|
6
|
+
# DsFileUploaded
|
|
7
|
+
|
|
8
|
+
<Description />
|
|
9
|
+
|
|
10
|
+
The `ds-file-uploaded` component represents a single file either currently being uploaded or already uploaded.
|
|
11
|
+
|
|
12
|
+
## Anatomy
|
|
13
|
+
It leverages the `ds-rich-list-item` and supports custom `media` slots, a close button, and states for loading (with progress) and error.
|
|
14
|
+
|
|
15
|
+
## Examples
|
|
16
|
+
|
|
17
|
+
### Default
|
|
18
|
+
<Canvas>
|
|
19
|
+
<Story of={DsFileUploadedStories.Default} />
|
|
20
|
+
</Canvas>
|
|
21
|
+
|
|
22
|
+
### Loading
|
|
23
|
+
<Canvas>
|
|
24
|
+
<Story of={DsFileUploadedStories.Loading} />
|
|
25
|
+
</Canvas>
|
|
26
|
+
|
|
27
|
+
### Error
|
|
28
|
+
<Canvas>
|
|
29
|
+
<Story of={DsFileUploadedStories.Error} />
|
|
30
|
+
</Canvas>
|
|
31
|
+
|
|
32
|
+
## API Reference
|
|
33
|
+
<ArgsTable />
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import './ds-file-uploaded.js';
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Components/File Uploaded',
|
|
6
|
+
component: 'ds-file-uploaded',
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
argTypes: {
|
|
9
|
+
filename: { control: 'text' },
|
|
10
|
+
size: { control: 'text' },
|
|
11
|
+
progress: { control: { type: 'range', min: 0, max: 100 } },
|
|
12
|
+
loading: { control: 'boolean' },
|
|
13
|
+
error: { control: 'boolean' },
|
|
14
|
+
errorMessage: { control: 'text', name: 'error-message' },
|
|
15
|
+
disabled: { control: 'boolean' },
|
|
16
|
+
previewUrl: { control: 'text', name: 'preview-url' },
|
|
17
|
+
icon: { control: 'text' }
|
|
18
|
+
},
|
|
19
|
+
parameters: {
|
|
20
|
+
actions: {
|
|
21
|
+
handles: ['ds-remove-file']
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const Template = (args) => html`
|
|
27
|
+
<ds-file-uploaded
|
|
28
|
+
filename=${args.filename}
|
|
29
|
+
size=${args.size}
|
|
30
|
+
progress=${args.progress}
|
|
31
|
+
?loading=${args.loading}
|
|
32
|
+
?error=${args.error}
|
|
33
|
+
error-message=${args.errorMessage || ''}
|
|
34
|
+
?disabled=${args.disabled}
|
|
35
|
+
preview-url=${args.previewUrl || ''}
|
|
36
|
+
icon=${args.icon || 'document'}
|
|
37
|
+
></ds-file-uploaded>
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
export const Default = Template.bind({});
|
|
41
|
+
Default.args = {
|
|
42
|
+
filename: 'document.pdf',
|
|
43
|
+
size: '1.2 MB',
|
|
44
|
+
progress: 0,
|
|
45
|
+
loading: false,
|
|
46
|
+
error: false,
|
|
47
|
+
errorMessage: '',
|
|
48
|
+
disabled: false,
|
|
49
|
+
icon: 'image'
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const Loading = Template.bind({});
|
|
53
|
+
Loading.args = {
|
|
54
|
+
...Default.args,
|
|
55
|
+
progress: 45,
|
|
56
|
+
loading: true
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const Error = Template.bind({});
|
|
60
|
+
Error.args = {
|
|
61
|
+
...Default.args,
|
|
62
|
+
filename: 'corrupted-file.zip',
|
|
63
|
+
size: '12 KB',
|
|
64
|
+
error: true,
|
|
65
|
+
errorMessage: 'File must be a valid format'
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const Disabled = Template.bind({});
|
|
69
|
+
Disabled.args = {
|
|
70
|
+
...Default.args,
|
|
71
|
+
disabled: true
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const CustomMedia = (args) => html`
|
|
75
|
+
<ds-file-uploaded
|
|
76
|
+
filename="image-placeholder.png"
|
|
77
|
+
size="350 KB"
|
|
78
|
+
>
|
|
79
|
+
<ds-thumbnail slot="media" src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?w=400&h=400&fit=crop" icon="image"></ds-thumbnail>
|
|
80
|
+
</ds-file-uploaded>
|
|
81
|
+
`;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import './ds-file-uploaded.js';
|
|
3
|
+
|
|
4
|
+
describe('DsFileUploaded', () => {
|
|
5
|
+
let container;
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
container = document.createElement('div');
|
|
9
|
+
document.body.appendChild(container);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
container.remove();
|
|
14
|
+
vi.restoreAllMocks();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should render correctly', async () => {
|
|
18
|
+
container.innerHTML = '<ds-file-uploaded filename="test.pdf" size="1.2 MB"></ds-file-uploaded>';
|
|
19
|
+
const el = container.querySelector('ds-file-uploaded');
|
|
20
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
21
|
+
expect(el).toBeTruthy();
|
|
22
|
+
expect(el.shadowRoot.querySelector('ds-rich-list-item')).toBeTruthy();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('displays the filename and size', async () => {
|
|
26
|
+
container.innerHTML = '<ds-file-uploaded filename="document.pdf" size="2 MB"></ds-file-uploaded>';
|
|
27
|
+
const el = container.querySelector('ds-file-uploaded');
|
|
28
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
29
|
+
|
|
30
|
+
const title = el.shadowRoot.querySelector('span[slot="title"]');
|
|
31
|
+
const desc = el.shadowRoot.querySelector('span[slot="description"]');
|
|
32
|
+
expect(title.textContent).toBe('document.pdf');
|
|
33
|
+
expect(desc.textContent).toBe('2 MB');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('shows progress bar when loading', async () => {
|
|
37
|
+
container.innerHTML = '<ds-file-uploaded filename="doc.pdf" loading progress="50"></ds-file-uploaded>';
|
|
38
|
+
const el = container.querySelector('ds-file-uploaded');
|
|
39
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
40
|
+
|
|
41
|
+
const progressBar = el.shadowRoot.querySelector('ds-progress-bar');
|
|
42
|
+
expect(progressBar).toBeTruthy();
|
|
43
|
+
expect(progressBar.getAttribute('value')).toBe('50');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('shows error message when error is true', async () => {
|
|
47
|
+
container.innerHTML = '<ds-file-uploaded filename="doc.pdf" error error-message="File too large"></ds-file-uploaded>';
|
|
48
|
+
const el = container.querySelector('ds-file-uploaded');
|
|
49
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
50
|
+
|
|
51
|
+
const errorText = el.shadowRoot.querySelector('.error-text span');
|
|
52
|
+
expect(errorText).toBeTruthy();
|
|
53
|
+
expect(errorText.textContent).toBe('File too large');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('dispatches ds-remove-file event when close button is clicked', async () => {
|
|
57
|
+
container.innerHTML = '<ds-file-uploaded filename="doc.pdf"></ds-file-uploaded>';
|
|
58
|
+
const el = container.querySelector('ds-file-uploaded');
|
|
59
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
60
|
+
|
|
61
|
+
const removeSpy = vi.fn();
|
|
62
|
+
el.addEventListener('ds-remove-file', removeSpy);
|
|
63
|
+
|
|
64
|
+
const closeButton = el.shadowRoot.querySelector('ds-icon-button');
|
|
65
|
+
closeButton.click();
|
|
66
|
+
|
|
67
|
+
expect(removeSpy).toHaveBeenCalledOnce();
|
|
68
|
+
const eventDetail = removeSpy.mock.calls[0][0].detail;
|
|
69
|
+
expect(eventDetail.filename).toBe('doc.pdf');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('does not dispatch ds-remove-file when disabled', async () => {
|
|
73
|
+
container.innerHTML = '<ds-file-uploaded filename="doc.pdf" disabled></ds-file-uploaded>';
|
|
74
|
+
const el = container.querySelector('ds-file-uploaded');
|
|
75
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
76
|
+
|
|
77
|
+
const removeSpy = vi.fn();
|
|
78
|
+
el.addEventListener('ds-remove-file', removeSpy);
|
|
79
|
+
|
|
80
|
+
const closeButton = el.shadowRoot.querySelector('ds-icon-button');
|
|
81
|
+
closeButton.click();
|
|
82
|
+
|
|
83
|
+
expect(removeSpy).not.toHaveBeenCalled();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import axe from 'axe-core';
|
|
3
|
+
import './ds-file-uploader.js';
|
|
4
|
+
|
|
5
|
+
describe('DsFileUploader 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 = '<ds-file-uploader label="Upload Area" help-text="Only PNGs"></ds-file-uploader>';
|
|
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('disabled state passes axe a11y checks', async () => {
|
|
26
|
+
container.innerHTML = '<ds-file-uploader disabled label="Upload Area"></ds-file-uploader>';
|
|
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 = '<ds-file-uploader error-text="Invalid file" label="Upload Area"></ds-file-uploader>';
|
|
35
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
36
|
+
|
|
37
|
+
const results = await axe.run(container);
|
|
38
|
+
expect(results.violations).toHaveLength(0);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('populated list passes axe a11y checks', async () => {
|
|
42
|
+
container.innerHTML = '<ds-file-uploader label="Upload Area"></ds-file-uploader>';
|
|
43
|
+
const el = container.querySelector('ds-file-uploader');
|
|
44
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
45
|
+
|
|
46
|
+
// Manually add a file
|
|
47
|
+
el.files = [{
|
|
48
|
+
id: '123',
|
|
49
|
+
filename: 'a11y-test.pdf',
|
|
50
|
+
size: '12 KB',
|
|
51
|
+
progress: 0,
|
|
52
|
+
loading: false,
|
|
53
|
+
error: false,
|
|
54
|
+
errorMessage: ''
|
|
55
|
+
}];
|
|
56
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
57
|
+
|
|
58
|
+
const results = await axe.run(container);
|
|
59
|
+
expect(results.violations).toHaveLength(0);
|
|
60
|
+
});
|
|
61
|
+
});
|