@ds-mo/ui 2.11.1 → 2.12.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 +13 -13
- package/dist/.build-stamp +1 -1
- package/dist/components/ds-app-shell.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-accordion.d.ts → ds-button-unfilled.d.ts} +4 -4
- package/dist/components/ds-button-unfilled.js +2 -0
- package/dist/components/ds-card-data-viz.js +1 -1
- package/dist/components/ds-card-data-viz.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-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-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-header.js +1 -1
- package/dist/components/ds-header.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-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-scrollbar.js +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-skeleton.js +1 -1
- package/dist/components/ds-skeleton.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-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-toggle.js.map +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/ds-tooltip.js.map +1 -1
- package/dist/components/p-B9dHCgY-.js +2 -0
- package/dist/components/p-B9dHCgY-.js.map +1 -0
- package/dist/components/p-BPK76IsW.js +2 -0
- package/dist/components/p-BPK76IsW.js.map +1 -0
- package/dist/components/p-BQq26pt9.js.map +1 -1
- package/dist/components/p-BTC9Njj6.js +2 -0
- package/dist/components/p-BTC9Njj6.js.map +1 -0
- package/dist/components/p-BZIOTcnM.js +2 -0
- package/dist/components/p-BZIOTcnM.js.map +1 -0
- package/dist/components/{p-DdFUTZ3y.js → p-C3ORQUOp.js} +2 -2
- package/dist/components/{p-8Nt92j1-.js → p-CyFVn2Sc.js} +2 -2
- package/dist/components/p-DKdI8T8v.js +2 -0
- package/dist/components/p-DKdI8T8v.js.map +1 -0
- package/dist/components/{p-DOU4cbpc.js → p-DRqxVEye.js} +2 -2
- package/dist/components/p-DkcH8mRl.js +2 -0
- package/dist/components/p-DkcH8mRl.js.map +1 -0
- package/dist/components/p-DusYu-if.js +2 -0
- package/dist/components/p-DusYu-if.js.map +1 -0
- package/dist/components/p-EK1hOP19.js.map +1 -1
- package/dist/components/p-UbKTMQjv.js +2 -0
- package/dist/components/p-UbKTMQjv.js.map +1 -0
- package/dist/lib/nav/index.js +3 -0
- package/dist/lib/nav/index.js.map +2 -2
- package/dist/lib/utils/index.js +6 -0
- package/dist/lib/utils/index.js.map +2 -2
- package/dist/lib/utils/token-defaults.d.ts +3 -0
- package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +17 -3
- package/dist/types/components/ButtonFilled/index.d.ts +1 -1
- package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +66 -0
- package/dist/types/components/ButtonUnfilled/index.d.ts +2 -0
- package/dist/types/components/CardDataViz/CardDataViz.d.ts +5 -1
- package/dist/types/components/CardSetting/CardSetting.d.ts +1 -1
- package/dist/types/components/ChartDonut/ChartDonut.d.ts +7 -0
- package/dist/types/components/Checkbox/Checkbox.d.ts +1 -1
- package/dist/types/components/Chip/Chip.d.ts +18 -14
- package/dist/types/components/Chip/index.d.ts +1 -1
- package/dist/types/components/Input/Input.d.ts +1 -1
- package/dist/types/components/Pagination/Pagination.d.ts +1 -1
- package/dist/types/components/PanelNav/PanelNav.d.ts +2 -0
- package/dist/types/components/PanelTools/panel-tools-types.d.ts +1 -1
- package/dist/types/components/RadioGroup/RadioGroup.d.ts +2 -2
- package/dist/types/components/Select/Select.d.ts +2 -2
- package/dist/types/components/ShellGradientSwatch/ShellGradientSwatch.d.ts +1 -1
- package/dist/types/components/Slider/Slider.d.ts +1 -1
- package/dist/types/components/TabGroup/TabGroup.d.ts +1 -1
- package/dist/types/components/TabGroup/tab-item-utils.d.ts +2 -1
- package/dist/types/components/TabGroupNav/TabGroupNav.d.ts +1 -1
- package/dist/types/components/Tag/Tag.d.ts +0 -2
- package/dist/types/components/Tag/index.d.ts +1 -1
- package/dist/types/components/Toggle/Toggle.d.ts +1 -1
- package/dist/types/components/Tooltip/Tooltip.d.ts +25 -6
- package/dist/types/components/TooltipDataViz/TooltipDataViz.d.ts +18 -0
- package/dist/types/components.d.ts +277 -476
- package/dist/types/utils/token-defaults.d.ts +3 -0
- package/package.json +6 -3
- package/src/angular/index.ts +1 -6
- package/src/angular/proxies.ts +33 -170
- package/src/react/components.ts +1 -6
- package/src/react/ds-button-unfilled.ts +33 -0
- package/src/react/ds-chip.ts +2 -10
- package/src/wc/components/BarNav/BarNav.tsx +3 -2
- package/src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts +1 -1
- package/src/wc/components/ButtonFilled/ButtonFilled.tsx +90 -11
- package/src/wc/components/ButtonFilled/index.ts +6 -1
- package/src/wc/components/ButtonUnfilled/ButtonUnfilled.tsx +223 -0
- package/src/wc/components/ButtonUnfilled/index.ts +6 -0
- package/src/wc/components/CardDataViz/CardDataViz.tsx +36 -2
- package/src/wc/components/CardSetting/CardSetting.tsx +4 -6
- package/src/wc/components/ChartDonut/ChartDonut.tsx +50 -3
- package/src/wc/components/ChartLegend/ChartLegend.tsx +3 -0
- package/src/wc/components/Checkbox/Checkbox.tsx +5 -5
- package/src/wc/components/Chip/Chip.tsx +50 -67
- package/src/wc/components/Chip/index.ts +1 -1
- package/src/wc/components/Input/Input.tsx +4 -4
- package/src/wc/components/Menu/Menu.tsx +7 -4
- package/src/wc/components/Pagination/Pagination.tsx +6 -6
- package/src/wc/components/PanelNav/PanelNav.tsx +77 -48
- package/src/wc/components/PanelTools/PanelTools.tsx +19 -16
- package/src/wc/components/PanelTools/panel-tools-types.ts +1 -1
- package/src/wc/components/PanelTools/panel-tools-utils.ts +1 -1
- package/src/wc/components/RadioGroup/RadioGroup.tsx +7 -7
- package/src/wc/components/Select/Select.tsx +5 -5
- package/src/wc/components/ShellGradientSwatch/ShellGradientSwatch.tsx +4 -3
- package/src/wc/components/Slider/Slider.tsx +7 -3
- package/src/wc/components/TabGroup/TabGroup.tsx +13 -7
- package/src/wc/components/TabGroup/tab-item-utils.ts +2 -1
- package/src/wc/components/TabGroupNav/TabGroupNav.tsx +14 -13
- package/src/wc/components/Tag/Tag.tsx +25 -24
- package/src/wc/components/Tag/index.ts +1 -1
- package/src/wc/components/Toggle/Toggle.tsx +6 -6
- package/src/wc/components/Tooltip/Tooltip.tsx +166 -64
- package/src/wc/components/TooltipDataViz/TooltipDataViz.tsx +57 -2
- package/src/wc/components.d.ts +277 -476
- package/src/wc/utils/control-density.css +42 -0
- package/src/wc/utils/control-inactive.css +20 -0
- package/src/wc/utils/interaction-fill.css +162 -0
- package/src/wc/utils/scroll-edge-fade.css +5 -0
- package/src/wc/utils/token-defaults.ts +6 -0
- package/dist/components/ds-accordion.js +0 -2
- package/dist/components/ds-accordion.js.map +0 -1
- package/dist/components/ds-breadcrumb.d.ts +0 -11
- package/dist/components/ds-breadcrumb.js +0 -2
- package/dist/components/ds-breadcrumb.js.map +0 -1
- package/dist/components/ds-button-unfilled-icon.d.ts +0 -11
- package/dist/components/ds-button-unfilled-icon.js +0 -2
- package/dist/components/ds-fade.d.ts +0 -11
- package/dist/components/ds-fade.js +0 -2
- package/dist/components/ds-fade.js.map +0 -1
- package/dist/components/ds-surface.d.ts +0 -11
- package/dist/components/ds-surface.js +0 -2
- package/dist/components/ds-surface.js.map +0 -1
- package/dist/components/ds-toast-provider.d.ts +0 -11
- package/dist/components/ds-toast-provider.js +0 -2
- package/dist/components/ds-toast-provider.js.map +0 -1
- package/dist/components/p-BMQbEIrQ.js +0 -2
- package/dist/components/p-BMQbEIrQ.js.map +0 -1
- package/dist/components/p-BSFgy5r6.js +0 -2
- package/dist/components/p-BSFgy5r6.js.map +0 -1
- package/dist/components/p-CBUIn8dk.js +0 -2
- package/dist/components/p-CBUIn8dk.js.map +0 -1
- package/dist/components/p-ChVwCVHy.js +0 -2
- package/dist/components/p-ChVwCVHy.js.map +0 -1
- package/dist/components/p-CpNIQXz6.js +0 -2
- package/dist/components/p-CpNIQXz6.js.map +0 -1
- package/dist/components/p-CvgHQfvT.js +0 -2
- package/dist/components/p-CvgHQfvT.js.map +0 -1
- package/dist/components/p-bDf6yBQd.js +0 -2
- package/dist/components/p-bDf6yBQd.js.map +0 -1
- package/dist/types/components/Accordion/Accordion.d.ts +0 -28
- package/dist/types/components/Breadcrumb/Breadcrumb.d.ts +0 -16
- package/dist/types/components/ButtonUnfilledIcon/ButtonUnfilledIcon.d.ts +0 -45
- package/dist/types/components/ButtonUnfilledIcon/index.d.ts +0 -2
- package/dist/types/components/Fade/Fade.d.ts +0 -22
- package/dist/types/components/Fade/index.d.ts +0 -2
- package/dist/types/components/Surface/Surface.d.ts +0 -22
- package/dist/types/components/Toast/Toast.d.ts +0 -16
- package/dist/types/components/Toast/toast-service.d.ts +0 -24
- package/src/react/ds-accordion.ts +0 -27
- package/src/react/ds-breadcrumb.ts +0 -27
- package/src/react/ds-button-unfilled-icon.ts +0 -33
- package/src/react/ds-fade.ts +0 -26
- package/src/react/ds-surface.ts +0 -26
- package/src/react/ds-toast-provider.ts +0 -26
- package/src/wc/components/Accordion/Accordion.tsx +0 -144
- package/src/wc/components/Breadcrumb/Breadcrumb.tsx +0 -61
- package/src/wc/components/ButtonUnfilledIcon/ButtonUnfilledIcon.tsx +0 -129
- package/src/wc/components/ButtonUnfilledIcon/index.ts +0 -1
- package/src/wc/components/Fade/Fade.tsx +0 -58
- package/src/wc/components/Fade/index.ts +0 -1
- package/src/wc/components/Surface/Surface.tsx +0 -81
- package/src/wc/components/Toast/Toast.tsx +0 -179
- package/src/wc/components/Toast/toast-service.ts +0 -67
- /package/dist/components/{ds-button-unfilled-icon.js.map → ds-button-unfilled.js.map} +0 -0
- /package/dist/components/{p-DdFUTZ3y.js.map → p-C3ORQUOp.js.map} +0 -0
- /package/dist/components/{p-8Nt92j1-.js.map → p-CyFVn2Sc.js.map} +0 -0
- /package/dist/components/{p-DOU4cbpc.js.map → p-DRqxVEye.js.map} +0 -0
|
@@ -13,6 +13,27 @@ export type ButtonFilledIntent =
|
|
|
13
13
|
|
|
14
14
|
export type ButtonFilledContrast = 'bold' | 'strong' | 'medium' | 'faint';
|
|
15
15
|
|
|
16
|
+
export type ButtonFilledVariant = 'icon' | 'label' | 'icon-label';
|
|
17
|
+
|
|
18
|
+
export type ButtonFilledSize = 'md' | 'sm' | 'xs';
|
|
19
|
+
|
|
20
|
+
/** Emphasis text per control-density size (buttons use emphasis, unlike Tag). */
|
|
21
|
+
const TEXT_VARIANT: Record<ButtonFilledSize, string> = {
|
|
22
|
+
md: 'text-body-medium-emphasis',
|
|
23
|
+
sm: 'text-body-small-emphasis',
|
|
24
|
+
xs: 'text-caption-emphasis',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* `ds-icon` size prop matching control-density icon metrics
|
|
29
|
+
* (md→20 / sm→16 / xs→12 via `--dimension-iconography-*`).
|
|
30
|
+
*/
|
|
31
|
+
const ICON_SIZE: Record<ButtonFilledSize, 'md' | 'sm' | 'xs'> = {
|
|
32
|
+
md: 'md',
|
|
33
|
+
sm: 'sm',
|
|
34
|
+
xs: 'xs',
|
|
35
|
+
};
|
|
36
|
+
|
|
16
37
|
@Component({
|
|
17
38
|
tag: 'ds-button-filled',
|
|
18
39
|
styleUrl: 'ButtonFilled.css',
|
|
@@ -21,7 +42,19 @@ export type ButtonFilledContrast = 'bold' | 'strong' | 'medium' | 'faint';
|
|
|
21
42
|
export class ButtonFilled {
|
|
22
43
|
@Element() el!: HTMLElement;
|
|
23
44
|
|
|
24
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Content layout. Default is label-only; pass `icon` for icon-only chrome
|
|
47
|
+
* (nav / tool rails) or `icon-label` for leading icon + text.
|
|
48
|
+
*/
|
|
49
|
+
@Prop() variant: ButtonFilledVariant = 'label';
|
|
50
|
+
|
|
51
|
+
/** Control density (height, padding, icon, type). */
|
|
52
|
+
@Prop() size: ButtonFilledSize = 'md';
|
|
53
|
+
|
|
54
|
+
/** Visible text for `label` / `icon-label` variants. */
|
|
55
|
+
@Prop() label: string = '';
|
|
56
|
+
|
|
57
|
+
/** Icon name passed to <ds-icon> for `icon` / `icon-label` variants. */
|
|
25
58
|
@Prop() icon: string = '';
|
|
26
59
|
|
|
27
60
|
/** Semantic colour intent. */
|
|
@@ -34,12 +67,12 @@ export class ButtonFilled {
|
|
|
34
67
|
@Prop() contrast: ButtonFilledContrast = 'bold';
|
|
35
68
|
|
|
36
69
|
/** Disables interaction. */
|
|
37
|
-
@Prop()
|
|
70
|
+
@Prop() isInactive: boolean = false;
|
|
38
71
|
|
|
39
72
|
/** Native button type. */
|
|
40
73
|
@Prop() type: 'button' | 'submit' | 'reset' = 'button';
|
|
41
74
|
|
|
42
|
-
@Prop({ attribute: 'aria-label' }) ariaLabel: string
|
|
75
|
+
@Prop({ attribute: 'aria-label' }) ariaLabel: string | undefined;
|
|
43
76
|
|
|
44
77
|
@Event() dsClick!: EventEmitter<MouseEvent>;
|
|
45
78
|
|
|
@@ -51,34 +84,80 @@ export class ButtonFilled {
|
|
|
51
84
|
}
|
|
52
85
|
|
|
53
86
|
private handleClick = (event: MouseEvent) => {
|
|
54
|
-
if (this.
|
|
87
|
+
if (this.isInactive) return;
|
|
55
88
|
this.dsClick.emit(event);
|
|
56
89
|
};
|
|
57
90
|
|
|
91
|
+
private get showIcon(): boolean {
|
|
92
|
+
return this.variant === 'icon' || this.variant === 'icon-label';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private get showLabel(): boolean {
|
|
96
|
+
return this.variant === 'label' || this.variant === 'icon-label';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private get accessibleName(): string | undefined {
|
|
100
|
+
if (this.ariaLabel) return this.ariaLabel;
|
|
101
|
+
if (this.showLabel && this.label) return undefined;
|
|
102
|
+
if (this.variant === 'icon') return this.icon || 'action';
|
|
103
|
+
return this.label || 'action';
|
|
104
|
+
}
|
|
105
|
+
|
|
58
106
|
render() {
|
|
107
|
+
const textVariant = TEXT_VARIANT[this.size];
|
|
108
|
+
const iconSize = ICON_SIZE[this.size];
|
|
109
|
+
|
|
59
110
|
const cls: Record<string, boolean> = {
|
|
60
111
|
'button-filled': true,
|
|
61
112
|
'ds-focus-ring-inset': true,
|
|
62
|
-
'
|
|
113
|
+
'ds-interaction-fill': !this.isInactive,
|
|
114
|
+
/* Bold is the default filled contrast — on-bold interaction tokens. */
|
|
115
|
+
'ds-interaction-fill--on-bold': this.contrast === 'bold',
|
|
116
|
+
'ds-interaction-fill--on-strong': this.contrast === 'strong',
|
|
117
|
+
'ds-interaction-fill--on-medium': this.contrast === 'medium',
|
|
118
|
+
/* faint → default app interaction tokens (no --on-*). */
|
|
119
|
+
'ds-control-inactive': this.isInactive,
|
|
120
|
+
'ds-control--md': this.size === 'md',
|
|
121
|
+
'ds-control--sm': this.size === 'sm',
|
|
122
|
+
'ds-control--xs': this.size === 'xs',
|
|
123
|
+
'button-filled--icon': this.variant === 'icon',
|
|
124
|
+
'button-filled--label': this.variant === 'label',
|
|
125
|
+
'button-filled--icon-label': this.variant === 'icon-label',
|
|
63
126
|
[`button-filled--intent-${this.intent}`]: true,
|
|
64
127
|
[`button-filled--contrast-${this.contrast}`]: this.contrast !== 'bold',
|
|
65
128
|
};
|
|
66
129
|
|
|
67
130
|
return (
|
|
68
|
-
<Host
|
|
131
|
+
<Host
|
|
132
|
+
class={{
|
|
133
|
+
'button-filled-host': true,
|
|
134
|
+
'button-filled-host--icon': this.variant === 'icon',
|
|
135
|
+
'ds-control--md': this.size === 'md',
|
|
136
|
+
'ds-control--sm': this.size === 'sm',
|
|
137
|
+
'ds-control--xs': this.size === 'xs',
|
|
138
|
+
}}
|
|
139
|
+
tabIndex={-1}
|
|
140
|
+
>
|
|
69
141
|
<button
|
|
70
142
|
ref={el => {
|
|
71
143
|
this.buttonEl = el ?? null;
|
|
72
144
|
}}
|
|
73
145
|
type={this.type}
|
|
74
146
|
class={cls}
|
|
75
|
-
disabled={this.
|
|
76
|
-
aria-label={this.
|
|
147
|
+
disabled={this.isInactive}
|
|
148
|
+
aria-label={this.accessibleName}
|
|
77
149
|
onClick={this.handleClick}
|
|
78
150
|
>
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
|
|
151
|
+
{this.showIcon && (
|
|
152
|
+
<span class="button-filled__icon-wrap ds-interaction-fill__content">
|
|
153
|
+
<ds-icon name={this.icon} size={iconSize} color="inherit" />
|
|
154
|
+
</span>
|
|
155
|
+
)}
|
|
156
|
+
{this.showLabel && (
|
|
157
|
+
<span class={{ 'button-filled__label': true, [textVariant]: true, 'ds-interaction-fill__content': true }}>
|
|
158
|
+
{this.label}
|
|
159
|
+
</span>
|
|
160
|
+
)}
|
|
82
161
|
</button>
|
|
83
162
|
</Host>
|
|
84
163
|
);
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { Component, Element, Event, EventEmitter, h, Host, Method, Prop } from '@stencil/core';
|
|
2
|
+
|
|
3
|
+
export type ButtonUnfilledOnBackgroundContrast = 'default' | 'medium' | 'bold' | 'strong';
|
|
4
|
+
|
|
5
|
+
export type ButtonUnfilledBackground = 'always-dark' | 'navigation';
|
|
6
|
+
|
|
7
|
+
export type ButtonUnfilledVariant = 'icon' | 'label' | 'icon-label';
|
|
8
|
+
|
|
9
|
+
export type ButtonUnfilledSize = 'md' | 'sm' | 'xs';
|
|
10
|
+
|
|
11
|
+
/** Emphasis text per control-density size (buttons use emphasis, unlike Tag). */
|
|
12
|
+
const TEXT_VARIANT: Record<ButtonUnfilledSize, string> = {
|
|
13
|
+
md: 'text-body-medium-emphasis',
|
|
14
|
+
sm: 'text-body-small-emphasis',
|
|
15
|
+
xs: 'text-caption-emphasis',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* `ds-icon` size prop matching control-density icon metrics
|
|
20
|
+
* (md→20 / sm→16 / xs→12 via `--dimension-iconography-*`).
|
|
21
|
+
*/
|
|
22
|
+
const ICON_SIZE: Record<ButtonUnfilledSize, 'md' | 'sm' | 'xs'> = {
|
|
23
|
+
md: 'md',
|
|
24
|
+
sm: 'sm',
|
|
25
|
+
xs: 'xs',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
@Component({
|
|
29
|
+
tag: 'ds-button-unfilled',
|
|
30
|
+
styleUrl: 'ButtonUnfilled.css',
|
|
31
|
+
scoped: true,
|
|
32
|
+
})
|
|
33
|
+
export class ButtonUnfilled {
|
|
34
|
+
@Element() el!: HTMLElement;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Content layout. Default is label-only; pass `icon` for icon-only chrome
|
|
38
|
+
* (nav / tool rails) or `icon-label` for leading icon + text.
|
|
39
|
+
*/
|
|
40
|
+
@Prop() variant: ButtonUnfilledVariant = 'label';
|
|
41
|
+
|
|
42
|
+
/** Control density (height, padding, icon, type). */
|
|
43
|
+
@Prop() size: ButtonUnfilledSize = 'md';
|
|
44
|
+
|
|
45
|
+
/** Visible text for `label` / `icon-label` variants. */
|
|
46
|
+
@Prop() label: string = '';
|
|
47
|
+
|
|
48
|
+
/** Icon name passed to <ds-icon> for `icon` / `icon-label` variants. */
|
|
49
|
+
@Prop() icon: string = '';
|
|
50
|
+
|
|
51
|
+
/** Active/selected visual state. */
|
|
52
|
+
@Prop() isActive: boolean = false;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* When active, render the selected interaction fill.
|
|
56
|
+
* Default `true` for general UI. Shell chrome (nav / tool rails) should pass
|
|
57
|
+
* `false` so selection is foreground-only.
|
|
58
|
+
*/
|
|
59
|
+
@Prop() activeFill: boolean = true;
|
|
60
|
+
|
|
61
|
+
/** Show a 1px tertiary inset border. Default on; shell chrome can pass `false`. */
|
|
62
|
+
@Prop() hasBorder: boolean = true;
|
|
63
|
+
|
|
64
|
+
/** Show a notification dot at the top-right of the icon zone (icon variant only). */
|
|
65
|
+
@Prop() dot: boolean = false;
|
|
66
|
+
|
|
67
|
+
/** Disables interaction. */
|
|
68
|
+
@Prop() isInactive: boolean = false;
|
|
69
|
+
|
|
70
|
+
/** Native button type. */
|
|
71
|
+
@Prop() type: 'button' | 'submit' | 'reset' = 'button';
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Foreground and interaction tokens when the button sits on a contrasting parent
|
|
75
|
+
* background (default, medium, bold, or strong).
|
|
76
|
+
*/
|
|
77
|
+
@Prop({ attribute: 'on-background-contrast' })
|
|
78
|
+
backgroundContrast?: ButtonUnfilledOnBackgroundContrast;
|
|
79
|
+
|
|
80
|
+
/** Parent surface context for navigation and always-dark chrome. */
|
|
81
|
+
@Prop() background: ButtonUnfilledBackground | undefined;
|
|
82
|
+
|
|
83
|
+
@Prop({ attribute: 'aria-label' }) ariaLabel: string | undefined;
|
|
84
|
+
@Prop() controls: string | undefined;
|
|
85
|
+
@Prop() expanded: boolean | undefined;
|
|
86
|
+
@Prop() haspopup: string | undefined;
|
|
87
|
+
@Prop() pressed: boolean | undefined;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Native `tabindex` for roving keyboard groups in shell chrome.
|
|
91
|
+
* Omit for the default button tab stop (`0`).
|
|
92
|
+
*/
|
|
93
|
+
@Prop({ attribute: 'tab-index' }) focusTabIndex?: number;
|
|
94
|
+
|
|
95
|
+
@Event() dsClick!: EventEmitter<MouseEvent>;
|
|
96
|
+
@Event() dsChange!: EventEmitter<boolean>;
|
|
97
|
+
|
|
98
|
+
private buttonEl: HTMLButtonElement | null = null;
|
|
99
|
+
|
|
100
|
+
@Method()
|
|
101
|
+
async setFocus() {
|
|
102
|
+
this.buttonEl?.focus();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private handleClick = (event: MouseEvent) => {
|
|
106
|
+
if (this.isInactive) return;
|
|
107
|
+
this.dsClick.emit(event);
|
|
108
|
+
this.dsChange.emit(!this.isActive);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
private effectiveContrast(): ButtonUnfilledOnBackgroundContrast {
|
|
112
|
+
return this.backgroundContrast ?? 'default';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private get showIcon(): boolean {
|
|
116
|
+
return this.variant === 'icon' || this.variant === 'icon-label';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private get showLabel(): boolean {
|
|
120
|
+
return this.variant === 'label' || this.variant === 'icon-label';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private get showDot(): boolean {
|
|
124
|
+
return this.variant === 'icon' && this.dot;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Knock-out ring: selected fill → active wash; otherwise surface token. */
|
|
128
|
+
private get dotRing(): string {
|
|
129
|
+
if (this.isActive && this.activeFill) {
|
|
130
|
+
return 'var(--ds-interaction-active)';
|
|
131
|
+
}
|
|
132
|
+
return 'var(--ds-button-unfilled-dot-ring)';
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private get accessibleName(): string | undefined {
|
|
136
|
+
if (this.ariaLabel) return this.ariaLabel;
|
|
137
|
+
if (this.showLabel && this.label) return undefined;
|
|
138
|
+
if (this.variant === 'icon') return this.icon || 'action';
|
|
139
|
+
return this.label || 'action';
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
render() {
|
|
143
|
+
const bg = this.background;
|
|
144
|
+
const contrast = this.effectiveContrast();
|
|
145
|
+
const textVariant = TEXT_VARIANT[this.size];
|
|
146
|
+
const iconSize = ICON_SIZE[this.size];
|
|
147
|
+
|
|
148
|
+
const cls: Record<string, boolean> = {
|
|
149
|
+
'button-unfilled': true,
|
|
150
|
+
'ds-focus-ring-inset': true,
|
|
151
|
+
'ds-interaction-fill': true,
|
|
152
|
+
'ds-interaction-fill--selected': this.isActive && this.activeFill && !this.isInactive,
|
|
153
|
+
'ds-interaction-fill--on-medium': contrast === 'medium',
|
|
154
|
+
'ds-interaction-fill--on-bold': contrast === 'bold',
|
|
155
|
+
'ds-interaction-fill--on-strong': contrast === 'strong',
|
|
156
|
+
'ds-interaction-fill--on-always-dark': bg === 'always-dark',
|
|
157
|
+
'ds-interaction-fill--on-navigation': bg === 'navigation',
|
|
158
|
+
'button-unfilled--active': this.isActive,
|
|
159
|
+
'button-unfilled--bordered': this.hasBorder,
|
|
160
|
+
'ds-control-inactive': this.isInactive,
|
|
161
|
+
'ds-control--md': this.size === 'md',
|
|
162
|
+
'ds-control--sm': this.size === 'sm',
|
|
163
|
+
'ds-control--xs': this.size === 'xs',
|
|
164
|
+
'button-unfilled--icon': this.variant === 'icon',
|
|
165
|
+
'button-unfilled--label': this.variant === 'label',
|
|
166
|
+
'button-unfilled--icon-label': this.variant === 'icon-label',
|
|
167
|
+
'button-unfilled--contrast-medium': contrast === 'medium',
|
|
168
|
+
'button-unfilled--contrast-bold': contrast === 'bold',
|
|
169
|
+
'button-unfilled--contrast-strong': contrast === 'strong',
|
|
170
|
+
'button-unfilled--on-always-dark': bg === 'always-dark',
|
|
171
|
+
'button-unfilled--on-navigation': bg === 'navigation',
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
<Host
|
|
176
|
+
class={{
|
|
177
|
+
'button-unfilled-host': true,
|
|
178
|
+
'button-unfilled-host--icon': this.variant === 'icon',
|
|
179
|
+
'ds-control--md': this.size === 'md',
|
|
180
|
+
'ds-control--sm': this.size === 'sm',
|
|
181
|
+
'ds-control--xs': this.size === 'xs',
|
|
182
|
+
}}
|
|
183
|
+
tabIndex={-1}
|
|
184
|
+
>
|
|
185
|
+
<button
|
|
186
|
+
ref={el => {
|
|
187
|
+
this.buttonEl = el ?? null;
|
|
188
|
+
}}
|
|
189
|
+
type={this.type}
|
|
190
|
+
class={cls}
|
|
191
|
+
disabled={this.isInactive}
|
|
192
|
+
tabIndex={this.focusTabIndex ?? 0}
|
|
193
|
+
aria-label={this.accessibleName}
|
|
194
|
+
aria-controls={this.controls}
|
|
195
|
+
aria-expanded={this.expanded === undefined ? undefined : String(this.expanded)}
|
|
196
|
+
aria-haspopup={this.haspopup}
|
|
197
|
+
aria-pressed={this.pressed === undefined ? undefined : String(this.pressed)}
|
|
198
|
+
onClick={this.handleClick}
|
|
199
|
+
>
|
|
200
|
+
{this.showIcon && (
|
|
201
|
+
<span class="button-unfilled__icon-wrap ds-interaction-fill__content">
|
|
202
|
+
<ds-icon name={this.icon} size={iconSize} color="inherit" />
|
|
203
|
+
{this.showDot && (
|
|
204
|
+
<ds-badge
|
|
205
|
+
class="button-unfilled__dot"
|
|
206
|
+
variant="dot"
|
|
207
|
+
background={this.dotRing}
|
|
208
|
+
label=""
|
|
209
|
+
aria-hidden="true"
|
|
210
|
+
/>
|
|
211
|
+
)}
|
|
212
|
+
</span>
|
|
213
|
+
)}
|
|
214
|
+
{this.showLabel && (
|
|
215
|
+
<span class={{ 'button-unfilled__label': true, [textVariant]: true, 'ds-interaction-fill__content': true }}>
|
|
216
|
+
{this.label}
|
|
217
|
+
</span>
|
|
218
|
+
)}
|
|
219
|
+
</button>
|
|
220
|
+
</Host>
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Component, Element, State, h, Host, Prop } from '@stencil/core';
|
|
2
2
|
|
|
3
|
-
export type CardDataVizWidth = '
|
|
3
|
+
export type CardDataVizWidth = 'sm' | 'md' | 'lg';
|
|
4
|
+
|
|
5
|
+
/** Matches the `dsSliceHover`/`dsItemHover` detail shape emitted by `ds-chart-*` and `ds-chart-legend`. */
|
|
6
|
+
type HoveredDatum = { label: string } | null;
|
|
7
|
+
|
|
8
|
+
/** A slotted chart/legend that opts into hover sync by exposing an `activeLabel` prop. */
|
|
9
|
+
type SyncableSlot = HTMLElement & { activeLabel?: string | null };
|
|
4
10
|
|
|
5
11
|
const CARD_WIDTH_VARS: Record<CardDataVizWidth, string> = {
|
|
6
|
-
xs: 'var(--dimension-card-width-xs)',
|
|
7
12
|
sm: 'var(--dimension-card-width-sm)',
|
|
8
13
|
md: 'var(--dimension-card-width-md)',
|
|
9
14
|
lg: 'var(--dimension-card-width-lg)',
|
|
@@ -39,6 +44,35 @@ export class CardDataViz {
|
|
|
39
44
|
this.hasLegendSlot = !!this.el.querySelector(':scope > [slot="legend"]');
|
|
40
45
|
}
|
|
41
46
|
|
|
47
|
+
componentDidLoad() {
|
|
48
|
+
// Sync the chart's and legend's `activeLabel` from each other's hover events, so any
|
|
49
|
+
// ds-chart-* + ds-chart-legend pair cross-highlights without every consumer having to
|
|
50
|
+
// wire it up by hand. Delegated on the host (rather than bound to the specific slotted
|
|
51
|
+
// elements) since Stencil events bubble and the slot content can be swapped at runtime.
|
|
52
|
+
this.el.addEventListener('dsSliceHover', this.handleChartHover);
|
|
53
|
+
this.el.addEventListener('dsItemHover', this.handleLegendHover);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
disconnectedCallback() {
|
|
57
|
+
this.el.removeEventListener('dsSliceHover', this.handleChartHover);
|
|
58
|
+
this.el.removeEventListener('dsItemHover', this.handleLegendHover);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private handleChartHover = (e: Event) => {
|
|
62
|
+
// Not `:scope >` — Stencil's slot polyfill for scoped (non-shadow) components relocates
|
|
63
|
+
// slotted children into an inner `.chart-region`/`.legend-region` wrapper on render, so
|
|
64
|
+
// they're no longer direct children of the host by the time this fires.
|
|
65
|
+
const legend = this.el.querySelector('[slot="legend"]') as SyncableSlot | null;
|
|
66
|
+
if (!legend || !('activeLabel' in legend)) return;
|
|
67
|
+
legend.activeLabel = (e as CustomEvent<HoveredDatum>).detail?.label ?? null;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
private handleLegendHover = (e: Event) => {
|
|
71
|
+
const chart = this.el.querySelector('[slot="chart"]') as SyncableSlot | null;
|
|
72
|
+
if (!chart || !('activeLabel' in chart)) return;
|
|
73
|
+
chart.activeLabel = (e as CustomEvent<HoveredDatum>).detail?.label ?? null;
|
|
74
|
+
};
|
|
75
|
+
|
|
42
76
|
render() {
|
|
43
77
|
return (
|
|
44
78
|
<Host class="card-data-viz" style={{ '--_card-data-viz-width': CARD_WIDTH_VARS[this.cardWidth] }}>
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Component, Event, EventEmitter, h, Host, Prop } from '@stencil/core';
|
|
2
2
|
|
|
3
|
-
export type CardSettingWidth = '
|
|
3
|
+
export type CardSettingWidth = 'sm' | 'md' | 'lg';
|
|
4
4
|
|
|
5
5
|
const CARD_WIDTH_VARS: Record<CardSettingWidth, string> = {
|
|
6
|
-
xs: 'var(--dimension-card-width-xs)',
|
|
7
6
|
sm: 'var(--dimension-card-width-sm)',
|
|
8
7
|
md: 'var(--dimension-card-width-md)',
|
|
9
8
|
lg: 'var(--dimension-card-width-lg)',
|
|
@@ -60,7 +59,7 @@ export class CardSetting {
|
|
|
60
59
|
</ds-text>
|
|
61
60
|
</div>
|
|
62
61
|
{!editing ? (
|
|
63
|
-
<ds-button-unfilled
|
|
62
|
+
<ds-button-unfilled variant="icon"
|
|
64
63
|
type="button"
|
|
65
64
|
icon="Pencil"
|
|
66
65
|
aria-label="Edit"
|
|
@@ -68,15 +67,14 @@ export class CardSetting {
|
|
|
68
67
|
/>
|
|
69
68
|
) : (
|
|
70
69
|
<div class="card-setting__actions">
|
|
71
|
-
<ds-button-unfilled
|
|
70
|
+
<ds-button-unfilled variant="icon"
|
|
72
71
|
type="button"
|
|
73
72
|
icon="Cross"
|
|
74
73
|
backgroundContrast="bold"
|
|
75
|
-
has-border
|
|
76
74
|
aria-label="Cancel"
|
|
77
75
|
onDsClick={this.exitEdit}
|
|
78
76
|
/>
|
|
79
|
-
<ds-button-filled
|
|
77
|
+
<ds-button-filled variant="icon"
|
|
80
78
|
type="button"
|
|
81
79
|
icon="Check"
|
|
82
80
|
intent="brand"
|
|
@@ -10,6 +10,12 @@ const CENTER_GAP_PX = 0;
|
|
|
10
10
|
/** Fraction of the inner-circle diameter center text is allowed to use before truncating. */
|
|
11
11
|
const CENTER_TEXT_SAFE_WIDTH_RATIO = 0.82;
|
|
12
12
|
|
|
13
|
+
type DonutTooltipState = {
|
|
14
|
+
datum: ChartDatum;
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
13
19
|
@Component({
|
|
14
20
|
tag: 'ds-chart-donut',
|
|
15
21
|
styleUrl: 'ChartDonut.css',
|
|
@@ -33,10 +39,14 @@ export class ChartDonut {
|
|
|
33
39
|
* Externally controlled highlight, matched by `label` — e.g. drive this from a sibling
|
|
34
40
|
* `ds-chart-legend`'s `dsItemHover` event to keep chart and legend hover in sync.
|
|
35
41
|
* Falls back to this component's own pointer/focus hover when unset.
|
|
42
|
+
* External sync dims slices only — the data-viz tooltip is reserved for this
|
|
43
|
+
* component's own pointer/keyboard interaction.
|
|
36
44
|
*/
|
|
37
45
|
@Prop() activeLabel: string | null = null;
|
|
38
46
|
|
|
39
47
|
@State() private hoveredLabel: string | null = null;
|
|
48
|
+
/** Own-hover tooltip (cursor-following). Cleared on leave; not driven by `activeLabel`. */
|
|
49
|
+
@State() private tooltip: DonutTooltipState | null = null;
|
|
40
50
|
/** Center text, truncated with an ellipsis if it doesn't fit inside the inner circle. */
|
|
41
51
|
@State() private displayedValueText: string = '';
|
|
42
52
|
@State() private displayedCaptionText: string = '';
|
|
@@ -46,10 +56,30 @@ export class ChartDonut {
|
|
|
46
56
|
|
|
47
57
|
private valueTextEl?: SVGTextElement;
|
|
48
58
|
private captionTextEl?: SVGTextElement;
|
|
59
|
+
private wrapperEl?: HTMLDivElement;
|
|
49
60
|
|
|
50
|
-
private handleHover(datum: ChartDatum | null) {
|
|
61
|
+
private handleHover(datum: ChartDatum | null, event?: MouseEvent) {
|
|
51
62
|
this.hoveredLabel = datum?.label ?? null;
|
|
52
63
|
this.dsSliceHover.emit(datum);
|
|
64
|
+
if (!datum) {
|
|
65
|
+
this.tooltip = null;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.updateTooltip(datum, event);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private handleSliceMove(datum: ChartDatum, event: MouseEvent) {
|
|
72
|
+
if (this.hoveredLabel !== datum.label) return;
|
|
73
|
+
this.updateTooltip(datum, event);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private updateTooltip(datum: ChartDatum, event?: MouseEvent) {
|
|
77
|
+
const wrapper = this.wrapperEl;
|
|
78
|
+
if (!wrapper) return;
|
|
79
|
+
const rect = wrapper.getBoundingClientRect();
|
|
80
|
+
const x = event ? event.clientX - rect.left : this.size / 2;
|
|
81
|
+
const y = event ? event.clientY - rect.top : this.size / 2;
|
|
82
|
+
this.tooltip = { datum, x, y };
|
|
53
83
|
}
|
|
54
84
|
|
|
55
85
|
componentDidRender() {
|
|
@@ -115,10 +145,17 @@ export class ChartDonut {
|
|
|
115
145
|
// Show the full text before the post-render truncation pass has measured it (avoids a blank first paint).
|
|
116
146
|
const fullValueText = this.centerValue ?? formatCompactNumber(total);
|
|
117
147
|
const fullCaptionText = this.centerCaption ?? '';
|
|
148
|
+
const tip = this.tooltip;
|
|
118
149
|
|
|
119
150
|
return (
|
|
120
151
|
<Host class="chart-donut">
|
|
121
|
-
<div
|
|
152
|
+
<div
|
|
153
|
+
class="chart-donut__wrapper"
|
|
154
|
+
style={{ width: `${this.size}px`, height: `${this.size}px` }}
|
|
155
|
+
ref={el => {
|
|
156
|
+
this.wrapperEl = (el as HTMLDivElement) ?? undefined;
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
122
159
|
<svg
|
|
123
160
|
class="chart-donut__svg"
|
|
124
161
|
viewBox={`0 0 ${this.size} ${this.size}`}
|
|
@@ -141,7 +178,8 @@ export class ChartDonut {
|
|
|
141
178
|
tabindex={0}
|
|
142
179
|
role="img"
|
|
143
180
|
aria-label={`${datum.label}: ${datum.value}`}
|
|
144
|
-
onMouseEnter={() => this.handleHover(datum)}
|
|
181
|
+
onMouseEnter={(e: MouseEvent) => this.handleHover(datum, e)}
|
|
182
|
+
onMouseMove={(e: MouseEvent) => this.handleSliceMove(datum, e)}
|
|
145
183
|
onMouseLeave={() => this.handleHover(null)}
|
|
146
184
|
onFocus={() => this.handleHover(datum)}
|
|
147
185
|
onBlur={() => this.handleHover(null)}
|
|
@@ -177,6 +215,15 @@ export class ChartDonut {
|
|
|
177
215
|
</text>
|
|
178
216
|
)}
|
|
179
217
|
</svg>
|
|
218
|
+
{tip && (
|
|
219
|
+
<ds-tooltip-data-viz
|
|
220
|
+
key={tip.datum.label}
|
|
221
|
+
label={tip.datum.label}
|
|
222
|
+
value={formatCompactNumber(tip.datum.value)}
|
|
223
|
+
x={tip.x}
|
|
224
|
+
y={tip.y}
|
|
225
|
+
/>
|
|
226
|
+
)}
|
|
180
227
|
</div>
|
|
181
228
|
</Host>
|
|
182
229
|
);
|
|
@@ -73,6 +73,9 @@ export class ChartLegend {
|
|
|
73
73
|
class={{
|
|
74
74
|
'chart-legend__item': true,
|
|
75
75
|
'chart-legend__item--interactive': !!item.href,
|
|
76
|
+
'ds-control--md': true,
|
|
77
|
+
'ds-interaction-fill': true,
|
|
78
|
+
'ds-focus-ring-inset': !!item.href,
|
|
76
79
|
}}
|
|
77
80
|
style={{ opacity: isDimmed ? String(DIMMED_OPACITY) : '1' }}
|
|
78
81
|
href={item.href}
|
|
@@ -13,12 +13,12 @@ export class Checkbox {
|
|
|
13
13
|
@Prop() label!: string;
|
|
14
14
|
@Prop({ mutable: true }) checked: boolean = false;
|
|
15
15
|
@Prop() indeterminate: boolean = false;
|
|
16
|
-
@Prop()
|
|
16
|
+
@Prop() isInactive: boolean = false;
|
|
17
17
|
|
|
18
18
|
@Event() dsChange!: EventEmitter<boolean>;
|
|
19
19
|
|
|
20
20
|
private handleActivate = () => {
|
|
21
|
-
if (this.
|
|
21
|
+
if (this.isInactive) return;
|
|
22
22
|
this.checked = !this.checked;
|
|
23
23
|
this.dsChange.emit(this.checked);
|
|
24
24
|
};
|
|
@@ -37,10 +37,10 @@ export class Checkbox {
|
|
|
37
37
|
<Host
|
|
38
38
|
role="checkbox"
|
|
39
39
|
aria-checked={this.indeterminate ? 'mixed' : String(this.checked)}
|
|
40
|
-
aria-disabled={this.
|
|
40
|
+
aria-disabled={this.isInactive || undefined}
|
|
41
41
|
aria-labelledby={this.labelId}
|
|
42
|
-
tabIndex={this.
|
|
43
|
-
class={{ checkbox: true, inactive: this.
|
|
42
|
+
tabIndex={this.isInactive ? -1 : 0}
|
|
43
|
+
class={{ checkbox: true, 'ds-control-inactive': this.isInactive }}
|
|
44
44
|
onClick={this.handleActivate}
|
|
45
45
|
onKeyDown={this.handleKeyDown}
|
|
46
46
|
>
|