@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,78 @@
|
|
|
1
|
+
import { alertDialog, dialog, dialogStyles, overlayBackdrop } from '@ethlete/components/design/dialog';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import edge from './dialog.css?inline';
|
|
4
|
+
|
|
5
|
+
type Interaction = 'hover' | 'active' | 'focus-visible';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
kind: 'dialog' | 'alert';
|
|
9
|
+
long?: boolean;
|
|
10
|
+
close?: Interaction;
|
|
11
|
+
confirm?: Interaction;
|
|
12
|
+
cancel?: Interaction;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const PANE = 'data-et-surface-fill';
|
|
16
|
+
|
|
17
|
+
const mark = (control: string, interaction?: Interaction) =>
|
|
18
|
+
[`data-et-control="${control}" data-can-animate`, interaction && `data-et-force="${interaction}"`]
|
|
19
|
+
.filter(Boolean)
|
|
20
|
+
.join(' ');
|
|
21
|
+
|
|
22
|
+
const SHORT = '<p>Kick-off moves to 18:30. Both teams and the referee get an email with the new time.</p>';
|
|
23
|
+
|
|
24
|
+
const LONG = Array.from(
|
|
25
|
+
{ length: 8 },
|
|
26
|
+
(_, index) =>
|
|
27
|
+
`<p>Round ${index + 1}: every match of this round moves by one week. Teams that already confirmed get asked again, and open predictions stay open until the new kick-off.</p>`,
|
|
28
|
+
).join('');
|
|
29
|
+
|
|
30
|
+
const render = ({ kind, long, close, confirm, cancel }: Props) =>
|
|
31
|
+
kind === 'alert'
|
|
32
|
+
? alertDialog({
|
|
33
|
+
kind: 'confirm',
|
|
34
|
+
title: 'Delete this match?',
|
|
35
|
+
message: 'The match, its result and every prediction on it are removed. This cannot be undone.',
|
|
36
|
+
confirmLabel: 'Delete',
|
|
37
|
+
confirmAttributes: mark('confirm', confirm),
|
|
38
|
+
cancelAttributes: mark('cancel', cancel),
|
|
39
|
+
attributes: PANE,
|
|
40
|
+
})
|
|
41
|
+
: dialog({
|
|
42
|
+
title: long ? 'Move the season' : 'Move kick-off',
|
|
43
|
+
body: long ? LONG : SHORT,
|
|
44
|
+
close: mark('close', close),
|
|
45
|
+
dividers: long ? 'dynamic' : false,
|
|
46
|
+
actions: [
|
|
47
|
+
{ label: 'Cancel', variant: 'outline', attributes: mark('cancel', cancel) },
|
|
48
|
+
{ label: 'Save', attributes: mark('confirm', confirm) },
|
|
49
|
+
],
|
|
50
|
+
attributes: PANE,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export default definePart({
|
|
54
|
+
note: 'Decided rules only',
|
|
55
|
+
madeBy: ['claude-opus-5-5'],
|
|
56
|
+
states: {
|
|
57
|
+
default: { kind: 'dialog' },
|
|
58
|
+
'close-hover': { kind: 'dialog', close: 'hover' },
|
|
59
|
+
'close-focus-visible': { kind: 'dialog', close: 'focus-visible' },
|
|
60
|
+
'confirm-focus-visible': { kind: 'dialog', confirm: 'focus-visible' },
|
|
61
|
+
'cancel-focus-visible': { kind: 'dialog', cancel: 'focus-visible' },
|
|
62
|
+
alert: { kind: 'alert' },
|
|
63
|
+
'alert-cancel-focus-visible': { kind: 'alert', cancel: 'focus-visible' },
|
|
64
|
+
'alert-confirm-focus-visible': { kind: 'alert', confirm: 'focus-visible' },
|
|
65
|
+
'long-body': { kind: 'dialog', long: true },
|
|
66
|
+
},
|
|
67
|
+
widths: [480],
|
|
68
|
+
controls: {
|
|
69
|
+
close: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
70
|
+
cancel: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
71
|
+
confirm: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
72
|
+
},
|
|
73
|
+
render: (props: Props) =>
|
|
74
|
+
drawing({
|
|
75
|
+
body: `<div class="dialog-frame">${overlayBackdrop(render(props))}</div>`,
|
|
76
|
+
styles: [dialogStyles, edge].join('\n'),
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.divider-frame {
|
|
2
|
+
padding: 2.4rem 1.6rem;
|
|
3
|
+
background: var(--et-surface-background-solid);
|
|
4
|
+
color: var(--et-surface-color-solid);
|
|
5
|
+
font-size: 1.4rem;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.divider-frame p {
|
|
9
|
+
margin: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.divider-frame-row {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
block-size: 2.4rem;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.divider-frame-list {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
--et-divider-inset: 16px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.divider-frame-list > span {
|
|
25
|
+
padding: 0.4rem 1.6rem;
|
|
26
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { divider, dividerStyles } from '@ethlete/components/design/divider';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import frame from './divider.css?inline';
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
set?: 'horizontal' | 'vertical' | 'list';
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const horizontal = () =>
|
|
10
|
+
`<p>Match starts at 18:00. Doors open an hour earlier.</p>${divider()}<p>Tickets are sent by email after payment.</p>`;
|
|
11
|
+
|
|
12
|
+
const vertical = () =>
|
|
13
|
+
`<div class="divider-frame-row"><span>Overview</span>${divider({ orientation: 'vertical' })}<span>Squad</span>${divider({ orientation: 'vertical', decorative: true })}<span>Fixtures</span></div>`;
|
|
14
|
+
|
|
15
|
+
const list = () =>
|
|
16
|
+
`<div class="divider-frame-list"><span>Account</span>${divider({ decorative: true })}<span>Notifications</span>${divider({ decorative: true })}<span>Privacy</span></div>`;
|
|
17
|
+
|
|
18
|
+
const body = (props: Props) => {
|
|
19
|
+
switch (props.set) {
|
|
20
|
+
case 'vertical':
|
|
21
|
+
return vertical();
|
|
22
|
+
case 'list':
|
|
23
|
+
return list();
|
|
24
|
+
default:
|
|
25
|
+
return horizontal();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default definePart({
|
|
30
|
+
note: "Today's look",
|
|
31
|
+
madeBy: ['claude-opus-5-5'],
|
|
32
|
+
states: {
|
|
33
|
+
default: {},
|
|
34
|
+
vertical: { set: 'vertical' },
|
|
35
|
+
list: { set: 'list' },
|
|
36
|
+
},
|
|
37
|
+
widths: [480],
|
|
38
|
+
render: (props: Props) =>
|
|
39
|
+
drawing({
|
|
40
|
+
body: `<div class="divider-frame">${body(props)}</div>`,
|
|
41
|
+
styles: [dividerStyles, frame].join('\n'),
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.empty-state-frame {
|
|
2
|
+
padding: 2.4rem 1.6rem;
|
|
3
|
+
background: var(--et-surface-background-solid);
|
|
4
|
+
color: var(--et-surface-color-solid);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
@layer components {
|
|
8
|
+
.et-empty-state .et-focus-ring {
|
|
9
|
+
--_et-focus-ring-color: var(--et-theme-color-ink-solid);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.et-empty-state .et-button[data-variant='filled'] {
|
|
13
|
+
--et-button-shadow: inset 0 0 0 1px var(--et-theme-color-ink-solid);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { emptyState, emptyStateStyles } from '@ethlete/components/design/empty-state';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import frame from './empty-state.css?inline';
|
|
4
|
+
|
|
5
|
+
type Interaction = 'hover' | 'active' | 'focus-visible';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
form: 'default' | 'without-action' | 'errored' | 'heading-only';
|
|
9
|
+
action?: Interaction;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const mark = (interaction?: Interaction) =>
|
|
13
|
+
[`data-et-control="action" data-can-animate`, interaction && `data-et-force="${interaction}"`]
|
|
14
|
+
.filter(Boolean)
|
|
15
|
+
.join(' ');
|
|
16
|
+
|
|
17
|
+
const COPY = {
|
|
18
|
+
default: {
|
|
19
|
+
heading: 'No results',
|
|
20
|
+
description: 'Try a different search term or clear your filters.',
|
|
21
|
+
action: 'Clear filters',
|
|
22
|
+
},
|
|
23
|
+
'without-action': { heading: 'No results', description: 'Try a different search term or clear your filters.' },
|
|
24
|
+
errored: {
|
|
25
|
+
icon: 'triangle',
|
|
26
|
+
heading: 'Something went wrong',
|
|
27
|
+
description: 'We could not load this data. Please try again.',
|
|
28
|
+
action: 'Try again',
|
|
29
|
+
},
|
|
30
|
+
'heading-only': { icon: false, heading: 'Nothing here yet' },
|
|
31
|
+
} as const;
|
|
32
|
+
|
|
33
|
+
const render = ({ form, action }: Props) => emptyState({ ...COPY[form], actionAttributes: mark(action) });
|
|
34
|
+
|
|
35
|
+
export default definePart({
|
|
36
|
+
note: 'Decided rules only',
|
|
37
|
+
madeBy: ['claude-opus-5-5'],
|
|
38
|
+
states: {
|
|
39
|
+
default: { form: 'default' },
|
|
40
|
+
'without-action': { form: 'without-action' },
|
|
41
|
+
errored: { form: 'errored' },
|
|
42
|
+
'heading-only': { form: 'heading-only' },
|
|
43
|
+
'action-hover': { form: 'default', action: 'hover' },
|
|
44
|
+
'action-active': { form: 'default', action: 'active' },
|
|
45
|
+
'action-focus-visible': { form: 'default', action: 'focus-visible' },
|
|
46
|
+
},
|
|
47
|
+
widths: [480],
|
|
48
|
+
controls: {
|
|
49
|
+
action: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
50
|
+
},
|
|
51
|
+
render: (props: Props) =>
|
|
52
|
+
drawing({
|
|
53
|
+
body: `<div class="empty-state-frame">${render(props)}</div>`,
|
|
54
|
+
styles: [emptyStateStyles, frame].join('\n'),
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
.fa-frame {
|
|
2
|
+
position: relative;
|
|
3
|
+
overflow: hidden;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
block-size: 400px;
|
|
6
|
+
transform: translate(0);
|
|
7
|
+
background: var(--et-surface-background-solid);
|
|
8
|
+
color: var(--et-surface-color-solid);
|
|
9
|
+
font-size: 1.4rem;
|
|
10
|
+
|
|
11
|
+
.fa-page {
|
|
12
|
+
padding: 2.4rem;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.et-floating-action {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
gap: 1.6rem;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
p {
|
|
22
|
+
margin: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.fa-heading {
|
|
26
|
+
margin: 0;
|
|
27
|
+
font-size: 2rem;
|
|
28
|
+
font-weight: 600;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.fa-rows {
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-direction: column;
|
|
34
|
+
gap: 0.8rem;
|
|
35
|
+
margin: 0;
|
|
36
|
+
padding: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.fa-row {
|
|
40
|
+
padding: 1.2rem;
|
|
41
|
+
border-radius: 8px;
|
|
42
|
+
background: color-mix(in srgb, var(--et-surface-color-solid) 8%, transparent);
|
|
43
|
+
list-style: none;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@layer components {
|
|
48
|
+
.et-floating-action .et-floating-action-trigger:where([data-floating-action-state='floating']) {
|
|
49
|
+
--et-button-shadow: inset 0 0 0 1px light-dark(var(--et-theme-color-ink-solid), transparent);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { floatingAction, floatingActionStyles } from '@ethlete/components/design/floating-action';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import frame from './floating-action.css?inline';
|
|
4
|
+
|
|
5
|
+
type Interaction = 'hover' | 'active' | 'focus-visible';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
state?: 'inline' | 'floating' | 'hidden';
|
|
9
|
+
interaction?: Interaction;
|
|
10
|
+
filterIcon?: boolean;
|
|
11
|
+
color?: string;
|
|
12
|
+
inset?: number;
|
|
13
|
+
overRow?: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const SCROLL = { inline: 0, floating: 236, hidden: 980 };
|
|
17
|
+
const OVER_ROW_SCROLL = 252;
|
|
18
|
+
const PARAGRAPH =
|
|
19
|
+
'Pick a competition and a season, then narrow the list down by team, venue or kick-off time to find the match you are after.';
|
|
20
|
+
|
|
21
|
+
const rows = Array.from({ length: 12 }, (_, index) => `<li class="fa-row">Result ${index + 1}</li>`).join('');
|
|
22
|
+
const paragraphs = (count: number) => Array.from({ length: count }, () => `<p>${PARAGRAPH}</p>`).join('');
|
|
23
|
+
|
|
24
|
+
const render = ({ state = 'inline', interaction, filterIcon, color, inset }: Props) =>
|
|
25
|
+
floatingAction({
|
|
26
|
+
state,
|
|
27
|
+
filterIcon,
|
|
28
|
+
trigger: { label: 'Filter (2)', color },
|
|
29
|
+
triggerAttributes: interaction ? `data-et-force="${interaction}"` : undefined,
|
|
30
|
+
heldSize: { inlineSize: filterIcon ? 132 : 104, blockSize: 40 },
|
|
31
|
+
before: `${paragraphs(2)}<h2 class="fa-heading">Results</h2>`,
|
|
32
|
+
scope: `<ul class="fa-rows">${rows}</ul>`,
|
|
33
|
+
after: paragraphs(8),
|
|
34
|
+
attributes:
|
|
35
|
+
inset === undefined
|
|
36
|
+
? undefined
|
|
37
|
+
: `style="--et-floating-action-inset-inline-end: ${inset}px; --et-floating-action-inset-block-end: ${inset}px"`,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export default definePart({
|
|
41
|
+
note: 'Q138: the floating trigger gets the Q99a 1px inset ink edge in light only, so it reaches 3:1 on a light grey row (4.68) and the page (5.48); dark unchanged.',
|
|
42
|
+
madeBy: ['claude-opus-5-5'],
|
|
43
|
+
states: {
|
|
44
|
+
inline: {},
|
|
45
|
+
floating: { state: 'floating' },
|
|
46
|
+
'floating-hover': { state: 'floating', interaction: 'hover' },
|
|
47
|
+
'floating-active': { state: 'floating', interaction: 'active' },
|
|
48
|
+
'floating-focus-visible': { state: 'floating', interaction: 'focus-visible' },
|
|
49
|
+
'inline-focus-visible': { interaction: 'focus-visible' },
|
|
50
|
+
'floating-icon': { state: 'floating', filterIcon: true },
|
|
51
|
+
'floating-inset': { state: 'floating', inset: 12 },
|
|
52
|
+
'floating-danger': { state: 'floating', color: 'danger' },
|
|
53
|
+
'floating-danger-hover': { state: 'floating', color: 'danger', interaction: 'hover' },
|
|
54
|
+
'floating-over-row': { state: 'floating', overRow: true },
|
|
55
|
+
hidden: { state: 'hidden' },
|
|
56
|
+
},
|
|
57
|
+
widths: [480],
|
|
58
|
+
render: (props: Props) =>
|
|
59
|
+
drawing({
|
|
60
|
+
body: `<div class="fa-frame" data-et-skip="CLIPPED"><div class="fa-page" style="margin-block-start: -${props.overRow ? OVER_ROW_SCROLL : SCROLL[props.state ?? 'inline']}px">${render(props)}</div></div>`,
|
|
61
|
+
styles: [floatingActionStyles, frame].join('\n'),
|
|
62
|
+
}),
|
|
63
|
+
});
|
|
@@ -16,6 +16,7 @@ type Axes = Pick<FormFieldMockOptions, 'appearance' | 'fill' | 'labelMode' | 'si
|
|
|
16
16
|
type Props = Axes & {
|
|
17
17
|
control?: FieldControl;
|
|
18
18
|
value?: string;
|
|
19
|
+
textAlign?: 'center' | 'end';
|
|
19
20
|
hint?: string;
|
|
20
21
|
error?: string;
|
|
21
22
|
focused?: boolean;
|
|
@@ -40,7 +41,7 @@ const axisRows = Object.fromEntries(
|
|
|
40
41
|
),
|
|
41
42
|
) as Record<string, Props>;
|
|
42
43
|
|
|
43
|
-
const
|
|
44
|
+
const interactive = interactionRows(
|
|
44
45
|
{
|
|
45
46
|
empty: { hint: 'Shown on your profile' },
|
|
46
47
|
filled: { value: 'Ada Lovelace' },
|
|
@@ -56,6 +57,23 @@ const { states, grid } = interactionRows(
|
|
|
56
57
|
},
|
|
57
58
|
);
|
|
58
59
|
|
|
60
|
+
const ALIGNMENTS = ['center', 'end'] as const;
|
|
61
|
+
|
|
62
|
+
const alignStates = Object.fromEntries(
|
|
63
|
+
ALIGNMENTS.map((textAlign) => [`text-align-${textAlign}`, { ...axisRow, textAlign }]),
|
|
64
|
+
) as Record<`text-align-${(typeof ALIGNMENTS)[number]}`, Props>;
|
|
65
|
+
|
|
66
|
+
const states = { ...interactive.states, ...alignStates };
|
|
67
|
+
const grid = {
|
|
68
|
+
columns: interactive.grid.columns,
|
|
69
|
+
rows: {
|
|
70
|
+
...interactive.grid.rows,
|
|
71
|
+
...Object.fromEntries(
|
|
72
|
+
ALIGNMENTS.map((textAlign) => [`textAlign ${textAlign}`, { rest: `text-align-${textAlign}` as const }]),
|
|
73
|
+
),
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
59
77
|
const markControl = (markup: string, control: FieldControl, interaction: FieldInteraction | undefined) => {
|
|
60
78
|
const frame = ['data-et-control-part', interaction && `data-et-force="${interaction}"`].filter(Boolean);
|
|
61
79
|
const native = control === 'input' ? '<input class="et-input-native"' : '<textarea class="et-textarea-native"';
|
|
@@ -67,7 +85,7 @@ const markControl = (markup: string, control: FieldControl, interaction: FieldIn
|
|
|
67
85
|
};
|
|
68
86
|
|
|
69
87
|
export default definePart<Props>({
|
|
70
|
-
note: '
|
|
88
|
+
note: 'scale of the decided shape, Q182, lead merge',
|
|
71
89
|
madeBy: ['claude-opus-5-5'],
|
|
72
90
|
states: {
|
|
73
91
|
...states,
|
|
@@ -82,14 +100,14 @@ export default definePart<Props>({
|
|
|
82
100
|
input: { kind: 'field', input: ['pointer', 'keyboard'], disabled: true },
|
|
83
101
|
textarea: { kind: 'field', input: ['pointer', 'keyboard'], disabled: true },
|
|
84
102
|
},
|
|
85
|
-
render: ({ control = 'input', value, interaction, ...field }) =>
|
|
103
|
+
render: ({ control = 'input', value, textAlign, interaction, ...field }) =>
|
|
86
104
|
drawing({
|
|
87
105
|
body: markControl(
|
|
88
106
|
formField({
|
|
89
107
|
id: 'name',
|
|
90
108
|
label: 'Name',
|
|
91
|
-
errorColor: 'danger
|
|
92
|
-
control: control === 'input' ? input({ value }) : textarea({ value }),
|
|
109
|
+
errorColor: 'danger',
|
|
110
|
+
control: control === 'input' ? input({ value, textAlign }) : textarea({ value }),
|
|
93
111
|
...field,
|
|
94
112
|
}),
|
|
95
113
|
control,
|
|
@@ -0,0 +1,17 @@
|
|
|
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-grid-item:focus-visible {
|
|
11
|
+
outline-color: var(--et-theme-color-ink-solid);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.et-grid-item-toolbar .et-focus-ring {
|
|
15
|
+
--_et-focus-ring-color: var(--et-theme-color-ink-solid);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { grid, GridMockItem, gridStyles } from '@ethlete/components/design/grid';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import frame from './grid.css?inline';
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
layout: 'rest' | 'spans';
|
|
7
|
+
actions?: boolean;
|
|
8
|
+
item?: Partial<GridMockItem> & { id: string };
|
|
9
|
+
drag?: boolean;
|
|
10
|
+
resize?: boolean;
|
|
11
|
+
longTitle?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const REST: (GridMockItem & { id: string })[] = [
|
|
15
|
+
{ id: 'revenue', col: 0, row: 0, colSpan: 2, rowSpan: 1, title: 'Revenue', subtitle: 'Last 30 days' },
|
|
16
|
+
{ id: 'visitors', col: 2, row: 0, colSpan: 2, rowSpan: 1, title: 'Visitors', subtitle: 'This week' },
|
|
17
|
+
{ id: 'orders', col: 0, row: 1, colSpan: 2, rowSpan: 1, title: 'Orders', subtitle: 'Today' },
|
|
18
|
+
{ id: 'refunds', col: 2, row: 1, colSpan: 2, rowSpan: 1, title: 'Refunds', subtitle: 'Today' },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const SPANS: (GridMockItem & { id: string })[] = [
|
|
22
|
+
{ id: 'revenue', col: 0, row: 0, colSpan: 2, rowSpan: 1, title: 'Revenue', subtitle: 'Last 30 days' },
|
|
23
|
+
{ id: 'visitors', col: 2, row: 0, colSpan: 2, rowSpan: 2, title: 'Visitors', subtitle: 'This week' },
|
|
24
|
+
{ id: 'orders', col: 0, row: 1, colSpan: 1, rowSpan: 1, title: 'Orders', subtitle: 'Today' },
|
|
25
|
+
{ id: 'refunds', col: 1, row: 1, colSpan: 1, rowSpan: 1, title: 'Refunds', subtitle: 'Today' },
|
|
26
|
+
{ id: 'activity', col: 0, row: 2, colSpan: 4, rowSpan: 1, title: 'Activity', subtitle: 'Latest events' },
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const LONG_TITLE = 'Revenue by region and sales channel';
|
|
30
|
+
|
|
31
|
+
const itemsOf = (props: Props) => {
|
|
32
|
+
const items = (props.layout === 'rest' ? REST : SPANS).map((item) =>
|
|
33
|
+
props.item?.id === item.id ? { ...item, ...props.item } : item,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
if (props.drag) {
|
|
37
|
+
return items.map((item) => {
|
|
38
|
+
if (item.id === 'orders') return { ...item, state: 'dragging' as const, offset: { x: 70, y: 18 } };
|
|
39
|
+
if (item.id === 'refunds') return { ...item, col: 0 };
|
|
40
|
+
return item;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (props.resize) {
|
|
45
|
+
return items.map((item) =>
|
|
46
|
+
item.id === 'activity' ? { ...item, rowSpan: 2, state: 'resizing' as const, activeEdge: 's' as const } : item,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (props.longTitle) return items.map((item) => (item.id === 'revenue' ? { ...item, title: LONG_TITLE } : item));
|
|
51
|
+
|
|
52
|
+
return items;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default definePart({
|
|
56
|
+
note: 'Decided rules only',
|
|
57
|
+
madeBy: ['claude-opus-5-5'],
|
|
58
|
+
states: {
|
|
59
|
+
rest: { layout: 'rest' },
|
|
60
|
+
spans: { layout: 'spans' },
|
|
61
|
+
'item-hover': { layout: 'spans', item: { id: 'visitors', force: 'hover' } },
|
|
62
|
+
'item-focus-visible': { layout: 'spans', item: { id: 'visitors', force: 'focus-visible' } },
|
|
63
|
+
actions: { layout: 'spans', actions: true },
|
|
64
|
+
'action-hover': { layout: 'spans', actions: true, item: { id: 'revenue', removeForce: 'hover' } },
|
|
65
|
+
'action-focus-visible': { layout: 'spans', actions: true, item: { id: 'revenue', removeForce: 'focus-visible' } },
|
|
66
|
+
dragging: { layout: 'spans', drag: true },
|
|
67
|
+
resizing: { layout: 'spans', resize: true },
|
|
68
|
+
'long-title': { layout: 'spans', actions: true, longTitle: true },
|
|
69
|
+
},
|
|
70
|
+
widths: [480],
|
|
71
|
+
render: (props: Props) =>
|
|
72
|
+
drawing({
|
|
73
|
+
body: `<div class="t-frame">${grid({
|
|
74
|
+
items: itemsOf(props),
|
|
75
|
+
actions: props.actions,
|
|
76
|
+
ghost: props.drag ? { col: 1, row: 1, colSpan: 1, rowSpan: 1 } : undefined,
|
|
77
|
+
})}</div>`,
|
|
78
|
+
styles: [gridStyles, frame].join('\n'),
|
|
79
|
+
}),
|
|
80
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
.t-frame {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
display: grid;
|
|
4
|
+
gap: 1.6rem;
|
|
5
|
+
padding: 1.6rem;
|
|
6
|
+
background: var(--et-surface-background-solid);
|
|
7
|
+
color: var(--et-surface-color-solid);
|
|
8
|
+
font-size: 1.4rem;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@layer components {
|
|
12
|
+
et-form-field[data-text-shell] {
|
|
13
|
+
--_et-form-field-frame-border: var(--et-surface-interaction-solid);
|
|
14
|
+
--_et-form-field-frame-border-hover: color-mix(
|
|
15
|
+
in srgb,
|
|
16
|
+
var(--et-surface-interaction-solid) 75%,
|
|
17
|
+
var(--et-surface-color-solid)
|
|
18
|
+
);
|
|
19
|
+
--_et-form-field-frame-focus: var(--et-surface-color-solid);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
et-form-field[data-text-shell][data-error] {
|
|
23
|
+
--_et-form-field-frame-border: var(--et-theme-color-primary-solid);
|
|
24
|
+
--_et-form-field-frame-border-hover: light-dark(
|
|
25
|
+
rgb(var(--et-color-primary-hover, var(--et-color-primary))),
|
|
26
|
+
rgb(
|
|
27
|
+
var(
|
|
28
|
+
--et-color-primary-ink-active,
|
|
29
|
+
var(
|
|
30
|
+
--et-color-primary-ink-focus,
|
|
31
|
+
var(
|
|
32
|
+
--et-color-primary-ink-hover,
|
|
33
|
+
var(
|
|
34
|
+
--et-color-primary-ink,
|
|
35
|
+
var(
|
|
36
|
+
--et-color-primary-active,
|
|
37
|
+
var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary)))
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
);
|
|
45
|
+
--_et-form-field-frame-focus: var(--et-theme-color-ink-solid);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
et-form-field[data-text-shell]:is([data-focused], :has(:focus-visible)):not([data-readonly])
|
|
49
|
+
.et-form-field-control-frame {
|
|
50
|
+
border-color: var(--_et-form-field-frame-focus);
|
|
51
|
+
box-shadow: inset 0 0 0 1px var(--_et-form-field-frame-focus);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
et-form-field[data-text-shell][data-readonly] .et-form-field-control-frame {
|
|
55
|
+
border-style: dashed;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
et-form-field[data-text-shell][data-readonly]:is([data-focused], :has(:focus-visible)) .et-form-field-control-frame {
|
|
59
|
+
border-color: transparent;
|
|
60
|
+
outline: 2px dashed var(--_et-form-field-frame-focus);
|
|
61
|
+
outline-offset: -2px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
et-form-field[data-text-shell] .et-form-field-prefix:not(:has(svg)) {
|
|
65
|
+
margin-inline-end: calc(4px - var(--et-form-field-control-affix-gap));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
et-form-field et-label .et-label-required-marker {
|
|
69
|
+
color: var(--et-theme-color-ink-solid);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
et-input .et-input-native::placeholder {
|
|
73
|
+
color: color-mix(in srgb, currentColor 60%, transparent);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { textInput, type TextInputMockOptions, textInputStyles } from '@ethlete/components/design/input';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import frame from './input.css?inline';
|
|
4
|
+
|
|
5
|
+
type Props = { field: TextInputMockOptions };
|
|
6
|
+
|
|
7
|
+
const email = (extra: Partial<TextInputMockOptions> = {}): Props => ({
|
|
8
|
+
field: { id: 'email', label: 'Email', placeholder: 'name@example.com', ...extra },
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const VALUE = 'lena.hoffmann@example.com';
|
|
12
|
+
|
|
13
|
+
const INVALID = {
|
|
14
|
+
required: true,
|
|
15
|
+
value: 'lena.hoffmann@',
|
|
16
|
+
error: 'Enter a valid email address.',
|
|
17
|
+
errorColor: 'danger',
|
|
18
|
+
} satisfies Partial<TextInputMockOptions>;
|
|
19
|
+
|
|
20
|
+
export default definePart({
|
|
21
|
+
note: 'scale of the decided shape, Q182, lead merge',
|
|
22
|
+
madeBy: ['claude-opus-5-5'],
|
|
23
|
+
states: {
|
|
24
|
+
empty: email({ placeholder: undefined }),
|
|
25
|
+
placeholder: email(),
|
|
26
|
+
filled: email({ value: VALUE }),
|
|
27
|
+
hover: email({ force: 'hover' }),
|
|
28
|
+
'hover-filled': email({ value: VALUE, force: 'hover' }),
|
|
29
|
+
focus: email({ focused: true, force: 'focus-visible' }),
|
|
30
|
+
'focus-filled': email({ value: VALUE, focused: true, force: 'focus-visible' }),
|
|
31
|
+
'focus-hover': email({ value: VALUE, focused: true, force: ['focus-visible', 'hover'] }),
|
|
32
|
+
hint: email({ hint: 'We only use it to sign you in.' }),
|
|
33
|
+
description: email({ description: 'Your team sees this address on your profile.' }),
|
|
34
|
+
required: email({ required: true, hint: 'We only use it to sign you in.' }),
|
|
35
|
+
invalid: email(INVALID),
|
|
36
|
+
'invalid-hover': email({ ...INVALID, force: 'hover' }),
|
|
37
|
+
'invalid-focus': email({ ...INVALID, focused: true, force: 'focus-visible' }),
|
|
38
|
+
'invalid-focus-hover': email({ ...INVALID, focused: true, force: ['focus-visible', 'hover'] }),
|
|
39
|
+
disabled: email({ disabled: true }),
|
|
40
|
+
'disabled-filled': email({ value: VALUE, disabled: true }),
|
|
41
|
+
readonly: email({ value: VALUE, readonly: true }),
|
|
42
|
+
'readonly-hover': email({ value: VALUE, readonly: true, force: 'hover' }),
|
|
43
|
+
'readonly-focus': email({ value: VALUE, readonly: true, focused: true, force: 'focus-visible' }),
|
|
44
|
+
long: email({ value: 'lena.hoffmann-schulze.marketing-department@example-company.com' }),
|
|
45
|
+
'icon-affixes': {
|
|
46
|
+
field: { id: 'key', label: 'API key', placeholder: 'sk-…', prefixIcon: 'lock', suffixIcon: 'check' },
|
|
47
|
+
},
|
|
48
|
+
'text-affixes': {
|
|
49
|
+
field: { id: 'site', label: 'Website', value: 'example.com', prefix: 'https://', suffix: '.de' },
|
|
50
|
+
},
|
|
51
|
+
'text-prefix': {
|
|
52
|
+
field: { id: 'price', label: 'Price', value: '1,250.00', prefix: '€' },
|
|
53
|
+
},
|
|
54
|
+
search: {
|
|
55
|
+
field: { id: 'search', label: 'Search', type: 'search', value: 'running shoes' },
|
|
56
|
+
},
|
|
57
|
+
password: {
|
|
58
|
+
field: { id: 'password', label: 'Password', type: 'password', value: 'correct-horse' },
|
|
59
|
+
},
|
|
60
|
+
'align-end': {
|
|
61
|
+
field: { id: 'amount', label: 'Amount', value: '1,250.00', textAlign: 'end', suffix: 'EUR' },
|
|
62
|
+
},
|
|
63
|
+
mixed: {
|
|
64
|
+
field: { id: 'title', label: 'Title', value: 'shared draft title', mixed: true, mixedLabel: 'Mixed values' },
|
|
65
|
+
},
|
|
66
|
+
'no-label': {
|
|
67
|
+
field: { id: 'quick', placeholder: 'Search…', prefixIcon: 'lock' },
|
|
68
|
+
},
|
|
69
|
+
'size-sm': email({ value: VALUE, size: 'sm' }),
|
|
70
|
+
'size-lg': email({ value: VALUE, size: 'lg' }),
|
|
71
|
+
'align-center': email({ value: VALUE, textAlign: 'center' }),
|
|
72
|
+
},
|
|
73
|
+
widths: [320, 360, 640],
|
|
74
|
+
render: (props: Props) =>
|
|
75
|
+
drawing({
|
|
76
|
+
body: `<div class="t-frame">${textInput(props.field)}</div>`,
|
|
77
|
+
styles: [textInputStyles, frame].join('\n'),
|
|
78
|
+
}),
|
|
79
|
+
});
|