@zeyos/zx 4.3.4 → 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 +438 -0
- package/README.md +49 -10
- package/dist/types/components/activity-item/activity-item.d.ts +351 -0
- package/dist/types/components/activity-list/activity-list.d.ts +217 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +33 -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 +23 -0
- package/dist/types/components/calendar/calendar.d.ts +19 -0
- package/dist/types/components/card/card.d.ts +7 -0
- package/dist/types/components/card-view/card-view.d.ts +11 -3
- package/dist/types/components/card-view/record-card.d.ts +7 -1
- 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 +149 -0
- package/dist/types/components/code-editor/field-adapter.d.ts +5 -0
- package/dist/types/components/context-menu/context-menu.d.ts +18 -2
- package/dist/types/components/date-picker/date-picker.d.ts +8 -0
- package/dist/types/components/date-picker/time-picker.d.ts +7 -0
- 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 +75 -6
- package/dist/types/components/dropdown/dropdown.d.ts +2 -2
- package/dist/types/components/entity-ref/entity-ref.d.ts +331 -0
- 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 +262 -0
- package/dist/types/components/file-list/file-list.d.ts +171 -0
- package/dist/types/components/filter/filter.d.ts +91 -36
- package/dist/types/components/filter-panel/filter-panel.d.ts +449 -0
- package/dist/types/components/form/form.d.ts +12 -1
- package/dist/types/components/kanban-view/kanban-card.d.ts +146 -0
- package/dist/types/components/kanban-view/kanban-view.d.ts +170 -4
- package/dist/types/components/launcher/launcher.d.ts +278 -26
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +599 -0
- package/dist/types/components/menu-button/menu-button.d.ts +37 -42
- package/dist/types/components/message/message.d.ts +126 -17
- package/dist/types/components/modal/modal.d.ts +61 -2
- package/dist/types/components/navigation-bar/navigation-bar.d.ts +105 -21
- package/dist/types/components/panel/panel.d.ts +7 -0
- package/dist/types/components/search/search.d.ts +7 -0
- 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 +15 -3
- package/dist/types/components/sort-control/sort-control.d.ts +105 -0
- package/dist/types/components/stat-tile/stat-tile.d.ts +288 -0
- package/dist/types/components/tabbox/tabbox.d.ts +16 -0
- package/dist/types/components/table/table.d.ts +190 -1
- package/dist/types/components/table-view/table-view.d.ts +11 -5
- package/dist/types/components/tag-picker/tag-picker.d.ts +21 -4
- package/dist/types/components/timebox/timebox.d.ts +7 -0
- package/dist/types/components/tree/tree.d.ts +13 -0
- package/dist/types/components/value-list/value-list.d.ts +8 -0
- package/dist/types/components/view/record-view.d.ts +96 -5
- package/dist/types/core/breakpoint.d.ts +1 -1
- package/dist/types/core/icons.d.ts +37 -22
- 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 +16 -3
- package/dist/types/internal/app-rail.d.ts +10 -0
- package/dist/types/internal/menu-items.d.ts +134 -0
- 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 +2206 -489
- package/dist/zx-zeyos.esm.min.js +56 -1
- package/dist/zx.css +3322 -724
- package/dist/zx.esm.js +12244 -5809
- package/dist/zx.esm.min.js +58 -3
- package/dist/zx.global.js +12246 -5811
- package/dist/zx.global.min.js +58 -3
- package/dist/zx.min.css +1 -1
- package/docs/api.json +1683 -146
- package/docs/llms.md +777 -110
- package/docs/llms.txt +14 -8
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.css +35 -10
- package/src/components/activity-item/activity-item.css +137 -0
- package/src/components/activity-item/activity-item.js +602 -0
- package/src/components/activity-list/activity-list.css +99 -0
- package/src/components/activity-list/activity-list.js +409 -0
- package/src/components/app-icon/app-icon.css +1 -1
- package/src/components/app-rail/app-rail.css +191 -22
- package/src/components/app-sidebar/app-sidebar.css +349 -24
- package/src/components/app-sidebar/app-sidebar.js +86 -11
- 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 +74 -8
- package/src/components/button/button.js +44 -1
- package/src/components/calendar/calendar.css +46 -46
- package/src/components/calendar/calendar.js +33 -3
- package/src/components/card/card.css +2 -2
- package/src/components/card/card.js +12 -1
- package/src/components/card-view/card-view.css +10 -7
- package/src/components/card-view/card-view.js +25 -9
- package/src/components/card-view/record-card.js +7 -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 +68 -0
- package/src/components/code-editor/code-editor.js +306 -0
- package/src/components/code-editor/field-adapter.js +34 -0
- package/src/components/context-menu/context-menu.css +87 -5
- package/src/components/context-menu/context-menu.js +22 -30
- 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-picker.js +22 -8
- package/src/components/date-picker/date-range-picker.css +3 -3
- package/src/components/date-picker/month-picker.js +3 -3
- package/src/components/date-picker/time-picker.css +1 -1
- package/src/components/date-picker/time-picker.js +20 -8
- 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 +174 -70
- package/src/components/dropdown/dropdown.css +1 -1
- package/src/components/dropdown/dropdown.js +7 -5
- package/src/components/empty-state/empty-state.css +2 -2
- package/src/components/entity-ref/entity-ref.css +182 -0
- package/src/components/entity-ref/entity-ref.js +496 -0
- 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.css +88 -0
- package/src/components/file-item/file-item.js +505 -0
- package/src/components/file-list/file-list.css +51 -0
- package/src/components/file-list/file-list.js +320 -0
- package/src/components/filter/filter.css +27 -1
- package/src/components/filter/filter.js +205 -47
- package/src/components/filter-panel/filter-panel.css +104 -0
- package/src/components/filter-panel/filter-panel.js +964 -0
- 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 +247 -0
- package/src/components/kanban-view/kanban-view.css +226 -8
- package/src/components/kanban-view/kanban-view.js +255 -12
- package/src/components/launcher/launcher.css +107 -25
- package/src/components/launcher/launcher.js +557 -63
- package/src/components/list-toolbar/list-toolbar.css +194 -0
- package/src/components/list-toolbar/list-toolbar.js +851 -0
- package/src/components/master-panel/master-panel.css +2 -0
- package/src/components/menu-button/menu-button.css +87 -5
- package/src/components/menu-button/menu-button.js +86 -46
- package/src/components/message/message.css +38 -5
- package/src/components/message/message.js +230 -17
- package/src/components/modal/modal.css +15 -0
- package/src/components/modal/modal.js +159 -3
- package/src/components/navigation-bar/navigation-bar.css +95 -11
- package/src/components/navigation-bar/navigation-bar.js +171 -4
- 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/panel/panel.js +13 -2
- package/src/components/rating/rating.css +7 -0
- package/src/components/search/search.js +17 -5
- package/src/components/select/color.js +22 -0
- package/src/components/select/field-adapter.js +6 -1
- package/src/components/select/glyphs.js +165 -0
- package/src/components/select/select.css +138 -45
- package/src/components/select/select.js +86 -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 +20 -0
- package/src/components/sort-control/sort-control.js +140 -0
- package/src/components/stat-tile/stat-tile.css +208 -0
- package/src/components/stat-tile/stat-tile.js +601 -0
- package/src/components/tabbox/tabbox.css +32 -27
- package/src/components/tabbox/tabbox.js +17 -2
- package/src/components/table/table.css +155 -31
- package/src/components/table/table.js +386 -33
- package/src/components/table-view/table-view.css +8 -2
- package/src/components/table-view/table-view.js +21 -6
- package/src/components/tag-picker/tag-picker.css +86 -6
- package/src/components/tag-picker/tag-picker.js +25 -8
- package/src/components/timebox/timebox.css +22 -2
- package/src/components/timebox/timebox.js +18 -5
- 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/value-list/value-list.js +22 -6
- package/src/components/view/record-view.css +5 -0
- package/src/components/view/record-view.js +100 -7
- package/src/core/breakpoint.js +1 -1
- package/src/core/icons.js +259 -57
- package/src/core/motion.js +147 -0
- package/src/core/overlay-host.js +21 -2
- package/src/index.js +30 -3
- package/src/internal/app-rail.js +18 -1
- package/src/internal/menu-items.js +142 -0
- 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/print.css +192 -0
- 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 +11 -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,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Component } from '../../core/component.js';
|
|
2
2
|
import { h } from '../../core/dom.js';
|
|
3
3
|
import { icon } from '../../core/icons.js';
|
|
4
|
+
import { printf } from '../../core/i18n.js';
|
|
4
5
|
import {
|
|
5
6
|
CALENDAR_VIEWS, addCalendarDays, calendarDayDifference, calendarDayKey,
|
|
6
7
|
calendarEventIntersects, calendarEventSpansDays, calendarPageDate, calendarRange,
|
|
@@ -189,7 +190,7 @@ export class Calendar extends Component {
|
|
|
189
190
|
ref: 'views',
|
|
190
191
|
class: 'zx-calendar__views',
|
|
191
192
|
role: 'group',
|
|
192
|
-
ariaLabel: 'Calendar view'
|
|
193
|
+
ariaLabel: this._message('calendar.viewSwitch', 'Calendar view')
|
|
193
194
|
}, this._views.map((view) => h('button', {
|
|
194
195
|
type: 'button',
|
|
195
196
|
class: 'zx-calendar__view-button',
|
|
@@ -643,7 +644,7 @@ export class Calendar extends Component {
|
|
|
643
644
|
eventCount: String(count)
|
|
644
645
|
},
|
|
645
646
|
ariaCurrent: sameCalendarDay(day, this._now()) ? 'date' : null,
|
|
646
|
-
ariaLabel:
|
|
647
|
+
ariaLabel: this._dayCountLabel(day, count),
|
|
647
648
|
disabled: this.options.disabled
|
|
648
649
|
}, this._format(day, { day: 'numeric' })));
|
|
649
650
|
}
|
|
@@ -708,7 +709,7 @@ export class Calendar extends Component {
|
|
|
708
709
|
activity: String(Math.min(3, count))
|
|
709
710
|
},
|
|
710
711
|
ariaCurrent: sameCalendarDay(day, this._now()) ? 'date' : null,
|
|
711
|
-
ariaLabel:
|
|
712
|
+
ariaLabel: this._dayCountLabel(day, count),
|
|
712
713
|
disabled: this.options.disabled
|
|
713
714
|
}, String(day.getDate())));
|
|
714
715
|
}
|
|
@@ -1473,6 +1474,35 @@ export class Calendar extends Component {
|
|
|
1473
1474
|
if (!this._destroyed) this.refs.status.textContent = message;
|
|
1474
1475
|
});
|
|
1475
1476
|
}
|
|
1477
|
+
|
|
1478
|
+
/**
|
|
1479
|
+
* Names a month or year cell by its date and how many events it holds. Singular and plural are
|
|
1480
|
+
* separate keys because a language that inflects the noun cannot reach it from one template.
|
|
1481
|
+
* @param {Date} day Day the cell stands for.
|
|
1482
|
+
* @param {number} count Events on that day.
|
|
1483
|
+
* @returns {string}
|
|
1484
|
+
*/
|
|
1485
|
+
_dayCountLabel(day, count) {
|
|
1486
|
+
const date = this._format(day, { dateStyle: 'full' });
|
|
1487
|
+
return count === 1
|
|
1488
|
+
? this._message('calendar.dayEvent', '%1, %2 event', date, count)
|
|
1489
|
+
: this._message('calendar.dayEvents', '%1, %2 events', date, count);
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
/**
|
|
1493
|
+
* Resolves a message through the host translator, falling back to the built-in English text.
|
|
1494
|
+
*
|
|
1495
|
+
* Distinct from `msg()`: the built-in `msg` option answers the calendar's own vocabulary, so a
|
|
1496
|
+
* dotted key falls past it to the host translator, which is what these strings never had.
|
|
1497
|
+
* @param {string} key Message key.
|
|
1498
|
+
* @param {string} fallback Built-in text, with `%1`-style placeholders.
|
|
1499
|
+
* @param {...unknown} args Interpolation values.
|
|
1500
|
+
* @returns {string}
|
|
1501
|
+
*/
|
|
1502
|
+
_message(key, fallback, ...args) {
|
|
1503
|
+
const message = this.msg(key, ...args);
|
|
1504
|
+
return message === key ? printf(fallback, args) : message;
|
|
1505
|
+
}
|
|
1476
1506
|
}
|
|
1477
1507
|
|
|
1478
1508
|
/** @param {unknown} value @returns {CalendarView[]} */
|
|
@@ -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,
|
|
@@ -86,7 +86,7 @@ export class Card extends Component {
|
|
|
86
86
|
ref: 'actions',
|
|
87
87
|
class: 'zx-card__actions',
|
|
88
88
|
role: 'group',
|
|
89
|
-
ariaLabel: 'Card actions',
|
|
89
|
+
ariaLabel: this._message('card.actions', 'Card actions'),
|
|
90
90
|
hidden: true
|
|
91
91
|
});
|
|
92
92
|
const content = h('div', { ref: 'content', class: 'zx-card__content', hidden: true });
|
|
@@ -225,6 +225,17 @@ export class Card extends Component {
|
|
|
225
225
|
if (!this.refs.header) return;
|
|
226
226
|
this.refs.header.hidden = this._title === '' && this.refs.actions.childElementCount === 0;
|
|
227
227
|
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Resolves a message through the host translator, falling back to the built-in English text.
|
|
231
|
+
* @param {string} key Message key.
|
|
232
|
+
* @param {string} fallback English default.
|
|
233
|
+
* @returns {string}
|
|
234
|
+
*/
|
|
235
|
+
_message(key, fallback) {
|
|
236
|
+
const message = this.msg(key);
|
|
237
|
+
return message === key ? fallback : message;
|
|
238
|
+
}
|
|
228
239
|
}
|
|
229
240
|
|
|
230
241
|
/** @param {Element} host @param {CardContent} content @param {string} label */
|
|
@@ -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
|
|
|
@@ -589,3 +591,4 @@
|
|
|
589
591
|
min-block-size: 44px;
|
|
590
592
|
}
|
|
591
593
|
}
|
|
594
|
+
.zx-card-view .zx-record-card[data-selection-trigger="card"] { cursor: pointer; }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { h, restoreTarget, snapshotTarget } from '../../core/dom.js';
|
|
3
|
-
import { RecordView, readViewField } from '../view/record-view.js';
|
|
3
|
+
import { normalizeViewFieldControls, RecordView, readViewField } from '../view/record-view.js';
|
|
4
4
|
import {
|
|
5
5
|
createRecordCard, resolveRecordActions
|
|
6
6
|
} from './record-card.js';
|
|
@@ -21,10 +21,13 @@ import {
|
|
|
21
21
|
* @property {import('../view/record-view.js').ViewSort|null} [sort=null] Initial shared sort.
|
|
22
22
|
* @property {'local'|'server'} [sortMode='local'] Local sorting or event-only server sorting.
|
|
23
23
|
* @property {false|'single'|'multi'} [selectable=false] Record selection behavior.
|
|
24
|
+
* @property {'checkbox'|'card'} [selectionTrigger='checkbox'] Select through a checkbox or the non-interactive card surface.
|
|
24
25
|
* @property {unknown[]} [selection=[]] Initially selected record ids.
|
|
25
26
|
* @property {string[]} [fieldOrder=[]] Preferred shared field order.
|
|
26
27
|
* @property {string[]} [hiddenFields=[]] Initially hidden metadata fields.
|
|
27
|
-
* @property {boolean} [fieldControls=true]
|
|
28
|
+
* @property {boolean|import('../view/record-view.js').ViewFieldControlsConfig} [fieldControls=true]
|
|
29
|
+
* Whether to expose shared field controls. `true` renders the chooser in the card toolbar and
|
|
30
|
+
* `false` omits it; an object customises its `label` and mounts it into `target`.
|
|
28
31
|
* @property {string|Node|(()=>string|Node)|null} [emptyText=null] Empty-result content.
|
|
29
32
|
* @property {RecordCardValueSource} [titleField=null] Title field id or explicit resolver.
|
|
30
33
|
* @property {RecordCardValueSource} [subtitleField=null] Subtitle field id or explicit resolver.
|
|
@@ -79,6 +82,7 @@ export class CardView extends RecordView {
|
|
|
79
82
|
/** @type {Readonly<CardViewOptions & RecordViewOptions>} */
|
|
80
83
|
static defaults = {
|
|
81
84
|
...RecordView.defaults,
|
|
85
|
+
selectionTrigger: 'checkbox',
|
|
82
86
|
titleField: null,
|
|
83
87
|
subtitleField: null,
|
|
84
88
|
preview: undefined,
|
|
@@ -124,10 +128,12 @@ export class CardView extends RecordView {
|
|
|
124
128
|
this._initRecordView(root);
|
|
125
129
|
root.setAttribute('aria-label', String(options.label || 'Card view'));
|
|
126
130
|
const sort = h('label', { ref: 'sortWrap', class: 'zx-card-view__sort' },
|
|
127
|
-
h('span', { class: 'zx-card-view__sort-label' }, 'Sort'),
|
|
128
|
-
h('select', { ref: 'sort', ariaLabel: 'Sort cards' }));
|
|
131
|
+
h('span', { class: 'zx-card-view__sort-label' }, this._message('cardView.sort', 'Sort')),
|
|
132
|
+
h('select', { ref: 'sort', ariaLabel: this._message('cardView.sortCards', 'Sort cards') }));
|
|
129
133
|
const toolbar = h('div', { class: 'zx-record-view__toolbar zx-card-view__toolbar' }, sort);
|
|
130
|
-
if (this.options.fieldControls)
|
|
134
|
+
if (normalizeViewFieldControls(this.options.fieldControls).enabled) {
|
|
135
|
+
this._mountViewFieldControls(toolbar);
|
|
136
|
+
}
|
|
131
137
|
const content = h('div', { ref: 'content', class: 'zx-card-view__content' });
|
|
132
138
|
root.replaceChildren(toolbar, content);
|
|
133
139
|
this.listen(this.refs.sort, 'change', () => this._changeCardSort());
|
|
@@ -140,6 +146,7 @@ export class CardView extends RecordView {
|
|
|
140
146
|
this._renderCards();
|
|
141
147
|
return root;
|
|
142
148
|
} catch (error) {
|
|
149
|
+
this._removeViewFieldControls();
|
|
143
150
|
if (!created) restoreTarget(root, this._cardOriginal);
|
|
144
151
|
throw error;
|
|
145
152
|
}
|
|
@@ -212,16 +219,18 @@ export class CardView extends RecordView {
|
|
|
212
219
|
if (!this.refs?.sort || !this.refs?.sortWrap) return;
|
|
213
220
|
const select = /** @type {HTMLSelectElement} */ (this.refs.sort);
|
|
214
221
|
const sort = this.getSort();
|
|
215
|
-
const options = [h('option', {
|
|
222
|
+
const options = [h('option', {
|
|
223
|
+
value: '', selected: sort === null
|
|
224
|
+
}, this._message('cardView.unsorted', 'Unsorted'))];
|
|
216
225
|
for (const field of this.getFields().filter((candidate) => candidate.sortable)) {
|
|
217
226
|
options.push(h('option', {
|
|
218
227
|
selected: sort?.id === field.id && sort.dir === 'asc',
|
|
219
228
|
dataset: { sortId: field.id, sortDir: 'asc' }
|
|
220
|
-
},
|
|
229
|
+
}, this._message('cardView.sortAscending', '%1 (ascending)', field.label)));
|
|
221
230
|
options.push(h('option', {
|
|
222
231
|
selected: sort?.id === field.id && sort.dir === 'desc',
|
|
223
232
|
dataset: { sortId: field.id, sortDir: 'desc' }
|
|
224
|
-
},
|
|
233
|
+
}, this._message('cardView.sortDescending', '%1 (descending)', field.label)));
|
|
225
234
|
}
|
|
226
235
|
select.replaceChildren(...options);
|
|
227
236
|
/** @type {HTMLElement} */ (this.refs.sortWrap).hidden = options.length === 1;
|
|
@@ -286,6 +295,7 @@ export class CardView extends RecordView {
|
|
|
286
295
|
link: options.link,
|
|
287
296
|
actions: options.actions,
|
|
288
297
|
selectable: this.options.selectable,
|
|
298
|
+
selectionTrigger: options.selectionTrigger,
|
|
289
299
|
selected: this._isViewSelected(id),
|
|
290
300
|
variant: this._cardVariant,
|
|
291
301
|
headingLevel: this._cardHeadingLevel
|
|
@@ -355,6 +365,11 @@ export class CardView extends RecordView {
|
|
|
355
365
|
return;
|
|
356
366
|
}
|
|
357
367
|
if (isInteractiveWithin(target, card) || hasCardTextSelection(card)) return;
|
|
368
|
+
if (this.options.selectable && this._cardOptions().selectionTrigger === 'card') {
|
|
369
|
+
this.toggleSelection(id, { range: event.shiftKey });
|
|
370
|
+
card.focus({ preventScroll: true });
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
358
373
|
this._activateCard(record, id, index, event);
|
|
359
374
|
if (this.options.selectable === 'single') this.toggleSelection(id, { selected: true });
|
|
360
375
|
}
|
|
@@ -381,7 +396,8 @@ export class CardView extends RecordView {
|
|
|
381
396
|
const id = this._viewRecordId(record);
|
|
382
397
|
if (event.key === 'Enter') {
|
|
383
398
|
event.preventDefault();
|
|
384
|
-
this.
|
|
399
|
+
if (this.options.selectable && this._cardOptions().selectionTrigger === 'card') this.toggleSelection(id);
|
|
400
|
+
else this._activateCard(record, id, index, event);
|
|
385
401
|
} else if (event.key === ' ' && this.options.selectable) {
|
|
386
402
|
event.preventDefault();
|
|
387
403
|
this.toggleSelection(id);
|
|
@@ -62,6 +62,7 @@ import { readViewField, renderViewField } from '../view/record-view.js';
|
|
|
62
62
|
* @property {RecordCardLink|((record:ViewRecord,index:number)=>RecordCardLink)} [link]
|
|
63
63
|
* @property {RecordCardAction[]|((record:ViewRecord,index:number)=>RecordCardAction[])} [actions=[]]
|
|
64
64
|
* @property {false|'single'|'multi'} [selectable=false] Selection presentation.
|
|
65
|
+
* @property {'checkbox'|'card'} [selectionTrigger='checkbox'] Selection affordance for owning views.
|
|
65
66
|
* @property {boolean} [selected=false] Current selection state.
|
|
66
67
|
* @property {'outlined'|'raised'|'filled'} [variant='outlined'] Surface treatment.
|
|
67
68
|
* @property {1|2|3|4|5|6} [headingLevel=3] Card title heading level.
|
|
@@ -84,7 +85,8 @@ import { readViewField, renderViewField } from '../view/record-view.js';
|
|
|
84
85
|
*
|
|
85
86
|
* The returned `<li>` belongs in a semantic `<ul>`/`<ol>`. When selectable its global
|
|
86
87
|
* `aria-description` announces selection without applying the unsupported `aria-selected` state
|
|
87
|
-
* to a listitem; multi-selection
|
|
88
|
+
* to a listitem; multi-selection adds a native checkbox unless the owner opts into card-surface
|
|
89
|
+
* selection. It deliberately remains a listitem
|
|
88
90
|
* rather than becoming an ARIA option because cards may contain native links and buttons, which
|
|
89
91
|
* the listbox pattern does not permit inside an option. Preview images are paired with a stable
|
|
90
92
|
* fallback. The owning component listens for image `error` and marks the fallback.
|
|
@@ -129,7 +131,7 @@ export function createRecordCard(record, index, options = {}) {
|
|
|
129
131
|
const titleRow = titlePrefix
|
|
130
132
|
? h('div', { class: 'zx-record-card__title-row' }, titlePrefix, heading)
|
|
131
133
|
: heading;
|
|
132
|
-
const selection = selectable === 'multi' ? h('label', {
|
|
134
|
+
const selection = selectable === 'multi' && options.selectionTrigger !== 'card' ? h('label', {
|
|
133
135
|
class: 'zx-record-card__selection'
|
|
134
136
|
}, h('input', {
|
|
135
137
|
type: 'checkbox',
|
|
@@ -154,10 +156,12 @@ export function createRecordCard(record, index, options = {}) {
|
|
|
154
156
|
tabindex: 0,
|
|
155
157
|
ariaDescription: selectable ? selected ? 'Selected' : 'Not selected' : undefined,
|
|
156
158
|
ariaLabelledby: headingId,
|
|
159
|
+
ariaKeyshortcuts: selectable && options.selectionTrigger === 'card' ? 'Space Enter' : undefined,
|
|
157
160
|
dataset: {
|
|
158
161
|
recordIndex: String(index),
|
|
159
162
|
variant: normalizeVariant(options.variant),
|
|
160
|
-
selected: String(selected)
|
|
163
|
+
selected: String(selected),
|
|
164
|
+
selectionTrigger: selectable && options.selectionTrigger === 'card' ? 'card' : 'checkbox'
|
|
161
165
|
}
|
|
162
166
|
}, preview ? createPreview(preview) : null, body));
|
|
163
167
|
return card;
|
|
@@ -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,
|