@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.
Files changed (262) hide show
  1. package/README.md +13 -13
  2. package/dist/.build-stamp +1 -1
  3. package/dist/components/ds-app-shell.js +1 -1
  4. package/dist/components/ds-banner.js +1 -1
  5. package/dist/components/ds-banner.js.map +1 -1
  6. package/dist/components/ds-bar-nav.js +1 -1
  7. package/dist/components/ds-bar-nav.js.map +1 -1
  8. package/dist/components/ds-button-filled.js +1 -1
  9. package/dist/components/{ds-accordion.d.ts → ds-button-unfilled.d.ts} +4 -4
  10. package/dist/components/ds-button-unfilled.js +2 -0
  11. package/dist/components/{ds-card-data-viz.d.ts → ds-card-data-viz-donut.d.ts} +4 -4
  12. package/dist/components/ds-card-data-viz-donut.js +2 -0
  13. package/dist/components/ds-card-data-viz-donut.js.map +1 -0
  14. package/dist/components/ds-card-setting.js +1 -1
  15. package/dist/components/ds-card-setting.js.map +1 -1
  16. package/dist/components/{ds-fade.d.ts → ds-card.d.ts} +4 -4
  17. package/dist/components/ds-card.js +2 -0
  18. package/dist/components/ds-card.js.map +1 -0
  19. package/dist/components/ds-chart-bar.js +1 -1
  20. package/dist/components/ds-chart-bar.js.map +1 -1
  21. package/dist/components/ds-chart-donut.js +1 -1
  22. package/dist/components/ds-chart-donut.js.map +1 -1
  23. package/dist/components/ds-chart-legend.js +1 -1
  24. package/dist/components/ds-chart-legend.js.map +1 -1
  25. package/dist/components/ds-chart-line.js +1 -1
  26. package/dist/components/ds-checkbox.js +1 -1
  27. package/dist/components/ds-checkbox.js.map +1 -1
  28. package/dist/components/ds-chip.js +1 -1
  29. package/dist/components/ds-chip.js.map +1 -1
  30. package/dist/components/ds-empty-state.js +1 -1
  31. package/dist/components/ds-empty-state.js.map +1 -1
  32. package/dist/components/ds-field.js +1 -1
  33. package/dist/components/ds-icon.js +1 -1
  34. package/dist/components/ds-input.js +1 -1
  35. package/dist/components/ds-input.js.map +1 -1
  36. package/dist/components/ds-loader.js +1 -1
  37. package/dist/components/ds-loader.js.map +1 -1
  38. package/dist/components/ds-menu.js +1 -1
  39. package/dist/components/ds-modal.js +1 -1
  40. package/dist/components/ds-pagination.js +1 -1
  41. package/dist/components/ds-pagination.js.map +1 -1
  42. package/dist/components/ds-panel-nav.js +1 -1
  43. package/dist/components/ds-panel-nav.js.map +1 -1
  44. package/dist/components/ds-panel-tools.js +1 -1
  45. package/dist/components/ds-panel-tools.js.map +1 -1
  46. package/dist/components/ds-radio-group.js +1 -1
  47. package/dist/components/ds-radio-group.js.map +1 -1
  48. package/dist/components/ds-select.js +1 -1
  49. package/dist/components/ds-select.js.map +1 -1
  50. package/dist/components/ds-shell-gradient-picker.js +1 -1
  51. package/dist/components/ds-shell-gradient-swatch.js +1 -1
  52. package/dist/components/ds-skeleton.js +1 -1
  53. package/dist/components/ds-skeleton.js.map +1 -1
  54. package/dist/components/ds-slider.js +1 -1
  55. package/dist/components/ds-slider.js.map +1 -1
  56. package/dist/components/ds-tab-group-nav.js +1 -1
  57. package/dist/components/ds-tab-group.js +1 -1
  58. package/dist/components/ds-tab-group.js.map +1 -1
  59. package/dist/components/ds-table.js +1 -1
  60. package/dist/components/ds-table.js.map +1 -1
  61. package/dist/components/ds-tag.js +1 -1
  62. package/dist/components/ds-tag.js.map +1 -1
  63. package/dist/components/ds-text.js +1 -1
  64. package/dist/components/ds-toggle.js +1 -1
  65. package/dist/components/ds-toggle.js.map +1 -1
  66. package/dist/components/ds-tooltip-data-viz.js +1 -1
  67. package/dist/components/ds-tooltip-data-viz.js.map +1 -1
  68. package/dist/components/ds-tooltip.js +1 -1
  69. package/dist/components/ds-tooltip.js.map +1 -1
  70. package/dist/components/p-1m8r0wFg.js +2 -0
  71. package/dist/components/p-1m8r0wFg.js.map +1 -0
  72. package/dist/components/p-3FLHei19.js +2 -0
  73. package/dist/components/p-3FLHei19.js.map +1 -0
  74. package/dist/components/p-B2_D4IDN.js +2 -0
  75. package/dist/components/p-B2_D4IDN.js.map +1 -0
  76. package/dist/components/p-B5NcWtpp.js +2 -0
  77. package/dist/components/p-B5NcWtpp.js.map +1 -0
  78. package/dist/components/{p-8Nt92j1-.js → p-B82KZX9D.js} +2 -2
  79. package/dist/components/p-BQq26pt9.js.map +1 -1
  80. package/dist/components/p-B_g8X0eh.js +2 -0
  81. package/dist/components/p-B_g8X0eh.js.map +1 -0
  82. package/dist/components/{p-DdFUTZ3y.js → p-Be3PHv34.js} +2 -2
  83. package/dist/components/p-CQmf2CeW.js +2 -0
  84. package/dist/components/p-CQmf2CeW.js.map +1 -0
  85. package/dist/components/{p-DOU4cbpc.js → p-CtwNUCnp.js} +2 -2
  86. package/dist/components/p-CuRjYmBk.js +2 -0
  87. package/dist/components/p-CuRjYmBk.js.map +1 -0
  88. package/dist/components/p-CwARVsZQ.js +2 -0
  89. package/dist/components/p-CwARVsZQ.js.map +1 -0
  90. package/dist/components/p-DohXlNCJ.js +2 -0
  91. package/dist/components/p-DohXlNCJ.js.map +1 -0
  92. package/dist/components/p-DuFm-ieS.js +2 -0
  93. package/dist/components/p-DuFm-ieS.js.map +1 -0
  94. package/dist/components/p-EK1hOP19.js.map +1 -1
  95. package/dist/lib/nav/index.js +3 -0
  96. package/dist/lib/nav/index.js.map +2 -2
  97. package/dist/lib/utils/control-width.d.ts +4 -0
  98. package/dist/lib/utils/index.d.ts +2 -0
  99. package/dist/lib/utils/index.js +20 -1
  100. package/dist/lib/utils/index.js.map +3 -3
  101. package/dist/lib/utils/token-defaults.d.ts +7 -0
  102. package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +21 -3
  103. package/dist/types/components/ButtonFilled/index.d.ts +1 -1
  104. package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +70 -0
  105. package/dist/types/components/ButtonUnfilled/index.d.ts +2 -0
  106. package/dist/types/components/Card/Card.d.ts +20 -0
  107. package/dist/types/components/Card/index.d.ts +2 -0
  108. package/dist/types/components/CardDataVizDonut/CardDataVizDonut.d.ts +26 -0
  109. package/dist/types/components/CardDataVizDonut/index.d.ts +2 -0
  110. package/dist/types/components/CardSetting/CardSetting.d.ts +7 -2
  111. package/dist/types/components/ChartDonut/ChartDonut.d.ts +31 -1
  112. package/dist/types/components/Checkbox/Checkbox.d.ts +1 -1
  113. package/dist/types/components/Chip/Chip.d.ts +18 -14
  114. package/dist/types/components/Chip/index.d.ts +1 -1
  115. package/dist/types/components/Input/Input.d.ts +1 -1
  116. package/dist/types/components/Pagination/Pagination.d.ts +1 -1
  117. package/dist/types/components/PanelNav/PanelNav.d.ts +2 -0
  118. package/dist/types/components/PanelTools/panel-tools-types.d.ts +1 -1
  119. package/dist/types/components/RadioGroup/RadioGroup.d.ts +2 -2
  120. package/dist/types/components/Select/Select.d.ts +34 -2
  121. package/dist/types/components/Select/index.d.ts +2 -0
  122. package/dist/types/components/ShellGradientSwatch/ShellGradientSwatch.d.ts +1 -1
  123. package/dist/types/components/Slider/Slider.d.ts +1 -1
  124. package/dist/types/components/TabGroup/TabGroup.d.ts +1 -1
  125. package/dist/types/components/TabGroup/tab-item-utils.d.ts +2 -1
  126. package/dist/types/components/TabGroupNav/TabGroupNav.d.ts +1 -1
  127. package/dist/types/components/Tag/Tag.d.ts +0 -2
  128. package/dist/types/components/Tag/index.d.ts +1 -1
  129. package/dist/types/components/Toggle/Toggle.d.ts +1 -1
  130. package/dist/types/components/Tooltip/Tooltip.d.ts +25 -6
  131. package/dist/types/components/TooltipDataViz/TooltipDataViz.d.ts +18 -0
  132. package/dist/types/components.d.ts +474 -576
  133. package/dist/types/utils/control-width.d.ts +5 -0
  134. package/dist/types/utils/index.d.ts +2 -0
  135. package/dist/types/utils/token-defaults.d.ts +7 -0
  136. package/package.json +7 -4
  137. package/src/angular/index.ts +3 -9
  138. package/src/angular/proxies.ts +62 -215
  139. package/src/react/components.ts +3 -9
  140. package/src/react/ds-button-unfilled.ts +33 -0
  141. package/src/react/ds-card-data-viz-donut.ts +27 -0
  142. package/src/react/{ds-fade.ts → ds-card.ts} +7 -7
  143. package/src/react/ds-chip.ts +2 -10
  144. package/src/wc/components/BarNav/BarNav.tsx +3 -2
  145. package/src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts +1 -1
  146. package/src/wc/components/ButtonFilled/ButtonFilled.tsx +97 -11
  147. package/src/wc/components/ButtonFilled/index.ts +7 -1
  148. package/src/wc/components/ButtonUnfilled/ButtonUnfilled.tsx +230 -0
  149. package/src/wc/components/ButtonUnfilled/index.ts +7 -0
  150. package/src/wc/components/Card/Card.tsx +79 -0
  151. package/src/wc/components/Card/index.ts +1 -0
  152. package/src/wc/components/{CardDataViz/CardDataViz.tsx → CardDataVizDonut/CardDataVizDonut.tsx} +47 -41
  153. package/src/wc/components/CardDataVizDonut/index.ts +1 -0
  154. package/src/wc/components/CardSetting/CardSetting.tsx +21 -36
  155. package/src/wc/components/ChartDonut/ChartDonut.tsx +159 -11
  156. package/src/wc/components/ChartLegend/ChartLegend.tsx +3 -0
  157. package/src/wc/components/Checkbox/Checkbox.tsx +5 -5
  158. package/src/wc/components/Chip/Chip.tsx +50 -67
  159. package/src/wc/components/Chip/index.ts +1 -1
  160. package/src/wc/components/Input/Input.tsx +4 -4
  161. package/src/wc/components/Menu/Menu.tsx +7 -4
  162. package/src/wc/components/Pagination/Pagination.tsx +6 -6
  163. package/src/wc/components/PanelNav/PanelNav.tsx +77 -48
  164. package/src/wc/components/PanelTools/PanelTools.tsx +19 -16
  165. package/src/wc/components/PanelTools/panel-tools-types.ts +1 -1
  166. package/src/wc/components/PanelTools/panel-tools-utils.ts +1 -1
  167. package/src/wc/components/RadioGroup/RadioGroup.tsx +7 -7
  168. package/src/wc/components/Select/Select.tsx +145 -64
  169. package/src/wc/components/Select/index.ts +1 -0
  170. package/src/wc/components/ShellGradientSwatch/ShellGradientSwatch.tsx +4 -3
  171. package/src/wc/components/Slider/Slider.tsx +7 -3
  172. package/src/wc/components/TabGroup/TabGroup.tsx +13 -7
  173. package/src/wc/components/TabGroup/tab-item-utils.ts +2 -1
  174. package/src/wc/components/TabGroupNav/TabGroupNav.tsx +14 -13
  175. package/src/wc/components/Tag/Tag.tsx +25 -24
  176. package/src/wc/components/Tag/index.ts +1 -1
  177. package/src/wc/components/Toggle/Toggle.tsx +6 -6
  178. package/src/wc/components/Tooltip/Tooltip.tsx +166 -64
  179. package/src/wc/components/TooltipDataViz/TooltipDataViz.tsx +57 -2
  180. package/src/wc/components.d.ts +474 -579
  181. package/src/wc/utils/control-density.css +42 -0
  182. package/src/wc/utils/control-inactive.css +20 -0
  183. package/src/wc/utils/control-width.css +28 -0
  184. package/src/wc/utils/control-width.ts +10 -0
  185. package/src/wc/utils/index.ts +2 -0
  186. package/src/wc/utils/interaction-fill.css +162 -0
  187. package/src/wc/utils/scroll-edge-fade.css +5 -0
  188. package/src/wc/utils/token-defaults.ts +10 -0
  189. package/dist/components/ds-accordion.js +0 -2
  190. package/dist/components/ds-accordion.js.map +0 -1
  191. package/dist/components/ds-breadcrumb.d.ts +0 -11
  192. package/dist/components/ds-breadcrumb.js +0 -2
  193. package/dist/components/ds-breadcrumb.js.map +0 -1
  194. package/dist/components/ds-button-unfilled-icon.d.ts +0 -11
  195. package/dist/components/ds-button-unfilled-icon.js +0 -2
  196. package/dist/components/ds-card-data-viz.js +0 -2
  197. package/dist/components/ds-card-data-viz.js.map +0 -1
  198. package/dist/components/ds-fade.js +0 -2
  199. package/dist/components/ds-fade.js.map +0 -1
  200. package/dist/components/ds-header.d.ts +0 -11
  201. package/dist/components/ds-header.js +0 -2
  202. package/dist/components/ds-header.js.map +0 -1
  203. package/dist/components/ds-scrollbar.d.ts +0 -11
  204. package/dist/components/ds-scrollbar.js +0 -2
  205. package/dist/components/ds-scrollbar.js.map +0 -1
  206. package/dist/components/ds-surface.d.ts +0 -11
  207. package/dist/components/ds-surface.js +0 -2
  208. package/dist/components/ds-surface.js.map +0 -1
  209. package/dist/components/ds-toast-provider.d.ts +0 -11
  210. package/dist/components/ds-toast-provider.js +0 -2
  211. package/dist/components/ds-toast-provider.js.map +0 -1
  212. package/dist/components/p-BMQbEIrQ.js +0 -2
  213. package/dist/components/p-BMQbEIrQ.js.map +0 -1
  214. package/dist/components/p-BSFgy5r6.js +0 -2
  215. package/dist/components/p-BSFgy5r6.js.map +0 -1
  216. package/dist/components/p-CBUIn8dk.js +0 -2
  217. package/dist/components/p-CBUIn8dk.js.map +0 -1
  218. package/dist/components/p-ChVwCVHy.js +0 -2
  219. package/dist/components/p-ChVwCVHy.js.map +0 -1
  220. package/dist/components/p-CpNIQXz6.js +0 -2
  221. package/dist/components/p-CpNIQXz6.js.map +0 -1
  222. package/dist/components/p-CvgHQfvT.js +0 -2
  223. package/dist/components/p-CvgHQfvT.js.map +0 -1
  224. package/dist/components/p-bDf6yBQd.js +0 -2
  225. package/dist/components/p-bDf6yBQd.js.map +0 -1
  226. package/dist/types/components/Accordion/Accordion.d.ts +0 -28
  227. package/dist/types/components/Breadcrumb/Breadcrumb.d.ts +0 -16
  228. package/dist/types/components/ButtonUnfilledIcon/ButtonUnfilledIcon.d.ts +0 -45
  229. package/dist/types/components/ButtonUnfilledIcon/index.d.ts +0 -2
  230. package/dist/types/components/CardDataViz/CardDataViz.d.ts +0 -22
  231. package/dist/types/components/CardDataViz/index.d.ts +0 -2
  232. package/dist/types/components/Fade/Fade.d.ts +0 -22
  233. package/dist/types/components/Fade/index.d.ts +0 -2
  234. package/dist/types/components/Header/Header.d.ts +0 -7
  235. package/dist/types/components/Scrollbar/Scrollbar.d.ts +0 -27
  236. package/dist/types/components/Surface/Surface.d.ts +0 -22
  237. package/dist/types/components/Toast/Toast.d.ts +0 -16
  238. package/dist/types/components/Toast/toast-service.d.ts +0 -24
  239. package/src/react/ds-accordion.ts +0 -27
  240. package/src/react/ds-breadcrumb.ts +0 -27
  241. package/src/react/ds-button-unfilled-icon.ts +0 -33
  242. package/src/react/ds-card-data-viz.ts +0 -26
  243. package/src/react/ds-header.ts +0 -26
  244. package/src/react/ds-scrollbar.ts +0 -26
  245. package/src/react/ds-surface.ts +0 -26
  246. package/src/react/ds-toast-provider.ts +0 -26
  247. package/src/wc/components/Accordion/Accordion.tsx +0 -144
  248. package/src/wc/components/Breadcrumb/Breadcrumb.tsx +0 -61
  249. package/src/wc/components/ButtonUnfilledIcon/ButtonUnfilledIcon.tsx +0 -129
  250. package/src/wc/components/ButtonUnfilledIcon/index.ts +0 -1
  251. package/src/wc/components/CardDataViz/index.ts +0 -1
  252. package/src/wc/components/Fade/Fade.tsx +0 -58
  253. package/src/wc/components/Fade/index.ts +0 -1
  254. package/src/wc/components/Header/Header.tsx +0 -33
  255. package/src/wc/components/Scrollbar/Scrollbar.tsx +0 -189
  256. package/src/wc/components/Surface/Surface.tsx +0 -81
  257. package/src/wc/components/Toast/Toast.tsx +0 -179
  258. package/src/wc/components/Toast/toast-service.ts +0 -67
  259. /package/dist/components/{ds-button-unfilled-icon.js.map → ds-button-unfilled.js.map} +0 -0
  260. /package/dist/components/{p-8Nt92j1-.js.map → p-B82KZX9D.js.map} +0 -0
  261. /package/dist/components/{p-DdFUTZ3y.js.map → p-Be3PHv34.js.map} +0 -0
  262. /package/dist/components/{p-DOU4cbpc.js.map → p-CtwNUCnp.js.map} +0 -0
@@ -1,189 +0,0 @@
1
- import { Component, Prop, State, Element, h, Host } from '@stencil/core';
2
-
3
- export type ScrollbarVariant = 'default' | 'thick';
4
-
5
- @Component({
6
- tag: 'ds-scrollbar',
7
- styleUrl: 'Scrollbar.css',
8
- scoped: true,
9
- })
10
- export class Scrollbar {
11
- @Element() el!: HTMLElement;
12
-
13
- @Prop() variant: ScrollbarVariant = 'default';
14
- @Prop() showTrackOnHover: boolean = true;
15
-
16
- @State() private thumbHeight: number = 0;
17
- @State() private thumbTop: number = 0;
18
- @State() private thumbWidth: number = 0;
19
- @State() private thumbLeft: number = 0;
20
- @State() private isDragging: boolean = false;
21
- @State() private isDraggingH: boolean = false;
22
- @State() private isPointerInside: boolean = false;
23
-
24
- private contentEl: HTMLElement | null = null;
25
- private resizeObserver: ResizeObserver | null = null;
26
- private scrollHandler: (() => void) | null = null;
27
-
28
- // Drag state (not reactive — no re-render needed)
29
- private dragStartY = 0;
30
- private dragStartScrollTop = 0;
31
- private dragStartX = 0;
32
- private dragStartScrollLeft = 0;
33
-
34
- componentDidLoad() {
35
- this.contentEl = this.el.querySelector('.scrollbar-content') as HTMLElement | null;
36
- if (!this.contentEl) return;
37
-
38
- this.scrollHandler = () => this.updateThumb();
39
- this.contentEl.addEventListener('scroll', this.scrollHandler);
40
-
41
- this.resizeObserver = new ResizeObserver(() => this.updateThumb());
42
- this.resizeObserver.observe(this.contentEl);
43
- window.addEventListener('resize', this.scrollHandler);
44
-
45
- this.updateThumb();
46
- }
47
-
48
- disconnectedCallback() {
49
- if (this.contentEl && this.scrollHandler) {
50
- this.contentEl.removeEventListener('scroll', this.scrollHandler);
51
- }
52
- if (this.scrollHandler) {
53
- window.removeEventListener('resize', this.scrollHandler);
54
- }
55
- this.resizeObserver?.disconnect();
56
- }
57
-
58
- private updateThumb() {
59
- const container = this.el.querySelector('.scrollbar-container') as HTMLElement | null;
60
- const content = this.contentEl;
61
- if (!container || !content) return;
62
-
63
- const cH = container.clientHeight;
64
- const cW = container.clientWidth;
65
- const sH = content.scrollHeight;
66
- const sW = content.scrollWidth;
67
- const st = content.scrollTop;
68
- const sl = content.scrollLeft;
69
-
70
- if (sH <= cH) {
71
- this.thumbHeight = 0;
72
- } else {
73
- const h = Math.max(20, cH * (cH / sH));
74
- this.thumbHeight = h;
75
- this.thumbTop = (st / (sH - cH)) * (cH - h);
76
- }
77
-
78
- if (sW <= cW) {
79
- this.thumbWidth = 0;
80
- } else {
81
- const w = Math.max(20, cW * (cW / sW));
82
- this.thumbWidth = w;
83
- this.thumbLeft = (sl / (sW - cW)) * (cW - w);
84
- }
85
- }
86
-
87
- private handleThumbMouseDown(e: MouseEvent) {
88
- e.preventDefault();
89
- e.stopPropagation();
90
- const content = this.contentEl;
91
- if (!content) return;
92
-
93
- this.isDragging = true;
94
- this.dragStartY = e.clientY;
95
- this.dragStartScrollTop = content.scrollTop;
96
-
97
- const container = this.el.querySelector('.scrollbar-container') as HTMLElement;
98
-
99
- const onMove = (ev: MouseEvent) => {
100
- const deltaY = ev.clientY - this.dragStartY;
101
- const scrollable = content.scrollHeight - container.clientHeight;
102
- const ratio = scrollable / (container.clientHeight - this.thumbHeight);
103
- content.scrollTop = Math.max(0, Math.min(scrollable, this.dragStartScrollTop + deltaY * ratio));
104
- };
105
- const onUp = () => {
106
- this.isDragging = false;
107
- document.removeEventListener('mousemove', onMove);
108
- document.removeEventListener('mouseup', onUp);
109
- };
110
- document.addEventListener('mousemove', onMove);
111
- document.addEventListener('mouseup', onUp);
112
- }
113
-
114
- private handleThumbHMouseDown(e: MouseEvent) {
115
- e.preventDefault();
116
- e.stopPropagation();
117
- const content = this.contentEl;
118
- if (!content) return;
119
-
120
- this.isDraggingH = true;
121
- this.dragStartX = e.clientX;
122
- this.dragStartScrollLeft = content.scrollLeft;
123
-
124
- const container = this.el.querySelector('.scrollbar-container') as HTMLElement;
125
-
126
- const onMove = (ev: MouseEvent) => {
127
- const deltaX = ev.clientX - this.dragStartX;
128
- const scrollable = content.scrollWidth - container.clientWidth;
129
- const ratio = scrollable / (container.clientWidth - this.thumbWidth);
130
- content.scrollLeft = Math.max(0, Math.min(scrollable, this.dragStartScrollLeft + deltaX * ratio));
131
- };
132
- const onUp = () => {
133
- this.isDraggingH = false;
134
- document.removeEventListener('mousemove', onMove);
135
- document.removeEventListener('mouseup', onUp);
136
- };
137
- document.addEventListener('mousemove', onMove);
138
- document.addEventListener('mouseup', onUp);
139
- }
140
-
141
- render() {
142
- const showThumb = this.thumbHeight > 0;
143
- const showThumbH = this.thumbWidth > 0;
144
- const isScrollable = showThumb || showThumbH;
145
- const showTrack = this.showTrackOnHover && (this.isPointerInside || this.isDragging || this.isDraggingH);
146
-
147
- return (
148
- <Host style={{ display: 'contents' }}>
149
- <div
150
- class={{
151
- 'scrollbar-container': true,
152
- 'scrollbar-container--thick': this.variant === 'thick',
153
- }}
154
- data-show-track={showTrack ? 'true' : 'false'}
155
- data-dragging={this.isDragging || this.isDraggingH}
156
- onMouseEnter={() => { if (this.showTrackOnHover) this.isPointerInside = true; }}
157
- onMouseLeave={() => { this.isPointerInside = false; }}
158
- >
159
- <div
160
- class="scrollbar-content"
161
- tabIndex={isScrollable ? 0 : undefined}
162
- >
163
- <slot />
164
- </div>
165
-
166
- {showThumb && (
167
- <div class="scrollbar-track" aria-hidden="true">
168
- <div
169
- class="scrollbar-thumb"
170
- style={{ height: `${this.thumbHeight}px`, top: `${this.thumbTop}px` }}
171
- onMouseDown={(e: MouseEvent) => this.handleThumbMouseDown(e)}
172
- />
173
- </div>
174
- )}
175
-
176
- {showThumbH && (
177
- <div class="scrollbar-track-h" aria-hidden="true">
178
- <div
179
- class="scrollbar-thumb-h"
180
- style={{ width: `${this.thumbWidth}px`, left: `${this.thumbLeft}px` }}
181
- onMouseDown={(e: MouseEvent) => this.handleThumbHMouseDown(e)}
182
- />
183
- </div>
184
- )}
185
- </div>
186
- </Host>
187
- );
188
- }
189
- }
@@ -1,81 +0,0 @@
1
- import { Component, Prop, h, Host } from '@stencil/core';
2
-
3
- export type SurfaceIntent =
4
- | 'brand' | 'positive' | 'negative' | 'warning' | 'caution'
5
- | 'ai' | 'neutral' | 'walkthrough' | 'guide';
6
- export type SurfaceBackground = 'primary' | 'secondary' | 'transparent' | 'translucent';
7
- export type SurfaceContrast = 'faint' | 'medium' | 'bold' | 'strong';
8
- export type SurfaceElevation =
9
- | 'none' | 'depressed' | 'depressed-md' | 'flat' | 'elevated' | 'floating'
10
- | 'overlayTop' | 'overlayRight' | 'overlayBottom' | 'overlayLeft';
11
- export type SurfaceEdge = 'top' | 'right' | 'bottom' | 'left';
12
- export type SurfaceRadius = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full' | (string & {});
13
- export type SurfaceElement = 'div' | 'section' | 'aside' | 'article' | 'header' | 'footer' | 'main' | 'nav' | 'span';
14
-
15
- const RADIUS_PRESETS = new Set(['none', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', 'full']);
16
-
17
- @Component({
18
- tag: 'ds-surface',
19
- styleUrl: 'Surface.css',
20
- scoped: true,
21
- })
22
- export class Surface {
23
- @Prop() background: SurfaceBackground = 'transparent';
24
- @Prop() intent: SurfaceIntent | undefined;
25
- @Prop() contrast: SurfaceContrast = 'faint';
26
- @Prop() elevation: SurfaceElevation = 'none';
27
- /** Space-separated list of edges: "top bottom" etc. Only applies when elevation='none'. */
28
- @Prop() edge: string | undefined;
29
- @Prop() radius: SurfaceRadius | undefined;
30
- @Prop() interactive: boolean = false;
31
- @Prop() selected: boolean = false;
32
- @Prop() inactive: boolean = false;
33
- @Prop() as: SurfaceElement = 'div';
34
-
35
- render() {
36
- // Polymorphic element: TSX treats a variable tag as a component, so a
37
- // dynamic intrinsic element name must be cast to `any` to render.
38
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
- const Tag = this.as as any;
40
-
41
- const intentClass = this.intent
42
- ? `intent-${this.intent}-${this.contrast}`
43
- : `bg-${this.background}`;
44
-
45
- const elevClass = `elevation-${this.elevation}`;
46
-
47
- const edgeClasses = this.edge && this.elevation === 'none'
48
- ? this.edge.trim().split(/\s+/).map(e => `edge-${e}`)
49
- : [];
50
-
51
- const radiusClass = this.radius && RADIUS_PRESETS.has(this.radius)
52
- ? `radius-${this.radius}`
53
- : '';
54
-
55
- const customRadius = this.radius && !RADIUS_PRESETS.has(this.radius)
56
- ? this.radius
57
- : undefined;
58
-
59
- const cls = [
60
- 'surface',
61
- intentClass,
62
- elevClass,
63
- ...edgeClasses,
64
- radiusClass,
65
- this.interactive ? 'interactive' : '',
66
- this.selected ? 'selected' : '',
67
- this.inactive ? 'inactive' : '',
68
- ].filter(Boolean).join(' ');
69
-
70
- return (
71
- <Host style={{ display: 'contents' }}>
72
- <Tag
73
- class={cls}
74
- style={customRadius ? { borderRadius: customRadius } : undefined}
75
- >
76
- <slot />
77
- </Tag>
78
- </Host>
79
- );
80
- }
81
- }
@@ -1,179 +0,0 @@
1
- import { Component, Prop, State, h, Host } from '@stencil/core';
2
- import { resolveCssTimeMs, TOKEN_DEFAULTS } from '../../utils';
3
- import { subscribeToToasts, getToasts, toast as toastService, type ToastData, type ToastIntent } from './toast-service';
4
-
5
- export type ToastPosition = 'top-center' | 'top-right' | 'bottom-center' | 'bottom-right';
6
-
7
- const INTENT_BG: Record<ToastIntent, string> = {
8
- neutral: 'var(--color-background-bold-neutral)',
9
- brand: 'var(--color-background-bold-brand)',
10
- positive: 'var(--color-background-bold-positive)',
11
- negative: 'var(--color-background-bold-negative)',
12
- warning: 'var(--color-background-bold-warning)',
13
- caution: 'var(--color-background-bold-caution)',
14
- };
15
-
16
- interface ToastItemState {
17
- data: ToastData;
18
- exiting: boolean;
19
- timer: ReturnType<typeof setTimeout> | null;
20
- remaining: number;
21
- startedAt: number;
22
- paused: boolean;
23
- }
24
-
25
- @Component({
26
- tag: 'ds-toast-provider',
27
- styleUrl: 'Toast.css',
28
- scoped: true,
29
- })
30
- export class ToastProvider {
31
- @Prop() position: ToastPosition = 'top-center';
32
-
33
- @State() private items: ToastItemState[] = [];
34
-
35
- private unsubscribe: (() => void) | null = null;
36
-
37
- private get fadeOutMs(): number {
38
- return resolveCssTimeMs(TOKEN_DEFAULTS.motionShort3, TOKEN_DEFAULTS.animationDurationShort3);
39
- }
40
-
41
- connectedCallback() {
42
- this.unsubscribe = subscribeToToasts(() => this.syncFromStore());
43
- this.syncFromStore();
44
- }
45
-
46
- disconnectedCallback() {
47
- this.items.forEach(item => { if (item.timer) clearTimeout(item.timer); });
48
- this.unsubscribe?.();
49
- }
50
-
51
- private syncFromStore() {
52
- const storeToasts = getToasts();
53
- const existingIds = new Set(this.items.map(i => i.data.id));
54
- const storeIds = new Set(storeToasts.map(t => t.id));
55
-
56
- // Remove items no longer in store (instant, no animation since dismiss() already fires animation)
57
- const kept = this.items.filter(i => storeIds.has(i.data.id));
58
-
59
- // Add new items
60
- const newItems: ToastItemState[] = storeToasts
61
- .filter(t => !existingIds.has(t.id))
62
- .map(data => {
63
- const state: ToastItemState = {
64
- data,
65
- exiting: false,
66
- timer: null,
67
- remaining: data.duration,
68
- startedAt: 0,
69
- paused: false,
70
- };
71
- if (data.duration > 0) {
72
- state.startedAt = Date.now();
73
- state.timer = setTimeout(() => this.dismissItem(data.id), data.duration);
74
- }
75
- return state;
76
- });
77
-
78
- this.items = [...kept, ...newItems];
79
- }
80
-
81
- private dismissItem(id: string) {
82
- this.items = this.items.map(i =>
83
- i.data.id === id ? { ...i, exiting: true, timer: null } : i
84
- );
85
- setTimeout(() => {
86
- this.items = this.items.filter(i => i.data.id !== id);
87
- toastService.dismiss(id);
88
- }, this.fadeOutMs);
89
- }
90
-
91
- private pauseItem(id: string) {
92
- this.items = this.items.map(i => {
93
- if (i.data.id !== id || i.paused || !i.timer) return i;
94
- clearTimeout(i.timer);
95
- const elapsed = Date.now() - i.startedAt;
96
- return { ...i, paused: true, timer: null, remaining: Math.max(0, i.remaining - elapsed) };
97
- });
98
- }
99
-
100
- private resumeItem(id: string) {
101
- this.items = this.items.map(i => {
102
- if (i.data.id !== id || !i.paused || i.remaining <= 0) return i;
103
- const timer = setTimeout(() => this.dismissItem(id), i.remaining);
104
- return { ...i, paused: false, timer, startedAt: Date.now() };
105
- });
106
- }
107
-
108
- private getPositionStyle(): Record<string, string> {
109
- const base: Record<string, string> = {
110
- position: 'fixed',
111
- zIndex: '9999',
112
- display: 'flex',
113
- flexDirection: 'column',
114
- gap: 'var(--dimension-space-075)',
115
- pointerEvents: 'none',
116
- padding: 'var(--dimension-space-100)',
117
- maxWidth: `var(${TOKEN_DEFAULTS.panelWidthMd})`,
118
- width: '100%',
119
- boxSizing: 'border-box',
120
- };
121
- switch (this.position) {
122
- case 'top-center':
123
- return { ...base, top: '0', left: '50%', transform: 'translateX(-50%)', alignItems: 'center' };
124
- case 'top-right':
125
- return { ...base, top: '0', right: '0', alignItems: 'flex-end' };
126
- case 'bottom-center':
127
- return { ...base, bottom: '0', left: '50%', transform: 'translateX(-50%)', alignItems: 'center' };
128
- case 'bottom-right':
129
- return { ...base, bottom: '0', right: '0', alignItems: 'flex-end' };
130
- }
131
- }
132
-
133
- render() {
134
- return (
135
- <Host style={{ display: 'contents' }}>
136
- <div
137
- class="toast-container"
138
- role="region"
139
- aria-label="Notifications"
140
- aria-live="polite"
141
- style={this.getPositionStyle()}
142
- >
143
- {this.items.map(item => (
144
- <div
145
- key={item.data.id}
146
- class={{ toast: true, 'toast--exit': item.exiting }}
147
- role={item.data.intent === 'negative' ? 'alert' : 'status'}
148
- style={{
149
- backgroundColor: INTENT_BG[item.data.intent],
150
- borderRadius: 'var(--dimension-radius-125)',
151
- boxShadow: 'var(--effect-elevation-elevated-floating)',
152
- display: 'flex',
153
- alignItems: 'center',
154
- gap: 'var(--dimension-space-075)',
155
- padding: 'var(--dimension-space-075) var(--dimension-space-100)',
156
- minHeight: 'var(--dimension-size-400)',
157
- pointerEvents: 'auto',
158
- color: 'var(--color-foreground-on-bold-background-primary)',
159
- boxSizing: 'border-box',
160
- }}
161
- onMouseEnter={() => this.pauseItem(item.data.id)}
162
- onMouseLeave={() => this.resumeItem(item.data.id)}
163
- >
164
- <span class="text-body-medium" style={{ flex: '1' }}>{item.data.message}</span>
165
- <button
166
- type="button"
167
- class="toast-dismiss"
168
- onClick={() => this.dismissItem(item.data.id)}
169
- aria-label="Dismiss"
170
- >
171
- &times;
172
- </button>
173
- </div>
174
- ))}
175
- </div>
176
- </Host>
177
- );
178
- }
179
- }
@@ -1,67 +0,0 @@
1
- import { resolveCssTimeMs, TOKEN_DEFAULTS } from '../../utils';
2
-
3
- export type ToastIntent = 'neutral' | 'brand' | 'positive' | 'negative' | 'warning' | 'caution';
4
-
5
- export interface ToastData {
6
- id: string;
7
- message: string;
8
- intent: ToastIntent;
9
- duration: number;
10
- }
11
-
12
- export interface ToastOptions {
13
- message: string;
14
- intent?: ToastIntent;
15
- duration?: number;
16
- }
17
-
18
- let toasts: ToastData[] = [];
19
- const listeners = new Set<() => void>();
20
- let idCounter = 0;
21
-
22
- function emit() {
23
- listeners.forEach(fn => fn());
24
- }
25
-
26
- export function subscribeToToasts(fn: () => void): () => void {
27
- listeners.add(fn);
28
- return () => listeners.delete(fn);
29
- }
30
-
31
- export function getToasts(): ToastData[] {
32
- return toasts;
33
- }
34
-
35
- function defaultToastDurationMs(): number {
36
- return resolveCssTimeMs(TOKEN_DEFAULTS.animationDelayLong2, TOKEN_DEFAULTS.animationDelayLong2);
37
- }
38
-
39
- export const toast = {
40
- show(options: ToastOptions): string {
41
- const id = `ds-toast-${++idCounter}`;
42
- const duration = options.duration ?? defaultToastDurationMs();
43
- toasts = [...toasts, { id, intent: 'neutral', ...options, duration }];
44
- emit();
45
- return id;
46
- },
47
- success(message: string, options?: Partial<ToastOptions>): string {
48
- return toast.show({ message, intent: 'positive', ...options });
49
- },
50
- error(message: string, options?: Partial<ToastOptions>): string {
51
- return toast.show({ message, intent: 'negative', ...options });
52
- },
53
- warning(message: string, options?: Partial<ToastOptions>): string {
54
- return toast.show({ message, intent: 'warning', ...options });
55
- },
56
- info(message: string, options?: Partial<ToastOptions>): string {
57
- return toast.show({ message, intent: 'neutral', ...options });
58
- },
59
- dismiss(id: string) {
60
- toasts = toasts.filter(t => t.id !== id);
61
- emit();
62
- },
63
- dismissAll() {
64
- toasts = [];
65
- emit();
66
- },
67
- };