@zeyos/zx 5.2.0 → 5.3.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 +34 -0
- package/dist/types/components/card-view/card-view.d.ts +236 -0
- package/dist/zx.css +56 -0
- package/dist/zx.esm.js +453 -30
- package/dist/zx.esm.min.js +6 -6
- package/dist/zx.global.js +453 -30
- package/dist/zx.global.min.js +6 -6
- package/dist/zx.min.css +1 -1
- package/docs/api.json +41 -0
- package/docs/llms.md +30 -2
- package/package.json +1 -1
- package/src/components/card-view/card-view.css +71 -0
- package/src/components/card-view/card-view.js +505 -15
- package/src/components/search/search.css +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,40 @@ and friends remain the complete record.
|
|
|
8
8
|
|
|
9
9
|
## Unreleased
|
|
10
10
|
|
|
11
|
+
## 5.3.0 — 2026-10-29
|
|
12
|
+
|
|
13
|
+
The record collection's toolbar, chips, drawers and pager become one shared composition in the
|
|
14
|
+
layout kit, and the CRM and the issue tracker are rebuilt on it.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `CardView` `keyboard: 'roving'` — the APG grid keyboard model the `Table` already has: the
|
|
19
|
+
collection is one Tab stop, arrows move between cards and group headings by the rendered rows,
|
|
20
|
+
Home/End and Page keys, Enter activates, Space and Shift+Arrow select, Ctrl/Cmd+A selects all;
|
|
21
|
+
focus is kept by record id across re-renders. `'tabs'`, the default, is unchanged.
|
|
22
|
+
- `CardView` `collapsibleGroups`, `collapsedGroups`, `setGroupCollapsed()`, `getCollapsedGroups()`
|
|
23
|
+
and the `groupcollapse` event; `renderGroupHeading(context)` renders a group's heading with the
|
|
24
|
+
id, label, count, records, collapsed state and a `toggle()`.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- A narrow `Search` field squeezed its submit and clear buttons below the control height.
|
|
29
|
+
|
|
30
|
+
### Website
|
|
31
|
+
|
|
32
|
+
- The record collection's composition — toolbar, chip strip and chip editors, the Filters and View
|
|
33
|
+
settings drawers, page slicing, grouping, pagination, board axes and the keyboard map — is one
|
|
34
|
+
shared layout-kit module, with `other` buckets that write back, a base filter for tabs and
|
|
35
|
+
scopes, a split empty state, a `rendered` event and one-line toolbars beside an open drawer.
|
|
36
|
+
- **CRM**: companies, people, deals and the curated lists use the shared overview: inline search,
|
|
37
|
+
the Filter, Sort and View drawers, the five-way shape switch, chips and the pager under the saved
|
|
38
|
+
view tabs. Companies gain cards and a stage board, people gain cards; owner and tier have
|
|
39
|
+
Unassigned and No tier buckets so no record drops out of a grouped view; the ARR total rides the
|
|
40
|
+
count line and the board columns keep their totals.
|
|
41
|
+
- **Issue tracker**: the list is a roving `CardView` in the tracker's dense row anatomy with
|
|
42
|
+
collapsible group headings carrying status glyphs and counts and "New issue in <group>" on each;
|
|
43
|
+
the board takes its swim lanes from the grouping; the fixed tabs stay in the header.
|
|
44
|
+
|
|
11
45
|
## 5.2.0 — 2026-10-29
|
|
12
46
|
|
|
13
47
|
A record collection pattern with a five-way view switch and filter chips, two components to go
|
|
@@ -113,7 +113,60 @@ export type CardViewOptions = {
|
|
|
113
113
|
* `cardView.label`, "Card view".
|
|
114
114
|
*/
|
|
115
115
|
label?: string | null;
|
|
116
|
+
/**
|
|
117
|
+
* Keyboard model. `'tabs'` makes every card, title
|
|
118
|
+
* link, checkbox, and action its own Tab stop. `'roving'` — recommended for lists — follows the
|
|
119
|
+
* APG Grid pattern with row focus: the collection is one Tab stop, the arrow keys, Home/End, and
|
|
120
|
+
* PageUp/PageDown move between cards, Enter activates, Space selects, and the controls inside a
|
|
121
|
+
* card stay pointer targets with `tabindex="-1"`.
|
|
122
|
+
*/
|
|
123
|
+
keyboard?: 'tabs' | 'roving';
|
|
124
|
+
/**
|
|
125
|
+
* Whether group headings carry a toggle that hides
|
|
126
|
+
* and shows the group's cards.
|
|
127
|
+
*/
|
|
128
|
+
collapsibleGroups?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Group ids that start collapsed.
|
|
131
|
+
*/
|
|
132
|
+
collapsedGroups?: unknown[];
|
|
133
|
+
/**
|
|
134
|
+
* Content of a group heading in place of its label. With `collapsibleGroups` it is placed inside
|
|
135
|
+
* the toggle button, so it must not contain interactive elements.
|
|
136
|
+
*/
|
|
137
|
+
renderGroupHeading?: ((context: CardGroupHeadingContext) => Node | string | null | undefined) | null;
|
|
116
138
|
onrecordaction?: (event: CustomEvent<Record<string, unknown>>) => void;
|
|
139
|
+
ongroupcollapse?: (event: CustomEvent<{
|
|
140
|
+
id: string;
|
|
141
|
+
collapsed: boolean;
|
|
142
|
+
collapsedGroups: string[];
|
|
143
|
+
}>) => void;
|
|
144
|
+
};
|
|
145
|
+
export type CardGroupHeadingContext = {
|
|
146
|
+
/**
|
|
147
|
+
* Normalized group id (`''` for records without a value).
|
|
148
|
+
*/
|
|
149
|
+
id: string;
|
|
150
|
+
/**
|
|
151
|
+
* Default label.
|
|
152
|
+
*/
|
|
153
|
+
label: string;
|
|
154
|
+
/**
|
|
155
|
+
* Records in the group.
|
|
156
|
+
*/
|
|
157
|
+
count: number;
|
|
158
|
+
/**
|
|
159
|
+
* The group's records in display order.
|
|
160
|
+
*/
|
|
161
|
+
records: ViewRecord[];
|
|
162
|
+
/**
|
|
163
|
+
* Whether the group is collapsed.
|
|
164
|
+
*/
|
|
165
|
+
collapsed: boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Collapses or expands the group.
|
|
168
|
+
*/
|
|
169
|
+
toggle: () => void;
|
|
117
170
|
};
|
|
118
171
|
export type CardViewState = {
|
|
119
172
|
/**
|
|
@@ -148,6 +201,10 @@ export type CardViewState = {
|
|
|
148
201
|
* Surface treatment.
|
|
149
202
|
*/
|
|
150
203
|
variant: 'outlined' | 'raised' | 'filled';
|
|
204
|
+
/**
|
|
205
|
+
* Collapsed group ids.
|
|
206
|
+
*/
|
|
207
|
+
collapsedGroups: string[];
|
|
151
208
|
};
|
|
152
209
|
export type CardRecordGroup = {
|
|
153
210
|
/**
|
|
@@ -206,7 +263,29 @@ export type CardRecordGroup = {
|
|
|
206
263
|
* @property {1|2|3|4|5|6} [headingLevel=3] Per-card title heading level.
|
|
207
264
|
* @property {string|null} [label=null] Accessible collection label; null resolves message
|
|
208
265
|
* `cardView.label`, "Card view".
|
|
266
|
+
* @property {'tabs'|'roving'} [keyboard='tabs'] Keyboard model. `'tabs'` makes every card, title
|
|
267
|
+
* link, checkbox, and action its own Tab stop. `'roving'` — recommended for lists — follows the
|
|
268
|
+
* APG Grid pattern with row focus: the collection is one Tab stop, the arrow keys, Home/End, and
|
|
269
|
+
* PageUp/PageDown move between cards, Enter activates, Space selects, and the controls inside a
|
|
270
|
+
* card stay pointer targets with `tabindex="-1"`.
|
|
271
|
+
* @property {boolean} [collapsibleGroups=false] Whether group headings carry a toggle that hides
|
|
272
|
+
* and shows the group's cards.
|
|
273
|
+
* @property {unknown[]} [collapsedGroups=[]] Group ids that start collapsed.
|
|
274
|
+
* @property {((context:CardGroupHeadingContext)=>Node|string|null|undefined)|null} [renderGroupHeading=null]
|
|
275
|
+
* Content of a group heading in place of its label. With `collapsibleGroups` it is placed inside
|
|
276
|
+
* the toggle button, so it must not contain interactive elements.
|
|
209
277
|
* @property {(event:CustomEvent<Record<string,unknown>>)=>void} [onrecordaction]
|
|
278
|
+
* @property {(event:CustomEvent<{id:string,collapsed:boolean,collapsedGroups:string[]}>)=>void} [ongroupcollapse]
|
|
279
|
+
*/
|
|
280
|
+
/**
|
|
281
|
+
* What `renderGroupHeading` is given for one group.
|
|
282
|
+
* @typedef {Object} CardGroupHeadingContext
|
|
283
|
+
* @property {string} id Normalized group id (`''` for records without a value).
|
|
284
|
+
* @property {string} label Default label.
|
|
285
|
+
* @property {number} count Records in the group.
|
|
286
|
+
* @property {ViewRecord[]} records The group's records in display order.
|
|
287
|
+
* @property {boolean} collapsed Whether the group is collapsed.
|
|
288
|
+
* @property {() => void} toggle Collapses or expands the group.
|
|
210
289
|
*/
|
|
211
290
|
/**
|
|
212
291
|
* @typedef {Object} CardViewState
|
|
@@ -218,6 +297,7 @@ export type CardRecordGroup = {
|
|
|
218
297
|
* @property {string} minCardWidth Responsive minimum card width.
|
|
219
298
|
* @property {number|null} maxColumns Maximum cards per row.
|
|
220
299
|
* @property {'outlined'|'raised'|'filled'} variant Surface treatment.
|
|
300
|
+
* @property {string[]} collapsedGroups Collapsed group ids.
|
|
221
301
|
*/
|
|
222
302
|
/**
|
|
223
303
|
* @typedef {Object} CardRecordGroup
|
|
@@ -228,7 +308,20 @@ export type CardRecordGroup = {
|
|
|
228
308
|
/**
|
|
229
309
|
* Responsive, schema-friendly record cards with shared fields, sorting, selection, state, groups,
|
|
230
310
|
* safe preview media, native title links, and delegated actions.
|
|
311
|
+
*
|
|
312
|
+
* With `keyboard: 'roving'` the collection follows the WAI-ARIA APG Grid pattern with row focus,
|
|
313
|
+
* the model `Table` uses: the content is a `grid`, each card a focusable `row` (`aria-selected`
|
|
314
|
+
* when selectable, `aria-multiselectable` on the grid for `multi`), and the collection is a single
|
|
315
|
+
* Tab stop. ArrowUp/ArrowDown move to the card above or below — columns are measured from where the
|
|
316
|
+
* cards actually are, so a multi-column layout moves by visual row — ArrowLeft/ArrowRight within a
|
|
317
|
+
* row, Home/End to the first or last card, PageUp/PageDown by a visible page. Enter activates
|
|
318
|
+
* (`recordclick`), Space toggles selection in `selectable` modes (and activates otherwise),
|
|
319
|
+
* Shift+movement extends a `multi` selection, and Ctrl/Cmd+A selects every rendered card. A
|
|
320
|
+
* collapsible group heading is part of the same order: Enter or Space toggles it, ArrowLeft
|
|
321
|
+
* collapses, ArrowRight expands. The current card is kept by record id across `setData`, sorting,
|
|
322
|
+
* grouping, and collapsing, and focus is restored without scrolling.
|
|
231
323
|
* @fires CardView#recordaction
|
|
324
|
+
* @fires CardView#groupcollapse
|
|
232
325
|
* @extends {RecordView}
|
|
233
326
|
*/
|
|
234
327
|
export declare class CardView extends RecordView {
|
|
@@ -242,6 +335,28 @@ export declare class CardView extends RecordView {
|
|
|
242
335
|
_cardVariant: "filled" | "outlined" | "raised";
|
|
243
336
|
_cardLoadingCount: number;
|
|
244
337
|
_cardHeadingLevel: 1 | 2 | 3 | 4 | 5 | 6;
|
|
338
|
+
_cardRoving: boolean;
|
|
339
|
+
_cardIdPrefix: string;
|
|
340
|
+
_cardCollapsed: Set<string>;
|
|
341
|
+
/** @type {{kind:'card'|'group', id:unknown}|null} */
|
|
342
|
+
_cardCurrent: {
|
|
343
|
+
kind: 'card' | 'group';
|
|
344
|
+
id: unknown;
|
|
345
|
+
} | null;
|
|
346
|
+
_cardCurrentIndex: number;
|
|
347
|
+
/** @type {HTMLElement|null} */
|
|
348
|
+
_cardTabStop: HTMLElement | null;
|
|
349
|
+
/** @type {number|null} */
|
|
350
|
+
_cardStickyX: number | null;
|
|
351
|
+
_cardMoving: boolean;
|
|
352
|
+
/** @type {Map<string, HTMLElement>} */
|
|
353
|
+
_cardHeadersById: Map<string, HTMLElement>;
|
|
354
|
+
/** @type {Map<unknown, string>} */
|
|
355
|
+
_cardGroupOfId: Map<unknown, string>;
|
|
356
|
+
/** @type {Map<Element, string>} */
|
|
357
|
+
_cardSectionIds: Map<Element, string>;
|
|
358
|
+
/** @type {WeakMap<Element, unknown>} */
|
|
359
|
+
_cardIdOfNode: WeakMap<Element, unknown>;
|
|
245
360
|
static cssName: string;
|
|
246
361
|
/** @type {Readonly<CardViewOptions & RecordViewOptions>} */
|
|
247
362
|
static defaults: Readonly<CardViewOptions & RecordViewOptions>;
|
|
@@ -264,6 +379,19 @@ export declare class CardView extends RecordView {
|
|
|
264
379
|
setViewState(state: Partial<CardViewState> | null, options?: {
|
|
265
380
|
silent?: boolean;
|
|
266
381
|
}): this;
|
|
382
|
+
/**
|
|
383
|
+
* Collapses or expands one group. A collapsed group keeps its heading and hides its cards.
|
|
384
|
+
* @param {unknown} id Group id, as `groupBy` produces it.
|
|
385
|
+
* @param {boolean} [collapsed=true] Next state.
|
|
386
|
+
* @param {{silent?:boolean}} [options={}] Set `silent` to suppress `groupcollapse` and `statechange`.
|
|
387
|
+
* @returns {this}
|
|
388
|
+
* @fires CardView#groupcollapse
|
|
389
|
+
*/
|
|
390
|
+
setGroupCollapsed(id: unknown, collapsed?: boolean, options?: {
|
|
391
|
+
silent?: boolean;
|
|
392
|
+
}): this;
|
|
393
|
+
/** Returns the collapsed group ids. @returns {string[]} */
|
|
394
|
+
getCollapsedGroups(): string[];
|
|
267
395
|
/** Restores an enhanced target exactly, or removes an owned root. @returns {void} */
|
|
268
396
|
destroy(): void;
|
|
269
397
|
/** @protected @param {string} reason Refresh reason. @returns {void} */
|
|
@@ -278,6 +406,67 @@ export declare class CardView extends RecordView {
|
|
|
278
406
|
private _renderCards;
|
|
279
407
|
/** @private @param {CardRecordGroup} group @param {ViewField[]} fields @param {ViewField[]} visibleFields @param {number} groupIndex @returns {HTMLElement} */
|
|
280
408
|
private _createCardGroup;
|
|
409
|
+
/**
|
|
410
|
+
* Builds a group heading: the label (or `renderGroupHeading` content), inside an APG
|
|
411
|
+
* disclosure button when the group can collapse.
|
|
412
|
+
* @private
|
|
413
|
+
* @param {CardRecordGroup} group Group.
|
|
414
|
+
* @param {string} headingId Heading id.
|
|
415
|
+
* @param {boolean} collapsible Whether the group can collapse.
|
|
416
|
+
* @param {boolean} collapsed Whether it is collapsed.
|
|
417
|
+
* @returns {HTMLElement}
|
|
418
|
+
*/
|
|
419
|
+
private _createGroupHeader;
|
|
420
|
+
/**
|
|
421
|
+
* Turns a rendered card into a grid row for the roving model: row focus, `aria-selected` when
|
|
422
|
+
* selectable, and the controls inside it out of the Tab order.
|
|
423
|
+
* @private
|
|
424
|
+
* @param {HTMLElement} card Card element.
|
|
425
|
+
* @param {unknown} id Record id.
|
|
426
|
+
* @returns {void}
|
|
427
|
+
*/
|
|
428
|
+
private _makeCardRow;
|
|
429
|
+
/**
|
|
430
|
+
* Moves the single Tab stop to the current item after a render — the same record or group by
|
|
431
|
+
* id; else the heading of the collapsed group that now hides the card; else the item now at its
|
|
432
|
+
* old position — and focuses it again, without scrolling, when the collection had focus.
|
|
433
|
+
* @private
|
|
434
|
+
* @param {boolean} hadFocus Whether focus was inside the collection before the render.
|
|
435
|
+
* @returns {void}
|
|
436
|
+
*/
|
|
437
|
+
private _syncCardRoving;
|
|
438
|
+
/**
|
|
439
|
+
* @private
|
|
440
|
+
* @param {HTMLElement} item New Tab stop.
|
|
441
|
+
* @param {HTMLElement[]} [items] Every item, when already collected.
|
|
442
|
+
* @returns {void}
|
|
443
|
+
*/
|
|
444
|
+
private _setCardTabStop;
|
|
445
|
+
/**
|
|
446
|
+
* While loading or empty there is no card to hold focus: the content takes it rather than
|
|
447
|
+
* letting it fall to the document, and gives the Tab order its old shape back afterwards.
|
|
448
|
+
* @private
|
|
449
|
+
* @param {boolean} hold Whether focus was inside and there is nothing to put it on.
|
|
450
|
+
* @returns {void}
|
|
451
|
+
*/
|
|
452
|
+
private _syncCardEmptyFocus;
|
|
453
|
+
/** @private @returns {HTMLElement[]} Roving items in display order. */
|
|
454
|
+
private _cardItems;
|
|
455
|
+
/** @private @param {HTMLElement} item @returns {{kind:'card'|'group', id:unknown}|null} */
|
|
456
|
+
private _cardItemKey;
|
|
457
|
+
/** @private @param {{kind:'card'|'group', id:unknown}|null} key @returns {HTMLElement|null} */
|
|
458
|
+
private _cardItemFor;
|
|
459
|
+
/** @private @param {FocusEvent} event @returns {void} */
|
|
460
|
+
private _cardFocusIn;
|
|
461
|
+
/**
|
|
462
|
+
* The roving keyboard model; see the class description.
|
|
463
|
+
* @private
|
|
464
|
+
* @param {KeyboardEvent} event Key event.
|
|
465
|
+
* @returns {void}
|
|
466
|
+
*/
|
|
467
|
+
private _cardRovingKeydown;
|
|
468
|
+
/** @private @param {HTMLElement[]} items @returns {unknown[]} Record ids of the card items. */
|
|
469
|
+
private _cardIdsOf;
|
|
281
470
|
/** @private @returns {HTMLElement} */
|
|
282
471
|
private _createCardSkeletons;
|
|
283
472
|
/** @private @returns {HTMLElement} */
|
|
@@ -299,6 +488,53 @@ export declare class CardView extends RecordView {
|
|
|
299
488
|
/** @private @returns {Readonly<CardViewOptions & RecordViewOptions>} */
|
|
300
489
|
private _cardOptions;
|
|
301
490
|
}
|
|
491
|
+
/**
|
|
492
|
+
* Sorts item rectangles into visual rows: items whose tops are within `tolerance` pixels share a
|
|
493
|
+
* row, rows run top to bottom, and items within a row left to right.
|
|
494
|
+
* @param {Array<{top:number,left:number}>} rects Item rectangles in display order.
|
|
495
|
+
* @param {number} [tolerance=4] Pixels two tops may differ by and still share a row.
|
|
496
|
+
* @returns {number[][]} Item indexes per row.
|
|
497
|
+
*/
|
|
498
|
+
export declare function cardGridRows(rects: Array<{
|
|
499
|
+
top: number;
|
|
500
|
+
left: number;
|
|
501
|
+
}>, tolerance?: number): number[][];
|
|
502
|
+
/**
|
|
503
|
+
* How many columns the cards are laid out in: the length of the longest visual row.
|
|
504
|
+
* @param {Array<{top:number,left:number}>} rects Item rectangles.
|
|
505
|
+
* @returns {number} At least 1 for a non-empty list, 0 for an empty one.
|
|
506
|
+
*/
|
|
507
|
+
export declare function cardColumnCount(rects: Array<{
|
|
508
|
+
top: number;
|
|
509
|
+
left: number;
|
|
510
|
+
}>): number;
|
|
511
|
+
/**
|
|
512
|
+
* Where a navigation key moves in a laid-out card grid. ArrowUp/ArrowDown go to the previous or
|
|
513
|
+
* next visual row and PageUp/PageDown `page` rows, landing on the item nearest to `x` (the column
|
|
514
|
+
* the reader is travelling in); ArrowLeft/ArrowRight move within the row and stop at its ends;
|
|
515
|
+
* Home/End go to the first or last item.
|
|
516
|
+
* @param {Array<{top:number,left:number}>} rects Item rectangles in display order.
|
|
517
|
+
* @param {number} index Current item.
|
|
518
|
+
* @param {string} key `KeyboardEvent.key`.
|
|
519
|
+
* @param {{page?:number, x?:number}} [options={}] Rows per page (default 10) and preferred x.
|
|
520
|
+
* @returns {number|null} Next item index, or null when the key is not a move.
|
|
521
|
+
*/
|
|
522
|
+
export declare function cardGridTarget(rects: Array<{
|
|
523
|
+
top: number;
|
|
524
|
+
left: number;
|
|
525
|
+
}>, index: number, key: string, options?: {
|
|
526
|
+
page?: number;
|
|
527
|
+
x?: number;
|
|
528
|
+
}): number | null;
|
|
529
|
+
/**
|
|
530
|
+
* How many rows a PageUp or PageDown moves: the rows that fit in the visible height, less one so
|
|
531
|
+
* the row focus leaves stays in view. Falls back when either height is unknown.
|
|
532
|
+
* @param {number} viewport Visible height of the scroll region.
|
|
533
|
+
* @param {number} rowHeight Height of one row of cards.
|
|
534
|
+
* @param {number} [fallback=10] Rows to move when the heights are unusable.
|
|
535
|
+
* @returns {number} At least 1.
|
|
536
|
+
*/
|
|
537
|
+
export declare function cardPageSize(viewport: number, rowHeight: number, fallback?: number): number;
|
|
302
538
|
/**
|
|
303
539
|
* Groups a cloned record list without mutating records or caller arrays. Explicit order entries
|
|
304
540
|
* are always materialized, including empty groups; remaining values keep first-seen order.
|
package/dist/zx.css
CHANGED
|
@@ -2881,6 +2881,7 @@ button.zx-panel__toggle:focus-visible {
|
|
|
2881
2881
|
}
|
|
2882
2882
|
.zx-search__clear,
|
|
2883
2883
|
.zx-search__submit {
|
|
2884
|
+
flex: none;
|
|
2884
2885
|
display: inline-grid;
|
|
2885
2886
|
place-items: center;
|
|
2886
2887
|
min-block-size: 0;
|
|
@@ -10472,6 +10473,61 @@ button.zx-stat-tile:focus-visible {
|
|
|
10472
10473
|
font-weight: 600;
|
|
10473
10474
|
line-height: 1.3;
|
|
10474
10475
|
}
|
|
10476
|
+
.zx-card-view__group-header {
|
|
10477
|
+
border-radius: var(--zx-radius-sm);
|
|
10478
|
+
}
|
|
10479
|
+
.zx-card-view__group-header:focus-visible {
|
|
10480
|
+
outline: 2px solid transparent;
|
|
10481
|
+
box-shadow: inset var(--zx-focus-ring);
|
|
10482
|
+
}
|
|
10483
|
+
.zx-card-view__group-toggle {
|
|
10484
|
+
display: inline-flex;
|
|
10485
|
+
align-items: center;
|
|
10486
|
+
gap: var(--zx-space-1);
|
|
10487
|
+
min-block-size: 0;
|
|
10488
|
+
margin-inline-start: calc(-1 * var(--zx-space-1));
|
|
10489
|
+
padding: var(--zx-space-1);
|
|
10490
|
+
border: 0;
|
|
10491
|
+
border-radius: var(--zx-radius-sm);
|
|
10492
|
+
background: none;
|
|
10493
|
+
color: inherit;
|
|
10494
|
+
font: inherit;
|
|
10495
|
+
cursor: pointer;
|
|
10496
|
+
}
|
|
10497
|
+
.zx-card-view__group-toggle:hover {
|
|
10498
|
+
background: var(--zx-color-bg-hover);
|
|
10499
|
+
}
|
|
10500
|
+
.zx-card-view__group-toggle:focus-visible {
|
|
10501
|
+
outline: 2px solid transparent;
|
|
10502
|
+
box-shadow: var(--zx-focus-ring);
|
|
10503
|
+
}
|
|
10504
|
+
.zx-card-view__group-toggle > .zx-icon {
|
|
10505
|
+
flex: none;
|
|
10506
|
+
color: var(--zx-color-text-subtle);
|
|
10507
|
+
}
|
|
10508
|
+
.zx-card-view__group-toggle[aria-expanded=false] > .zx-icon {
|
|
10509
|
+
transform: rotate(-90deg);
|
|
10510
|
+
}
|
|
10511
|
+
.zx-card-view__group[data-collapsed=true] .zx-card-view__group-heading {
|
|
10512
|
+
margin-block-end: 0;
|
|
10513
|
+
}
|
|
10514
|
+
.zx-card-view__list[hidden] {
|
|
10515
|
+
display: none;
|
|
10516
|
+
}
|
|
10517
|
+
.zx-card-view[data-keyboard=roving] .zx-record-card:focus-visible {
|
|
10518
|
+
outline: 2px solid transparent;
|
|
10519
|
+
outline-offset: -2px;
|
|
10520
|
+
box-shadow: inset var(--zx-focus-ring);
|
|
10521
|
+
}
|
|
10522
|
+
.zx-card-view__content[data-empty-focus]:focus-visible {
|
|
10523
|
+
outline: 2px solid transparent;
|
|
10524
|
+
box-shadow: inset var(--zx-focus-ring);
|
|
10525
|
+
}
|
|
10526
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
10527
|
+
.zx-card-view__group-toggle > .zx-icon {
|
|
10528
|
+
transition: transform var(--zx-dur-fast) var(--zx-ease);
|
|
10529
|
+
}
|
|
10530
|
+
}
|
|
10475
10531
|
.zx-card-view__list {
|
|
10476
10532
|
display: grid;
|
|
10477
10533
|
grid-template-columns: repeat(auto-fill, minmax(min(100%, max(var(--zx-card-view-min-card-width), calc(var(--zx-card-view-column-basis) - var(--zx-card-view-grid-gap)))), 1fr));
|