@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,55 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import './ds-tag-action.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Components/Tag Action',
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: 'padded',
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const ActionTemplate = (args) => html`
|
|
12
|
+
<ds-tag-action
|
|
13
|
+
label=${args.label}
|
|
14
|
+
icon=${args.icon}
|
|
15
|
+
size=${args.size}
|
|
16
|
+
color=${args.color}
|
|
17
|
+
?selected=${args.selected}
|
|
18
|
+
?disabled=${args.disabled}
|
|
19
|
+
@ds-selected-change=${(e) => console.log('Selection changed:', e.detail)}
|
|
20
|
+
></ds-tag-action>
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
export const Default = ActionTemplate.bind({});
|
|
24
|
+
Default.args = {
|
|
25
|
+
label: 'Action Tag',
|
|
26
|
+
icon: 'star',
|
|
27
|
+
size: 'm',
|
|
28
|
+
color: 'neutral',
|
|
29
|
+
selected: false,
|
|
30
|
+
disabled: false,
|
|
31
|
+
};
|
|
32
|
+
Default.argTypes = {
|
|
33
|
+
size: { control: { type: 'select' }, options: ['s', 'm'] },
|
|
34
|
+
color: { control: { type: 'select' }, options: ['neutral', 'info'] },
|
|
35
|
+
icon: { control: 'text' },
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const AllStates = () => html`
|
|
39
|
+
<div style="display: flex; gap: 16px; flex-direction: column;">
|
|
40
|
+
<!-- Neutral -->
|
|
41
|
+
<div style="display: flex; gap: 8px; align-items: center;">
|
|
42
|
+
<ds-tag-action label="Neutral M" size="m" color="neutral"></ds-tag-action>
|
|
43
|
+
<ds-tag-action label="Neutral S" size="s" color="neutral"></ds-tag-action>
|
|
44
|
+
<ds-tag-action label="Selected" size="m" color="neutral" selected></ds-tag-action>
|
|
45
|
+
<ds-tag-action label="Disabled" size="m" color="neutral" disabled></ds-tag-action>
|
|
46
|
+
</div>
|
|
47
|
+
<!-- Info -->
|
|
48
|
+
<div style="display: flex; gap: 8px; align-items: center;">
|
|
49
|
+
<ds-tag-action label="Info M" size="m" color="info"></ds-tag-action>
|
|
50
|
+
<ds-tag-action label="Info S" size="s" color="info"></ds-tag-action>
|
|
51
|
+
<ds-tag-action label="Selected" size="m" color="info" selected></ds-tag-action>
|
|
52
|
+
<ds-tag-action label="Disabled" size="m" color="info" disabled></ds-tag-action>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
`;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import './ds-tag-action.js';
|
|
3
|
+
|
|
4
|
+
describe('DsTagAction', () => {
|
|
5
|
+
let container;
|
|
6
|
+
beforeEach(() => { container = document.createElement('div'); document.body.appendChild(container); });
|
|
7
|
+
afterEach(() => { container.remove(); });
|
|
8
|
+
|
|
9
|
+
it('renders with default values', async () => {
|
|
10
|
+
container.innerHTML = '<ds-tag-action label="Test"></ds-tag-action>';
|
|
11
|
+
await new Promise(r => setTimeout(r, 0));
|
|
12
|
+
const el = container.querySelector('ds-tag-action');
|
|
13
|
+
expect(el.label).toBe('Test');
|
|
14
|
+
expect(el.shadowRoot.querySelector('span').textContent).toBe('Test');
|
|
15
|
+
expect(el.getAttribute('size')).toBe('m');
|
|
16
|
+
expect(el.getAttribute('color')).toBe('neutral');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('renders with icon', async () => {
|
|
20
|
+
container.innerHTML = '<ds-tag-action label="Test" icon="star"></ds-tag-action>';
|
|
21
|
+
await new Promise(r => setTimeout(r, 0));
|
|
22
|
+
const el = container.querySelector('ds-tag-action');
|
|
23
|
+
const icon = el.shadowRoot.querySelector('ds-icon');
|
|
24
|
+
expect(icon).to.exist;
|
|
25
|
+
expect(icon.getAttribute('name')).toBe('star');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('reflects selected state', async () => {
|
|
29
|
+
container.innerHTML = '<ds-tag-action label="Test" selected></ds-tag-action>';
|
|
30
|
+
await new Promise(r => setTimeout(r, 0));
|
|
31
|
+
const el = container.querySelector('ds-tag-action');
|
|
32
|
+
expect(el.hasAttribute('selected')).toBe(true);
|
|
33
|
+
const btn = el.shadowRoot.querySelector('button');
|
|
34
|
+
expect(btn.getAttribute('aria-pressed')).toBe('true');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('reflects disabled state', async () => {
|
|
38
|
+
container.innerHTML = '<ds-tag-action label="Test" disabled></ds-tag-action>';
|
|
39
|
+
await new Promise(r => setTimeout(r, 0));
|
|
40
|
+
const el = container.querySelector('ds-tag-action');
|
|
41
|
+
const btn = el.shadowRoot.querySelector('button');
|
|
42
|
+
expect(btn.hasAttribute('disabled')).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import './ds-tag-removable.js';
|
|
3
|
+
|
|
4
|
+
describe('DsTagRemovable A11y', () => {
|
|
5
|
+
let container;
|
|
6
|
+
beforeEach(() => { container = document.createElement('div'); document.body.appendChild(container); });
|
|
7
|
+
afterEach(() => { container.remove(); });
|
|
8
|
+
|
|
9
|
+
it('internal remove button has correct aria-label', async () => {
|
|
10
|
+
container.innerHTML = '<ds-tag-removable label="My Tag"></ds-tag-removable>';
|
|
11
|
+
await new Promise(r => setTimeout(r, 0));
|
|
12
|
+
const el = container.querySelector('ds-tag-removable');
|
|
13
|
+
const btn = el.shadowRoot.querySelector('ds-icon-button');
|
|
14
|
+
expect(btn.getAttribute('aria-label')).toBe('Remove My Tag');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('internal button disabled state', async () => {
|
|
18
|
+
container.innerHTML = '<ds-tag-removable label="Disabled" disabled></ds-tag-removable>';
|
|
19
|
+
await new Promise(r => setTimeout(r, 0));
|
|
20
|
+
const el = container.querySelector('ds-tag-removable');
|
|
21
|
+
const btn = el.shadowRoot.querySelector('ds-icon-button');
|
|
22
|
+
expect(btn.hasAttribute('disabled')).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,146 @@
|
|
|
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
|
+
* @element ds-tag-removable
|
|
7
|
+
* @summary A square-edged tag with a remove action.
|
|
8
|
+
*
|
|
9
|
+
* @prop {string} label - Text label.
|
|
10
|
+
* @prop {string} icon - Optional icon name (left).
|
|
11
|
+
* @prop {boolean} disabled - Whether the tag (and remove action) is disabled.
|
|
12
|
+
* @prop {string} size - 's' (24px) | 'm' (32px). Default: 'm'.
|
|
13
|
+
* @prop {string} color - 'neutral' | 'info'. Default: 'neutral'.
|
|
14
|
+
*
|
|
15
|
+
* @fires ds-tag-remove - Dispatched when remove button is clicked.
|
|
16
|
+
*/
|
|
17
|
+
export class DsTagRemovable extends LitElement {
|
|
18
|
+
static properties = {
|
|
19
|
+
label: { type: String },
|
|
20
|
+
icon: { type: String },
|
|
21
|
+
disabled: { type: Boolean, reflect: true },
|
|
22
|
+
size: { type: String, reflect: true },
|
|
23
|
+
color: { type: String, reflect: true },
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
static styles = css`
|
|
27
|
+
:host {
|
|
28
|
+
display: inline-flex;
|
|
29
|
+
vertical-align: middle;
|
|
30
|
+
box-sizing: border-box;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.container {
|
|
34
|
+
display: inline-flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
box-sizing: border-box;
|
|
37
|
+
|
|
38
|
+
border-radius: var(--ds-radius-container, 0px); /* Square/Sharp */
|
|
39
|
+
|
|
40
|
+
font: var(--ds-typo-content-body-regular);
|
|
41
|
+
color: var(--ds-color-text-default);
|
|
42
|
+
white-space: nowrap; /* Prevent breaking on resize */
|
|
43
|
+
|
|
44
|
+
/* Gap Logic:
|
|
45
|
+
Gap between Icon and Label is 4px.
|
|
46
|
+
Label to Action gap is 4px.
|
|
47
|
+
*/
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.content-wrapper {
|
|
51
|
+
display: inline-flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
gap: 4px; /* Icon to Label gap */
|
|
54
|
+
margin-right: 4px; /* Label to Action gap */
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
* SIZES
|
|
59
|
+
*/
|
|
60
|
+
/* Size M: 32px height */
|
|
61
|
+
:host([size="m"]) .container,
|
|
62
|
+
:host(:not([size])) .container {
|
|
63
|
+
height: 32px;
|
|
64
|
+
padding: 0 4px 0 var(--ds-space-sm);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Size S: 24px height */
|
|
68
|
+
:host([size="s"]) .container {
|
|
69
|
+
height: 24px;
|
|
70
|
+
padding: 0 4px 0 var(--ds-space-sm);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/*
|
|
74
|
+
* COLORS
|
|
75
|
+
*/
|
|
76
|
+
/* NEUTRAL */
|
|
77
|
+
:host([color="neutral"]) .container,
|
|
78
|
+
:host(:not([color])) .container {
|
|
79
|
+
background-color: var(--ds-color-bg-neutral-subtle);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* INFO */
|
|
83
|
+
:host([color="info"]) .container {
|
|
84
|
+
background-color: var(--ds-color-bg-brand-subtle);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/*
|
|
88
|
+
* DISABLED
|
|
89
|
+
*/
|
|
90
|
+
:host([disabled]) {
|
|
91
|
+
/* Reset opacity strategy */
|
|
92
|
+
pointer-events: none;
|
|
93
|
+
}
|
|
94
|
+
:host([disabled]) .container {
|
|
95
|
+
background-color: var(--ds-color-bg-disabled);
|
|
96
|
+
color: var(--ds-color-text-disabled);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
ds-icon {
|
|
100
|
+
/* User: "tamanho do ícone deve ser size S em ambos os casos" */
|
|
101
|
+
--size: var(--ds-icon-size-sm, 20px);
|
|
102
|
+
color: currentColor;
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
constructor() {
|
|
107
|
+
super();
|
|
108
|
+
this.disabled = false;
|
|
109
|
+
this.size = 'm';
|
|
110
|
+
this.color = 'neutral';
|
|
111
|
+
this.label = '';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
_handleRemove(e) {
|
|
115
|
+
e.stopPropagation(); // Don't bubble click if container had one (optional)
|
|
116
|
+
this.dispatchEvent(new CustomEvent('ds-tag-remove', {
|
|
117
|
+
bubbles: true,
|
|
118
|
+
composed: true
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
render() {
|
|
123
|
+
return html`
|
|
124
|
+
<div class="container" part="container">
|
|
125
|
+
<div class="content-wrapper">
|
|
126
|
+
${this.icon ? html`<ds-icon name=${this.icon} size="sm" part="icon"></ds-icon>` : ''}
|
|
127
|
+
<span>${this.label}</span>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<ds-icon-button
|
|
131
|
+
icon="close"
|
|
132
|
+
variant="action"
|
|
133
|
+
size="s"
|
|
134
|
+
?disabled=${this.disabled}
|
|
135
|
+
aria-label="Remove ${this.label}"
|
|
136
|
+
@click=${this._handleRemove}
|
|
137
|
+
part="remove-button"
|
|
138
|
+
></ds-icon-button>
|
|
139
|
+
</div>
|
|
140
|
+
`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (!customElements.get('ds-tag-removable')) {
|
|
145
|
+
customElements.define('ds-tag-removable', DsTagRemovable);
|
|
146
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import './ds-tag-removable.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Components/Tag Removable',
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: 'padded',
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const RemovableTemplate = (args) => html`
|
|
12
|
+
<ds-tag-removable
|
|
13
|
+
label=${args.label}
|
|
14
|
+
icon=${args.icon}
|
|
15
|
+
size=${args.size}
|
|
16
|
+
color=${args.color}
|
|
17
|
+
?disabled=${args.disabled}
|
|
18
|
+
@ds-tag-remove=${() => console.log('Remove Clicked')}
|
|
19
|
+
></ds-tag-removable>
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
export const Default = RemovableTemplate.bind({});
|
|
23
|
+
Default.args = {
|
|
24
|
+
label: 'Removable Tag',
|
|
25
|
+
icon: 'star',
|
|
26
|
+
size: 'm',
|
|
27
|
+
color: 'neutral',
|
|
28
|
+
disabled: false,
|
|
29
|
+
};
|
|
30
|
+
Default.argTypes = {
|
|
31
|
+
size: { control: { type: 'select' }, options: ['s', 'm'] },
|
|
32
|
+
color: { control: { type: 'select' }, options: ['neutral', 'info'] },
|
|
33
|
+
icon: { control: 'text' },
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const AllStates = () => html`
|
|
37
|
+
<div style="display: flex; gap: 16px; flex-direction: column;">
|
|
38
|
+
<!-- Neutral -->
|
|
39
|
+
<div style="display: flex; gap: 8px; align-items: flex-start;">
|
|
40
|
+
<ds-tag-removable label="Neutral M" size="m" color="neutral"></ds-tag-removable>
|
|
41
|
+
<ds-tag-removable label="Neutral S" size="s" color="neutral"></ds-tag-removable>
|
|
42
|
+
<ds-tag-removable label="With Icon" icon="favorite" size="m" color="neutral"></ds-tag-removable>
|
|
43
|
+
<ds-tag-removable label="Disabled" size="m" color="neutral" disabled></ds-tag-removable>
|
|
44
|
+
</div>
|
|
45
|
+
<!-- Info -->
|
|
46
|
+
<div style="display: flex; gap: 8px; align-items: flex-start;">
|
|
47
|
+
<ds-tag-removable label="Info M" size="m" color="info"></ds-tag-removable>
|
|
48
|
+
<ds-tag-removable label="Info S" size="s" color="info"></ds-tag-removable>
|
|
49
|
+
<ds-tag-removable label="Disabled" size="m" color="info" disabled></ds-tag-removable>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
`;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import './ds-tag-removable.js';
|
|
3
|
+
|
|
4
|
+
describe('DsTagRemovable', () => {
|
|
5
|
+
let container;
|
|
6
|
+
beforeEach(() => { container = document.createElement('div'); document.body.appendChild(container); });
|
|
7
|
+
afterEach(() => { container.remove(); });
|
|
8
|
+
|
|
9
|
+
it('renders with default values', async () => {
|
|
10
|
+
container.innerHTML = '<ds-tag-removable label="Removable"></ds-tag-removable>';
|
|
11
|
+
await new Promise(r => setTimeout(r, 0));
|
|
12
|
+
const el = container.querySelector('ds-tag-removable');
|
|
13
|
+
expect(el.label).toBe('Removable');
|
|
14
|
+
expect(el.shadowRoot.querySelector('span').textContent).toBe('Removable');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('dispatches ds-tag-remove event when close button is clicked', async () => {
|
|
18
|
+
container.innerHTML = '<ds-tag-removable label="Removable"></ds-tag-removable>';
|
|
19
|
+
await new Promise(r => setTimeout(r, 0));
|
|
20
|
+
const el = container.querySelector('ds-tag-removable');
|
|
21
|
+
const removeBtn = el.shadowRoot.querySelector('ds-icon-button');
|
|
22
|
+
|
|
23
|
+
const listener = vi.fn();
|
|
24
|
+
el.addEventListener('ds-tag-remove', listener);
|
|
25
|
+
|
|
26
|
+
removeBtn.click();
|
|
27
|
+
expect(listener).toHaveBeenCalled();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('passes disabled state to icon button', async () => {
|
|
31
|
+
container.innerHTML = '<ds-tag-removable label="Removable" disabled></ds-tag-removable>';
|
|
32
|
+
await new Promise(r => setTimeout(r, 0));
|
|
33
|
+
const el = container.querySelector('ds-tag-removable');
|
|
34
|
+
const removeBtn = el.shadowRoot.querySelector('ds-icon-button');
|
|
35
|
+
expect(removeBtn.hasAttribute('disabled')).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('renders size S structure', async () => {
|
|
39
|
+
container.innerHTML = '<ds-tag-removable label="Small" size="s"></ds-tag-removable>';
|
|
40
|
+
await new Promise(r => setTimeout(r, 0));
|
|
41
|
+
const el = container.querySelector('ds-tag-removable');
|
|
42
|
+
const removeBtn = el.shadowRoot.querySelector('ds-icon-button');
|
|
43
|
+
expect(removeBtn.getAttribute('size')).toBe('s');
|
|
44
|
+
expect(el.getAttribute('size')).toBe('s');
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import axe from 'axe-core';
|
|
3
|
+
import './ds-tag-status.js';
|
|
4
|
+
|
|
5
|
+
describe('ds-tag-status 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('should pass axe accessibility checks with size S', async () => {
|
|
18
|
+
container.innerHTML = '<ds-tag-status status="success" label="Active"></ds-tag-status>';
|
|
19
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
20
|
+
|
|
21
|
+
const results = await axe.run(container, {
|
|
22
|
+
rules: { 'color-contrast': { enabled: false } }
|
|
23
|
+
});
|
|
24
|
+
if (results.violations.length > 0) {
|
|
25
|
+
console.log('Violations:', JSON.stringify(results.violations, null, 2));
|
|
26
|
+
}
|
|
27
|
+
expect(results.violations).toHaveLength(0);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should pass axe accessibility checks with size XS', async () => {
|
|
31
|
+
container.innerHTML = '<ds-tag-status size="xs" status="warning" label="Pending"></ds-tag-status>';
|
|
32
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
33
|
+
|
|
34
|
+
const results = await axe.run(container, {
|
|
35
|
+
rules: { 'color-contrast': { enabled: false } }
|
|
36
|
+
});
|
|
37
|
+
expect(results.violations).toHaveLength(0);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should pass axe accessibility checks for error status', async () => {
|
|
41
|
+
container.innerHTML = '<ds-tag-status status="error" label="Failed"></ds-tag-status>';
|
|
42
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
43
|
+
|
|
44
|
+
const results = await axe.run(container, {
|
|
45
|
+
rules: { 'color-contrast': { enabled: false } }
|
|
46
|
+
});
|
|
47
|
+
expect(results.violations).toHaveLength(0);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should pass axe accessibility checks for info status', async () => {
|
|
51
|
+
container.innerHTML = '<ds-tag-status status="info" label="Information"></ds-tag-status>';
|
|
52
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
53
|
+
|
|
54
|
+
const results = await axe.run(container, {
|
|
55
|
+
rules: { 'color-contrast': { enabled: false } }
|
|
56
|
+
});
|
|
57
|
+
expect(results.violations).toHaveLength(0);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should pass axe accessibility checks for neutral status', async () => {
|
|
61
|
+
container.innerHTML = '<ds-tag-status status="neutral" label="Draft"></ds-tag-status>';
|
|
62
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
63
|
+
|
|
64
|
+
const results = await axe.run(container, {
|
|
65
|
+
rules: { 'color-contrast': { enabled: false } }
|
|
66
|
+
});
|
|
67
|
+
expect(results.violations).toHaveLength(0);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should pass axe accessibility checks without icon', async () => {
|
|
71
|
+
container.innerHTML = '<ds-tag-status hide-icon status="success" label="Complete"></ds-tag-status>';
|
|
72
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
73
|
+
|
|
74
|
+
const results = await axe.run(container, {
|
|
75
|
+
rules: { 'color-contrast': { enabled: false } }
|
|
76
|
+
});
|
|
77
|
+
expect(results.violations).toHaveLength(0);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should pass axe accessibility checks with all statuses', async () => {
|
|
81
|
+
const statuses = ['error', 'warning', 'success', 'info', 'neutral'];
|
|
82
|
+
|
|
83
|
+
for (const status of statuses) {
|
|
84
|
+
container.innerHTML = `<ds-tag-status status="${status}" label="Test ${status}"></ds-tag-status>`;
|
|
85
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
86
|
+
|
|
87
|
+
const results = await axe.run(container, {
|
|
88
|
+
rules: { 'color-contrast': { enabled: false } }
|
|
89
|
+
});
|
|
90
|
+
expect(results.violations).toHaveLength(0);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { LitElement, html, css } from 'lit';
|
|
2
|
+
import '../ds-icon/ds-icon.js';
|
|
3
|
+
|
|
4
|
+
// Icon mapping constant
|
|
5
|
+
const STATUS_ICONS = {
|
|
6
|
+
error: 'cancel',
|
|
7
|
+
warning: 'warning',
|
|
8
|
+
success: 'check-circle',
|
|
9
|
+
info: 'info',
|
|
10
|
+
neutral: 'pending'
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Tag status component for displaying status indicators
|
|
15
|
+
*
|
|
16
|
+
* @element ds-tag-status
|
|
17
|
+
*
|
|
18
|
+
* @prop {string} status - Status type: 'error' | 'warning' | 'success' | 'info' | 'neutral' (default: 'neutral')
|
|
19
|
+
* @prop {string} size - Size variant: 's' | 'xs' (default: 's')
|
|
20
|
+
* @prop {string} label - Label text to display
|
|
21
|
+
* @prop {boolean} hideIcon - Hide icon in size S (default: false)
|
|
22
|
+
* @prop {string} icon - Custom icon name (overrides status-based icon)
|
|
23
|
+
*
|
|
24
|
+
* @csspart container - The main container element
|
|
25
|
+
* @csspart icon - The icon element
|
|
26
|
+
* @csspart label - The label text element
|
|
27
|
+
*/
|
|
28
|
+
export class DsTagStatus extends LitElement {
|
|
29
|
+
static properties = {
|
|
30
|
+
status: { type: String, reflect: true },
|
|
31
|
+
size: { type: String, reflect: true },
|
|
32
|
+
label: { type: String },
|
|
33
|
+
hideIcon: { type: Boolean, attribute: 'hide-icon', reflect: true },
|
|
34
|
+
icon: { type: String }
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
static styles = css`
|
|
38
|
+
:host {
|
|
39
|
+
display: inline-flex;
|
|
40
|
+
vertical-align: middle;
|
|
41
|
+
box-sizing: border-box;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.container {
|
|
45
|
+
display: inline-flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
box-sizing: border-box;
|
|
48
|
+
border-radius: var(--ds-radius-container); /* 0px - sharp */
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Size S (default): 24px height */
|
|
52
|
+
:host([size="s"]) .container,
|
|
53
|
+
:host(:not([size])) .container {
|
|
54
|
+
height: 24px;
|
|
55
|
+
padding: 2px var(--ds-space-sm); /* 2px vertical, 8px horizontal */
|
|
56
|
+
gap: var(--ds-space-xs); /* 4px gap between icon and label */
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
:host([size="s"]) .label,
|
|
60
|
+
:host(:not([size])) .label {
|
|
61
|
+
font: var(--ds-typo-content-body-regular);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Size XS: 20px height (caption text box height) */
|
|
65
|
+
:host([size="xs"]) .container {
|
|
66
|
+
height: 20px;
|
|
67
|
+
padding: 2px var(--ds-space-sm); /* 2px vertical, 8px horizontal */
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
:host([size="xs"]) .label {
|
|
71
|
+
font: var(--ds-typo-content-caption-regular);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Label styling */
|
|
75
|
+
.label {
|
|
76
|
+
color: var(--ds-color-text-default);
|
|
77
|
+
white-space: nowrap;
|
|
78
|
+
line-height: 1;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Icon styling */
|
|
82
|
+
ds-icon {
|
|
83
|
+
color: var(--ds-color-icon-default);
|
|
84
|
+
flex-shrink: 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Status: Error */
|
|
88
|
+
:host([status="error"]) .container {
|
|
89
|
+
background-color: var(--ds-color-bg-error-subtle);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Status: Warning */
|
|
93
|
+
:host([status="warning"]) .container {
|
|
94
|
+
background-color: var(--ds-color-bg-warning-subtle);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* Status: Success */
|
|
98
|
+
:host([status="success"]) .container {
|
|
99
|
+
background-color: var(--ds-color-bg-success-subtle);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Status: Info */
|
|
103
|
+
:host([status="info"]) .container {
|
|
104
|
+
background-color: var(--ds-color-bg-info-subtle);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Status: Neutral (default) */
|
|
108
|
+
:host([status="neutral"]) .container,
|
|
109
|
+
:host(:not([status])) .container {
|
|
110
|
+
background-color: var(--ds-color-bg-neutral-subtle);
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
|
|
114
|
+
constructor() {
|
|
115
|
+
super();
|
|
116
|
+
this.status = 'neutral';
|
|
117
|
+
this.size = 's';
|
|
118
|
+
this.label = '';
|
|
119
|
+
this.hideIcon = false;
|
|
120
|
+
this.icon = '';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Returns the icon name based on the status
|
|
125
|
+
* @returns {string} Icon name
|
|
126
|
+
*/
|
|
127
|
+
_getIconName() {
|
|
128
|
+
// If custom icon is provided, use it
|
|
129
|
+
if (this.icon) {
|
|
130
|
+
return this.icon;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Otherwise use status-based icon
|
|
134
|
+
return STATUS_ICONS[this.status] || STATUS_ICONS.neutral;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Determines if the icon should be shown
|
|
139
|
+
* @returns {boolean} Whether to show the icon
|
|
140
|
+
*/
|
|
141
|
+
_shouldShowIcon() {
|
|
142
|
+
// Only show icon in size S, unless hideIcon is true
|
|
143
|
+
return this.size !== 'xs' && !this.hideIcon;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
render() {
|
|
147
|
+
const showIcon = this._shouldShowIcon();
|
|
148
|
+
|
|
149
|
+
return html`
|
|
150
|
+
<div class="container" part="container">
|
|
151
|
+
${showIcon ? html`
|
|
152
|
+
<ds-icon
|
|
153
|
+
name="${this._getIconName()}"
|
|
154
|
+
size="sm"
|
|
155
|
+
part="icon"
|
|
156
|
+
></ds-icon>
|
|
157
|
+
` : ''}
|
|
158
|
+
<span class="label" part="label">${this.label}</span>
|
|
159
|
+
</div>
|
|
160
|
+
`;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
customElements.define('ds-tag-status', DsTagStatus);
|