@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,188 @@
|
|
|
1
|
+
import { definePart, html, tokenSheet, type Drawing } from '@design-system';
|
|
2
|
+
import { contrastSheet, contrastStyles } from './shared/contrast';
|
|
3
|
+
import css from './colors.css?inline';
|
|
4
|
+
|
|
5
|
+
type Surface = 'light' | 'dark';
|
|
6
|
+
|
|
7
|
+
type Theme = 'brand' | 'danger' | 'warning';
|
|
8
|
+
|
|
9
|
+
type Props = { group: 'surface' | 'contrast' | Theme; surface: Surface };
|
|
10
|
+
|
|
11
|
+
const STATE_ENDS = ['', '-hover', '-focus', '-active', '-disabled'];
|
|
12
|
+
|
|
13
|
+
const labelOf = (end: string) => (end ? end.slice(1) : 'rest');
|
|
14
|
+
|
|
15
|
+
const SURFACE_TOKEN =
|
|
16
|
+
/^et-(surface-(background|color(-muted|-subtle)?|border|interaction(-hover|-focus|-active|-disabled)?)|shadow-color-rgb)$/u;
|
|
17
|
+
|
|
18
|
+
const COLOR_TOKEN = /^et-color-(on-)?primary(-ink)?(-hover|-focus|-active|-disabled)?$/u;
|
|
19
|
+
|
|
20
|
+
const TEXT_TOKEN = /^et-surface-(background|color(-muted|-subtle)?)$/u;
|
|
21
|
+
|
|
22
|
+
const themeClassOf = (theme: Theme, surface: Surface) => `et-color--${theme}${surface === 'light' ? '-on-light' : ''}`;
|
|
23
|
+
|
|
24
|
+
const demoNote = (theme: Theme, surface: Surface) =>
|
|
25
|
+
`${theme} is a demo theme of the SDK Storybook (apps/storybook/src/themes.ts); the SDK ships no theme names, each app registers its own.${surface === 'light' ? ` On a light surface the sheet reads .${themeClassOf(theme, surface)}.` : ''}`;
|
|
26
|
+
|
|
27
|
+
const swatch = (token: string) => html`<span class="sdk-swatch" style="background: rgb(var(--${token}))"></span>`;
|
|
28
|
+
|
|
29
|
+
const disabledOf = (name: string) => (name.endsWith('-disabled') ? 'aria-disabled="true"' : '');
|
|
30
|
+
|
|
31
|
+
const ink = (token: string, label = 'Aa') =>
|
|
32
|
+
html`<span class="sdk-ink" ${disabledOf(token)} style="color: rgb(var(--${token}))">${label}</span>`;
|
|
33
|
+
|
|
34
|
+
const surfaceSample = (name: string) => {
|
|
35
|
+
if (name === 'et-shadow-color-rgb') return html`<span class="sdk-swatch sdk-shadow"></span>`;
|
|
36
|
+
if (/^et-surface-color/u.test(name)) return ink(name);
|
|
37
|
+
|
|
38
|
+
return swatch(name);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const colorSample = (name: string) => {
|
|
42
|
+
const onFill = /^et-color-on-primary(.*)$/u.exec(name);
|
|
43
|
+
if (onFill)
|
|
44
|
+
return html`<span
|
|
45
|
+
class="sdk-fill"
|
|
46
|
+
${disabledOf(name)}
|
|
47
|
+
style="background: rgb(var(--et-color-primary${onFill[1]})); color: rgb(var(--${name}))"
|
|
48
|
+
>Aa</span
|
|
49
|
+
>`;
|
|
50
|
+
if (name.startsWith('et-color-primary-ink')) return ink(name, 'Ink');
|
|
51
|
+
|
|
52
|
+
return swatch(name);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const surfacePanel = html`<div class="sdk-card">
|
|
56
|
+
<span>Text</span>
|
|
57
|
+
<span class="sdk-muted">Muted text</span>
|
|
58
|
+
<span class="sdk-subtle">Subtle text</span>
|
|
59
|
+
</div>
|
|
60
|
+
<div class="sdk-states">
|
|
61
|
+
${STATE_ENDS.map(
|
|
62
|
+
(end) =>
|
|
63
|
+
html`<span class="sdk-state"
|
|
64
|
+
><span class="sdk-swatch" style="background: rgb(var(--et-surface-interaction${end}))"></span
|
|
65
|
+
>${labelOf(end)}</span
|
|
66
|
+
>`,
|
|
67
|
+
).join('')}
|
|
68
|
+
</div>
|
|
69
|
+
<div class="sdk-elevations">
|
|
70
|
+
<span class="sdk-elevation sdk-shadow-resting">Resting</span>
|
|
71
|
+
<span class="sdk-elevation sdk-shadow-raised">Raised</span>
|
|
72
|
+
</div>`;
|
|
73
|
+
|
|
74
|
+
const themePanel = html`<div class="sdk-states">
|
|
75
|
+
${STATE_ENDS.map(
|
|
76
|
+
(end) =>
|
|
77
|
+
html`<span
|
|
78
|
+
class="sdk-fill sdk-fill--wide"
|
|
79
|
+
${disabledOf(end)}
|
|
80
|
+
style="background: rgb(var(--et-color-primary${end})); color: rgb(var(--et-color-on-primary${end}))"
|
|
81
|
+
>${labelOf(end)}</span
|
|
82
|
+
>`,
|
|
83
|
+
).join('')}
|
|
84
|
+
</div>
|
|
85
|
+
<div class="sdk-states">
|
|
86
|
+
${STATE_ENDS.map(
|
|
87
|
+
(end) =>
|
|
88
|
+
html`<span class="sdk-link" ${disabledOf(end)} style="color: rgb(var(--et-color-primary-ink${end}))"
|
|
89
|
+
>Ink ${labelOf(end)}</span
|
|
90
|
+
>`,
|
|
91
|
+
).join('')}
|
|
92
|
+
</div>`;
|
|
93
|
+
|
|
94
|
+
const scopeOf = ({ group, surface }: Props) =>
|
|
95
|
+
group === 'surface' || group === 'contrast'
|
|
96
|
+
? `sdk-colors et-surface--${surface}`
|
|
97
|
+
: `sdk-colors et-surface--${surface} ${themeClassOf(group, surface)}`;
|
|
98
|
+
|
|
99
|
+
const titleOf = ({ group, surface }: Props) =>
|
|
100
|
+
group === 'surface'
|
|
101
|
+
? `Surface, ${surface}`
|
|
102
|
+
: group === 'contrast'
|
|
103
|
+
? `Contrast, ${surface}`
|
|
104
|
+
: `${group} (demo theme) on ${surface}`;
|
|
105
|
+
|
|
106
|
+
const sheetOf = (props: Props) => {
|
|
107
|
+
const { group, surface } = props;
|
|
108
|
+
|
|
109
|
+
if (group === 'surface')
|
|
110
|
+
return tokenSheet({
|
|
111
|
+
title: titleOf(props),
|
|
112
|
+
scope: scopeOf(props),
|
|
113
|
+
css,
|
|
114
|
+
sample: surfacePanel,
|
|
115
|
+
sampleOf: surfaceSample,
|
|
116
|
+
only: (name) => SURFACE_TOKEN.test(name),
|
|
117
|
+
});
|
|
118
|
+
if (group === 'contrast')
|
|
119
|
+
return tokenSheet({
|
|
120
|
+
title: titleOf(props),
|
|
121
|
+
scope: scopeOf(props),
|
|
122
|
+
css,
|
|
123
|
+
sample: contrastSheet(css, surface),
|
|
124
|
+
sampleClass: 'sdk-contrast',
|
|
125
|
+
sampleOf: surfaceSample,
|
|
126
|
+
only: (name) => TEXT_TOKEN.test(name),
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return tokenSheet({
|
|
130
|
+
title: titleOf(props),
|
|
131
|
+
scope: scopeOf(props),
|
|
132
|
+
note: demoNote(group, surface),
|
|
133
|
+
css,
|
|
134
|
+
sample: themePanel,
|
|
135
|
+
sampleOf: colorSample,
|
|
136
|
+
only: (name) => COLOR_TOKEN.test(name),
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const STYLES = `
|
|
141
|
+
${contrastStyles}
|
|
142
|
+
.sdk-colors { --surface: var(--et-surface-background-solid); --text: var(--et-surface-color-solid); --text-muted: var(--et-surface-color-muted-solid); --surface-border: var(--et-surface-border-solid); --font-ui: var(--et-font-family); --font-code: var(--et-font-family-mono); width: max-content; }
|
|
143
|
+
.sdk-colors .ts-row { grid-template-columns: 300px 160px 1fr; }
|
|
144
|
+
section.ts-panel { display: flex; flex-direction: column; gap: 1.2rem; }
|
|
145
|
+
section.ts-panel.sdk-contrast { flex-direction: row; flex-wrap: wrap; gap: 2.4rem; }
|
|
146
|
+
.sdk-table { display: flex; flex-direction: column; gap: 0.8rem; }
|
|
147
|
+
.sdk-title { margin: 0; font-size: 1.4rem; font-weight: 600; }
|
|
148
|
+
.sdk-value { font-family: var(--et-font-family-mono); font-size: 1.2rem; color: var(--et-surface-color-muted-solid); white-space: nowrap; }
|
|
149
|
+
.sdk-card { display: flex; gap: 2.4rem; padding: 1.2rem 1.6rem; border: 0.1rem solid var(--et-surface-border-solid); border-radius: 0.6rem; }
|
|
150
|
+
.sdk-muted { color: var(--et-surface-color-muted-solid); }
|
|
151
|
+
.sdk-subtle { color: var(--et-surface-color-subtle-solid); }
|
|
152
|
+
.sdk-states { display: flex; flex-wrap: wrap; gap: 1.2rem; align-items: center; }
|
|
153
|
+
.sdk-state { display: inline-flex; align-items: center; gap: 0.6rem; font-size: 1.2rem; }
|
|
154
|
+
.sdk-swatch { display: block; width: 4rem; height: 2.4rem; border-radius: 0.4rem; border: 0.1rem solid var(--et-surface-border-solid); }
|
|
155
|
+
.sdk-shadow { background: var(--et-surface-background-solid); box-shadow: 0 0.6rem 1.2rem rgb(var(--et-shadow-color-rgb) / 0.22), 0 0.2rem 0.4rem rgb(var(--et-shadow-color-rgb) / 0.14); }
|
|
156
|
+
.sdk-ink { font-size: 1.6rem; font-weight: 600; }
|
|
157
|
+
.sdk-fill { display: inline-grid; place-items: center; min-width: 4rem; height: 2.4rem; padding: 0 0.8rem; box-sizing: border-box; border-radius: 0.4rem; font-size: 1.2rem; font-weight: 600; }
|
|
158
|
+
.sdk-fill--wide { min-width: 8rem; height: 3.2rem; }
|
|
159
|
+
.sdk-link { min-width: 8rem; font-size: 1.3rem; font-weight: 600; text-decoration: underline; }
|
|
160
|
+
.sdk-elevations { display: flex; gap: 2.4rem; padding: 0.8rem 0; }
|
|
161
|
+
.sdk-elevation { display: grid; place-items: center; width: 12rem; height: 4.8rem; border-radius: 0.6rem; background: var(--et-surface-background-solid); font-size: 1.2rem; }
|
|
162
|
+
.sdk-shadow-resting { box-shadow: 0 0.3rem 0.8rem rgb(var(--et-shadow-color-rgb) / 0.2), 0 0.1rem 0.3rem rgb(var(--et-shadow-color-rgb) / 0.12); }
|
|
163
|
+
.sdk-shadow-raised { box-shadow: 0 0.6rem 1.2rem rgb(var(--et-shadow-color-rgb) / 0.22), 0 0.2rem 0.4rem rgb(var(--et-shadow-color-rgb) / 0.14); }
|
|
164
|
+
`;
|
|
165
|
+
|
|
166
|
+
const render = (props: Props): Drawing => {
|
|
167
|
+
const sheet = sheetOf(props);
|
|
168
|
+
|
|
169
|
+
return { ...sheet, styles: `${sheet.styles ?? ''}${STYLES}` };
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export default definePart<Props>({
|
|
173
|
+
note: 'The SDK colour tokens: a light and a dark surface, the demo colour themes brand, danger and warning with their on-light variants, and the AA contrast of text and fills. Every frame loads it before the part styles. Generated by tools/scripts/generate-sdk-tokens.mjs from the Storybook themes; never edit the CSS by hand.',
|
|
174
|
+
madeBy: ['claude-opus-5-5'],
|
|
175
|
+
states: {
|
|
176
|
+
'surface-light': { group: 'surface', surface: 'light' },
|
|
177
|
+
'surface-dark': { group: 'surface', surface: 'dark' },
|
|
178
|
+
'brand-light': { group: 'brand', surface: 'light' },
|
|
179
|
+
'brand-dark': { group: 'brand', surface: 'dark' },
|
|
180
|
+
'danger-light': { group: 'danger', surface: 'light' },
|
|
181
|
+
'danger-dark': { group: 'danger', surface: 'dark' },
|
|
182
|
+
'warning-light': { group: 'warning', surface: 'light' },
|
|
183
|
+
'warning-dark': { group: 'warning', surface: 'dark' },
|
|
184
|
+
'contrast-light': { group: 'contrast', surface: 'light' },
|
|
185
|
+
'contrast-dark': { group: 'contrast', surface: 'dark' },
|
|
186
|
+
},
|
|
187
|
+
render,
|
|
188
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extraColorThemes": ["brand-on-light", "danger-on-light", "warning-on-light"],
|
|
3
|
+
"values": {
|
|
4
|
+
"danger": {
|
|
5
|
+
"primary.color.hover": "185 28 28",
|
|
6
|
+
"primary.color.focus": "185 28 28",
|
|
7
|
+
"primary.color.active": "153 27 27"
|
|
8
|
+
},
|
|
9
|
+
"danger-on-light": {
|
|
10
|
+
"primary.color.hover": "185 28 28",
|
|
11
|
+
"primary.color.focus": "185 28 28",
|
|
12
|
+
"primary.color.active": "153 27 27"
|
|
13
|
+
},
|
|
14
|
+
"warning": { "primary.color.active": "251 191 36" },
|
|
15
|
+
"warning-on-light": { "primary.color.active": "251 191 36" },
|
|
16
|
+
"light": { "colorSubtle": "112 112 112" },
|
|
17
|
+
"dark": { "colorSubtle": "135 135 135" }
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { html } from '@design-system';
|
|
2
|
+
|
|
3
|
+
type Surface = 'light' | 'dark';
|
|
4
|
+
|
|
5
|
+
const tokenValues = (css: string, selector: string) => {
|
|
6
|
+
const start = css.indexOf(`${selector} {`);
|
|
7
|
+
|
|
8
|
+
if (start === -1) throw new Error(`colors.css has no ${selector} block`);
|
|
9
|
+
|
|
10
|
+
const block = css.slice(start, css.indexOf('}', start));
|
|
11
|
+
|
|
12
|
+
return Object.fromEntries(
|
|
13
|
+
[...block.matchAll(/(--[\w-]+): (\d+ \d+ \d+);/g)].map(([, name, value]) => [name, value as string]),
|
|
14
|
+
) as Record<string, string>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const channel = (value: number) => {
|
|
18
|
+
const c = value / 255;
|
|
19
|
+
|
|
20
|
+
return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const luminance = (rgb: string) => {
|
|
24
|
+
const [r = 0, g = 0, b = 0] = rgb.split(' ').map(Number);
|
|
25
|
+
|
|
26
|
+
return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const contrastRatio = (a: string, b: string) => {
|
|
30
|
+
const [high, low] = [luminance(a), luminance(b)].sort((x, y) => y - x) as [number, number];
|
|
31
|
+
|
|
32
|
+
return (high + 0.05) / (low + 0.05);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const AA = 4.5;
|
|
36
|
+
|
|
37
|
+
const pair = (label: string, fill: string, ink: string, fixed: boolean) => {
|
|
38
|
+
const ratio = contrastRatio(fill, ink);
|
|
39
|
+
|
|
40
|
+
return html`<span class="sdk-pair" style="background: rgb(${fill}); color: rgb(${ink})">Aa</span>
|
|
41
|
+
<span class="sdk-pair-label${fixed ? ' sdk-fixed' : ''}">${label}</span>
|
|
42
|
+
<code class="sdk-value">${fill} / ${ink}</code>
|
|
43
|
+
<strong class="sdk-ratio" data-pass="${ratio >= AA}"
|
|
44
|
+
>${ratio.toFixed(2)}:1 ${ratio >= AA ? 'AA' : 'below AA'}</strong
|
|
45
|
+
>`;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const STATE_SUFFIX = { rest: '', hover: '-hover', focus: '-focus', active: '-active' } as const;
|
|
49
|
+
|
|
50
|
+
const FIXED: Record<string, (keyof typeof STATE_SUFFIX)[]> = { danger: ['hover', 'focus'], warning: ['active'] };
|
|
51
|
+
|
|
52
|
+
const pairTable = (title: string, rows: string) =>
|
|
53
|
+
html`<section class="sdk-table">
|
|
54
|
+
<h2 class="sdk-title">${title}</h2>
|
|
55
|
+
<div class="sdk-pairs">${rows}</div>
|
|
56
|
+
</section>`;
|
|
57
|
+
|
|
58
|
+
export const contrastSheet = (css: string, surface: Surface) => {
|
|
59
|
+
const level = tokenValues(css, `.et-surface--${surface}`);
|
|
60
|
+
const background = level['--et-surface-background'] ?? '';
|
|
61
|
+
const suffix = surface === 'light' ? '-on-light' : '';
|
|
62
|
+
|
|
63
|
+
const text = pairTable(
|
|
64
|
+
`Text on the ${surface} background`,
|
|
65
|
+
(
|
|
66
|
+
[
|
|
67
|
+
['text', '--et-surface-color'],
|
|
68
|
+
['muted', '--et-surface-color-muted'],
|
|
69
|
+
['subtle', '--et-surface-color-subtle'],
|
|
70
|
+
] as const
|
|
71
|
+
)
|
|
72
|
+
.map(([role, token]) => pair(role, background, level[token] ?? '', role === 'subtle'))
|
|
73
|
+
.join(''),
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const fills = (['danger', 'warning'] as const)
|
|
77
|
+
.map((theme) => {
|
|
78
|
+
const values = tokenValues(css, `.et-color--${theme}${suffix}`);
|
|
79
|
+
|
|
80
|
+
return pairTable(
|
|
81
|
+
`.et-color--${theme}${suffix} (demo theme): on-primary on the fill`,
|
|
82
|
+
Object.entries(STATE_SUFFIX)
|
|
83
|
+
.map(([state, end]) =>
|
|
84
|
+
pair(
|
|
85
|
+
state,
|
|
86
|
+
values[`--et-color-primary${end}`] ?? '',
|
|
87
|
+
values[`--et-color-on-primary${end}`] ?? '',
|
|
88
|
+
FIXED[theme]?.includes(state as keyof typeof STATE_SUFFIX) ?? false,
|
|
89
|
+
),
|
|
90
|
+
)
|
|
91
|
+
.join(''),
|
|
92
|
+
);
|
|
93
|
+
})
|
|
94
|
+
.join('');
|
|
95
|
+
|
|
96
|
+
const ink = pairTable(
|
|
97
|
+
`Ink on the ${surface} background`,
|
|
98
|
+
(['brand', 'danger', 'warning'] as const)
|
|
99
|
+
.map((theme) =>
|
|
100
|
+
pair(
|
|
101
|
+
`${theme}${suffix}`,
|
|
102
|
+
background,
|
|
103
|
+
tokenValues(css, `.et-color--${theme}${suffix}`)['--et-color-primary-ink'] ?? '',
|
|
104
|
+
false,
|
|
105
|
+
),
|
|
106
|
+
)
|
|
107
|
+
.join(''),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return text + fills + ink;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const contrastStyles = `
|
|
114
|
+
.sdk-pairs { display: grid; grid-template-columns: 4rem auto auto auto; gap: 0.6rem 1.2rem; align-items: center; margin-top: 0.4rem; }
|
|
115
|
+
.sdk-pair { display: grid; place-items: center; width: 4rem; height: 2.8rem; border-radius: 0.4rem; border: 0.1rem solid var(--et-surface-border-solid); font-size: 1.4rem; font-weight: 600; }
|
|
116
|
+
.sdk-pair-label { font-size: 1.2rem; white-space: nowrap; }
|
|
117
|
+
.sdk-fixed { font-weight: 600; }
|
|
118
|
+
.sdk-ratio { font-size: 1.2rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
119
|
+
.sdk-ratio[data-pass='false'] { color: var(--et-surface-color-muted-solid); text-decoration: line-through; }
|
|
120
|
+
`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { definePart } from '@design-system';
|
|
2
|
+
import { ELEVATION_STATES, elevationScene, type ElevationProps } from './shared/elevation/scene';
|
|
3
|
+
import edge from './elevation.css?inline';
|
|
4
|
+
|
|
5
|
+
export default definePart<ElevationProps>({
|
|
6
|
+
note: 'How the SDK lifts things off the base surface: a card, an elevated panel and an overlay pane (the select panel mock), side by side and as a pane over a panel. Fills come from the elevated surface tokens; no background colour differs from the product. In the dark scheme a 1 px ring in --et-surface-ring-solid (24 % --et-surface-color-solid over the fill) replaces the border colour. The token is defined here; the generator does not emit it yet.',
|
|
7
|
+
madeBy: ['claude-opus-5-5'],
|
|
8
|
+
states: ELEVATION_STATES,
|
|
9
|
+
render: (props: ElevationProps) =>
|
|
10
|
+
elevationScene(props, { card: 'sdk-ring', panel: 'sdk-ring', pane: 'sdk-ring' }, edge),
|
|
11
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
.sdk-elevation {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
width: max-content;
|
|
4
|
+
padding: 4rem;
|
|
5
|
+
background: var(--et-surface-background-solid);
|
|
6
|
+
color: var(--et-surface-color-solid);
|
|
7
|
+
font-size: 1.4rem;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.sdk-elevation-row {
|
|
11
|
+
display: flex;
|
|
12
|
+
gap: 4rem;
|
|
13
|
+
align-items: flex-start;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.sdk-elevation-card,
|
|
17
|
+
.sdk-elevation-panel,
|
|
18
|
+
.sdk-elevation-pane-panel {
|
|
19
|
+
--sdk-elevation-edge: var(--et-surface-border-solid);
|
|
20
|
+
--sdk-elevation-highlight: 0 0 0 0 transparent;
|
|
21
|
+
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
border: 0.1rem solid var(--sdk-elevation-edge);
|
|
24
|
+
background: var(--et-surface-background-solid);
|
|
25
|
+
color: var(--et-surface-color-solid);
|
|
26
|
+
box-shadow: var(--sdk-elevation-highlight), var(--sdk-elevation-shadow);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.sdk-elevation-card {
|
|
30
|
+
--sdk-elevation-shadow:
|
|
31
|
+
0 0.3rem 0.8rem rgb(var(--et-shadow-color-rgb) / 0.2), 0 0.1rem 0.3rem rgb(var(--et-shadow-color-rgb) / 0.12);
|
|
32
|
+
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
gap: 0.4rem;
|
|
36
|
+
width: 20rem;
|
|
37
|
+
padding: 1.6rem;
|
|
38
|
+
border-radius: 1.2rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.sdk-elevation-panel {
|
|
42
|
+
--sdk-elevation-shadow:
|
|
43
|
+
0 0.6rem 1.2rem rgb(var(--et-shadow-color-rgb) / 0.22), 0 0.2rem 0.4rem rgb(var(--et-shadow-color-rgb) / 0.14);
|
|
44
|
+
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
gap: 0.6rem;
|
|
48
|
+
width: 28rem;
|
|
49
|
+
padding: 2rem;
|
|
50
|
+
border-radius: 1.6rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.sdk-elevation-pane-panel {
|
|
54
|
+
--sdk-elevation-shadow: var(--et-anchored-panel-shadow, 0 1rem 2.4rem rgb(var(--et-shadow-color-rgb) / 0.16));
|
|
55
|
+
|
|
56
|
+
width: 22rem;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.sdk-elevation-pane {
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
gap: 0.8rem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.sdk-elevation-label {
|
|
66
|
+
color: var(--et-surface-color-muted-solid);
|
|
67
|
+
font-size: 1.2rem;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.sdk-elevation-muted {
|
|
71
|
+
color: var(--et-surface-color-muted-solid);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.sdk-elevation-line {
|
|
75
|
+
height: 3.2rem;
|
|
76
|
+
margin-top: 0.8rem;
|
|
77
|
+
border-radius: 0.6rem;
|
|
78
|
+
background: color-mix(in srgb, var(--et-surface-interaction-solid) 12%, transparent);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.sdk-elevation-line--short {
|
|
82
|
+
width: 60%;
|
|
83
|
+
margin-top: 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.sdk-elevation-stack {
|
|
87
|
+
position: relative;
|
|
88
|
+
width: 40rem;
|
|
89
|
+
height: 30rem;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.sdk-elevation-stack .sdk-elevation-panel {
|
|
93
|
+
width: 32rem;
|
|
94
|
+
height: 22rem;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.sdk-elevation-pane--over {
|
|
98
|
+
position: absolute;
|
|
99
|
+
top: 12rem;
|
|
100
|
+
left: 16rem;
|
|
101
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { selectOption, selectPanel, selectStyles } from '@ethlete/components/design/select';
|
|
2
|
+
import { drawing, html } from '@design-system';
|
|
3
|
+
import sceneStyles from './scene.css?inline';
|
|
4
|
+
|
|
5
|
+
export type ElevationProps = { scene: 'overview' | 'stacked' };
|
|
6
|
+
|
|
7
|
+
/** The variant's class for each elevated thing. */
|
|
8
|
+
type ElevationEdges = { card: string; panel: string; pane: string };
|
|
9
|
+
|
|
10
|
+
const OPTIONS = [
|
|
11
|
+
{ value: 'drafts', label: 'Drafts' },
|
|
12
|
+
{ value: 'review', label: 'In review' },
|
|
13
|
+
{ value: 'merged', label: 'Merged' },
|
|
14
|
+
{ value: 'archived', label: 'Archived' },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const pane = (id: string, edge: string) =>
|
|
18
|
+
selectPanel({
|
|
19
|
+
id,
|
|
20
|
+
color: 'brand',
|
|
21
|
+
content: OPTIONS.map((option) =>
|
|
22
|
+
selectOption(option, {
|
|
23
|
+
id: `${id}-${option.value}`,
|
|
24
|
+
selected: option.value === 'review',
|
|
25
|
+
active: option.value === 'merged' ? 'keyboard' : undefined,
|
|
26
|
+
}),
|
|
27
|
+
).join(''),
|
|
28
|
+
}).replace(
|
|
29
|
+
'<et-select-panel class="',
|
|
30
|
+
`<et-select-panel data-et-surface-fill class="sdk-elevation-pane-panel ${edge} `,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const card = (edge: string) =>
|
|
34
|
+
html`<article class="sdk-elevation-card ${edge} et-surface--inherited" data-et-surface-fill>
|
|
35
|
+
<span class="sdk-elevation-label">Card</span>
|
|
36
|
+
<strong>Season 2026</strong>
|
|
37
|
+
<span class="sdk-elevation-muted">12 matches, 3 open</span>
|
|
38
|
+
</article>`;
|
|
39
|
+
|
|
40
|
+
const panel = (edge: string) =>
|
|
41
|
+
html`<section class="sdk-elevation-panel ${edge} et-surface--inherited" data-et-surface-fill>
|
|
42
|
+
<span class="sdk-elevation-label">Panel</span>
|
|
43
|
+
<strong>Edit match</strong>
|
|
44
|
+
<span class="sdk-elevation-muted">Kick-off, venue and referee</span>
|
|
45
|
+
<div class="sdk-elevation-line"></div>
|
|
46
|
+
<div class="sdk-elevation-line sdk-elevation-line--short"></div>
|
|
47
|
+
</section>`;
|
|
48
|
+
|
|
49
|
+
const overview = (edges: ElevationEdges) =>
|
|
50
|
+
html`<div class="sdk-elevation-row">
|
|
51
|
+
${card(edges.card)} ${panel(edges.panel)}
|
|
52
|
+
<div class="sdk-elevation-pane">
|
|
53
|
+
<span class="sdk-elevation-label">Overlay pane</span>
|
|
54
|
+
${pane('overview', edges.pane)}
|
|
55
|
+
</div>
|
|
56
|
+
</div>`;
|
|
57
|
+
|
|
58
|
+
const stacked = (edges: ElevationEdges) =>
|
|
59
|
+
html`<div class="sdk-elevation-stack">
|
|
60
|
+
${panel(edges.panel)}
|
|
61
|
+
<div class="sdk-elevation-pane sdk-elevation-pane--over">${pane('stacked', edges.pane)}</div>
|
|
62
|
+
</div>`;
|
|
63
|
+
|
|
64
|
+
/** Draws the elevated things of one scene on the base surface, each with its class from `edges`. */
|
|
65
|
+
export const elevationScene = ({ scene }: ElevationProps, edges: ElevationEdges, styles: string) =>
|
|
66
|
+
drawing({
|
|
67
|
+
body: html`<div class="sdk-elevation">${scene === 'overview' ? overview(edges) : stacked(edges)}</div>`,
|
|
68
|
+
styles: [selectStyles, sceneStyles, styles].join('\n'),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export const ELEVATION_STATES = {
|
|
72
|
+
overview: { scene: 'overview' },
|
|
73
|
+
stacked: { scene: 'stacked' },
|
|
74
|
+
} satisfies Record<string, ElevationProps>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { SDK_ICONS } from '@ethlete/components/design/icon-set';
|
|
2
|
+
import { definePart, iconSheet } from '@design-system';
|
|
3
|
+
|
|
4
|
+
const GRID = 16;
|
|
5
|
+
|
|
6
|
+
const PADDING = 1;
|
|
7
|
+
|
|
8
|
+
const svg = (body: string) =>
|
|
9
|
+
`<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`;
|
|
10
|
+
|
|
11
|
+
const FILL = 'fill="currentColor" stroke="none"';
|
|
12
|
+
|
|
13
|
+
const REDRAWN: Record<string, string> = {
|
|
14
|
+
'et-arrow-out-up-right': svg(
|
|
15
|
+
'<path d="M5.5 5.5H4A1.5 1.5 0 0 0 2.5 7v5A1.5 1.5 0 0 0 4 13.5h5a1.5 1.5 0 0 0 1.5-1.5v-1.5"/><path d="M9.5 2.5h4v4M13.5 2.5l-6 6"/>',
|
|
16
|
+
),
|
|
17
|
+
'et-arrow-right': svg('<path d="M2.5 8.5h11M9 4l4.5 4.5L9 13"/>'),
|
|
18
|
+
'et-arrow-up': svg('<path d="M8.5 13.5v-11M4 7l4.5-4.5L13 7"/>'),
|
|
19
|
+
'et-arrows-left-right': svg('<path d="M2 8.5h12M5.5 5 2 8.5 5.5 12M10.5 5 14 8.5 10.5 12"/>'),
|
|
20
|
+
'et-calendar': svg('<rect x="2.5" y="3.5" width="11" height="10" rx="1.5"/><path d="M5.5 2v3M10.5 2v3M2.5 6.5h11"/>'),
|
|
21
|
+
'et-check': svg('<path d="M2.5 8.5 6 12l7.5-7.5"/>'),
|
|
22
|
+
'et-chevron': svg('<path d="M3 10.5 8 5.5l5 5"/>'),
|
|
23
|
+
'et-circle-check': svg('<circle cx="8" cy="8" r="6.25"/><path d="M5.25 8.25 7.2 10.2 10.75 6.5"/>'),
|
|
24
|
+
'et-circle-info': svg(
|
|
25
|
+
`<circle cx="8" cy="8" r="6.25"/><path d="M8 7.25V11"/><circle cx="8" cy="4.75" r=".85" ${FILL}/>`,
|
|
26
|
+
),
|
|
27
|
+
'et-clipboard-check': svg(
|
|
28
|
+
'<path d="M5.5 3.5H4A1.5 1.5 0 0 0 2.5 5v7A1.5 1.5 0 0 0 4 13.5h8a1.5 1.5 0 0 0 1.5-1.5V5A1.5 1.5 0 0 0 12 3.5h-1.5"/><rect x="5.5" y="2" width="5" height="2.5" rx=".75"/><path d="M5.5 9 7.25 10.75 10.5 7.5"/>',
|
|
29
|
+
),
|
|
30
|
+
'et-clock': svg('<circle cx="8" cy="8" r="6.25"/><path d="M8 4.5V8l2.5 1.5"/>'),
|
|
31
|
+
'et-ellipsis': svg(
|
|
32
|
+
`<circle cx="3" cy="8" r="1.25" ${FILL}/><circle cx="8" cy="8" r="1.25" ${FILL}/><circle cx="13" cy="8" r="1.25" ${FILL}/>`,
|
|
33
|
+
),
|
|
34
|
+
'et-ellipsis-vertical': svg(
|
|
35
|
+
`<circle cx="8" cy="3" r="1.25" ${FILL}/><circle cx="8" cy="8" r="1.25" ${FILL}/><circle cx="8" cy="13" r="1.25" ${FILL}/>`,
|
|
36
|
+
),
|
|
37
|
+
'et-eye': svg(
|
|
38
|
+
'<path d="M1.75 8C3 5.5 5.25 3.5 8 3.5s5 2 6.25 4.5C13 10.5 10.75 12.5 8 12.5S3 10.5 1.75 8Z"/><circle cx="8" cy="8" r="2"/>',
|
|
39
|
+
),
|
|
40
|
+
'et-eye-slash': svg(
|
|
41
|
+
'<mask id="et-eye-slash-cut"><rect width="16" height="16" fill="#fff"/><path d="M2.5 2.5l11 11" stroke="#000" stroke-width="4.2"/></mask><g mask="url(#et-eye-slash-cut)"><path d="M1.75 8C3 5.5 5.25 3.5 8 3.5s5 2 6.25 4.5C13 10.5 10.75 12.5 8 12.5S3 10.5 1.75 8Z"/><circle cx="8" cy="8" r="2"/></g><path d="M2.5 2.5l11 11"/>',
|
|
42
|
+
),
|
|
43
|
+
'et-eyedropper': svg(
|
|
44
|
+
'<path d="M2 14l.67-.67h2l5.67-5.67"/><path d="M2.67 13.33v-2l5.67-5.67"/><path d="M10 4l1.93-1.93a1.37 1.37 0 0 1 1.93 1.93L11.93 5.93l.27.27a1.37 1.37 0 0 1-1.93 1.93l-2.4-2.4a1.37 1.37 0 0 1 1.93-1.93l.2.2Z"/>',
|
|
45
|
+
),
|
|
46
|
+
'et-file': svg(
|
|
47
|
+
'<path d="M9 2H5a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 5 14h6a1.5 1.5 0 0 0 1.5-1.5V5.5M9 2l3.5 3.5M9 2v3.5h3.5"/>',
|
|
48
|
+
),
|
|
49
|
+
'et-floppy-disk': svg(
|
|
50
|
+
'<path d="M2.5 2.5H11l2.5 2.5v7a1.5 1.5 0 0 1-1.5 1.5H4A1.5 1.5 0 0 1 2.5 12Z"/><path d="M5.5 2.5v3h4v-3M5.5 10.5h5"/>',
|
|
51
|
+
),
|
|
52
|
+
'et-focus-frame': svg(
|
|
53
|
+
`<rect x="2.5" y="2.5" width="11" height="11" rx="1.5"/><rect x="5.5" y="5.5" width="5" height="5" rx=".75" ${FILL}/>`,
|
|
54
|
+
),
|
|
55
|
+
'et-grid-2x2': svg('<rect x="2.5" y="2.5" width="11" height="11" rx="1.5"/><path d="M8 2.5v11M2.5 8h11"/>'),
|
|
56
|
+
'et-image': svg(
|
|
57
|
+
`<rect x="1.5" y="2.5" width="13" height="11" rx="1.5"/><circle cx="5.25" cy="5.75" r="1.1" ${FILL}/><path d="M3.75 11 6.5 8l1.6 1.75L10 6.5l2.25 4.5Z" ${FILL}/>`,
|
|
58
|
+
),
|
|
59
|
+
'et-location': svg(
|
|
60
|
+
'<path d="M8 14.25s-4.75-4.2-4.75-7.75a4.75 4.75 0 0 1 9.5 0c0 3.55-4.75 7.75-4.75 7.75Z"/><circle cx="8" cy="6.5" r="1.75"/>',
|
|
61
|
+
),
|
|
62
|
+
'et-lock': svg(
|
|
63
|
+
`<path d="M5.5 7.5V4.75a2.5 2.5 0 0 1 5 0V7.5"/><rect x="2.5" y="7.5" width="11" height="6" rx="1.5"/><circle cx="8" cy="10.5" r="1" ${FILL}/>`,
|
|
64
|
+
),
|
|
65
|
+
'et-minus': svg('<path d="M3.5 8.5h10"/>'),
|
|
66
|
+
'et-pause': svg(
|
|
67
|
+
`<rect x="4" y="3" width="3" height="10" rx=".75" ${FILL}/><rect x="9" y="3" width="3" height="10" rx=".75" ${FILL}/>`,
|
|
68
|
+
),
|
|
69
|
+
'et-pencil': svg(
|
|
70
|
+
'<path d="M2.5 13.5l.75-3.1L9.6 4.05a1.3 1.3 0 0 1 1.85 0l.5.5a1.3 1.3 0 0 1 0 1.85L5.6 12.75Z"/><path d="M8.5 5.25l2.25 2.25"/>',
|
|
71
|
+
),
|
|
72
|
+
'et-play': svg('<path d="M5 3.5v9l7.5-4.5Z" fill="currentColor"/>'),
|
|
73
|
+
'et-plus': svg('<path d="M8.5 3.5v10M3.5 8.5h10"/>'),
|
|
74
|
+
'et-quote': svg(
|
|
75
|
+
`<path d="M6.5 4.5C4.5 5.17 3.5 6.83 3.5 8.83V11.5H7V8H5.17c0-1.33.47-2.2 1.33-2.67Z" ${FILL}/><path d="M12.5 4.5c-2 .67-3 2.33-3 4.33v2.67H13V8h-1.83c0-1.33.47-2.2 1.33-2.67Z" ${FILL}/>`,
|
|
76
|
+
),
|
|
77
|
+
'et-redo': svg('<path d="M10 10l3.5-3.5L10 3M13.5 6.5h-7a3.5 3.5 0 0 0 0 7h2"/>'),
|
|
78
|
+
'et-rotate-right': svg(
|
|
79
|
+
'<path d="M2.75 6A5.5 5.5 0 0 1 12.25 4M13.5 2v4h-4M13.25 10A5.5 5.5 0 0 1 3.75 12M2.5 14v-4h4"/>',
|
|
80
|
+
),
|
|
81
|
+
'et-star': svg(
|
|
82
|
+
'<path d="M8 2.5l1.62 3.88 4.18.33-3.18 2.74.97 4.09L8 11.35l-3.59 2.19.97-4.09L2.2 6.71l4.18-.33Z" fill="currentColor"/>',
|
|
83
|
+
),
|
|
84
|
+
'et-thumbtack': svg('<path d="M6 2.5h4M6.75 2.5v3.75L4.5 9.5h7L9.25 6.25V2.5M8 9.5v4"/>'),
|
|
85
|
+
'et-times': svg('<path d="M4 4l8 8M12 4l-8 8"/>'),
|
|
86
|
+
'et-trash': svg(
|
|
87
|
+
'<path d="M2.5 4h11M6 4V2.75A.75.75 0 0 1 6.75 2h2.5a.75.75 0 0 1 .75.75V4M3.75 4l.7 8.75A1.25 1.25 0 0 0 5.7 14h4.6a1.25 1.25 0 0 0 1.25-1.25l.7-8.75M6.5 7v4M9.5 7v4"/>',
|
|
88
|
+
),
|
|
89
|
+
'et-triangle-exclamation': svg(
|
|
90
|
+
`<path d="M8 1.75 14.25 13.75H1.75Z"/><path d="M8 6.25v3"/><circle cx="8" cy="11.4" r=".85" ${FILL}/>`,
|
|
91
|
+
),
|
|
92
|
+
'et-trophy': svg(
|
|
93
|
+
'<path d="M4.5 2.5h7V6a3.5 3.5 0 0 1-7 0Z"/><path d="M4.5 3.5h-2v1a2.5 2.5 0 0 0 2.2 2.48M11.5 3.5h2v1a2.5 2.5 0 0 1-2.2 2.48M8 9.5v2M5 13.5h6l-.5-2h-5Z"/>',
|
|
94
|
+
),
|
|
95
|
+
'et-undo': svg('<path d="M6 10 2.5 6.5 6 3M2.5 6.5h7a3.5 3.5 0 0 1 0 7h-2"/>'),
|
|
96
|
+
'et-upload': svg(
|
|
97
|
+
'<path d="M8 10V2.5M4.5 6 8 2.5 11.5 6M2.5 10.5V12A1.5 1.5 0 0 0 4 13.5h8a1.5 1.5 0 0 0 1.5-1.5v-1.5"/>',
|
|
98
|
+
),
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const icons = SDK_ICONS.map((icon) => {
|
|
102
|
+
const name = icon.variant ? `${icon.name}--${icon.variant}` : icon.name;
|
|
103
|
+
|
|
104
|
+
return { name, svg: REDRAWN[name] ?? icon.data, grid: GRID, padding: PADDING };
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const titles = {
|
|
108
|
+
catalogue: `Icons: the ${SDK_ICONS.length} icons the SDK ships, at each size a component draws`,
|
|
109
|
+
construction: `Every icon on the ${GRID} px candidate grid: pixel lines, centre lines, and the ${PADDING} px padding`,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
type View = 'catalogue' | 'construction';
|
|
113
|
+
|
|
114
|
+
export default definePart<{ view: View }>({
|
|
115
|
+
note: "Today's look",
|
|
116
|
+
madeBy: ['claude-opus-5-5'],
|
|
117
|
+
states: { catalogue: { view: 'catalogue' }, construction: { view: 'construction' } },
|
|
118
|
+
render: ({ view }) => iconSheet({ view, title: titles[view], icons, sizes: [16, 20, 24] }),
|
|
119
|
+
});
|