@ethlete/components 1.0.0-next.69 → 1.0.0-next.71

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.
Files changed (239) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/design/button.ts +57 -0
  3. package/design/form-field.ts +210 -0
  4. package/design/select.ts +110 -0
  5. package/fesm2022/ethlete-components-testing.mjs +3 -1
  6. package/fesm2022/ethlete-components-testing.mjs.map +1 -1
  7. package/fesm2022/ethlete-components.mjs +830 -108
  8. package/fesm2022/ethlete-components.mjs.map +1 -1
  9. package/package.json +20 -14
  10. package/src/lib/accordion/accordion-group.component.css +12 -0
  11. package/src/lib/accordion/accordion.component.css +185 -0
  12. package/src/lib/avatar/avatar-group.component.css +31 -0
  13. package/src/lib/avatar/avatar.component.css +75 -0
  14. package/src/lib/badge/badge.component.css +111 -0
  15. package/src/lib/banner/banner.component.css +94 -0
  16. package/src/lib/bracket/bracket-default-continue.component.css +29 -0
  17. package/src/lib/bracket/bracket-default-final-match.component.css +76 -0
  18. package/src/lib/bracket/bracket-default-match.component.css +21 -0
  19. package/src/lib/bracket/bracket-default-round-header.component.css +36 -0
  20. package/src/lib/bracket/bracket-participants.component.css +13 -0
  21. package/src/lib/bracket/bracket-pick-card.component.css +232 -0
  22. package/src/lib/bracket/bracket-rounds-list.component.css +75 -0
  23. package/src/lib/bracket/bracket-skeleton.component.css +55 -0
  24. package/src/lib/bracket/bracket.component.css +102 -0
  25. package/src/lib/bracket/layouts/swiss/bracket-swiss-styles.component.css +10 -0
  26. package/src/lib/breadcrumb/breadcrumb-overflow.component.css +38 -0
  27. package/src/lib/breadcrumb/breadcrumb.component.css +120 -0
  28. package/src/lib/button/button-properties-styles.component.css +143 -0
  29. package/src/lib/button/button.component.css +196 -0
  30. package/src/lib/button/fab.component.css +252 -0
  31. package/src/lib/button/icon-button.component.css +143 -0
  32. package/src/lib/button/split-button.component.css +77 -0
  33. package/src/lib/button/text-button.component.css +140 -0
  34. package/src/lib/button/window-control-button.component.css +158 -0
  35. package/src/lib/calendar/calendar-coarse-grid-styles.component.css +29 -0
  36. package/src/lib/calendar/calendar-comparison-band-styles.component.css +36 -0
  37. package/src/lib/calendar/calendar-week-numbers-styles.component.css +32 -0
  38. package/src/lib/calendar/calendar.component.css +366 -0
  39. package/src/lib/card/card.component.css +39 -0
  40. package/src/lib/carousel/carousel-autoplay-styles.component.css +166 -0
  41. package/src/lib/carousel/carousel-transition-styles.component.css +179 -0
  42. package/src/lib/carousel/carousel.component.css +142 -0
  43. package/src/lib/chart/bar-chart.component.css +176 -0
  44. package/src/lib/chart/chart-axis.component.css +40 -0
  45. package/src/lib/chart/chart-grid.component.css +6 -0
  46. package/src/lib/chart/chart-legend.component.css +46 -0
  47. package/src/lib/chart/chart-tooltip.component.css +34 -0
  48. package/src/lib/chart/line-chart-tooltip.component.css +51 -0
  49. package/src/lib/chart/line-chart.component.css +234 -0
  50. package/src/lib/chart/pie-chart.component.css +176 -0
  51. package/src/lib/chart/sankey-chart.component.css +221 -0
  52. package/src/lib/chip/chip.component.css +155 -0
  53. package/src/lib/command-palette/command-palette-item.component.css +94 -0
  54. package/src/lib/command-palette/command-palette.component.css +100 -0
  55. package/src/lib/description-list/description-list.component.css +77 -0
  56. package/src/lib/divider/divider.component.css +36 -0
  57. package/src/lib/empty-state/empty-state.component.css +73 -0
  58. package/src/lib/floating-action/floating-action-styles.component.css +78 -0
  59. package/src/lib/focus-ring/focus-ring-styles.component.css +13 -0
  60. package/src/lib/forms/cascader/cascader-breadcrumb-styles.component.css +98 -0
  61. package/src/lib/forms/cascader/cascader-panel.component.css +386 -0
  62. package/src/lib/forms/cascader/cascader-sheet-styles.component.css +241 -0
  63. package/src/lib/forms/cascader/cascader.component.css +52 -0
  64. package/src/lib/forms/checkbox/checkbox.component.css +247 -0
  65. package/src/lib/forms/choice-field/choice-field-card-styles.component.css +59 -0
  66. package/src/lib/forms/choice-field/choice-field.component.css +186 -0
  67. package/src/lib/forms/color-input/color-input.component.css +108 -0
  68. package/src/lib/forms/color-input/color-picker-panel.component.css +349 -0
  69. package/src/lib/forms/date-time/date-input/date-input.component.css +35 -0
  70. package/src/lib/forms/date-time/date-picker-panel.component.css +115 -0
  71. package/src/lib/forms/date-time/date-range-input/date-range-input.component.css +16 -0
  72. package/src/lib/forms/date-time/date-range-presets.component.css +60 -0
  73. package/src/lib/forms/date-time/date-time-input/date-time-input.component.css +151 -0
  74. package/src/lib/forms/date-time/date-time-range-input/date-time-range-input.component.css +121 -0
  75. package/src/lib/forms/date-time/duration-input/duration-input.component.css +88 -0
  76. package/src/lib/forms/date-time/range-input-shell-styles.component.css +55 -0
  77. package/src/lib/forms/date-time/time-input/time-input.component.css +35 -0
  78. package/src/lib/forms/date-time/time-range-input/time-range-input.component.css +16 -0
  79. package/src/lib/forms/dropzone/dropzone-item.component.css +51 -0
  80. package/src/lib/forms/dropzone/dropzone-preview-styles.component.css +67 -0
  81. package/src/lib/forms/dropzone/dropzone-readonly-styles.component.css +34 -0
  82. package/src/lib/forms/dropzone/dropzone.component.css +267 -0
  83. package/src/lib/forms/form-field/counter.component.css +25 -0
  84. package/src/lib/forms/form-field/form-field-control-suffix-styles.component.css +116 -0
  85. package/src/lib/forms/form-field/form-field-rich-text-styles.component.css +31 -0
  86. package/src/lib/forms/form-field/form-field-suffix-overlap-styles.component.css +66 -0
  87. package/src/lib/forms/form-field/form-field-text-shell-styles.component.css +312 -0
  88. package/src/lib/forms/form-field/form-field-textarea-styles.component.css +32 -0
  89. package/src/lib/forms/form-field/form-field.component.css +328 -0
  90. package/src/lib/forms/form-field/form-support-styles.component.css +102 -0
  91. package/src/lib/forms/form-field/headless/label.directive.css +25 -0
  92. package/src/lib/forms/form-field/hint.component.css +20 -0
  93. package/src/lib/forms/input/input.component.css +49 -0
  94. package/src/lib/forms/input/number-input.component.css +128 -0
  95. package/src/lib/forms/input/password-input.component.css +103 -0
  96. package/src/lib/forms/multi-language-rich-text-editor/multi-language-rich-text-editor.component.css +8 -0
  97. package/src/lib/forms/multi-language-rich-text-editor/tools/multi-language-rich-text-editor-language-tool.component.css +104 -0
  98. package/src/lib/forms/otp-input/otp-input.component.css +194 -0
  99. package/src/lib/forms/phone-input/phone-input.component.css +126 -0
  100. package/src/lib/forms/rating/rating.component.css +197 -0
  101. package/src/lib/forms/rich-text-editor/rich-text-content-styles.component.css +234 -0
  102. package/src/lib/forms/rich-text-editor/rich-text-editor-floating-toolbar.component.css +90 -0
  103. package/src/lib/forms/rich-text-editor/rich-text-editor-image-editor.component.css +172 -0
  104. package/src/lib/forms/rich-text-editor/rich-text-editor-link-editor.component.css +149 -0
  105. package/src/lib/forms/rich-text-editor/rich-text-editor-token-palette.component.css +18 -0
  106. package/src/lib/forms/rich-text-editor/rich-text-editor-token-popup.component.css +199 -0
  107. package/src/lib/forms/rich-text-editor/rich-text-editor.component.css +175 -0
  108. package/src/lib/forms/rich-text-editor/rich-text-viewer.component.css +6 -0
  109. package/src/lib/forms/rich-text-editor/tools/rich-text-editor-align-tool.component.css +5 -0
  110. package/src/lib/forms/rich-text-editor/tools/rich-text-editor-heading-tool.component.css +5 -0
  111. package/src/lib/forms/rich-text-editor/tools/rich-text-editor-image-styles.component.css +109 -0
  112. package/src/lib/forms/rich-text-editor/tools/rich-text-editor-table-styles.component.css +21 -0
  113. package/src/lib/forms/rich-text-editor/tools/rich-text-editor-table-tool.component.css +44 -0
  114. package/src/lib/forms/select/select-all-option.component.css +14 -0
  115. package/src/lib/forms/select/select-extras-styles.component.css +143 -0
  116. package/src/lib/forms/select/select-option-group.component.css +35 -0
  117. package/src/lib/forms/select/select-option-styles.component.css +137 -0
  118. package/src/lib/forms/select/select-panel.component.css +112 -0
  119. package/src/lib/forms/select/select.component.css +180 -0
  120. package/src/lib/forms/selection-card-styles.component.css +136 -0
  121. package/src/lib/forms/selection-list/checkbox-group/checkbox-group-select-all.component.css +89 -0
  122. package/src/lib/forms/selection-list/checkbox-group/checkbox-group.component.css +142 -0
  123. package/src/lib/forms/selection-list/checkbox-group/checkbox-option.component.css +153 -0
  124. package/src/lib/forms/selection-list/radio-group/radio-group.component.css +134 -0
  125. package/src/lib/forms/selection-list/radio-group/radio.component.css +137 -0
  126. package/src/lib/forms/selection-list/segmented-button-group/segmented-button-group.component.css +149 -0
  127. package/src/lib/forms/selection-list/segmented-button-group/segmented-button.component.css +180 -0
  128. package/src/lib/forms/slider/range-slider.component.css +348 -0
  129. package/src/lib/forms/slider/slider.component.css +342 -0
  130. package/src/lib/forms/switch/switch.component.css +187 -0
  131. package/src/lib/forms/tag-input/tag-input.component.css +54 -0
  132. package/src/lib/forms/textarea/textarea-autosize-styles.component.css +17 -0
  133. package/src/lib/forms/textarea/textarea.component.css +40 -0
  134. package/src/lib/grid/grid-debug.component.css +130 -0
  135. package/src/lib/grid/grid-item-default-actions.component.css +11 -0
  136. package/src/lib/grid/grid-item.component.css +172 -0
  137. package/src/lib/grid/grid.component.css +56 -0
  138. package/src/lib/icon/headless/icon-styles.component.css +7 -0
  139. package/src/lib/kbd/kbd.component.css +62 -0
  140. package/src/lib/loader/brand-loader/brand-loader.component.css +130 -0
  141. package/src/lib/loader/progress-bar/progress-bar.component.css +176 -0
  142. package/src/lib/loader/spinner/spinner.component.css +216 -0
  143. package/src/lib/masonry/masonry-styles.component.css +84 -0
  144. package/src/lib/match/match-card.component.css +441 -0
  145. package/src/lib/match/match-participant.component.css +137 -0
  146. package/src/lib/match/match-score.component.css +74 -0
  147. package/src/lib/menu/menu-group-label.component.css +12 -0
  148. package/src/lib/menu/menu-item-shortcut.component.css +10 -0
  149. package/src/lib/menu/menu-item-submenu-icon.component.css +18 -0
  150. package/src/lib/menu/menu-item.component.css +32 -0
  151. package/src/lib/menu/menu-search-styles.component.css +56 -0
  152. package/src/lib/menu/menu-selection-item.component.css +88 -0
  153. package/src/lib/menu/menu-separator.component.css +9 -0
  154. package/src/lib/menu/menu.component.css +296 -0
  155. package/src/lib/notification/notification-stack.component.css +114 -0
  156. package/src/lib/notification/notification.component.css +271 -0
  157. package/src/lib/overlay/alert-dialog/alert-dialog.component.css +45 -0
  158. package/src/lib/overlay/floating-panel-styles.component.css +71 -0
  159. package/src/lib/overlay/floating-tip-styles.component.css +78 -0
  160. package/src/lib/overlay/overlay-container.component.css +167 -0
  161. package/src/lib/overlay/overlay-main-styles.component.css +105 -0
  162. package/src/lib/overlay/overlay-template-host.component.css +7 -0
  163. package/src/lib/overlay/routing/overlay-route-header-template-outlet.component.css +36 -0
  164. package/src/lib/overlay/routing/overlay-router-outlet.component.css +207 -0
  165. package/src/lib/overlay/routing/overlay-shared-route-template-outlet.component.css +5 -0
  166. package/src/lib/overlay/sidebar/overlay-sidebar.component.css +16 -0
  167. package/src/lib/overlay/strategies/anchored-dialog-styles.component.css +51 -0
  168. package/src/lib/overlay/strategies/dialog-styles.component.css +50 -0
  169. package/src/lib/overlay/strategies/full-screen-dialog-styles.component.css +83 -0
  170. package/src/lib/overlay/strategies/overlay-arrow-styles.component.css +112 -0
  171. package/src/lib/overlay/strategies/overlay-origin-clone.component.css +63 -0
  172. package/src/lib/overlay/strategies/sheet-styles.component.css +143 -0
  173. package/src/lib/pagination/page-size-select.component.css +102 -0
  174. package/src/lib/pagination/pagination.component.css +192 -0
  175. package/src/lib/picture/picture.component.css +66 -0
  176. package/src/lib/progress-steps/progress-step.component.css +187 -0
  177. package/src/lib/progress-steps/progress-steps.component.css +26 -0
  178. package/src/lib/query-error/query-error.component.css +21 -0
  179. package/src/lib/scheduler/scheduler-agenda-view.component.css +97 -0
  180. package/src/lib/scheduler/scheduler-appointment-drag-styles.component.css +56 -0
  181. package/src/lib/scheduler/scheduler-appointment-styles.component.css +111 -0
  182. package/src/lib/scheduler/scheduler-edit-color.component.css +16 -0
  183. package/src/lib/scheduler/scheduler-edit-surface-actions.component.css +14 -0
  184. package/src/lib/scheduler/scheduler-edit-surface-breadcrumb.component.css +26 -0
  185. package/src/lib/scheduler/scheduler-edit-surface-children.component.css +57 -0
  186. package/src/lib/scheduler/scheduler-edit-surface-fields.component.css +11 -0
  187. package/src/lib/scheduler/scheduler-edit-surface-footer.component.css +7 -0
  188. package/src/lib/scheduler/scheduler-edit-surface-header.component.css +15 -0
  189. package/src/lib/scheduler/scheduler-edit-time-range.component.css +11 -0
  190. package/src/lib/scheduler/scheduler-month-view.component.css +143 -0
  191. package/src/lib/scheduler/scheduler-time-grid-view.component.css +260 -0
  192. package/src/lib/scheduler/scheduler.component.css +87 -0
  193. package/src/lib/scrollable/headless/scrollable-buttons.component.css +122 -0
  194. package/src/lib/scrollable/headless/scrollable-footer.css +25 -0
  195. package/src/lib/scrollable/headless/scrollable-masks.component.css +112 -0
  196. package/src/lib/scrollable/headless/scrollable-navigation.component.css +94 -0
  197. package/src/lib/scrollable/scrollable.component.css +192 -0
  198. package/src/lib/scrollbar/scrollbar.component.css +110 -0
  199. package/src/lib/skeleton/skeleton.component.css +108 -0
  200. package/src/lib/standings/standings-pick.component.css +172 -0
  201. package/src/lib/standings/standings.component.css +201 -0
  202. package/src/lib/stat-tile/stat-tile-sparkline.component.css +49 -0
  203. package/src/lib/stat-tile/stat-tile.component.css +111 -0
  204. package/src/lib/stream/pip/pip-chrome.component.css +96 -0
  205. package/src/lib/stream/pip/pip-player.component.css +40 -0
  206. package/src/lib/stream/pip/pip-window.component.css +222 -0
  207. package/src/lib/stream/stream-manager-styles.component.css +10 -0
  208. package/src/lib/stream/stream-overlay-card-styles.component.css +43 -0
  209. package/src/lib/stream/stream-player-slot-styles.component.css +14 -0
  210. package/src/lib/table/table-column-chooser.component.css +17 -0
  211. package/src/lib/table/table-column-menu-trigger.component.css +31 -0
  212. package/src/lib/table/table-detail-styles.component.css +103 -0
  213. package/src/lib/table/table-drag-scroll-styles.component.css +18 -0
  214. package/src/lib/table/table-expander-cell.component.css +58 -0
  215. package/src/lib/table/table-filter-trigger.component.css +44 -0
  216. package/src/lib/table/table-group-header-row.component.css +38 -0
  217. package/src/lib/table/table-inline-edit-styles.component.css +20 -0
  218. package/src/lib/table/table-page-sticky-header-styles.component.css +77 -0
  219. package/src/lib/table/table-reorder-overlay.component.css +42 -0
  220. package/src/lib/table/table-resize-grip.component.css +65 -0
  221. package/src/lib/table/table-row-box-styles.component.css +260 -0
  222. package/src/lib/table/table-select-cell.component.css +89 -0
  223. package/src/lib/table/table-skeleton-rows.component.css +19 -0
  224. package/src/lib/table/table-sort-priority-styles.component.css +15 -0
  225. package/src/lib/table/table-sticky-columns-styles.component.css +80 -0
  226. package/src/lib/table/table-virtual-scroll-styles.component.css +9 -0
  227. package/src/lib/table/table.component.css +829 -0
  228. package/src/lib/tabs/nav-tabs/nav-tab-link-styles.component.css +33 -0
  229. package/src/lib/tabs/tab-bar-styles.component.css +173 -0
  230. package/src/lib/tabs/tab-scale-styles.component.css +61 -0
  231. package/src/lib/time-picker/time-picker.component.css +220 -0
  232. package/src/lib/timeline/timeline-item.component.css +116 -0
  233. package/src/lib/timeline/timeline.component.css +7 -0
  234. package/src/lib/toggletip/toggletip.component.css +83 -0
  235. package/src/lib/toolbar/toolbar.component.css +40 -0
  236. package/src/lib/tooltip/tooltip.component.css +64 -0
  237. package/src/lib/tree/tree.component.css +221 -0
  238. package/types/ethlete-components-testing.d.ts +1 -1
  239. package/types/ethlete-components.d.ts +172 -7
@@ -0,0 +1,98 @@
1
+ @layer components {
2
+ .et-cascader-panel {
3
+ /* the row follows the columns' width instead of contributing its own to the panel's
4
+ max-content measurement (a long path would otherwise stretch the panel) */
5
+ .et-cascader-breadcrumbs {
6
+ display: flex;
7
+ align-items: center;
8
+ gap: 2px;
9
+ box-sizing: border-box;
10
+ inline-size: 0;
11
+ min-inline-size: 100%;
12
+ padding: 6px;
13
+ border-block-start: 1px solid var(--et-surface-border-solid, rgb(255 255 255 / 0.1));
14
+ overflow: hidden;
15
+ }
16
+
17
+ .et-cascader-crumb {
18
+ display: flex;
19
+ align-items: center;
20
+ gap: 2px;
21
+ min-inline-size: 0;
22
+
23
+ &.et-cascader-crumb--enter {
24
+ animation: et-cascader-crumb-in 200ms ease;
25
+ }
26
+
27
+ &.et-cascader-crumb--leave {
28
+ animation: et-cascader-crumb-out 160ms ease forwards;
29
+ }
30
+ }
31
+
32
+ .et-cascader-breadcrumb {
33
+ display: block;
34
+ min-inline-size: 0;
35
+ padding: 4px 8px;
36
+ border: none;
37
+ border-radius: 6px;
38
+ background: transparent;
39
+ font: inherit;
40
+ font-size: 12px;
41
+ color: var(--et-surface-color-muted-solid, currentColor);
42
+ text-align: start;
43
+ white-space: nowrap;
44
+ overflow: hidden;
45
+ text-overflow: ellipsis;
46
+ cursor: pointer;
47
+ appearance: none;
48
+ outline: none;
49
+ transition:
50
+ background 120ms ease,
51
+ color 120ms ease;
52
+
53
+ @media (hover: hover) {
54
+ &:hover {
55
+ background: color-mix(in srgb, var(--et-surface-interaction-solid, currentColor) 12%, transparent);
56
+ color: var(--et-surface-color-solid, currentColor);
57
+ }
58
+ }
59
+
60
+ &:focus-visible {
61
+ background: color-mix(in srgb, var(--et-surface-interaction-solid, currentColor) 16%, transparent);
62
+ color: var(--et-surface-color-solid, currentColor);
63
+ }
64
+
65
+ &[data-current] {
66
+ color: var(--et-surface-color-solid, currentColor);
67
+ }
68
+ }
69
+
70
+ .et-cascader-breadcrumb-chevron {
71
+ flex: none;
72
+ inline-size: 10px;
73
+ block-size: 10px;
74
+ color: var(--et-surface-color-subtle-solid, currentColor);
75
+ rotate: 90deg;
76
+ }
77
+ }
78
+
79
+ @keyframes et-cascader-crumb-in {
80
+ from {
81
+ opacity: 0;
82
+ transform: translateX(8px);
83
+ }
84
+ }
85
+
86
+ @keyframes et-cascader-crumb-out {
87
+ to {
88
+ opacity: 0;
89
+ transform: translateX(8px);
90
+ }
91
+ }
92
+
93
+ @media (prefers-reduced-motion: reduce) {
94
+ .et-cascader-panel .et-cascader-crumb {
95
+ animation: none;
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,386 @@
1
+ @layer components {
2
+ @property --et-cascader-column-inline-size {
3
+ syntax: '<length>';
4
+ /* inherits so one ancestor override reaches both the columns and the carousel viewport
5
+ that multiplies it (their widths must agree for the window transform to line up) */
6
+ inherits: true;
7
+ initial-value: 220px;
8
+ }
9
+
10
+ @property --et-cascader-panel-max-block-size {
11
+ syntax: '<length-percentage>';
12
+ inherits: false;
13
+ initial-value: 320px;
14
+ }
15
+
16
+ @property --et-cascader-node-height {
17
+ syntax: '<length>';
18
+ /* inherits so an ancestor scope (e.g. the bottom sheet) can enlarge the rows */
19
+ inherits: true;
20
+ initial-value: 36px;
21
+ }
22
+
23
+ .et-overlay--cascader {
24
+ --et-floating-panel-enter-duration: 140ms;
25
+ --et-floating-panel-leave-duration: 100ms;
26
+ --et-floating-panel-distance: 0.3rem;
27
+ }
28
+
29
+ .et-cascader-panel {
30
+ display: block;
31
+ box-sizing: border-box;
32
+ /* an anchored pane does not clip, so dropping the pane's own cap here lets columns taller than
33
+ the room next to the field hang out of the pane and past the viewport edge */
34
+ --_et-cascader-panel-max-block-size: min(
35
+ var(--et-cascader-panel-max-block-size),
36
+ var(--et-overlay-max-height, 100vh)
37
+ );
38
+ border-radius: 10px;
39
+ border: 1px solid var(--et-surface-border-solid, rgb(255 255 255 / 0.1));
40
+ background: var(--et-surface-background-solid, rgb(32 32 32));
41
+ color: var(--et-surface-color-solid, rgb(244 244 245));
42
+ font-size: 14px;
43
+ box-shadow: var(--et-anchored-panel-shadow, 0 10px 24px rgb(var(--et-shadow-color-rgb, 0 0 0) / 0.16));
44
+ overflow: hidden;
45
+
46
+ &.et-cascader-panel--resizing {
47
+ overflow: clip;
48
+ }
49
+
50
+ /* the body is content-sized so the width animation can measure the natural target width — a
51
+ plain block child would just mirror the host's animated width back into the ResizeObserver
52
+ (feedback loop) */
53
+ &:not([data-sheet]) > .et-cascader-panel-body {
54
+ inline-size: max-content;
55
+ }
56
+
57
+ .et-cascader-columns {
58
+ display: flex;
59
+ max-block-size: var(--_et-cascader-panel-max-block-size);
60
+
61
+ /* `clip`, not `hidden` — a focused node's scrollIntoView must never desync the track
62
+ transform below with a stray programmatic scrollLeft */
63
+ &:not([data-sheet]) {
64
+ display: block;
65
+ inline-size: calc(var(--_et-cascader-visible-columns, 1) * var(--et-cascader-column-inline-size));
66
+ overflow: clip;
67
+
68
+ /* the carousel math multiplies the token, so it must be the full outer width */
69
+ .et-cascader-column {
70
+ box-sizing: border-box;
71
+ }
72
+
73
+ /* a column outside the window stays mounted (it has to slide, not pop) but must
74
+ not contribute its height to the panel */
75
+ .et-cascader-column--offstage {
76
+ contain: size;
77
+ }
78
+ }
79
+
80
+ &[data-sheet] {
81
+ display: block;
82
+ flex: 1;
83
+ min-block-size: 0;
84
+ max-block-size: none;
85
+ overflow-y: auto;
86
+ overflow-x: clip;
87
+ overscroll-behavior: contain;
88
+
89
+ /* the column area, not the column, is the scrollport here - the wrapper has to pass the
90
+ full body height through, or the column's own 100% resolves against nothing */
91
+ .et-cascader-column-wrapper {
92
+ block-size: 100%;
93
+ }
94
+
95
+ .et-cascader-column {
96
+ inline-size: 100%;
97
+ block-size: 100%;
98
+ max-block-size: none;
99
+ overflow: visible;
100
+ border-inline-end: none;
101
+ }
102
+
103
+ .et-cascader-column:has(.et-cascader-state) {
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: center;
107
+ }
108
+ }
109
+ }
110
+
111
+ .et-cascader-columns-track {
112
+ display: flex;
113
+ max-block-size: inherit;
114
+ transform: translateX(
115
+ calc(var(--_et-cascader-column-window-start, 0) * -1 * var(--et-cascader-column-inline-size))
116
+ );
117
+ transition: transform 240ms ease;
118
+ }
119
+
120
+ .et-cascader-search {
121
+ padding: 6px;
122
+ border-block-end: 1px solid var(--et-surface-border-solid, rgb(255 255 255 / 0.1));
123
+
124
+ input[etcascadersearch] {
125
+ inline-size: 100%;
126
+ block-size: 36px;
127
+ box-sizing: border-box;
128
+ padding-inline: 10px;
129
+ border-radius: 6px;
130
+ border: 1px solid var(--et-surface-border-solid, rgb(255 255 255 / 0.1));
131
+ background: color-mix(in srgb, var(--et-surface-interaction-solid, rgb(255 255 255)) 6%, transparent);
132
+ color: inherit;
133
+ font: inherit;
134
+ outline: none;
135
+ caret-color: var(--et-theme-color-primary-solid, currentColor);
136
+ transition:
137
+ border-color 120ms ease,
138
+ background 120ms ease;
139
+
140
+ &:focus-visible {
141
+ border-color: var(--et-theme-color-primary-solid, rgb(255 255 255 / 0.3));
142
+ }
143
+
144
+ &::placeholder {
145
+ color: var(--et-surface-color-muted-solid, rgb(255 255 255 / 0.55));
146
+ }
147
+ }
148
+ }
149
+
150
+ .et-cascader-results-wrapper {
151
+ position: relative;
152
+ display: flex;
153
+ flex-direction: column;
154
+ }
155
+
156
+ .et-cascader-results {
157
+ display: block;
158
+ box-sizing: border-box;
159
+ inline-size: min(320px, calc(100vw - 24px));
160
+ max-block-size: var(--_et-cascader-panel-max-block-size);
161
+ overflow-y: auto;
162
+ overflow-x: clip;
163
+ overscroll-behavior: contain;
164
+ padding: 6px;
165
+ }
166
+
167
+ .et-cascader-column-wrapper {
168
+ position: relative;
169
+ flex: none;
170
+ }
171
+
172
+ .et-cascader-column {
173
+ display: block;
174
+ flex: none;
175
+ inline-size: var(--et-cascader-column-inline-size);
176
+ max-block-size: var(--_et-cascader-panel-max-block-size);
177
+ overflow-y: auto;
178
+ /* clip the X axis so the slide-in transform never spawns a horizontal scrollbar
179
+ (overflow-y: auto would otherwise compute overflow-x to auto) */
180
+ overflow-x: clip;
181
+ overscroll-behavior: contain;
182
+ padding: 6px;
183
+ }
184
+
185
+ .et-cascader-column-wrapper:not(:last-child) .et-cascader-column {
186
+ border-inline-end: 1px solid var(--et-surface-border-solid, rgb(255 255 255 / 0.1));
187
+ }
188
+
189
+ .et-cascader-columns[data-sheet] .et-cascader-column {
190
+ &:where([data-nav='forward']) {
191
+ animation: et-cascader-column-in-forward 200ms ease;
192
+ }
193
+
194
+ &:where([data-nav='backward']) {
195
+ animation: et-cascader-column-in-backward 200ms ease;
196
+ }
197
+ }
198
+
199
+ .et-cascader-columns:not([data-sheet]) .et-cascader-column:where([data-nav='forward']) {
200
+ animation: et-cascader-column-grow-in 180ms ease;
201
+ }
202
+
203
+ /* the column scrolls and clips, so the default 3px outward ring would be cut off on a node
204
+ scrolled to its edge */
205
+ .et-cascader-node,
206
+ .et-cascader-search-option {
207
+ --_et-focus-ring-offset: -2px;
208
+ display: flex;
209
+ align-items: center;
210
+ gap: 8px;
211
+ inline-size: 100%;
212
+ min-block-size: var(--et-cascader-node-height);
213
+ padding-inline: 10px;
214
+ border: none;
215
+ border-radius: 6px;
216
+ background: transparent;
217
+ font: inherit;
218
+ text-align: start;
219
+ color: inherit;
220
+ cursor: pointer;
221
+ appearance: none;
222
+ transition: background 120ms ease;
223
+
224
+ @media (hover: hover) {
225
+ &:hover {
226
+ background: color-mix(in srgb, var(--et-surface-interaction-solid, currentColor) 12%, transparent);
227
+ }
228
+ }
229
+
230
+ &:focus-visible,
231
+ &[data-focused] {
232
+ background: color-mix(in srgb, var(--et-surface-interaction-solid, currentColor) 16%, transparent);
233
+ }
234
+
235
+ &[data-expanded] {
236
+ background: color-mix(in srgb, var(--et-surface-interaction-solid, currentColor) 12%, transparent);
237
+ }
238
+
239
+ &[data-selected] {
240
+ color: var(--et-theme-color-ink-solid, currentColor);
241
+ font-weight: 500;
242
+ }
243
+
244
+ &[data-disabled] {
245
+ cursor: default;
246
+ opacity: 0.4;
247
+ }
248
+ }
249
+
250
+ .et-cascader-node-label,
251
+ .et-cascader-search-option-label {
252
+ flex: 1;
253
+ min-inline-size: 0;
254
+ overflow: hidden;
255
+ white-space: nowrap;
256
+ text-overflow: ellipsis;
257
+ }
258
+
259
+ .et-cascader-search-option-ancestor {
260
+ color: var(--et-surface-color-muted-solid, currentColor);
261
+ }
262
+
263
+ .et-cascader-check {
264
+ position: relative;
265
+ flex: none;
266
+ inline-size: 16px;
267
+ block-size: 16px;
268
+ box-sizing: border-box;
269
+ border: 2px solid var(--et-surface-border-solid, rgb(255 255 255 / 0.3));
270
+ border-radius: 4px;
271
+ transition:
272
+ background 120ms ease,
273
+ border-color 120ms ease;
274
+
275
+ &::after {
276
+ content: '';
277
+ position: absolute;
278
+ opacity: 0;
279
+ }
280
+ }
281
+
282
+ [data-selected] > .et-cascader-check,
283
+ [data-indeterminate] > .et-cascader-check {
284
+ border-color: var(--et-theme-color-primary-solid, currentColor);
285
+ background: var(--et-theme-color-primary-solid, currentColor);
286
+ }
287
+
288
+ [data-selected] > .et-cascader-check::after {
289
+ inset-inline-start: 4px;
290
+ inset-block-start: 1px;
291
+ inline-size: 4px;
292
+ block-size: 8px;
293
+ border: solid var(--et-theme-color-on-primary, rgb(0 0 0));
294
+ border-width: 0 2px 2px 0;
295
+ rotate: 45deg;
296
+ opacity: 1;
297
+ }
298
+
299
+ [data-indeterminate] > .et-cascader-check::after {
300
+ inset-inline-start: 2px;
301
+ inset-block-start: 5px;
302
+ inline-size: 8px;
303
+ block-size: 2px;
304
+ background: var(--et-theme-color-on-primary, rgb(0 0 0));
305
+ opacity: 1;
306
+ }
307
+
308
+ .et-cascader-node-chevron {
309
+ flex: none;
310
+ inline-size: 12px;
311
+ block-size: 12px;
312
+ color: var(--et-surface-color-muted-solid, currentColor);
313
+ rotate: 90deg;
314
+ }
315
+
316
+ .et-cascader-state {
317
+ display: flex;
318
+ align-items: center;
319
+ justify-content: center;
320
+ gap: 8px;
321
+ min-block-size: var(--et-cascader-node-height);
322
+ padding: 12px 16px;
323
+ text-align: center;
324
+ color: var(--et-surface-color-muted-solid, currentColor);
325
+
326
+ &.et-cascader-state--error {
327
+ flex-direction: column;
328
+ gap: 8px;
329
+ font-size: 12px;
330
+ }
331
+ }
332
+
333
+ .et-cascader-state-content {
334
+ display: flex;
335
+ align-items: center;
336
+ gap: 8px;
337
+ opacity: 0;
338
+ transition: opacity 120ms ease;
339
+
340
+ &.et-cascader-state-content--visible {
341
+ opacity: 1;
342
+ }
343
+ }
344
+
345
+ @media (prefers-reduced-motion: reduce) {
346
+ .et-cascader-state-content {
347
+ transition: none;
348
+ }
349
+ }
350
+
351
+ .et-cascader-state-error-message {
352
+ color: var(--et-theme-color-ink-solid, rgb(248 113 113));
353
+ }
354
+ }
355
+
356
+ @keyframes et-cascader-column-in-forward {
357
+ from {
358
+ opacity: 0;
359
+ transform: translateX(14px);
360
+ }
361
+ }
362
+
363
+ @keyframes et-cascader-column-in-backward {
364
+ from {
365
+ opacity: 0;
366
+ transform: translateX(-14px);
367
+ }
368
+ }
369
+
370
+ @keyframes et-cascader-column-grow-in {
371
+ from {
372
+ opacity: 0;
373
+ transform: translateX(-10px);
374
+ }
375
+ }
376
+
377
+ @media (prefers-reduced-motion: reduce) {
378
+ .et-cascader-panel .et-cascader-column {
379
+ animation: none;
380
+ }
381
+
382
+ .et-cascader-panel .et-cascader-columns-track {
383
+ transition: none;
384
+ }
385
+ }
386
+ }
@@ -0,0 +1,241 @@
1
+ @layer components {
2
+ .et-overlay.et-cascader-sheet {
3
+ --et-cascader-node-height: 52px;
4
+
5
+ border-radius: 16px 16px 0 0;
6
+
7
+ /* the panel draws the handle itself (below), so the container's own must go. Matching
8
+ `.et-overlay--bottom-sheet` too is what makes it win: the rule that shows the handle is
9
+ `.et-overlay.et-overlay--bottom-sheet .et-overlay-container-drag-handle`, identical in
10
+ specificity to this selector without it, so the tie went to source order - and this sheet is
11
+ unloaded with its last instance when the cascader closes, then re-appended on the next open.
12
+ That re-append put it after the overlay's rule the first time and before it every time after,
13
+ which is why a reopened sheet showed two handles. */
14
+ &.et-overlay--bottom-sheet .et-overlay-container-drag-handle {
15
+ display: none;
16
+ }
17
+
18
+ .et-cascader-node,
19
+ .et-cascader-search-option {
20
+ font-size: 16px;
21
+ padding-inline: 14px;
22
+ }
23
+
24
+ .et-cascader-search {
25
+ padding-inline: 20px;
26
+ }
27
+
28
+ /* 16px also keeps iOS Safari from zooming into the focused input */
29
+ .et-cascader-search input[etcascadersearch] {
30
+ block-size: 44px;
31
+ font-size: 16px;
32
+ }
33
+
34
+ .et-cascader-node-chevron {
35
+ inline-size: 14px;
36
+ block-size: 14px;
37
+ }
38
+
39
+ .et-cascader-panel {
40
+ max-inline-size: none;
41
+ border: none;
42
+ border-radius: 0;
43
+ box-shadow: none;
44
+ padding-block-end: max(8px, env(safe-area-inset-bottom));
45
+
46
+ &::before {
47
+ content: '';
48
+ display: block;
49
+ inline-size: 32px;
50
+ block-size: 4px;
51
+ margin-inline: auto;
52
+ margin-block: 8px 4px;
53
+ border-radius: 999px;
54
+ background: var(--et-surface-border-solid, rgb(255 255 255 / 0.2));
55
+ }
56
+ }
57
+ }
58
+
59
+ .et-cascader-panel {
60
+ .et-cascader-sheet-header {
61
+ position: relative;
62
+ display: flex;
63
+ align-items: center;
64
+ flex: none;
65
+ box-sizing: border-box;
66
+ block-size: var(--et-cascader-node-height);
67
+ padding-block: 4px;
68
+ /* column padding (6px) + node padding-inline (14px) = the option label inset */
69
+ padding-inline: 20px;
70
+ border-block-end: 1px solid var(--et-surface-border-solid, rgb(255 255 255 / 0.1));
71
+ }
72
+
73
+ .et-cascader-back {
74
+ position: absolute;
75
+ inset-block: 0;
76
+ inset-inline-start: 20px;
77
+ display: inline-flex;
78
+ align-items: center;
79
+ transition:
80
+ opacity 180ms ease,
81
+ transform 180ms ease;
82
+
83
+ &.et-cascader-back--hidden {
84
+ opacity: 0;
85
+ transform: translateX(-6px);
86
+ pointer-events: none;
87
+ }
88
+ }
89
+
90
+ .et-cascader-back-icon {
91
+ rotate: -90deg;
92
+ }
93
+
94
+ .et-cascader-sheet-title-slot {
95
+ position: relative;
96
+ flex: 1;
97
+ min-inline-size: 0;
98
+ align-self: stretch;
99
+ overflow: hidden;
100
+ /* the slot spans the full width and paints over the absolute Back button; the title is
101
+ display-only, so let clicks pass through to Back underneath */
102
+ pointer-events: none;
103
+ }
104
+
105
+ /* the title shifts right to clear Back via transform (transitions reliably, unlike a flex
106
+ width change which jumps); at the root it sits flush-left, aligned with the option labels */
107
+ .et-cascader-sheet-title-shift {
108
+ position: absolute;
109
+ inset: 0;
110
+ transform: translateX(0);
111
+ transition: transform 180ms ease;
112
+ }
113
+
114
+ .et-cascader-sheet-header[data-back] .et-cascader-sheet-title-shift {
115
+ /* em (font-relative), not rem — the app root font can be tiny (10px here) */
116
+ transform: translateX(var(--et-cascader-back-slot, 4em));
117
+ }
118
+
119
+ .et-cascader-sheet-title {
120
+ position: absolute;
121
+ inset: 0;
122
+ display: flex;
123
+ align-items: center;
124
+ overflow: hidden;
125
+ white-space: nowrap;
126
+ text-overflow: ellipsis;
127
+ font-weight: 600;
128
+ color: var(--et-surface-color-solid, currentColor);
129
+ }
130
+
131
+ /* Direction comes from the persistent slot, so the leaving title (kept mounted by
132
+ animate.leave, still a child of the slot) reads the current travel direction too. */
133
+ .et-cascader-sheet-title-slot[data-anim='slide'][data-nav='forward'] .et-cascader-sheet-title--enter {
134
+ animation: et-cascader-title-enter-forward 200ms ease;
135
+ }
136
+
137
+ .et-cascader-sheet-title-slot[data-anim='slide'][data-nav='backward'] .et-cascader-sheet-title--enter {
138
+ animation: et-cascader-title-enter-backward 200ms ease;
139
+ }
140
+
141
+ .et-cascader-sheet-title-slot[data-anim='slide'][data-nav='forward'] .et-cascader-sheet-title--leave {
142
+ animation: et-cascader-title-leave-forward 180ms ease forwards;
143
+ }
144
+
145
+ .et-cascader-sheet-title-slot[data-anim='slide'][data-nav='backward'] .et-cascader-sheet-title--leave {
146
+ animation: et-cascader-title-leave-backward 180ms ease forwards;
147
+ }
148
+
149
+ .et-cascader-sheet-title-slot[data-anim='fade'] .et-cascader-sheet-title--enter {
150
+ animation: et-cascader-title-fade-in 180ms ease;
151
+ }
152
+
153
+ .et-cascader-sheet-title-slot[data-anim='fade'] .et-cascader-sheet-title--leave {
154
+ animation: et-cascader-title-fade-out 180ms ease forwards;
155
+ }
156
+
157
+ /* fixed-height sheet body: header + column area share it, so toggling the Back bar
158
+ redistributes space instead of resizing the panel */
159
+ .et-cascader-sheet-body {
160
+ display: flex;
161
+ flex-direction: column;
162
+ block-size: min(60vh, 480px);
163
+ }
164
+
165
+ .et-cascader-sheet-body .et-cascader-results-wrapper,
166
+ .et-cascader-sheet-columns-wrapper {
167
+ position: relative;
168
+ flex: 1;
169
+ min-block-size: 0;
170
+ }
171
+
172
+ .et-cascader-sheet-columns-wrapper {
173
+ display: flex;
174
+ flex-direction: column;
175
+ }
176
+
177
+ .et-cascader-sheet-body .et-cascader-results {
178
+ flex: 1;
179
+ min-block-size: 0;
180
+ inline-size: 100%;
181
+ max-block-size: none;
182
+ }
183
+
184
+ /* a drilled sheet column does not scroll - the column area around it does - but its content
185
+ still overflows the fixed body, so its own scrollbar would read that as scrollable */
186
+ .et-cascader-columns[data-sheet] .et-cascader-column-wrapper > .et-scrollbar {
187
+ display: none;
188
+ }
189
+ }
190
+
191
+ @keyframes et-cascader-title-enter-forward {
192
+ from {
193
+ opacity: 0;
194
+ transform: translateX(12px);
195
+ }
196
+ }
197
+
198
+ @keyframes et-cascader-title-enter-backward {
199
+ from {
200
+ opacity: 0;
201
+ transform: translateX(-12px);
202
+ }
203
+ }
204
+
205
+ @keyframes et-cascader-title-leave-forward {
206
+ to {
207
+ opacity: 0;
208
+ transform: translateX(-12px);
209
+ }
210
+ }
211
+
212
+ @keyframes et-cascader-title-leave-backward {
213
+ to {
214
+ opacity: 0;
215
+ transform: translateX(12px);
216
+ }
217
+ }
218
+
219
+ @keyframes et-cascader-title-fade-in {
220
+ from {
221
+ opacity: 0;
222
+ }
223
+ }
224
+
225
+ @keyframes et-cascader-title-fade-out {
226
+ to {
227
+ opacity: 0;
228
+ }
229
+ }
230
+
231
+ @media (prefers-reduced-motion: reduce) {
232
+ .et-cascader-panel .et-cascader-sheet-title {
233
+ animation: none;
234
+ }
235
+
236
+ .et-cascader-panel .et-cascader-back,
237
+ .et-cascader-panel .et-cascader-sheet-title-shift {
238
+ transition: none;
239
+ }
240
+ }
241
+ }