@ethlete/components 1.0.0-next.77 → 1.0.0-next.79

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 (318) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/design/accordion.ts +73 -0
  3. package/design/avatar.ts +90 -0
  4. package/design/badge.ts +48 -0
  5. package/design/banner.ts +77 -0
  6. package/design/bracket.ts +457 -0
  7. package/design/breadcrumb.ts +145 -0
  8. package/design/button.ts +49 -0
  9. package/design/calendar.ts +306 -0
  10. package/design/card.ts +92 -0
  11. package/design/carousel.ts +240 -0
  12. package/design/chart.ts +512 -0
  13. package/design/checkbox.ts +275 -0
  14. package/design/chip.ts +64 -0
  15. package/design/config.json +22 -0
  16. package/design/control.ts +19 -0
  17. package/design/copy-button.ts +59 -0
  18. package/design/description-list.ts +41 -0
  19. package/design/dialog.ts +214 -0
  20. package/design/divider.ts +27 -0
  21. package/design/empty-state.ts +45 -0
  22. package/design/floating-action.ts +55 -0
  23. package/design/form-field.ts +40 -1
  24. package/design/grid.ts +148 -0
  25. package/design/icon-set.ts +19 -0
  26. package/design/icon.ts +9 -0
  27. package/design/input.ts +86 -0
  28. package/design/kbd.ts +19 -0
  29. package/design/loader.ts +152 -0
  30. package/design/masonry.ts +115 -0
  31. package/design/match.ts +131 -0
  32. package/design/menu.ts +143 -0
  33. package/design/notification.ts +129 -0
  34. package/design/otp-input.ts +107 -0
  35. package/design/pagination.ts +120 -0
  36. package/design/picture.ts +80 -0
  37. package/design/progress-steps.ts +79 -0
  38. package/design/query-error.ts +60 -0
  39. package/design/radio-group.ts +132 -0
  40. package/design/scheduler.ts +369 -0
  41. package/design/scrollable.ts +218 -0
  42. package/design/scrollbar.ts +47 -0
  43. package/design/sdk/assets/fallback.svg +1 -0
  44. package/design/sdk/assets/tall.svg +1 -0
  45. package/design/sdk/assets/wide.svg +1 -0
  46. package/design/sdk/components/accent-on-light/accent-on-light.css +35 -0
  47. package/design/sdk/components/accent-on-light/accent-on-light.ts +10 -0
  48. package/design/sdk/components/accent-on-light/shared/controls.ts +46 -0
  49. package/design/sdk/components/accordion/accordion.css +17 -0
  50. package/design/sdk/components/accordion/accordion.ts +64 -0
  51. package/design/sdk/components/avatar/avatar.css +14 -0
  52. package/design/sdk/components/avatar/avatar.ts +78 -0
  53. package/design/sdk/components/badge/badge.css +13 -0
  54. package/design/sdk/components/badge/badge.ts +52 -0
  55. package/design/sdk/components/banner/banner.css +18 -0
  56. package/design/sdk/components/banner/banner.ts +87 -0
  57. package/design/sdk/components/bracket/bracket.css +59 -0
  58. package/design/sdk/components/bracket/bracket.ts +143 -0
  59. package/design/sdk/components/breadcrumb/breadcrumb.css +25 -0
  60. package/design/sdk/components/breadcrumb/breadcrumb.ts +81 -0
  61. package/design/sdk/components/button/button.css +33 -0
  62. package/design/sdk/components/button/button.ts +82 -0
  63. package/design/sdk/components/calendar/calendar.css +33 -0
  64. package/design/sdk/components/calendar/calendar.ts +96 -0
  65. package/design/sdk/components/card/card.css +19 -0
  66. package/design/sdk/components/card/card.ts +61 -0
  67. package/design/sdk/components/carousel/carousel.css +44 -0
  68. package/design/sdk/components/carousel/carousel.ts +74 -0
  69. package/design/sdk/components/chart/chart.css +56 -0
  70. package/design/sdk/components/chart/chart.ts +98 -0
  71. package/design/sdk/components/chip/chip.css +18 -0
  72. package/design/sdk/components/chip/chip.ts +76 -0
  73. package/design/sdk/components/copy-button/copy-button.css +14 -0
  74. package/design/sdk/components/copy-button/copy-button.ts +59 -0
  75. package/design/sdk/components/description-list/description-list.css +7 -0
  76. package/design/sdk/components/description-list/description-list.ts +53 -0
  77. package/design/sdk/components/dialog/dialog.css +29 -0
  78. package/design/sdk/components/dialog/dialog.ts +78 -0
  79. package/design/sdk/components/divider/divider.css +26 -0
  80. package/design/sdk/components/divider/divider.ts +43 -0
  81. package/design/sdk/components/empty-state/empty-state.css +15 -0
  82. package/design/sdk/components/empty-state/empty-state.ts +56 -0
  83. package/design/sdk/components/floating-action/floating-action.css +51 -0
  84. package/design/sdk/components/floating-action/floating-action.ts +63 -0
  85. package/design/sdk/components/form-field/form-field.ts +118 -0
  86. package/design/sdk/components/grid/grid.css +17 -0
  87. package/design/sdk/components/grid/grid.ts +80 -0
  88. package/design/sdk/components/input/input.css +75 -0
  89. package/design/sdk/components/input/input.ts +79 -0
  90. package/design/sdk/components/kbd/kbd.css +25 -0
  91. package/design/sdk/components/kbd/kbd.ts +57 -0
  92. package/design/sdk/components/loader/loader.css +37 -0
  93. package/design/sdk/components/loader/loader.ts +68 -0
  94. package/design/sdk/components/masonry/masonry.css +7 -0
  95. package/design/sdk/components/masonry/masonry.ts +42 -0
  96. package/design/sdk/components/match/match.css +25 -0
  97. package/design/sdk/components/match/match.ts +76 -0
  98. package/design/sdk/components/menu/menu.css +22 -0
  99. package/design/sdk/components/menu/menu.ts +91 -0
  100. package/design/sdk/components/notification/notification.css +32 -0
  101. package/design/sdk/components/notification/notification.ts +106 -0
  102. package/design/sdk/components/otp-input/otp-input.css +35 -0
  103. package/design/sdk/components/otp-input/otp-input.ts +64 -0
  104. package/design/sdk/components/pagination/pagination.css +14 -0
  105. package/design/sdk/components/pagination/pagination.ts +75 -0
  106. package/design/sdk/components/picture/picture.css +37 -0
  107. package/design/sdk/components/picture/picture.ts +96 -0
  108. package/design/sdk/components/progress-steps/progress-steps.css +37 -0
  109. package/design/sdk/components/progress-steps/progress-steps.ts +91 -0
  110. package/design/sdk/components/query-error/query-error.css +33 -0
  111. package/design/sdk/components/query-error/query-error.ts +120 -0
  112. package/design/sdk/components/scheduler/scheduler.css +55 -0
  113. package/design/sdk/components/scheduler/scheduler.ts +239 -0
  114. package/design/sdk/components/scrollable/scrollable.css +58 -0
  115. package/design/sdk/components/scrollable/scrollable.ts +133 -0
  116. package/design/sdk/components/scrollbar/scrollbar.css +78 -0
  117. package/design/sdk/components/scrollbar/scrollbar.ts +123 -0
  118. package/design/sdk/components/select/select.css +5 -0
  119. package/design/sdk/components/select/select.ts +16 -0
  120. package/design/sdk/components/select/shared/select-part.ts +75 -0
  121. package/design/sdk/components/select-panel/select-panel.css +3 -0
  122. package/design/sdk/components/select-panel/select-panel.ts +124 -0
  123. package/design/sdk/components/skeleton/skeleton.css +22 -0
  124. package/design/sdk/components/skeleton/skeleton.ts +50 -0
  125. package/design/sdk/components/slider/slider.css +52 -0
  126. package/design/sdk/components/slider/slider.ts +86 -0
  127. package/design/sdk/components/standings/standings.css +33 -0
  128. package/design/sdk/components/standings/standings.ts +130 -0
  129. package/design/sdk/components/stat-tile/stat-tile.css +15 -0
  130. package/design/sdk/components/stat-tile/stat-tile.ts +84 -0
  131. package/design/sdk/components/stream/stream.css +48 -0
  132. package/design/sdk/components/stream/stream.ts +38 -0
  133. package/design/sdk/components/switch/switch.css +35 -0
  134. package/design/sdk/components/switch/switch.ts +63 -0
  135. package/design/sdk/components/table/table.css +67 -0
  136. package/design/sdk/components/table/table.ts +160 -0
  137. package/design/sdk/components/tabs/tabs.css +13 -0
  138. package/design/sdk/components/tabs/tabs.ts +74 -0
  139. package/design/sdk/components/textarea/textarea.css +116 -0
  140. package/design/sdk/components/textarea/textarea.ts +64 -0
  141. package/design/sdk/components/timeline/timeline.css +30 -0
  142. package/design/sdk/components/timeline/timeline.ts +87 -0
  143. package/design/sdk/components/toolbar/toolbar.css +24 -0
  144. package/design/sdk/components/toolbar/toolbar.ts +87 -0
  145. package/design/sdk/components/tooltip/tooltip.css +15 -0
  146. package/design/sdk/components/tooltip/tooltip.ts +28 -0
  147. package/design/sdk/components/tree/selected-tint.css +15 -0
  148. package/design/sdk/components/tree/tree.ts +70 -0
  149. package/design/sdk/fixtures.ts +0 -0
  150. package/design/sdk/foundations/colors/colors.css +632 -0
  151. package/design/sdk/foundations/colors/colors.ts +188 -0
  152. package/design/sdk/foundations/colors/overrides.json +19 -0
  153. package/design/sdk/foundations/colors/shared/contrast.ts +120 -0
  154. package/design/sdk/foundations/elevation/elevation.css +6 -0
  155. package/design/sdk/foundations/elevation/elevation.ts +11 -0
  156. package/design/sdk/foundations/elevation/shared/elevation/scene.css +101 -0
  157. package/design/sdk/foundations/elevation/shared/elevation/scene.ts +74 -0
  158. package/design/sdk/foundations/icons/icons.ts +119 -0
  159. package/design/select.ts +113 -28
  160. package/design/skeleton.ts +67 -0
  161. package/design/slider.ts +155 -0
  162. package/design/standings.ts +161 -0
  163. package/design/stat-tile.ts +109 -0
  164. package/design/stream.ts +92 -0
  165. package/design/switch.ts +83 -0
  166. package/design/table.ts +302 -0
  167. package/design/tabs.ts +75 -0
  168. package/design/textarea.ts +92 -0
  169. package/design/timeline.ts +52 -0
  170. package/design/toolbar.ts +95 -0
  171. package/design/tooltip.ts +87 -0
  172. package/design/tree.ts +106 -0
  173. package/fesm2022/ethlete-components.mjs +240 -199
  174. package/fesm2022/ethlete-components.mjs.map +1 -1
  175. package/package.json +1 -1
  176. package/src/lib/accordion/accordion.component.css +2 -1
  177. package/src/lib/avatar/avatar.component.css +10 -0
  178. package/src/lib/badge/badge.component.css +2 -2
  179. package/src/lib/banner/banner.component.css +3 -1
  180. package/src/lib/breadcrumb/breadcrumb-outlet.component.css +5 -0
  181. package/src/lib/breadcrumb/breadcrumb.component.css +5 -1
  182. package/src/lib/button/button.component.css +19 -0
  183. package/src/lib/button/icon-button.component.css +19 -20
  184. package/src/lib/button/split-button.component.css +5 -1
  185. package/src/lib/calendar/calendar.component.css +13 -3
  186. package/src/lib/card/card.component.css +4 -0
  187. package/src/lib/carousel/carousel-autoplay-styles.component.css +1 -1
  188. package/src/lib/carousel/carousel.component.css +2 -2
  189. package/src/lib/chart/chart-axis.component.css +3 -3
  190. package/src/lib/chip/chip.component.css +8 -2
  191. package/src/lib/description-list/description-list.component.css +2 -1
  192. package/src/lib/empty-state/empty-state.component.css +4 -0
  193. package/src/lib/floating-action/floating-action-styles.component.css +27 -0
  194. package/src/lib/focus-ring/focus-ring-styles.component.css +4 -1
  195. package/src/lib/forms/checkbox/checkbox.component.css +31 -5
  196. package/src/lib/forms/color-input/color-input.component.css +3 -1
  197. package/src/lib/forms/color-input/color-picker-panel.component.css +6 -2
  198. package/src/lib/forms/date-time/date-input/date-input.component.css +1 -1
  199. package/src/lib/forms/date-time/date-time-input/date-time-input.component.css +1 -1
  200. package/src/lib/forms/date-time/duration-input/duration-input.component.css +1 -1
  201. package/src/lib/forms/date-time/range-input-shell-styles.component.css +1 -1
  202. package/src/lib/forms/date-time/time-input/time-input.component.css +1 -1
  203. package/src/lib/forms/description/description.component.css +7 -0
  204. package/src/lib/forms/dropzone/dropzone.component.css +26 -0
  205. package/src/lib/forms/form-field/form-field-control-suffix-styles.component.css +4 -2
  206. package/src/lib/forms/form-field/form-field-text-shell-styles.component.css +74 -17
  207. package/src/lib/forms/form-field/form-field-textarea-styles.component.css +62 -0
  208. package/src/lib/forms/form-field/form-field.component.css +6 -0
  209. package/src/lib/forms/form-field/headless/label.directive.css +1 -1
  210. package/src/lib/forms/input/input.component.css +6 -2
  211. package/src/lib/forms/input/number-input.component.css +2 -2
  212. package/src/lib/forms/input/password-input.component.css +4 -3
  213. package/src/lib/forms/otp-input/otp-input.component.css +23 -4
  214. package/src/lib/forms/phone-input/phone-input.component.css +4 -3
  215. package/src/lib/forms/rating/rating.component.css +2 -1
  216. package/src/lib/forms/rich-text-editor/rich-text-editor.component.css +1 -1
  217. package/src/lib/forms/select/select-option-styles.component.css +3 -2
  218. package/src/lib/forms/selection-card-styles.component.css +3 -2
  219. package/src/lib/forms/selection-list/checkbox-group/checkbox-group-select-all.component.css +4 -2
  220. package/src/lib/forms/selection-list/checkbox-group/checkbox-option.component.css +4 -2
  221. package/src/lib/forms/selection-list/radio-group/radio.component.css +5 -2
  222. package/src/lib/forms/selection-list/segmented-button-group/segmented-button.component.css +2 -1
  223. package/src/lib/forms/slider/range-slider.component.css +98 -6
  224. package/src/lib/forms/slider/slider.component.css +96 -4
  225. package/src/lib/forms/switch/switch.component.css +47 -4
  226. package/src/lib/forms/tag-input/tag-input.component.css +2 -2
  227. package/src/lib/forms/textarea/textarea-autosize-styles.component.css +2 -3
  228. package/src/lib/forms/textarea/textarea.component.css +7 -2
  229. package/src/lib/grid/grid-item-toolbar.component.css +10 -0
  230. package/src/lib/grid/grid-item.component.css +6 -1
  231. package/src/lib/icon/headless/align-icons.ts +30 -0
  232. package/src/lib/icon/headless/arrow-out-up-right-icon.ts +17 -0
  233. package/src/lib/icon/headless/arrow-right-icon.ts +23 -0
  234. package/src/lib/icon/headless/arrow-up-icon.ts +30 -0
  235. package/src/lib/icon/headless/arrows-left-right-icon.ts +31 -0
  236. package/src/lib/icon/headless/bold-icon.ts +11 -0
  237. package/src/lib/icon/headless/calendar-icon.ts +21 -0
  238. package/src/lib/icon/headless/check-icon.ts +14 -0
  239. package/src/lib/icon/headless/chevron-icon.ts +14 -0
  240. package/src/lib/icon/headless/circle-check-icon.ts +14 -0
  241. package/src/lib/icon/headless/circle-info-icon.ts +14 -0
  242. package/src/lib/icon/headless/clipboard-check-icon.ts +28 -0
  243. package/src/lib/icon/headless/clock-icon.ts +21 -0
  244. package/src/lib/icon/headless/code-block-icon.ts +15 -0
  245. package/src/lib/icon/headless/code-icon.ts +14 -0
  246. package/src/lib/icon/headless/ellipsis-icon.ts +13 -0
  247. package/src/lib/icon/headless/ellipsis-vertical-icon.ts +13 -0
  248. package/src/lib/icon/headless/eye-icons.ts +27 -0
  249. package/src/lib/icon/headless/eyedropper-icon.ts +22 -0
  250. package/src/lib/icon/headless/file-icon.ts +16 -0
  251. package/src/lib/icon/headless/filter-icon.ts +11 -0
  252. package/src/lib/icon/headless/floppy-disk-icon.ts +27 -0
  253. package/src/lib/icon/headless/focus-frame-icon.ts +16 -0
  254. package/src/lib/icon/headless/grid-2x2-icon.ts +17 -0
  255. package/src/lib/icon/headless/heading-1-icon.ts +11 -0
  256. package/src/lib/icon/headless/heading-2-icon.ts +11 -0
  257. package/src/lib/icon/headless/heading-3-icon.ts +11 -0
  258. package/src/lib/icon/headless/icon-definition.ts +14 -0
  259. package/src/lib/icon/headless/image-icon.ts +14 -0
  260. package/src/lib/icon/headless/italic-icon.ts +19 -0
  261. package/src/lib/icon/headless/link-icon.ts +17 -0
  262. package/src/lib/icon/headless/list-bulleted-icon.ts +14 -0
  263. package/src/lib/icon/headless/list-numbered-icon.ts +14 -0
  264. package/src/lib/icon/headless/location-icon.ts +21 -0
  265. package/src/lib/icon/headless/lock-icon.ts +14 -0
  266. package/src/lib/icon/headless/minus-icon.ts +14 -0
  267. package/src/lib/icon/headless/paragraph-icon.ts +11 -0
  268. package/src/lib/icon/headless/pause-icon.ts +11 -0
  269. package/src/lib/icon/headless/pencil-icon.ts +21 -0
  270. package/src/lib/icon/headless/play-icon.ts +10 -0
  271. package/src/lib/icon/headless/plus-icon.ts +21 -0
  272. package/src/lib/icon/headless/quote-icon.ts +15 -0
  273. package/src/lib/icon/headless/rotate-right-icon.ts +16 -0
  274. package/src/lib/icon/headless/star-icon.ts +14 -0
  275. package/src/lib/icon/headless/strikethrough-icon.ts +18 -0
  276. package/src/lib/icon/headless/table-icon.ts +15 -0
  277. package/src/lib/icon/headless/thumbtack-icon.ts +18 -0
  278. package/src/lib/icon/headless/times-icon.ts +14 -0
  279. package/src/lib/icon/headless/trash-icon.ts +24 -0
  280. package/src/lib/icon/headless/triangle-exclamation-icon.ts +14 -0
  281. package/src/lib/icon/headless/trophy-icon.ts +24 -0
  282. package/src/lib/icon/headless/underline-icon.ts +12 -0
  283. package/src/lib/icon/headless/undo-redo-icons.ts +24 -0
  284. package/src/lib/icon/headless/upload-icon.ts +16 -0
  285. package/src/lib/loader/brand-loader/brand-loader.component.css +4 -1
  286. package/src/lib/loader/progress-bar/progress-bar.component.css +1 -1
  287. package/src/lib/loader/spinner/spinner-styles.component.css +1 -1
  288. package/src/lib/match/match-card.component.css +9 -3
  289. package/src/lib/match/match-score.component.css +4 -1
  290. package/src/lib/menu/menu-selection-item.component.css +1 -1
  291. package/src/lib/menu/menu.component.css +5 -0
  292. package/src/lib/overlay/overlay-container.component.css +4 -0
  293. package/src/lib/pagination/pagination.component.css +4 -0
  294. package/src/lib/progress-steps/progress-step.component.css +4 -4
  295. package/src/lib/query-error/query-error.component.css +4 -0
  296. package/src/lib/scheduler/scheduler-appointment-styles.component.css +21 -5
  297. package/src/lib/scheduler/scheduler-month-view.component.css +4 -2
  298. package/src/lib/scheduler/scheduler-time-grid-view.component.css +8 -2
  299. package/src/lib/scrollable/headless/scrollable-navigation.component.css +1 -1
  300. package/src/lib/standings/standings-pick.component.css +1 -1
  301. package/src/lib/standings/standings.component.css +10 -10
  302. package/src/lib/stat-tile/stat-tile-sparkline.component.css +1 -1
  303. package/src/lib/stream/consent/stream-consent.component.css +99 -0
  304. package/src/lib/stream/error/stream-player-error.component.css +100 -0
  305. package/src/lib/stream/loading/stream-player-loading.component.css +16 -0
  306. package/src/lib/stream/pip/pip-slot-placeholder.component.css +68 -0
  307. package/src/lib/stream/stream-player-slot-styles.component.css +4 -0
  308. package/src/lib/table/table-resize-grip.component.css +2 -1
  309. package/src/lib/table/table-select-cell.component.css +45 -15
  310. package/src/lib/table/table.component.css +15 -5
  311. package/src/lib/tabs/tab-bar-styles.component.css +1 -1
  312. package/src/lib/tabs/tabs/tab-group.component.css +111 -0
  313. package/src/lib/time-picker/time-picker.component.css +2 -1
  314. package/src/lib/timeline/timeline-item.component.css +5 -1
  315. package/src/lib/toolbar/toolbar.component.css +4 -0
  316. package/src/lib/tooltip/tooltip.component.css +14 -0
  317. package/src/lib/tree/tree.component.css +2 -2
  318. package/types/ethlete-components.d.ts +62 -53
@@ -0,0 +1,84 @@
1
+ import { card, cardStyles } from '@ethlete/components/design/card';
2
+ import { statTile, StatTileMockOptions, statTileStyles } from '@ethlete/components/design/stat-tile';
3
+ import { definePart, drawing } from '@design-system';
4
+ import frame from './stat-tile.css?inline';
5
+
6
+ type Form =
7
+ | 'up-good'
8
+ | 'up-bad'
9
+ | 'down-good'
10
+ | 'down-unrated'
11
+ | 'unchanged'
12
+ | 'unit'
13
+ | 'no-value'
14
+ | 'without-sparkline'
15
+ | 'loading';
16
+
17
+ type Props = { form: Form };
18
+
19
+ const WEEKLY_USERS = [182, 176, 190, 201, 195, 210, 224, 218, 231, 240, 236, 252];
20
+ const LATENCY = [180, 185, 178, 190, 196, 188, 201, 199, 205, 210, 204, 212];
21
+
22
+ const DEFAULT: StatTileMockOptions = {
23
+ label: 'Weekly active users',
24
+ value: '25.2K',
25
+ delta: { text: '+6.8%', direction: 'up', sentiment: 'good' },
26
+ caption: 'vs last week',
27
+ sparkline: WEEKLY_USERS,
28
+ };
29
+
30
+ const FORMS: Record<Form, StatTileMockOptions> = {
31
+ 'up-good': DEFAULT,
32
+ 'up-bad': {
33
+ label: 'p95 latency',
34
+ value: '212',
35
+ unit: 'ms',
36
+ delta: { text: '+18', direction: 'up', sentiment: 'bad', color: 'danger' },
37
+ caption: 'vs last month',
38
+ sparkline: LATENCY,
39
+ },
40
+ 'down-good': {
41
+ label: 'Churn rate',
42
+ value: '3.4%',
43
+ delta: { text: '-2.1%', direction: 'down', sentiment: 'good' },
44
+ caption: 'vs last month',
45
+ },
46
+ 'down-unrated': {
47
+ label: 'Page views',
48
+ value: '12.9K',
49
+ delta: { text: '-310', direction: 'down' },
50
+ caption: 'vs last month',
51
+ },
52
+ unchanged: {
53
+ label: 'Open tickets',
54
+ value: '1,284',
55
+ delta: { text: '0', direction: 'neutral' },
56
+ caption: 'vs last month',
57
+ },
58
+ unit: { label: 'p95 latency', value: '212', unit: 'ms', caption: 'last 24 hours', sparkline: LATENCY },
59
+ 'no-value': { label: 'Weekly active users', value: null, caption: 'vs last week' },
60
+ 'without-sparkline': { ...DEFAULT, sparkline: undefined },
61
+ loading: { ...DEFAULT, loading: true },
62
+ };
63
+
64
+ export default definePart({
65
+ note: 'Decided rules only',
66
+ madeBy: ['claude-opus-5-5'],
67
+ states: {
68
+ default: { form: 'up-good' },
69
+ 'up-bad': { form: 'up-bad' },
70
+ 'down-good': { form: 'down-good' },
71
+ 'down-unrated': { form: 'down-unrated' },
72
+ unchanged: { form: 'unchanged' },
73
+ unit: { form: 'unit' },
74
+ 'no-value': { form: 'no-value' },
75
+ 'without-sparkline': { form: 'without-sparkline' },
76
+ loading: { form: 'loading' },
77
+ },
78
+ widths: [480],
79
+ render: ({ form }: Props) =>
80
+ drawing({
81
+ body: `<div class="stat-tile-frame">${card({ content: statTile(FORMS[form]) })}</div>`,
82
+ styles: [cardStyles, statTileStyles, frame].join('\n'),
83
+ }),
84
+ });
@@ -0,0 +1,48 @@
1
+ .t-frame {
2
+ box-sizing: border-box;
3
+ padding: 1.6rem;
4
+ background: var(--et-surface-background-solid);
5
+ color: var(--et-surface-color-solid);
6
+ font-size: 1.4rem;
7
+ }
8
+
9
+ .t-frame .et-stream-player-slot {
10
+ inline-size: 100%;
11
+ aspect-ratio: 16 / 9;
12
+ }
13
+
14
+ .t-video {
15
+ position: absolute;
16
+ inset: 0;
17
+ display: grid;
18
+ place-items: center;
19
+ background: color-mix(in srgb, var(--et-surface-color-solid) 14%, var(--et-surface-background-solid));
20
+ }
21
+
22
+ .t-video::after {
23
+ content: '';
24
+ inline-size: 0;
25
+ block-size: 0;
26
+ border-block: 1.4rem solid transparent;
27
+ border-inline-start: 2.4rem solid var(--et-surface-color-muted-solid);
28
+ }
29
+
30
+ @layer components {
31
+ .et-stream-player-loading .et-spinner {
32
+ --et-spinner-color: light-dark(var(--et-theme-color-ink-solid), var(--et-theme-color-primary-solid));
33
+ }
34
+
35
+ .et-button {
36
+ --_et-focus-ring-color: var(--et-theme-color-ink-solid);
37
+ }
38
+
39
+ .et-button:where([data-variant='filled']) {
40
+ --et-button-shadow: inset 0 0 0 1px var(--et-theme-color-ink-solid);
41
+
42
+ @media (hover: hover) {
43
+ &:hover {
44
+ --et-theme-color-primary-rgb: var(--et-color-primary-active);
45
+ }
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,38 @@
1
+ import { streamPlayerSlot, StreamMockState, streamStyles } from '@ethlete/components/design/stream';
2
+ import { definePart, drawing } from '@design-system';
3
+ import frame from './stream.css?inline';
4
+
5
+ type Interaction = 'hover' | 'active' | 'focus-visible';
6
+
7
+ type Props = { state: StreamMockState; button?: Interaction };
8
+
9
+ const VIDEO = '<div class="t-video" aria-hidden="true"></div>';
10
+
11
+ const buttonAttributes = (interaction: Interaction | undefined) =>
12
+ ['data-et-control="action" data-can-animate', interaction && `data-et-force="${interaction}"`]
13
+ .filter(Boolean)
14
+ .join(' ');
15
+
16
+ export default definePart({
17
+ note: 'Decided rules only',
18
+ madeBy: ['claude-opus-5-5'],
19
+ states: {
20
+ player: { state: 'player' },
21
+ consent: { state: 'consent' },
22
+ loading: { state: 'loading' },
23
+ error: { state: 'error' },
24
+ 'pip-placeholder': { state: 'pip-placeholder' },
25
+ 'consent-hover': { state: 'consent', button: 'hover' },
26
+ 'consent-active': { state: 'consent', button: 'active' },
27
+ 'consent-focus-visible': { state: 'consent', button: 'focus-visible' },
28
+ },
29
+ widths: [320, 480, 720],
30
+ controls: {
31
+ action: { kind: 'button', input: ['pointer', 'keyboard'] },
32
+ },
33
+ render: (props: Props) =>
34
+ drawing({
35
+ body: `<div class="t-frame">${streamPlayerSlot({ state: props.state, player: VIDEO, buttonAttributes: buttonAttributes(props.button) }).replace('<et-spinner ', '<et-spinner data-et-skip="CLIPPED" ')}</div>`,
36
+ styles: [streamStyles, frame].join('\n'),
37
+ }),
38
+ });
@@ -0,0 +1,35 @@
1
+ @layer components {
2
+ et-switch:not([aria-checked='true']):not([data-indeterminate]) .et-switch-track {
3
+ box-shadow: inset 0 0 0 1px var(--et-surface-interaction-solid);
4
+ }
5
+
6
+ @media (hover: hover) {
7
+ et-switch:hover:not([aria-disabled='true']):not([data-readonly]):not([aria-checked='true']):not(
8
+ [data-indeterminate]
9
+ ),
10
+ :where(et-choice-field:has(.et-choice-field-label-area:hover))
11
+ et-switch:not([aria-disabled='true']):not([data-readonly]):not([aria-checked='true']):not([data-indeterminate]) {
12
+ .et-switch-track {
13
+ box-shadow: inset 0 0 0 1px var(--et-surface-interaction-hover-solid);
14
+ }
15
+ }
16
+ }
17
+
18
+ et-switch:focus-visible .et-switch-track {
19
+ outline-color: light-dark(var(--et-theme-color-ink-solid), var(--et-theme-color-primary-solid));
20
+ }
21
+
22
+ et-switch[aria-checked='true'] .et-switch-track {
23
+ box-shadow: inset 0 0 0 1px var(--et-theme-color-ink-solid);
24
+ }
25
+
26
+ et-switch[data-indeterminate] {
27
+ .et-switch-track::before {
28
+ border-color: var(--et-theme-color-ink-solid);
29
+ }
30
+
31
+ .et-switch-thumb {
32
+ background-color: var(--et-theme-color-ink-solid);
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,63 @@
1
+ import { switchControl, type SwitchMockOptions, switchStyles } from '@ethlete/components/design/switch';
2
+ import { definePart, drawing } from '@design-system';
3
+ import offTrack from './switch.css?inline';
4
+
5
+ type Interaction = 'hover' | 'focus-visible' | 'active';
6
+
7
+ type Props = SwitchMockOptions & { interaction?: Interaction };
8
+
9
+ const ROWS = {
10
+ off: {},
11
+ on: { checked: true },
12
+ indeterminate: { indeterminate: true },
13
+ } satisfies Record<string, Props>;
14
+
15
+ const INTERACTIONS = ['hover', 'focus-visible', 'active'] as const;
16
+
17
+ type Row = keyof typeof ROWS;
18
+
19
+ const rowStates = Object.fromEntries(
20
+ Object.entries(ROWS).flatMap(([row, props]) => [
21
+ [row, props],
22
+ ...INTERACTIONS.map((interaction) => [`${row}-${interaction}`, { ...props, interaction }]),
23
+ [`${row}-disabled`, { ...props, disabled: true }],
24
+ ]),
25
+ ) as Record<Row | `${Row}-${Interaction | 'disabled'}`, Props>;
26
+
27
+ const columns = ['rest', ...INTERACTIONS, 'disabled'] as const;
28
+
29
+ export default definePart({
30
+ note: 'The SDK switch, drawn by its mock from @ethlete/components/design: alone off, on and indeterminate in every interaction, and inside an et-choice-field with a label in each size and as a card. The label area skips CLIPPED: its 1.2 line height rounds the 12 and 16 px line box down by under a pixel, with no glyph cut.',
31
+ madeBy: ['claude-opus-5-5'],
32
+ states: {
33
+ ...rowStates,
34
+ 'label-sm': { label: 'Email me updates', size: 'sm', checked: true },
35
+ 'label-md': { label: 'Email me updates', size: 'md', checked: true },
36
+ 'label-lg': { label: 'Email me updates', size: 'lg', checked: true },
37
+ 'card-off': { label: 'Weekly digest', variant: 'card' },
38
+ 'card-on': { label: 'Weekly digest', variant: 'card', checked: true },
39
+ },
40
+ grid: {
41
+ columns,
42
+ rows: Object.fromEntries(
43
+ Object.keys(ROWS).map((row) => [
44
+ row,
45
+ Object.fromEntries(columns.map((column) => [column, column === 'rest' ? row : `${row}-${column}`])),
46
+ ]),
47
+ ) as Record<Row, Record<(typeof columns)[number], keyof typeof rowStates>>,
48
+ },
49
+ controls: {
50
+ switch: { kind: 'button', input: ['pointer', 'keyboard'], disabled: true },
51
+ },
52
+ render: ({ interaction, ...options }: Props) =>
53
+ drawing({
54
+ body: switchControl({
55
+ ...options,
56
+ color: 'brand',
57
+ attributes: ['data-et-control="switch"', interaction && `data-et-force="${interaction}"`]
58
+ .filter(Boolean)
59
+ .join(' '),
60
+ }).replace('class="et-choice-field-label-area', 'data-et-skip="CLIPPED" class="et-choice-field-label-area'),
61
+ styles: [switchStyles, offTrack].join('\n'),
62
+ }),
63
+ });
@@ -0,0 +1,67 @@
1
+ .t-frame {
2
+ box-sizing: border-box;
3
+ padding: 1.6rem;
4
+ background: var(--et-surface-background-solid);
5
+ color: var(--et-surface-color-solid);
6
+ font-size: 1.4rem;
7
+
8
+ .t-detail {
9
+ display: flex;
10
+ flex-wrap: wrap;
11
+ gap: 0.4rem 1.6rem;
12
+ color: var(--et-surface-color-muted-solid);
13
+ }
14
+
15
+ .et-table-host[data-scrolled] {
16
+ scroll-snap-type: x mandatory;
17
+ scroll-padding-inline-start: 140px;
18
+
19
+ .et-table-header-cell:nth-child(3) {
20
+ scroll-snap-align: start;
21
+ }
22
+ }
23
+ }
24
+
25
+ @layer components {
26
+ .et-table-header-label:focus-visible .et-table-header-label-box,
27
+ .et-table-expander:focus-visible,
28
+ .et-table-cell:focus-visible {
29
+ outline-color: var(--et-theme-color-ink-solid);
30
+ }
31
+
32
+ .et-table-sort-indicator {
33
+ color: light-dark(var(--et-theme-color-ink-solid), var(--et-theme-color-primary-solid));
34
+ }
35
+
36
+ .et-table-busy-bar::after {
37
+ background: light-dark(var(--et-theme-color-ink-solid), var(--et-theme-color-primary-solid));
38
+ }
39
+
40
+ .et-table-row.et-table-row--selected .et-table-cell {
41
+ background: light-dark(
42
+ color-mix(in srgb, var(--_et-table-selected-accent, var(--et-theme-color-primary-solid)) 32%, transparent),
43
+ color-mix(in srgb, var(--_et-table-selected-accent, var(--et-theme-color-primary-solid)) 12%, transparent)
44
+ );
45
+ }
46
+
47
+ @media (hover: hover) {
48
+ .et-table-row.et-table-row--selected:hover .et-table-cell {
49
+ background: light-dark(
50
+ color-mix(in srgb, var(--_et-table-selected-accent, var(--et-theme-color-primary-solid)) 38%, transparent),
51
+ color-mix(in srgb, var(--_et-table-selected-accent, var(--et-theme-color-primary-solid)) 18%, transparent)
52
+ );
53
+ }
54
+ }
55
+
56
+ .et-table-row.et-table-row--selected:where(.et-table-row--interactive, .et-table-row--link):active .et-table-cell {
57
+ background: light-dark(
58
+ color-mix(in srgb, var(--_et-table-selected-accent, var(--et-theme-color-primary-solid)) 44%, transparent),
59
+ color-mix(in srgb, var(--_et-table-selected-accent, var(--et-theme-color-primary-solid)) 26%, transparent)
60
+ );
61
+ }
62
+
63
+ et-checkbox:is([aria-checked='true'], [aria-checked='mixed']) .et-checkbox-box {
64
+ outline: 1px solid var(--et-theme-color-ink-solid);
65
+ outline-offset: -1px;
66
+ }
67
+ }
@@ -0,0 +1,160 @@
1
+ import { table, tableStyles, TableColumnMock, TableMockOptions, TableRowMock } from '@ethlete/components/design/table';
2
+ import { definePart, drawing } from '@design-system';
3
+ import frame from './table.css?inline';
4
+
5
+ type Interaction = 'hover' | 'active' | 'focus-visible';
6
+
7
+ type Props = {
8
+ appearance?: TableMockOptions['appearance'];
9
+ sort?: 'asc' | 'desc';
10
+ header?: Interaction;
11
+ row?: Interaction;
12
+ cell?: 'focus-visible';
13
+ selection?: boolean;
14
+ expanded?: boolean;
15
+ expander?: Interaction;
16
+ groups?: boolean;
17
+ cellError?: boolean;
18
+ message?: 'empty' | 'error';
19
+ loading?: boolean;
20
+ busy?: boolean;
21
+ longValue?: boolean;
22
+ wide?: 'start' | 'scrolled';
23
+ stickyHeader?: boolean;
24
+ density?: TableMockOptions['density'];
25
+ center?: boolean;
26
+ };
27
+
28
+ const PLAYERS: [string, string, string, string][] = [
29
+ ['Lena Hoffmann', 'FC Nordhafen', '14', '6'],
30
+ ['Mara Jensen', 'SV Lindenau', '11', '9'],
31
+ ['Ida Krüger', 'TSV Altmark', '9', '3'],
32
+ ['Pia Schulte', 'FC Nordhafen', '7', '11'],
33
+ ['Romy Wagner', 'SC Ostwall', '6', '2'],
34
+ ['Nele Brandt', 'SV Lindenau', '5', '7'],
35
+ ['Clara Vogt', 'TSV Altmark', '4', '4'],
36
+ ['Hanna Peters', 'SC Ostwall', '3', '8'],
37
+ ];
38
+
39
+ const LONG = 'Hoffmann-Wiesenthal-Brandenburger-Lindqvist-Oberhausen';
40
+
41
+ const columns = (
42
+ sort: Props['sort'],
43
+ header: Props['header'],
44
+ align: TableColumnMock['align'] = 'end',
45
+ ): TableColumnMock[] => [
46
+ { header: 'Player', sortable: true, sort: sort ?? 'asc' },
47
+ {
48
+ header: 'Team',
49
+ sortable: true,
50
+ labelAttributes: header ? `data-et-force="${header}"` : undefined,
51
+ },
52
+ { header: 'Goals', sortable: true, align },
53
+ { header: 'Assists', align },
54
+ ];
55
+
56
+ const WIDE_HEADERS = ['Team', 'Goals', 'Assists', 'Shots', 'Minutes', 'Cards'];
57
+ const WIDE: string[][] = [
58
+ ['FC Nordhafen', '14', '6', '41', '1 620', '2'],
59
+ ['SV Lindenau', '11', '9', '36', '1 540', '1'],
60
+ ['TSV Altmark', '9', '3', '30', '1 390', '4'],
61
+ ['FC Nordhafen', '7', '11', '22', '1 480', '0'],
62
+ ];
63
+
64
+ const wideTable = (scrolled: boolean) =>
65
+ table({
66
+ errorColor: 'danger',
67
+ tracks: '140px 132px repeat(5, 96px)',
68
+ columns: [
69
+ { header: 'Player', sortable: true, sort: 'asc', sticky: scrolled ? { side: 'start', offset: 0 } : undefined },
70
+ ...WIDE_HEADERS.map((header, index) => ({ header, align: index === 0 ? undefined : ('end' as const) })),
71
+ ],
72
+ rows: WIDE.map((cells, index) => ({ cells: [PLAYERS[index]?.[0] ?? '', ...cells] })),
73
+ scrolled: scrolled ? { inlineStart: true, inlineEnd: true } : { inlineEnd: true },
74
+ attributes: scrolled ? 'data-scrolled' : undefined,
75
+ });
76
+
77
+ const rows = (props: Props): TableRowMock[] =>
78
+ PLAYERS.slice(props.stickyHeader ? 3 : 0, props.stickyHeader ? 8 : 4).map((cells, index) => {
79
+ const row: TableRowMock = { cells: [...cells] };
80
+
81
+ if (props.longValue && index === 1) row.cells[0] = LONG;
82
+ if (props.cellError && index === 1) {
83
+ row.cells[2] = { value: '—', state: 'error', message: 'Goals could not be loaded' };
84
+ }
85
+ if (props.cell && index === 1) row.cells[1] = { value: cells[1], attributes: `data-et-force="${props.cell}"` };
86
+ if (props.row && index === 1) row.attributes = `data-et-force="${props.row}"`;
87
+ if (props.selection) row.selected = index === 1 || index === 2;
88
+ if (props.expanded && index === 1) {
89
+ row.detail = `<div class="t-detail"><span>Club since 2021</span><span>Left foot</span><span>2 hat-tricks this season</span></div>`;
90
+ }
91
+ if (props.expander && index === 1) row.expanderAttributes = `data-et-force="${props.expander}"`;
92
+ if (props.expanded && index === 3) row.noExpander = true;
93
+
94
+ return row;
95
+ });
96
+
97
+ const render = (props: Props) => {
98
+ if (props.wide) return wideTable(props.wide === 'scrolled');
99
+
100
+ return table({
101
+ errorColor: 'danger',
102
+ tracks: 'minmax(0, 1.6fr) minmax(0, 1.4fr) minmax(0, 0.8fr) minmax(0, 0.8fr)',
103
+ appearance: props.appearance,
104
+ density: props.density,
105
+ columns: columns(props.sort, props.header, props.center ? 'center' : undefined),
106
+ rows: rows(props),
107
+ selection: props.selection ? 'mixed' : undefined,
108
+ expandable: props.expanded || props.expander !== undefined,
109
+ groups: props.groups ? [{ span: 2 }, { label: 'Season', span: 2 }] : undefined,
110
+ message: props.message,
111
+ placeholder: props.loading ? { rows: 4, widths: [70, 55, 30, 30] } : undefined,
112
+ busyAt: props.busy ? 0.4 : undefined,
113
+ interactive: props.row !== undefined,
114
+ cellNavigation: props.cell !== undefined,
115
+ scrolled: props.stickyHeader ? { blockStart: true } : undefined,
116
+ });
117
+ };
118
+
119
+ export default definePart({
120
+ note: 'scale of the decided shape, Q182, lead merge',
121
+ madeBy: ['claude-opus-5-5'],
122
+ states: {
123
+ rest: {},
124
+ 'sort-desc': { sort: 'desc' },
125
+ 'header-hover': { header: 'hover' },
126
+ 'header-active': { header: 'active' },
127
+ 'header-focus-visible': { header: 'focus-visible' },
128
+ 'row-hover': { row: 'hover' },
129
+ 'row-active': { row: 'active' },
130
+ 'cell-focus-visible': { cell: 'focus-visible' },
131
+ divided: { appearance: 'divided' },
132
+ zebra: { appearance: 'zebra' },
133
+ grid: { appearance: 'grid' },
134
+ bare: { appearance: 'bare' },
135
+ selection: { selection: true },
136
+ 'selection-hover': { selection: true, row: 'hover' },
137
+ expanded: { expanded: true },
138
+ 'expander-hover': { expanded: true, expander: 'hover' },
139
+ 'expander-focus-visible': { expanded: true, expander: 'focus-visible' },
140
+ 'group-header': { groups: true },
141
+ 'cell-error': { cellError: true },
142
+ empty: { message: 'empty' },
143
+ error: { message: 'error' },
144
+ loading: { loading: true },
145
+ busy: { busy: true },
146
+ 'long-value': { longValue: true },
147
+ 'wide-scroll': { wide: 'start' },
148
+ 'sticky-column': { wide: 'scrolled' },
149
+ 'sticky-header': { stickyHeader: true },
150
+ 'density-sm': { density: 'sm' },
151
+ 'density-lg': { density: 'lg' },
152
+ 'align-center': { center: true },
153
+ },
154
+ widths: [480],
155
+ render: (props: Props) =>
156
+ drawing({
157
+ body: `<div class="t-frame">${render(props)}</div>`,
158
+ styles: [tableStyles, frame].join('\n'),
159
+ }),
160
+ });
@@ -0,0 +1,13 @@
1
+ @layer components {
2
+ .et-tab-group__trigger {
3
+ --_et-focus-ring-color: light-dark(var(--et-theme-color-ink-solid), var(--et-theme-color-primary-solid));
4
+ }
5
+
6
+ .et-tab-group__trigger:focus-visible .et-tab-group__trigger-content {
7
+ outline-color: light-dark(var(--et-theme-color-ink-solid), var(--et-theme-color-primary-solid));
8
+ }
9
+
10
+ .et-tab-group {
11
+ --et-tab-baseline-opacity: 1;
12
+ }
13
+ }
@@ -0,0 +1,74 @@
1
+ import { iconMarkup } from '@ethlete/components/design/icon';
2
+ import { SDK_ICONS } from '@ethlete/components/design/icon-set';
3
+ import { tabs, type TabsMockOptions, tabsStyles } from '@ethlete/components/design/tabs';
4
+ import { definePart, drawing, interactionRows } from '@design-system';
5
+ import edge from './tabs.css?inline';
6
+
7
+ type TriggerInteraction = 'hover' | 'active' | 'focus-visible';
8
+
9
+ type Props = TabsMockOptions & { forced?: { tab: number; interaction: TriggerInteraction } };
10
+
11
+ const TABS = [{ label: 'Overview' }, { label: 'Activity' }, { label: 'Settings' }];
12
+ const WITH_DISABLED = [...TABS, { label: 'Billing', disabled: true }];
13
+
14
+ const icon = (name: string) =>
15
+ iconMarkup(
16
+ SDK_ICONS.find((each) => each.name === name)!,
17
+ 'et-tab-group__trigger-icon',
18
+ );
19
+ const WITH_ICONS = [
20
+ { label: `${icon('et-grid-2x2')}Overview` },
21
+ { label: `${icon('et-clock')}Activity` },
22
+ { label: `${icon('et-pencil')}Settings` },
23
+ ];
24
+ const ICON_ONLY = [
25
+ { label: icon('et-grid-2x2'), name: 'Overview' },
26
+ { label: icon('et-clock'), name: 'Activity' },
27
+ { label: icon('et-pencil'), name: 'Settings' },
28
+ ];
29
+ const ICON_ONLY_LABELS = Object.fromEntries(ICON_ONLY.map(({ name }, index) => [index, `aria-label="${name}"`]));
30
+
31
+ const { states, grid } = interactionRows(
32
+ {
33
+ tab: { tabs: TABS, selected: 0 },
34
+ selected: { tabs: TABS, selected: 1 },
35
+ } satisfies Record<string, Props>,
36
+ {
37
+ interactions: ['hover', 'active', 'focus-visible'],
38
+ force: (props: Props, interaction: TriggerInteraction): Props => ({ ...props, forced: { tab: 1, interaction } }),
39
+ },
40
+ );
41
+
42
+ export default definePart({
43
+ note: 'The SDK tab group, drawn by its mock from @ethlete/components/design: the bar with its triggers, the underline of the selected tab and the baseline, in every size, both variants and both orientations.',
44
+ madeBy: ['claude-opus-5-5'],
45
+ states: {
46
+ ...states,
47
+ disabled: { tabs: WITH_DISABLED, selected: 0 },
48
+ sm: { tabs: TABS, size: 'sm' },
49
+ lg: { tabs: TABS, size: 'lg' },
50
+ primary: { tabs: TABS, variant: 'primary' },
51
+ icons: { tabs: WITH_ICONS },
52
+ 'primary-icons': { tabs: WITH_ICONS, variant: 'primary' },
53
+ 'icon-only': { tabs: ICON_ONLY, triggerAttributes: ICON_ONLY_LABELS },
54
+ 'primary-icon-only': { tabs: ICON_ONLY, triggerAttributes: ICON_ONLY_LABELS, variant: 'primary' },
55
+ 'no-divider': { tabs: TABS, divider: false },
56
+ vertical: { tabs: TABS, orientation: 'vertical' },
57
+ panel: { tabs: TABS, panel: '<p>Three open tasks, two of them due this week.</p>' },
58
+ },
59
+ grid,
60
+ widths: [480],
61
+ controls: {
62
+ tab: { kind: 'button', input: ['pointer', 'keyboard'], disabled: true },
63
+ },
64
+ render: ({ forced, ...props }: Props) =>
65
+ drawing({
66
+ body: tabs({
67
+ ...props,
68
+ triggerAttributes: forced
69
+ ? { ...props.triggerAttributes, [forced.tab]: `data-et-force="${forced.interaction}"` }
70
+ : props.triggerAttributes,
71
+ }).replaceAll('role="tab"', 'data-et-control="tab" role="tab"'),
72
+ styles: [tabsStyles, edge].join('\n'),
73
+ }),
74
+ });