@ds-mo/ui 2.11.2 → 2.13.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.d.ts → ds-card-data-viz-donut.d.ts} +4 -4
- package/dist/components/ds-card-data-viz-donut.js +2 -0
- package/dist/components/ds-card-data-viz-donut.js.map +1 -0
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-card-setting.js.map +1 -1
- package/dist/components/{ds-fade.d.ts → ds-card.d.ts} +4 -4
- package/dist/components/ds-card.js +2 -0
- package/dist/components/ds-card.js.map +1 -0
- 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-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-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-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-1m8r0wFg.js +2 -0
- package/dist/components/p-1m8r0wFg.js.map +1 -0
- package/dist/components/p-3FLHei19.js +2 -0
- package/dist/components/p-3FLHei19.js.map +1 -0
- package/dist/components/p-B2_D4IDN.js +2 -0
- package/dist/components/p-B2_D4IDN.js.map +1 -0
- package/dist/components/p-B5NcWtpp.js +2 -0
- package/dist/components/p-B5NcWtpp.js.map +1 -0
- package/dist/components/{p-8Nt92j1-.js → p-B82KZX9D.js} +2 -2
- package/dist/components/p-BQq26pt9.js.map +1 -1
- package/dist/components/p-B_g8X0eh.js +2 -0
- package/dist/components/p-B_g8X0eh.js.map +1 -0
- package/dist/components/{p-DdFUTZ3y.js → p-Be3PHv34.js} +2 -2
- package/dist/components/p-CQmf2CeW.js +2 -0
- package/dist/components/p-CQmf2CeW.js.map +1 -0
- package/dist/components/{p-DOU4cbpc.js → p-CtwNUCnp.js} +2 -2
- package/dist/components/p-CuRjYmBk.js +2 -0
- package/dist/components/p-CuRjYmBk.js.map +1 -0
- package/dist/components/p-CwARVsZQ.js +2 -0
- package/dist/components/p-CwARVsZQ.js.map +1 -0
- package/dist/components/p-DohXlNCJ.js +2 -0
- package/dist/components/p-DohXlNCJ.js.map +1 -0
- package/dist/components/p-DuFm-ieS.js +2 -0
- package/dist/components/p-DuFm-ieS.js.map +1 -0
- package/dist/components/p-EK1hOP19.js.map +1 -1
- package/dist/lib/nav/index.js +3 -0
- package/dist/lib/nav/index.js.map +2 -2
- package/dist/lib/utils/control-width.d.ts +4 -0
- package/dist/lib/utils/index.d.ts +2 -0
- package/dist/lib/utils/index.js +20 -1
- package/dist/lib/utils/index.js.map +3 -3
- package/dist/lib/utils/token-defaults.d.ts +7 -0
- package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +21 -3
- package/dist/types/components/ButtonFilled/index.d.ts +1 -1
- package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +70 -0
- package/dist/types/components/ButtonUnfilled/index.d.ts +2 -0
- package/dist/types/components/Card/Card.d.ts +20 -0
- package/dist/types/components/Card/index.d.ts +2 -0
- package/dist/types/components/CardDataVizDonut/CardDataVizDonut.d.ts +26 -0
- package/dist/types/components/CardDataVizDonut/index.d.ts +2 -0
- package/dist/types/components/CardSetting/CardSetting.d.ts +7 -2
- package/dist/types/components/ChartDonut/ChartDonut.d.ts +31 -1
- 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 +34 -2
- package/dist/types/components/Select/index.d.ts +2 -0
- 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 +474 -576
- package/dist/types/utils/control-width.d.ts +5 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/token-defaults.d.ts +7 -0
- package/package.json +7 -4
- package/src/angular/index.ts +3 -9
- package/src/angular/proxies.ts +62 -215
- package/src/react/components.ts +3 -9
- package/src/react/ds-button-unfilled.ts +33 -0
- package/src/react/ds-card-data-viz-donut.ts +27 -0
- package/src/react/{ds-fade.ts → ds-card.ts} +7 -7
- 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 +97 -11
- package/src/wc/components/ButtonFilled/index.ts +7 -1
- package/src/wc/components/ButtonUnfilled/ButtonUnfilled.tsx +230 -0
- package/src/wc/components/ButtonUnfilled/index.ts +7 -0
- package/src/wc/components/Card/Card.tsx +79 -0
- package/src/wc/components/Card/index.ts +1 -0
- package/src/wc/components/{CardDataViz/CardDataViz.tsx → CardDataVizDonut/CardDataVizDonut.tsx} +47 -41
- package/src/wc/components/CardDataVizDonut/index.ts +1 -0
- package/src/wc/components/CardSetting/CardSetting.tsx +21 -36
- package/src/wc/components/ChartDonut/ChartDonut.tsx +159 -11
- 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 +145 -64
- package/src/wc/components/Select/index.ts +1 -0
- 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 +474 -579
- package/src/wc/utils/control-density.css +42 -0
- package/src/wc/utils/control-inactive.css +20 -0
- package/src/wc/utils/control-width.css +28 -0
- package/src/wc/utils/control-width.ts +10 -0
- package/src/wc/utils/index.ts +2 -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 +10 -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-card-data-viz.js +0 -2
- package/dist/components/ds-card-data-viz.js.map +0 -1
- package/dist/components/ds-fade.js +0 -2
- package/dist/components/ds-fade.js.map +0 -1
- package/dist/components/ds-header.d.ts +0 -11
- package/dist/components/ds-header.js +0 -2
- package/dist/components/ds-header.js.map +0 -1
- package/dist/components/ds-scrollbar.d.ts +0 -11
- package/dist/components/ds-scrollbar.js +0 -2
- package/dist/components/ds-scrollbar.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/CardDataViz/CardDataViz.d.ts +0 -22
- package/dist/types/components/CardDataViz/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/Header/Header.d.ts +0 -7
- package/dist/types/components/Scrollbar/Scrollbar.d.ts +0 -27
- 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-card-data-viz.ts +0 -26
- package/src/react/ds-header.ts +0 -26
- package/src/react/ds-scrollbar.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/CardDataViz/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/Header/Header.tsx +0 -33
- package/src/wc/components/Scrollbar/Scrollbar.tsx +0 -189
- 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-8Nt92j1-.js.map → p-B82KZX9D.js.map} +0 -0
- /package/dist/components/{p-DdFUTZ3y.js.map → p-Be3PHv34.js.map} +0 -0
- /package/dist/components/{p-DOU4cbpc.js.map → p-CtwNUCnp.js.map} +0 -0
|
@@ -12,15 +12,15 @@ import { createComponent } from '@stencil/react-output-target/runtime';
|
|
|
12
12
|
import React from 'react';
|
|
13
13
|
|
|
14
14
|
import type { Components } from "@ds-mo/ui/dist/components";
|
|
15
|
-
import {
|
|
15
|
+
import { DsCard as DsCardElement, defineCustomElement as defineDsCard } from "@ds-mo/ui/dist/components/ds-card.js";
|
|
16
16
|
|
|
17
|
-
export type
|
|
17
|
+
export type DsCardEvents = NonNullable<unknown>;
|
|
18
18
|
|
|
19
|
-
export const
|
|
20
|
-
tagName: 'ds-
|
|
21
|
-
elementClass:
|
|
19
|
+
export const DsCard: StencilReactComponent<DsCardElement, DsCardEvents, Components.DsCard> = /*@__PURE__*/ createComponent<DsCardElement, DsCardEvents, Components.DsCard>({
|
|
20
|
+
tagName: 'ds-card',
|
|
21
|
+
elementClass: DsCardElement,
|
|
22
22
|
// @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
|
|
23
23
|
react: React,
|
|
24
|
-
events: {} as
|
|
25
|
-
defineCustomElement:
|
|
24
|
+
events: {} as DsCardEvents,
|
|
25
|
+
defineCustomElement: defineDsCard
|
|
26
26
|
});
|
package/src/react/ds-chip.ts
CHANGED
|
@@ -15,21 +15,13 @@ import { type DsChipCustomEvent } from "@ds-mo/ui";
|
|
|
15
15
|
import type { Components } from "@ds-mo/ui/dist/components";
|
|
16
16
|
import { DsChip as DsChipElement, defineCustomElement as defineDsChip } from "@ds-mo/ui/dist/components/ds-chip.js";
|
|
17
17
|
|
|
18
|
-
export type DsChipEvents = {
|
|
19
|
-
onDsRemove: EventName<DsChipCustomEvent<void>>,
|
|
20
|
-
onDsClick: EventName<DsChipCustomEvent<void>>,
|
|
21
|
-
onDsPressedChange: EventName<DsChipCustomEvent<boolean>>
|
|
22
|
-
};
|
|
18
|
+
export type DsChipEvents = { onDsRemove: EventName<DsChipCustomEvent<void>> };
|
|
23
19
|
|
|
24
20
|
export const DsChip: StencilReactComponent<DsChipElement, DsChipEvents, Components.DsChip> = /*@__PURE__*/ createComponent<DsChipElement, DsChipEvents, Components.DsChip>({
|
|
25
21
|
tagName: 'ds-chip',
|
|
26
22
|
elementClass: DsChipElement,
|
|
27
23
|
// @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
|
|
28
24
|
react: React,
|
|
29
|
-
events: {
|
|
30
|
-
onDsRemove: 'dsRemove',
|
|
31
|
-
onDsClick: 'dsClick',
|
|
32
|
-
onDsPressedChange: 'dsPressedChange'
|
|
33
|
-
} as DsChipEvents,
|
|
25
|
+
events: { onDsRemove: 'dsRemove' } as DsChipEvents,
|
|
34
26
|
defineCustomElement: defineDsChip
|
|
35
27
|
});
|
|
@@ -687,15 +687,16 @@ export class BarNav {
|
|
|
687
687
|
)}
|
|
688
688
|
|
|
689
689
|
{hasTabs && this.hasOverflowTabs && (
|
|
690
|
-
<ds-button-unfilled
|
|
690
|
+
<ds-button-unfilled variant="icon"
|
|
691
691
|
class={{
|
|
692
692
|
'bar-nav__overflow-trigger': true,
|
|
693
693
|
}}
|
|
694
694
|
icon="Ellipses"
|
|
695
695
|
isActive={this.menuOpen}
|
|
696
696
|
activeFill={false}
|
|
697
|
+
hasBorder={false}
|
|
697
698
|
focusTabIndex={this.overflowRovingFocused ? 0 : -1}
|
|
698
|
-
ref={(el?:
|
|
699
|
+
ref={(el?: HTMLDsButtonUnfilledElement) => {
|
|
699
700
|
this.triggerEl = (el as (HTMLElement & { setFocus?: () => Promise<void> })) ?? null;
|
|
700
701
|
}}
|
|
701
702
|
haspopup="menu"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Component, Element, Event, EventEmitter, h, Host, Method, Prop } from '@stencil/core';
|
|
2
|
+
import { controlWidthClass, type ControlWidth } from '../../utils/control-width';
|
|
2
3
|
|
|
3
4
|
export type ButtonFilledIntent =
|
|
4
5
|
| 'neutral'
|
|
@@ -13,6 +14,29 @@ export type ButtonFilledIntent =
|
|
|
13
14
|
|
|
14
15
|
export type ButtonFilledContrast = 'bold' | 'strong' | 'medium' | 'faint';
|
|
15
16
|
|
|
17
|
+
export type ButtonFilledVariant = 'icon' | 'label' | 'icon-label';
|
|
18
|
+
|
|
19
|
+
export type ButtonFilledSize = 'md' | 'sm' | 'xs';
|
|
20
|
+
|
|
21
|
+
export type ButtonFilledWidth = ControlWidth;
|
|
22
|
+
|
|
23
|
+
/** Emphasis text per control-density size (buttons use emphasis, unlike Tag). */
|
|
24
|
+
const TEXT_VARIANT: Record<ButtonFilledSize, string> = {
|
|
25
|
+
md: 'text-body-medium-emphasis',
|
|
26
|
+
sm: 'text-body-small-emphasis',
|
|
27
|
+
xs: 'text-caption-emphasis',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* `ds-icon` size prop matching control-density icon metrics
|
|
32
|
+
* (md→20 / sm→16 / xs→12 via `--dimension-iconography-*`).
|
|
33
|
+
*/
|
|
34
|
+
const ICON_SIZE: Record<ButtonFilledSize, 'md' | 'sm' | 'xs'> = {
|
|
35
|
+
md: 'md',
|
|
36
|
+
sm: 'sm',
|
|
37
|
+
xs: 'xs',
|
|
38
|
+
};
|
|
39
|
+
|
|
16
40
|
@Component({
|
|
17
41
|
tag: 'ds-button-filled',
|
|
18
42
|
styleUrl: 'ButtonFilled.css',
|
|
@@ -21,7 +45,22 @@ export type ButtonFilledContrast = 'bold' | 'strong' | 'medium' | 'faint';
|
|
|
21
45
|
export class ButtonFilled {
|
|
22
46
|
@Element() el!: HTMLElement;
|
|
23
47
|
|
|
24
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Content layout. Default is label-only; pass `icon` for icon-only chrome
|
|
50
|
+
* (nav / tool rails) or `icon-label` for leading icon + text.
|
|
51
|
+
*/
|
|
52
|
+
@Prop() variant: ButtonFilledVariant = 'label';
|
|
53
|
+
|
|
54
|
+
/** Control density (height, padding, icon, type). */
|
|
55
|
+
@Prop() size: ButtonFilledSize = 'md';
|
|
56
|
+
|
|
57
|
+
/** Width fit — hug content (default) or fill the parent. */
|
|
58
|
+
@Prop() width: ButtonFilledWidth = 'hug';
|
|
59
|
+
|
|
60
|
+
/** Visible text for `label` / `icon-label` variants. */
|
|
61
|
+
@Prop() label: string = '';
|
|
62
|
+
|
|
63
|
+
/** Icon name passed to <ds-icon> for `icon` / `icon-label` variants. */
|
|
25
64
|
@Prop() icon: string = '';
|
|
26
65
|
|
|
27
66
|
/** Semantic colour intent. */
|
|
@@ -34,12 +73,12 @@ export class ButtonFilled {
|
|
|
34
73
|
@Prop() contrast: ButtonFilledContrast = 'bold';
|
|
35
74
|
|
|
36
75
|
/** Disables interaction. */
|
|
37
|
-
@Prop()
|
|
76
|
+
@Prop() isInactive: boolean = false;
|
|
38
77
|
|
|
39
78
|
/** Native button type. */
|
|
40
79
|
@Prop() type: 'button' | 'submit' | 'reset' = 'button';
|
|
41
80
|
|
|
42
|
-
@Prop({ attribute: 'aria-label' }) ariaLabel: string
|
|
81
|
+
@Prop({ attribute: 'aria-label' }) ariaLabel: string | undefined;
|
|
43
82
|
|
|
44
83
|
@Event() dsClick!: EventEmitter<MouseEvent>;
|
|
45
84
|
|
|
@@ -51,34 +90,81 @@ export class ButtonFilled {
|
|
|
51
90
|
}
|
|
52
91
|
|
|
53
92
|
private handleClick = (event: MouseEvent) => {
|
|
54
|
-
if (this.
|
|
93
|
+
if (this.isInactive) return;
|
|
55
94
|
this.dsClick.emit(event);
|
|
56
95
|
};
|
|
57
96
|
|
|
97
|
+
private get showIcon(): boolean {
|
|
98
|
+
return this.variant === 'icon' || this.variant === 'icon-label';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private get showLabel(): boolean {
|
|
102
|
+
return this.variant === 'label' || this.variant === 'icon-label';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private get accessibleName(): string | undefined {
|
|
106
|
+
if (this.ariaLabel) return this.ariaLabel;
|
|
107
|
+
if (this.showLabel && this.label) return undefined;
|
|
108
|
+
if (this.variant === 'icon') return this.icon || 'action';
|
|
109
|
+
return this.label || 'action';
|
|
110
|
+
}
|
|
111
|
+
|
|
58
112
|
render() {
|
|
113
|
+
const textVariant = TEXT_VARIANT[this.size];
|
|
114
|
+
const iconSize = ICON_SIZE[this.size];
|
|
115
|
+
|
|
59
116
|
const cls: Record<string, boolean> = {
|
|
60
117
|
'button-filled': true,
|
|
61
118
|
'ds-focus-ring-inset': true,
|
|
62
|
-
'
|
|
119
|
+
'ds-interaction-fill': !this.isInactive,
|
|
120
|
+
/* Bold is the default filled contrast — on-bold interaction tokens. */
|
|
121
|
+
'ds-interaction-fill--on-bold': this.contrast === 'bold',
|
|
122
|
+
'ds-interaction-fill--on-strong': this.contrast === 'strong',
|
|
123
|
+
'ds-interaction-fill--on-medium': this.contrast === 'medium',
|
|
124
|
+
/* faint → default app interaction tokens (no --on-*). */
|
|
125
|
+
'ds-control-inactive': this.isInactive,
|
|
126
|
+
'ds-control--md': this.size === 'md',
|
|
127
|
+
'ds-control--sm': this.size === 'sm',
|
|
128
|
+
'ds-control--xs': this.size === 'xs',
|
|
129
|
+
'button-filled--icon': this.variant === 'icon',
|
|
130
|
+
'button-filled--label': this.variant === 'label',
|
|
131
|
+
'button-filled--icon-label': this.variant === 'icon-label',
|
|
63
132
|
[`button-filled--intent-${this.intent}`]: true,
|
|
64
133
|
[`button-filled--contrast-${this.contrast}`]: this.contrast !== 'bold',
|
|
65
134
|
};
|
|
66
135
|
|
|
67
136
|
return (
|
|
68
|
-
<Host
|
|
137
|
+
<Host
|
|
138
|
+
class={{
|
|
139
|
+
'button-filled-host': true,
|
|
140
|
+
'button-filled-host--icon': this.variant === 'icon',
|
|
141
|
+
'ds-control--md': this.size === 'md',
|
|
142
|
+
'ds-control--sm': this.size === 'sm',
|
|
143
|
+
'ds-control--xs': this.size === 'xs',
|
|
144
|
+
...controlWidthClass(this.width),
|
|
145
|
+
}}
|
|
146
|
+
tabIndex={-1}
|
|
147
|
+
>
|
|
69
148
|
<button
|
|
70
149
|
ref={el => {
|
|
71
150
|
this.buttonEl = el ?? null;
|
|
72
151
|
}}
|
|
73
152
|
type={this.type}
|
|
74
153
|
class={cls}
|
|
75
|
-
disabled={this.
|
|
76
|
-
aria-label={this.
|
|
154
|
+
disabled={this.isInactive}
|
|
155
|
+
aria-label={this.accessibleName}
|
|
77
156
|
onClick={this.handleClick}
|
|
78
157
|
>
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
|
|
158
|
+
{this.showIcon && (
|
|
159
|
+
<span class="button-filled__icon-wrap ds-interaction-fill__content">
|
|
160
|
+
<ds-icon name={this.icon} size={iconSize} color="inherit" />
|
|
161
|
+
</span>
|
|
162
|
+
)}
|
|
163
|
+
{this.showLabel && (
|
|
164
|
+
<span class={{ 'button-filled__label': true, [textVariant]: true, 'ds-interaction-fill__content': true }}>
|
|
165
|
+
{this.label}
|
|
166
|
+
</span>
|
|
167
|
+
)}
|
|
82
168
|
</button>
|
|
83
169
|
</Host>
|
|
84
170
|
);
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { Component, Element, Event, EventEmitter, h, Host, Method, Prop } from '@stencil/core';
|
|
2
|
+
import { controlWidthClass, type ControlWidth } from '../../utils/control-width';
|
|
3
|
+
|
|
4
|
+
export type ButtonUnfilledOnBackgroundContrast = 'default' | 'medium' | 'bold' | 'strong';
|
|
5
|
+
|
|
6
|
+
export type ButtonUnfilledBackground = 'always-dark' | 'navigation';
|
|
7
|
+
|
|
8
|
+
export type ButtonUnfilledVariant = 'icon' | 'label' | 'icon-label';
|
|
9
|
+
|
|
10
|
+
export type ButtonUnfilledSize = 'md' | 'sm' | 'xs';
|
|
11
|
+
|
|
12
|
+
export type ButtonUnfilledWidth = ControlWidth;
|
|
13
|
+
|
|
14
|
+
/** Emphasis text per control-density size (buttons use emphasis, unlike Tag). */
|
|
15
|
+
const TEXT_VARIANT: Record<ButtonUnfilledSize, string> = {
|
|
16
|
+
md: 'text-body-medium-emphasis',
|
|
17
|
+
sm: 'text-body-small-emphasis',
|
|
18
|
+
xs: 'text-caption-emphasis',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* `ds-icon` size prop matching control-density icon metrics
|
|
23
|
+
* (md→20 / sm→16 / xs→12 via `--dimension-iconography-*`).
|
|
24
|
+
*/
|
|
25
|
+
const ICON_SIZE: Record<ButtonUnfilledSize, 'md' | 'sm' | 'xs'> = {
|
|
26
|
+
md: 'md',
|
|
27
|
+
sm: 'sm',
|
|
28
|
+
xs: 'xs',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
@Component({
|
|
32
|
+
tag: 'ds-button-unfilled',
|
|
33
|
+
styleUrl: 'ButtonUnfilled.css',
|
|
34
|
+
scoped: true,
|
|
35
|
+
})
|
|
36
|
+
export class ButtonUnfilled {
|
|
37
|
+
@Element() el!: HTMLElement;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Content layout. Default is label-only; pass `icon` for icon-only chrome
|
|
41
|
+
* (nav / tool rails) or `icon-label` for leading icon + text.
|
|
42
|
+
*/
|
|
43
|
+
@Prop() variant: ButtonUnfilledVariant = 'label';
|
|
44
|
+
|
|
45
|
+
/** Control density (height, padding, icon, type). */
|
|
46
|
+
@Prop() size: ButtonUnfilledSize = 'md';
|
|
47
|
+
|
|
48
|
+
/** Width fit — hug content (default) or fill the parent. */
|
|
49
|
+
@Prop() width: ButtonUnfilledWidth = 'hug';
|
|
50
|
+
|
|
51
|
+
/** Visible text for `label` / `icon-label` variants. */
|
|
52
|
+
@Prop() label: string = '';
|
|
53
|
+
|
|
54
|
+
/** Icon name passed to <ds-icon> for `icon` / `icon-label` variants. */
|
|
55
|
+
@Prop() icon: string = '';
|
|
56
|
+
|
|
57
|
+
/** Active/selected visual state. Always promotes foreground to primary. */
|
|
58
|
+
@Prop() isActive: boolean = false;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* When active, render the selected interaction fill.
|
|
62
|
+
* Default `true` for general UI. Shell chrome (nav / tool rails) should pass
|
|
63
|
+
* `false` so selection is foreground-only (primary color, no fill).
|
|
64
|
+
*/
|
|
65
|
+
@Prop() activeFill: boolean = true;
|
|
66
|
+
|
|
67
|
+
/** Show a 1px secondary inset border. Default on; shell chrome can pass `false`. */
|
|
68
|
+
@Prop() hasBorder: boolean = true;
|
|
69
|
+
|
|
70
|
+
/** Show a notification dot at the top-right of the icon zone (icon variant only). */
|
|
71
|
+
@Prop() dot: boolean = false;
|
|
72
|
+
|
|
73
|
+
/** Disables interaction. */
|
|
74
|
+
@Prop() isInactive: boolean = false;
|
|
75
|
+
|
|
76
|
+
/** Native button type. */
|
|
77
|
+
@Prop() type: 'button' | 'submit' | 'reset' = 'button';
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Foreground and interaction tokens when the button sits on a contrasting parent
|
|
81
|
+
* background (default, medium, bold, or strong).
|
|
82
|
+
*/
|
|
83
|
+
@Prop({ attribute: 'on-background-contrast' })
|
|
84
|
+
backgroundContrast?: ButtonUnfilledOnBackgroundContrast;
|
|
85
|
+
|
|
86
|
+
/** Parent surface context for navigation and always-dark chrome. */
|
|
87
|
+
@Prop() background: ButtonUnfilledBackground | undefined;
|
|
88
|
+
|
|
89
|
+
@Prop({ attribute: 'aria-label' }) ariaLabel: string | undefined;
|
|
90
|
+
@Prop() controls: string | undefined;
|
|
91
|
+
@Prop() expanded: boolean | undefined;
|
|
92
|
+
@Prop() haspopup: string | undefined;
|
|
93
|
+
@Prop() pressed: boolean | undefined;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Native `tabindex` for roving keyboard groups in shell chrome.
|
|
97
|
+
* Omit for the default button tab stop (`0`).
|
|
98
|
+
*/
|
|
99
|
+
@Prop({ attribute: 'tab-index' }) focusTabIndex?: number;
|
|
100
|
+
|
|
101
|
+
@Event() dsClick!: EventEmitter<MouseEvent>;
|
|
102
|
+
@Event() dsChange!: EventEmitter<boolean>;
|
|
103
|
+
|
|
104
|
+
private buttonEl: HTMLButtonElement | null = null;
|
|
105
|
+
|
|
106
|
+
@Method()
|
|
107
|
+
async setFocus() {
|
|
108
|
+
this.buttonEl?.focus();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private handleClick = (event: MouseEvent) => {
|
|
112
|
+
if (this.isInactive) return;
|
|
113
|
+
this.dsClick.emit(event);
|
|
114
|
+
this.dsChange.emit(!this.isActive);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
private effectiveContrast(): ButtonUnfilledOnBackgroundContrast {
|
|
118
|
+
return this.backgroundContrast ?? 'default';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private get showIcon(): boolean {
|
|
122
|
+
return this.variant === 'icon' || this.variant === 'icon-label';
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private get showLabel(): boolean {
|
|
126
|
+
return this.variant === 'label' || this.variant === 'icon-label';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private get showDot(): boolean {
|
|
130
|
+
return this.variant === 'icon' && this.dot;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Knock-out ring: selected fill → active wash; otherwise surface token. */
|
|
134
|
+
private get dotRing(): string {
|
|
135
|
+
if (this.isActive && this.activeFill) {
|
|
136
|
+
return 'var(--ds-interaction-active)';
|
|
137
|
+
}
|
|
138
|
+
return 'var(--ds-button-unfilled-dot-ring)';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private get accessibleName(): string | undefined {
|
|
142
|
+
if (this.ariaLabel) return this.ariaLabel;
|
|
143
|
+
if (this.showLabel && this.label) return undefined;
|
|
144
|
+
if (this.variant === 'icon') return this.icon || 'action';
|
|
145
|
+
return this.label || 'action';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
render() {
|
|
149
|
+
const bg = this.background;
|
|
150
|
+
const contrast = this.effectiveContrast();
|
|
151
|
+
const textVariant = TEXT_VARIANT[this.size];
|
|
152
|
+
const iconSize = ICON_SIZE[this.size];
|
|
153
|
+
|
|
154
|
+
const cls: Record<string, boolean> = {
|
|
155
|
+
'button-unfilled': true,
|
|
156
|
+
'ds-focus-ring-inset': true,
|
|
157
|
+
'ds-interaction-fill': true,
|
|
158
|
+
'ds-interaction-fill--selected': this.isActive && this.activeFill && !this.isInactive,
|
|
159
|
+
'ds-interaction-fill--on-medium': contrast === 'medium',
|
|
160
|
+
'ds-interaction-fill--on-bold': contrast === 'bold',
|
|
161
|
+
'ds-interaction-fill--on-strong': contrast === 'strong',
|
|
162
|
+
'ds-interaction-fill--on-always-dark': bg === 'always-dark',
|
|
163
|
+
'ds-interaction-fill--on-navigation': bg === 'navigation',
|
|
164
|
+
'button-unfilled--active': this.isActive,
|
|
165
|
+
'button-unfilled--bordered': this.hasBorder,
|
|
166
|
+
'ds-control-inactive': this.isInactive,
|
|
167
|
+
'ds-control--md': this.size === 'md',
|
|
168
|
+
'ds-control--sm': this.size === 'sm',
|
|
169
|
+
'ds-control--xs': this.size === 'xs',
|
|
170
|
+
'button-unfilled--icon': this.variant === 'icon',
|
|
171
|
+
'button-unfilled--label': this.variant === 'label',
|
|
172
|
+
'button-unfilled--icon-label': this.variant === 'icon-label',
|
|
173
|
+
'button-unfilled--contrast-medium': contrast === 'medium',
|
|
174
|
+
'button-unfilled--contrast-bold': contrast === 'bold',
|
|
175
|
+
'button-unfilled--contrast-strong': contrast === 'strong',
|
|
176
|
+
'button-unfilled--on-always-dark': bg === 'always-dark',
|
|
177
|
+
'button-unfilled--on-navigation': bg === 'navigation',
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<Host
|
|
182
|
+
class={{
|
|
183
|
+
'button-unfilled-host': true,
|
|
184
|
+
'button-unfilled-host--icon': this.variant === 'icon',
|
|
185
|
+
'ds-control--md': this.size === 'md',
|
|
186
|
+
'ds-control--sm': this.size === 'sm',
|
|
187
|
+
'ds-control--xs': this.size === 'xs',
|
|
188
|
+
...controlWidthClass(this.width),
|
|
189
|
+
}}
|
|
190
|
+
tabIndex={-1}
|
|
191
|
+
>
|
|
192
|
+
<button
|
|
193
|
+
ref={el => {
|
|
194
|
+
this.buttonEl = el ?? null;
|
|
195
|
+
}}
|
|
196
|
+
type={this.type}
|
|
197
|
+
class={cls}
|
|
198
|
+
disabled={this.isInactive}
|
|
199
|
+
tabIndex={this.focusTabIndex ?? 0}
|
|
200
|
+
aria-label={this.accessibleName}
|
|
201
|
+
aria-controls={this.controls}
|
|
202
|
+
aria-expanded={this.expanded === undefined ? undefined : String(this.expanded)}
|
|
203
|
+
aria-haspopup={this.haspopup}
|
|
204
|
+
aria-pressed={this.pressed === undefined ? undefined : String(this.pressed)}
|
|
205
|
+
onClick={this.handleClick}
|
|
206
|
+
>
|
|
207
|
+
{this.showIcon && (
|
|
208
|
+
<span class="button-unfilled__icon-wrap ds-interaction-fill__content">
|
|
209
|
+
<ds-icon name={this.icon} size={iconSize} color="inherit" />
|
|
210
|
+
{this.showDot && (
|
|
211
|
+
<ds-badge
|
|
212
|
+
class="button-unfilled__dot"
|
|
213
|
+
variant="dot"
|
|
214
|
+
background={this.dotRing}
|
|
215
|
+
label=""
|
|
216
|
+
aria-hidden="true"
|
|
217
|
+
/>
|
|
218
|
+
)}
|
|
219
|
+
</span>
|
|
220
|
+
)}
|
|
221
|
+
{this.showLabel && (
|
|
222
|
+
<span class={{ 'button-unfilled__label': true, [textVariant]: true, 'ds-interaction-fill__content': true }}>
|
|
223
|
+
{this.label}
|
|
224
|
+
</span>
|
|
225
|
+
)}
|
|
226
|
+
</button>
|
|
227
|
+
</Host>
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Component, h, Host, Prop } from '@stencil/core';
|
|
2
|
+
|
|
3
|
+
export type CardWidth = 'sm' | 'md' | 'lg';
|
|
4
|
+
|
|
5
|
+
/** Visual chrome recipe — default app surface, or settings edit wash. */
|
|
6
|
+
export type CardAppearance = 'default' | 'editing';
|
|
7
|
+
|
|
8
|
+
const CARD_WIDTH_VARS: Record<CardWidth, string> = {
|
|
9
|
+
sm: 'var(--dimension-card-width-sm)',
|
|
10
|
+
md: 'var(--dimension-card-width-md)',
|
|
11
|
+
lg: 'var(--dimension-card-width-lg)',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const CARD_HEIGHT_VARS: Record<CardWidth, string> = {
|
|
15
|
+
sm: 'var(--dimension-card-height-sm)',
|
|
16
|
+
md: 'var(--dimension-card-height-md)',
|
|
17
|
+
lg: 'var(--dimension-card-height-lg)',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const FAINT_BRAND_TITLE_COLOR = 'var(--color-foreground-faint-brand)';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Shared card chrome — width + matching min-height tokens, header (title + actions),
|
|
24
|
+
* and a flex body that fills leftover space. Compose this from settings / data-viz cards.
|
|
25
|
+
*/
|
|
26
|
+
@Component({
|
|
27
|
+
tag: 'ds-card',
|
|
28
|
+
styleUrl: 'Card.css',
|
|
29
|
+
scoped: true,
|
|
30
|
+
})
|
|
31
|
+
export class Card {
|
|
32
|
+
/** Section heading shown in the card header. */
|
|
33
|
+
@Prop() heading!: string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Card width token (`sm` / `md` / `lg`). Also sets host `min-height` to the
|
|
37
|
+
* matching `--dimension-card-height-*` so empty bodies still fill the card.
|
|
38
|
+
*/
|
|
39
|
+
@Prop() cardWidth: CardWidth = 'md';
|
|
40
|
+
|
|
41
|
+
/** Chrome recipe — `editing` applies the settings edit wash. */
|
|
42
|
+
@Prop() appearance: CardAppearance = 'default';
|
|
43
|
+
|
|
44
|
+
render() {
|
|
45
|
+
const editing = this.appearance === 'editing';
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Host
|
|
49
|
+
class={{
|
|
50
|
+
card: true,
|
|
51
|
+
'card--editing': editing,
|
|
52
|
+
}}
|
|
53
|
+
style={{
|
|
54
|
+
'--_card-width': CARD_WIDTH_VARS[this.cardWidth],
|
|
55
|
+
'--_card-min-height': CARD_HEIGHT_VARS[this.cardWidth],
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
<header class="card__header">
|
|
59
|
+
<div class="card__title-wrap">
|
|
60
|
+
<ds-text
|
|
61
|
+
class="card__title"
|
|
62
|
+
variant="text-title-small"
|
|
63
|
+
color={editing ? FAINT_BRAND_TITLE_COLOR : 'primary'}
|
|
64
|
+
as="h2"
|
|
65
|
+
>
|
|
66
|
+
{this.heading}
|
|
67
|
+
</ds-text>
|
|
68
|
+
</div>
|
|
69
|
+
<div class="card__actions">
|
|
70
|
+
<slot name="actions" />
|
|
71
|
+
</div>
|
|
72
|
+
</header>
|
|
73
|
+
<div class="card__body">
|
|
74
|
+
<slot />
|
|
75
|
+
</div>
|
|
76
|
+
</Host>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { CardWidth, CardAppearance } from './Card';
|