@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.
- package/CHANGELOG.md +119 -0
- package/design/accordion.ts +73 -0
- package/design/avatar.ts +90 -0
- package/design/badge.ts +48 -0
- package/design/banner.ts +77 -0
- package/design/bracket.ts +457 -0
- package/design/breadcrumb.ts +145 -0
- package/design/button.ts +49 -0
- package/design/calendar.ts +306 -0
- package/design/card.ts +92 -0
- package/design/carousel.ts +240 -0
- package/design/chart.ts +512 -0
- package/design/checkbox.ts +275 -0
- package/design/chip.ts +64 -0
- package/design/config.json +22 -0
- package/design/control.ts +19 -0
- package/design/copy-button.ts +59 -0
- package/design/description-list.ts +41 -0
- package/design/dialog.ts +214 -0
- package/design/divider.ts +27 -0
- package/design/empty-state.ts +45 -0
- package/design/floating-action.ts +55 -0
- package/design/form-field.ts +40 -1
- package/design/grid.ts +148 -0
- package/design/icon-set.ts +19 -0
- package/design/icon.ts +9 -0
- package/design/input.ts +86 -0
- package/design/kbd.ts +19 -0
- package/design/loader.ts +152 -0
- package/design/masonry.ts +115 -0
- package/design/match.ts +131 -0
- package/design/menu.ts +143 -0
- package/design/notification.ts +129 -0
- package/design/otp-input.ts +107 -0
- package/design/pagination.ts +120 -0
- package/design/picture.ts +80 -0
- package/design/progress-steps.ts +79 -0
- package/design/query-error.ts +60 -0
- package/design/radio-group.ts +132 -0
- package/design/scheduler.ts +369 -0
- package/design/scrollable.ts +218 -0
- package/design/scrollbar.ts +47 -0
- package/design/sdk/assets/fallback.svg +1 -0
- package/design/sdk/assets/tall.svg +1 -0
- package/design/sdk/assets/wide.svg +1 -0
- package/design/sdk/components/accent-on-light/accent-on-light.css +35 -0
- package/design/sdk/components/accent-on-light/accent-on-light.ts +10 -0
- package/design/sdk/components/accent-on-light/shared/controls.ts +46 -0
- package/design/sdk/components/accordion/accordion.css +17 -0
- package/design/sdk/components/accordion/accordion.ts +64 -0
- package/design/sdk/components/avatar/avatar.css +14 -0
- package/design/sdk/components/avatar/avatar.ts +78 -0
- package/design/sdk/components/badge/badge.css +13 -0
- package/design/sdk/components/badge/badge.ts +52 -0
- package/design/sdk/components/banner/banner.css +18 -0
- package/design/sdk/components/banner/banner.ts +87 -0
- package/design/sdk/components/bracket/bracket.css +59 -0
- package/design/sdk/components/bracket/bracket.ts +143 -0
- package/design/sdk/components/breadcrumb/breadcrumb.css +25 -0
- package/design/sdk/components/breadcrumb/breadcrumb.ts +81 -0
- package/design/sdk/components/button/button.css +33 -0
- package/design/sdk/components/button/button.ts +82 -0
- package/design/sdk/components/calendar/calendar.css +33 -0
- package/design/sdk/components/calendar/calendar.ts +96 -0
- package/design/sdk/components/card/card.css +19 -0
- package/design/sdk/components/card/card.ts +61 -0
- package/design/sdk/components/carousel/carousel.css +44 -0
- package/design/sdk/components/carousel/carousel.ts +74 -0
- package/design/sdk/components/chart/chart.css +56 -0
- package/design/sdk/components/chart/chart.ts +98 -0
- package/design/sdk/components/chip/chip.css +18 -0
- package/design/sdk/components/chip/chip.ts +76 -0
- package/design/sdk/components/copy-button/copy-button.css +14 -0
- package/design/sdk/components/copy-button/copy-button.ts +59 -0
- package/design/sdk/components/description-list/description-list.css +7 -0
- package/design/sdk/components/description-list/description-list.ts +53 -0
- package/design/sdk/components/dialog/dialog.css +29 -0
- package/design/sdk/components/dialog/dialog.ts +78 -0
- package/design/sdk/components/divider/divider.css +26 -0
- package/design/sdk/components/divider/divider.ts +43 -0
- package/design/sdk/components/empty-state/empty-state.css +15 -0
- package/design/sdk/components/empty-state/empty-state.ts +56 -0
- package/design/sdk/components/floating-action/floating-action.css +51 -0
- package/design/sdk/components/floating-action/floating-action.ts +63 -0
- package/design/sdk/components/form-field/form-field.ts +118 -0
- package/design/sdk/components/grid/grid.css +17 -0
- package/design/sdk/components/grid/grid.ts +80 -0
- package/design/sdk/components/input/input.css +75 -0
- package/design/sdk/components/input/input.ts +79 -0
- package/design/sdk/components/kbd/kbd.css +25 -0
- package/design/sdk/components/kbd/kbd.ts +57 -0
- package/design/sdk/components/loader/loader.css +37 -0
- package/design/sdk/components/loader/loader.ts +68 -0
- package/design/sdk/components/masonry/masonry.css +7 -0
- package/design/sdk/components/masonry/masonry.ts +42 -0
- package/design/sdk/components/match/match.css +25 -0
- package/design/sdk/components/match/match.ts +76 -0
- package/design/sdk/components/menu/menu.css +22 -0
- package/design/sdk/components/menu/menu.ts +91 -0
- package/design/sdk/components/notification/notification.css +32 -0
- package/design/sdk/components/notification/notification.ts +106 -0
- package/design/sdk/components/otp-input/otp-input.css +35 -0
- package/design/sdk/components/otp-input/otp-input.ts +64 -0
- package/design/sdk/components/pagination/pagination.css +14 -0
- package/design/sdk/components/pagination/pagination.ts +75 -0
- package/design/sdk/components/picture/picture.css +37 -0
- package/design/sdk/components/picture/picture.ts +96 -0
- package/design/sdk/components/progress-steps/progress-steps.css +37 -0
- package/design/sdk/components/progress-steps/progress-steps.ts +91 -0
- package/design/sdk/components/query-error/query-error.css +33 -0
- package/design/sdk/components/query-error/query-error.ts +120 -0
- package/design/sdk/components/scheduler/scheduler.css +55 -0
- package/design/sdk/components/scheduler/scheduler.ts +239 -0
- package/design/sdk/components/scrollable/scrollable.css +58 -0
- package/design/sdk/components/scrollable/scrollable.ts +133 -0
- package/design/sdk/components/scrollbar/scrollbar.css +78 -0
- package/design/sdk/components/scrollbar/scrollbar.ts +123 -0
- package/design/sdk/components/select/select.css +5 -0
- package/design/sdk/components/select/select.ts +16 -0
- package/design/sdk/components/select/shared/select-part.ts +75 -0
- package/design/sdk/components/select-panel/select-panel.css +3 -0
- package/design/sdk/components/select-panel/select-panel.ts +124 -0
- package/design/sdk/components/skeleton/skeleton.css +22 -0
- package/design/sdk/components/skeleton/skeleton.ts +50 -0
- package/design/sdk/components/slider/slider.css +52 -0
- package/design/sdk/components/slider/slider.ts +86 -0
- package/design/sdk/components/standings/standings.css +33 -0
- package/design/sdk/components/standings/standings.ts +130 -0
- package/design/sdk/components/stat-tile/stat-tile.css +15 -0
- package/design/sdk/components/stat-tile/stat-tile.ts +84 -0
- package/design/sdk/components/stream/stream.css +48 -0
- package/design/sdk/components/stream/stream.ts +38 -0
- package/design/sdk/components/switch/switch.css +35 -0
- package/design/sdk/components/switch/switch.ts +63 -0
- package/design/sdk/components/table/table.css +67 -0
- package/design/sdk/components/table/table.ts +160 -0
- package/design/sdk/components/tabs/tabs.css +13 -0
- package/design/sdk/components/tabs/tabs.ts +74 -0
- package/design/sdk/components/textarea/textarea.css +116 -0
- package/design/sdk/components/textarea/textarea.ts +64 -0
- package/design/sdk/components/timeline/timeline.css +30 -0
- package/design/sdk/components/timeline/timeline.ts +87 -0
- package/design/sdk/components/toolbar/toolbar.css +24 -0
- package/design/sdk/components/toolbar/toolbar.ts +87 -0
- package/design/sdk/components/tooltip/tooltip.css +15 -0
- package/design/sdk/components/tooltip/tooltip.ts +28 -0
- package/design/sdk/components/tree/selected-tint.css +15 -0
- package/design/sdk/components/tree/tree.ts +70 -0
- package/design/sdk/fixtures.ts +0 -0
- package/design/sdk/foundations/colors/colors.css +632 -0
- package/design/sdk/foundations/colors/colors.ts +188 -0
- package/design/sdk/foundations/colors/overrides.json +19 -0
- package/design/sdk/foundations/colors/shared/contrast.ts +120 -0
- package/design/sdk/foundations/elevation/elevation.css +6 -0
- package/design/sdk/foundations/elevation/elevation.ts +11 -0
- package/design/sdk/foundations/elevation/shared/elevation/scene.css +101 -0
- package/design/sdk/foundations/elevation/shared/elevation/scene.ts +74 -0
- package/design/sdk/foundations/icons/icons.ts +119 -0
- package/design/select.ts +113 -28
- package/design/skeleton.ts +67 -0
- package/design/slider.ts +155 -0
- package/design/standings.ts +161 -0
- package/design/stat-tile.ts +109 -0
- package/design/stream.ts +92 -0
- package/design/switch.ts +83 -0
- package/design/table.ts +302 -0
- package/design/tabs.ts +75 -0
- package/design/textarea.ts +92 -0
- package/design/timeline.ts +52 -0
- package/design/toolbar.ts +95 -0
- package/design/tooltip.ts +87 -0
- package/design/tree.ts +106 -0
- package/fesm2022/ethlete-components.mjs +240 -199
- package/fesm2022/ethlete-components.mjs.map +1 -1
- package/package.json +1 -1
- package/src/lib/accordion/accordion.component.css +2 -1
- package/src/lib/avatar/avatar.component.css +10 -0
- package/src/lib/badge/badge.component.css +2 -2
- package/src/lib/banner/banner.component.css +3 -1
- package/src/lib/breadcrumb/breadcrumb-outlet.component.css +5 -0
- package/src/lib/breadcrumb/breadcrumb.component.css +5 -1
- package/src/lib/button/button.component.css +19 -0
- package/src/lib/button/icon-button.component.css +19 -20
- package/src/lib/button/split-button.component.css +5 -1
- package/src/lib/calendar/calendar.component.css +13 -3
- package/src/lib/card/card.component.css +4 -0
- package/src/lib/carousel/carousel-autoplay-styles.component.css +1 -1
- package/src/lib/carousel/carousel.component.css +2 -2
- package/src/lib/chart/chart-axis.component.css +3 -3
- package/src/lib/chip/chip.component.css +8 -2
- package/src/lib/description-list/description-list.component.css +2 -1
- package/src/lib/empty-state/empty-state.component.css +4 -0
- package/src/lib/floating-action/floating-action-styles.component.css +27 -0
- package/src/lib/focus-ring/focus-ring-styles.component.css +4 -1
- package/src/lib/forms/checkbox/checkbox.component.css +31 -5
- package/src/lib/forms/color-input/color-input.component.css +3 -1
- package/src/lib/forms/color-input/color-picker-panel.component.css +6 -2
- package/src/lib/forms/date-time/date-input/date-input.component.css +1 -1
- package/src/lib/forms/date-time/date-time-input/date-time-input.component.css +1 -1
- package/src/lib/forms/date-time/duration-input/duration-input.component.css +1 -1
- package/src/lib/forms/date-time/range-input-shell-styles.component.css +1 -1
- package/src/lib/forms/date-time/time-input/time-input.component.css +1 -1
- package/src/lib/forms/description/description.component.css +7 -0
- package/src/lib/forms/dropzone/dropzone.component.css +26 -0
- package/src/lib/forms/form-field/form-field-control-suffix-styles.component.css +4 -2
- package/src/lib/forms/form-field/form-field-text-shell-styles.component.css +74 -17
- package/src/lib/forms/form-field/form-field-textarea-styles.component.css +62 -0
- package/src/lib/forms/form-field/form-field.component.css +6 -0
- package/src/lib/forms/form-field/headless/label.directive.css +1 -1
- package/src/lib/forms/input/input.component.css +6 -2
- package/src/lib/forms/input/number-input.component.css +2 -2
- package/src/lib/forms/input/password-input.component.css +4 -3
- package/src/lib/forms/otp-input/otp-input.component.css +23 -4
- package/src/lib/forms/phone-input/phone-input.component.css +4 -3
- package/src/lib/forms/rating/rating.component.css +2 -1
- package/src/lib/forms/rich-text-editor/rich-text-editor.component.css +1 -1
- package/src/lib/forms/select/select-option-styles.component.css +3 -2
- package/src/lib/forms/selection-card-styles.component.css +3 -2
- package/src/lib/forms/selection-list/checkbox-group/checkbox-group-select-all.component.css +4 -2
- package/src/lib/forms/selection-list/checkbox-group/checkbox-option.component.css +4 -2
- package/src/lib/forms/selection-list/radio-group/radio.component.css +5 -2
- package/src/lib/forms/selection-list/segmented-button-group/segmented-button.component.css +2 -1
- package/src/lib/forms/slider/range-slider.component.css +98 -6
- package/src/lib/forms/slider/slider.component.css +96 -4
- package/src/lib/forms/switch/switch.component.css +47 -4
- package/src/lib/forms/tag-input/tag-input.component.css +2 -2
- package/src/lib/forms/textarea/textarea-autosize-styles.component.css +2 -3
- package/src/lib/forms/textarea/textarea.component.css +7 -2
- package/src/lib/grid/grid-item-toolbar.component.css +10 -0
- package/src/lib/grid/grid-item.component.css +6 -1
- package/src/lib/icon/headless/align-icons.ts +30 -0
- package/src/lib/icon/headless/arrow-out-up-right-icon.ts +17 -0
- package/src/lib/icon/headless/arrow-right-icon.ts +23 -0
- package/src/lib/icon/headless/arrow-up-icon.ts +30 -0
- package/src/lib/icon/headless/arrows-left-right-icon.ts +31 -0
- package/src/lib/icon/headless/bold-icon.ts +11 -0
- package/src/lib/icon/headless/calendar-icon.ts +21 -0
- package/src/lib/icon/headless/check-icon.ts +14 -0
- package/src/lib/icon/headless/chevron-icon.ts +14 -0
- package/src/lib/icon/headless/circle-check-icon.ts +14 -0
- package/src/lib/icon/headless/circle-info-icon.ts +14 -0
- package/src/lib/icon/headless/clipboard-check-icon.ts +28 -0
- package/src/lib/icon/headless/clock-icon.ts +21 -0
- package/src/lib/icon/headless/code-block-icon.ts +15 -0
- package/src/lib/icon/headless/code-icon.ts +14 -0
- package/src/lib/icon/headless/ellipsis-icon.ts +13 -0
- package/src/lib/icon/headless/ellipsis-vertical-icon.ts +13 -0
- package/src/lib/icon/headless/eye-icons.ts +27 -0
- package/src/lib/icon/headless/eyedropper-icon.ts +22 -0
- package/src/lib/icon/headless/file-icon.ts +16 -0
- package/src/lib/icon/headless/filter-icon.ts +11 -0
- package/src/lib/icon/headless/floppy-disk-icon.ts +27 -0
- package/src/lib/icon/headless/focus-frame-icon.ts +16 -0
- package/src/lib/icon/headless/grid-2x2-icon.ts +17 -0
- package/src/lib/icon/headless/heading-1-icon.ts +11 -0
- package/src/lib/icon/headless/heading-2-icon.ts +11 -0
- package/src/lib/icon/headless/heading-3-icon.ts +11 -0
- package/src/lib/icon/headless/icon-definition.ts +14 -0
- package/src/lib/icon/headless/image-icon.ts +14 -0
- package/src/lib/icon/headless/italic-icon.ts +19 -0
- package/src/lib/icon/headless/link-icon.ts +17 -0
- package/src/lib/icon/headless/list-bulleted-icon.ts +14 -0
- package/src/lib/icon/headless/list-numbered-icon.ts +14 -0
- package/src/lib/icon/headless/location-icon.ts +21 -0
- package/src/lib/icon/headless/lock-icon.ts +14 -0
- package/src/lib/icon/headless/minus-icon.ts +14 -0
- package/src/lib/icon/headless/paragraph-icon.ts +11 -0
- package/src/lib/icon/headless/pause-icon.ts +11 -0
- package/src/lib/icon/headless/pencil-icon.ts +21 -0
- package/src/lib/icon/headless/play-icon.ts +10 -0
- package/src/lib/icon/headless/plus-icon.ts +21 -0
- package/src/lib/icon/headless/quote-icon.ts +15 -0
- package/src/lib/icon/headless/rotate-right-icon.ts +16 -0
- package/src/lib/icon/headless/star-icon.ts +14 -0
- package/src/lib/icon/headless/strikethrough-icon.ts +18 -0
- package/src/lib/icon/headless/table-icon.ts +15 -0
- package/src/lib/icon/headless/thumbtack-icon.ts +18 -0
- package/src/lib/icon/headless/times-icon.ts +14 -0
- package/src/lib/icon/headless/trash-icon.ts +24 -0
- package/src/lib/icon/headless/triangle-exclamation-icon.ts +14 -0
- package/src/lib/icon/headless/trophy-icon.ts +24 -0
- package/src/lib/icon/headless/underline-icon.ts +12 -0
- package/src/lib/icon/headless/undo-redo-icons.ts +24 -0
- package/src/lib/icon/headless/upload-icon.ts +16 -0
- package/src/lib/loader/brand-loader/brand-loader.component.css +4 -1
- package/src/lib/loader/progress-bar/progress-bar.component.css +1 -1
- package/src/lib/loader/spinner/spinner-styles.component.css +1 -1
- package/src/lib/match/match-card.component.css +9 -3
- package/src/lib/match/match-score.component.css +4 -1
- package/src/lib/menu/menu-selection-item.component.css +1 -1
- package/src/lib/menu/menu.component.css +5 -0
- package/src/lib/overlay/overlay-container.component.css +4 -0
- package/src/lib/pagination/pagination.component.css +4 -0
- package/src/lib/progress-steps/progress-step.component.css +4 -4
- package/src/lib/query-error/query-error.component.css +4 -0
- package/src/lib/scheduler/scheduler-appointment-styles.component.css +21 -5
- package/src/lib/scheduler/scheduler-month-view.component.css +4 -2
- package/src/lib/scheduler/scheduler-time-grid-view.component.css +8 -2
- package/src/lib/scrollable/headless/scrollable-navigation.component.css +1 -1
- package/src/lib/standings/standings-pick.component.css +1 -1
- package/src/lib/standings/standings.component.css +10 -10
- package/src/lib/stat-tile/stat-tile-sparkline.component.css +1 -1
- package/src/lib/stream/consent/stream-consent.component.css +99 -0
- package/src/lib/stream/error/stream-player-error.component.css +100 -0
- package/src/lib/stream/loading/stream-player-loading.component.css +16 -0
- package/src/lib/stream/pip/pip-slot-placeholder.component.css +68 -0
- package/src/lib/stream/stream-player-slot-styles.component.css +4 -0
- package/src/lib/table/table-resize-grip.component.css +2 -1
- package/src/lib/table/table-select-cell.component.css +45 -15
- package/src/lib/table/table.component.css +15 -5
- package/src/lib/tabs/tab-bar-styles.component.css +1 -1
- package/src/lib/tabs/tabs/tab-group.component.css +111 -0
- package/src/lib/time-picker/time-picker.component.css +2 -1
- package/src/lib/timeline/timeline-item.component.css +5 -1
- package/src/lib/toolbar/toolbar.component.css +4 -0
- package/src/lib/tooltip/tooltip.component.css +14 -0
- package/src/lib/tree/tree.component.css +2 -2
- 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
|
+
});
|