@ds-mo/ui 2.14.0 → 3.0.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/dist/.build-stamp +1 -1
- package/dist/components/ds-app-shell.js +1 -1
- package/dist/components/ds-badge.js +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.js +1 -1
- package/dist/components/ds-bar-nav.js.map +1 -1
- package/dist/components/ds-button-filled.js +1 -1
- package/dist/components/ds-button-unfilled.js +1 -1
- package/dist/components/ds-card-data-viz-donut.js +1 -1
- package/dist/components/ds-card-data-viz-donut.js.map +1 -1
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-card-setting.js.map +1 -1
- package/dist/components/ds-card.js +1 -1
- package/dist/components/ds-chart-bar.js +1 -1
- package/dist/components/ds-chart-bar.js.map +1 -1
- package/dist/components/ds-chart-donut.js +1 -1
- package/dist/components/ds-chart-donut.js.map +1 -1
- package/dist/components/ds-chart-legend.js +1 -1
- package/dist/components/ds-chart-legend.js.map +1 -1
- package/dist/components/ds-chart-line.js +1 -1
- package/dist/components/ds-chart-line.js.map +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/ds-checkbox.js.map +1 -1
- package/dist/components/ds-chip.js +1 -1
- package/dist/components/ds-chip.js.map +1 -1
- package/dist/components/ds-divider.js +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-empty-state.js.map +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-field.js.map +1 -1
- package/dist/components/ds-icon.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-input.js.map +1 -1
- package/dist/components/ds-loader.js +1 -1
- package/dist/components/ds-loader.js.map +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-modal.js +1 -1
- package/dist/components/ds-modal.js.map +1 -1
- package/dist/components/ds-pagination.js +1 -1
- package/dist/components/ds-pagination.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-panel-tools.js +1 -1
- package/dist/components/ds-panel-tools.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-select.js +1 -1
- package/dist/components/ds-select.js.map +1 -1
- package/dist/components/ds-shell-gradient-picker.js +1 -1
- package/dist/components/ds-shell-gradient-swatch.js +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-slider.js.map +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-toggle.js +1 -1
- package/dist/components/ds-tooltip-data-viz.js +1 -1
- package/dist/components/ds-tooltip-data-viz.js.map +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/p-8WTsyLQ9.js +2 -0
- package/dist/components/p-8WTsyLQ9.js.map +1 -0
- package/dist/components/{p-B82KZX9D.js → p-9Qu1ls2y.js} +2 -2
- package/dist/components/p-BSNlp8Di.js +2 -0
- package/dist/components/p-BSNlp8Di.js.map +1 -0
- package/dist/components/p-BVNJnFI9.js +2 -0
- package/dist/components/p-BVNJnFI9.js.map +1 -0
- package/dist/components/p-B_ENgncs.js +2 -0
- package/dist/components/p-B_ENgncs.js.map +1 -0
- package/dist/components/p-CNgNgezy.js +2 -0
- package/dist/components/p-CNgNgezy.js.map +1 -0
- package/dist/components/p-CQmul5NK.js +2 -0
- package/dist/components/p-CQmul5NK.js.map +1 -0
- package/dist/components/p-CsaW5gDM.js +2 -0
- package/dist/components/{p-CYmVDfd_.js.map → p-CsaW5gDM.js.map} +1 -1
- package/dist/components/p-Cx-ywr1e.js +2 -0
- package/dist/components/p-Cx-ywr1e.js.map +1 -0
- package/dist/components/p-DQ3l2TXw.js +2 -0
- package/dist/components/p-DQ3l2TXw.js.map +1 -0
- package/dist/components/p-DRqJ3RUb.js +2 -0
- package/dist/components/p-DRqJ3RUb.js.map +1 -0
- package/dist/components/p-V2qW8NL0.js +2 -0
- package/dist/components/p-V2qW8NL0.js.map +1 -0
- package/dist/components/p-sBx2MuF2.js +2 -0
- package/dist/components/p-sBx2MuF2.js.map +1 -0
- package/dist/lib/components/Text/text-types.d.ts +9 -0
- package/dist/lib/utils/control-text.d.ts +5 -0
- package/dist/lib/utils/index.d.ts +2 -0
- package/dist/lib/utils/index.js +8 -0
- package/dist/lib/utils/index.js.map +3 -3
- package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +1 -1
- package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +1 -1
- package/dist/types/components/ChartDonut/ChartDonut.d.ts +2 -7
- package/dist/types/components/Loader/Loader.d.ts +7 -3
- package/dist/types/components/Loader/index.d.ts +1 -1
- package/dist/types/components/Select/Select.d.ts +1 -1
- package/dist/types/components/Text/Text.d.ts +9 -9
- package/dist/types/components/Text/index.d.ts +2 -1
- package/dist/types/components/Text/text-types.d.ts +10 -0
- package/dist/types/components/Text/text-utils.d.ts +6 -0
- package/dist/types/components/Tooltip/Tooltip.d.ts +1 -0
- package/dist/types/components/TooltipDataViz/TooltipDataViz.d.ts +3 -2
- package/dist/types/components.d.ts +54 -19
- package/dist/types/utils/control-text.d.ts +6 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/package.json +7 -7
- package/src/angular/proxies.ts +4 -4
- package/src/wc/components/Badge/Badge.tsx +6 -8
- package/src/wc/components/Banner/Banner.tsx +3 -1
- package/src/wc/components/BarNav/BarNav.tsx +10 -1
- package/src/wc/components/ButtonFilled/ButtonFilled.tsx +10 -11
- package/src/wc/components/ButtonUnfilled/ButtonUnfilled.tsx +10 -11
- package/src/wc/components/Card/Card.tsx +9 -10
- package/src/wc/components/ChartDonut/ChartDonut.tsx +4 -47
- package/src/wc/components/ChartLegend/ChartLegend.tsx +23 -15
- package/src/wc/components/Checkbox/Checkbox.tsx +2 -2
- package/src/wc/components/Chip/Chip.tsx +4 -10
- package/src/wc/components/EmptyState/EmptyState.tsx +3 -5
- package/src/wc/components/Field/Field.tsx +3 -1
- package/src/wc/components/Input/Input.tsx +10 -3
- package/src/wc/components/Loader/Loader.tsx +77 -30
- package/src/wc/components/Loader/index.ts +1 -1
- package/src/wc/components/Menu/Menu.tsx +21 -6
- package/src/wc/components/Modal/Modal.tsx +16 -3
- package/src/wc/components/Pagination/Pagination.tsx +5 -5
- package/src/wc/components/PanelNav/PanelNav.tsx +30 -30
- package/src/wc/components/PanelTools/PanelTools.tsx +10 -7
- package/src/wc/components/RadioGroup/RadioGroup.tsx +3 -1
- package/src/wc/components/Select/Select.tsx +15 -17
- package/src/wc/components/Slider/Slider.tsx +6 -2
- package/src/wc/components/TabGroup/TabGroup.tsx +3 -2
- package/src/wc/components/TabGroupNav/TabGroupNav.tsx +3 -2
- package/src/wc/components/Table/Table.tsx +21 -16
- package/src/wc/components/Tag/Tag.tsx +4 -10
- package/src/wc/components/Text/Text.tsx +54 -59
- package/src/wc/components/Text/index.ts +12 -1
- package/src/wc/components/Text/text-types.ts +23 -0
- package/src/wc/components/Text/text-utils.ts +13 -0
- package/src/wc/components/Tooltip/Tooltip.tsx +64 -41
- package/src/wc/components/TooltipDataViz/TooltipDataViz.tsx +20 -12
- package/src/wc/components.d.ts +54 -19
- package/src/wc/utils/control-density.css +1 -0
- package/src/wc/utils/control-text.ts +11 -0
- package/src/wc/utils/index.ts +2 -0
- package/src/wc/utils/interaction-fill.css +2 -2
- package/src/wc/utils/typography.css +146 -0
- package/dist/components/p-1m8r0wFg.js +0 -2
- package/dist/components/p-1m8r0wFg.js.map +0 -1
- package/dist/components/p-B2_D4IDN.js +0 -2
- package/dist/components/p-B2_D4IDN.js.map +0 -1
- package/dist/components/p-B5NcWtpp.js +0 -2
- package/dist/components/p-B5NcWtpp.js.map +0 -1
- package/dist/components/p-BAeKw2pj.js +0 -2
- package/dist/components/p-BAeKw2pj.js.map +0 -1
- package/dist/components/p-B_g8X0eh.js +0 -2
- package/dist/components/p-B_g8X0eh.js.map +0 -1
- package/dist/components/p-CDHRJqea.js +0 -2
- package/dist/components/p-CDHRJqea.js.map +0 -1
- package/dist/components/p-CYmVDfd_.js +0 -2
- package/dist/components/p-CtwNUCnp.js +0 -2
- package/dist/components/p-CtwNUCnp.js.map +0 -1
- package/dist/components/p-CuRjYmBk.js +0 -2
- package/dist/components/p-CuRjYmBk.js.map +0 -1
- package/dist/components/p-Dlol7hPg.js +0 -2
- package/dist/components/p-Dlol7hPg.js.map +0 -1
- package/dist/components/p-EK1hOP19.js +0 -2
- package/dist/components/p-EK1hOP19.js.map +0 -1
- package/dist/components/p-XNHSe8Mg.js +0 -2
- package/dist/components/p-XNHSe8Mg.js.map +0 -1
- /package/dist/components/{p-B82KZX9D.js.map → p-9Qu1ls2y.js.map} +0 -0
|
@@ -150,9 +150,9 @@ export class Table {
|
|
|
150
150
|
}}
|
|
151
151
|
style={col.minWidth ? { minWidth: typeof col.minWidth === 'number' ? `${col.minWidth}px` : col.minWidth as string } : undefined}
|
|
152
152
|
>
|
|
153
|
-
<span
|
|
153
|
+
<ds-text as="span" variant="text-body-small" emphasis color="secondary">
|
|
154
154
|
{col.header}
|
|
155
|
-
</
|
|
155
|
+
</ds-text>
|
|
156
156
|
{isSorted && (
|
|
157
157
|
<span class="sort-indicator" aria-hidden="true">
|
|
158
158
|
{sort.direction === 'asc' ? '↑' : '↓'}
|
|
@@ -181,11 +181,15 @@ export class Table {
|
|
|
181
181
|
|
|
182
182
|
{/* Empty state */}
|
|
183
183
|
{isEmpty && (
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
184
|
+
<ds-text
|
|
185
|
+
class="empty-row"
|
|
186
|
+
as="p"
|
|
187
|
+
variant="text-body-medium"
|
|
188
|
+
color="secondary"
|
|
189
|
+
style={{ gridColumn: '1 / -1' }}
|
|
190
|
+
>
|
|
191
|
+
{this.emptyMessage}
|
|
192
|
+
</ds-text>
|
|
189
193
|
)}
|
|
190
194
|
|
|
191
195
|
{/* Data rows */}
|
|
@@ -211,19 +215,20 @@ export class Table {
|
|
|
211
215
|
}}
|
|
212
216
|
>
|
|
213
217
|
{visibleCols.map(col => (
|
|
214
|
-
<
|
|
218
|
+
<ds-text
|
|
215
219
|
key={col.id}
|
|
216
220
|
class={{
|
|
217
221
|
'cell': true,
|
|
218
222
|
'align-right': col.align === 'right',
|
|
219
223
|
'align-center': col.align === 'center',
|
|
220
224
|
}}
|
|
225
|
+
as="span"
|
|
226
|
+
variant="text-body-medium"
|
|
227
|
+
lineTruncation={1}
|
|
221
228
|
role="cell"
|
|
222
229
|
>
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
</span>
|
|
226
|
-
</div>
|
|
230
|
+
{String(getCellValue(col, row) ?? '')}
|
|
231
|
+
</ds-text>
|
|
227
232
|
))}
|
|
228
233
|
</div>
|
|
229
234
|
);
|
|
@@ -243,11 +248,11 @@ export class Table {
|
|
|
243
248
|
this.dsPageChange.emit({ pageIndex: this.pageIndex });
|
|
244
249
|
}}
|
|
245
250
|
>
|
|
246
|
-
<span
|
|
251
|
+
<ds-text as="span" variant="text-body-small">Previous</ds-text>
|
|
247
252
|
</button>
|
|
248
|
-
<span
|
|
253
|
+
<ds-text as="span" variant="text-body-small" color="secondary">
|
|
249
254
|
Page {this.pageIndex! + 1} of {totalPages}
|
|
250
|
-
</
|
|
255
|
+
</ds-text>
|
|
251
256
|
<button
|
|
252
257
|
type="button"
|
|
253
258
|
class="page-button"
|
|
@@ -257,7 +262,7 @@ export class Table {
|
|
|
257
262
|
this.dsPageChange.emit({ pageIndex: this.pageIndex });
|
|
258
263
|
}}
|
|
259
264
|
>
|
|
260
|
-
<span
|
|
265
|
+
<ds-text as="span" variant="text-body-small">Next</ds-text>
|
|
261
266
|
</button>
|
|
262
267
|
</div>
|
|
263
268
|
)}
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { Component, Prop, h, Host } from '@stencil/core';
|
|
2
|
+
import { CONTROL_TEXT_VARIANT } from '../../utils';
|
|
2
3
|
|
|
3
4
|
export type TagIntent = 'neutral' | 'brand' | 'ai' | 'negative' | 'warning' | 'caution' | 'positive';
|
|
4
5
|
export type TagContrast = 'strong' | 'bold' | 'medium' | 'faint';
|
|
5
6
|
export type TagSize = 'md' | 'sm' | 'xs';
|
|
6
7
|
|
|
7
|
-
/** Text variant per control-density recipe (md / sm / xs). */
|
|
8
|
-
const TEXT_VARIANT: Record<TagSize, string> = {
|
|
9
|
-
md: 'text-body-medium',
|
|
10
|
-
sm: 'text-body-small',
|
|
11
|
-
xs: 'text-caption',
|
|
12
|
-
};
|
|
13
|
-
|
|
14
8
|
/**
|
|
15
9
|
* `ds-icon` size prop matching control-density icon metrics
|
|
16
10
|
* (md→20 / sm→16 / xs→12 via `--dimension-iconography-*`).
|
|
@@ -35,7 +29,7 @@ export class Tag {
|
|
|
35
29
|
@Prop() maxWidth: string | number | undefined;
|
|
36
30
|
|
|
37
31
|
render() {
|
|
38
|
-
const textVariant =
|
|
32
|
+
const textVariant = CONTROL_TEXT_VARIANT[this.size];
|
|
39
33
|
const iconSize = ICON_SIZE[this.size];
|
|
40
34
|
|
|
41
35
|
const maxWidthStyle = this.maxWidth != null
|
|
@@ -60,9 +54,9 @@ export class Tag {
|
|
|
60
54
|
<span class="tag__icon-slot" data-icon-size={iconSize}>
|
|
61
55
|
<slot name="icon" />
|
|
62
56
|
</span>
|
|
63
|
-
<
|
|
57
|
+
<ds-text class="tag__label" as="span" variant={textVariant} color="inherit">
|
|
64
58
|
{this.label}
|
|
65
|
-
</
|
|
59
|
+
</ds-text>
|
|
66
60
|
</Host>
|
|
67
61
|
);
|
|
68
62
|
}
|
|
@@ -1,32 +1,15 @@
|
|
|
1
1
|
import { Component, Prop, h, Host } from '@stencil/core';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
| 'text-body-small'
|
|
14
|
-
| 'text-body-small-emphasis'
|
|
15
|
-
| 'text-caption'
|
|
16
|
-
| 'text-caption-emphasis';
|
|
17
|
-
|
|
18
|
-
export type TextColorToken =
|
|
19
|
-
| 'primary' | 'secondary' | 'tertiary'
|
|
20
|
-
| 'brand' | 'negative' | 'positive' | 'warning' | 'caution' | 'ai'
|
|
21
|
-
| 'on-strong' | 'on-bold' | 'inherit';
|
|
22
|
-
|
|
23
|
-
export type TextColor = TextColorToken | `var(--${string})`;
|
|
24
|
-
export type TextDecoration = 'none' | 'underline' | 'dotted-underline';
|
|
25
|
-
export type TextAlign = 'left' | 'center' | 'right';
|
|
26
|
-
export type LineTruncation = 1 | 2 | 3 | 4 | 5 | 'none';
|
|
27
|
-
export type TextWrap = 'wrap' | 'nowrap' | 'balance' | 'pretty';
|
|
28
|
-
export type TextElement = 'p' | 'span' | 'div' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
29
|
-
export type TextFontFeature = 'normal' | 'tabular-nums';
|
|
2
|
+
import { textDisplayClass, textVariantClass } from './text-utils';
|
|
3
|
+
import type {
|
|
4
|
+
TextAlign,
|
|
5
|
+
TextColor,
|
|
6
|
+
TextDecoration,
|
|
7
|
+
TextElement,
|
|
8
|
+
TextFontFeature,
|
|
9
|
+
TextVariant,
|
|
10
|
+
LineTruncation,
|
|
11
|
+
TextWrap,
|
|
12
|
+
} from './text-types';
|
|
30
13
|
|
|
31
14
|
@Component({
|
|
32
15
|
tag: 'ds-text',
|
|
@@ -35,6 +18,12 @@ export type TextFontFeature = 'normal' | 'tabular-nums';
|
|
|
35
18
|
})
|
|
36
19
|
export class Text {
|
|
37
20
|
@Prop() variant: TextVariant = 'text-body-medium';
|
|
21
|
+
/**
|
|
22
|
+
* Heavier weight + tighter letter-spacing for the variant.
|
|
23
|
+
* `false` (default): regular weight (caption stays medium).
|
|
24
|
+
* `true`: display bold, title/caption semibold, body medium.
|
|
25
|
+
*/
|
|
26
|
+
@Prop() emphasis: boolean = false;
|
|
38
27
|
@Prop() color: TextColor | undefined;
|
|
39
28
|
@Prop() decoration: TextDecoration | undefined;
|
|
40
29
|
@Prop() italic: boolean = false;
|
|
@@ -45,6 +34,8 @@ export class Text {
|
|
|
45
34
|
@Prop() as: TextElement = 'p';
|
|
46
35
|
/** Maps to `for` attribute on <label> elements. */
|
|
47
36
|
@Prop() for: string | undefined;
|
|
37
|
+
/** Forwarded to the inner element (e.g. aria-labelledby targets). */
|
|
38
|
+
@Prop() textId: string | undefined;
|
|
48
39
|
|
|
49
40
|
render() {
|
|
50
41
|
// Polymorphic element: TSX treats a variable tag as a component, so a
|
|
@@ -54,35 +45,38 @@ export class Text {
|
|
|
54
45
|
const isCustomColor = (c: TextColor) => typeof c === 'string' && c.startsWith('var(--');
|
|
55
46
|
|
|
56
47
|
const cls: Record<string, boolean> = {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
'text--
|
|
61
|
-
'text--
|
|
62
|
-
'text--
|
|
63
|
-
'text--
|
|
64
|
-
'text--
|
|
65
|
-
'text--truncate-
|
|
66
|
-
'text--truncate-
|
|
67
|
-
'text--
|
|
68
|
-
'text--
|
|
69
|
-
'text--
|
|
70
|
-
'text--color-
|
|
71
|
-
'text--color-
|
|
72
|
-
'text--color-
|
|
73
|
-
'text--color-
|
|
74
|
-
'text--color-
|
|
75
|
-
'text--color-
|
|
76
|
-
'text--color-
|
|
77
|
-
'text--color-
|
|
78
|
-
'text--color-
|
|
79
|
-
'text--
|
|
80
|
-
'text--
|
|
81
|
-
'text--
|
|
82
|
-
'text--
|
|
83
|
-
'text--
|
|
84
|
-
'text--
|
|
85
|
-
'text--
|
|
48
|
+
'ds-text': true,
|
|
49
|
+
[textDisplayClass(this.as)]: true,
|
|
50
|
+
[textVariantClass(this.variant)]: true,
|
|
51
|
+
'ds-text--emphasis': this.emphasis,
|
|
52
|
+
'ds-text--regular': !this.emphasis,
|
|
53
|
+
'ds-text--nowrap': this.wrap === 'nowrap',
|
|
54
|
+
'ds-text--balance': this.wrap === 'balance',
|
|
55
|
+
'ds-text--pretty': this.wrap === 'pretty',
|
|
56
|
+
'ds-text--truncate-1': this.lineTruncation === 1 && this.wrap !== 'nowrap',
|
|
57
|
+
'ds-text--truncate-2': this.lineTruncation === 2 && this.wrap !== 'nowrap',
|
|
58
|
+
'ds-text--truncate-3': this.lineTruncation === 3 && this.wrap !== 'nowrap',
|
|
59
|
+
'ds-text--truncate-4': this.lineTruncation === 4 && this.wrap !== 'nowrap',
|
|
60
|
+
'ds-text--truncate-5': this.lineTruncation === 5 && this.wrap !== 'nowrap',
|
|
61
|
+
'ds-text--color-primary': this.color === 'primary',
|
|
62
|
+
'ds-text--color-secondary': this.color === 'secondary',
|
|
63
|
+
'ds-text--color-tertiary': this.color === 'tertiary',
|
|
64
|
+
'ds-text--color-brand': this.color === 'brand',
|
|
65
|
+
'ds-text--color-negative': this.color === 'negative',
|
|
66
|
+
'ds-text--color-positive': this.color === 'positive',
|
|
67
|
+
'ds-text--color-warning': this.color === 'warning',
|
|
68
|
+
'ds-text--color-caution': this.color === 'caution',
|
|
69
|
+
'ds-text--color-ai': this.color === 'ai',
|
|
70
|
+
'ds-text--color-on-strong': this.color === 'on-strong',
|
|
71
|
+
'ds-text--color-on-bold': this.color === 'on-bold',
|
|
72
|
+
'ds-text--color-inherit': this.color === 'inherit',
|
|
73
|
+
'ds-text--decoration-underline': this.decoration === 'underline',
|
|
74
|
+
'ds-text--decoration-dotted-underline': this.decoration === 'dotted-underline',
|
|
75
|
+
'ds-text--italic': this.italic,
|
|
76
|
+
'ds-text--align-left': this.align === 'left',
|
|
77
|
+
'ds-text--align-center': this.align === 'center',
|
|
78
|
+
'ds-text--align-right': this.align === 'right',
|
|
79
|
+
'ds-text--font-feature-tabular-nums': this.fontFeature === 'tabular-nums',
|
|
86
80
|
};
|
|
87
81
|
|
|
88
82
|
const style = this.color && isCustomColor(this.color)
|
|
@@ -91,10 +85,11 @@ export class Text {
|
|
|
91
85
|
|
|
92
86
|
const extraProps: Record<string, string> = {};
|
|
93
87
|
if (this.as === 'label' && this.for) extraProps['for'] = this.for;
|
|
88
|
+
if (this.textId) extraProps['id'] = this.textId;
|
|
94
89
|
|
|
95
90
|
return (
|
|
96
|
-
<Host style={
|
|
97
|
-
<Tag class=
|
|
91
|
+
<Host class={cls} style={style}>
|
|
92
|
+
<Tag class="ds-text__element" {...extraProps}>
|
|
98
93
|
<slot />
|
|
99
94
|
</Tag>
|
|
100
95
|
</Host>
|
|
@@ -1 +1,12 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type {
|
|
2
|
+
TextVariant,
|
|
3
|
+
TextColor,
|
|
4
|
+
TextColorToken,
|
|
5
|
+
TextDecoration,
|
|
6
|
+
TextAlign,
|
|
7
|
+
LineTruncation,
|
|
8
|
+
TextWrap,
|
|
9
|
+
TextElement,
|
|
10
|
+
TextFontFeature,
|
|
11
|
+
} from './text-types';
|
|
12
|
+
export { textVariantClass } from './text-utils';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type TextVariant =
|
|
2
|
+
| 'text-display-medium'
|
|
3
|
+
| 'text-display-small'
|
|
4
|
+
| 'text-title-large'
|
|
5
|
+
| 'text-title-medium'
|
|
6
|
+
| 'text-title-small'
|
|
7
|
+
| 'text-body-large'
|
|
8
|
+
| 'text-body-medium'
|
|
9
|
+
| 'text-body-small'
|
|
10
|
+
| 'text-caption';
|
|
11
|
+
|
|
12
|
+
export type TextColorToken =
|
|
13
|
+
| 'primary' | 'secondary' | 'tertiary'
|
|
14
|
+
| 'brand' | 'negative' | 'positive' | 'warning' | 'caution' | 'ai'
|
|
15
|
+
| 'on-strong' | 'on-bold' | 'inherit';
|
|
16
|
+
|
|
17
|
+
export type TextColor = TextColorToken | `var(--${string})`;
|
|
18
|
+
export type TextDecoration = 'none' | 'underline' | 'dotted-underline';
|
|
19
|
+
export type TextAlign = 'left' | 'center' | 'right';
|
|
20
|
+
export type LineTruncation = 1 | 2 | 3 | 4 | 5 | 'none';
|
|
21
|
+
export type TextWrap = 'wrap' | 'nowrap' | 'balance' | 'pretty';
|
|
22
|
+
export type TextElement = 'p' | 'span' | 'div' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
23
|
+
export type TextFontFeature = 'normal' | 'tabular-nums';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TextElement, TextVariant } from './text-types';
|
|
2
|
+
|
|
3
|
+
/** `text-body-medium` → `ds-text--body-medium` */
|
|
4
|
+
export function textVariantClass(variant: TextVariant): string {
|
|
5
|
+
return `ds-text--${variant.replace(/^text-/, '')}`;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Inline semantics get a measurable inline box; paragraphs/headings get a block box. */
|
|
9
|
+
export function textDisplayClass(element: TextElement): string {
|
|
10
|
+
return element === 'span' || element === 'label'
|
|
11
|
+
? 'ds-text--inline-box'
|
|
12
|
+
: 'ds-text--block-box';
|
|
13
|
+
}
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
import { Component, Prop, Element, Watch, h, Host } from '@stencil/core';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
CONTROL_TEXT_VARIANT,
|
|
4
|
+
resolveCssLengthPx,
|
|
5
|
+
resolveCssTimeMs,
|
|
6
|
+
TOKEN_CSS_LENGTHS,
|
|
7
|
+
TOKEN_DEFAULTS,
|
|
8
|
+
} from '../../utils';
|
|
9
|
+
import type { TextVariant } from '../Text/text-types';
|
|
10
|
+
// Side-effect: register `ds-text` — the portal builds it via createElement, not JSX.
|
|
11
|
+
import '../Text/Text';
|
|
3
12
|
|
|
4
13
|
export type TooltipSide = 'top' | 'right' | 'bottom' | 'left';
|
|
5
14
|
export type TooltipAlign = 'start' | 'center' | 'end';
|
|
6
15
|
export type TooltipSize = 'md' | 'sm' | 'xs';
|
|
7
16
|
|
|
8
|
-
/** Body text per control-density size (regular weight — not emphasis). */
|
|
9
|
-
const TEXT_VARIANT: Record<TooltipSize, string> = {
|
|
10
|
-
md: 'text-body-medium',
|
|
11
|
-
sm: 'text-body-small',
|
|
12
|
-
xs: 'text-caption',
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const LINE_HEIGHT: Record<TooltipSize, string> = {
|
|
16
|
-
md: 'var(--typography-lineheight-md)',
|
|
17
|
-
sm: 'var(--typography-lineheight-sm)',
|
|
18
|
-
xs: 'var(--typography-lineheight-xs)',
|
|
19
|
-
};
|
|
20
|
-
|
|
21
17
|
const FALLBACK_HEIGHT: Record<TooltipSize, string> = {
|
|
22
18
|
md: TOKEN_DEFAULTS.size400,
|
|
23
19
|
sm: TOKEN_DEFAULTS.size300,
|
|
@@ -29,6 +25,30 @@ let tooltipIdCounter = 0;
|
|
|
29
25
|
/** Currently open tooltip — force-cleared on warm handoff so tips don't cross-fade. */
|
|
30
26
|
let activeTooltip: Tooltip | null = null;
|
|
31
27
|
|
|
28
|
+
type DsTextEl = HTMLElement & {
|
|
29
|
+
as: string;
|
|
30
|
+
variant: TextVariant;
|
|
31
|
+
emphasis: boolean;
|
|
32
|
+
color: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function createDsText(opts: {
|
|
36
|
+
variant: TextVariant;
|
|
37
|
+
emphasis?: boolean;
|
|
38
|
+
color?: string;
|
|
39
|
+
className?: string;
|
|
40
|
+
text: string;
|
|
41
|
+
}): DsTextEl {
|
|
42
|
+
const el = document.createElement('ds-text') as DsTextEl;
|
|
43
|
+
if (opts.className) el.className = opts.className;
|
|
44
|
+
el.as = 'span';
|
|
45
|
+
el.variant = opts.variant;
|
|
46
|
+
el.emphasis = opts.emphasis ?? false;
|
|
47
|
+
el.color = opts.color ?? 'inherit';
|
|
48
|
+
el.textContent = opts.text;
|
|
49
|
+
return el;
|
|
50
|
+
}
|
|
51
|
+
|
|
32
52
|
/**
|
|
33
53
|
* Imperative body portal for the popup.
|
|
34
54
|
* Stencil must not own the portaled node — moving a VDOM child to `document.body`
|
|
@@ -204,6 +224,7 @@ export class Tooltip {
|
|
|
204
224
|
activeTooltip.hideInstant();
|
|
205
225
|
instant = true;
|
|
206
226
|
}
|
|
227
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias -- module singleton tracks the active instance
|
|
207
228
|
activeTooltip = this;
|
|
208
229
|
this.skipEnterAnimation = instant;
|
|
209
230
|
if (instant) {
|
|
@@ -263,28 +284,39 @@ export class Tooltip {
|
|
|
263
284
|
|
|
264
285
|
private renderPopupContent() {
|
|
265
286
|
if (!this.popupEl) return;
|
|
266
|
-
const textVariant =
|
|
267
|
-
const lineHeight = LINE_HEIGHT[this.size];
|
|
287
|
+
const textVariant = CONTROL_TEXT_VARIANT[this.size];
|
|
268
288
|
const density =
|
|
269
289
|
this.size === 'md' ? 'ds-control--md' : this.size === 'sm' ? 'ds-control--sm' : 'ds-control--xs';
|
|
270
|
-
// Every node needs `sc-ds-tooltip` so scoped selectors (`.foo.sc-ds-tooltip`) match.
|
|
290
|
+
// Every layout node needs `sc-ds-tooltip` so scoped selectors (`.foo.sc-ds-tooltip`) match.
|
|
271
291
|
const sc = 'sc-ds-tooltip';
|
|
272
292
|
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
293
|
+
const inner = document.createElement('div');
|
|
294
|
+
inner.className = `tooltip-inner ${density} ${sc}`;
|
|
295
|
+
|
|
296
|
+
const appendShortcut = (position: 'start' | 'end') => {
|
|
297
|
+
if (!this.shortcutKey || this.shortcutKeyPosition !== position) return;
|
|
298
|
+
const hint = document.createElement('div');
|
|
299
|
+
hint.className = `key-hint ${sc}`;
|
|
300
|
+
hint.setAttribute('aria-hidden', 'true');
|
|
301
|
+
hint.appendChild(
|
|
302
|
+
createDsText({ variant: 'text-caption', emphasis: true, text: this.shortcutKey }),
|
|
303
|
+
);
|
|
304
|
+
inner.appendChild(hint);
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
appendShortcut('start');
|
|
308
|
+
|
|
309
|
+
inner.appendChild(
|
|
310
|
+
createDsText({
|
|
311
|
+
className: `tooltip-label ${sc}`,
|
|
312
|
+
variant: textVariant,
|
|
313
|
+
text: this.label,
|
|
314
|
+
}),
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
appendShortcut('end');
|
|
318
|
+
|
|
319
|
+
this.popupEl.replaceChildren(inner);
|
|
288
320
|
}
|
|
289
321
|
|
|
290
322
|
private calculatePosition() {
|
|
@@ -338,12 +370,3 @@ export class Tooltip {
|
|
|
338
370
|
);
|
|
339
371
|
}
|
|
340
372
|
}
|
|
341
|
-
|
|
342
|
-
function escapeHtml(value: string): string {
|
|
343
|
-
return value
|
|
344
|
-
.replace(/&/g, '&')
|
|
345
|
-
.replace(/</g, '<')
|
|
346
|
-
.replace(/>/g, '>')
|
|
347
|
-
.replace(/"/g, '"')
|
|
348
|
-
.replace(/'/g, ''');
|
|
349
|
-
}
|
|
@@ -8,8 +8,9 @@ export type TooltipDataVizSide = 'left' | 'right';
|
|
|
8
8
|
export type TooltipDataVizAlign = 'top' | 'bottom';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Positioned value/label callout for chart hover interactions (
|
|
12
|
-
*
|
|
11
|
+
* Positioned value/label callout for chart hover interactions (bar, line point, …).
|
|
12
|
+
* Donut charts skip this — legend sync already surfaces the hovered slice.
|
|
13
|
+
* Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element —
|
|
13
14
|
* charts hover-highlight data that lives inside an SVG, so the chart itself computes
|
|
14
15
|
* the anchor point (e.g. the cursor position while hovering) and passes it in as `x`/`y`.
|
|
15
16
|
*
|
|
@@ -120,16 +121,23 @@ export class TooltipDataViz {
|
|
|
120
121
|
style={{ left: `${this.x}px`, top: `${this.y}px`, transform: `translate(${translateX}, ${translateY})` }}
|
|
121
122
|
>
|
|
122
123
|
<div class="tooltip-data-viz__item ds-control--md">
|
|
123
|
-
<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
124
|
+
<ds-text
|
|
125
|
+
class="tooltip-data-viz__label"
|
|
126
|
+
as="span"
|
|
127
|
+
variant="text-body-medium"
|
|
128
|
+
color="var(--color-foreground-on-translucent-background-secondary)"
|
|
129
|
+
>
|
|
130
|
+
{this.label}
|
|
131
|
+
</ds-text>
|
|
132
|
+
<ds-text
|
|
133
|
+
class="tooltip-data-viz__value"
|
|
134
|
+
as="span"
|
|
135
|
+
variant="text-body-medium"
|
|
136
|
+
emphasis
|
|
137
|
+
color="var(--color-foreground-on-translucent-background-primary)"
|
|
138
|
+
>
|
|
139
|
+
{this.value}
|
|
140
|
+
</ds-text>
|
|
133
141
|
</div>
|
|
134
142
|
</Host>
|
|
135
143
|
);
|