@ethlete/components 1.0.0-next.78 → 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 +113 -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 +4 -1
- 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/grid.ts +148 -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 +50 -7
- 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 +23 -5
- 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.ts +1 -1
- package/design/sdk/components/select/shared/select-part.ts +16 -1
- 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/foundations/colors/colors.css +108 -4
- 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/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/fesm2022/ethlete-components.mjs +228 -187
- 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 +54 -5
- 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/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/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/types/ethlete-components.d.ts +11 -2
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { button } from '@ethlete/components/design/button';
|
|
2
|
+
import { card, cardContent, CardMockOptions, cardPlaceholderMedia, cardStyles } from '@ethlete/components/design/card';
|
|
3
|
+
import { definePart, drawing } from '@design-system';
|
|
4
|
+
import frame from './card.css?inline';
|
|
5
|
+
|
|
6
|
+
type Interaction = 'hover' | 'active' | 'focus-visible';
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
variant: NonNullable<CardMockOptions['variant']>;
|
|
10
|
+
form?: 'full' | 'media' | 'plain';
|
|
11
|
+
confirm?: Interaction;
|
|
12
|
+
cancel?: Interaction;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const mark = (control: string, interaction?: Interaction) =>
|
|
16
|
+
[`data-et-control="${control}" data-can-animate`, interaction && `data-et-force="${interaction}"`]
|
|
17
|
+
.filter(Boolean)
|
|
18
|
+
.join(' ');
|
|
19
|
+
|
|
20
|
+
const actions = ({ confirm, cancel }: Props) =>
|
|
21
|
+
`<div class="et-card-mock-actions">${[
|
|
22
|
+
button({ label: 'Cancel', variant: 'outline' }).replace(/^<button /, `<button ${mark('cancel', cancel)} `),
|
|
23
|
+
button({ label: 'Open', variant: 'filled' }).replace(/^<button /, `<button ${mark('confirm', confirm)} `),
|
|
24
|
+
].join('')}</div>`;
|
|
25
|
+
|
|
26
|
+
const content = (props: Props) => {
|
|
27
|
+
if (props.form === 'plain') return cardContent({ title: 'Revenue', text: '$12,400 this month' });
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
cardContent({
|
|
31
|
+
media: props.form === 'media' ? cardPlaceholderMedia : undefined,
|
|
32
|
+
title: 'Spring league',
|
|
33
|
+
subtitle: 'Starts 12 April',
|
|
34
|
+
text: 'Eight teams play two rounds. Sign-ups close one week before kick-off.',
|
|
35
|
+
}) + actions(props)
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default definePart({
|
|
40
|
+
note: 'Decided rules only',
|
|
41
|
+
madeBy: ['claude-opus-5-5'],
|
|
42
|
+
states: {
|
|
43
|
+
outlined: { variant: 'outlined' },
|
|
44
|
+
elevated: { variant: 'elevated' },
|
|
45
|
+
filled: { variant: 'filled' },
|
|
46
|
+
media: { variant: 'outlined', form: 'media' },
|
|
47
|
+
plain: { variant: 'outlined', form: 'plain' },
|
|
48
|
+
'confirm-focus-visible': { variant: 'outlined', confirm: 'focus-visible' },
|
|
49
|
+
'cancel-focus-visible': { variant: 'outlined', cancel: 'focus-visible' },
|
|
50
|
+
},
|
|
51
|
+
widths: [480],
|
|
52
|
+
controls: {
|
|
53
|
+
cancel: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
54
|
+
confirm: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
55
|
+
},
|
|
56
|
+
render: (props: Props) =>
|
|
57
|
+
drawing({
|
|
58
|
+
body: `<div class="card-frame">${card({ variant: props.variant, content: content(props) })}</div>`,
|
|
59
|
+
styles: [cardStyles, frame].join('\n'),
|
|
60
|
+
}),
|
|
61
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
.carousel-frame {
|
|
2
|
+
padding: 2.4rem;
|
|
3
|
+
background: var(--et-surface-background-solid);
|
|
4
|
+
color: var(--et-surface-color-solid);
|
|
5
|
+
font-size: 1.4rem;
|
|
6
|
+
|
|
7
|
+
.carousel-slide {
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
justify-content: flex-end;
|
|
11
|
+
gap: 0.4rem;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
block-size: 100%;
|
|
14
|
+
min-block-size: 200px;
|
|
15
|
+
padding: 2.4rem;
|
|
16
|
+
border-radius: 12px;
|
|
17
|
+
background: color-mix(in srgb, var(--et-surface-color-solid) 14%, transparent);
|
|
18
|
+
color: var(--et-surface-color-solid);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.carousel-slide p {
|
|
22
|
+
margin: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.carousel-slide-title {
|
|
26
|
+
font-size: 2rem;
|
|
27
|
+
font-weight: 600;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.carousel-slide-meta {
|
|
31
|
+
font-size: 1.2rem;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@layer components {
|
|
36
|
+
.et-carousel .et-focus-ring {
|
|
37
|
+
--_et-focus-ring-color: var(--et-theme-color-ink-solid);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.et-carousel .et-carousel-dot[data-active]::before,
|
|
41
|
+
.et-carousel .et-carousel-dot-progress-half::before {
|
|
42
|
+
background: light-dark(var(--et-theme-color-ink-solid), var(--et-theme-color-primary-solid));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { carousel, carouselStyles, type CarouselMockOptions } from '@ethlete/components/design/carousel';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import frame from './carousel.css?inline';
|
|
4
|
+
|
|
5
|
+
type Interaction = 'hover' | 'active' | 'focus-visible';
|
|
6
|
+
|
|
7
|
+
type Props = Omit<CarouselMockOptions, 'slides'> & {
|
|
8
|
+
count?: number;
|
|
9
|
+
longCaption?: boolean;
|
|
10
|
+
previous?: Interaction;
|
|
11
|
+
next?: Interaction;
|
|
12
|
+
playToggle?: Interaction;
|
|
13
|
+
dot?: { index: number; interaction: Interaction };
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const TITLES = ['Kick-off', 'First half', 'Half time', 'Second half', 'Full time'];
|
|
17
|
+
const LONG_CAPTION =
|
|
18
|
+
'A long caption that wraps over several lines inside the slide, the way a match report teaser runs on past a single line of text.';
|
|
19
|
+
|
|
20
|
+
const force = (interaction: Interaction | undefined) => (interaction ? `data-et-force="${interaction}"` : undefined);
|
|
21
|
+
|
|
22
|
+
const slideContent = (index: number, count: number, longCaption: boolean) =>
|
|
23
|
+
`<div class="carousel-slide"><p class="carousel-slide-title">${index + 1}. ${TITLES[index % TITLES.length]}</p>` +
|
|
24
|
+
`<p>${longCaption && index === 0 ? LONG_CAPTION : 'A short line about the slide.'}</p>` +
|
|
25
|
+
`<p class="carousel-slide-meta">slide ${index + 1} of ${count}</p></div>`;
|
|
26
|
+
|
|
27
|
+
const render = ({ count = 5, longCaption = false, previous, next, playToggle, dot, ...options }: Props) =>
|
|
28
|
+
carousel({
|
|
29
|
+
...options,
|
|
30
|
+
slides: Array.from({ length: count }, (_, index) => ({ content: slideContent(index, count, longCaption) })),
|
|
31
|
+
previousAttributes: force(previous),
|
|
32
|
+
nextAttributes: force(next),
|
|
33
|
+
playToggleAttributes: force(playToggle),
|
|
34
|
+
dotAttributes: dot ? { [dot.index]: `data-et-force="${dot.interaction}"` } : undefined,
|
|
35
|
+
trackAttributes: 'data-et-skip="CLIPPED"',
|
|
36
|
+
}).replaceAll(
|
|
37
|
+
'class="et-carousel-dot-progress-half"',
|
|
38
|
+
'data-et-skip="CLIPPED" class="et-carousel-dot-progress-half"',
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export default definePart({
|
|
42
|
+
note: 'scale of the decided shape, Q182, lead merge',
|
|
43
|
+
madeBy: ['claude-opus-5-5'],
|
|
44
|
+
states: {
|
|
45
|
+
'first-slide': {},
|
|
46
|
+
'middle-slide': { active: 2 },
|
|
47
|
+
'last-slide': { active: 4 },
|
|
48
|
+
'no-loop-first': { loop: false },
|
|
49
|
+
'no-loop-last': { loop: false, active: 4 },
|
|
50
|
+
'next-hover': { active: 2, next: 'hover' },
|
|
51
|
+
'next-active': { active: 2, next: 'active' },
|
|
52
|
+
'next-focus-visible': { active: 2, next: 'focus-visible' },
|
|
53
|
+
'dot-hover': { active: 2, dot: { index: 3, interaction: 'hover' } },
|
|
54
|
+
'active-dot-hover': { active: 2, dot: { index: 2, interaction: 'hover' } },
|
|
55
|
+
'dot-focus-visible': { active: 2, dot: { index: 3, interaction: 'focus-visible' } },
|
|
56
|
+
'active-dot-focus-visible': { active: 2, dot: { index: 2, interaction: 'focus-visible' } },
|
|
57
|
+
'autoplay-playing': { active: 1, autoplay: true },
|
|
58
|
+
'autoplay-paused': { active: 1, autoplay: true, playing: false },
|
|
59
|
+
'play-toggle-hover': { active: 1, autoplay: true, playToggle: 'hover' },
|
|
60
|
+
'play-toggle-focus-visible': { active: 1, autoplay: true, playToggle: 'focus-visible' },
|
|
61
|
+
'multiple-items': { itemSize: 'half', slideGap: 16, active: 1 },
|
|
62
|
+
'item-size-third': { itemSize: 'third', slideGap: 16, active: 1 },
|
|
63
|
+
'center-aligned': { itemSize: 'half', slideGap: 16, slideAlign: 'center', active: 2 },
|
|
64
|
+
'no-controls': { active: 1, showControls: false },
|
|
65
|
+
'long-caption': { longCaption: true },
|
|
66
|
+
'single-slide': { count: 1 },
|
|
67
|
+
},
|
|
68
|
+
widths: [480],
|
|
69
|
+
render: (props: Props) =>
|
|
70
|
+
drawing({
|
|
71
|
+
body: `<div class="carousel-frame">${render(props)}</div>`,
|
|
72
|
+
styles: [carouselStyles, frame].join('\n'),
|
|
73
|
+
}),
|
|
74
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
@layer components {
|
|
10
|
+
.et-line-chart-series,
|
|
11
|
+
.et-line-chart-slice .et-line-chart-slice-point,
|
|
12
|
+
.et-chart-legend[data-mark='line'] .et-chart-legend-swatch,
|
|
13
|
+
.et-chart-tooltip .et-chart-tooltip-key,
|
|
14
|
+
.et-line-chart-tooltip .et-line-chart-tooltip-key {
|
|
15
|
+
--_et-chart-mark-accent: color-mix(
|
|
16
|
+
in oklab,
|
|
17
|
+
light-dark(var(--et-theme-color-ink-solid), var(--et-theme-color-primary-solid)) var(--_et-chart-accent-mix, 100%),
|
|
18
|
+
var(--et-surface-background-solid, transparent)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.et-line-chart-series {
|
|
23
|
+
--_et-line-chart-color: var(--_et-chart-mark-accent);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.et-line-chart-slice .et-line-chart-slice-point {
|
|
27
|
+
fill: var(--_et-chart-mark-accent);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.et-chart-legend[data-mark='line'] .et-chart-legend-swatch,
|
|
31
|
+
.et-chart-tooltip .et-chart-tooltip-key,
|
|
32
|
+
.et-line-chart-tooltip .et-line-chart-tooltip-key {
|
|
33
|
+
background: var(--_et-chart-mark-accent);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.et-bar-chart-bar .et-bar-chart-bar-mark,
|
|
37
|
+
.et-pie-chart-slice .et-pie-chart-slice-mark {
|
|
38
|
+
stroke: var(--et-theme-color-ink-solid);
|
|
39
|
+
stroke-width: 1px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.et-chart-legend:not([data-mark='line']) .et-chart-legend-swatch,
|
|
43
|
+
.et-pie-chart-legend .et-pie-chart-legend-swatch {
|
|
44
|
+
box-shadow: inset 0 0 0 1px var(--et-theme-color-ink-solid);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.et-bar-chart-bar:focus-visible .et-bar-chart-bar-target,
|
|
48
|
+
.et-line-chart-slice:focus-visible .et-line-chart-focus-ring {
|
|
49
|
+
stroke: var(--et-theme-color-ink-solid);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.et-pie-chart-slice:focus-visible .et-pie-chart-slice-mark {
|
|
53
|
+
stroke: var(--et-theme-color-ink-solid);
|
|
54
|
+
stroke-width: 2px;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { barChart, chartStyles, ChartMockMark, lineChart, pieChart } from '@ethlete/components/design/chart';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import frame from './chart.css?inline';
|
|
4
|
+
|
|
5
|
+
type Kind = 'bar' | 'line' | 'pie';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
kind: Kind;
|
|
9
|
+
series?: boolean;
|
|
10
|
+
mark?: ChartMockMark;
|
|
11
|
+
empty?: boolean;
|
|
12
|
+
longLabel?: boolean;
|
|
13
|
+
points?: boolean;
|
|
14
|
+
donut?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
|
|
18
|
+
const LONG_MONTHS = ['January', 'February', 'March', 'April', 'May', 'June'];
|
|
19
|
+
const DAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
|
20
|
+
const BAR_2026 = { label: '2026', values: [32, 48, 41, 67, 54, 72] };
|
|
21
|
+
const BAR_2025 = { label: '2025', values: [28, 35, 44, 51, 47, 58] };
|
|
22
|
+
const VISITS = { label: 'Visits', values: [42, 55, 49, 63, 71, 38, 30] };
|
|
23
|
+
const SIGNUPS = { label: 'Sign-ups', values: [18, 24, 21, 30, 34, 15, 12] };
|
|
24
|
+
const SOURCES = [
|
|
25
|
+
{ label: 'Direct', value: 420 },
|
|
26
|
+
{ label: 'Search', value: 280 },
|
|
27
|
+
{ label: 'Social', value: 180 },
|
|
28
|
+
{ label: 'Referral', value: 120 },
|
|
29
|
+
];
|
|
30
|
+
const LONG_SOURCES = [
|
|
31
|
+
{ label: 'Direct', value: 420 },
|
|
32
|
+
{ label: 'Search engines and paid search campaigns', value: 280 },
|
|
33
|
+
{ label: 'Social', value: 180 },
|
|
34
|
+
{ label: 'Referral', value: 120 },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const PLOT_WIDTH = 410;
|
|
38
|
+
|
|
39
|
+
const render = (props: Props) => {
|
|
40
|
+
if (props.kind === 'bar') {
|
|
41
|
+
return barChart({
|
|
42
|
+
plotWidth: PLOT_WIDTH,
|
|
43
|
+
categories: props.longLabel ? LONG_MONTHS.map((month) => `${month} 2026`) : MONTHS,
|
|
44
|
+
series: props.empty ? [{ label: '2026', values: [] }] : props.series ? [BAR_2025, BAR_2026] : [BAR_2026],
|
|
45
|
+
empty: 'No sales in this period',
|
|
46
|
+
mark: props.mark,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (props.kind === 'line') {
|
|
51
|
+
return lineChart({
|
|
52
|
+
plotWidth: PLOT_WIDTH,
|
|
53
|
+
categories: DAYS,
|
|
54
|
+
series: props.series ? [VISITS, SIGNUPS] : [VISITS],
|
|
55
|
+
points: props.points,
|
|
56
|
+
mark: props.mark,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return pieChart({
|
|
61
|
+
data: props.empty ? SOURCES.map((source) => ({ ...source, value: 0 })) : props.longLabel ? LONG_SOURCES : SOURCES,
|
|
62
|
+
innerRadius: props.donut ? 0.6 : 0,
|
|
63
|
+
mark: props.mark,
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default definePart({
|
|
68
|
+
note: "The SDK charts (et-bar-chart, et-line-chart, et-pie-chart), first drawing, drawn by their mocks from @ethlete/components/design/chart with the real markup and CSS: bar, line and pie chart sheets plus the axis, grid, legend, chart tooltip and line chart tooltip sheets, and the et-tooltip pane for the open tooltip. Framed as a 480px page with 16px padding; bar and line plots 410px wide, 240px high (the default); pie 200px (the default), donut innerRadius 0.6 with its total. Single series draw in the accent; two or more in accent mix steps (100 / 40 %, pie 100 / 80 / 60 / 40 %). States: bar (Jan to Jun), bar-series (2025 and 2026, legend), bar-hover and bar-focus-visible (Apr), bar-tooltip (Mar 2025, hover with its tooltip), bar-empty (projected etBarChartEmpty text), bar-long-label (January 2026 ... June 2026: the auto label spacing thins to every second label); line, line-series (Visits and Sign-ups, legend), line-points, line-hover and line-focus-visible (Thu: crosshair, slice dots, focus box), line-tooltip (Wed, active slice with the multi-series tooltip); pie, donut, pie-hover and pie-focus-visible (Search), pie-tooltip (Direct), pie-empty (all zero: the empty ring), pie-long-label (a long legend label, ellipsed). Static snapshot: the bar grow, line reveal and slice fade are drawn at rest. The lib has no loading state. Numbers (light / dark), from shot pixels at scale 2, brand mint, a: mint marks (bars, line 1, dots, legend and tooltip keys) 1.33 / 13.50; 40 % series (bar 2026, line 2) 1.13 / 2.79; axis and legend text (muted) 7.81 / 6.94; crosshair (subtle) 4.95 / 4.99; hover and focus tint 1.07 / 1.08; focus rings: bar and line (2px, series colour / primary) 1.33 / 13.50, pie (2px, text colour) 17.93 / 17.18. Q98 numbers only: grid lines vs page 1.26 / 1.73 (as the table's edges). Decided rules that arise: Q88 (bar, line and pie focus rings), Q99a (on light the line strokes, slice dots, line legend swatches and tooltip keys take ink in their mix steps; bars, pie slices and the square legend swatches are mint fills and get a 1px ink edge). Series colours otherwise stay data colours: the mix steps are kept. Q101 does not arise: no filled button. An ink edge arises, so Q102 arises: under the brand theme the dark ink is the mint, so the edge is invisible on the full mint fill but shows as a bright outline around the 40 % series in dark (b), while c drops it there. The thinned first and last category labels sit inside the plot (lib fix 3c26c2204). Findings for later, not render refusals: the pie focus ring in b is the same ink as its new 1px edge, only 1px wider, so a focused slice reads close to rest (a used the text colour); d draws it as an outer ring instead. The pie tooltip opens over the legend. Later rounds, left out here: horizontal and stacked bars, negative values, area and stacked area, the time scale, sankey, per-series colour themes, the title and note slots, touch tap.",
|
|
69
|
+
madeBy: ['claude-opus-5-5'],
|
|
70
|
+
states: {
|
|
71
|
+
bar: { kind: 'bar' },
|
|
72
|
+
'bar-series': { kind: 'bar', series: true },
|
|
73
|
+
'bar-hover': { kind: 'bar', mark: { index: 3, force: 'hover' } },
|
|
74
|
+
'bar-focus-visible': { kind: 'bar', mark: { index: 3, force: 'focus-visible' } },
|
|
75
|
+
'bar-tooltip': { kind: 'bar', series: true, mark: { index: 4, force: 'hover', tooltip: true } },
|
|
76
|
+
'bar-empty': { kind: 'bar', empty: true },
|
|
77
|
+
'bar-long-label': { kind: 'bar', longLabel: true },
|
|
78
|
+
line: { kind: 'line' },
|
|
79
|
+
'line-series': { kind: 'line', series: true },
|
|
80
|
+
'line-points': { kind: 'line', points: true },
|
|
81
|
+
'line-hover': { kind: 'line', series: true, mark: { index: 3, force: 'hover' } },
|
|
82
|
+
'line-focus-visible': { kind: 'line', series: true, mark: { index: 3, force: 'focus-visible' } },
|
|
83
|
+
'line-tooltip': { kind: 'line', series: true, mark: { index: 2, force: 'hover', tooltip: true } },
|
|
84
|
+
pie: { kind: 'pie' },
|
|
85
|
+
donut: { kind: 'pie', donut: true },
|
|
86
|
+
'pie-hover': { kind: 'pie', mark: { index: 1, force: 'hover' } },
|
|
87
|
+
'pie-focus-visible': { kind: 'pie', mark: { index: 1, force: 'focus-visible' } },
|
|
88
|
+
'pie-tooltip': { kind: 'pie', mark: { index: 0, force: 'hover', tooltip: true } },
|
|
89
|
+
'pie-empty': { kind: 'pie', empty: true },
|
|
90
|
+
'pie-long-label': { kind: 'pie', longLabel: true },
|
|
91
|
+
},
|
|
92
|
+
widths: [480],
|
|
93
|
+
render: (props: Props) =>
|
|
94
|
+
drawing({
|
|
95
|
+
body: `<div class="t-frame">${render(props)}</div>`,
|
|
96
|
+
styles: [chartStyles, frame].join('\n'),
|
|
97
|
+
}),
|
|
98
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.chip-frame {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
padding: 2.4rem 1.6rem;
|
|
5
|
+
background: var(--et-surface-background-solid);
|
|
6
|
+
color: var(--et-surface-color-solid);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@layer components {
|
|
10
|
+
.et-chip:where([role='checkbox'], [role='radio']):focus-visible,
|
|
11
|
+
.et-chip .et-chip-remove-button:focus-visible {
|
|
12
|
+
outline-color: var(--et-theme-color-ink-solid);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.et-chip:where([aria-checked='true']) {
|
|
16
|
+
box-shadow: inset 0 0 0 1px var(--et-theme-color-ink-solid);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { chip, chipRow, chipStyles, ChipMockOptions } from '@ethlete/components/design/chip';
|
|
2
|
+
import { definePart, drawing, interactionRows } from '@design-system';
|
|
3
|
+
import frame from './chip.css?inline';
|
|
4
|
+
|
|
5
|
+
type Interaction = 'hover' | 'active' | 'focus-visible';
|
|
6
|
+
|
|
7
|
+
type Props = ChipMockOptions & { interaction?: Interaction; row?: true };
|
|
8
|
+
|
|
9
|
+
const mark = (control: string, interaction?: Interaction) =>
|
|
10
|
+
[`data-et-control="${control}" data-can-animate`, interaction && `data-et-force="${interaction}"`]
|
|
11
|
+
.filter(Boolean)
|
|
12
|
+
.join(' ');
|
|
13
|
+
|
|
14
|
+
const draw = ({ interaction, ...options }: Props) =>
|
|
15
|
+
chip({
|
|
16
|
+
...options,
|
|
17
|
+
attributes: options.selection ? mark('chip', options.removable ? undefined : interaction) : undefined,
|
|
18
|
+
removeAttributes: options.removable ? mark('remove', interaction) : undefined,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const ROW: ChipMockOptions[] = [
|
|
22
|
+
{ label: 'Bundesliga' },
|
|
23
|
+
{ label: 'U19', removable: true },
|
|
24
|
+
{ label: 'Upcoming', selection: 'checkbox' },
|
|
25
|
+
{ label: 'Live', selection: 'checkbox', selected: true },
|
|
26
|
+
{ label: 'Finished', selection: 'checkbox', selected: true, readonly: true },
|
|
27
|
+
{ label: 'Archived', selection: 'checkbox', disabled: true },
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
export const { states: rows, grid } = interactionRows<
|
|
31
|
+
Props,
|
|
32
|
+
'removable' | 'filter' | 'selected' | 'danger' | 'disabled' | 'disabled-selected' | 'disabled-removable',
|
|
33
|
+
Interaction
|
|
34
|
+
>(
|
|
35
|
+
{
|
|
36
|
+
removable: { label: 'U19', removable: true },
|
|
37
|
+
filter: { label: 'Upcoming', selection: 'checkbox' },
|
|
38
|
+
selected: { label: 'Live', selection: 'checkbox', selected: true },
|
|
39
|
+
danger: { label: 'Overdue', selection: 'checkbox', selected: true, color: 'danger' },
|
|
40
|
+
disabled: { label: 'Archived', selection: 'checkbox', disabled: true },
|
|
41
|
+
'disabled-selected': { label: 'Archived', selection: 'checkbox', selected: true, disabled: true },
|
|
42
|
+
'disabled-removable': { label: 'U19', removable: true, disabled: true },
|
|
43
|
+
},
|
|
44
|
+
{ interactions: ['hover', 'active', 'focus-visible'], force: (props, interaction) => ({ ...props, interaction }) },
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
export default definePart({
|
|
48
|
+
note: 'Decided rules only',
|
|
49
|
+
madeBy: ['claude-opus-5-5'],
|
|
50
|
+
states: {
|
|
51
|
+
...rows,
|
|
52
|
+
plain: { label: 'Bundesliga' },
|
|
53
|
+
readonly: { label: 'Finished', selection: 'checkbox', selected: true, readonly: true },
|
|
54
|
+
row: { label: '', row: true },
|
|
55
|
+
},
|
|
56
|
+
grid,
|
|
57
|
+
widths: [480],
|
|
58
|
+
contrast: {
|
|
59
|
+
exceptions: [
|
|
60
|
+
{
|
|
61
|
+
selector: '.et-chip.et-color--danger .et-chip-label',
|
|
62
|
+
reason:
|
|
63
|
+
"Hovered, the selected danger chip's 24% fill takes its ink label to 4.42:1 on light; the hover step is open in another round (Q101), not this round's question.",
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
controls: {
|
|
68
|
+
chip: { kind: 'button', input: ['pointer', 'keyboard'], disabled: true },
|
|
69
|
+
remove: { kind: 'button', input: ['pointer', 'keyboard'], disabled: true },
|
|
70
|
+
},
|
|
71
|
+
render: (props: Props) =>
|
|
72
|
+
drawing({
|
|
73
|
+
body: `<div class="chip-frame">${props.row ? chipRow(ROW.map((each) => draw(each))) : draw(props)}</div>`,
|
|
74
|
+
styles: [chipStyles, frame].join('\n'),
|
|
75
|
+
}),
|
|
76
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.copy-button-frame {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: 1.6rem;
|
|
5
|
+
padding: 2.4rem 1.6rem;
|
|
6
|
+
background: var(--et-surface-background-solid);
|
|
7
|
+
color: var(--et-surface-color-solid);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@layer components {
|
|
11
|
+
.copy-button-frame .et-focus-ring {
|
|
12
|
+
--_et-focus-ring-color: var(--et-theme-color-ink-solid);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { copyButton, copyButtonStyles } from '@ethlete/components/design/copy-button';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import frame from './copy-button.css?inline';
|
|
4
|
+
|
|
5
|
+
type Interaction = 'hover' | 'active' | 'focus-visible';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
outcome?: 'copied' | 'failed';
|
|
9
|
+
interaction?: Interaction;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
size?: 'xs' | 'sm' | 'lg' | 'xl';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const mark = (control: 'icon' | 'text', interaction?: Interaction) =>
|
|
15
|
+
[`data-et-control="${control}" data-can-animate`, interaction && `data-et-force="${interaction}"`]
|
|
16
|
+
.filter(Boolean)
|
|
17
|
+
.join(' ');
|
|
18
|
+
|
|
19
|
+
const render = ({ outcome, interaction, disabled, size }: Props) =>
|
|
20
|
+
['icon', 'text']
|
|
21
|
+
.map((kind) =>
|
|
22
|
+
copyButton({
|
|
23
|
+
kind: kind as 'icon' | 'text',
|
|
24
|
+
outcome,
|
|
25
|
+
disabled,
|
|
26
|
+
size,
|
|
27
|
+
attributes: mark(kind as 'icon' | 'text', interaction),
|
|
28
|
+
}),
|
|
29
|
+
)
|
|
30
|
+
.join('');
|
|
31
|
+
|
|
32
|
+
export default definePart({
|
|
33
|
+
note: 'scale of the decided shape, Q182, lead merge',
|
|
34
|
+
madeBy: ['claude-opus-5-5'],
|
|
35
|
+
states: {
|
|
36
|
+
idle: {},
|
|
37
|
+
copied: { outcome: 'copied' },
|
|
38
|
+
failed: { outcome: 'failed' },
|
|
39
|
+
hover: { interaction: 'hover' },
|
|
40
|
+
active: { interaction: 'active' },
|
|
41
|
+
'focus-visible': { interaction: 'focus-visible' },
|
|
42
|
+
'copied-focus-visible': { outcome: 'copied', interaction: 'focus-visible' },
|
|
43
|
+
disabled: { disabled: true },
|
|
44
|
+
'size-xs': { size: 'xs' },
|
|
45
|
+
'size-sm': { size: 'sm' },
|
|
46
|
+
'size-lg': { size: 'lg' },
|
|
47
|
+
'size-xl': { size: 'xl' },
|
|
48
|
+
},
|
|
49
|
+
widths: [480],
|
|
50
|
+
controls: {
|
|
51
|
+
icon: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
52
|
+
text: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
53
|
+
},
|
|
54
|
+
render: (props: Props) =>
|
|
55
|
+
drawing({
|
|
56
|
+
body: `<div class="copy-button-frame">${render(props)}</div>`,
|
|
57
|
+
styles: [copyButtonStyles, frame].join('\n'),
|
|
58
|
+
}),
|
|
59
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
descriptionList,
|
|
3
|
+
descriptionListStyles,
|
|
4
|
+
type DescriptionListMockItem,
|
|
5
|
+
} from '@ethlete/components/design/description-list';
|
|
6
|
+
import { definePart, drawing } from '@design-system';
|
|
7
|
+
import frame from './description-list.css?inline';
|
|
8
|
+
|
|
9
|
+
type Props = {
|
|
10
|
+
variant?: 'inline' | 'stacked';
|
|
11
|
+
items?: DescriptionListMockItem[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const STORY: DescriptionListMockItem[] = [
|
|
15
|
+
{ term: 'Name', detail: 'Jane Doe' },
|
|
16
|
+
{ term: 'Email', detail: 'jane@example.com' },
|
|
17
|
+
{ term: 'Role', detail: 'Administrator' },
|
|
18
|
+
{ term: 'Notes', detail: 'Joined during the private beta and has opted into every early-access feature flag.' },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const LONG: DescriptionListMockItem[] = [
|
|
22
|
+
{ term: 'Name', detail: 'Jane Doe' },
|
|
23
|
+
{ term: 'Profile URL', detail: 'https://example.com/organisations/ethlete/members/jane-doe-administrator-0042' },
|
|
24
|
+
{ term: 'Billing contact for invoices', detail: 'accounts-payable@example.com' },
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const EMPTY: DescriptionListMockItem[] = [
|
|
28
|
+
{ term: 'Name', detail: 'Jane Doe' },
|
|
29
|
+
{ term: 'Phone', detail: '' },
|
|
30
|
+
{ term: 'Role', detail: 'Administrator' },
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const GROUPED: DescriptionListMockItem[] = STORY.map((item) => ({ ...item, grouped: true }));
|
|
34
|
+
|
|
35
|
+
export default definePart({
|
|
36
|
+
note: "Today's look",
|
|
37
|
+
madeBy: ['claude-opus-5-5'],
|
|
38
|
+
states: {
|
|
39
|
+
default: {},
|
|
40
|
+
stacked: { variant: 'stacked' },
|
|
41
|
+
'long-value': { items: LONG },
|
|
42
|
+
'long-value-stacked': { items: LONG, variant: 'stacked' },
|
|
43
|
+
'empty-value': { items: EMPTY },
|
|
44
|
+
grouped: { items: GROUPED },
|
|
45
|
+
'grouped-stacked': { items: GROUPED, variant: 'stacked' },
|
|
46
|
+
},
|
|
47
|
+
widths: [480],
|
|
48
|
+
render: ({ variant, items = STORY }: Props) =>
|
|
49
|
+
drawing({
|
|
50
|
+
body: `<div class="description-list-frame">${descriptionList({ items, variant })}</div>`,
|
|
51
|
+
styles: [descriptionListStyles, frame].join('\n'),
|
|
52
|
+
}),
|
|
53
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
.dialog-frame {
|
|
2
|
+
overflow: hidden;
|
|
3
|
+
background: var(--et-surface-background-solid);
|
|
4
|
+
color: var(--et-surface-color-solid);
|
|
5
|
+
font-size: 1.4rem;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.dialog-frame .et-overlay--dialog {
|
|
9
|
+
inline-size: 100%;
|
|
10
|
+
max-inline-size: 51.2rem;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.dialog-frame .et-overlay--dialog:has(.et-overlay-body--dynamic-dividers) {
|
|
14
|
+
max-block-size: 36rem;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.dialog-frame .et-overlay-body p {
|
|
18
|
+
margin: 0 0 1.2rem;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@layer components {
|
|
22
|
+
.et-overlay--dialog .et-focus-ring {
|
|
23
|
+
--_et-focus-ring-color: var(--et-theme-color-ink-solid);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.et-overlay--dialog .et-button[data-variant='filled'] {
|
|
27
|
+
--et-button-shadow: inset 0 0 0 1px var(--et-theme-color-ink-solid);
|
|
28
|
+
}
|
|
29
|
+
}
|