@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,218 @@
|
|
|
1
|
+
import iconButtonBase from '../src/lib/button/icon-button.component.css?inline';
|
|
2
|
+
import { CHEVRON_ICON } from '../src/lib/icon/headless/chevron-icon';
|
|
3
|
+
import iconBase from '../src/lib/icon/headless/icon-styles.component.css?inline';
|
|
4
|
+
import buttonsBase from '../src/lib/scrollable/headless/scrollable-buttons.component.css?inline';
|
|
5
|
+
import footerBase from '../src/lib/scrollable/headless/scrollable-footer.css?inline';
|
|
6
|
+
import masksBase from '../src/lib/scrollable/headless/scrollable-masks.component.css?inline';
|
|
7
|
+
import navigationBase from '../src/lib/scrollable/headless/scrollable-navigation.component.css?inline';
|
|
8
|
+
import scrollableBase from '../src/lib/scrollable/scrollable.component.css?inline';
|
|
9
|
+
import { buttonStyles } from './button';
|
|
10
|
+
import { iconMarkup } from './icon';
|
|
11
|
+
|
|
12
|
+
export type ScrollableMockItem = {
|
|
13
|
+
/** The item's inner HTML. */
|
|
14
|
+
content: string;
|
|
15
|
+
/** Extra attributes on the item, e.g. a class, a style or design markers. */
|
|
16
|
+
attributes?: string;
|
|
17
|
+
/** The tag the consumer projects. Left out, `div`. */
|
|
18
|
+
tag?: string;
|
|
19
|
+
/** Draws `et-scrollable-item--not-intersecting`, as `etScrollableDarken` does for an item out of view. */
|
|
20
|
+
notIntersecting?: boolean;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type ScrollableMockOptions = {
|
|
24
|
+
items: ScrollableMockItem[];
|
|
25
|
+
direction?: 'horizontal' | 'vertical';
|
|
26
|
+
/** Draws `et-scrollable--can-scroll`. Left out, the content overflows. */
|
|
27
|
+
canScroll?: boolean;
|
|
28
|
+
/** The scroll position the directive reads: it decides the start and end classes. Left out, `start`. */
|
|
29
|
+
position?: 'start' | 'middle' | 'end';
|
|
30
|
+
/** Draws `et-scrollable--has-partial-items`. Left out, true while the content can scroll and masks render. */
|
|
31
|
+
partialItems?: boolean;
|
|
32
|
+
/** Left out, the masks render, as `renderMasks` defaults to. */
|
|
33
|
+
renderMasks?: boolean;
|
|
34
|
+
maskVariant?: 'gradient' | 'border';
|
|
35
|
+
/** Where `etScrollableButtons` renders its buttons. Left out, no buttons. */
|
|
36
|
+
buttons?: 'inside' | 'footer';
|
|
37
|
+
stickyButtons?: boolean;
|
|
38
|
+
/** Extra attributes on the start button, e.g. design markers. */
|
|
39
|
+
startButtonAttributes?: string;
|
|
40
|
+
/** Extra attributes on the end button, e.g. design markers. */
|
|
41
|
+
endButtonAttributes?: string;
|
|
42
|
+
/** The dot index `etScrollableNavigation` marks active. Left out, no navigation. */
|
|
43
|
+
navigationActive?: number;
|
|
44
|
+
/** Draws `et-scrollable--darken-non-intersecting-items`, as `etScrollableDarken` does. */
|
|
45
|
+
darken?: boolean;
|
|
46
|
+
/** Draws the `snap` attributes `etScrollableSnap` sets. */
|
|
47
|
+
snap?: boolean;
|
|
48
|
+
/** A color theme name the app registers. Left out, the scrollable takes the color theme around it. */
|
|
49
|
+
color?: string;
|
|
50
|
+
/** The `itemSize` the scrollable lays its items out with. Left out, `auto`. */
|
|
51
|
+
itemSize?: 'auto' | 'same' | 'full' | 'half' | 'third' | 'quarter';
|
|
52
|
+
/** The gap between the items in px, as the directive reads it from the container. Left out, 0. */
|
|
53
|
+
itemGap?: number;
|
|
54
|
+
/** Extra classes on the host, e.g. the class a wrapping component puts on it. */
|
|
55
|
+
class?: string;
|
|
56
|
+
/** Extra attributes on the host, e.g. a style or design markers. */
|
|
57
|
+
attributes?: string;
|
|
58
|
+
/** Extra attributes on the scroll container, e.g. a style that offsets it to a scrolled position. */
|
|
59
|
+
containerAttributes?: string;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/** The stylesheets `scrollable()` draws with: the real scrollable, masks, buttons, navigation and icon-button CSS. */
|
|
63
|
+
export const scrollableStyles = /* @__PURE__ */ [
|
|
64
|
+
buttonStyles,
|
|
65
|
+
iconBase,
|
|
66
|
+
iconButtonBase,
|
|
67
|
+
scrollableBase,
|
|
68
|
+
masksBase,
|
|
69
|
+
buttonsBase,
|
|
70
|
+
navigationBase,
|
|
71
|
+
footerBase,
|
|
72
|
+
].join('\n');
|
|
73
|
+
|
|
74
|
+
type ScrollButtonOptions = { edge: 'start' | 'end'; disabled: boolean; attributes?: string };
|
|
75
|
+
|
|
76
|
+
const scrollButton = ({ edge, disabled, attributes }: ScrollButtonOptions) => {
|
|
77
|
+
const classes = [
|
|
78
|
+
'et-scrollable-button',
|
|
79
|
+
`et-scrollable-button--${edge}`,
|
|
80
|
+
'et-icon-button',
|
|
81
|
+
'et-color-interactive',
|
|
82
|
+
'et-focus-ring',
|
|
83
|
+
'et-color--inherited',
|
|
84
|
+
];
|
|
85
|
+
const host = [
|
|
86
|
+
attributes,
|
|
87
|
+
disabled && 'disabled aria-disabled="true"',
|
|
88
|
+
`class="${classes.join(' ')}"`,
|
|
89
|
+
'aria-hidden="true"',
|
|
90
|
+
'type="button"',
|
|
91
|
+
'tabindex="-1"',
|
|
92
|
+
'data-variant="transparent"',
|
|
93
|
+
'data-size="xs"',
|
|
94
|
+
].filter(Boolean);
|
|
95
|
+
|
|
96
|
+
return `<button ${host.join(' ')}><div class="et-icon-button-icon">${iconMarkup(CHEVRON_ICON)}</div></button>`;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
type NavigationOptions = { count: number; active: number; horizontal: boolean };
|
|
100
|
+
|
|
101
|
+
const navigation = ({ count, active, horizontal }: NavigationOptions) => {
|
|
102
|
+
const offset = count > 5 ? (active < 3 ? 0 : active >= count - 3 ? 5 - count : -(active - 2)) * 20 : 0;
|
|
103
|
+
const dots = Array.from({ length: count }, (_, index) => {
|
|
104
|
+
const distance = Math.abs(index - active);
|
|
105
|
+
const classes = [
|
|
106
|
+
'et-scrollable-navigation-item',
|
|
107
|
+
distance === 0 && 'et-scrollable-navigation-item--active',
|
|
108
|
+
distance === 1 && 'et-scrollable-navigation-item--close',
|
|
109
|
+
distance > 1 && 'et-scrollable-navigation-item--far',
|
|
110
|
+
].filter(Boolean);
|
|
111
|
+
|
|
112
|
+
return `<button active-offset="${distance}" class="${classes.join(' ')}" type="button" tabindex="-1" aria-hidden="true"></button>`;
|
|
113
|
+
}).join('');
|
|
114
|
+
|
|
115
|
+
const container = [
|
|
116
|
+
'class="et-scrollable-dots-container"',
|
|
117
|
+
`style="transform: translate${horizontal ? 'X' : 'Y'}(${offset}px)"`,
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
`<et-scrollable-navigation class="et-scrollable-navigation" aria-hidden="true"><div class="et-scrollable-progress-bar">` +
|
|
122
|
+
`<div ${container.join(' ')}>${dots}</div>` +
|
|
123
|
+
`</div></et-scrollable-navigation>`
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Draws `<et-scrollable>` as HTML: the scroll container with its observer elements and the projected items, the
|
|
129
|
+
* edge masks, and the buttons and navigation dots its feature directives contribute. A scrolled position is
|
|
130
|
+
* drawn by offsetting the container's content statically through `containerAttributes`.
|
|
131
|
+
*/
|
|
132
|
+
export const scrollable = (options: ScrollableMockOptions) => {
|
|
133
|
+
const direction = options.direction ?? 'horizontal';
|
|
134
|
+
const canScroll = options.canScroll ?? true;
|
|
135
|
+
const position = canScroll ? (options.position ?? 'start') : 'start';
|
|
136
|
+
const renderMasks = options.renderMasks ?? true;
|
|
137
|
+
const atStart = !canScroll || position === 'start';
|
|
138
|
+
const atEnd = !canScroll || position === 'end';
|
|
139
|
+
const hasNavigation = options.navigationActive !== undefined;
|
|
140
|
+
|
|
141
|
+
const classes = [
|
|
142
|
+
'et-scrollable',
|
|
143
|
+
`et-color--${options.color ?? 'inherited'}`,
|
|
144
|
+
canScroll && 'et-scrollable--can-scroll',
|
|
145
|
+
atStart && 'et-scrollable--is-at-start',
|
|
146
|
+
atEnd && 'et-scrollable--is-at-end',
|
|
147
|
+
(options.partialItems ?? (canScroll && renderMasks)) && 'et-scrollable--has-partial-items',
|
|
148
|
+
options.darken && 'et-scrollable--darken-non-intersecting-items',
|
|
149
|
+
options.stickyButtons && options.buttons === 'inside' && 'et-scrollable--sticky-buttons',
|
|
150
|
+
options.class,
|
|
151
|
+
].filter(Boolean);
|
|
152
|
+
|
|
153
|
+
const host = [
|
|
154
|
+
options.attributes,
|
|
155
|
+
`class="${classes.join(' ')}"`,
|
|
156
|
+
`item-size="${options.itemSize ?? 'auto'}"`,
|
|
157
|
+
`direction="${direction}"`,
|
|
158
|
+
options.snap && 'snap="" snap-origin="auto"',
|
|
159
|
+
`mask-variant="${options.maskVariant ?? 'gradient'}"`,
|
|
160
|
+
`style="--item-count: ${options.items.length}; --item-gap: ${options.itemGap ?? 0}px; --_et-scrollable-scroll-margin: 0px"`,
|
|
161
|
+
].filter(Boolean);
|
|
162
|
+
|
|
163
|
+
const itemMarkup = options.items
|
|
164
|
+
.map((item) => {
|
|
165
|
+
const tag = item.tag ?? 'div';
|
|
166
|
+
const itemClasses = ['et-scrollable-item', item.notIntersecting && 'et-scrollable-item--not-intersecting'].filter(
|
|
167
|
+
Boolean,
|
|
168
|
+
);
|
|
169
|
+
const attributes = item.attributes ?? '';
|
|
170
|
+
const merged = /\bclass="/.test(attributes)
|
|
171
|
+
? attributes.replace(/\bclass="/, `class="${itemClasses.join(' ')} `)
|
|
172
|
+
: `${attributes} class="${itemClasses.join(' ')}"`;
|
|
173
|
+
|
|
174
|
+
return `<${tag} ${merged.trim()}>${item.content}</${tag}>`;
|
|
175
|
+
})
|
|
176
|
+
.join('');
|
|
177
|
+
|
|
178
|
+
const buttons = (slot: 'overlay' | 'footer') =>
|
|
179
|
+
`<et-scrollable-buttons class="et-scrollable-buttons et-scrollable-buttons--${slot === 'footer' ? 'footer' : 'inside'}">` +
|
|
180
|
+
scrollButton({ edge: 'start', disabled: atStart, attributes: options.startButtonAttributes }) +
|
|
181
|
+
scrollButton({ edge: 'end', disabled: atEnd, attributes: options.endButtonAttributes }) +
|
|
182
|
+
`</et-scrollable-buttons>`;
|
|
183
|
+
|
|
184
|
+
const footerParts = [
|
|
185
|
+
options.buttons === 'footer' && buttons('footer'),
|
|
186
|
+
hasNavigation &&
|
|
187
|
+
navigation({
|
|
188
|
+
count: options.items.length,
|
|
189
|
+
active: options.navigationActive ?? 0,
|
|
190
|
+
horizontal: direction === 'horizontal',
|
|
191
|
+
}),
|
|
192
|
+
].filter(Boolean);
|
|
193
|
+
|
|
194
|
+
const footerClasses = [
|
|
195
|
+
'et-scrollable-footer',
|
|
196
|
+
hasNavigation && 'et-scrollable-footer--with-navigation',
|
|
197
|
+
options.buttons === 'footer' && 'et-scrollable-footer--with-buttons',
|
|
198
|
+
].filter(Boolean);
|
|
199
|
+
|
|
200
|
+
const footer =
|
|
201
|
+
footerParts.length && canScroll
|
|
202
|
+
? `<div class="${footerClasses.join(' ')}" aria-hidden="true">${footerParts.join('')}</div>`
|
|
203
|
+
: '';
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
`<et-scrollable ${host.join(' ')}><div class="et-scrollable-wrapper" role="presentation">` +
|
|
207
|
+
`<div class="et-scrollable-container" ${options.containerAttributes ?? ''}>` +
|
|
208
|
+
`<div class="et-scroll-observer-first-element" etscrollableignorechild=""></div>` +
|
|
209
|
+
itemMarkup +
|
|
210
|
+
`<div class="et-scroll-observer-last-element" etscrollableignorechild=""></div>` +
|
|
211
|
+
`</div>` +
|
|
212
|
+
(renderMasks
|
|
213
|
+
? `<et-scrollable-masks class="et-scrollable-masks"><div class="et-scrollable-mask et-scrollable-mask--start"></div><div class="et-scrollable-mask et-scrollable-mask--end"></div></et-scrollable-masks>`
|
|
214
|
+
: '') +
|
|
215
|
+
(options.buttons === 'inside' ? buttons('overlay') : '') +
|
|
216
|
+
`</div>${footer}</et-scrollable>`
|
|
217
|
+
);
|
|
218
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import scrollbarBase from '../src/lib/scrollbar/scrollbar.component.css?inline';
|
|
2
|
+
|
|
3
|
+
export type ScrollbarMockOptions = {
|
|
4
|
+
orientation?: 'vertical' | 'horizontal';
|
|
5
|
+
/** The thumb length in px, as the directive computes it from the container's scroll size. */
|
|
6
|
+
thumbSize: number;
|
|
7
|
+
/** The thumb distance from the track start in px, as the directive computes it from the scroll position. */
|
|
8
|
+
thumbOffset?: number;
|
|
9
|
+
/** Draws the `et-scrollbar--visible` class. Left out, visible, as without `autoHide`. */
|
|
10
|
+
visible?: boolean;
|
|
11
|
+
/** Draws the `et-scrollbar--dragging` class, as while the thumb is held. */
|
|
12
|
+
dragging?: boolean;
|
|
13
|
+
/** Draws the host's `data-direction="rtl"`, read off a right-to-left container. */
|
|
14
|
+
rtl?: boolean;
|
|
15
|
+
/** Extra attributes on the host, e.g. a style or design markers. */
|
|
16
|
+
attributes?: string;
|
|
17
|
+
/** Extra attributes on the thumb, e.g. design markers. */
|
|
18
|
+
thumbAttributes?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** The stylesheets `scrollbar()` draws with: the real scrollbar CSS. */
|
|
22
|
+
export const scrollbarStyles = /* @__PURE__ */ [scrollbarBase].join('\n');
|
|
23
|
+
|
|
24
|
+
/** The class the directive puts on the scroll container to hide its native scrollbar. */
|
|
25
|
+
export const scrollbarHostClass = 'et-scrollbar-host';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Draws `<et-scrollbar>` as HTML: the track over the end edge of its positioned wrapper and the thumb at the given
|
|
29
|
+
* size and offset. Place it next to a container with `scrollbarHostClass` inside a `position: relative` wrapper.
|
|
30
|
+
*/
|
|
31
|
+
export const scrollbar = (options: ScrollbarMockOptions) => {
|
|
32
|
+
const classes = [
|
|
33
|
+
'et-scrollbar',
|
|
34
|
+
(options.visible ?? true) && 'et-scrollbar--visible',
|
|
35
|
+
options.dragging && 'et-scrollbar--dragging',
|
|
36
|
+
].filter(Boolean);
|
|
37
|
+
const host = [
|
|
38
|
+
options.attributes,
|
|
39
|
+
`class="${classes.join(' ')}"`,
|
|
40
|
+
`data-orientation="${options.orientation ?? 'vertical'}"`,
|
|
41
|
+
options.rtl && 'data-direction="rtl"',
|
|
42
|
+
`style="--_et-scrollbar-thumb-size: ${options.thumbSize}px; --_et-scrollbar-thumb-offset: ${options.thumbOffset ?? 0}px"`,
|
|
43
|
+
].filter(Boolean);
|
|
44
|
+
const thumb = [options.thumbAttributes, 'class="et-scrollbar-thumb"', 'etscrollbarthumb=""'].filter(Boolean);
|
|
45
|
+
|
|
46
|
+
return `<et-scrollbar ${host.join(' ')}><div ${thumb.join(' ')}></div></et-scrollbar>`;
|
|
47
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" width="800" height="450" viewBox="0 0 800 450"><rect width="100%" height="100%" fill="#ffd000"/><text x="50%" y="50%" fill="#000" font-family="sans-serif" font-size="24" text-anchor="middle" dominant-baseline="middle">fallback</text></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" width="450" height="600" viewBox="0 0 450 600"><rect width="100%" height="100%" fill="#00d0ff"/><text x="50%" y="50%" fill="#000" font-family="sans-serif" font-size="24" text-anchor="middle" dominant-baseline="middle">tall 3:4</text></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" width="800" height="450" viewBox="0 0 800 450"><rect width="100%" height="100%" fill="#00ffa1"/><text x="50%" y="50%" fill="#000" font-family="sans-serif" font-size="24" text-anchor="middle" dominant-baseline="middle">wide 16:9</text></svg>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.accent-on-light {
|
|
3
|
+
display: grid;
|
|
4
|
+
gap: 20px;
|
|
5
|
+
padding: 16px;
|
|
6
|
+
justify-items: start;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.accent-on-light-row {
|
|
10
|
+
display: flex;
|
|
11
|
+
gap: 16px;
|
|
12
|
+
align-items: center;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.accent-on-light et-radio[aria-checked='true'] .et-radio-circle {
|
|
16
|
+
border-color: var(--et-theme-color-ink-solid);
|
|
17
|
+
|
|
18
|
+
&::after {
|
|
19
|
+
background-color: var(--et-theme-color-ink-solid);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.accent-on-light .et-selection-card:is([aria-checked='true'], :has([aria-checked='true'], [aria-checked='mixed'])) {
|
|
24
|
+
border-color: var(--et-theme-color-ink-solid);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.accent-on-light et-checkbox:is([aria-checked='true'], [aria-checked='mixed']) .et-checkbox-box {
|
|
28
|
+
border-color: var(--et-theme-color-ink-solid);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.accent-on-light et-switch[aria-checked='true'] .et-switch-track,
|
|
32
|
+
.accent-on-light et-segmented-button[aria-checked='true'] .et-segmented-button-bg {
|
|
33
|
+
box-shadow: inset 0 0 0 1px var(--et-theme-color-ink-solid);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { definePart, drawing } from '@design-system';
|
|
2
|
+
import { controls } from './shared/controls';
|
|
3
|
+
import styles from './accent-on-light.css?inline';
|
|
4
|
+
|
|
5
|
+
export default definePart({
|
|
6
|
+
note: 'The brand mint on light controls: checkbox checked, mixed and off, switch on, a radio group, a segmented button group and a choice-field card, drawn by the real components under one accent rule.',
|
|
7
|
+
madeBy: ['claude-opus-5-5'],
|
|
8
|
+
states: { default: {} },
|
|
9
|
+
render: async () => drawing({ body: await controls(), styles }),
|
|
10
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ng } from '@design-system';
|
|
2
|
+
|
|
3
|
+
export const controls = () =>
|
|
4
|
+
ng(
|
|
5
|
+
`<div class="accent-on-light et-color--brand">
|
|
6
|
+
<div class="accent-on-light-row">
|
|
7
|
+
<et-checkbox [formField]="fields.checked" aria-label="Checked" />
|
|
8
|
+
<et-checkbox [formField]="fields.mixed" [indeterminate]="true" aria-label="Mixed" />
|
|
9
|
+
<et-checkbox [formField]="fields.unchecked" aria-label="Unchecked" />
|
|
10
|
+
<et-switch [formField]="fields.on" aria-label="On" />
|
|
11
|
+
</div>
|
|
12
|
+
<et-radio-group [formField]="fields.plan">
|
|
13
|
+
<et-label>Plan</et-label>
|
|
14
|
+
<et-radio value="free">Free</et-radio>
|
|
15
|
+
<et-radio value="pro">Pro</et-radio>
|
|
16
|
+
</et-radio-group>
|
|
17
|
+
<et-segmented-button-group [formField]="fields.view">
|
|
18
|
+
<et-label>View</et-label>
|
|
19
|
+
<et-segmented-button value="list">List</et-segmented-button>
|
|
20
|
+
<et-segmented-button value="grid">Grid</et-segmented-button>
|
|
21
|
+
</et-segmented-button-group>
|
|
22
|
+
<et-choice-field variant="card">
|
|
23
|
+
<et-checkbox [formField]="fields.digest" />
|
|
24
|
+
<et-label>Weekly digest</et-label>
|
|
25
|
+
</et-choice-field>
|
|
26
|
+
</div>`,
|
|
27
|
+
{
|
|
28
|
+
imports: [
|
|
29
|
+
'CHECKBOX_IMPORTS',
|
|
30
|
+
'SWITCH_IMPORTS',
|
|
31
|
+
'RADIO_GROUP_IMPORTS',
|
|
32
|
+
'SEGMENTED_BUTTON_IMPORTS',
|
|
33
|
+
'CHOICE_FIELD_IMPORTS',
|
|
34
|
+
'FORM_FIELD_IMPORTS',
|
|
35
|
+
],
|
|
36
|
+
fields: {
|
|
37
|
+
checked: { value: true },
|
|
38
|
+
mixed: { value: false },
|
|
39
|
+
unchecked: { value: false },
|
|
40
|
+
on: { value: true },
|
|
41
|
+
plan: { value: 'pro' },
|
|
42
|
+
view: { value: 'list' },
|
|
43
|
+
digest: { value: true },
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.accordion-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
|
+
.accordion-text {
|
|
9
|
+
margin: 0;
|
|
10
|
+
line-height: 1.5;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@layer components {
|
|
14
|
+
.et-accordion-trigger:focus-visible {
|
|
15
|
+
outline-color: var(--et-theme-color-ink-solid);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { accordionGroup, AccordionMockItem, accordionStyles } from '@ethlete/components/design/accordion';
|
|
2
|
+
import { definePart, drawing } from '@design-system';
|
|
3
|
+
import frame from './accordion.css?inline';
|
|
4
|
+
|
|
5
|
+
type Interaction = 'hover' | 'active' | 'focus-visible';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
open?: boolean;
|
|
9
|
+
shipping?: Interaction;
|
|
10
|
+
archive?: Interaction;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const mark = (control: string, interaction?: Interaction) =>
|
|
14
|
+
[`data-et-control="${control}"`, interaction && `data-et-force="${interaction}"`].filter(Boolean).join(' ');
|
|
15
|
+
|
|
16
|
+
const items = (props: Props): AccordionMockItem[] => [
|
|
17
|
+
{
|
|
18
|
+
label: 'Match rules',
|
|
19
|
+
content: '<p class="accordion-text">Two halves of 20 minutes. A draw after extra time goes to penalties.</p>',
|
|
20
|
+
open: props.open,
|
|
21
|
+
triggerAttributes: mark('rules'),
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: 'Shipping',
|
|
25
|
+
hint: '3 options',
|
|
26
|
+
content: '<p class="accordion-text">Standard, express and pick-up at the venue.</p>',
|
|
27
|
+
triggerAttributes: mark('shipping', props.shipping),
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
label: 'Payment',
|
|
31
|
+
content: '<p class="accordion-text">Card, PayPal or invoice.</p>',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
label: 'Archive',
|
|
35
|
+
hint: 'Closed',
|
|
36
|
+
content: '<p class="accordion-text">Past seasons.</p>',
|
|
37
|
+
disabled: true,
|
|
38
|
+
triggerAttributes: mark('archive', props.archive),
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
export default definePart({
|
|
43
|
+
note: 'The SDK accordion (et-accordion in an et-accordion-group), drawn by its mock from @ethlete/components/design: a 500-weight header with an optional muted hint and a 14px chevron in the muted surface text, a 1px surface-border divider under every item but the last, a 7 % interaction tint on header hover (14 % active) inside a 4px inset with an 8px radius, a 2px inset focus outline in the primary theme colour, and muted text for a disabled header. Item 1 opens in the expanded states; item 2 carries a hint; item 4 is disabled. The accordion has no variants.',
|
|
44
|
+
madeBy: ['claude-opus-5-5'],
|
|
45
|
+
states: {
|
|
46
|
+
collapsed: {},
|
|
47
|
+
expanded: { open: true },
|
|
48
|
+
disabled: { open: true, archive: 'hover' },
|
|
49
|
+
'header-hover': { open: true, shipping: 'hover' },
|
|
50
|
+
'header-active': { open: true, shipping: 'active' },
|
|
51
|
+
'header-focus-visible': { open: true, shipping: 'focus-visible' },
|
|
52
|
+
},
|
|
53
|
+
widths: [480],
|
|
54
|
+
controls: {
|
|
55
|
+
rules: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
56
|
+
shipping: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
57
|
+
archive: { kind: 'button', input: ['pointer', 'keyboard'] },
|
|
58
|
+
},
|
|
59
|
+
render: (props: Props) =>
|
|
60
|
+
drawing({
|
|
61
|
+
body: `<div class="accordion-frame">${accordionGroup(items(props)).replaceAll('inert=""><div class="et-accordion-panel-clip"', 'inert=""><div data-et-skip="CLIPPED" class="et-accordion-panel-clip"')}</div>`,
|
|
62
|
+
styles: [accordionStyles, frame].join('\n'),
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.avatar-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-avatar:not(:has(> .et-avatar-image)) {
|
|
11
|
+
outline: 1px solid var(--et-theme-color-ink-solid);
|
|
12
|
+
outline-offset: -1px;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
avatar,
|
|
3
|
+
avatarGroup,
|
|
4
|
+
avatarPlaceholderImage,
|
|
5
|
+
avatarRow,
|
|
6
|
+
avatarStyles,
|
|
7
|
+
AvatarMockOptions,
|
|
8
|
+
} from '@ethlete/components/design/avatar';
|
|
9
|
+
import { SDK_ICONS } from '@ethlete/components/design/icon-set';
|
|
10
|
+
import { definePart, drawing } from '@design-system';
|
|
11
|
+
import frame from './avatar.css?inline';
|
|
12
|
+
|
|
13
|
+
const icon = (name: string) => SDK_ICONS.find((each) => each.name === name);
|
|
14
|
+
|
|
15
|
+
type Shape = NonNullable<AvatarMockOptions['shape']>;
|
|
16
|
+
|
|
17
|
+
type Props = { avatars?: AvatarMockOptions[]; groups?: { avatars: AvatarMockOptions[]; maxVisible?: number }[] };
|
|
18
|
+
|
|
19
|
+
const themed = (shape: Shape): Props => ({
|
|
20
|
+
avatars: [
|
|
21
|
+
{ name: 'Jane Doe', shape },
|
|
22
|
+
{ name: 'Alex Kim', shape, color: 'brand' },
|
|
23
|
+
{ name: 'Sam Lee', shape, color: 'warning' },
|
|
24
|
+
{ name: 'Max Roe', shape, color: 'danger' },
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const forms = (shape: Shape): Props => ({
|
|
29
|
+
avatars: [
|
|
30
|
+
{ src: avatarPlaceholderImage, name: 'Jane Doe', shape },
|
|
31
|
+
{ name: 'Jane Doe', shape },
|
|
32
|
+
{ name: 'Dr. Anna Maria Schmidt', initials: 'AS', shape },
|
|
33
|
+
{ icon: icon('et-image'), shape },
|
|
34
|
+
{ shape },
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const sizes = (shape: Shape): Props => ({
|
|
39
|
+
avatars: (['xs', 'sm', 'md', 'lg', 'xl'] as const).map((size) => ({ name: 'Jane Doe', size, shape })),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const members: AvatarMockOptions[] = [
|
|
43
|
+
{ src: avatarPlaceholderImage, name: 'Jane Doe' },
|
|
44
|
+
{ name: 'Alex Kim', color: 'brand' },
|
|
45
|
+
{ name: 'Sam Lee', color: 'warning' },
|
|
46
|
+
{ name: 'Max Roe', color: 'danger' },
|
|
47
|
+
{ name: 'Ada Byron' },
|
|
48
|
+
{ name: 'Kai Berg' },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
export default definePart({
|
|
52
|
+
note: 'Decided rules only (Q99 rule a)',
|
|
53
|
+
madeBy: ['claude-opus-5-5'],
|
|
54
|
+
states: {
|
|
55
|
+
themes: themed('circle'),
|
|
56
|
+
'themes-square': themed('square'),
|
|
57
|
+
forms: forms('circle'),
|
|
58
|
+
'forms-square': forms('square'),
|
|
59
|
+
sizes: sizes('circle'),
|
|
60
|
+
'sizes-square': sizes('square'),
|
|
61
|
+
group: { groups: [{ avatars: members.slice(0, 4) }] },
|
|
62
|
+
'group-overflow': {
|
|
63
|
+
groups: [
|
|
64
|
+
{ avatars: members, maxVisible: 3 },
|
|
65
|
+
{ avatars: members.map((each) => ({ ...each, size: 'sm' as const, shape: 'square' as const })), maxVisible: 4 },
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
widths: [480],
|
|
70
|
+
render: (props: Props) =>
|
|
71
|
+
drawing({
|
|
72
|
+
body: `<div class="avatar-frame">${avatarRow([
|
|
73
|
+
...(props.avatars ?? []).map((each) => avatar(each)),
|
|
74
|
+
...(props.groups ?? []).map((each) => avatarGroup(each.avatars, each.maxVisible)),
|
|
75
|
+
])}</div>`,
|
|
76
|
+
styles: [avatarStyles, frame].join('\n'),
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.badge-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-badge:where([data-variant='filled'], [data-variant='tonal']) {
|
|
11
|
+
--_et-badge-border-color: var(--et-theme-color-ink-solid);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { badge, badgeRow, badgeStyles, BadgeMockOptions } from '@ethlete/components/design/badge';
|
|
2
|
+
import { SDK_ICONS } from '@ethlete/components/design/icon-set';
|
|
3
|
+
import { definePart, drawing } from '@design-system';
|
|
4
|
+
import frame from './badge.css?inline';
|
|
5
|
+
|
|
6
|
+
const icon = (name: string) => SDK_ICONS.find((each) => each.name === name);
|
|
7
|
+
|
|
8
|
+
type Variant = NonNullable<BadgeMockOptions['variant']>;
|
|
9
|
+
|
|
10
|
+
type Props = { badges: BadgeMockOptions[] };
|
|
11
|
+
|
|
12
|
+
const themed = (variant: Variant, size?: BadgeMockOptions['size']): Props => ({
|
|
13
|
+
badges: [
|
|
14
|
+
{ label: 'Default', variant, size },
|
|
15
|
+
{ label: 'Active', variant, size, color: 'brand' },
|
|
16
|
+
{ label: 'Pending', variant, size, color: 'warning' },
|
|
17
|
+
{ label: '3 errors', variant, size, color: 'danger' },
|
|
18
|
+
],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const withIcons = (variant: Variant): Props => ({
|
|
22
|
+
badges: [
|
|
23
|
+
{ label: 'Verified', variant, icon: icon('et-check'), color: 'brand' },
|
|
24
|
+
{ label: 'Featured', variant, icon: icon('et-star'), iconAlignment: 'end', color: 'warning' },
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const sizes = (variant: Variant): Props => ({
|
|
29
|
+
badges: (['sm', 'md', 'lg'] as const).map((size) => ({ label: size, variant, size })),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export default definePart({
|
|
33
|
+
note: 'Decided rules only',
|
|
34
|
+
madeBy: ['claude-opus-5-5'],
|
|
35
|
+
states: {
|
|
36
|
+
filled: themed('filled'),
|
|
37
|
+
tonal: themed('tonal'),
|
|
38
|
+
outline: themed('outline'),
|
|
39
|
+
'filled-icons': withIcons('filled'),
|
|
40
|
+
'tonal-icons': withIcons('tonal'),
|
|
41
|
+
'outline-icons': withIcons('outline'),
|
|
42
|
+
'filled-sizes': sizes('filled'),
|
|
43
|
+
'tonal-sizes': sizes('tonal'),
|
|
44
|
+
'outline-sizes': sizes('outline'),
|
|
45
|
+
},
|
|
46
|
+
widths: [480],
|
|
47
|
+
render: (props: Props) =>
|
|
48
|
+
drawing({
|
|
49
|
+
body: `<div class="badge-frame">${badgeRow(props.badges.map((each) => badge(each)))}</div>`,
|
|
50
|
+
styles: [badgeStyles, frame].join('\n'),
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.banner-frame {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 1.2rem;
|
|
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
|
+
.et-banner {
|
|
12
|
+
border-color: var(--et-theme-color-ink-solid);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.et-banner .et-focus-ring {
|
|
16
|
+
--_et-focus-ring-color: var(--et-theme-color-ink-solid);
|
|
17
|
+
}
|
|
18
|
+
}
|