@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,223 @@
|
|
|
1
|
+
import { LitElement, html, css } from 'lit';
|
|
2
|
+
import '../ds-icon/ds-icon.js';
|
|
3
|
+
import '../ds-icon-button/ds-icon-button.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Alert component for user feedback with different severity levels
|
|
7
|
+
*
|
|
8
|
+
* @element ds-alert
|
|
9
|
+
*
|
|
10
|
+
* @prop {string} status - Status type: 'error' | 'warning' | 'success' | 'info' (default: 'info')
|
|
11
|
+
* @prop {boolean} dismissible - Show/hide close button (default: false)
|
|
12
|
+
*
|
|
13
|
+
* @slot - Default slot for message content
|
|
14
|
+
* @slot title - Optional slot for title content
|
|
15
|
+
* @slot actions - Optional slot for action buttons
|
|
16
|
+
*
|
|
17
|
+
* @fires ds-dismiss - Dispatched when user clicks the close button
|
|
18
|
+
*
|
|
19
|
+
* @csspart alert - The main alert container
|
|
20
|
+
* @csspart icon - The status icon element
|
|
21
|
+
* @csspart content - Content area (title + message + actions)
|
|
22
|
+
* @csspart close-button - The close button
|
|
23
|
+
*/
|
|
24
|
+
export class DsAlert extends LitElement {
|
|
25
|
+
static properties = {
|
|
26
|
+
status: { type: String, reflect: true },
|
|
27
|
+
dismissible: { type: Boolean, reflect: true },
|
|
28
|
+
title: { type: String },
|
|
29
|
+
message: { type: String },
|
|
30
|
+
hideIcon: { type: Boolean, attribute: 'hide-icon', reflect: true },
|
|
31
|
+
_hasActions: { type: Boolean, state: true }
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
static styles = css`
|
|
35
|
+
:host {
|
|
36
|
+
display: block;
|
|
37
|
+
box-sizing: border-box;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.alert {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: flex-start;
|
|
43
|
+
gap: var(--ds-space-sm); /* 8px */
|
|
44
|
+
min-height: 40px;
|
|
45
|
+
padding: 10px 8px;
|
|
46
|
+
border-radius: var(--ds-radius-container); /* 0px - sharp */
|
|
47
|
+
box-sizing: border-box;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Side containers for alignment */
|
|
51
|
+
.icon-container,
|
|
52
|
+
.dismiss-container {
|
|
53
|
+
flex-shrink: 0;
|
|
54
|
+
display: flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
height: 20px; /* Matching line-height of body text (20px) */
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Status icon */
|
|
61
|
+
.icon {
|
|
62
|
+
color: var(--ds-color-icon-default);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Content area */
|
|
66
|
+
.content {
|
|
67
|
+
flex: 1;
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-direction: column;
|
|
70
|
+
min-width: 0; /* Allow text wrapping */
|
|
71
|
+
font: var(--ds-typo-content-body-regular);
|
|
72
|
+
color: var(--ds-color-text-default);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* Title styling */
|
|
76
|
+
.title {
|
|
77
|
+
font: var(--ds-typo-content-body-bold);
|
|
78
|
+
margin-bottom: var(--ds-space-xs); /* 4px gap to message */
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Title slot styling */
|
|
82
|
+
.content ::slotted([slot="title"]) {
|
|
83
|
+
font: var(--ds-typo-content-body-bold);
|
|
84
|
+
margin-bottom: var(--ds-space-xs);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Actions slot wrapper */
|
|
88
|
+
.actions {
|
|
89
|
+
display: flex;
|
|
90
|
+
gap: var(--ds-space-sm); /* 8px between action buttons */
|
|
91
|
+
flex-wrap: wrap;
|
|
92
|
+
margin-top: var(--ds-space-sm); /* 8px gap from message as requested */
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.actions[hidden] {
|
|
96
|
+
display: none;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Close button */
|
|
100
|
+
.close-button {
|
|
101
|
+
/* No absolute sizing here, handled by parent flex centering */
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Status: Error */
|
|
105
|
+
:host([status="error"]) .alert {
|
|
106
|
+
background-color: var(--ds-color-bg-error-subtle);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Status: Warning */
|
|
110
|
+
:host([status="warning"]) .alert {
|
|
111
|
+
background-color: var(--ds-color-bg-warning-subtle);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Status: Success */
|
|
115
|
+
:host([status="success"]) .alert {
|
|
116
|
+
background-color: var(--ds-color-bg-success-subtle);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Status: Info (default) */
|
|
120
|
+
:host([status="info"]) .alert,
|
|
121
|
+
:host(:not([status])) .alert {
|
|
122
|
+
background-color: var(--ds-color-bg-info-subtle);
|
|
123
|
+
}
|
|
124
|
+
`;
|
|
125
|
+
|
|
126
|
+
constructor() {
|
|
127
|
+
super();
|
|
128
|
+
this.status = 'info';
|
|
129
|
+
this.dismissible = false;
|
|
130
|
+
this.title = '';
|
|
131
|
+
this.message = '';
|
|
132
|
+
this.hideIcon = false;
|
|
133
|
+
this._hasActions = false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
connectedCallback() {
|
|
137
|
+
super.connectedCallback();
|
|
138
|
+
|
|
139
|
+
// Set role for accessibility
|
|
140
|
+
if (!this.hasAttribute('role')) {
|
|
141
|
+
this.setAttribute('role', 'alert');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Returns the icon name based on the status
|
|
147
|
+
* @returns {string} Icon name
|
|
148
|
+
*/
|
|
149
|
+
_getIconName() {
|
|
150
|
+
const iconMap = {
|
|
151
|
+
error: 'cancel',
|
|
152
|
+
warning: 'warning',
|
|
153
|
+
success: 'check-circle',
|
|
154
|
+
info: 'info'
|
|
155
|
+
};
|
|
156
|
+
return iconMap[this.status] || iconMap.info;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Handles close button click
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
_handleDismiss() {
|
|
164
|
+
this.dispatchEvent(new CustomEvent('ds-dismiss', {
|
|
165
|
+
bubbles: true,
|
|
166
|
+
composed: true
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Handles slot change for actions to show/hide the container
|
|
172
|
+
* @private
|
|
173
|
+
*/
|
|
174
|
+
_handleSlotChange(e) {
|
|
175
|
+
const assignedNodes = e.target.assignedNodes({ flatten: true });
|
|
176
|
+
this._hasActions = assignedNodes.length > 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
render() {
|
|
180
|
+
return html`
|
|
181
|
+
<div class="alert" part="alert" role="alert">
|
|
182
|
+
${!this.hideIcon ? html`
|
|
183
|
+
<div class="icon-container" part="icon-container">
|
|
184
|
+
<ds-icon
|
|
185
|
+
class="icon"
|
|
186
|
+
name="${this._getIconName()}"
|
|
187
|
+
size="sm"
|
|
188
|
+
part="icon"
|
|
189
|
+
></ds-icon>
|
|
190
|
+
</div>
|
|
191
|
+
` : ''}
|
|
192
|
+
|
|
193
|
+
<div class="content" part="content">
|
|
194
|
+
${this.title ? html`<div class="title" part="title">${this.title}</div>` : ''}
|
|
195
|
+
<slot name="title"></slot>
|
|
196
|
+
|
|
197
|
+
<div class="message" part="message">${this.message}</div>
|
|
198
|
+
<slot></slot>
|
|
199
|
+
|
|
200
|
+
<div class="actions" ?hidden="${!this._hasActions}" part="actions">
|
|
201
|
+
<slot name="actions" @slotchange="${this._handleSlotChange}"></slot>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
${this.dismissible ? html`
|
|
206
|
+
<div class="dismiss-container" part="dismiss-container">
|
|
207
|
+
<ds-icon-button
|
|
208
|
+
class="close-button"
|
|
209
|
+
icon="close"
|
|
210
|
+
variant="action"
|
|
211
|
+
size="m"
|
|
212
|
+
aria-label="Fechar alerta"
|
|
213
|
+
part="close-button"
|
|
214
|
+
@click="${this._handleDismiss}"
|
|
215
|
+
></ds-icon-button>
|
|
216
|
+
</div>
|
|
217
|
+
` : ''}
|
|
218
|
+
</div>
|
|
219
|
+
`;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
customElements.define('ds-alert', DsAlert);
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Meta, Canvas, Controls } from '@storybook/blocks';
|
|
2
|
+
import * as DsAlertStories from './ds-alert.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={DsAlertStories} />
|
|
5
|
+
|
|
6
|
+
# Alert
|
|
7
|
+
|
|
8
|
+
Alerts provide contextual feedback messages for typical user actions with different severity levels.
|
|
9
|
+
|
|
10
|
+
## Playground
|
|
11
|
+
Interact with the alert properties using the controls below.
|
|
12
|
+
|
|
13
|
+
<Canvas of={DsAlertStories.Default} />
|
|
14
|
+
<Controls of={DsAlertStories.Default} />
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
### When to use
|
|
19
|
+
- To communicate important information to users.
|
|
20
|
+
- To provide feedback after an action (success, error, warning).
|
|
21
|
+
- To display system-level notifications or updates.
|
|
22
|
+
|
|
23
|
+
### When not to use
|
|
24
|
+
- For critical errors that require immediate action—use a modal dialog instead.
|
|
25
|
+
- For inline form validation—use field-level error messages.
|
|
26
|
+
- For temporary notifications—consider using a toast/snackbar pattern.
|
|
27
|
+
|
|
28
|
+
## Best Practices
|
|
29
|
+
|
|
30
|
+
### General
|
|
31
|
+
- ✅ **Clarity:** Keep messages concise and actionable.
|
|
32
|
+
- ✅ **Placement:** Position alerts near the content they relate to.
|
|
33
|
+
- ✅ **Persistence:** Non-dismissible alerts should only be used for critical, persistent information.
|
|
34
|
+
- ✅ **Actions:** Limit to 1-2 action buttons to avoid overwhelming users.
|
|
35
|
+
|
|
36
|
+
### Status Selection
|
|
37
|
+
- ✅ **Error:** For critical failures or validation errors.
|
|
38
|
+
- ✅ **Warning:** For cautionary information that requires attention.
|
|
39
|
+
- ✅ **Success:** For positive confirmations of completed actions.
|
|
40
|
+
- ✅ **Info:** For neutral, informational messages.
|
|
41
|
+
|
|
42
|
+
## Status Types
|
|
43
|
+
|
|
44
|
+
### Error
|
|
45
|
+
Use for critical failures, errors, or validation issues that prevent users from proceeding.
|
|
46
|
+
|
|
47
|
+
<Canvas of={DsAlertStories.Error} />
|
|
48
|
+
|
|
49
|
+
### Warning
|
|
50
|
+
Use for cautionary information that requires user attention but doesn't prevent action.
|
|
51
|
+
|
|
52
|
+
<Canvas of={DsAlertStories.Warning} />
|
|
53
|
+
|
|
54
|
+
### Success
|
|
55
|
+
Use to confirm that an action was completed successfully.
|
|
56
|
+
|
|
57
|
+
<Canvas of={DsAlertStories.Success} />
|
|
58
|
+
|
|
59
|
+
### Info
|
|
60
|
+
Use for neutral, informational messages that don't require immediate action.
|
|
61
|
+
|
|
62
|
+
<Canvas of={DsAlertStories.Info} />
|
|
63
|
+
|
|
64
|
+
## Functionality & States
|
|
65
|
+
|
|
66
|
+
### Non-Dismissible
|
|
67
|
+
Alerts can be made non-dismissible for critical information that must remain visible.
|
|
68
|
+
|
|
69
|
+
<Canvas of={DsAlertStories.NonDismissible} />
|
|
70
|
+
|
|
71
|
+
### With Title
|
|
72
|
+
Use the title property for alerts that need a heading above the main message.
|
|
73
|
+
|
|
74
|
+
<Canvas of={DsAlertStories.WithTitle} />
|
|
75
|
+
|
|
76
|
+
## Accessibility
|
|
77
|
+
|
|
78
|
+
<table style={{ width: '100%' }}>
|
|
79
|
+
<thead>
|
|
80
|
+
<tr>
|
|
81
|
+
<th>Attribute</th>
|
|
82
|
+
<th>Value</th>
|
|
83
|
+
<th>Notes</th>
|
|
84
|
+
</tr>
|
|
85
|
+
</thead>
|
|
86
|
+
<tbody>
|
|
87
|
+
<tr>
|
|
88
|
+
<td><code>role</code></td>
|
|
89
|
+
<td><code>alert</code></td>
|
|
90
|
+
<td>Automatically applied for screen reader announcements</td>
|
|
91
|
+
</tr>
|
|
92
|
+
<tr>
|
|
93
|
+
<td><code>aria-label</code></td>
|
|
94
|
+
<td><code>"Fechar alerta"</code></td>
|
|
95
|
+
<td>Applied to close button for accessibility</td>
|
|
96
|
+
</tr>
|
|
97
|
+
</tbody>
|
|
98
|
+
</table>
|
|
99
|
+
|
|
100
|
+
### Keyboard Support
|
|
101
|
+
|
|
102
|
+
<table style={{ width: '100%' }}>
|
|
103
|
+
<thead>
|
|
104
|
+
<tr>
|
|
105
|
+
<th>Key</th>
|
|
106
|
+
<th>Action</th>
|
|
107
|
+
</tr>
|
|
108
|
+
</thead>
|
|
109
|
+
<tbody>
|
|
110
|
+
<tr>
|
|
111
|
+
<td><kbd>Tab</kbd></td>
|
|
112
|
+
<td>Moves focus to close button or action buttons</td>
|
|
113
|
+
</tr>
|
|
114
|
+
<tr>
|
|
115
|
+
<td><kbd>Enter</kbd> / <kbd>Space</kbd></td>
|
|
116
|
+
<td>Activates focused button (close or action)</td>
|
|
117
|
+
</tr>
|
|
118
|
+
<tr>
|
|
119
|
+
<td><kbd>Shift</kbd> + <kbd>Tab</kbd></td>
|
|
120
|
+
<td>Moves focus to previous focusable element</td>
|
|
121
|
+
</tr>
|
|
122
|
+
</tbody>
|
|
123
|
+
</table>
|
|
124
|
+
|
|
125
|
+
## Events
|
|
126
|
+
|
|
127
|
+
<table style={{ width: '100%' }}>
|
|
128
|
+
<thead>
|
|
129
|
+
<tr>
|
|
130
|
+
<th>Event</th>
|
|
131
|
+
<th>Detail</th>
|
|
132
|
+
<th>Description</th>
|
|
133
|
+
</tr>
|
|
134
|
+
</thead>
|
|
135
|
+
<tbody>
|
|
136
|
+
<tr>
|
|
137
|
+
<td><code>ds-dismiss</code></td>
|
|
138
|
+
<td><code>{}</code></td>
|
|
139
|
+
<td>Fired when the user clicks the close button</td>
|
|
140
|
+
</tr>
|
|
141
|
+
</tbody>
|
|
142
|
+
</table>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import './ds-alert.js';
|
|
3
|
+
import '../ds-button/ds-button.js';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Components/Alert',
|
|
7
|
+
component: 'ds-alert',
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
argTypes: {
|
|
10
|
+
status: {
|
|
11
|
+
control: 'select',
|
|
12
|
+
options: ['error', 'warning', 'success', 'info'],
|
|
13
|
+
description: 'Status type that determines background color and icon',
|
|
14
|
+
table: {
|
|
15
|
+
defaultValue: { summary: 'info' }
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
title: {
|
|
19
|
+
control: 'text',
|
|
20
|
+
description: 'Optional title text'
|
|
21
|
+
},
|
|
22
|
+
message: {
|
|
23
|
+
control: 'text',
|
|
24
|
+
description: 'Message text'
|
|
25
|
+
},
|
|
26
|
+
hideIcon: {
|
|
27
|
+
control: 'boolean',
|
|
28
|
+
description: 'Hide the status icon',
|
|
29
|
+
table: {
|
|
30
|
+
defaultValue: { summary: 'false' }
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
dismissible: {
|
|
34
|
+
control: 'boolean',
|
|
35
|
+
description: 'Show/hide close button',
|
|
36
|
+
table: {
|
|
37
|
+
defaultValue: { summary: 'true' }
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const Template = (args) => html`
|
|
44
|
+
<ds-alert
|
|
45
|
+
.status=${args.status}
|
|
46
|
+
.title=${args.title}
|
|
47
|
+
.message=${args.message}
|
|
48
|
+
?dismissible=${args.dismissible}
|
|
49
|
+
?hide-icon=${args.hideIcon}
|
|
50
|
+
>
|
|
51
|
+
${args.slotContent ? html`${args.slotContent}` : ''}
|
|
52
|
+
</ds-alert>
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Default alert with info status
|
|
57
|
+
*/
|
|
58
|
+
export const Default = {
|
|
59
|
+
args: {
|
|
60
|
+
status: 'info',
|
|
61
|
+
title: 'Alert Title',
|
|
62
|
+
message: 'This is an informational message.',
|
|
63
|
+
dismissible: true,
|
|
64
|
+
hideIcon: false
|
|
65
|
+
},
|
|
66
|
+
render: (args) => Template(args)
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Error status for critical/failed states
|
|
71
|
+
*/
|
|
72
|
+
export const Error = {
|
|
73
|
+
args: {
|
|
74
|
+
status: 'error',
|
|
75
|
+
message: 'An error occurred while processing your request.',
|
|
76
|
+
dismissible: true
|
|
77
|
+
},
|
|
78
|
+
render: (args) => Template(args)
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Warning status for caution/attention states
|
|
83
|
+
*/
|
|
84
|
+
export const Warning = {
|
|
85
|
+
args: {
|
|
86
|
+
status: 'warning',
|
|
87
|
+
message: 'Please review your changes before proceeding.',
|
|
88
|
+
dismissible: true
|
|
89
|
+
},
|
|
90
|
+
render: (args) => Template(args)
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Success status for completed/positive states
|
|
95
|
+
*/
|
|
96
|
+
export const Success = {
|
|
97
|
+
args: {
|
|
98
|
+
status: 'success',
|
|
99
|
+
message: 'Your changes have been saved successfully.',
|
|
100
|
+
dismissible: true
|
|
101
|
+
},
|
|
102
|
+
render: (args) => Template(args)
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Info status for informational states
|
|
107
|
+
*/
|
|
108
|
+
export const Info = {
|
|
109
|
+
args: {
|
|
110
|
+
status: 'info',
|
|
111
|
+
message: 'New features are now available in your dashboard.',
|
|
112
|
+
dismissible: true
|
|
113
|
+
},
|
|
114
|
+
render: (args) => Template(args)
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Alert without dismiss button
|
|
119
|
+
*/
|
|
120
|
+
export const NonDismissible = {
|
|
121
|
+
args: {
|
|
122
|
+
status: 'warning',
|
|
123
|
+
message: 'This alert cannot be dismissed.',
|
|
124
|
+
dismissible: false
|
|
125
|
+
},
|
|
126
|
+
render: (args) => Template(args)
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Alert with title and description using properties
|
|
131
|
+
*/
|
|
132
|
+
export const WithTitle = {
|
|
133
|
+
args: {
|
|
134
|
+
status: 'error',
|
|
135
|
+
title: 'Payment Failed',
|
|
136
|
+
message: 'Your payment could not be processed. Please check your payment details and try again.',
|
|
137
|
+
dismissible: true
|
|
138
|
+
},
|
|
139
|
+
render: (args) => Template(args)
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Alert with action buttons
|
|
144
|
+
*/
|
|
145
|
+
export const WithActions = {
|
|
146
|
+
args: {
|
|
147
|
+
status: 'info',
|
|
148
|
+
message: 'A new version of the application is available.',
|
|
149
|
+
dismissible: true
|
|
150
|
+
},
|
|
151
|
+
render: (args) => html`
|
|
152
|
+
<ds-alert
|
|
153
|
+
.status=${args.status}
|
|
154
|
+
.title=${args.title}
|
|
155
|
+
.message=${args.message}
|
|
156
|
+
?dismissible=${args.dismissible}
|
|
157
|
+
>
|
|
158
|
+
<div slot="actions" style="display: flex; gap: 8px;">
|
|
159
|
+
<ds-button variant="action">Update</ds-button>
|
|
160
|
+
<ds-button variant="action">Later</ds-button>
|
|
161
|
+
</div>
|
|
162
|
+
</ds-alert>
|
|
163
|
+
`
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
|