@ds-mo/ui 1.1.0 → 1.3.0
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/README.md +82 -3
- package/dist/components/ds-badge.js +1 -1
- package/dist/components/ds-badge.js.map +1 -1
- package/dist/components/ds-banner.js +1 -1
- package/dist/components/ds-banner.js.map +1 -1
- package/dist/components/ds-bar-nav-action.js +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-nav.js.map +1 -1
- package/dist/components/ds-button-group.js +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/{ds-label-wrap.d.ts → ds-chip.d.ts} +4 -4
- package/dist/components/ds-chip.js +2 -0
- package/dist/components/ds-chip.js.map +1 -0
- package/dist/components/ds-divider.js +1 -1
- package/dist/components/ds-divider.js.map +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-fade.js +1 -1
- package/dist/components/ds-fade.js.map +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-header.js +1 -1
- package/dist/components/ds-icon.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-modal.js +1 -1
- package/dist/components/ds-modal.js.map +1 -1
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-nav.js.map +1 -1
- package/dist/components/ds-radio-group.js +1 -1
- package/dist/components/ds-radio-group.js.map +1 -1
- package/dist/components/ds-scrollbar.js +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-sidebar.js +1 -1
- package/dist/components/ds-sidebar.js.map +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-slider.js.map +1 -1
- package/dist/components/ds-surface.js +1 -1
- package/dist/components/ds-tab-group-nav.js +1 -1
- package/dist/components/ds-tab-group.js +1 -1
- package/dist/components/ds-tab-group.js.map +1 -1
- package/dist/components/ds-table.js +1 -1
- package/dist/components/ds-table.js.map +1 -1
- package/dist/components/ds-tag.js +1 -1
- package/dist/components/ds-tag.js.map +1 -1
- package/dist/components/ds-text.js +1 -1
- package/dist/components/ds-toast-provider.js +1 -1
- package/dist/components/ds-toggle-button-group.js +1 -1
- package/dist/components/ds-toggle-button.js +1 -1
- package/dist/components/ds-toggle.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/p-B_enucPQ.js +2 -0
- package/dist/components/p-B_enucPQ.js.map +1 -0
- package/dist/components/p-DOtcc9UU.js +2 -0
- package/dist/components/p-DOtcc9UU.js.map +1 -0
- package/dist/components/{p-H89PzqGU.js → p-DrDrPeVV.js} +2 -2
- package/dist/components/p-OT-Q-NxH.js +2 -0
- package/dist/components/p-OT-Q-NxH.js.map +1 -0
- package/dist/components/{p-Dd0GrKaF.js → p-U1A-rprN.js} +2 -2
- package/dist/components/p-X1N_ggsY.js +2 -0
- package/dist/components/p-X1N_ggsY.js.map +1 -0
- package/dist/components/p-qfvbc9w-.js +2 -0
- package/dist/components/p-qfvbc9w-.js.map +1 -0
- package/dist/types/.stencil/Badge/Badge.d.ts +12 -0
- package/dist/types/.stencil/Badge/index.d.ts +1 -1
- package/dist/types/.stencil/Chip/Chip.d.ts +30 -0
- package/dist/types/.stencil/Chip/index.d.ts +2 -0
- package/dist/types/.stencil/Divider/Divider.d.ts +14 -0
- package/dist/types/.stencil/Fade/Fade.d.ts +17 -2
- package/dist/types/.stencil/Fade/index.d.ts +1 -1
- package/dist/types/.stencil/Tag/Tag.d.ts +0 -17
- package/dist/types/.stencil/Tag/index.d.ts +1 -1
- package/dist/types/.stencil/Text/Text.d.ts +2 -0
- package/dist/types/components.d.ts +283 -143
- package/package.json +12 -5
- package/src/angular/index.ts +1 -1
- package/src/angular/proxies.ts +51 -51
- package/src/react/components.ts +1 -1
- package/src/react/ds-chip.ts +35 -0
- package/src/react/ds-tag.ts +3 -12
- package/src/wc/components/Badge/Badge.tsx +58 -8
- package/src/wc/components/Badge/index.ts +1 -1
- package/src/wc/components/Banner/Banner.tsx +2 -2
- package/src/wc/components/BarNav/BarNav.tsx +7 -1
- package/src/wc/components/BarNavAction/BarNavAction.tsx +9 -1
- package/src/wc/components/Chip/Chip.tsx +127 -0
- package/src/wc/components/Chip/index.ts +1 -0
- package/src/wc/components/Divider/Divider.tsx +88 -4
- package/src/wc/components/Fade/Fade.tsx +86 -6
- package/src/wc/components/Fade/index.ts +1 -1
- package/src/wc/components/PanelNav/PanelNav.tsx +17 -1
- package/src/wc/components/TabGroup/TabGroup.tsx +9 -1
- package/src/wc/components/TabGroupNav/TabGroupNav.tsx +9 -1
- package/src/wc/components/Tag/Tag.tsx +3 -70
- package/src/wc/components/Tag/index.ts +1 -1
- package/src/wc/components/Text/Text.tsx +3 -0
- package/src/wc/components.d.ts +283 -143
- package/dist/components/ds-label-wrap.js +0 -2
- package/dist/components/ds-label-wrap.js.map +0 -1
- package/dist/components/p-CMyQsk0K.js +0 -2
- package/dist/components/p-CMyQsk0K.js.map +0 -1
- package/dist/components/p-Vwlmhl4E.js +0 -2
- package/dist/components/p-Vwlmhl4E.js.map +0 -1
- package/dist/components/p-woooYulR.js +0 -2
- package/dist/components/p-woooYulR.js.map +0 -1
- package/dist/types/.stencil/LabelWrap/LabelWrap.d.ts +0 -15
- package/src/react/ds-label-wrap.ts +0 -26
- package/src/wc/components/LabelWrap/LabelWrap.tsx +0 -38
- /package/dist/components/{p-H89PzqGU.js.map → p-DrDrPeVV.js.map} +0 -0
- /package/dist/components/{p-Dd0GrKaF.js.map → p-U1A-rprN.js.map} +0 -0
|
@@ -1,22 +1,106 @@
|
|
|
1
1
|
import { Component, Prop, h, Host } from '@stencil/core';
|
|
2
2
|
|
|
3
3
|
export type DividerOrientation = 'horizontal' | 'vertical';
|
|
4
|
+
export type DividerSurface =
|
|
5
|
+
| 'default'
|
|
6
|
+
| 'on-bold-background'
|
|
7
|
+
| 'on-strong-background'
|
|
8
|
+
| 'on-medium-background'
|
|
9
|
+
| 'on-translucent-background'
|
|
10
|
+
| 'navigation'
|
|
11
|
+
| 'media'
|
|
12
|
+
| 'always-dark'
|
|
13
|
+
| 'inverted';
|
|
14
|
+
export type DividerInsetToken =
|
|
15
|
+
| 'space-000'
|
|
16
|
+
| 'space-012'
|
|
17
|
+
| 'space-025'
|
|
18
|
+
| 'space-050'
|
|
19
|
+
| 'space-075'
|
|
20
|
+
| 'space-100'
|
|
21
|
+
| 'space-125'
|
|
22
|
+
| 'space-150'
|
|
23
|
+
| 'space-175'
|
|
24
|
+
| 'space-200'
|
|
25
|
+
| 'space-250'
|
|
26
|
+
| 'space-300'
|
|
27
|
+
| 'space-400'
|
|
28
|
+
| 'space-600'
|
|
29
|
+
| 'space-800';
|
|
30
|
+
export type DividerInset = 'none' | DividerInsetToken | (string & {});
|
|
31
|
+
export type DividerLength = 'auto' | 'full' | (string & {});
|
|
32
|
+
|
|
33
|
+
const INSET_VALUE: Record<'none' | DividerInsetToken, string> = {
|
|
34
|
+
none: '0',
|
|
35
|
+
'space-000': 'var(--dimension-space-000)',
|
|
36
|
+
'space-012': 'var(--dimension-space-012)',
|
|
37
|
+
'space-025': 'var(--dimension-space-025)',
|
|
38
|
+
'space-050': 'var(--dimension-space-050)',
|
|
39
|
+
'space-075': 'var(--dimension-space-075)',
|
|
40
|
+
'space-100': 'var(--dimension-space-100)',
|
|
41
|
+
'space-125': 'var(--dimension-space-125)',
|
|
42
|
+
'space-150': 'var(--dimension-space-150)',
|
|
43
|
+
'space-175': 'var(--dimension-space-175)',
|
|
44
|
+
'space-200': 'var(--dimension-space-200)',
|
|
45
|
+
'space-250': 'var(--dimension-space-250)',
|
|
46
|
+
'space-300': 'var(--dimension-space-300)',
|
|
47
|
+
'space-400': 'var(--dimension-space-400)',
|
|
48
|
+
'space-600': 'var(--dimension-space-600)',
|
|
49
|
+
'space-800': 'var(--dimension-space-800)',
|
|
50
|
+
};
|
|
4
51
|
|
|
5
52
|
@Component({
|
|
6
53
|
tag: 'ds-divider',
|
|
7
54
|
styleUrl: 'Divider.css',
|
|
8
|
-
|
|
55
|
+
scoped: true,
|
|
9
56
|
})
|
|
10
57
|
export class Divider {
|
|
11
58
|
/** Direction of the divider line. Defaults to 'horizontal'. */
|
|
12
59
|
@Prop() orientation: DividerOrientation = 'horizontal';
|
|
13
60
|
|
|
61
|
+
/** Surface context so the divider uses the right TokoMo divider token. */
|
|
62
|
+
@Prop() surface: DividerSurface = 'default';
|
|
63
|
+
|
|
64
|
+
/** Insets the divider from its start/end edges. Accepts spacing token names or any CSS length. */
|
|
65
|
+
@Prop() inset: DividerInset = 'none';
|
|
66
|
+
|
|
67
|
+
/** Visual line length. Defaults to filling the available axis. Accepts any CSS length. */
|
|
68
|
+
@Prop() length: DividerLength = 'auto';
|
|
69
|
+
|
|
70
|
+
/** Expose the divider as a semantic separator. Visual-only dividers are hidden from assistive tech by default. */
|
|
71
|
+
@Prop() semantic: boolean = false;
|
|
72
|
+
|
|
73
|
+
private resolveInset(): string {
|
|
74
|
+
return Object.prototype.hasOwnProperty.call(INSET_VALUE, this.inset)
|
|
75
|
+
? INSET_VALUE[this.inset as keyof typeof INSET_VALUE]
|
|
76
|
+
: this.inset;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private resolveLength(): string {
|
|
80
|
+
return this.length === 'auto' || this.length === 'full'
|
|
81
|
+
? '100%'
|
|
82
|
+
: this.length;
|
|
83
|
+
}
|
|
84
|
+
|
|
14
85
|
render() {
|
|
86
|
+
const isVertical = this.orientation === 'vertical';
|
|
87
|
+
const hasCustomLength = this.length !== 'auto' && this.length !== 'full';
|
|
88
|
+
|
|
15
89
|
return (
|
|
16
90
|
<Host
|
|
17
|
-
role=
|
|
18
|
-
aria-orientation={this.orientation}
|
|
19
|
-
|
|
91
|
+
role={this.semantic ? 'separator' : undefined}
|
|
92
|
+
aria-orientation={this.semantic ? this.orientation : undefined}
|
|
93
|
+
aria-hidden={this.semantic ? undefined : 'true'}
|
|
94
|
+
class={{
|
|
95
|
+
divider: true,
|
|
96
|
+
'divider--vertical': isVertical,
|
|
97
|
+
'divider--custom-length': hasCustomLength,
|
|
98
|
+
[`divider--surface-${this.surface}`]: true,
|
|
99
|
+
}}
|
|
100
|
+
style={{
|
|
101
|
+
'--_divider-inset': this.resolveInset(),
|
|
102
|
+
'--_divider-length': this.resolveLength(),
|
|
103
|
+
}}
|
|
20
104
|
/>
|
|
21
105
|
);
|
|
22
106
|
}
|
|
@@ -1,30 +1,110 @@
|
|
|
1
1
|
import { Component, Prop, h, Host } from '@stencil/core';
|
|
2
2
|
|
|
3
3
|
export type FadeSide = 'top' | 'bottom' | 'left' | 'right';
|
|
4
|
+
export type FadeSurface =
|
|
5
|
+
| 'default'
|
|
6
|
+
| 'primary'
|
|
7
|
+
| 'secondary'
|
|
8
|
+
| 'navigation'
|
|
9
|
+
| 'media'
|
|
10
|
+
| 'always-dark'
|
|
11
|
+
| 'inverted';
|
|
12
|
+
export type FadeSizeToken =
|
|
13
|
+
| 'size-000'
|
|
14
|
+
| 'size-050'
|
|
15
|
+
| 'size-075'
|
|
16
|
+
| 'size-100'
|
|
17
|
+
| 'size-150'
|
|
18
|
+
| 'size-200'
|
|
19
|
+
| 'size-250'
|
|
20
|
+
| 'size-300'
|
|
21
|
+
| 'size-400'
|
|
22
|
+
| 'size-500'
|
|
23
|
+
| 'size-600'
|
|
24
|
+
| 'size-800';
|
|
25
|
+
export type FadeSize = FadeSizeToken | (string & {});
|
|
26
|
+
|
|
27
|
+
const SIZE_VALUE: Record<FadeSizeToken, string> = {
|
|
28
|
+
'size-000': 'var(--dimension-size-000)',
|
|
29
|
+
'size-050': 'var(--dimension-size-050)',
|
|
30
|
+
'size-075': 'var(--dimension-size-075)',
|
|
31
|
+
'size-100': 'var(--dimension-size-100)',
|
|
32
|
+
'size-150': 'var(--dimension-size-150)',
|
|
33
|
+
'size-200': 'var(--dimension-size-200)',
|
|
34
|
+
'size-250': 'var(--dimension-size-250)',
|
|
35
|
+
'size-300': 'var(--dimension-size-300)',
|
|
36
|
+
'size-400': 'var(--dimension-size-400)',
|
|
37
|
+
'size-500': 'var(--dimension-size-500)',
|
|
38
|
+
'size-600': 'var(--dimension-size-600)',
|
|
39
|
+
'size-800': 'var(--dimension-size-800)',
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const SURFACE_BACKGROUND: Record<FadeSurface, string> = {
|
|
43
|
+
default: 'var(--color-background-secondary)',
|
|
44
|
+
primary: 'var(--color-background-primary)',
|
|
45
|
+
secondary: 'var(--color-background-secondary)',
|
|
46
|
+
navigation: 'var(--color-navigation-background)',
|
|
47
|
+
media: 'var(--color-media-background)',
|
|
48
|
+
'always-dark': 'var(--color-always-dark-background)',
|
|
49
|
+
inverted: 'var(--color-inverted-background)',
|
|
50
|
+
};
|
|
4
51
|
|
|
5
52
|
@Component({
|
|
6
53
|
tag: 'ds-fade',
|
|
7
54
|
styleUrl: 'Fade.css',
|
|
8
|
-
|
|
55
|
+
scoped: true,
|
|
9
56
|
})
|
|
10
57
|
export class Fade {
|
|
11
|
-
|
|
12
|
-
|
|
58
|
+
/** Edge where the fade is anchored. */
|
|
59
|
+
@Prop() side: FadeSide = 'bottom';
|
|
60
|
+
|
|
61
|
+
/** Fade depth along the fade axis. Accepts dimension size token names or any CSS length. */
|
|
62
|
+
@Prop() size: FadeSize = 'size-600';
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Deprecated alias for size. Kept for existing consumers that pass a raw CSS length.
|
|
66
|
+
* Prefer `size`.
|
|
67
|
+
*/
|
|
13
68
|
@Prop() height: string | undefined;
|
|
14
|
-
|
|
69
|
+
|
|
70
|
+
/** Surface context used to choose the fade target background token. */
|
|
71
|
+
@Prop() surface: FadeSurface = 'default';
|
|
72
|
+
|
|
73
|
+
/** Direct background override for contexts that already expose a resolved surface var. */
|
|
15
74
|
@Prop() background: string = 'var(--color-background-secondary)';
|
|
16
75
|
|
|
76
|
+
/** Controls visibility without removing the element from layout/positioning. */
|
|
77
|
+
@Prop() visible: boolean = true;
|
|
78
|
+
|
|
79
|
+
private resolveSize(): string {
|
|
80
|
+
if (this.height) return this.height;
|
|
81
|
+
|
|
82
|
+
return Object.prototype.hasOwnProperty.call(SIZE_VALUE, this.size)
|
|
83
|
+
? SIZE_VALUE[this.size as FadeSizeToken]
|
|
84
|
+
: this.size;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private resolveBackground(): string {
|
|
88
|
+
if (this.background !== 'var(--color-background-secondary)') return this.background;
|
|
89
|
+
return SURFACE_BACKGROUND[this.surface];
|
|
90
|
+
}
|
|
91
|
+
|
|
17
92
|
render() {
|
|
93
|
+
const isVerticalEdge = this.side === 'top' || this.side === 'bottom';
|
|
94
|
+
|
|
18
95
|
return (
|
|
19
96
|
<Host
|
|
20
97
|
aria-hidden="true"
|
|
21
98
|
class={{
|
|
22
99
|
fade: true,
|
|
100
|
+
'fade--hidden': !this.visible,
|
|
101
|
+
'fade--vertical-edge': isVerticalEdge,
|
|
102
|
+
'fade--horizontal-edge': !isVerticalEdge,
|
|
23
103
|
[`fade--${this.side}`]: true,
|
|
24
104
|
}}
|
|
25
105
|
style={{
|
|
26
|
-
|
|
27
|
-
'--ds-fade-bg': this.
|
|
106
|
+
'--ds-fade-size': this.resolveSize(),
|
|
107
|
+
'--ds-fade-bg': this.resolveBackground(),
|
|
28
108
|
} as Record<string, string>}
|
|
29
109
|
/>
|
|
30
110
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { FadeSide } from './Fade';
|
|
1
|
+
export type { FadeSide, FadeSize, FadeSizeToken, FadeSurface } from './Fade';
|
|
@@ -517,7 +517,15 @@ export class PanelNav {
|
|
|
517
517
|
</ds-text>
|
|
518
518
|
</span>
|
|
519
519
|
</span>,
|
|
520
|
-
item.dot &&
|
|
520
|
+
item.dot && (
|
|
521
|
+
<ds-badge
|
|
522
|
+
class="panel-nav__item-dot"
|
|
523
|
+
variant="dot"
|
|
524
|
+
background="var(--_nav-bg)"
|
|
525
|
+
label=""
|
|
526
|
+
aria-hidden="true"
|
|
527
|
+
/>
|
|
528
|
+
),
|
|
521
529
|
];
|
|
522
530
|
|
|
523
531
|
const sharedProps = {
|
|
@@ -604,6 +612,14 @@ export class PanelNav {
|
|
|
604
612
|
|
|
605
613
|
{/* ── Footer ── */}
|
|
606
614
|
<div class="panel-nav__footer">
|
|
615
|
+
<ds-fade
|
|
616
|
+
class="panel-nav__footer-fade"
|
|
617
|
+
side="bottom"
|
|
618
|
+
size="size-600"
|
|
619
|
+
background="var(--_nav-bg)"
|
|
620
|
+
visible={!this.atBottom}
|
|
621
|
+
/>
|
|
622
|
+
|
|
607
623
|
{/* Left icon button — Gear in dashboard, Dashboard in settings */}
|
|
608
624
|
<button
|
|
609
625
|
type="button"
|
|
@@ -176,7 +176,15 @@ export class TabGroup {
|
|
|
176
176
|
[isSelected ? 'text-body-small-emphasis' : 'text-body-small']: true,
|
|
177
177
|
}}>
|
|
178
178
|
{tab.label}
|
|
179
|
-
{tab.dot &&
|
|
179
|
+
{tab.dot && (
|
|
180
|
+
<ds-badge
|
|
181
|
+
class="tab__dot"
|
|
182
|
+
variant="dot"
|
|
183
|
+
background="var(--_dot-ring)"
|
|
184
|
+
label=""
|
|
185
|
+
aria-hidden="true"
|
|
186
|
+
/>
|
|
187
|
+
)}
|
|
180
188
|
</span>
|
|
181
189
|
</button>
|
|
182
190
|
);
|
|
@@ -176,7 +176,15 @@ export class TabGroupNav {
|
|
|
176
176
|
[isSelected ? 'text-body-medium-emphasis' : 'text-body-medium']: true,
|
|
177
177
|
}}>
|
|
178
178
|
{tab.label}
|
|
179
|
-
{tab.dot &&
|
|
179
|
+
{tab.dot && (
|
|
180
|
+
<ds-badge
|
|
181
|
+
class="tab__dot"
|
|
182
|
+
variant="dot"
|
|
183
|
+
background="var(--_dot-ring)"
|
|
184
|
+
label=""
|
|
185
|
+
aria-hidden="true"
|
|
186
|
+
/>
|
|
187
|
+
)}
|
|
180
188
|
</span>
|
|
181
189
|
</button>
|
|
182
190
|
);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { Component, Prop,
|
|
1
|
+
import { Component, Prop, h, Host } from '@stencil/core';
|
|
2
2
|
|
|
3
3
|
export type TagIntent = 'neutral' | 'brand' | 'ai' | 'negative' | 'warning' | 'caution' | 'positive';
|
|
4
4
|
export type TagContrast = 'strong' | 'bold' | 'medium' | 'faint';
|
|
5
5
|
export type TagElevation = 'none' | 'flat' | 'elevated';
|
|
6
6
|
export type TagSize = 'md' | 'sm' | 'xs';
|
|
7
|
-
export type TagBackground = 'faint' | 'medium' | 'bold' | 'strong' | 'always-dark';
|
|
8
7
|
|
|
9
8
|
const TEXT_VARIANT: Record<TagSize, string> = {
|
|
10
9
|
md: 'text-body-medium',
|
|
@@ -26,45 +25,10 @@ export class Tag {
|
|
|
26
25
|
@Prop() elevation: TagElevation = 'none';
|
|
27
26
|
@Prop() size: TagSize = 'md';
|
|
28
27
|
@Prop() rounded: boolean = false;
|
|
29
|
-
@Prop() removable: boolean = false;
|
|
30
28
|
@Prop() maxWidth: string | number | undefined;
|
|
31
|
-
@Prop() inactive: boolean = false;
|
|
32
|
-
@Prop() background: TagBackground | undefined;
|
|
33
|
-
@Prop({ mutable: true }) pressed: boolean = false;
|
|
34
|
-
/** Whether the tag has a click/toggle behavior. */
|
|
35
|
-
@Prop() interactive: boolean = false;
|
|
36
|
-
|
|
37
|
-
/** Fired when the remove button is clicked. */
|
|
38
|
-
@Event() dsRemove!: EventEmitter<void>;
|
|
39
|
-
/** Fired when an interactive tag is clicked. */
|
|
40
|
-
@Event() dsClick!: EventEmitter<void>;
|
|
41
|
-
/** Fired when the pressed state toggles. */
|
|
42
|
-
@Event() dsPressedChange!: EventEmitter<boolean>;
|
|
43
|
-
|
|
44
|
-
private handleClick = () => {
|
|
45
|
-
if (this.inactive) return;
|
|
46
|
-
this.pressed = !this.pressed;
|
|
47
|
-
this.dsPressedChange.emit(this.pressed);
|
|
48
|
-
this.dsClick.emit();
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
private handleKeyDown = (e: KeyboardEvent) => {
|
|
52
|
-
if (this.inactive) return;
|
|
53
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
54
|
-
e.preventDefault();
|
|
55
|
-
this.handleClick();
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
private handleRemove = (e: MouseEvent) => {
|
|
60
|
-
e.stopPropagation();
|
|
61
|
-
this.dsRemove.emit();
|
|
62
|
-
};
|
|
63
29
|
|
|
64
30
|
render() {
|
|
65
|
-
const cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
66
31
|
const sz = this.size.toUpperCase() as 'MD' | 'SM' | 'XS';
|
|
67
|
-
const hasIconSlot = true; // always render slot, consumer decides whether to fill it
|
|
68
32
|
const textVariant = TEXT_VARIANT[this.size];
|
|
69
33
|
const iconSize = ICON_SIZE[this.size];
|
|
70
34
|
|
|
@@ -80,29 +44,15 @@ export class Tag {
|
|
|
80
44
|
[`tag--size-${this.size}`]: true,
|
|
81
45
|
'tag--rounded': this.rounded,
|
|
82
46
|
'tag--rounded-no-icon-left': this.rounded, // consumer overrides via slot presence hack
|
|
83
|
-
'tag--rounded-no-remove-right': this.rounded
|
|
47
|
+
'tag--rounded-no-remove-right': this.rounded,
|
|
84
48
|
[`tag--icon-left-${sz}`]: false, // toggled by slotchange
|
|
85
|
-
[`tag--icon-right-${sz}`]:
|
|
86
|
-
'tag--removable': this.removable,
|
|
87
|
-
'tag--interactive': this.interactive,
|
|
88
|
-
'tag--inactive': this.inactive,
|
|
89
|
-
'tag--pressed': this.pressed,
|
|
90
|
-
'tag--on-medium': this.background === 'medium',
|
|
91
|
-
'tag--on-bold': this.background === 'bold',
|
|
92
|
-
'tag--on-strong': this.background === 'strong',
|
|
93
|
-
'tag--on-always-dark': this.background === 'always-dark',
|
|
49
|
+
[`tag--icon-right-${sz}`]: false,
|
|
94
50
|
};
|
|
95
51
|
|
|
96
52
|
return (
|
|
97
53
|
<Host
|
|
98
54
|
class={hostCls}
|
|
99
55
|
style={maxWidthStyle}
|
|
100
|
-
onClick={this.interactive ? this.handleClick : undefined}
|
|
101
|
-
onKeyDown={this.interactive ? this.handleKeyDown : undefined}
|
|
102
|
-
role={this.interactive ? 'button' : undefined}
|
|
103
|
-
tabIndex={this.interactive ? (this.inactive ? -1 : 0) : undefined}
|
|
104
|
-
aria-pressed={this.interactive && this.pressed !== undefined ? String(this.pressed) : undefined}
|
|
105
|
-
aria-disabled={this.inactive || undefined}
|
|
106
56
|
>
|
|
107
57
|
{/* Leading icon slot — consumer provides an icon element */}
|
|
108
58
|
<span class="tag__icon-slot" style={{ fontSize: `${iconSize}px`, lineHeight: '0' }}>
|
|
@@ -112,23 +62,6 @@ export class Tag {
|
|
|
112
62
|
<span class={{ 'tag__label': true, [textVariant]: true }}>
|
|
113
63
|
{this.label}
|
|
114
64
|
</span>
|
|
115
|
-
{/* Remove button */}
|
|
116
|
-
{this.removable && (
|
|
117
|
-
<button
|
|
118
|
-
type="button"
|
|
119
|
-
class="tag__remove"
|
|
120
|
-
onClick={this.handleRemove}
|
|
121
|
-
aria-label={`Remove ${this.label}`}
|
|
122
|
-
tabIndex={-1}
|
|
123
|
-
>
|
|
124
|
-
{/* Remove icon slot — defaults to × glyph */}
|
|
125
|
-
<slot name="remove-icon">
|
|
126
|
-
<span class="tag__remove-x" style={{ fontSize: `${iconSize}px`, lineHeight: '0' }}>
|
|
127
|
-
✕
|
|
128
|
-
</span>
|
|
129
|
-
</slot>
|
|
130
|
-
</button>
|
|
131
|
-
)}
|
|
132
65
|
</Host>
|
|
133
66
|
);
|
|
134
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { TagIntent, TagContrast, TagElevation, TagSize
|
|
1
|
+
export type { TagIntent, TagContrast, TagElevation, TagSize } from './Tag';
|
|
@@ -26,6 +26,7 @@ export type TextAlign = 'left' | 'center' | 'right';
|
|
|
26
26
|
export type LineTruncation = 1 | 2 | 3 | 4 | 5 | 'none';
|
|
27
27
|
export type TextWrap = 'wrap' | 'nowrap' | 'balance' | 'pretty';
|
|
28
28
|
export type TextElement = 'p' | 'span' | 'div' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
29
|
+
export type TextFontFeature = 'normal' | 'tabular-nums';
|
|
29
30
|
|
|
30
31
|
@Component({
|
|
31
32
|
tag: 'ds-text',
|
|
@@ -40,6 +41,7 @@ export class Text {
|
|
|
40
41
|
@Prop() align: TextAlign | undefined;
|
|
41
42
|
@Prop() lineTruncation: LineTruncation = 'none';
|
|
42
43
|
@Prop() wrap: TextWrap | undefined;
|
|
44
|
+
@Prop() fontFeature: TextFontFeature = 'normal';
|
|
43
45
|
@Prop() as: TextElement = 'p';
|
|
44
46
|
/** Maps to `for` attribute on <label> elements. */
|
|
45
47
|
@Prop() for: string | undefined;
|
|
@@ -80,6 +82,7 @@ export class Text {
|
|
|
80
82
|
'text--align-left': this.align === 'left',
|
|
81
83
|
'text--align-center': this.align === 'center',
|
|
82
84
|
'text--align-right': this.align === 'right',
|
|
85
|
+
'text--font-feature-tabular-nums': this.fontFeature === 'tabular-nums',
|
|
83
86
|
};
|
|
84
87
|
|
|
85
88
|
const style = this.color && isCustomColor(this.color)
|