@zeyos/zx 4.4.0 → 5.2.0
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 +447 -0
- package/README.md +44 -11
- package/dist/types/components/account-menu/account-menu.d.ts +8 -0
- package/dist/types/components/activity-list/activity-list.d.ts +31 -1
- package/dist/types/components/app-icon/app-icon.d.ts +14 -2
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +293 -17
- package/dist/types/components/avatar/avatar.d.ts +46 -7
- package/dist/types/components/badge/badge.d.ts +21 -1
- package/dist/types/components/button/button.d.ts +15 -0
- package/dist/types/components/calendar/calendar.d.ts +67 -5
- package/dist/types/components/card-view/card-view.d.ts +7 -4
- package/dist/types/components/card-view/record-card.d.ts +11 -0
- package/dist/types/components/chart/chart.d.ts +10 -0
- package/dist/types/components/checklist/checklist.d.ts +9 -0
- package/dist/types/components/code-editor/code-editor.d.ts +6 -17
- package/dist/types/components/context-menu/context-menu.d.ts +6 -2
- package/dist/types/components/data-filter/data-filter.d.ts +4 -4
- package/dist/types/components/datebox/date-range-box.d.ts +5 -1
- package/dist/types/components/datebox/datebox.d.ts +7 -2
- package/dist/types/components/dialog/dialog.d.ts +46 -6
- package/dist/types/components/dropdown/dropdown.d.ts +24 -9
- package/dist/types/components/entity-ref/entity-ref.d.ts +2 -2
- package/dist/types/components/field/field.d.ts +54 -2
- package/dist/types/components/fieldset/external-adapter.d.ts +83 -0
- package/dist/types/components/fieldset/fieldset.d.ts +26 -1
- package/dist/types/components/file-item/file-item.d.ts +34 -6
- package/dist/types/components/file-list/file-list.d.ts +35 -3
- package/dist/types/components/filter/filter.d.ts +127 -3
- package/dist/types/components/filter-panel/filter-panel.d.ts +36 -7
- package/dist/types/components/form/form.d.ts +12 -1
- package/dist/types/components/kanban-view/kanban-card.d.ts +8 -0
- package/dist/types/components/launcher/launcher.d.ts +268 -15
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +16 -7
- package/dist/types/components/menu-button/menu-button.d.ts +39 -5
- package/dist/types/components/message/message.d.ts +132 -17
- package/dist/types/components/modal/modal.d.ts +43 -2
- package/dist/types/components/module-bar/module-bar.d.ts +395 -0
- package/dist/types/components/pagination/pagination.d.ts +17 -3
- package/dist/types/components/select/color.d.ts +12 -0
- package/dist/types/components/select/glyphs.d.ts +124 -0
- package/dist/types/components/select/select.d.ts +17 -3
- package/dist/types/components/sheet/sheet.d.ts +15 -0
- package/dist/types/components/stat-tile/stat-tile.d.ts +16 -5
- package/dist/types/components/tabbox/tabbox.d.ts +9 -0
- package/dist/types/components/table/table.d.ts +311 -18
- package/dist/types/components/tag-picker/tag-picker.d.ts +21 -4
- package/dist/types/components/tree/tree.d.ts +13 -0
- package/dist/types/components/view/record-view.d.ts +59 -2
- package/dist/types/components/view-settings/view-settings.d.ts +879 -0
- package/dist/types/components/workspace-switcher/workspace-switcher.d.ts +327 -0
- package/dist/types/core/breakpoint.d.ts +1 -1
- package/dist/types/core/component.d.ts +12 -2
- package/dist/types/core/i18n.d.ts +27 -3
- package/dist/types/core/icons.d.ts +23 -25
- package/dist/types/core/keyboard.d.ts +98 -1
- package/dist/types/core/messages.d.ts +382 -0
- package/dist/types/core/motion.d.ts +59 -0
- package/dist/types/core/overlay-host.d.ts +42 -1
- package/dist/types/core/overlay-stack.d.ts +260 -0
- package/dist/types/index.d.ts +10 -5
- package/dist/types/internal/app-rail.d.ts +38 -0
- package/dist/types/internal/menu-items.d.ts +71 -3
- package/dist/types/zeyos/connect.d.ts +6 -0
- package/dist/types/zeyos/form.d.ts +50 -9
- package/dist/types/zeyos/index.d.ts +2 -1
- package/dist/types/zeyos/launcher.d.ts +9 -0
- package/dist/types/zeyos/module-bar.d.ts +176 -0
- package/dist/types/zeyos/query.d.ts +110 -5
- package/dist/types/zeyos/schema.d.ts +24 -1
- package/dist/types/zeyos/table.d.ts +345 -22
- package/dist/types/zeyos/view.d.ts +26 -2
- package/dist/zx-zeyos.esm.js +6178 -1008
- package/dist/zx-zeyos.esm.min.js +53 -5
- package/dist/zx.css +2861 -827
- package/dist/zx.esm.js +8909 -1480
- package/dist/zx.esm.min.js +55 -7
- package/dist/zx.global.js +8911 -1482
- package/dist/zx.global.min.js +55 -7
- package/dist/zx.min.css +1 -1
- package/docs/api.json +1079 -117
- package/docs/llms.md +956 -154
- package/docs/llms.txt +9 -5
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.css +35 -10
- package/src/components/account-menu/account-menu.js +12 -0
- package/src/components/activity-item/activity-item.css +1 -1
- package/src/components/activity-item/activity-item.js +3 -0
- package/src/components/activity-list/activity-list.css +38 -3
- package/src/components/activity-list/activity-list.js +61 -1
- package/src/components/app-icon/app-icon.css +14 -3
- package/src/components/app-icon/app-icon.js +11 -1
- package/src/components/app-rail/app-rail.css +59 -79
- package/src/components/app-sidebar/app-sidebar.css +304 -168
- package/src/components/app-sidebar/app-sidebar.js +667 -46
- package/src/components/aurora/aurora.css +5 -3
- package/src/components/avatar/avatar.css +32 -7
- package/src/components/avatar/avatar.js +72 -8
- package/src/components/badge/badge.css +54 -2
- package/src/components/badge/badge.js +29 -2
- package/src/components/breadcrumb/breadcrumb.css +1 -1
- package/src/components/button/button.css +67 -9
- package/src/components/button/button.js +38 -0
- package/src/components/calendar/calendar.css +47 -47
- package/src/components/calendar/calendar.js +26 -52
- package/src/components/card/card.css +4 -4
- package/src/components/card-view/card-view.css +14 -12
- package/src/components/card-view/card-view.js +13 -9
- package/src/components/card-view/record-card.js +14 -3
- package/src/components/chart/chart.css +4 -1
- package/src/components/chart/chart.js +12 -0
- package/src/components/check-button/check-button.css +10 -2
- package/src/components/checklist/checklist.css +9 -2
- package/src/components/checklist/checklist.js +11 -5
- package/src/components/checklist/field-adapter.js +3 -1
- package/src/components/code-editor/code-editor.css +7 -6
- package/src/components/code-editor/code-editor.js +19 -1
- package/src/components/code-editor/field-adapter.js +9 -2
- package/src/components/context-menu/context-menu.css +9 -4
- package/src/components/context-menu/context-menu.js +8 -2
- package/src/components/copy/copy-button.css +6 -0
- package/src/components/copy/copy-input.css +9 -4
- package/src/components/data-filter/data-filter.css +5 -4
- package/src/components/data-filter/data-filter.js +2 -2
- package/src/components/date-picker/date-picker.css +6 -6
- package/src/components/date-picker/date-range-picker.css +3 -3
- package/src/components/date-picker/time-picker.css +3 -3
- package/src/components/datebox/date-range-box.css +79 -2
- package/src/components/datebox/date-range-box.js +13 -2
- package/src/components/datebox/datebox.css +79 -2
- package/src/components/datebox/datebox.js +13 -2
- package/src/components/dialog/dialog.css +26 -0
- package/src/components/dialog/dialog.js +99 -17
- package/src/components/dock/dock.css +5 -4
- package/src/components/dropdown/dropdown.css +1 -1
- package/src/components/dropdown/dropdown.js +159 -72
- package/src/components/empty-state/empty-state.css +2 -2
- package/src/components/entity-ref/entity-ref.css +1 -1
- package/src/components/entity-ref/entity-ref.js +1 -1
- package/src/components/field/field.css +28 -9
- package/src/components/field/field.js +101 -29
- package/src/components/field-upload/field-upload.css +1 -1
- package/src/components/fieldset/external-adapter.js +363 -0
- package/src/components/fieldset/fieldset.css +5 -3
- package/src/components/fieldset/fieldset.js +38 -64
- package/src/components/file-item/file-item.js +144 -10
- package/src/components/file-list/file-list.js +144 -21
- package/src/components/filter/filter.css +86 -2
- package/src/components/filter/filter.js +307 -11
- package/src/components/filter-panel/filter-panel.css +1 -1
- package/src/components/filter-panel/filter-panel.js +149 -32
- package/src/components/finder/finder.css +16 -14
- package/src/components/form/form.css +5 -4
- package/src/components/form/form.js +11 -2
- package/src/components/grid/grid.css +1 -1
- package/src/components/groupbox/groupbox.css +1 -1
- package/src/components/kanban-view/kanban-card.js +11 -3
- package/src/components/kanban-view/kanban-view.css +42 -18
- package/src/components/kanban-view/kanban-view.js +9 -6
- package/src/components/launcher/launcher.css +108 -26
- package/src/components/launcher/launcher.js +530 -42
- package/src/components/list-toolbar/list-toolbar.css +13 -8
- package/src/components/list-toolbar/list-toolbar.js +40 -14
- package/src/components/master-panel/master-panel.css +2 -0
- package/src/components/master-panel/master-panel.js +0 -1
- package/src/components/menu-button/menu-button.css +72 -4
- package/src/components/menu-button/menu-button.js +160 -18
- package/src/components/message/message.css +33 -3
- package/src/components/message/message.js +264 -22
- package/src/components/modal/modal.css +1 -1
- package/src/components/modal/modal.js +83 -15
- package/src/components/module-bar/module-bar.css +486 -0
- package/src/components/module-bar/module-bar.js +1074 -0
- package/src/components/multi-value-editor/multi-value-editor.css +1 -1
- package/src/components/navigation-bar/navigation-bar.css +18 -9
- package/src/components/number-field/field-adapter.js +3 -1
- package/src/components/number-field/number-field.css +70 -0
- package/src/components/number-field/number-field.js +2 -0
- package/src/components/pagination/pagination.css +13 -11
- package/src/components/pagination/pagination.js +20 -4
- package/src/components/panel/panel.css +4 -3
- package/src/components/questionnaire/questionnaire.css +4 -4
- package/src/components/rating/field-adapter.js +2 -1
- package/src/components/rating/rating.css +8 -1
- package/src/components/search/search.css +4 -1
- package/src/components/select/color.js +22 -0
- package/src/components/select/field-adapter.js +2 -0
- package/src/components/select/glyphs.js +165 -0
- package/src/components/select/select.css +138 -45
- package/src/components/select/select.js +92 -47
- package/src/components/sheet/sheet.css +12 -9
- package/src/components/sheet/sheet.js +74 -32
- package/src/components/slider/field-adapter.js +6 -1
- package/src/components/slider/slider.css +18 -4
- package/src/components/slider/slider.js +1 -1
- package/src/components/sort-control/sort-control.css +4 -1
- package/src/components/split-view/split-view.css +1 -1
- package/src/components/stat-tile/stat-tile.css +42 -47
- package/src/components/stat-tile/stat-tile.js +17 -6
- package/src/components/stepper/stepper.css +1 -1
- package/src/components/tabbox/tabbox.css +41 -32
- package/src/components/tabbox/tabbox.js +5 -1
- package/src/components/table/table.css +187 -37
- package/src/components/table/table.js +718 -73
- package/src/components/tag-picker/field-adapter.js +2 -1
- package/src/components/tag-picker/tag-picker.css +83 -5
- package/src/components/tag-picker/tag-picker.js +25 -8
- package/src/components/timebox/timebox.css +22 -2
- package/src/components/toggle/toggle.css +12 -1
- package/src/components/toolbar/toolbar.js +2 -2
- package/src/components/tooltip/tooltip.css +4 -0
- package/src/components/tooltip/tooltip.js +44 -19
- package/src/components/tree/tree.css +26 -17
- package/src/components/tree/tree.js +31 -0
- package/src/components/value-list/value-list.css +3 -3
- package/src/components/view/record-view.css +1 -1
- package/src/components/view/record-view.js +178 -18
- package/src/components/view-settings/view-settings.css +285 -0
- package/src/components/view-settings/view-settings.js +1830 -0
- package/src/components/workspace-switcher/workspace-switcher.css +188 -0
- package/src/components/workspace-switcher/workspace-switcher.js +463 -0
- package/src/core/breakpoint.js +1 -1
- package/src/core/component.js +88 -17
- package/src/core/fontawesome.js +5 -1
- package/src/core/i18n.js +47 -4
- package/src/core/icons.js +204 -61
- package/src/core/keyboard.js +206 -11
- package/src/core/messages.js +427 -0
- package/src/core/motion.js +147 -0
- package/src/core/overlay-host.js +77 -3
- package/src/core/overlay-stack.js +487 -0
- package/src/core/position.js +22 -3
- package/src/index.js +10 -5
- package/src/internal/app-rail.js +135 -55
- package/src/internal/menu-items.js +61 -3
- package/src/zeyos/connect.js +6 -2
- package/src/zeyos/form.js +69 -27
- package/src/zeyos/index.js +4 -1
- package/src/zeyos/launcher.js +8 -3
- package/src/zeyos/module-bar.js +181 -0
- package/src/zeyos/query.js +197 -13
- package/src/zeyos/schema.js +144 -27
- package/src/zeyos/table.js +287 -84
- package/src/zeyos/view.js +49 -93
- package/styles/base.css +72 -1
- package/styles/icons.css +11 -1
- package/styles/print.css +1 -1
- package/styles/tokens/dark.css +117 -37
- package/styles/tokens/global.css +121 -27
- package/styles/tokens/semantic.css +140 -43
- package/styles/tokens/themes.css +7 -6
- package/styles/zx.css +3 -1
- package/styles/tokens/density.css +0 -9
|
@@ -30,7 +30,10 @@
|
|
|
30
30
|
padding-inline-start: var(--zx-space-2) !important;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
.
|
|
33
|
+
/* The ring follows keyboard focus. A text input matches :focus-visible on a click as well, so the
|
|
34
|
+
component marks a pointer focus on a read-only input (`data-focus-origin="pointer"`) and the ring
|
|
35
|
+
waits for the first key. An editable input keeps it on click, as any text field does. */
|
|
36
|
+
.zx-select:not([data-focus-origin="pointer"]) .zx-select__control:has(.zx-select__input:focus-visible) {
|
|
34
37
|
box-shadow: var(--zx-focus-ring);
|
|
35
38
|
}
|
|
36
39
|
|
|
@@ -85,9 +88,17 @@
|
|
|
85
88
|
border-radius: var(--zx-radius-full);
|
|
86
89
|
}
|
|
87
90
|
|
|
91
|
+
/* Disabled reads the way a disabled Field does: text and frame fade together, nothing else
|
|
92
|
+
changes. Inside a disabled Field the field has already faded, so the Select does not again. */
|
|
93
|
+
.zx-select[aria-disabled="true"] {
|
|
94
|
+
opacity: 0.65;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.zx-field[data-disabled="true"] .zx-select[aria-disabled="true"] {
|
|
98
|
+
opacity: 1;
|
|
99
|
+
}
|
|
100
|
+
|
|
88
101
|
.zx-select[aria-disabled="true"] .zx-select__control {
|
|
89
|
-
background: var(--zx-color-bg-page);
|
|
90
|
-
color: var(--zx-color-text-muted);
|
|
91
102
|
cursor: default;
|
|
92
103
|
}
|
|
93
104
|
|
|
@@ -97,7 +108,7 @@
|
|
|
97
108
|
max-inline-size: calc(100vw - var(--zx-space-4));
|
|
98
109
|
overflow: hidden;
|
|
99
110
|
border: 1px solid var(--zx-color-overlay-border);
|
|
100
|
-
border-radius: var(--zx-radius-
|
|
111
|
+
border-radius: var(--zx-radius-lg);
|
|
101
112
|
background-color: var(--zx-color-overlay-surface);
|
|
102
113
|
background-image: var(--zx-overlay-surface-image);
|
|
103
114
|
background-clip: padding-box;
|
|
@@ -118,10 +129,12 @@
|
|
|
118
129
|
display: flex;
|
|
119
130
|
align-items: center;
|
|
120
131
|
gap: var(--zx-space-2);
|
|
121
|
-
|
|
132
|
+
/* The same row as a menu item: a little under a control, the smallest radius. */
|
|
133
|
+
min-block-size: calc(var(--zx-control-height) - 2px);
|
|
122
134
|
border-radius: var(--zx-radius-sm);
|
|
123
135
|
cursor: default;
|
|
124
|
-
padding: var(--zx-space-1) var(--zx-
|
|
136
|
+
padding: var(--zx-space-1) var(--zx-space-2);
|
|
137
|
+
line-height: 1.35;
|
|
125
138
|
}
|
|
126
139
|
|
|
127
140
|
.zx-select__option-content {
|
|
@@ -137,6 +150,8 @@
|
|
|
137
150
|
background: var(--zx-color-overlay-hover);
|
|
138
151
|
}
|
|
139
152
|
|
|
153
|
+
/* The highlighted option (keyboard or pointer) is a neutral step; a chosen option is a pick and
|
|
154
|
+
keeps the accent tint and its check mark. */
|
|
140
155
|
.zx-select__option[aria-selected="true"] {
|
|
141
156
|
background: var(--zx-color-overlay-selected);
|
|
142
157
|
}
|
|
@@ -146,6 +161,7 @@
|
|
|
146
161
|
color: var(--zx-color-accent);
|
|
147
162
|
}
|
|
148
163
|
|
|
164
|
+
/* A caption for the options under it, in sentence case: quieter than the options, never louder. */
|
|
149
165
|
.zx-select__group {
|
|
150
166
|
position: sticky;
|
|
151
167
|
z-index: 1;
|
|
@@ -153,10 +169,8 @@
|
|
|
153
169
|
background: var(--zx-color-overlay-scrim);
|
|
154
170
|
color: var(--zx-color-text-muted);
|
|
155
171
|
font-size: var(--zx-text-xs);
|
|
156
|
-
font-weight:
|
|
157
|
-
|
|
158
|
-
padding: var(--zx-space-2) var(--zx-control-pad-x) var(--zx-space-1);
|
|
159
|
-
text-transform: uppercase;
|
|
172
|
+
font-weight: var(--zx-weight-semibold);
|
|
173
|
+
padding: var(--zx-space-1) var(--zx-space-2);
|
|
160
174
|
}
|
|
161
175
|
|
|
162
176
|
@media (prefers-reduced-transparency: reduce) {
|
|
@@ -175,13 +189,13 @@
|
|
|
175
189
|
|
|
176
190
|
.zx-select__separator {
|
|
177
191
|
block-size: 1px;
|
|
178
|
-
margin: var(--zx-space-1) var(--zx-
|
|
192
|
+
margin: var(--zx-space-1) var(--zx-space-2);
|
|
179
193
|
background: var(--zx-color-overlay-divider);
|
|
180
194
|
}
|
|
181
195
|
|
|
182
196
|
.zx-select__empty {
|
|
183
197
|
color: var(--zx-color-text-muted);
|
|
184
|
-
padding: var(--zx-space-3) var(--zx-
|
|
198
|
+
padding: var(--zx-space-3) var(--zx-space-2);
|
|
185
199
|
text-align: center;
|
|
186
200
|
}
|
|
187
201
|
|
|
@@ -191,30 +205,59 @@
|
|
|
191
205
|
gap: var(--zx-space-2);
|
|
192
206
|
}
|
|
193
207
|
|
|
194
|
-
.
|
|
208
|
+
/* The priority glyph — `priorityIcon()`, and the one Select.priority() draws, which also carries
|
|
209
|
+
`.zx-select__priority-icon`. Priority is read by height, not by hue: four signal bars, the filled
|
|
210
|
+
ones in muted ink and the rest a step quieter. Only the top level, the one that needs attention,
|
|
211
|
+
is coloured — a danger square with an exclamation mark. "No priority" is a row of dashes. Every
|
|
212
|
+
glyph takes the same box, so the labels after them line up. */
|
|
213
|
+
.zx-priority-icon {
|
|
195
214
|
display: inline-flex;
|
|
196
|
-
gap: 2px;
|
|
197
215
|
flex: none;
|
|
198
|
-
|
|
216
|
+
vertical-align: middle;
|
|
217
|
+
align-items: flex-end;
|
|
218
|
+
gap: 1px;
|
|
219
|
+
box-sizing: border-box;
|
|
220
|
+
inline-size: 15px;
|
|
221
|
+
block-size: 14px;
|
|
222
|
+
padding-block: 1px;
|
|
223
|
+
color: var(--zx-color-text-muted);
|
|
199
224
|
}
|
|
200
225
|
|
|
201
|
-
.zx-
|
|
202
|
-
inline-size:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
border-radius: 2px;
|
|
226
|
+
.zx-priority-icon > span {
|
|
227
|
+
inline-size: 3px;
|
|
228
|
+
border-radius: 1px;
|
|
229
|
+
background: var(--zx-color-border-strong);
|
|
206
230
|
}
|
|
207
231
|
|
|
208
|
-
.zx-
|
|
209
|
-
.zx-
|
|
210
|
-
.zx-
|
|
211
|
-
|
|
232
|
+
.zx-priority-icon > span:nth-child(1) { block-size: 25%; }
|
|
233
|
+
.zx-priority-icon > span:nth-child(2) { block-size: 50%; }
|
|
234
|
+
.zx-priority-icon > span:nth-child(3) { block-size: 75%; }
|
|
235
|
+
.zx-priority-icon > span:nth-child(4) { block-size: 100%; }
|
|
236
|
+
.zx-priority-icon > span[data-filled="true"] { background: currentColor; }
|
|
237
|
+
|
|
238
|
+
.zx-priority-icon[data-level="none"] { align-items: center; }
|
|
239
|
+
.zx-priority-icon[data-level="none"] > span {
|
|
240
|
+
block-size: 2px;
|
|
241
|
+
background: currentColor;
|
|
212
242
|
}
|
|
213
|
-
|
|
214
|
-
.zx-
|
|
215
|
-
|
|
243
|
+
|
|
244
|
+
.zx-priority-icon[data-level="4"] {
|
|
245
|
+
align-items: center;
|
|
246
|
+
justify-content: center;
|
|
247
|
+
inline-size: 14px;
|
|
248
|
+
margin-inline-end: 1px;
|
|
249
|
+
padding: 0;
|
|
250
|
+
border-radius: var(--zx-radius-sm);
|
|
251
|
+
background: var(--zx-color-danger);
|
|
252
|
+
color: var(--zx-color-on-accent);
|
|
253
|
+
font-size: 11px;
|
|
254
|
+
font-weight: var(--zx-weight-semibold);
|
|
255
|
+
line-height: 1;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.zx-priority-icon[data-level="4"]::before {
|
|
259
|
+
content: "!";
|
|
216
260
|
}
|
|
217
|
-
.zx-select__priority-icon[data-level="4"] { color: var(--zx-color-danger); }
|
|
218
261
|
|
|
219
262
|
.zx-select__status {
|
|
220
263
|
display: grid;
|
|
@@ -223,13 +266,20 @@
|
|
|
223
266
|
gap: var(--zx-space-2);
|
|
224
267
|
}
|
|
225
268
|
|
|
269
|
+
/* An entity without a colour of its own is a neutral tile with muted ink; one with a colour is
|
|
270
|
+
filled with it and drawn in the inverse text colour. */
|
|
226
271
|
.zx-select__entity-glyph {
|
|
227
272
|
display: inline-grid;
|
|
228
273
|
place-items: center;
|
|
229
274
|
inline-size: 20px;
|
|
230
275
|
block-size: 20px;
|
|
231
276
|
border-radius: var(--zx-radius-sm);
|
|
232
|
-
background: var(--zx-
|
|
277
|
+
background: var(--zx-color-bg-muted);
|
|
278
|
+
color: var(--zx-color-text-muted);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.zx-select__entity-glyph[style*="--zx-select-entity-color"] {
|
|
282
|
+
background: var(--zx-select-entity-color);
|
|
233
283
|
color: var(--zx-color-text-invert);
|
|
234
284
|
}
|
|
235
285
|
|
|
@@ -256,10 +306,14 @@
|
|
|
256
306
|
font-size: var(--zx-text-xs);
|
|
257
307
|
}
|
|
258
308
|
|
|
259
|
-
|
|
309
|
+
/* The workflow-status glyph — `statusIcon()`, and the one Select.status() draws, which also carries
|
|
310
|
+
`.zx-select__status-indicator`. Each status is a shape first and a colour second. */
|
|
311
|
+
.zx-status-icon {
|
|
260
312
|
position: relative;
|
|
261
313
|
display: inline-grid;
|
|
262
314
|
place-items: center;
|
|
315
|
+
box-sizing: border-box;
|
|
316
|
+
vertical-align: middle;
|
|
263
317
|
inline-size: 14px;
|
|
264
318
|
block-size: 14px;
|
|
265
319
|
flex: none;
|
|
@@ -268,37 +322,37 @@
|
|
|
268
322
|
color: var(--zx-color-text-muted);
|
|
269
323
|
}
|
|
270
324
|
|
|
271
|
-
.zx-
|
|
272
|
-
.zx-
|
|
273
|
-
.zx-
|
|
274
|
-
.zx-
|
|
275
|
-
.zx-
|
|
276
|
-
.zx-
|
|
325
|
+
.zx-status-icon[data-tone="neutral"] { color: var(--zx-color-border-strong); }
|
|
326
|
+
.zx-status-icon[data-tone="warning"] { color: var(--zx-color-warning); }
|
|
327
|
+
.zx-status-icon[data-tone="info"] { color: var(--zx-color-info); }
|
|
328
|
+
.zx-status-icon[data-tone="accent"] { color: var(--zx-color-accent); }
|
|
329
|
+
.zx-status-icon[data-tone="success"] { color: var(--zx-color-success); }
|
|
330
|
+
.zx-status-icon[data-tone="danger"] { color: var(--zx-color-danger); }
|
|
277
331
|
|
|
278
|
-
.zx-
|
|
279
|
-
.zx-
|
|
332
|
+
.zx-status-icon[data-indicator="dotted"] { border-style: dotted; }
|
|
333
|
+
.zx-status-icon[data-indicator="progress"]::after {
|
|
280
334
|
content: "";
|
|
281
335
|
inline-size: 4px;
|
|
282
336
|
block-size: 4px;
|
|
283
337
|
border-radius: inherit;
|
|
284
338
|
background: currentColor;
|
|
285
339
|
}
|
|
286
|
-
.zx-
|
|
340
|
+
.zx-status-icon[data-indicator="review"] {
|
|
287
341
|
background: linear-gradient(90deg, currentColor 50%, transparent 50%);
|
|
288
342
|
}
|
|
289
|
-
.zx-
|
|
343
|
+
.zx-status-icon[data-indicator="ready"] {
|
|
290
344
|
background: conic-gradient(currentColor 0 35%, transparent 35% 100%);
|
|
291
345
|
}
|
|
292
|
-
.zx-
|
|
346
|
+
.zx-status-icon[data-indicator="waiting"] {
|
|
293
347
|
background: conic-gradient(currentColor 0 70%, transparent 70% 100%);
|
|
294
348
|
}
|
|
295
|
-
.zx-
|
|
349
|
+
.zx-status-icon:is([data-indicator="done"], [data-indicator="canceled"]) {
|
|
296
350
|
background: currentColor;
|
|
297
351
|
}
|
|
298
|
-
.zx-
|
|
352
|
+
.zx-status-icon:is([data-indicator="done"], [data-indicator="canceled"]) > .zx-icon {
|
|
299
353
|
color: var(--zx-color-bg-raised);
|
|
300
354
|
}
|
|
301
|
-
.zx-
|
|
355
|
+
.zx-status-icon[data-indicator="duplicate"]::after {
|
|
302
356
|
content: "";
|
|
303
357
|
inline-size: 8px;
|
|
304
358
|
block-size: 2px;
|
|
@@ -343,7 +397,7 @@
|
|
|
343
397
|
|
|
344
398
|
@media (prefers-reduced-motion: no-preference) {
|
|
345
399
|
.zx-select__loading {
|
|
346
|
-
animation: zx-select-spin
|
|
400
|
+
animation: zx-select-spin 720ms linear infinite;
|
|
347
401
|
}
|
|
348
402
|
}
|
|
349
403
|
|
|
@@ -352,3 +406,42 @@
|
|
|
352
406
|
transform: rotate(1turn);
|
|
353
407
|
}
|
|
354
408
|
}
|
|
409
|
+
|
|
410
|
+
/*
|
|
411
|
+
* Quiet fields. Inside `[data-zx-fields="quiet"]` — a property panel, an inspector — the control
|
|
412
|
+
* reads as its value: no border, no fill, no chevron or clear button. Hover brings the hover fill
|
|
413
|
+
* and the chevron back; focus or an open list brings back the border, the control fill and the
|
|
414
|
+
* focus ring. A disabled control never lights up.
|
|
415
|
+
*/
|
|
416
|
+
[data-zx-fields="quiet"] .zx-select__control,
|
|
417
|
+
[data-zx-fields="quiet"] .zx-select[aria-disabled="true"] .zx-select__control {
|
|
418
|
+
border-color: transparent;
|
|
419
|
+
background: transparent;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
[data-zx-fields="quiet"] .zx-select :is(.zx-select__toggle, .zx-select__clear) {
|
|
423
|
+
opacity: 0;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
[data-zx-fields="quiet"] .zx-select:not([aria-disabled="true"]):hover .zx-select__control {
|
|
427
|
+
background: var(--zx-color-bg-hover);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
[data-zx-fields="quiet"] .zx-select:not([aria-disabled="true"]):is(:hover, :focus-within, [data-state="open"]) :is(.zx-select__toggle, .zx-select__clear) {
|
|
431
|
+
opacity: 1;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
[data-zx-fields="quiet"] .zx-select:not([aria-disabled="true"]):is(:focus-within, [data-state="open"]) .zx-select__control {
|
|
435
|
+
border-color: var(--zx-color-border-control);
|
|
436
|
+
background: var(--zx-color-bg-control);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
440
|
+
[data-zx-fields="quiet"] .zx-select__control {
|
|
441
|
+
transition: background-color var(--zx-dur-fast) var(--zx-ease), border-color var(--zx-dur-fast) var(--zx-ease);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
[data-zx-fields="quiet"] .zx-select :is(.zx-select__toggle, .zx-select__clear) {
|
|
445
|
+
transition: opacity var(--zx-dur-fast) var(--zx-ease);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
@@ -3,8 +3,12 @@ import { h, restoreTarget, snapshotTarget } from '../../core/dom.js';
|
|
|
3
3
|
import { icon } from '../../core/icons.js';
|
|
4
4
|
import { typeahead } from '../../core/keyboard.js';
|
|
5
5
|
import { position } from '../../core/position.js';
|
|
6
|
-
import {
|
|
6
|
+
import { uid } from '../../core/util.js';
|
|
7
|
+
import { itemColor } from './color.js';
|
|
7
8
|
import { matchItems } from './filter.js';
|
|
9
|
+
import {
|
|
10
|
+
DEFAULT_STATUSES, STATUS_INDICATORS, STATUS_TONES, normalizePriorityLevel, priorityIcon, statusIcon
|
|
11
|
+
} from './glyphs.js';
|
|
8
12
|
|
|
9
13
|
/** @typedef {string|number|boolean|symbol|bigint|null|undefined} Primitive */
|
|
10
14
|
/** @typedef {Record<string, any>|Primitive} SelectItem */
|
|
@@ -49,7 +53,9 @@ import { matchItems } from './filter.js';
|
|
|
49
53
|
* @property {string} [recentLabel='Recent'] Heading above recent choices.
|
|
50
54
|
* @property {boolean|SelectAction} [create=false] Optional create command at the bottom.
|
|
51
55
|
* @property {string|((item: SelectItem)=>unknown)} [iconKey='icon'] Item icon reader.
|
|
52
|
-
* @property {string|((item: SelectItem)=>unknown)} [colorKey='color'] Optional icon colour reader
|
|
56
|
+
* @property {string|((item: SelectItem)=>unknown)} [colorKey='color'] Optional icon colour reader: a CSS
|
|
57
|
+
* colour or a token reference such as `var(--zx-color-tone-blue-fg)`. Without one the glyph is a
|
|
58
|
+
* neutral tile in muted ink.
|
|
53
59
|
* @property {string|((item: SelectItem)=>unknown)} [subtitleKey='description'] Secondary-text reader.
|
|
54
60
|
* @property {((item: SelectItem, context:{selected:boolean})=>Node|string|null)|null} [renderIcon=null] Entity icon renderer.
|
|
55
61
|
*/
|
|
@@ -69,18 +75,6 @@ const PRIORITY_KEYS = [
|
|
|
69
75
|
];
|
|
70
76
|
const PRIORITY_FALLBACKS = ['Lowest', 'Low', 'Medium', 'High', 'Highest'];
|
|
71
77
|
|
|
72
|
-
const DEFAULT_STATUSES = Object.freeze([
|
|
73
|
-
['backlog', 'status.backlog', 'Backlog', 'dotted', 'muted'],
|
|
74
|
-
['todo', 'status.todo', 'Todo', 'ring', 'neutral'],
|
|
75
|
-
['in-progress', 'status.inProgress', 'In Progress', 'progress', 'warning'],
|
|
76
|
-
['in-review', 'status.inReview', 'In Review', 'review', 'info'],
|
|
77
|
-
['ready', 'status.ready', 'Ready to Merge', 'ready', 'accent'],
|
|
78
|
-
['waiting', 'status.waiting', 'Waiting for feedback', 'waiting', 'warning'],
|
|
79
|
-
['done', 'status.done', 'Done', 'done', 'info'],
|
|
80
|
-
['canceled', 'status.canceled', 'Canceled', 'canceled', 'muted'],
|
|
81
|
-
['duplicate', 'status.duplicate', 'Duplicate', 'duplicate', 'muted']
|
|
82
|
-
]);
|
|
83
|
-
|
|
84
78
|
/**
|
|
85
79
|
* APG editable combobox with optional local or asynchronous filtering.
|
|
86
80
|
*
|
|
@@ -125,7 +119,7 @@ export class Select extends Component {
|
|
|
125
119
|
render() {
|
|
126
120
|
// Instance state initialized here because render() runs inside the base
|
|
127
121
|
// constructor, before class-field initializers would run (and clobber it).
|
|
128
|
-
this._items = []; this._visibleItems = []; this._fixedItems = []; this._visibleFixed = []; this._actions = []; this._selected = null; this._optionEntries = []; this._activeIndex = -1; this._open = false; this._disabled = false; this._loading = false; this._requestSequence = 0; this._queryTimer = null; this._position = null; this._createdRoot = false; this._root = null; this._snapshot = null;
|
|
122
|
+
this._items = []; this._visibleItems = []; this._fixedItems = []; this._visibleFixed = []; this._actions = []; this._selected = null; this._optionEntries = []; this._activeIndex = -1; this._open = false; this._disabled = false; this._loading = false; this._requestSequence = 0; this._queryTimer = null; this._position = null; this._createdRoot = false; this._root = null; this._snapshot = null; this._pointerModality = false;
|
|
129
123
|
this._createdRoot = this.el === null;
|
|
130
124
|
const root = /** @type {HTMLElement} */ (this.el ?? h('div'));
|
|
131
125
|
this.el = root;
|
|
@@ -209,7 +203,22 @@ export class Select extends Component {
|
|
|
209
203
|
|
|
210
204
|
this.listen(input, 'click', () => this.open());
|
|
211
205
|
this.listen(input, 'input', () => this._onInput());
|
|
212
|
-
this.listen(input, 'keydown', (event) =>
|
|
206
|
+
this.listen(input, 'keydown', (event) => {
|
|
207
|
+
if (!isModifierKey(/** @type {KeyboardEvent} */ (event))) root.removeAttribute('data-focus-origin');
|
|
208
|
+
this._onKeydown(/** @type {KeyboardEvent} */ (event));
|
|
209
|
+
});
|
|
210
|
+
// A text input matches :focus-visible however it was focused, read-only or not, so a click on
|
|
211
|
+
// a read-only Select would draw the keyboard ring. Track how the user last interacted and mark
|
|
212
|
+
// a pointer focus; the ring then follows keyboard focus only, and returns on the first key.
|
|
213
|
+
this.listen(input, 'focus', () => {
|
|
214
|
+
if (this._pointerModality && /** @type {HTMLInputElement} */ (input).readOnly) {
|
|
215
|
+
root.setAttribute('data-focus-origin', 'pointer');
|
|
216
|
+
} else root.removeAttribute('data-focus-origin');
|
|
217
|
+
});
|
|
218
|
+
this.listen(input, 'blur', () => root.removeAttribute('data-focus-origin'));
|
|
219
|
+
this.listen(document, 'keydown', (event) => {
|
|
220
|
+
if (!isModifierKey(/** @type {KeyboardEvent} */ (event))) this._pointerModality = false;
|
|
221
|
+
}, { capture: true });
|
|
213
222
|
this.listen(toggle, 'click', () => {
|
|
214
223
|
this.focus();
|
|
215
224
|
if (this._open) this.close();
|
|
@@ -222,6 +231,7 @@ export class Select extends Component {
|
|
|
222
231
|
this.listen(panel, 'pointerdown', (event) => event.preventDefault());
|
|
223
232
|
this.listen(panel, 'click', (event) => this._onOptionClick(event));
|
|
224
233
|
this.listen(document, 'pointerdown', (event) => {
|
|
234
|
+
this._pointerModality = true;
|
|
225
235
|
if (this._open && !root.contains(/** @type {Node} */ (event.target))) this.close();
|
|
226
236
|
}, { capture: true });
|
|
227
237
|
|
|
@@ -241,6 +251,15 @@ export class Select extends Component {
|
|
|
241
251
|
this.set(id);
|
|
242
252
|
}
|
|
243
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Returns the selected item ID, or null: the same as reading `value`, under the `get()`/`set()`
|
|
256
|
+
* pair the other value components share.
|
|
257
|
+
* @returns {unknown}
|
|
258
|
+
*/
|
|
259
|
+
get() {
|
|
260
|
+
return this.value;
|
|
261
|
+
}
|
|
262
|
+
|
|
244
263
|
/** Selected item, or null. @returns {SelectItem|null} */
|
|
245
264
|
get selected() {
|
|
246
265
|
return this._selected;
|
|
@@ -381,26 +400,44 @@ export class Select extends Component {
|
|
|
381
400
|
}
|
|
382
401
|
|
|
383
402
|
/**
|
|
384
|
-
* Creates the five-level priority preset
|
|
403
|
+
* Creates the five-level priority preset: values 0 (lowest) to 4 (highest), each drawn as grey
|
|
404
|
+
* signal bars filled to its level, except the highest, which is the one coloured level — a
|
|
405
|
+
* danger square with an exclamation mark. A "No priority" row (value null, a row of dashes)
|
|
406
|
+
* heads the list and labels the empty control; `clearable: false` removes it.
|
|
385
407
|
* @param {Element|string|null} target Component target.
|
|
386
|
-
* @param {SelectOptions} [options={}] Select overrides other than
|
|
408
|
+
* @param {SelectOptions} [options={}] Select overrides other than items and renderers.
|
|
409
|
+
* `clearable` defaults to true here; `noneLabel` and `placeholder` default to the
|
|
410
|
+
* `priority.none` message ("No priority").
|
|
387
411
|
* @returns {Select}
|
|
388
412
|
*/
|
|
389
413
|
static priority(target, options = {}) {
|
|
390
414
|
const requestedValue = options.value ?? null;
|
|
391
|
-
const
|
|
415
|
+
const clearable = options.clearable ?? true;
|
|
416
|
+
/** @type {Select|null} */
|
|
417
|
+
let select = null;
|
|
418
|
+
// The constructor renders the list once before `select` is assigned; the label is settled by
|
|
419
|
+
// the setItems() below, which renders it again.
|
|
420
|
+
const noneLabel = () => options.noneLabel
|
|
421
|
+
?? (select ? select._message('priority.none', 'No priority') : 'No priority');
|
|
422
|
+
select = new Select(target, {
|
|
392
423
|
...options,
|
|
424
|
+
clearable,
|
|
393
425
|
value: null,
|
|
394
426
|
items: [],
|
|
395
427
|
renderItem(item) {
|
|
396
428
|
return priorityContent(item, true);
|
|
397
429
|
},
|
|
430
|
+
renderNone: options.renderNone ?? (() => priorityContent({ level: null, name: noneLabel() }, true)),
|
|
398
431
|
renderValueAdornment(item) { return priorityIndicator(item.level); }
|
|
399
432
|
});
|
|
433
|
+
if (clearable && !options.placeholder) {
|
|
434
|
+
/** @type {HTMLInputElement} */ (select.refs.input).placeholder = noneLabel();
|
|
435
|
+
}
|
|
436
|
+
const preset = select;
|
|
400
437
|
select.setItems(PRIORITY_KEYS.map((key, level) => {
|
|
401
|
-
let name = level === 2 ?
|
|
402
|
-
if (name === 'priority.medium') name =
|
|
403
|
-
else if (level !== 2) name =
|
|
438
|
+
let name = level === 2 ? preset.msg('priority.medium') : key;
|
|
439
|
+
if (name === 'priority.medium') name = preset._message(key, PRIORITY_FALLBACKS[level]);
|
|
440
|
+
else if (level !== 2) name = preset._message(key, PRIORITY_FALLBACKS[level]);
|
|
404
441
|
return { ID: level, name, level };
|
|
405
442
|
}));
|
|
406
443
|
select.set(requestedValue, { silent: true });
|
|
@@ -453,10 +490,10 @@ export class Select extends Component {
|
|
|
453
490
|
const value = readSelectItem(item, iconKey);
|
|
454
491
|
if (value && typeof value === 'object' && typeof value.nodeType === 'number') return value.cloneNode(true);
|
|
455
492
|
if (typeof value !== 'string' || !value) return null;
|
|
456
|
-
const color = readSelectItem(item, colorKey);
|
|
493
|
+
const color = itemColor(readSelectItem(item, colorKey));
|
|
457
494
|
return h('span', {
|
|
458
495
|
class: 'zx-select__entity-glyph',
|
|
459
|
-
style:
|
|
496
|
+
style: color ? { '--zx-select-entity-color': color } : null,
|
|
460
497
|
ariaHidden: 'true'
|
|
461
498
|
}, icon(value, { size: 14 }));
|
|
462
499
|
};
|
|
@@ -992,28 +1029,26 @@ function priorityContent(item, label) {
|
|
|
992
1029
|
label ? h('span', {}, String(item.name)) : null);
|
|
993
1030
|
}
|
|
994
1031
|
|
|
995
|
-
/**
|
|
1032
|
+
/**
|
|
1033
|
+
* The priority glyph `priorityIcon()` draws, carrying the Select's own class as well so styles
|
|
1034
|
+
* written against it keep applying.
|
|
1035
|
+
* @param {unknown} level Priority level 0–4, or null for none.
|
|
1036
|
+
* @returns {Node}
|
|
1037
|
+
*/
|
|
996
1038
|
function priorityIndicator(level) {
|
|
997
|
-
const
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
dataset: { level: normalized },
|
|
1001
|
-
ariaHidden: 'true'
|
|
1002
|
-
}, Array.from({ length: 5 }, (_, index) => h('span', {
|
|
1003
|
-
dataset: { filled: String(index <= normalized) }
|
|
1004
|
-
})));
|
|
1039
|
+
const glyph = priorityIcon(/** @type {number|null} */ (normalizePriorityLevel(level)));
|
|
1040
|
+
glyph.classList.add('zx-select__priority-icon');
|
|
1041
|
+
return glyph;
|
|
1005
1042
|
}
|
|
1006
1043
|
|
|
1007
1044
|
/** @param {unknown} input @returns {Record<string, any>|null} */
|
|
1008
1045
|
function normalizeStatusItem(input) {
|
|
1009
1046
|
if (!input || typeof input !== 'object' || input.ID == null || input.name == null) return null;
|
|
1010
|
-
const indicators = ['dotted', 'ring', 'progress', 'review', 'ready', 'waiting', 'done', 'canceled', 'duplicate'];
|
|
1011
|
-
const tones = ['muted', 'neutral', 'warning', 'info', 'accent', 'success', 'danger'];
|
|
1012
1047
|
return {
|
|
1013
1048
|
...input,
|
|
1014
1049
|
name: String(input.name),
|
|
1015
|
-
indicator:
|
|
1016
|
-
tone:
|
|
1050
|
+
indicator: STATUS_INDICATORS.includes(String(input.indicator)) ? String(input.indicator) : 'ring',
|
|
1051
|
+
tone: STATUS_TONES.includes(String(input.tone)) ? String(input.tone) : 'muted',
|
|
1017
1052
|
description: input.description == null ? '' : String(input.description),
|
|
1018
1053
|
shortcut: input.shortcut == null ? '' : String(input.shortcut)
|
|
1019
1054
|
};
|
|
@@ -1029,17 +1064,16 @@ function statusContent(item) {
|
|
|
1029
1064
|
item.shortcut ? h('kbd', { class: 'zx-select__status-shortcut' }, item.shortcut) : null);
|
|
1030
1065
|
}
|
|
1031
1066
|
|
|
1032
|
-
/**
|
|
1067
|
+
/**
|
|
1068
|
+
* The status glyph `statusIcon()` draws for a settled status item, carrying the Select's own class
|
|
1069
|
+
* as well so styles written against it keep applying.
|
|
1070
|
+
* @param {Record<string, any>} item Normalized status item.
|
|
1071
|
+
* @returns {Node}
|
|
1072
|
+
*/
|
|
1033
1073
|
function statusIndicator(item) {
|
|
1034
|
-
const
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
dataset: { indicator, tone: String(item.tone ?? 'muted') },
|
|
1038
|
-
ariaHidden: 'true'
|
|
1039
|
-
});
|
|
1040
|
-
if (indicator === 'done') marker.append(icon('check', { size: 8 }));
|
|
1041
|
-
if (indicator === 'canceled') marker.append(icon('x', { size: 7 }));
|
|
1042
|
-
return marker;
|
|
1074
|
+
const glyph = statusIcon({ indicator: item.indicator ?? 'ring', tone: item.tone ?? 'muted' });
|
|
1075
|
+
glyph.classList.add('zx-select__status-indicator');
|
|
1076
|
+
return glyph;
|
|
1043
1077
|
}
|
|
1044
1078
|
|
|
1045
1079
|
/** Change emitted when the selected value changes. @event Select#change @type {CustomEvent<SelectChangeDetail>} */
|
|
@@ -1061,6 +1095,17 @@ function readItem(item, reader) {
|
|
|
1061
1095
|
return item[reader];
|
|
1062
1096
|
}
|
|
1063
1097
|
|
|
1098
|
+
/**
|
|
1099
|
+
* Reports a key press that says nothing about how the user is moving focus: a lone modifier, or a
|
|
1100
|
+
* shortcut chord the page or the browser handles.
|
|
1101
|
+
* @param {KeyboardEvent} event Key event.
|
|
1102
|
+
* @returns {boolean}
|
|
1103
|
+
*/
|
|
1104
|
+
function isModifierKey(event) {
|
|
1105
|
+
return ['Shift', 'Control', 'Alt', 'Meta', 'CapsLock'].includes(event.key)
|
|
1106
|
+
|| event.ctrlKey || event.metaKey;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1064
1109
|
/** @param {KeyboardEvent} event @returns {boolean} */
|
|
1065
1110
|
function isPrintable(event) {
|
|
1066
1111
|
return event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey;
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
inset-block-start: 0;
|
|
58
58
|
inset-block-end: auto;
|
|
59
59
|
border-block-end: 1px solid var(--zx-color-overlay-border);
|
|
60
|
-
border-end-start-radius: var(--zx-sheet-radius, var(--zx-radius-
|
|
61
|
-
border-end-end-radius: var(--zx-sheet-radius, var(--zx-radius-
|
|
60
|
+
border-end-start-radius: var(--zx-sheet-radius, var(--zx-radius-lg));
|
|
61
|
+
border-end-end-radius: var(--zx-sheet-radius, var(--zx-radius-lg));
|
|
62
62
|
--zx-sheet-enter: 0 -100%;
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
inset-block-start: auto;
|
|
67
67
|
inset-block-end: 0;
|
|
68
68
|
border-block-start: 1px solid var(--zx-color-overlay-border);
|
|
69
|
-
border-start-start-radius: var(--zx-sheet-radius, var(--zx-radius-
|
|
70
|
-
border-start-end-radius: var(--zx-sheet-radius, var(--zx-radius-
|
|
69
|
+
border-start-start-radius: var(--zx-sheet-radius, var(--zx-radius-lg));
|
|
70
|
+
border-start-end-radius: var(--zx-sheet-radius, var(--zx-radius-lg));
|
|
71
71
|
--zx-sheet-enter: 0 100%;
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -105,11 +105,14 @@
|
|
|
105
105
|
* `display: none` immediately — so `display` and `overlay` transition with `allow-discrete`, which
|
|
106
106
|
* defers the discrete jump until the rest of the transition has finished. `@starting-style` gives
|
|
107
107
|
* the entry its from-state. Where either is unsupported the sheet simply appears and disappears.
|
|
108
|
+
*
|
|
109
|
+
* The slide runs on the drawer curve — most of the distance at once, then a settle — while the
|
|
110
|
+
* fade keeps the ordinary ease, so the panel arrives decisively without flashing in.
|
|
108
111
|
*/
|
|
109
112
|
@media (prefers-reduced-motion: no-preference) {
|
|
110
113
|
.zx-sheet {
|
|
111
114
|
transition:
|
|
112
|
-
translate var(--zx-dur-base) var(--zx-ease),
|
|
115
|
+
translate var(--zx-dur-base) var(--zx-ease-drawer),
|
|
113
116
|
opacity var(--zx-dur-base) var(--zx-ease),
|
|
114
117
|
display var(--zx-dur-base) allow-discrete,
|
|
115
118
|
overlay var(--zx-dur-base) allow-discrete;
|
|
@@ -193,7 +196,7 @@
|
|
|
193
196
|
@media (prefers-reduced-motion: no-preference) {
|
|
194
197
|
.zx-sheet[data-docked] {
|
|
195
198
|
transition:
|
|
196
|
-
flex-basis var(--zx-dur-base) var(--zx-ease),
|
|
199
|
+
flex-basis var(--zx-dur-base) var(--zx-ease-drawer),
|
|
197
200
|
opacity var(--zx-dur-base) var(--zx-ease),
|
|
198
201
|
display var(--zx-dur-base) allow-discrete,
|
|
199
202
|
overlay var(--zx-dur-base) allow-discrete;
|
|
@@ -246,7 +249,7 @@
|
|
|
246
249
|
}
|
|
247
250
|
|
|
248
251
|
.zx-sheet__handle:focus-visible {
|
|
249
|
-
outline:
|
|
252
|
+
outline-color: transparent;
|
|
250
253
|
box-shadow: var(--zx-focus-ring);
|
|
251
254
|
}
|
|
252
255
|
|
|
@@ -363,8 +366,8 @@
|
|
|
363
366
|
@media (prefers-reduced-motion: no-preference) {
|
|
364
367
|
.zx-sheet[data-stack] {
|
|
365
368
|
transition:
|
|
366
|
-
transform var(--zx-dur-base) var(--zx-ease),
|
|
367
|
-
translate var(--zx-dur-base) var(--zx-ease),
|
|
369
|
+
transform var(--zx-dur-base) var(--zx-ease-drawer),
|
|
370
|
+
translate var(--zx-dur-base) var(--zx-ease-drawer),
|
|
368
371
|
opacity var(--zx-dur-base) var(--zx-ease),
|
|
369
372
|
display var(--zx-dur-base) allow-discrete,
|
|
370
373
|
overlay var(--zx-dur-base) allow-discrete;
|