@zeyos/zx 4.4.0 → 5.0.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 +283 -0
- package/README.md +42 -10
- package/dist/types/components/activity-list/activity-list.d.ts +22 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +5 -3
- 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/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/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 +2 -2
- package/dist/types/components/entity-ref/entity-ref.d.ts +2 -2
- package/dist/types/components/field/field.d.ts +24 -2
- package/dist/types/components/fieldset/fieldset.d.ts +19 -1
- package/dist/types/components/file-item/file-item.d.ts +34 -6
- 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 +260 -15
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +1 -1
- package/dist/types/components/menu-button/menu-button.d.ts +33 -5
- package/dist/types/components/message/message.d.ts +119 -17
- package/dist/types/components/modal/modal.d.ts +13 -2
- 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 +11 -3
- 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 +46 -1
- 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/core/breakpoint.d.ts +1 -1
- package/dist/types/core/icons.d.ts +23 -25
- package/dist/types/core/motion.d.ts +59 -0
- package/dist/types/core/overlay-host.d.ts +15 -1
- package/dist/types/index.d.ts +5 -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 +1 -1
- package/dist/types/zeyos/query.d.ts +79 -0
- package/dist/types/zeyos/schema.d.ts +24 -1
- package/dist/types/zeyos/table.d.ts +100 -14
- package/dist/types/zeyos/view.d.ts +10 -0
- package/dist/zx-zeyos.esm.js +1621 -443
- package/dist/zx-zeyos.esm.min.js +53 -5
- package/dist/zx.css +1411 -660
- package/dist/zx.esm.js +1976 -703
- package/dist/zx.esm.min.js +56 -8
- package/dist/zx.global.js +1978 -705
- package/dist/zx.global.min.js +56 -8
- package/dist/zx.min.css +1 -1
- package/docs/api.json +219 -34
- package/docs/llms.md +472 -110
- package/docs/llms.txt +3 -3
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.css +35 -10
- 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 +34 -0
- package/src/components/app-icon/app-icon.css +1 -1
- package/src/components/app-rail/app-rail.css +40 -79
- package/src/components/app-sidebar/app-sidebar.css +109 -174
- package/src/components/app-sidebar/app-sidebar.js +21 -6
- 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/button/button.css +67 -9
- package/src/components/button/button.js +38 -0
- package/src/components/calendar/calendar.css +46 -46
- package/src/components/card/card.css +2 -2
- package/src/components/card-view/card-view.css +9 -7
- 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 +6 -5
- package/src/components/code-editor/code-editor.js +19 -1
- package/src/components/context-menu/context-menu.css +9 -4
- package/src/components/copy/copy-button.css +6 -0
- package/src/components/copy/copy-input.css +8 -3
- package/src/components/data-filter/data-filter.css +5 -4
- 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 +1 -1
- 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/dropdown/dropdown.css +1 -1
- package/src/components/dropdown/dropdown.js +5 -3
- 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 +68 -26
- package/src/components/field-upload/field-upload.css +1 -1
- package/src/components/fieldset/fieldset.css +5 -3
- package/src/components/fieldset/fieldset.js +28 -5
- package/src/components/file-item/file-item.js +144 -10
- package/src/components/filter/filter.js +7 -3
- package/src/components/filter-panel/filter-panel.css +1 -1
- package/src/components/finder/finder.css +15 -13
- 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 +39 -15
- package/src/components/kanban-view/kanban-view.js +4 -4
- package/src/components/launcher/launcher.css +107 -25
- package/src/components/launcher/launcher.js +503 -41
- package/src/components/list-toolbar/list-toolbar.css +13 -8
- package/src/components/list-toolbar/list-toolbar.js +1 -1
- package/src/components/master-panel/master-panel.css +2 -0
- package/src/components/menu-button/menu-button.css +9 -4
- package/src/components/menu-button/menu-button.js +65 -9
- package/src/components/message/message.css +33 -3
- package/src/components/message/message.js +217 -15
- package/src/components/modal/modal.js +18 -3
- package/src/components/navigation-bar/navigation-bar.css +18 -9
- package/src/components/number-field/field-adapter.js +1 -0
- 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 +8 -6
- package/src/components/panel/panel.css +1 -1
- package/src/components/rating/rating.css +7 -0
- 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 +83 -47
- package/src/components/sheet/sheet.css +11 -8
- package/src/components/slider/slider.css +16 -2
- package/src/components/slider/slider.js +1 -1
- package/src/components/sort-control/sort-control.css +4 -1
- package/src/components/stat-tile/stat-tile.css +41 -46
- package/src/components/stat-tile/stat-tile.js +17 -6
- package/src/components/tabbox/tabbox.css +32 -27
- package/src/components/tabbox/tabbox.js +5 -1
- package/src/components/table/table.css +104 -29
- package/src/components/table/table.js +90 -16
- 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 +10 -3
- package/src/components/tree/tree.css +25 -16
- package/src/components/tree/tree.js +31 -0
- package/src/components/value-list/value-list.css +3 -3
- package/src/components/view/record-view.js +1 -1
- package/src/core/breakpoint.js +1 -1
- package/src/core/icons.js +193 -60
- package/src/core/motion.js +147 -0
- package/src/core/overlay-host.js +21 -2
- package/src/index.js +5 -3
- package/src/internal/app-rail.js +1 -2
- package/src/zeyos/connect.js +6 -2
- package/src/zeyos/form.js +67 -27
- package/src/zeyos/index.js +1 -1
- package/src/zeyos/query.js +153 -0
- package/src/zeyos/schema.js +144 -27
- package/src/zeyos/table.js +68 -5
- package/src/zeyos/view.js +6 -0
- package/styles/base.css +56 -0
- package/styles/icons.css +11 -1
- package/styles/tokens/dark.css +113 -37
- package/styles/tokens/global.css +121 -27
- package/styles/tokens/semantic.css +100 -31
- package/styles/tokens/themes.css +7 -6
- package/styles/zx.css +0 -1
- package/styles/tokens/density.css +0 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.zx-calendar {
|
|
2
2
|
--zx-calendar-time-axis: 4.75rem;
|
|
3
|
-
--zx-calendar-slot-height:
|
|
3
|
+
--zx-calendar-slot-height: var(--zx-space-6);
|
|
4
4
|
--zx-calendar-event-color: var(--zx-color-accent);
|
|
5
5
|
position: relative;
|
|
6
6
|
container-type: inline-size;
|
|
@@ -40,13 +40,15 @@
|
|
|
40
40
|
|
|
41
41
|
.zx-calendar__navigation { justify-self: start; gap: var(--zx-space-1); }
|
|
42
42
|
.zx-calendar__commands { justify-self: end; gap: var(--zx-space-3); }
|
|
43
|
+
/* The view switch is one framed control with the current view on the neutral current fill — the
|
|
44
|
+
same recipe as ListToolbar's view switch and the segmented Tabbox. */
|
|
43
45
|
.zx-calendar__views {
|
|
44
46
|
block-size: var(--zx-control-height);
|
|
45
47
|
gap: 2px;
|
|
46
48
|
overflow-x: auto;
|
|
47
|
-
border
|
|
48
|
-
|
|
49
|
-
padding:
|
|
49
|
+
border: 1px solid var(--zx-color-border-control);
|
|
50
|
+
border-radius: var(--zx-control-radius);
|
|
51
|
+
padding: 2px;
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
.zx-calendar__toolbar-button,
|
|
@@ -75,32 +77,32 @@
|
|
|
75
77
|
block-size: 100%;
|
|
76
78
|
min-block-size: 0;
|
|
77
79
|
border-color: transparent;
|
|
78
|
-
border-radius:
|
|
80
|
+
border-radius: max(0px, calc(var(--zx-control-radius) - 2px));
|
|
79
81
|
background: transparent;
|
|
82
|
+
color: var(--zx-color-text-muted);
|
|
80
83
|
padding-inline: var(--zx-space-3);
|
|
84
|
+
font-weight: var(--zx-weight-medium);
|
|
81
85
|
}
|
|
86
|
+
.zx-calendar__view-button:hover:not(:disabled) { color: var(--zx-color-text); }
|
|
82
87
|
.zx-calendar__view-button[aria-pressed="true"] {
|
|
83
|
-
|
|
84
|
-
z-index: 1;
|
|
85
|
-
border-color: var(--zx-color-border-control);
|
|
86
|
-
background: var(--zx-color-bg-control);
|
|
87
|
-
box-shadow: var(--zx-shadow-2);
|
|
88
|
+
background: var(--zx-color-bg-current);
|
|
88
89
|
color: var(--zx-color-text);
|
|
90
|
+
font-weight: var(--zx-weight-semibold);
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
.zx-calendar__new {
|
|
92
94
|
gap: var(--zx-space-2);
|
|
93
|
-
border-color: var(--zx-color-accent);
|
|
95
|
+
border-color: var(--zx-color-accent-solid);
|
|
94
96
|
border-radius: var(--zx-control-radius);
|
|
95
|
-
background: var(--zx-color-accent);
|
|
96
|
-
color: var(--zx-color-on-accent);
|
|
97
|
+
background: var(--zx-color-accent-solid);
|
|
98
|
+
color: var(--zx-color-on-accent-solid);
|
|
97
99
|
padding-inline: var(--zx-space-3);
|
|
98
|
-
font-weight:
|
|
100
|
+
font-weight: var(--zx-weight-medium);
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
.zx-calendar__toolbar-button:hover:not(:disabled),
|
|
102
104
|
.zx-calendar__view-button:hover:not(:disabled):not([aria-pressed="true"]) { background: var(--zx-color-bg-hover); }
|
|
103
|
-
.zx-calendar__new:hover:not(:disabled) { background: var(--zx-color-accent-hover); }
|
|
105
|
+
.zx-calendar__new:hover:not(:disabled) { border-color: var(--zx-color-accent-solid-hover); background: var(--zx-color-accent-solid-hover); }
|
|
104
106
|
.zx-calendar button:disabled { cursor: default; opacity: .55; }
|
|
105
107
|
|
|
106
108
|
.zx-calendar__toolbar-button:focus-visible,
|
|
@@ -126,7 +128,8 @@
|
|
|
126
128
|
overflow: hidden;
|
|
127
129
|
color: var(--zx-color-text);
|
|
128
130
|
font-size: var(--zx-text-lg);
|
|
129
|
-
font-weight:
|
|
131
|
+
font-weight: var(--zx-weight-semibold);
|
|
132
|
+
letter-spacing: var(--zx-tracking-title);
|
|
130
133
|
line-height: 1.25;
|
|
131
134
|
text-align: center;
|
|
132
135
|
text-overflow: ellipsis;
|
|
@@ -148,10 +151,10 @@
|
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
.zx-calendar__time-header,
|
|
151
|
-
.zx-calendar__all-day { border-block-end: 1px solid var(--zx-color-border); }
|
|
154
|
+
.zx-calendar__all-day { border-block-end: 1px solid var(--zx-color-border-subtle); }
|
|
152
155
|
.zx-calendar__time-corner,
|
|
153
156
|
.zx-calendar__all-day-label {
|
|
154
|
-
border-inline-end: 1px solid var(--zx-color-border);
|
|
157
|
+
border-inline-end: 1px solid var(--zx-color-border-subtle);
|
|
155
158
|
color: var(--zx-color-text-muted);
|
|
156
159
|
}
|
|
157
160
|
|
|
@@ -167,7 +170,7 @@
|
|
|
167
170
|
place-content: center;
|
|
168
171
|
border: 0;
|
|
169
172
|
border-radius: 0;
|
|
170
|
-
border-inline-end: 1px solid var(--zx-color-border);
|
|
173
|
+
border-inline-end: 1px solid var(--zx-color-border-subtle);
|
|
171
174
|
background: var(--zx-color-bg-surface);
|
|
172
175
|
color: var(--zx-color-text);
|
|
173
176
|
font: inherit;
|
|
@@ -176,8 +179,8 @@
|
|
|
176
179
|
|
|
177
180
|
.zx-calendar__day-heading:last-child { border-inline-end: 0; }
|
|
178
181
|
.zx-calendar__day-heading:hover:not(:disabled) { background: var(--zx-color-bg-hover); }
|
|
179
|
-
.zx-calendar__day-heading[aria-current="date"] .zx-calendar__day-number { color: var(--zx-color-accent); font-weight:
|
|
180
|
-
.zx-calendar__day-weekday { color: var(--zx-color-text-muted); font-size: var(--zx-text-xs);
|
|
182
|
+
.zx-calendar__day-heading[aria-current="date"] .zx-calendar__day-number { color: var(--zx-color-accent); font-weight: 650; }
|
|
183
|
+
.zx-calendar__day-weekday { color: var(--zx-color-text-muted); font-size: var(--zx-text-xs); font-weight: var(--zx-weight-medium); }
|
|
181
184
|
.zx-calendar__day-number { font-size: var(--zx-text-sm); }
|
|
182
185
|
|
|
183
186
|
.zx-calendar__all-day { min-block-size: calc(var(--zx-control-height) + var(--zx-space-2)); }
|
|
@@ -198,7 +201,7 @@
|
|
|
198
201
|
overflow: hidden;
|
|
199
202
|
}
|
|
200
203
|
|
|
201
|
-
.zx-calendar__all-day-cell { border-inline-end: 1px solid var(--zx-color-border); }
|
|
204
|
+
.zx-calendar__all-day-cell { border-inline-end: 1px solid var(--zx-color-border-subtle); }
|
|
202
205
|
.zx-calendar__all-day-cell:last-of-type { border-inline-end: 0; }
|
|
203
206
|
|
|
204
207
|
.zx-calendar__time-scroller {
|
|
@@ -212,7 +215,7 @@
|
|
|
212
215
|
.zx-calendar__time-axis {
|
|
213
216
|
position: relative;
|
|
214
217
|
z-index: 2;
|
|
215
|
-
border-inline-end: 1px solid var(--zx-color-border);
|
|
218
|
+
border-inline-end: 1px solid var(--zx-color-border-subtle);
|
|
216
219
|
background: var(--zx-color-bg-surface);
|
|
217
220
|
}
|
|
218
221
|
|
|
@@ -247,8 +250,8 @@
|
|
|
247
250
|
min-inline-size: 0;
|
|
248
251
|
border: 0;
|
|
249
252
|
border-radius: 0;
|
|
250
|
-
border-block-start: 1px solid var(--zx-color-border);
|
|
251
|
-
border-inline-end: 1px solid var(--zx-color-border);
|
|
253
|
+
border-block-start: 1px solid var(--zx-color-border-subtle);
|
|
254
|
+
border-inline-end: 1px solid var(--zx-color-border-subtle);
|
|
252
255
|
background: var(--zx-color-bg-surface);
|
|
253
256
|
padding: 0;
|
|
254
257
|
cursor: crosshair;
|
|
@@ -321,7 +324,7 @@
|
|
|
321
324
|
}
|
|
322
325
|
|
|
323
326
|
.zx-calendar__event-time { overflow: hidden; color: var(--zx-color-text-muted); text-overflow: ellipsis; white-space: nowrap; }
|
|
324
|
-
.zx-calendar__event-title { overflow: hidden; font-weight:
|
|
327
|
+
.zx-calendar__event-title { overflow: hidden; font-weight: var(--zx-weight-semibold); text-overflow: ellipsis; white-space: nowrap; }
|
|
325
328
|
.zx-calendar__event-location { overflow: hidden; color: var(--zx-color-text-muted); text-overflow: ellipsis; white-space: nowrap; }
|
|
326
329
|
|
|
327
330
|
.zx-calendar__event-resize {
|
|
@@ -378,7 +381,8 @@
|
|
|
378
381
|
inset-inline-start: var(--zx-space-1);
|
|
379
382
|
color: var(--zx-color-danger);
|
|
380
383
|
font-size: var(--zx-text-xs);
|
|
381
|
-
font-weight:
|
|
384
|
+
font-weight: var(--zx-weight-semibold);
|
|
385
|
+
font-variant-numeric: tabular-nums;
|
|
382
386
|
transform: translateY(-100%);
|
|
383
387
|
}
|
|
384
388
|
|
|
@@ -386,19 +390,19 @@
|
|
|
386
390
|
.zx-calendar__agenda-day {
|
|
387
391
|
display: grid;
|
|
388
392
|
grid-template-columns: minmax(10rem, 22%) minmax(0, 1fr);
|
|
389
|
-
border-block-end: 1px solid var(--zx-color-border);
|
|
393
|
+
border-block-end: 1px solid var(--zx-color-border-subtle);
|
|
390
394
|
}
|
|
391
395
|
.zx-calendar__agenda-heading {
|
|
392
396
|
align-self: stretch;
|
|
393
397
|
appearance: none;
|
|
394
398
|
border: 0;
|
|
395
|
-
border-inline-end: 1px solid var(--zx-color-border);
|
|
399
|
+
border-inline-end: 1px solid var(--zx-color-border-subtle);
|
|
396
400
|
border-radius: 0;
|
|
397
401
|
background: var(--zx-color-bg-muted);
|
|
398
402
|
color: var(--zx-color-text);
|
|
399
403
|
padding: var(--zx-space-3);
|
|
400
404
|
font: inherit;
|
|
401
|
-
font-weight:
|
|
405
|
+
font-weight: var(--zx-weight-semibold);
|
|
402
406
|
text-align: start;
|
|
403
407
|
cursor: pointer;
|
|
404
408
|
}
|
|
@@ -408,7 +412,7 @@
|
|
|
408
412
|
min-inline-size: 0;
|
|
409
413
|
}
|
|
410
414
|
.zx-calendar__agenda-empty { margin: 0; color: var(--zx-color-text-muted); padding: var(--zx-space-3); }
|
|
411
|
-
.zx-calendar__agenda-events > .zx-calendar__event { border-block-end: 1px solid var(--zx-color-border); }
|
|
415
|
+
.zx-calendar__agenda-events > .zx-calendar__event { border-block-end: 1px solid var(--zx-color-border-subtle); }
|
|
412
416
|
.zx-calendar__agenda-events > .zx-calendar__event:last-child { border-block-end: 0; }
|
|
413
417
|
.zx-calendar__event[data-variant="agenda"] .zx-calendar__event-action {
|
|
414
418
|
grid-template-columns: minmax(6rem, 18%) minmax(0, 1fr);
|
|
@@ -440,7 +444,7 @@
|
|
|
440
444
|
grid-template-columns: auto minmax(0, 1fr);
|
|
441
445
|
}
|
|
442
446
|
|
|
443
|
-
.zx-calendar__month-weekdays { border-block-end: 1px solid var(--zx-color-border); }
|
|
447
|
+
.zx-calendar__month-weekdays { border-block-end: 1px solid var(--zx-color-border-subtle); }
|
|
444
448
|
.zx-calendar__month-week-gutter,
|
|
445
449
|
.zx-calendar__month-week-number { inline-size: 2.5rem; }
|
|
446
450
|
.zx-calendar__month-weekdays:not(:has(.zx-calendar__month-week-gutter)) { grid-template-columns: repeat(7, minmax(0, 1fr)); }
|
|
@@ -449,17 +453,15 @@
|
|
|
449
453
|
padding: var(--zx-space-2);
|
|
450
454
|
color: var(--zx-color-text-muted);
|
|
451
455
|
font-size: var(--zx-text-xs);
|
|
452
|
-
font-weight:
|
|
456
|
+
font-weight: var(--zx-weight-medium);
|
|
453
457
|
text-align: center;
|
|
454
|
-
text-transform: uppercase;
|
|
455
|
-
letter-spacing: .04em;
|
|
456
458
|
}
|
|
457
|
-
.zx-calendar__month-week { min-block-size: 7.5rem; border-block-end: 1px solid var(--zx-color-border); }
|
|
459
|
+
.zx-calendar__month-week { min-block-size: 7.5rem; border-block-end: 1px solid var(--zx-color-border-subtle); }
|
|
458
460
|
.zx-calendar__month-week-number {
|
|
459
461
|
grid-row: 1;
|
|
460
462
|
appearance: none;
|
|
461
463
|
border: 0;
|
|
462
|
-
border-inline-end: 1px solid var(--zx-color-border);
|
|
464
|
+
border-inline-end: 1px solid var(--zx-color-border-subtle);
|
|
463
465
|
border-radius: 0;
|
|
464
466
|
background: var(--zx-color-bg-muted);
|
|
465
467
|
color: var(--zx-color-text-muted);
|
|
@@ -488,7 +490,7 @@
|
|
|
488
490
|
justify-content: flex-end;
|
|
489
491
|
min-block-size: var(--zx-control-height);
|
|
490
492
|
border: 0;
|
|
491
|
-
border-inline-end: 1px solid var(--zx-color-border);
|
|
493
|
+
border-inline-end: 1px solid var(--zx-color-border-subtle);
|
|
492
494
|
border-radius: 0;
|
|
493
495
|
background: var(--zx-color-bg-surface);
|
|
494
496
|
color: var(--zx-color-text);
|
|
@@ -501,7 +503,7 @@
|
|
|
501
503
|
.zx-calendar__month-day[data-other-month="true"] { color: var(--zx-color-text-muted); background: var(--zx-color-bg-muted); }
|
|
502
504
|
.zx-calendar__month-day[aria-current="date"] {
|
|
503
505
|
color: var(--zx-color-accent);
|
|
504
|
-
font-weight:
|
|
506
|
+
font-weight: 650;
|
|
505
507
|
}
|
|
506
508
|
.zx-calendar__month-day:hover:not(:disabled) { background: var(--zx-color-bg-hover); }
|
|
507
509
|
.zx-calendar__month-events {
|
|
@@ -545,8 +547,8 @@
|
|
|
545
547
|
padding: var(--zx-space-5);
|
|
546
548
|
}
|
|
547
549
|
.zx-calendar__year-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; align-content: start; }
|
|
548
|
-
.zx-calendar__year-heading { grid-column: 1 / -1; margin: 0 0 var(--zx-space-2); font-size: var(--zx-text-md); }
|
|
549
|
-
.zx-calendar__year-weekday { color: var(--zx-color-text-muted); font-size: var(--zx-text-xs); font-weight:
|
|
550
|
+
.zx-calendar__year-heading { grid-column: 1 / -1; margin: 0 0 var(--zx-space-2); font-size: var(--zx-text-md); font-weight: var(--zx-weight-semibold); }
|
|
551
|
+
.zx-calendar__year-weekday { color: var(--zx-color-text-muted); font-size: var(--zx-text-xs); font-weight: var(--zx-weight-medium); text-align: center; }
|
|
550
552
|
.zx-calendar__year-day,
|
|
551
553
|
.zx-calendar__year-blank { aspect-ratio: 1; }
|
|
552
554
|
.zx-calendar__year-day {
|
|
@@ -562,7 +564,7 @@
|
|
|
562
564
|
}
|
|
563
565
|
.zx-calendar__year-day[data-activity="1"] { background: color-mix(in srgb, var(--zx-color-accent) 10%, var(--zx-color-bg-surface)); }
|
|
564
566
|
.zx-calendar__year-day[data-activity="2"] { background: color-mix(in srgb, var(--zx-color-accent) 20%, var(--zx-color-bg-surface)); }
|
|
565
|
-
.zx-calendar__year-day[data-activity="3"] { background: color-mix(in srgb, var(--zx-color-accent) 32%, var(--zx-color-bg-surface)); font-weight:
|
|
567
|
+
.zx-calendar__year-day[data-activity="3"] { background: color-mix(in srgb, var(--zx-color-accent) 32%, var(--zx-color-bg-surface)); font-weight: var(--zx-weight-semibold); }
|
|
566
568
|
.zx-calendar__year-day[aria-current="date"] { outline: 2px solid var(--zx-color-accent); outline-offset: -2px; }
|
|
567
569
|
.zx-calendar__year-day:hover:not(:disabled) { background: var(--zx-color-bg-hover); }
|
|
568
570
|
|
|
@@ -574,7 +576,7 @@
|
|
|
574
576
|
place-items: center;
|
|
575
577
|
background: color-mix(in srgb, var(--zx-color-bg-surface) 82%, transparent);
|
|
576
578
|
color: var(--zx-color-text);
|
|
577
|
-
font-weight:
|
|
579
|
+
font-weight: var(--zx-weight-medium);
|
|
578
580
|
}
|
|
579
581
|
.zx-calendar__loading[hidden] { display: none; }
|
|
580
582
|
.zx-calendar[data-state="loading"] .zx-calendar__body { opacity: .55; }
|
|
@@ -606,15 +608,13 @@
|
|
|
606
608
|
inset-block-start: 0;
|
|
607
609
|
z-index: 3;
|
|
608
610
|
border-inline-end: 0;
|
|
609
|
-
border-block-end: 1px solid var(--zx-color-border);
|
|
611
|
+
border-block-end: 1px solid var(--zx-color-border-subtle);
|
|
610
612
|
}
|
|
611
613
|
.zx-calendar__agenda-events { grid-column: 1; }
|
|
612
614
|
.zx-calendar__event[data-variant="agenda"] .zx-calendar__event-action { grid-template-columns: 5.5rem minmax(0, 1fr); }
|
|
613
615
|
.zx-calendar__year { grid-template-columns: 1fr; padding: var(--zx-space-3); }
|
|
614
616
|
}
|
|
615
617
|
|
|
616
|
-
[data-zx-density="compact"] .zx-calendar { --zx-calendar-slot-height: 20px; }
|
|
617
|
-
|
|
618
618
|
@media (prefers-reduced-motion: no-preference) {
|
|
619
619
|
.zx-calendar__event { transition: transform var(--zx-dur-fast) var(--zx-ease), opacity var(--zx-dur-fast) var(--zx-ease); }
|
|
620
620
|
.zx-calendar__toolbar-button,
|
|
@@ -107,9 +107,9 @@
|
|
|
107
107
|
min-inline-size: 0;
|
|
108
108
|
margin: 0;
|
|
109
109
|
font-size: var(--zx-text-lg);
|
|
110
|
-
font-weight:
|
|
110
|
+
font-weight: 650;
|
|
111
111
|
line-height: 1.3;
|
|
112
|
-
letter-spacing: -
|
|
112
|
+
letter-spacing: var(--zx-tracking-title);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
.zx-card__primary,
|
|
@@ -107,9 +107,11 @@
|
|
|
107
107
|
box-shadow: var(--zx-focus-ring);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
/* A selected card is a pick, so it keeps the accent — as a tint over the card and its outline,
|
|
111
|
+
not a doubled frame. */
|
|
110
112
|
.zx-record-card[data-selected="true"] {
|
|
111
113
|
border-color: var(--zx-color-accent);
|
|
112
|
-
|
|
114
|
+
background: var(--zx-color-bg-selected);
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
.zx-record-card__preview {
|
|
@@ -224,7 +226,7 @@
|
|
|
224
226
|
margin: 0;
|
|
225
227
|
overflow-wrap: anywhere;
|
|
226
228
|
font-size: var(--zx-text-lg);
|
|
227
|
-
font-weight:
|
|
229
|
+
font-weight: 650;
|
|
228
230
|
line-height: 1.35;
|
|
229
231
|
}
|
|
230
232
|
|
|
@@ -317,7 +319,7 @@
|
|
|
317
319
|
overflow: hidden;
|
|
318
320
|
color: var(--zx-color-text-muted);
|
|
319
321
|
font-size: var(--zx-text-xs);
|
|
320
|
-
font-weight:
|
|
322
|
+
font-weight: var(--zx-weight-medium);
|
|
321
323
|
line-height: 1.35;
|
|
322
324
|
text-overflow: ellipsis;
|
|
323
325
|
white-space: nowrap;
|
|
@@ -475,7 +477,7 @@
|
|
|
475
477
|
|
|
476
478
|
.zx-card-view .zx-record-card__heading {
|
|
477
479
|
font-size: var(--zx-text-md);
|
|
478
|
-
font-weight:
|
|
480
|
+
font-weight: var(--zx-weight-semibold);
|
|
479
481
|
line-height: 1.3;
|
|
480
482
|
}
|
|
481
483
|
|
|
@@ -521,8 +523,8 @@
|
|
|
521
523
|
align-items: center;
|
|
522
524
|
gap: var(--zx-space-1);
|
|
523
525
|
max-inline-size: 100%;
|
|
524
|
-
|
|
525
|
-
border-radius: var(--zx-radius-
|
|
526
|
+
/* A tinted label/value pair, not a box inside the card's box: the fill alone separates it. */
|
|
527
|
+
border-radius: var(--zx-radius-sm);
|
|
526
528
|
background: var(--zx-color-bg-muted);
|
|
527
529
|
padding: calc(var(--zx-space-1) / 2) var(--zx-space-2);
|
|
528
530
|
}
|
|
@@ -530,7 +532,7 @@
|
|
|
530
532
|
.zx-card-view .zx-record-card__label {
|
|
531
533
|
flex: none;
|
|
532
534
|
font-size: var(--zx-text-xs);
|
|
533
|
-
font-weight:
|
|
535
|
+
font-weight: var(--zx-weight-medium);
|
|
534
536
|
line-height: 1.2;
|
|
535
537
|
}
|
|
536
538
|
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
.zx-chart__viewport {
|
|
9
9
|
position: relative;
|
|
10
10
|
inline-size: 100%;
|
|
11
|
+
/* The automatic minimum width would carry the 220px floor through the aspect ratio (587px at
|
|
12
|
+
16 / 6) and push the canvas out of a narrow card; narrow, the chart grows taller instead. */
|
|
13
|
+
min-inline-size: 0;
|
|
11
14
|
min-block-size: 220px;
|
|
12
15
|
aspect-ratio: var(--zx-chart-aspect-ratio, 16 / 9);
|
|
13
16
|
}
|
|
@@ -54,7 +57,7 @@
|
|
|
54
57
|
border-collapse: collapse;
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
.zx-chart__table caption { margin-block-end: var(--zx-space-2); font-weight:
|
|
60
|
+
.zx-chart__table caption { margin-block-end: var(--zx-space-2); font-weight: var(--zx-weight-semibold); text-align: start; }
|
|
58
61
|
.zx-chart__table th,
|
|
59
62
|
.zx-chart__table td { border-block-end: 1px solid var(--zx-color-border); padding: var(--zx-space-2); text-align: end; }
|
|
60
63
|
.zx-chart__table th:first-child,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Component } from '../../core/component.js';
|
|
2
2
|
import { h } from '../../core/dom.js';
|
|
3
|
+
import { prefersReducedMotion, watchMotion } from '../../core/motion.js';
|
|
3
4
|
import { uid } from '../../core/util.js';
|
|
4
5
|
|
|
5
6
|
/** @typedef {{label?: string, data?: unknown[], [key: string]: unknown}} ChartDataset */
|
|
@@ -9,6 +10,9 @@ import { uid } from '../../core/util.js';
|
|
|
9
10
|
* @property {string} type Chart type.
|
|
10
11
|
* @property {ChartData} data Chart data.
|
|
11
12
|
* @property {Record<string, unknown>} options Engine-specific options.
|
|
13
|
+
* @property {boolean} reducedMotion Whether the chart must not animate: the operating system asks
|
|
14
|
+
* for reduced motion, or the host sits inside a `data-zx-motion="reduced"` region. An adapter turns
|
|
15
|
+
* its engine's own animation off when this is true; `ChartJsAdapter` sets `animation: false`.
|
|
12
16
|
* @property {(detail: ChartSelectDetail) => void} onSelect Point-selection callback.
|
|
13
17
|
*/
|
|
14
18
|
/**
|
|
@@ -145,6 +149,9 @@ export class Chart extends Component {
|
|
|
145
149
|
|
|
146
150
|
this._observer = typeof ResizeObserver === 'function' ? new ResizeObserver(() => this.resize()) : null;
|
|
147
151
|
this._observer?.observe(viewport);
|
|
152
|
+
// The engine tweens in script, where no stylesheet can reach it: when motion is reduced, or
|
|
153
|
+
// stops being reduced, the mounted chart is updated with the new answer in its spec.
|
|
154
|
+
this._stopWatchingMotion = watchMotion(root, () => this._mountOrUpdate(false));
|
|
148
155
|
return root;
|
|
149
156
|
}
|
|
150
157
|
|
|
@@ -232,6 +239,7 @@ export class Chart extends Component {
|
|
|
232
239
|
this._destroyed = true;
|
|
233
240
|
const original = this._original;
|
|
234
241
|
this._observer?.disconnect();
|
|
242
|
+
this._stopWatchingMotion?.();
|
|
235
243
|
this._destroyHandle();
|
|
236
244
|
super.destroy();
|
|
237
245
|
if (!this._createdRoot && original) {
|
|
@@ -277,6 +285,7 @@ export class Chart extends Component {
|
|
|
277
285
|
...themeChartOptions(/** @type {HTMLElement} */ (this.el)),
|
|
278
286
|
...cloneChartValue(this._chartOptions)
|
|
279
287
|
},
|
|
288
|
+
reducedMotion: prefersReducedMotion(this.el),
|
|
280
289
|
onSelect: (detail) => this.emit('select', detail)
|
|
281
290
|
};
|
|
282
291
|
}
|
|
@@ -386,6 +395,9 @@ function chartJsConfig(spec, defaults, getInstance) {
|
|
|
386
395
|
...cloneChartValue(defaults),
|
|
387
396
|
...supplied
|
|
388
397
|
};
|
|
398
|
+
// Reduced motion wins over any animation the application configured: a person who asked for
|
|
399
|
+
// less motion gets it from every chart, not only from the ones that remembered to ask.
|
|
400
|
+
if (spec.reducedMotion) options.animation = false;
|
|
389
401
|
const originalClick = options.onClick;
|
|
390
402
|
options.onClick = (event, elements, chart) => {
|
|
391
403
|
if (typeof originalClick === 'function') originalClick(event, elements, chart);
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
padding-inline: var(--zx-control-pad-x);
|
|
12
12
|
font: inherit;
|
|
13
13
|
font-size: var(--zx-control-font-size);
|
|
14
|
+
font-weight: var(--zx-control-font-weight);
|
|
14
15
|
cursor: pointer;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -18,9 +19,16 @@
|
|
|
18
19
|
background: var(--zx-color-bg-hover);
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
/* Pressed is a state the button is in, so the button itself goes neutral — the current fill, a
|
|
23
|
+
stronger border, the full text colour — and only the check glyph, which is the mark, keeps the
|
|
24
|
+
accent, as a checkbox would. */
|
|
21
25
|
.zx-check-button[aria-pressed="true"] {
|
|
22
|
-
border-color: var(--zx-color-
|
|
23
|
-
background: var(--zx-color-bg-
|
|
26
|
+
border-color: var(--zx-color-border-strong);
|
|
27
|
+
background: var(--zx-color-bg-current);
|
|
28
|
+
color: var(--zx-color-text);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.zx-check-button__on {
|
|
24
32
|
color: var(--zx-color-accent);
|
|
25
33
|
}
|
|
26
34
|
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
.zx-checklist__label {
|
|
10
|
-
|
|
10
|
+
color: var(--zx-color-text-muted);
|
|
11
|
+
font-size: var(--zx-text-sm);
|
|
12
|
+
font-weight: var(--zx-weight-medium);
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
.zx-checklist__search {
|
|
@@ -31,10 +33,12 @@
|
|
|
31
33
|
display: flex;
|
|
32
34
|
align-items: center;
|
|
33
35
|
gap: var(--zx-space-2);
|
|
34
|
-
|
|
36
|
+
/* The same row as a listbox option. */
|
|
37
|
+
min-block-size: calc(var(--zx-control-height) - 2px);
|
|
35
38
|
border-radius: var(--zx-radius-sm);
|
|
36
39
|
cursor: pointer;
|
|
37
40
|
padding: var(--zx-space-1) var(--zx-space-2);
|
|
41
|
+
line-height: 1.35;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
.zx-checklist__item:hover {
|
|
@@ -45,8 +49,11 @@
|
|
|
45
49
|
background: var(--zx-color-bg-selected);
|
|
46
50
|
}
|
|
47
51
|
|
|
52
|
+
/* The base control height is for text fields; a checkbox that inherited it would make every row
|
|
53
|
+
a field tall. */
|
|
48
54
|
.zx-checklist__item input {
|
|
49
55
|
flex: none;
|
|
56
|
+
min-block-size: 0;
|
|
50
57
|
accent-color: var(--zx-color-accent);
|
|
51
58
|
}
|
|
52
59
|
|
|
@@ -13,6 +13,9 @@ import { matchItems } from '../select/filter.js';
|
|
|
13
13
|
* @property {boolean} [search=true] Whether the search field is shown.
|
|
14
14
|
* @property {number} [height=280] Maximum list height in pixels.
|
|
15
15
|
* @property {boolean} [defaultChecked=false] Fallback initial checked state.
|
|
16
|
+
* @property {boolean} [hideLabel=false] Whether the heading is left out. The group keeps the
|
|
17
|
+
* heading text as its accessible name (`aria-label`); a Field labelling the checklist names it
|
|
18
|
+
* instead, which is why the `checklist` field type sets this.
|
|
16
19
|
* @property {(() => Promise<ChecklistItem[]>|ChecklistItem[])|null} [load=null] Async item loader.
|
|
17
20
|
* @property {Record<string, string>|Record<string, Record<string, string>>} [msg] Localized messages.
|
|
18
21
|
* @property {(event: CustomEvent<ChecklistChangeDetail>) => void} [onchange] Change listener.
|
|
@@ -40,6 +43,7 @@ export class Checklist extends Component {
|
|
|
40
43
|
search: true,
|
|
41
44
|
height: 280,
|
|
42
45
|
defaultChecked: false,
|
|
46
|
+
hideLabel: false,
|
|
43
47
|
load: null
|
|
44
48
|
};
|
|
45
49
|
|
|
@@ -53,15 +57,16 @@ export class Checklist extends Component {
|
|
|
53
57
|
const root = /** @type {HTMLElement} */ (this.el ?? h('div'));
|
|
54
58
|
this.el = root;
|
|
55
59
|
if (!this._createdRoot) this._originalChildren = Array.from(root.childNodes);
|
|
56
|
-
for (const name of ['role', 'aria-labelledby', 'data-state']) {
|
|
60
|
+
for (const name of ['role', 'aria-label', 'aria-labelledby', 'data-state']) {
|
|
57
61
|
this._originalAttributes.set(name, root.getAttribute(name));
|
|
58
62
|
}
|
|
59
63
|
|
|
64
|
+
const labelText = this._message('checklist.label', 'Checklist');
|
|
60
65
|
const labelId = uid('zx-checklist-label');
|
|
61
|
-
const title = h('div', {
|
|
66
|
+
const title = this.options.hideLabel ? null : h('div', {
|
|
62
67
|
class: 'zx-checklist__label',
|
|
63
68
|
id: labelId
|
|
64
|
-
},
|
|
69
|
+
}, labelText);
|
|
65
70
|
const search = h('input', {
|
|
66
71
|
ref: 'search',
|
|
67
72
|
class: 'zx-checklist__search',
|
|
@@ -76,9 +81,10 @@ export class Checklist extends Component {
|
|
|
76
81
|
class: 'zx-checklist__list'
|
|
77
82
|
});
|
|
78
83
|
list.style.maxBlockSize = `${Math.max(0, Number(this.options.height) || 0)}px`;
|
|
79
|
-
root.replaceChildren(title, search, list);
|
|
84
|
+
root.replaceChildren(...[title, search, list].filter(Boolean));
|
|
80
85
|
root.setAttribute('role', 'group');
|
|
81
|
-
root.setAttribute('aria-labelledby', labelId);
|
|
86
|
+
if (title) root.setAttribute('aria-labelledby', labelId);
|
|
87
|
+
else root.setAttribute('aria-label', labelText);
|
|
82
88
|
|
|
83
89
|
this.listen(search, 'input', () => this.search(/** @type {HTMLInputElement} */ (search).value));
|
|
84
90
|
this.listen(list, 'change', (event) => {
|
|
@@ -7,7 +7,9 @@ import { Checklist } from './checklist.js';
|
|
|
7
7
|
*/
|
|
8
8
|
export function registerChecklistFieldAdapter() {
|
|
9
9
|
Field.register('checklist', (field, options) => {
|
|
10
|
-
|
|
10
|
+
// The Field's label names the list (`aria-labelledby`), so the checklist draws no heading of
|
|
11
|
+
// its own under it.
|
|
12
|
+
const checklist = field.own(new Checklist(null, { hideLabel: true, ...(options.props ?? {}) }));
|
|
11
13
|
let disabled = false;
|
|
12
14
|
let setting = false;
|
|
13
15
|
const syncDisabled = () => {
|
|
@@ -17,17 +17,18 @@
|
|
|
17
17
|
min-block-size: var(--zx-control-height);
|
|
18
18
|
padding-inline: var(--zx-space-3);
|
|
19
19
|
border-block-end: 1px solid var(--zx-color-border);
|
|
20
|
-
background: var(--zx-color-bg-
|
|
20
|
+
background: var(--zx-color-bg-muted);
|
|
21
21
|
color: var(--zx-color-text-muted);
|
|
22
22
|
font-size: var(--zx-text-xs);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/* The language is an identifier (`json`, `sql`), so it is shown as one — in the mono face, as
|
|
26
|
+
written — rather than shouted in letter-spaced capitals. */
|
|
25
27
|
.zx-code-editor__language {
|
|
26
28
|
overflow: hidden;
|
|
27
|
-
font-
|
|
28
|
-
|
|
29
|
+
font-family: var(--zx-font-mono);
|
|
30
|
+
font-weight: var(--zx-weight-medium);
|
|
29
31
|
text-overflow: ellipsis;
|
|
30
|
-
text-transform: uppercase;
|
|
31
32
|
text-wrap: nowrap;
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -59,7 +60,7 @@
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
.zx-code-editor[data-readonly="true"] {
|
|
62
|
-
background: var(--zx-color-bg-
|
|
63
|
+
background: var(--zx-color-bg-muted);
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
.zx-code-editor[data-disabled="true"] {
|
|
@@ -19,10 +19,17 @@ import { h } from '../../core/dom.js';
|
|
|
19
19
|
* @property {(event: CustomEvent<{value:string}>) => void} [onchange] Change listener.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
/** Keys that only modify the next one: pressing them is not the keystroke that ends a Tab release. */
|
|
23
|
+
const MODIFIER_KEYS = new Set(['Shift', 'Control', 'Alt', 'Meta', 'AltGraph', 'CapsLock', 'Fn', 'OS']);
|
|
24
|
+
|
|
22
25
|
/**
|
|
23
26
|
* Dependency-free source editor for structured text, Markdown, JSON and code. It deliberately uses
|
|
24
27
|
* a native textarea: values remain text-safe, browser undo and IME behavior stay intact, and Tab /
|
|
25
28
|
* Shift+Tab provide predictable indentation without a third-party editor runtime.
|
|
29
|
+
*
|
|
30
|
+
* Capturing Tab is what a code surface has to do, and it would be a keyboard trap if nothing undid
|
|
31
|
+
* it: Escape releases the capture until the next keystroke in the editor, so Escape then Tab (or
|
|
32
|
+
* Shift+Tab) moves focus out of the editor as it would leave any other field.
|
|
26
33
|
* @fires CodeEditor#input
|
|
27
34
|
* @fires CodeEditor#change
|
|
28
35
|
* @extends {Component<CodeEditorOptions>}
|
|
@@ -81,8 +88,11 @@ export class CodeEditor extends Component {
|
|
|
81
88
|
root.dataset.readonly = String(Boolean(this.options.readOnly));
|
|
82
89
|
root.dataset.disabled = String(Boolean(this.options.disabled));
|
|
83
90
|
root.replaceChildren(this._header, this._input);
|
|
91
|
+
/** Set by Escape: the next Tab moves focus instead of indenting. */
|
|
92
|
+
this._tabReleased = false;
|
|
84
93
|
|
|
85
94
|
this.listen(this._input, 'keydown', (event) => this._handleKeydown(event));
|
|
95
|
+
this.listen(this._input, 'blur', () => { this._tabReleased = false; });
|
|
86
96
|
this.listen(this._input, 'input', () => {
|
|
87
97
|
this._updatePosition();
|
|
88
98
|
this.emit('input', { value: this.getValue() });
|
|
@@ -139,7 +149,15 @@ export class CodeEditor extends Component {
|
|
|
139
149
|
|
|
140
150
|
/** @param {KeyboardEvent} event @returns {void} */
|
|
141
151
|
_handleKeydown(event) {
|
|
142
|
-
if (event.
|
|
152
|
+
if (event.isComposing || MODIFIER_KEYS.has(event.key)) return;
|
|
153
|
+
if (event.key === 'Escape') {
|
|
154
|
+
this._tabReleased = true;
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// Any other keystroke ends the release, the Tab it was for included.
|
|
158
|
+
const released = this._tabReleased;
|
|
159
|
+
this._tabReleased = false;
|
|
160
|
+
if (released || event.key !== 'Tab' || event.altKey || event.ctrlKey || event.metaKey ||
|
|
143
161
|
this._input.readOnly || this._input.disabled) return;
|
|
144
162
|
const indent = String(this.options.indent ?? '\t');
|
|
145
163
|
if (!indent) return;
|
|
@@ -21,12 +21,16 @@
|
|
|
21
21
|
align-items: center;
|
|
22
22
|
gap: var(--zx-space-2);
|
|
23
23
|
inline-size: 100%;
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/* A menu row sits a little under a control so a list of them reads lighter than a column of
|
|
25
|
+
fields; the radius is the smallest step, inset inside the panel's own. */
|
|
26
|
+
min-block-size: calc(var(--zx-control-height) - 2px);
|
|
27
|
+
border: 0;
|
|
28
|
+
border-radius: var(--zx-radius-sm);
|
|
26
29
|
background: transparent;
|
|
27
|
-
padding
|
|
30
|
+
padding: var(--zx-space-1) var(--zx-space-2);
|
|
28
31
|
color: inherit;
|
|
29
32
|
font: inherit;
|
|
33
|
+
line-height: 1.35;
|
|
30
34
|
text-align: start;
|
|
31
35
|
text-decoration: none;
|
|
32
36
|
}
|
|
@@ -117,8 +121,9 @@
|
|
|
117
121
|
box-shadow: inset 0 0 0 2px var(--zx-color-bg-raised);
|
|
118
122
|
}
|
|
119
123
|
|
|
124
|
+
/* A section label is a caption, never taller than the rows it introduces. */
|
|
120
125
|
.zx-context-menu__heading {
|
|
121
|
-
padding: var(--zx-space-
|
|
126
|
+
padding: var(--zx-space-1) var(--zx-space-2);
|
|
122
127
|
color: var(--zx-color-text-muted);
|
|
123
128
|
font-size: var(--zx-text-xs);
|
|
124
129
|
font-weight: 600;
|