@ixfx/components 0.7.4 → 0.7.5
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/bundle/index.d.ts +536 -178
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +1324 -442
- package/bundle/index.js.map +1 -1
- package/dist/ac-token.js +1 -1
- package/dist/crumbs.d.ts +5 -1
- package/dist/crumbs.d.ts.map +1 -1
- package/dist/crumbs.js +10 -0
- package/dist/crumbs.js.map +1 -1
- package/dist/{data-grid-BddUjAti.d.ts → data-grid-CtJ35v8L.d.ts} +26 -1
- package/dist/data-grid-CtJ35v8L.d.ts.map +1 -0
- package/dist/data-grid.d.ts +1 -1
- package/dist/data-grid.js +88 -7
- package/dist/data-grid.js.map +1 -1
- package/dist/{detail-list-Br0WAnry.d.ts → detail-list-BS5dRDda.d.ts} +20 -12
- package/dist/detail-list-BS5dRDda.d.ts.map +1 -0
- package/dist/detail-list.d.ts +2 -2
- package/dist/detail-list.js +51 -135
- package/dist/detail-list.js.map +1 -1
- package/dist/{grid-list-B_orPsot.d.ts → grid-list-D-GbghSH.d.ts} +18 -1
- package/dist/grid-list-D-GbghSH.d.ts.map +1 -0
- package/dist/grid-list.d.ts +1 -1
- package/dist/grid-list.js +76 -15
- package/dist/grid-list.js.map +1 -1
- package/dist/incr-search-DpbSJtgj.js +962 -0
- package/dist/incr-search-DpbSJtgj.js.map +1 -0
- package/dist/incr-search.d.ts +2 -2
- package/dist/incr-search.js +2 -3
- package/dist/index-CBS4z1v-.d.ts +365 -0
- package/dist/index-CBS4z1v-.d.ts.map +1 -0
- package/dist/index.d.ts +8 -8
- package/dist/index.js +4 -5
- package/dist/index.js.map +1 -1
- package/dist/{list-selection-controller-CUo-Hhcm.js → list-selection-controller-DTFI40li.js} +2 -76
- package/dist/list-selection-controller-DTFI40li.js.map +1 -0
- package/dist/miller.d.ts +81 -3
- package/dist/miller.d.ts.map +1 -1
- package/dist/miller.js +327 -68
- package/dist/miller.js.map +1 -1
- package/dist/narrowed-text.js +1 -2
- package/dist/narrowed-text.js.map +1 -1
- package/dist/{tree-B74zdI60.js → tree-DAii2A1g.js} +77 -15
- package/dist/tree-DAii2A1g.js.map +1 -0
- package/dist/{tree-component-BvV4muxx.d.ts → tree-component-F6qZ0Gdv.d.ts} +9 -1
- package/dist/{tree-component-BvV4muxx.d.ts.map → tree-component-F6qZ0Gdv.d.ts.map} +1 -1
- package/dist/tree.d.ts +22 -1
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +1 -1
- package/dist/{vertical-list-CQSEVeOT.d.ts → vertical-list-DwtCPy1b.d.ts} +17 -14
- package/dist/vertical-list-DwtCPy1b.d.ts.map +1 -0
- package/dist/vertical-list.d.ts +1 -1
- package/dist/vertical-list.js +59 -127
- package/dist/vertical-list.js.map +1 -1
- package/docs-user/data-grid.md +19 -0
- package/docs-user/detail-list.md +1 -1
- package/docs-user/grid-list.md +24 -0
- package/docs-user/incr-search.md +12 -2
- package/docs-user/index.json +2 -2
- package/docs-user/tree.md +22 -1
- package/docs-user/vertical-list.md +7 -1
- package/package.json +1 -1
- package/dist/data-grid-BddUjAti.d.ts.map +0 -1
- package/dist/detail-list-Br0WAnry.d.ts.map +0 -1
- package/dist/element-search-Y8SRfPGM.js +0 -185
- package/dist/element-search-Y8SRfPGM.js.map +0 -1
- package/dist/grid-list-B_orPsot.d.ts.map +0 -1
- package/dist/incr-search-vCzuao-2.js +0 -137
- package/dist/incr-search-vCzuao-2.js.map +0 -1
- package/dist/index-Cu5i8zZY.d.ts +0 -160
- package/dist/index-Cu5i8zZY.d.ts.map +0 -1
- package/dist/list-selection-controller-CUo-Hhcm.js.map +0 -1
- package/dist/tree-B74zdI60.js.map +0 -1
- package/dist/vertical-list-CQSEVeOT.d.ts.map +0 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { y as ListSearchController } from "./index-CBS4z1v-.js";
|
|
1
2
|
import { i as ListInteractionMode, l as ListSelectionMode } from "./list-selection-types-B5ioL-dG.js";
|
|
2
3
|
import { n as TickledController } from "./tickled-controller-Bn3YdQsM.js";
|
|
3
4
|
import { LitElement, PropertyValues, html } from "lit";
|
|
5
|
+
import { CommandRegistry } from "@clinth/ui-commands";
|
|
4
6
|
//#region src/grid-list/types.d.ts
|
|
5
7
|
/**
|
|
6
8
|
* How the caption relates to the cell's content.
|
|
@@ -240,12 +242,27 @@ declare class GridListElement extends LitElement {
|
|
|
240
242
|
*/
|
|
241
243
|
captionHeight: number;
|
|
242
244
|
itemWrap: `stop` | `wrap`;
|
|
245
|
+
/**
|
|
246
|
+
* Predicate used by incremental filter-search (and callable directly). Items
|
|
247
|
+
* for which it returns `false` are removed from layout and navigation.
|
|
248
|
+
*/
|
|
249
|
+
filterPredicate: ((el: Element) => boolean) | undefined;
|
|
250
|
+
/**
|
|
251
|
+
* Space-separated subset of `navigate select filter` — limits which
|
|
252
|
+
* incremental-search modes are offered (as commands and in-popover switches).
|
|
253
|
+
* Unset ⇒ all three; empty ⇒ search disabled. See `docs/infra-incremental.md`.
|
|
254
|
+
*/
|
|
255
|
+
searchModes: string | undefined;
|
|
243
256
|
private _scrollTop;
|
|
244
257
|
private _scrollLeft;
|
|
245
258
|
private _viewportHeight;
|
|
246
259
|
private _viewportWidth;
|
|
247
260
|
readonly selection: ListSelectionController<Element>;
|
|
248
261
|
readonly tickled: TickledController<Element>;
|
|
262
|
+
/** Incremental search (navigate / select / filter). See `docs/infra-incremental.md`. */
|
|
263
|
+
readonly search: ListSearchController<Element>;
|
|
264
|
+
/** Command registry carrying this grid's `list.search.*` commands. */
|
|
265
|
+
get registry(): CommandRegistry<unknown> | undefined;
|
|
249
266
|
connectedCallback(): void;
|
|
250
267
|
disconnectedCallback(): void;
|
|
251
268
|
protected firstUpdated(): void;
|
|
@@ -301,4 +318,4 @@ interface GridListElement {
|
|
|
301
318
|
}
|
|
302
319
|
//#endregion
|
|
303
320
|
export { GridListViewportChangeEvent as C, GridListViewportChangeDetail as S, GridListOrientation as _, ListSelectionModes as a, GridListTickleDetail as b, GridListActivateEvent as c, GridListCaptionPosition as d, GridListCaptionStyle as f, GridListItemClickEvent as g, GridListItemClickDetail as h, ListSelectionGesture as i, GridListCaptionAlign as l, GridListFullElementEventMap as m, ListSelectionController as n, isMultiMode as o, GridListElementEventMap as p, ListSelectionControllerConfig as r, GridListActivateDetail as s, GridListElement as t, GridListCaptionBackdrop as u, GridListSelectDetail as v, GridListTickleEvent as x, GridListSelectEvent as y };
|
|
304
|
-
//# sourceMappingURL=grid-list-
|
|
321
|
+
//# sourceMappingURL=grid-list-D-GbghSH.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grid-list-D-GbghSH.d.ts","names":[],"sources":["../src/grid-list/types.ts","../src/interaction/list-selection-controller.ts","../src/grid-list/grid-list.ts"],"mappings":";;;;;;;;;;;;;;;;;KA8BY;;KAGA;;KAGA;;;;;;;;KASA;;;;;;;;KASA;UAEK;WACN,UAAU,YAAY;WACtB,UAAU,YAAY;;WAEtB,cAAc;;KAGb,sBAAsB,YAAY;UAE7B;WACN,MAAM;;KAGL,wBAAwB,YAAY;UAE/B;WACN,MAAM;;KAGL,yBAAyB,YAAY;UAEhC;WACN,MAAM;;KAGL,sBAAsB,YAAY;UAE7B;EACf,eAAe;EACf,iBAAiB;EACjB,mBAAmB;EACnB,eAAe;;KAGL;WACD;;KAGC,8BAA8B,YAAY;UAErC,oCAAoC;EACnD,6BAA6B;;;;;KC9FnB;WACD;WACA;WACA;;KAGC;WACD,eAAe;WACf,iBAAiB;;;;;;;;KAShB,8BAA8B;;WAE/B,gCAAgC;;WAEhC,eAAe,MAAM;;WAErB,gBAAgB;;;;;;WAMhB,WAAW,UAAU,YAAY,IAAI,UAAU,YAAY;;;;;WAK3D,UAAU,MAAM;;;iBAIX,YAAY,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;cA4BrB,wBAAwB;;EAKvB,YAAA,QAAQ,8BAA8B;;MAK9C,YAAY,YAAY;;;;;;MASxB,gBAAgB;;MAehB,UAAU;;EAKd;;EAKA;;EAQA,QAAQ,MAAM;;EAUd,OAAO,MAAM;;EAoBb,QAAQ,MAAM;;EAoBd;;EAOA;;;;;EAcA,WAAW,OAAO,SAAS;;EAa3B,SAAS,MAAM;;;;;;;EA6Bf,WAAW,MAAM,kBAAkB,UAAU,gBAAgB;;;;;EAsB7D,QAAQ,MAAM,kBAAkB,UAAU,gBAAgB;;;;;EAqB1D,WAAW,MAAM,kBAAkB,UAAU,gBAAgB;;EAmB7D,YAAY,MAAM,GAAG,SAAS;;EAyC9B,YAAY,MAAM;;EAgBlB;;;;;;EASA,MAAM,KAAK,MAAM,MAAM;;;;;EAUvB;;;;;;EAUA,KAAK,OAAO,SAAS,IAAI,SAAS;;;;cCvNvB,wBAAwB;;SACnB,sBAAM;EAuQtB,eAAe;EAGf,iBAAiB;EAGjB;EAGA;;;;;;;EASA,aAAa;;;;;;;;EAUb,cAAc;;EAId,cAAc;;EAId,iBAAiB;;EAIjB,iBAAiB;;;;;EAOjB;EAGA;;;;;EAOA,mBAAmB,IAAI;;;;;;EAQvB;UAEiB;UACA;UACA;UACA;WAgCR,WAAS,wBAAA;WAkBT,SAAO,kBAAA;;WAgBP,QAAM,qBAAA;;MAiBX,YAAY;EAqBP;EAwBA;YAiFU;YAiBA,WAAW,SAAS;YAuEpB,QAAQ,SAAS;UAmF5B;MAQJ;;;;;;MASA;MAIA,iBAAiB,YAAY;;MAK7B,gBAAgB;EAIpB,OAAO,MAAM;EAIb,WAAW,OAAO,SAAS;EAI3B,SAAS,MAAM;EAIf;EAIA;;;;;;EAWA,WAAW,MAAM;;EAKjB,gBAAgB,MAAM;;EAKtB,mBAAmB,MAAM;;EAKzB,SAAS;;MASL;EAKJ,QAAQ,cAAc;EAItB,eAAe,gBAAgB;EAI/B,OAAO,MAAM;EAIb;UA+CQ;UAQA;YAUW,UAAU,kBAAkB;UA+GvC;;QA6FF;YACI;IACR,kBAAkB;;;UAIL;EACf,iBAAiB,gBAAgB,6BAC/B,MAAM,GACN,WAAW,MAAM,iBAAiB,IAAI,4BAA4B,aAClE,oBAAoB;EAEtB,iBACE,cACA,UAAU,oCACV,oBAAoB"}
|
package/dist/grid-list.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { i as ListInteractionMode, l as ListSelectionMode } from "./list-selection-types-B5ioL-dG.js";
|
|
2
|
-
import { C as GridListViewportChangeEvent, S as GridListViewportChangeDetail, _ as GridListOrientation, b as GridListTickleDetail, c as GridListActivateEvent, d as GridListCaptionPosition, f as GridListCaptionStyle, g as GridListItemClickEvent, h as GridListItemClickDetail, l as GridListCaptionAlign, m as GridListFullElementEventMap, p as GridListElementEventMap, s as GridListActivateDetail, t as GridListElement, u as GridListCaptionBackdrop, v as GridListSelectDetail, x as GridListTickleEvent, y as GridListSelectEvent } from "./grid-list-
|
|
2
|
+
import { C as GridListViewportChangeEvent, S as GridListViewportChangeDetail, _ as GridListOrientation, b as GridListTickleDetail, c as GridListActivateEvent, d as GridListCaptionPosition, f as GridListCaptionStyle, g as GridListItemClickEvent, h as GridListItemClickDetail, l as GridListCaptionAlign, m as GridListFullElementEventMap, p as GridListElementEventMap, s as GridListActivateDetail, t as GridListElement, u as GridListCaptionBackdrop, v as GridListSelectDetail, x as GridListTickleEvent, y as GridListSelectEvent } from "./grid-list-D-GbghSH.js";
|
|
3
3
|
export { type GridListActivateDetail, type GridListActivateEvent, type GridListCaptionAlign, type GridListCaptionBackdrop, type GridListCaptionPosition, type GridListCaptionStyle, GridListElement, type GridListElementEventMap, type GridListFullElementEventMap, type GridListItemClickDetail, type GridListItemClickEvent, type GridListOrientation, type GridListSelectDetail, type GridListSelectEvent, type GridListTickleDetail, type GridListTickleEvent, type GridListViewportChangeDetail, type GridListViewportChangeEvent, type ListInteractionMode, type ListSelectionMode };
|
package/dist/grid-list.js
CHANGED
|
@@ -2,12 +2,14 @@ import { t as TickledController } from "./tickled-controller-C66DgJHl.js";
|
|
|
2
2
|
import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
|
|
3
3
|
import { t as themeFallbacks } from "./fallbacks-DNI9xt0F.js";
|
|
4
4
|
import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
|
|
5
|
-
import { i as
|
|
5
|
+
import { c as createElementListSearchAdapter, i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, u as keyForElement } from "./incr-search-DpbSJtgj.js";
|
|
6
6
|
import { i as listItemFadeKeyframes } from "./list-item-animation-DuiwgN3l.js";
|
|
7
|
+
import { t as ListSelectionController } from "./list-selection-controller-DTFI40li.js";
|
|
7
8
|
import "./interaction-Cr13azbM.js";
|
|
8
9
|
import { t as scrollFadeStyles } from "./scroll-fade-CAs1EabA.js";
|
|
9
10
|
import { LitElement, css, html } from "lit";
|
|
10
11
|
import { property, state } from "lit/decorators.js";
|
|
12
|
+
import { createCommandRegistry } from "@clinth/ui-commands";
|
|
11
13
|
import { repeat } from "lit/directives/repeat.js";
|
|
12
14
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
13
15
|
//#region src/grid-list/grid-list.ts
|
|
@@ -145,6 +147,11 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
145
147
|
onStateChange: () => this._syncItemStates(),
|
|
146
148
|
itemWrap: this.#itemWrap
|
|
147
149
|
});
|
|
150
|
+
this.search = new ListSearchController(this, { adapter: createElementListSearchAdapter(this, {
|
|
151
|
+
itemSelector: ITEM_SELECTOR,
|
|
152
|
+
getLabel: (el) => el.getAttribute(`data-label`) ?? el.querySelector(`[data-grid-list-caption]`)?.textContent?.trim() ?? el.getAttribute(`data-search-label`) ?? el.textContent?.trim() ?? ``,
|
|
153
|
+
highlightKey: `grid-list-search`
|
|
154
|
+
}) });
|
|
148
155
|
this.#onScroll = (e) => {
|
|
149
156
|
const el = e.target;
|
|
150
157
|
this.#cancelScrollRaf();
|
|
@@ -171,7 +178,10 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
171
178
|
const from = this.tickled.tickledId ? this.#items.indexOf(this.tickled.tickledId) : -1;
|
|
172
179
|
const nextIndex = Math.max(0, Math.min(count - 1, from + delta));
|
|
173
180
|
const next = this.#items[nextIndex];
|
|
174
|
-
if (next)
|
|
181
|
+
if (next) {
|
|
182
|
+
this.tickled.handleKeyboardNavigation(next);
|
|
183
|
+
this.#scrollItemIntoView(next);
|
|
184
|
+
}
|
|
175
185
|
};
|
|
176
186
|
const perLine = this.orientation === `grid` ? win.cols : 1;
|
|
177
187
|
switch (e.key) {
|
|
@@ -189,9 +199,11 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
189
199
|
break;
|
|
190
200
|
case `Home`:
|
|
191
201
|
this.tickled.handleKeyboardNavigation(`first`);
|
|
202
|
+
if (this.tickled.tickledId) this.#scrollItemIntoView(this.tickled.tickledId);
|
|
192
203
|
break;
|
|
193
204
|
case `End`:
|
|
194
205
|
this.tickled.handleKeyboardNavigation(`last`);
|
|
206
|
+
if (this.tickled.tickledId) this.#scrollItemIntoView(this.tickled.tickledId);
|
|
195
207
|
break;
|
|
196
208
|
case `PageUp`:
|
|
197
209
|
case `PageDown`: {
|
|
@@ -234,11 +246,13 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
234
246
|
scrollFadeStyles(`x`),
|
|
235
247
|
scrollFadeStyles(`y`),
|
|
236
248
|
listItemFadeKeyframes,
|
|
249
|
+
listSearchStyles,
|
|
237
250
|
css`
|
|
238
251
|
:host {
|
|
239
252
|
--grid-list-item-bg: var(--item-bg);
|
|
240
253
|
--grid-list-radius: var(--radius-m);
|
|
241
254
|
--grid-list-gap: var(--space-xs);
|
|
255
|
+
position: relative;
|
|
242
256
|
display: block;
|
|
243
257
|
height: 100%;
|
|
244
258
|
min-height: 2em;
|
|
@@ -351,16 +365,19 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
351
365
|
overflow: hidden;
|
|
352
366
|
transition: background var(--transition), border-color var(--transition);
|
|
353
367
|
}
|
|
354
|
-
:host(:not([caption-style="separate"])) .cell:hover
|
|
368
|
+
:host(:not([caption-style="separate"])) .cell:hover,
|
|
369
|
+
:host(:not([caption-style="separate"])) .cell.tickled {
|
|
355
370
|
background: var(--item-bg-tickled);
|
|
356
|
-
border
|
|
371
|
+
border: var(--item-border-tickled);
|
|
357
372
|
}
|
|
358
373
|
:host(:not([caption-style="separate"])) .cell.selected {
|
|
359
374
|
outline: 2px solid var(--accent);
|
|
360
375
|
outline-offset: -2px;
|
|
361
376
|
}
|
|
362
|
-
:host(:not([caption-style="separate"])) .cell.tickled {
|
|
363
|
-
|
|
377
|
+
:host(:not([caption-style="separate"])) .cell.selected.tickled {
|
|
378
|
+
background: var(--item-bg-selected-tickled);
|
|
379
|
+
outline: 2px dashed var(--surface-3);
|
|
380
|
+
outline-offset: -2px;
|
|
364
381
|
}
|
|
365
382
|
|
|
366
383
|
/* under: caption is a strip inside the box, below the content */
|
|
@@ -419,9 +436,10 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
419
436
|
background: var(--grid-list-item-bg);
|
|
420
437
|
border: 1px solid transparent;
|
|
421
438
|
}
|
|
422
|
-
:host([caption-style="separate"]) .cell:hover .thumb
|
|
439
|
+
:host([caption-style="separate"]) .cell:hover .thumb,
|
|
440
|
+
:host([caption-style="separate"]) .cell.tickled .thumb {
|
|
423
441
|
background: var(--item-bg-tickled);
|
|
424
|
-
border
|
|
442
|
+
border: var(--item-border-tickled);
|
|
425
443
|
}
|
|
426
444
|
:host([caption-style="separate"]) .caption {
|
|
427
445
|
display: flex;
|
|
@@ -433,20 +451,27 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
433
451
|
}
|
|
434
452
|
:host([caption-style="separate"][caption-align="left"]) .caption { align-self: flex-start; }
|
|
435
453
|
:host([caption-style="separate"][caption-align="right"]) .caption { align-self: flex-end; }
|
|
436
|
-
:host([caption-style="separate"]) .cell.selected .thumb
|
|
437
|
-
:host([caption-style="separate"]) .cell.tickled .thumb {
|
|
454
|
+
:host([caption-style="separate"]) .cell.selected .thumb {
|
|
438
455
|
outline: 2px solid var(--accent);
|
|
439
456
|
outline-offset: 2px;
|
|
440
457
|
}
|
|
441
|
-
:host([caption-style="separate"]) .cell.tickled .thumb {
|
|
442
|
-
|
|
458
|
+
:host([caption-style="separate"]) .cell.selected.tickled .thumb {
|
|
459
|
+
background: var(--item-bg-selected-tickled);
|
|
460
|
+
outline: 2px dashed var(--surface-3);
|
|
461
|
+
outline-offset: 2px;
|
|
443
462
|
}
|
|
444
463
|
:host([caption-style="separate"]) .cell.selected .caption {
|
|
445
464
|
background: var(--accent);
|
|
446
465
|
color: var(--accent-text, #000);
|
|
447
466
|
}
|
|
448
467
|
:host([caption-style="separate"]) .cell.tickled .caption {
|
|
449
|
-
|
|
468
|
+
background: var(--item-bg-tickled);
|
|
469
|
+
outline: var(--item-border-tickled);
|
|
470
|
+
}
|
|
471
|
+
:host([caption-style="separate"]) .cell.selected.tickled .caption {
|
|
472
|
+
background: var(--item-bg-selected-tickled);
|
|
473
|
+
outline: 2px dashed var(--surface-3);
|
|
474
|
+
outline-offset: -2px;
|
|
450
475
|
}
|
|
451
476
|
|
|
452
477
|
/* ---- Insertion / removal animation ----
|
|
@@ -499,6 +524,25 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
499
524
|
*/
|
|
500
525
|
#slotNames;
|
|
501
526
|
#slotSeq;
|
|
527
|
+
#searchRegistry;
|
|
528
|
+
#unregisterSearchCommands;
|
|
529
|
+
/** Command registry carrying this grid's `list.search.*` commands. */
|
|
530
|
+
get registry() {
|
|
531
|
+
return this.#searchRegistry;
|
|
532
|
+
}
|
|
533
|
+
/** Effective search modes: this component's capability (all three) ∩ the `search-modes` attribute. */
|
|
534
|
+
#effectiveSearchModes() {
|
|
535
|
+
const raw = this.searchModes?.trim();
|
|
536
|
+
if (raw === void 0) return [...LIST_SEARCH_MODES];
|
|
537
|
+
const requested = new Set(raw.split(/\s+/));
|
|
538
|
+
return LIST_SEARCH_MODES.filter((m) => requested.has(m));
|
|
539
|
+
}
|
|
540
|
+
#syncSearchCommands() {
|
|
541
|
+
if (!this.#searchRegistry) return;
|
|
542
|
+
this.search.setModes(this.#effectiveSearchModes());
|
|
543
|
+
this.#unregisterSearchCommands?.();
|
|
544
|
+
this.#unregisterSearchCommands = registerListSearchCommands(this.#searchRegistry, this.search);
|
|
545
|
+
}
|
|
502
546
|
connectedCallback() {
|
|
503
547
|
super.connectedCallback();
|
|
504
548
|
if (!this.hasAttribute(`tabindex`)) this.tabIndex = 0;
|
|
@@ -510,7 +554,12 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
510
554
|
]) if (!this.hasAttribute(attr)) this.setAttribute(attr, value);
|
|
511
555
|
this.addEventListener(`keydown`, this._onKeyDown);
|
|
512
556
|
this.#mutationObserver ??= new MutationObserver((records) => this.#onChildrenChanged(records));
|
|
513
|
-
this.#mutationObserver.observe(this, {
|
|
557
|
+
this.#mutationObserver.observe(this, {
|
|
558
|
+
childList: true,
|
|
559
|
+
attributeFilter: [`hidden`]
|
|
560
|
+
});
|
|
561
|
+
this.#searchRegistry ??= createCommandRegistry();
|
|
562
|
+
this.#syncSearchCommands();
|
|
514
563
|
}
|
|
515
564
|
disconnectedCallback() {
|
|
516
565
|
super.disconnectedCallback();
|
|
@@ -519,6 +568,9 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
519
568
|
this.#resizeObserver = void 0;
|
|
520
569
|
this.#mutationObserver?.disconnect();
|
|
521
570
|
this.#cancelScrollRaf();
|
|
571
|
+
this.#unregisterSearchCommands?.();
|
|
572
|
+
this.#unregisterSearchCommands = void 0;
|
|
573
|
+
this.#searchRegistry = void 0;
|
|
522
574
|
if (this.#reflowTimer) {
|
|
523
575
|
clearTimeout(this.#reflowTimer);
|
|
524
576
|
this.#reflowTimer = 0;
|
|
@@ -586,6 +638,8 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
586
638
|
this.requestUpdate();
|
|
587
639
|
}
|
|
588
640
|
willUpdate(changed) {
|
|
641
|
+
if (changed.has(`searchModes`)) this.#syncSearchCommands();
|
|
642
|
+
if (changed.has(`filterPredicate`)) this.#syncItems();
|
|
589
643
|
if (changed.has(`itemSize`) || changed.has(`gap`)) {
|
|
590
644
|
this.itemSize = Math.max(MIN_ITEM_SIZE, Math.round(this.itemSize));
|
|
591
645
|
this.gap = Math.max(0, Math.round(this.gap));
|
|
@@ -670,7 +724,7 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
670
724
|
}
|
|
671
725
|
}
|
|
672
726
|
#syncItems() {
|
|
673
|
-
this.#items = Array.from(this.querySelectorAll(ITEM_SELECTOR));
|
|
727
|
+
this.#items = Array.from(this.querySelectorAll(ITEM_SELECTOR)).filter((el) => !el.hidden && (this.filterPredicate === void 0 || this.filterPredicate(el)));
|
|
674
728
|
for (const el of this.#items) {
|
|
675
729
|
const name = this.#slotNameFor(el);
|
|
676
730
|
if (el.getAttribute(`slot`) !== name) el.setAttribute(`slot`, name);
|
|
@@ -826,6 +880,7 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
826
880
|
${repeat(slice, (el) => this.#slotNameFor(el), (el, i) => this.#renderCell(el, win.startIndex + i, win))}
|
|
827
881
|
</div>
|
|
828
882
|
</div>
|
|
883
|
+
${this.search.renderField()}
|
|
829
884
|
`;
|
|
830
885
|
}
|
|
831
886
|
#renderCell(el, index, win) {
|
|
@@ -922,6 +977,12 @@ __decorate([property({
|
|
|
922
977
|
type: String,
|
|
923
978
|
attribute: `item-wrap`
|
|
924
979
|
})], GridListElement.prototype, "itemWrap", void 0);
|
|
980
|
+
__decorate([property({ attribute: false })], GridListElement.prototype, "filterPredicate", void 0);
|
|
981
|
+
__decorate([property({
|
|
982
|
+
type: String,
|
|
983
|
+
attribute: `search-modes`,
|
|
984
|
+
reflect: true
|
|
985
|
+
})], GridListElement.prototype, "searchModes", void 0);
|
|
925
986
|
__decorate([state()], GridListElement.prototype, "_scrollTop", void 0);
|
|
926
987
|
__decorate([state()], GridListElement.prototype, "_scrollLeft", void 0);
|
|
927
988
|
__decorate([state()], GridListElement.prototype, "_viewportHeight", void 0);
|
package/dist/grid-list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-list.js","names":["#items","#itemWrap","#cancelScrollRaf","#scrollRaf","#emitViewportChange","#currentWindow","#onCellActivate","#mutationObserver","#onChildrenChanged","#resizeObserver","#reflowTimer","#syncItems","#noteChildMutation","#entering","#viewportRef","#zoomAnchor","#applyZoomAnchor","#slotNameFor","#slotNames","#slotSeq","#scrollItemIntoView","#rowHeight","#onScroll","#renderCell","#captionFor","#onCellClick","customElement"],"sources":["../src/grid-list/grid-list.ts"],"sourcesContent":["/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues } from 'lit';\nimport type { ListInteractionMode, ListSelectionMode } from '../interaction/list-selection-types.js';\nimport type {\n GridListActivateDetail,\n GridListCaptionAlign,\n GridListCaptionBackdrop,\n GridListCaptionPosition,\n GridListCaptionStyle,\n GridListFullElementEventMap,\n GridListItemClickDetail,\n GridListOrientation,\n GridListSelectDetail,\n GridListTickleDetail,\n GridListViewportChangeDetail,\n} from './types.js';\nimport { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { createRef, ref } from 'lit/directives/ref.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { listItemFadeKeyframes, tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { keyForElement } from '../interaction/keyed-list.js';\nimport { ListSelectionController } from '../interaction/list-selection-controller.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { scrollFadeStyles } from '../styles/scroll-fade.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type {\n GridListActivateDetail,\n GridListActivateEvent,\n GridListCaptionAlign,\n GridListCaptionBackdrop,\n GridListCaptionPosition,\n GridListCaptionStyle,\n GridListElementEventMap,\n GridListFullElementEventMap,\n GridListItemClickDetail,\n GridListItemClickEvent,\n GridListOrientation,\n GridListSelectDetail,\n GridListSelectEvent,\n GridListTickleDetail,\n GridListTickleEvent,\n GridListViewportChangeDetail,\n GridListViewportChangeEvent,\n ListInteractionMode,\n ListSelectionMode,\n} from './types.js';\n\ntype GridWindow = {\n readonly cols: number;\n readonly rows: number;\n /** Spacer height in px (vertical orientations); 0 when CSS controls it. */\n readonly totalHeight: number;\n /** Spacer width in px (`row` orientation); 0 when CSS controls it. */\n readonly totalWidth: number;\n readonly startIndex: number;\n readonly endIndex: number;\n /** Distance between the left edges of adjacent columns (item width + gap). */\n readonly colStride: number;\n /** Distance between the top edges of adjacent rows (row height + gap). */\n readonly rowStride: number;\n /** `true` for `row` orientation — the list scrolls along the x axis. */\n readonly horizontal: boolean;\n};\n\nconst ITEM_SELECTOR = `:scope > *`;\n\nconst MIN_ITEM_SIZE = 16;\n\n/**\n * How long the host keeps the `[reflowing]` attribute after items are inserted\n * mid-list — long enough for the cell move-transition and the enter animation\n * to finish. Kept a touch above the default `--grid-list-item-move-duration`.\n */\nconst REFLOW_WINDOW_MS = 320;\n\n// `itemWidth` is the square's width; `rowHeight` is the full cell height\n// (square, plus the caption band in `labelled` style). `scrollOffset` is\n// `scrollTop` for `grid`/`column` and `scrollLeft` for `row`.\nfunction computeGridWindow(\n count: number,\n itemWidth: number,\n rowHeight: number,\n gap: number,\n viewportWidth: number,\n viewportHeight: number,\n scrollOffset: number,\n orientation: GridListOrientation,\n overscan = 2,\n): GridWindow {\n const w = Math.max(1, itemWidth);\n const h = Math.max(1, rowHeight);\n const g = Math.max(0, gap);\n const colStride = w + g;\n const rowStride = h + g;\n const offset = Math.max(0, scrollOffset);\n\n if (orientation === `row`) {\n const rows = count === 0 ? 0 : 1;\n const totalWidth = count === 0 ? 0 : (count - 1) * colStride + w;\n if (count === 0 || viewportWidth <= 0) {\n return { cols: count, rows, totalHeight: 0, totalWidth, startIndex: 0, endIndex: 0, colStride, rowStride, horizontal: true };\n }\n const firstVisible = Math.max(0, Math.floor(offset / colStride));\n const lastVisible = Math.ceil((offset + viewportWidth) / colStride);\n return {\n cols: count,\n rows,\n totalHeight: 0,\n totalWidth,\n startIndex: Math.max(0, firstVisible - overscan),\n endIndex: Math.min(count, lastVisible + overscan),\n colStride,\n rowStride,\n horizontal: true,\n };\n }\n\n const cols = orientation === `column`\n ? 1\n : Math.max(1, Math.floor((Math.max(0, viewportWidth) + g) / colStride));\n const rows = count === 0 ? 0 : Math.ceil(count / cols);\n const totalHeight = rows === 0 ? 0 : (rows - 1) * rowStride + h;\n\n if (count === 0 || viewportHeight <= 0) {\n return { cols, rows, totalHeight, totalWidth: 0, startIndex: 0, endIndex: 0, colStride, rowStride, horizontal: false };\n }\n\n const firstVisibleRow = Math.max(0, Math.floor(offset / rowStride));\n const lastVisibleRow = Math.ceil((offset + viewportHeight) / rowStride);\n const rowStart = Math.max(0, firstVisibleRow - overscan);\n const rowEnd = Math.min(rows, lastVisibleRow + overscan);\n\n return {\n cols,\n rows,\n totalHeight,\n totalWidth: 0,\n startIndex: rowStart * cols,\n endIndex: Math.min(count, rowEnd * cols),\n colStride,\n rowStride,\n horizontal: false,\n };\n}\n\nfunction columnOf(index: number, cols: number): number {\n return cols <= 1 ? 0 : index % cols;\n}\n\nfunction rowOf(index: number, cols: number): number {\n return cols <= 1 ? index : Math.floor(index / cols);\n}\n\n@customElement(`ixfx-grid-list`)\nexport class GridListElement extends LitElement {\n static override styles = [\n themeFallbacks,\n tickledStyles,\n tickledItemStyles,\n // Both axes are registered; `render()` applies whichever one matches the\n // current orientation to the viewport (see the `scroll-fade-*` class there).\n scrollFadeStyles(`x`),\n scrollFadeStyles(`y`),\n listItemFadeKeyframes,\n css`\n :host {\n --grid-list-item-bg: var(--item-bg);\n --grid-list-radius: var(--radius-m);\n --grid-list-gap: var(--space-xs);\n display: block;\n height: 100%;\n min-height: 2em;\n overflow: hidden;\n user-select: none;\n background: var(--surface-3);\n color: var(--surface-3-text);\n border-radius: var(--radius-s);\n border: 1px solid var(--border);\n }\n :host(:focus-visible) {\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n }\n .viewport {\n position: relative;\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n }\n :host([orientation=\"row\"]) .viewport {\n overflow-x: auto;\n overflow-y: hidden;\n }\n .spacer {\n position: relative;\n width: 100%;\n }\n .cell {\n position: absolute;\n inset: 0 auto auto 0;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n contain: layout style;\n border-radius: var(--grid-list-radius);\n }\n\n /* The square that holds the slotted content. */\n .thumb {\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n align-items: stretch;\n box-sizing: border-box;\n overflow: hidden;\n border-radius: 0;\n background: transparent;\n border: 1px solid transparent;\n transition: background var(--transition), border-color var(--transition);\n }\n .thumb ::slotted(*) {\n flex: 1;\n min-width: 0;\n min-height: 0;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n }\n .thumb ::slotted(*:empty)::after {\n content: \"Empty\";\n color: var(--surface-muted-text);\n font-size: var(--text-s);\n }\n ::slotted([hidden]) {\n display: none !important;\n }\n\n /* Selection / cursor wash — sits over the slotted content so it reads\n on photos and arbitrary DOM alike. */\n .thumb::after {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n border-radius: inherit;\n background: var(--accent);\n opacity: 0;\n transition: opacity var(--transition, 0.1s ease-out);\n }\n .cell.selected .thumb::after {\n opacity: 0.18;\n }\n\n /* ---- Caption (base) ---- */\n .caption {\n box-sizing: border-box;\n flex: none;\n padding: 3px 6px;\n font-size: var(--text-s, 0.8rem);\n line-height: 1.3;\n text-align: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--surface-3-text);\n }\n :host([caption-align=\"left\"]) .caption { text-align: left; }\n :host([caption-align=\"right\"]) .caption { text-align: right; }\n\n /* ---- Box modes (hidden / under / overlaid): the cell is one box with a\n single selection outline ---- */\n :host(:not([caption-style=\"separate\"])) .cell {\n background: var(--grid-list-item-bg);\n border: 1px solid transparent;\n overflow: hidden;\n transition: background var(--transition), border-color var(--transition);\n }\n :host(:not([caption-style=\"separate\"])) .cell:hover {\n background: var(--item-bg-tickled);\n border-color: var(--item-border-tickled);\n }\n :host(:not([caption-style=\"separate\"])) .cell.selected {\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n }\n :host(:not([caption-style=\"separate\"])) .cell.tickled {\n box-shadow: inset 0 0 0 2px var(--accent);\n }\n\n /* under: caption is a strip inside the box, below the content */\n :host([caption-style=\"under\"]) .caption {\n border-top: 1px solid var(--border, rgba(128, 128, 128, 0.3));\n background: var(--surface-4, transparent);\n }\n\n /* overlaid: caption floats over the content */\n :host([caption-style=\"overlaid\"]) .caption {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n color: #fff;\n }\n :host([caption-style=\"overlaid\"][caption-position=\"top\"]) .caption {\n top: 0;\n bottom: auto;\n }\n :host([caption-style=\"overlaid\"][caption-position=\"middle\"]) .caption {\n top: 50%;\n bottom: auto;\n transform: translateY(-50%);\n }\n /* overlaid backdrop */\n :host([caption-style=\"overlaid\"][caption-backdrop=\"scrim\"]) .caption {\n background: rgba(0, 0, 0, 0.55);\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"gradient\"]) .caption {\n background: linear-gradient(to top, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));\n padding-block: 10px 4px;\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"gradient\"][caption-position=\"top\"]) .caption {\n background: linear-gradient(to bottom, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));\n padding-block: 4px 10px;\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"gradient\"][caption-position=\"middle\"]) .caption {\n background: rgba(0, 0, 0, 0.5);\n padding-block: 3px;\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"blur\"]) .caption {\n background: rgba(20, 20, 20, 0.3);\n backdrop-filter: blur(6px);\n -webkit-backdrop-filter: blur(6px);\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"none\"]) .caption {\n background: none;\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.95), 0 0 6px rgba(0, 0, 0, 0.7);\n }\n\n /* ---- separate mode: square + detached caption, each highlighted ---- */\n :host([caption-style=\"separate\"]) .thumb {\n flex: none;\n border-radius: var(--grid-list-radius);\n background: var(--grid-list-item-bg);\n border: 1px solid transparent;\n }\n :host([caption-style=\"separate\"]) .cell:hover .thumb {\n background: var(--item-bg-tickled);\n border-color: var(--item-border-tickled);\n }\n :host([caption-style=\"separate\"]) .caption {\n display: flex;\n align-items: center;\n align-self: center;\n max-width: 100%;\n margin-top: 4px;\n border-radius: var(--radius-s, 4px);\n }\n :host([caption-style=\"separate\"][caption-align=\"left\"]) .caption { align-self: flex-start; }\n :host([caption-style=\"separate\"][caption-align=\"right\"]) .caption { align-self: flex-end; }\n :host([caption-style=\"separate\"]) .cell.selected .thumb,\n :host([caption-style=\"separate\"]) .cell.tickled .thumb {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n :host([caption-style=\"separate\"]) .cell.tickled .thumb {\n outline-style: dashed;\n }\n :host([caption-style=\"separate\"]) .cell.selected .caption {\n background: var(--accent);\n color: var(--accent-text, #000);\n }\n :host([caption-style=\"separate\"]) .cell.tickled .caption {\n outline: 1px dashed var(--accent);\n }\n\n /* ---- Insertion / removal animation ----\n Active only while the host carries [reflowing] — the ~0.3s window after\n the child list changes mid-list (see #noteChildMutation). Kept out of\n the base rules so it never fires during scroll virtualisation, where\n cells are recycled to wildly different positions every frame. Placed\n last so it wins over the earlier cell transition rule regardless of\n specificity. Survivors slide to their new slot; a freshly inserted cell\n also fades in. (A removed item's element is already gone, so there's\n nothing left to fade — the gap simply closes as the others slide.) */\n :host([reflowing]) .cell {\n transition:\n transform var(--grid-list-item-move-duration, 200ms) cubic-bezier(0.2, 0, 0, 1),\n background var(--transition),\n border-color var(--transition);\n }\n .cell.entering {\n animation: ixfx-list-item-in var(--grid-list-item-move-duration, 200ms) ease both;\n }\n @media (prefers-reduced-motion: reduce) {\n :host([reflowing]) .cell { transition: background var(--transition), border-color var(--transition); }\n .cell.entering { animation: none; }\n }\n `,\n ];\n\n @property({ type: String, attribute: `selection-mode` })\n selectionMode: ListSelectionMode = `single`;\n\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: ListInteractionMode = `standard`;\n\n @property({ type: Number, attribute: `item-size` })\n itemSize = 160;\n\n @property({ type: Number })\n gap = 8;\n\n /**\n * Layout / scroll direction.\n * - `grid` (default): items wrap across as many columns as fit, scrolls vertically.\n * - `row`: a single row of items, scrolls horizontally.\n * - `column`: a single column of items, scrolls vertically.\n */\n @property({ type: String, reflect: true })\n orientation: GridListOrientation = `grid`;\n\n /**\n * How the caption relates to the content — see {@link GridListCaptionStyle}.\n * - `hidden`: no caption.\n * - `separate`: detached label below the square, each highlighted on its own.\n * - `under` (default): one box, content on top, caption strip below it inside.\n * - `overlaid`: caption floats over the content.\n */\n @property({ type: String, attribute: `caption-style`, reflect: true })\n captionStyle: GridListCaptionStyle = `under`;\n\n /** Horizontal alignment of the caption text: `left`, `middle` (default), `right`. */\n @property({ type: String, attribute: `caption-align`, reflect: true })\n captionAlign: GridListCaptionAlign = `middle`;\n\n /** `overlaid` only — vertical placement: `top`, `middle`, `bottom` (default). */\n @property({ type: String, attribute: `caption-position`, reflect: true })\n captionPosition: GridListCaptionPosition = `bottom`;\n\n /** `overlaid` only — backdrop behind the caption: `scrim` (default), `gradient`, `blur`, `none`. */\n @property({ type: String, attribute: `caption-backdrop`, reflect: true })\n captionBackdrop: GridListCaptionBackdrop = `scrim`;\n\n /**\n * Height reserved for the caption in `separate` / `under` styles, in pixels.\n * Ignored by `overlaid` and `hidden`.\n */\n @property({ type: Number, attribute: `caption-height` })\n captionHeight = 24;\n\n @property({ type: String, attribute: `item-wrap` })\n itemWrap: `stop` | `wrap` = `stop`;\n\n @state() private _scrollTop = 0;\n @state() private _scrollLeft = 0;\n @state() private _viewportHeight = 0;\n @state() private _viewportWidth = 0;\n\n #viewportRef = createRef<HTMLDivElement>();\n\n #resizeObserver?: ResizeObserver;\n #mutationObserver?: MutationObserver;\n #scrollRaf = 0;\n #items: Element[] = [];\n #itemWrap: `stop` | `wrap` = `stop`;\n\n /** Items added mid-list that are still playing their enter animation. */\n #entering = new Set<Element>();\n /** Timer that ends the `[reflowing]` window opened by a mid-list insertion. */\n #reflowTimer = 0;\n\n /**\n * When cell geometry changes (zoom), the item nearest the viewport centre is\n * captured here in `willUpdate` and the scroll position is corrected in\n * `updated` so that item stays put — rather than the grid anchoring to its\n * top-left corner.\n */\n #zoomAnchor?: { index: number; lineFrac: number };\n\n /**\n * Per-item slot name. Each cell renders its own named `<slot>` and the\n * matching light-DOM child carries `slot=\"<name>\"`, so a child is projected\n * into exactly one cell. (A single unnamed slot would collapse every child\n * into the first cell.)\n */\n #slotNames = new WeakMap<Element, string>();\n #slotSeq = 0;\n\n readonly selection = new ListSelectionController<Element>({\n getOrderedItems: () => this._getVisibleItems(),\n isSelectable: () => true,\n getModes: () => ({ selectionMode: this.selectionMode, interactionMode: this.interactionMode }),\n getKey: keyForElement,\n onChange: (selected, previous) => {\n this._syncItemStates();\n // ListSelectionController isn't a reactive controller, so nudge Lit to\n // re-render the cells with updated `selected` classes.\n this.requestUpdate();\n this._dispatch<GridListSelectDetail>(`list-select`, {\n selected,\n previous,\n selectedKeys: this.selection.selectedKeys,\n });\n },\n });\n\n readonly tickled = new TickledController<Element>(this, {\n getItems: () =>\n this.#items.map(el => ({\n id: el,\n enabled: !el.hasAttribute(`not-checked`),\n })),\n onTickle: (id) => {\n if (id !== undefined) {\n this._dispatch<GridListTickleDetail>(`list-tickle`, { item: id });\n }\n },\n onStateChange: () => this._syncItemStates(),\n itemWrap: this.#itemWrap,\n });\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute(`tabindex`)) {\n this.tabIndex = 0;\n }\n // Reflect caption defaults up-front so the `:host([caption-*])` style rules\n // apply even when the consumer never sets the attributes.\n for (const [attr, value] of [\n [`caption-style`, this.captionStyle],\n [`caption-align`, this.captionAlign],\n [`caption-position`, this.captionPosition],\n [`caption-backdrop`, this.captionBackdrop],\n ] as const) {\n if (!this.hasAttribute(attr)) {\n this.setAttribute(attr, value);\n }\n }\n this.addEventListener(`keydown`, this._onKeyDown as EventListener);\n this.#mutationObserver ??= new MutationObserver(records => this.#onChildrenChanged(records));\n this.#mutationObserver.observe(this, { childList: true });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`keydown`, this._onKeyDown as EventListener);\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n this.#mutationObserver?.disconnect();\n this.#cancelScrollRaf();\n if (this.#reflowTimer) {\n clearTimeout(this.#reflowTimer);\n this.#reflowTimer = 0;\n }\n }\n\n #onChildrenChanged(records?: MutationRecord[]): void {\n const previousLength = this.#items.length;\n this.#syncItems();\n this._syncItemStates();\n this.#noteChildMutation(previousLength, records);\n this.requestUpdate();\n void this.updateComplete.then(() => this.#emitViewportChange());\n }\n\n /**\n * When the child list changes mid-list — not a first populate or a wholesale\n * replace — mark any newcomers for an enter animation and open a short\n * `[reflowing]` window so the cells that shift slide to their new position\n * instead of snapping. Removals get the same window (the survivors slide to\n * close the gap). The window is bounded in time so the transform transition\n * never bleeds into scroll virtualisation.\n *\n * Reads the `MutationRecord`s directly rather than diffing `#items`, because a\n * `requestUpdate()` between the DOM change and this callback (e.g. a caller\n * that clears the selection before removing) lets `updated()` re-sync `#items`\n * first, which would hide the change from a naive diff.\n */\n #noteChildMutation(previousLength: number, records?: MutationRecord[]): void {\n if (!this.hasUpdated || !records || records.length === 0)\n return;\n const currentSet = new Set(this.#items);\n const added: Element[] = [];\n let removedCount = 0;\n for (const record of records) {\n for (const node of record.addedNodes) {\n if (node.nodeType === Node.ELEMENT_NODE && currentSet.has(node as Element))\n added.push(node as Element);\n }\n for (const node of record.removedNodes) {\n if (node.nodeType === Node.ELEMENT_NODE)\n removedCount++;\n }\n }\n // Nothing to animate, a first populate, or a wholesale replace (every\n // current item is new) — leave it alone.\n if (added.length === 0 && removedCount === 0)\n return;\n if (previousLength === 0 && removedCount === 0)\n return;\n if (added.length > 0 && added.length === this.#items.length)\n return;\n for (const el of added)\n this.#entering.add(el);\n this.toggleAttribute(`reflowing`, true);\n if (this.#reflowTimer)\n clearTimeout(this.#reflowTimer);\n this.#reflowTimer = window.setTimeout(() => {\n this.#reflowTimer = 0;\n this.#entering.clear();\n this.toggleAttribute(`reflowing`, false);\n this.requestUpdate();\n }, REFLOW_WINDOW_MS);\n }\n\n #emitViewportChange(): void {\n this._dispatch<GridListViewportChangeDetail>(`grid-list-viewport-change`, {\n visibleKeys: this.visibleKeys(),\n });\n }\n\n protected override firstUpdated(): void {\n const el = this.#viewportRef.value;\n if (!el)\n return;\n this._viewportWidth = el.clientWidth;\n this._viewportHeight = el.clientHeight;\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n this._viewportWidth = entry.contentRect.width;\n this._viewportHeight = entry.contentRect.height;\n }\n });\n this.#resizeObserver.observe(el);\n this.#syncItems();\n this.requestUpdate();\n }\n\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has(`itemSize`) || changed.has(`gap`)) {\n this.itemSize = Math.max(MIN_ITEM_SIZE, Math.round(this.itemSize));\n this.gap = Math.max(0, Math.round(this.gap));\n }\n if (changed.has(`captionHeight`)) {\n this.captionHeight = Math.max(0, Math.round(this.captionHeight));\n }\n if (changed.has(`itemWrap`)) {\n this.#itemWrap = this.itemWrap;\n }\n\n const geometryChanged = changed.has(`itemSize`) || changed.has(`gap`)\n || changed.has(`captionStyle`) || changed.has(`captionHeight`)\n || changed.has(`orientation`);\n if (geometryChanged && this.hasUpdated && this.#items.length > 0) {\n const prevOrientation = (changed.get(`orientation`) as GridListOrientation | undefined) ?? this.orientation;\n const horizontal = prevOrientation === `row`;\n const prevOffset = horizontal ? this._scrollLeft : this._scrollTop;\n const prevExtent = horizontal ? this._viewportWidth : this._viewportHeight;\n if (prevExtent > 0 && prevOffset > 1) {\n const prevItemSize = (changed.get(`itemSize`) as number | undefined) ?? this.itemSize;\n const prevGap = (changed.get(`gap`) as number | undefined) ?? this.gap;\n const prevCaptionStyle = (changed.get(`captionStyle`) as GridListCaptionStyle | undefined) ?? this.captionStyle;\n const prevCaptionHeight = (changed.get(`captionHeight`) as number | undefined) ?? this.captionHeight;\n const prevBand = prevCaptionStyle === `separate` || prevCaptionStyle === `under`;\n const prevRowHeight = prevItemSize + (prevBand ? prevCaptionHeight : 0);\n const prev = computeGridWindow(\n this.#items.length,\n prevItemSize,\n prevRowHeight,\n prevGap,\n this._viewportWidth,\n this._viewportHeight,\n prevOffset,\n prevOrientation,\n );\n const mainStride = horizontal ? prev.colStride : prev.rowStride;\n const centerLine = (prevOffset + prevExtent / 2) / mainStride;\n const lineFloor = Math.max(0, Math.floor(centerLine));\n const index = horizontal\n ? Math.min(this.#items.length - 1, lineFloor)\n : Math.min(\n this.#items.length - 1,\n lineFloor * prev.cols + Math.max(0, Math.floor((prev.cols - 1) / 2)),\n );\n this.#zoomAnchor = { index, lineFrac: centerLine - lineFloor };\n }\n }\n }\n\n /** Full cell height: the square, plus a caption band in `separate` / `under`. */\n #rowHeight(): number {\n const captionBand = this.captionStyle === `separate` || this.captionStyle === `under`;\n return this.itemSize + (captionBand ? this.captionHeight : 0);\n }\n\n #captionFor(el: Element): string {\n return (\n el.getAttribute(`data-label`)\n ?? el.querySelector(`[data-grid-list-caption]`)?.textContent?.trim()\n ?? ``\n );\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n super.updated(changed);\n this.#syncItems();\n if (changed.has(`selectionMode`) || changed.has(`interactionMode`)) {\n this.selection.clearAnchor();\n }\n if (changed.has(`orientation`)) {\n // Reset the axis that's no longer scrollable so a later switch back\n // doesn't inherit a stale offset.\n const vp = this.#viewportRef.value;\n if (vp) {\n if (this.orientation === `row`) {\n vp.scrollTop = 0;\n this._scrollTop = 0;\n } else {\n vp.scrollLeft = 0;\n this._scrollLeft = 0;\n }\n }\n }\n this.#applyZoomAnchor();\n }\n\n /** Re-anchor the scroll so the item captured in `willUpdate` stays centred. */\n #applyZoomAnchor(): void {\n if (!this.#zoomAnchor)\n return;\n const { index, lineFrac } = this.#zoomAnchor;\n this.#zoomAnchor = undefined;\n\n const vp = this.#viewportRef.value;\n if (!vp)\n return;\n const win = this.#currentWindow();\n\n if (win.horizontal) {\n if (this._viewportWidth <= 0)\n return;\n const targetCenter = (index + lineFrac) * win.colStride;\n const maxScroll = Math.max(0, win.totalWidth - this._viewportWidth);\n const next = Math.min(maxScroll, Math.max(0, targetCenter - this._viewportWidth / 2));\n if (Math.abs(vp.scrollLeft - next) > 0.5) {\n vp.scrollLeft = next;\n this._scrollLeft = next;\n }\n return;\n }\n\n if (this._viewportHeight <= 0)\n return;\n const line = win.cols > 0 ? Math.floor(index / win.cols) : 0;\n const targetCenter = (line + lineFrac) * win.rowStride;\n const maxScroll = Math.max(0, win.totalHeight - this._viewportHeight);\n const next = Math.min(maxScroll, Math.max(0, targetCenter - this._viewportHeight / 2));\n if (Math.abs(vp.scrollTop - next) > 0.5) {\n vp.scrollTop = next;\n this._scrollTop = next;\n }\n }\n\n #syncItems(): void {\n this.#items = Array.from(this.querySelectorAll(ITEM_SELECTOR));\n for (const el of this.#items) {\n const name = this.#slotNameFor(el);\n if (el.getAttribute(`slot`) !== name) {\n el.setAttribute(`slot`, name);\n }\n }\n }\n\n #slotNameFor(el: Element): string {\n let name = this.#slotNames.get(el);\n if (name === undefined) {\n this.#slotSeq += 1;\n name = `gl-item-${this.#slotSeq}`;\n this.#slotNames.set(el, name);\n }\n return name;\n }\n\n private _getVisibleItems(): Element[] {\n return this.#items.filter((el) => {\n if ((el as HTMLElement).hidden)\n return false;\n return true;\n });\n }\n\n get count(): number {\n return this.#items.length;\n }\n\n /**\n * Number of cells currently rendered in the shadow DOM. With virtualization\n * this is roughly the visible rows plus overscan, regardless of how large\n * `count` is — useful for demos/diagnostics.\n */\n get renderedCount(): number {\n return this.renderRoot.querySelectorAll(`.cell`).length;\n }\n\n get selectedItems(): ReadonlySet<Element> {\n return this.selection.selected;\n }\n\n /** The selection as stable `data-key` / `data-value` strings. */\n get selectedKeys(): ReadonlySet<string> {\n return this.selection.selectedKeys;\n }\n\n select(item: Element): void {\n this.selection.replace(item);\n }\n\n selectMany(items: Iterable<Element>): void {\n this.selection.selectMany(items);\n }\n\n deselect(item: Element): void {\n this.selection.deselect(item);\n }\n\n clearSelection(): void {\n this.selection.clear();\n }\n\n selectAll(): void {\n if (this.selection.canSelectAll()) {\n this.selection.selectAll();\n }\n }\n\n /**\n * Replace the selection with the items carrying these keys. Unknown keys are\n * ignored; survives the host rebuilding the item set. Requires each item to\n * have a `data-key` (or `data-value`).\n */\n selectKeys(keys: Iterable<string>): void {\n this.selection.selectKeys(keys, key => this.getItem(key));\n }\n\n /** Add items by key to the selection (multi-select modes only). */\n addSelectedKeys(keys: Iterable<string>): void {\n this.selection.addKeys(keys, key => this.getItem(key));\n }\n\n /** Remove items by key from the selection. */\n removeSelectedKeys(keys: Iterable<string>): void {\n this.selection.removeKeys(keys, key => this.getItem(key));\n }\n\n /** Move the cursor to the item with this key and scroll it into view. */\n focusKey(key: string): void {\n const el = this.getItem(key);\n if (!el)\n return;\n this.tickled.focus(el);\n this.#scrollItemIntoView(el);\n }\n\n /** The key of the item under the cursor, or `undefined`. */\n get tickledKey(): string | undefined {\n const id = this.tickled.tickledId;\n return id ? keyForElement(id) : undefined;\n }\n\n getItem(key: string): Element | undefined {\n return this.#items.find(el => keyForElement(el) === key);\n }\n\n getItemByIndex(index: number): Element | undefined {\n return this.#items[index];\n }\n\n getKey(item: Element): string | undefined {\n return keyForElement(item);\n }\n\n visibleKeys(): string[] {\n const win = this.#currentWindow();\n const slice = this.#items.slice(win.startIndex, win.endIndex);\n return slice\n .map(el => keyForElement(el))\n .filter((k): k is string => k !== undefined);\n }\n\n /** Adjust the scroll offset so `el` is fully within the viewport. */\n #scrollItemIntoView(el: Element): void {\n const index = this.#items.indexOf(el);\n const vp = this.#viewportRef.value;\n if (index < 0 || !vp)\n return;\n const win = this.#currentWindow();\n\n if (win.horizontal) {\n const left = index * win.colStride;\n const right = left + this.itemSize;\n const viewLeft = vp.scrollLeft;\n let next = viewLeft;\n if (left < viewLeft)\n next = left;\n else if (right > viewLeft + this._viewportWidth)\n next = right - this._viewportWidth;\n if (next !== viewLeft) {\n vp.scrollLeft = next;\n this._scrollLeft = next;\n }\n return;\n }\n\n const row = win.cols > 0 ? Math.floor(index / win.cols) : 0;\n const top = row * win.rowStride;\n const bottom = top + this.#rowHeight();\n const viewTop = vp.scrollTop;\n let next = viewTop;\n if (top < viewTop)\n next = top;\n else if (bottom > viewTop + this._viewportHeight)\n next = bottom - this._viewportHeight;\n if (next !== viewTop) {\n vp.scrollTop = next;\n this._scrollTop = next;\n }\n }\n\n private _syncItemStates(): void {\n for (const el of this.#items) {\n el.toggleAttribute(`data-tickled`, this.tickled.isTickled(el));\n el.toggleAttribute(`data-selected`, this.selection.selected.has(el));\n }\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n }\n\n private _dispatch<T>(name: string, detail: T): void {\n this.dispatchEvent(\n new CustomEvent<T>(name, {\n detail,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n protected override render(): ReturnType<typeof html> {\n const win = this.#currentWindow();\n const slice = this.#items.slice(win.startIndex, win.endIndex);\n const spacerStyle = win.horizontal\n ? `width:${win.totalWidth}px;height:100%`\n : `height:${win.totalHeight}px`;\n // Fade the edge that can still be scrolled towards (see ../styles/scroll-fade.ts).\n const scrollFade = win.horizontal ? `scroll-fade-x` : `scroll-fade-y`;\n return html`\n <div\n class=\"viewport ${scrollFade}\"\n part=\"viewport\"\n ${ref(this.#viewportRef)}\n data-input-mode=${this.tickled.inputMode}\n @scroll=${this.#onScroll}\n >\n <div class=\"spacer\" style=${spacerStyle}>\n ${repeat(\n slice,\n el => this.#slotNameFor(el),\n (el, i) => this.#renderCell(el, win.startIndex + i, win),\n )}\n </div>\n </div>\n `;\n }\n\n #renderCell(el: Element, index: number, win: GridWindow): ReturnType<typeof html> {\n const selected = this.selection.selected.has(el);\n const tickled = this.tickled.isTickled(el);\n const entering = this.#entering.has(el);\n const style = this.captionStyle;\n const separate = style === `separate`;\n const caption = style === `hidden` ? `` : this.#captionFor(el);\n const showCaption = caption !== ``;\n const cellHeight = win.rowStride - this.gap;\n const x = win.horizontal ? index * win.colStride : columnOf(index, win.cols) * win.colStride;\n // `row`: a single row, vertically centred in the viewport.\n const y = win.horizontal\n ? Math.max(0, (this._viewportHeight - cellHeight) / 2)\n : rowOf(index, win.cols) * win.rowStride;\n const thumbStyle = separate ? `height:${this.itemSize}px` : ``;\n const captionCss = separate\n ? `height:${Math.max(0, this.captionHeight - 4)}px`\n : style === `under`\n ? `height:${this.captionHeight}px`\n : ``;\n return html`\n <div\n class=\"cell${selected ? ` selected` : ``}${tickled ? ` tickled` : ``}${entering ? ` entering` : ``}\"\n part=\"item\"\n style=\"width:${this.itemSize}px;height:${cellHeight}px;transform:translate(${x}px,${y}px)\"\n data-index=${index}\n @click=${(e: MouseEvent) => this.#onCellClick(e, el)}\n @dblclick=${() => this.#onCellActivate(el)}\n @pointerenter=${() => this.tickled.handlePointerEnter(el)}\n >\n <div class=\"thumb\" part=\"thumb\" style=${thumbStyle}>\n <slot name=${this.#slotNameFor(el)}></slot>\n </div>\n ${showCaption\n ? html`<div class=\"caption\" part=\"caption\" style=${captionCss}>${caption}</div>`\n : ``}\n </div>\n `;\n }\n\n #onScroll = (e: Event): void => {\n const el = e.target as HTMLDivElement;\n this.#cancelScrollRaf();\n this.#scrollRaf = requestAnimationFrame(() => {\n this.#scrollRaf = 0;\n this._scrollTop = el.scrollTop;\n this._scrollLeft = el.scrollLeft;\n this.#emitViewportChange();\n });\n };\n\n #cancelScrollRaf(): void {\n if (this.#scrollRaf !== 0) {\n cancelAnimationFrame(this.#scrollRaf);\n this.#scrollRaf = 0;\n }\n }\n\n #onCellClick(e: MouseEvent, item: Element): void {\n this.selection.handleClick(item, e);\n this._dispatch<GridListItemClickDetail>(`list-item-click`, { item });\n }\n\n #onCellActivate(item: Element): void {\n if (this.interactionMode !== `manual`) {\n this.selection.replace(item);\n }\n this._dispatch<GridListActivateDetail>(`list-activate`, { item });\n }\n\n #currentWindow(): GridWindow {\n return computeGridWindow(\n this.#items.length,\n this.itemSize,\n this.#rowHeight(),\n this.gap,\n this._viewportWidth,\n this._viewportHeight,\n this.orientation === `row` ? this._scrollLeft : this._scrollTop,\n this.orientation,\n );\n }\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if ((e.ctrlKey || e.metaKey) && e.key === `f`) {\n return;\n }\n if ((e.ctrlKey || e.metaKey) && e.key === `a`) {\n if (this.selection.canSelectAll()) {\n e.preventDefault();\n this.selection.selectAll();\n }\n return;\n }\n\n const count = this.#items.length;\n if (count === 0)\n return;\n\n const win = this.#currentWindow();\n const move = (delta: number): void => {\n const from = this.tickled.tickledId\n ? this.#items.indexOf(this.tickled.tickledId)\n : -1;\n const nextIndex = Math.max(0, Math.min(count - 1, from + delta));\n const next = this.#items[nextIndex];\n if (next) {\n this.tickled.handleKeyboardNavigation(next);\n }\n };\n\n // In `grid` a vertical arrow jumps a whole row; in `row`/`column` every\n // arrow just steps one item along the single line.\n const perLine = this.orientation === `grid` ? win.cols : 1;\n\n switch (e.key) {\n case `ArrowLeft`:\n move(-1);\n break;\n case `ArrowRight`:\n move(1);\n break;\n case `ArrowUp`:\n move(-perLine);\n break;\n case `ArrowDown`:\n move(perLine);\n break;\n case `Home`:\n this.tickled.handleKeyboardNavigation(`first`);\n break;\n case `End`:\n this.tickled.handleKeyboardNavigation(`last`);\n break;\n case `PageUp`:\n case `PageDown`: {\n const mainExtent = win.horizontal ? this._viewportWidth : this._viewportHeight;\n const mainStride = win.horizontal ? win.colStride : win.rowStride;\n const visibleLines = Math.max(1, Math.floor(mainExtent / mainStride));\n move((e.key === `PageDown` ? 1 : -1) * visibleLines * perLine);\n break;\n }\n case `Enter`: {\n const id = this.tickled.tickledId;\n if (id) {\n e.preventDefault();\n this._dispatch<GridListItemClickDetail>(`list-item-click`, { item: id });\n this.#onCellActivate(id);\n }\n break;\n }\n case ` `: {\n const id = this.tickled.tickledId;\n if (id) {\n e.preventDefault();\n this.selection.handleSpace(id);\n }\n break;\n }\n case `Escape`:\n this.selection.clear();\n break;\n default:\n return;\n }\n e.preventDefault();\n };\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-grid-list': GridListElement;\n }\n}\n\nexport interface GridListElement {\n addEventListener<K extends keyof GridListFullElementEventMap>(\n type: K,\n listener: (this: GridListElement, ev: GridListFullElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"grid-list.js","names":["#items","#itemWrap","#cancelScrollRaf","#scrollRaf","#emitViewportChange","#currentWindow","#scrollItemIntoView","#onCellActivate","#searchRegistry","#effectiveSearchModes","#unregisterSearchCommands","#mutationObserver","#onChildrenChanged","#syncSearchCommands","#resizeObserver","#reflowTimer","#syncItems","#noteChildMutation","#entering","#viewportRef","#zoomAnchor","#applyZoomAnchor","#slotNameFor","#slotNames","#slotSeq","#rowHeight","#onScroll","#renderCell","#captionFor","#onCellClick","customElement"],"sources":["../src/grid-list/grid-list.ts"],"sourcesContent":["/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type { ListInteractionMode, ListSelectionMode } from '../interaction/list-selection-types.js';\nimport type {\n GridListActivateDetail,\n GridListCaptionAlign,\n GridListCaptionBackdrop,\n GridListCaptionPosition,\n GridListCaptionStyle,\n GridListFullElementEventMap,\n GridListItemClickDetail,\n GridListOrientation,\n GridListSelectDetail,\n GridListTickleDetail,\n GridListViewportChangeDetail,\n} from './types.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { createRef, ref } from 'lit/directives/ref.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport {\n createElementListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { listItemFadeKeyframes, tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { keyForElement } from '../interaction/keyed-list.js';\nimport { ListSelectionController } from '../interaction/list-selection-controller.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { scrollFadeStyles } from '../styles/scroll-fade.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type {\n GridListActivateDetail,\n GridListActivateEvent,\n GridListCaptionAlign,\n GridListCaptionBackdrop,\n GridListCaptionPosition,\n GridListCaptionStyle,\n GridListElementEventMap,\n GridListFullElementEventMap,\n GridListItemClickDetail,\n GridListItemClickEvent,\n GridListOrientation,\n GridListSelectDetail,\n GridListSelectEvent,\n GridListTickleDetail,\n GridListTickleEvent,\n GridListViewportChangeDetail,\n GridListViewportChangeEvent,\n ListInteractionMode,\n ListSelectionMode,\n} from './types.js';\n\ntype GridWindow = {\n readonly cols: number;\n readonly rows: number;\n /** Spacer height in px (vertical orientations); 0 when CSS controls it. */\n readonly totalHeight: number;\n /** Spacer width in px (`row` orientation); 0 when CSS controls it. */\n readonly totalWidth: number;\n readonly startIndex: number;\n readonly endIndex: number;\n /** Distance between the left edges of adjacent columns (item width + gap). */\n readonly colStride: number;\n /** Distance between the top edges of adjacent rows (row height + gap). */\n readonly rowStride: number;\n /** `true` for `row` orientation — the list scrolls along the x axis. */\n readonly horizontal: boolean;\n};\n\nconst ITEM_SELECTOR = `:scope > *`;\n\nconst MIN_ITEM_SIZE = 16;\n\n/**\n * How long the host keeps the `[reflowing]` attribute after items are inserted\n * mid-list — long enough for the cell move-transition and the enter animation\n * to finish. Kept a touch above the default `--grid-list-item-move-duration`.\n */\nconst REFLOW_WINDOW_MS = 320;\n\n// `itemWidth` is the square's width; `rowHeight` is the full cell height\n// (square, plus the caption band in `labelled` style). `scrollOffset` is\n// `scrollTop` for `grid`/`column` and `scrollLeft` for `row`.\nfunction computeGridWindow(\n count: number,\n itemWidth: number,\n rowHeight: number,\n gap: number,\n viewportWidth: number,\n viewportHeight: number,\n scrollOffset: number,\n orientation: GridListOrientation,\n overscan = 2,\n): GridWindow {\n const w = Math.max(1, itemWidth);\n const h = Math.max(1, rowHeight);\n const g = Math.max(0, gap);\n const colStride = w + g;\n const rowStride = h + g;\n const offset = Math.max(0, scrollOffset);\n\n if (orientation === `row`) {\n const rows = count === 0 ? 0 : 1;\n const totalWidth = count === 0 ? 0 : (count - 1) * colStride + w;\n if (count === 0 || viewportWidth <= 0) {\n return { cols: count, rows, totalHeight: 0, totalWidth, startIndex: 0, endIndex: 0, colStride, rowStride, horizontal: true };\n }\n const firstVisible = Math.max(0, Math.floor(offset / colStride));\n const lastVisible = Math.ceil((offset + viewportWidth) / colStride);\n return {\n cols: count,\n rows,\n totalHeight: 0,\n totalWidth,\n startIndex: Math.max(0, firstVisible - overscan),\n endIndex: Math.min(count, lastVisible + overscan),\n colStride,\n rowStride,\n horizontal: true,\n };\n }\n\n const cols = orientation === `column`\n ? 1\n : Math.max(1, Math.floor((Math.max(0, viewportWidth) + g) / colStride));\n const rows = count === 0 ? 0 : Math.ceil(count / cols);\n const totalHeight = rows === 0 ? 0 : (rows - 1) * rowStride + h;\n\n if (count === 0 || viewportHeight <= 0) {\n return { cols, rows, totalHeight, totalWidth: 0, startIndex: 0, endIndex: 0, colStride, rowStride, horizontal: false };\n }\n\n const firstVisibleRow = Math.max(0, Math.floor(offset / rowStride));\n const lastVisibleRow = Math.ceil((offset + viewportHeight) / rowStride);\n const rowStart = Math.max(0, firstVisibleRow - overscan);\n const rowEnd = Math.min(rows, lastVisibleRow + overscan);\n\n return {\n cols,\n rows,\n totalHeight,\n totalWidth: 0,\n startIndex: rowStart * cols,\n endIndex: Math.min(count, rowEnd * cols),\n colStride,\n rowStride,\n horizontal: false,\n };\n}\n\nfunction columnOf(index: number, cols: number): number {\n return cols <= 1 ? 0 : index % cols;\n}\n\nfunction rowOf(index: number, cols: number): number {\n return cols <= 1 ? index : Math.floor(index / cols);\n}\n\n@customElement(`ixfx-grid-list`)\nexport class GridListElement extends LitElement {\n static override styles = [\n themeFallbacks,\n tickledStyles,\n tickledItemStyles,\n // Both axes are registered; `render()` applies whichever one matches the\n // current orientation to the viewport (see the `scroll-fade-*` class there).\n scrollFadeStyles(`x`),\n scrollFadeStyles(`y`),\n listItemFadeKeyframes,\n listSearchStyles,\n css`\n :host {\n --grid-list-item-bg: var(--item-bg);\n --grid-list-radius: var(--radius-m);\n --grid-list-gap: var(--space-xs);\n position: relative;\n display: block;\n height: 100%;\n min-height: 2em;\n overflow: hidden;\n user-select: none;\n background: var(--surface-3);\n color: var(--surface-3-text);\n border-radius: var(--radius-s);\n border: 1px solid var(--border);\n }\n :host(:focus-visible) {\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n }\n .viewport {\n position: relative;\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n }\n :host([orientation=\"row\"]) .viewport {\n overflow-x: auto;\n overflow-y: hidden;\n }\n .spacer {\n position: relative;\n width: 100%;\n }\n .cell {\n position: absolute;\n inset: 0 auto auto 0;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n contain: layout style;\n border-radius: var(--grid-list-radius);\n }\n\n /* The square that holds the slotted content. */\n .thumb {\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n align-items: stretch;\n box-sizing: border-box;\n overflow: hidden;\n border-radius: 0;\n background: transparent;\n border: 1px solid transparent;\n transition: background var(--transition), border-color var(--transition);\n }\n .thumb ::slotted(*) {\n flex: 1;\n min-width: 0;\n min-height: 0;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n }\n .thumb ::slotted(*:empty)::after {\n content: \"Empty\";\n color: var(--surface-muted-text);\n font-size: var(--text-s);\n }\n ::slotted([hidden]) {\n display: none !important;\n }\n\n /* Selection / cursor wash — sits over the slotted content so it reads\n on photos and arbitrary DOM alike. */\n .thumb::after {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n border-radius: inherit;\n background: var(--accent);\n opacity: 0;\n transition: opacity var(--transition, 0.1s ease-out);\n }\n .cell.selected .thumb::after {\n opacity: 0.18;\n }\n\n /* ---- Caption (base) ---- */\n .caption {\n box-sizing: border-box;\n flex: none;\n padding: 3px 6px;\n font-size: var(--text-s, 0.8rem);\n line-height: 1.3;\n text-align: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--surface-3-text);\n }\n :host([caption-align=\"left\"]) .caption { text-align: left; }\n :host([caption-align=\"right\"]) .caption { text-align: right; }\n\n /* ---- Box modes (hidden / under / overlaid): the cell is one box with a\n single selection outline ---- */\n :host(:not([caption-style=\"separate\"])) .cell {\n background: var(--grid-list-item-bg);\n border: 1px solid transparent;\n overflow: hidden;\n transition: background var(--transition), border-color var(--transition);\n }\n :host(:not([caption-style=\"separate\"])) .cell:hover,\n :host(:not([caption-style=\"separate\"])) .cell.tickled {\n background: var(--item-bg-tickled);\n border: var(--item-border-tickled);\n }\n :host(:not([caption-style=\"separate\"])) .cell.selected {\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n }\n :host(:not([caption-style=\"separate\"])) .cell.selected.tickled {\n background: var(--item-bg-selected-tickled);\n outline: 2px dashed var(--surface-3);\n outline-offset: -2px;\n }\n\n /* under: caption is a strip inside the box, below the content */\n :host([caption-style=\"under\"]) .caption {\n border-top: 1px solid var(--border, rgba(128, 128, 128, 0.3));\n background: var(--surface-4, transparent);\n }\n\n /* overlaid: caption floats over the content */\n :host([caption-style=\"overlaid\"]) .caption {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n color: #fff;\n }\n :host([caption-style=\"overlaid\"][caption-position=\"top\"]) .caption {\n top: 0;\n bottom: auto;\n }\n :host([caption-style=\"overlaid\"][caption-position=\"middle\"]) .caption {\n top: 50%;\n bottom: auto;\n transform: translateY(-50%);\n }\n /* overlaid backdrop */\n :host([caption-style=\"overlaid\"][caption-backdrop=\"scrim\"]) .caption {\n background: rgba(0, 0, 0, 0.55);\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"gradient\"]) .caption {\n background: linear-gradient(to top, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));\n padding-block: 10px 4px;\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"gradient\"][caption-position=\"top\"]) .caption {\n background: linear-gradient(to bottom, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));\n padding-block: 4px 10px;\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"gradient\"][caption-position=\"middle\"]) .caption {\n background: rgba(0, 0, 0, 0.5);\n padding-block: 3px;\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"blur\"]) .caption {\n background: rgba(20, 20, 20, 0.3);\n backdrop-filter: blur(6px);\n -webkit-backdrop-filter: blur(6px);\n }\n :host([caption-style=\"overlaid\"][caption-backdrop=\"none\"]) .caption {\n background: none;\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.95), 0 0 6px rgba(0, 0, 0, 0.7);\n }\n\n /* ---- separate mode: square + detached caption, each highlighted ---- */\n :host([caption-style=\"separate\"]) .thumb {\n flex: none;\n border-radius: var(--grid-list-radius);\n background: var(--grid-list-item-bg);\n border: 1px solid transparent;\n }\n :host([caption-style=\"separate\"]) .cell:hover .thumb,\n :host([caption-style=\"separate\"]) .cell.tickled .thumb {\n background: var(--item-bg-tickled);\n border: var(--item-border-tickled);\n }\n :host([caption-style=\"separate\"]) .caption {\n display: flex;\n align-items: center;\n align-self: center;\n max-width: 100%;\n margin-top: 4px;\n border-radius: var(--radius-s, 4px);\n }\n :host([caption-style=\"separate\"][caption-align=\"left\"]) .caption { align-self: flex-start; }\n :host([caption-style=\"separate\"][caption-align=\"right\"]) .caption { align-self: flex-end; }\n :host([caption-style=\"separate\"]) .cell.selected .thumb {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n :host([caption-style=\"separate\"]) .cell.selected.tickled .thumb {\n background: var(--item-bg-selected-tickled);\n outline: 2px dashed var(--surface-3);\n outline-offset: 2px;\n }\n :host([caption-style=\"separate\"]) .cell.selected .caption {\n background: var(--accent);\n color: var(--accent-text, #000);\n }\n :host([caption-style=\"separate\"]) .cell.tickled .caption {\n background: var(--item-bg-tickled);\n outline: var(--item-border-tickled);\n }\n :host([caption-style=\"separate\"]) .cell.selected.tickled .caption {\n background: var(--item-bg-selected-tickled);\n outline: 2px dashed var(--surface-3);\n outline-offset: -2px;\n }\n\n /* ---- Insertion / removal animation ----\n Active only while the host carries [reflowing] — the ~0.3s window after\n the child list changes mid-list (see #noteChildMutation). Kept out of\n the base rules so it never fires during scroll virtualisation, where\n cells are recycled to wildly different positions every frame. Placed\n last so it wins over the earlier cell transition rule regardless of\n specificity. Survivors slide to their new slot; a freshly inserted cell\n also fades in. (A removed item's element is already gone, so there's\n nothing left to fade — the gap simply closes as the others slide.) */\n :host([reflowing]) .cell {\n transition:\n transform var(--grid-list-item-move-duration, 200ms) cubic-bezier(0.2, 0, 0, 1),\n background var(--transition),\n border-color var(--transition);\n }\n .cell.entering {\n animation: ixfx-list-item-in var(--grid-list-item-move-duration, 200ms) ease both;\n }\n @media (prefers-reduced-motion: reduce) {\n :host([reflowing]) .cell { transition: background var(--transition), border-color var(--transition); }\n .cell.entering { animation: none; }\n }\n `,\n ];\n\n @property({ type: String, attribute: `selection-mode` })\n selectionMode: ListSelectionMode = `single`;\n\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: ListInteractionMode = `standard`;\n\n @property({ type: Number, attribute: `item-size` })\n itemSize = 160;\n\n @property({ type: Number })\n gap = 8;\n\n /**\n * Layout / scroll direction.\n * - `grid` (default): items wrap across as many columns as fit, scrolls vertically.\n * - `row`: a single row of items, scrolls horizontally.\n * - `column`: a single column of items, scrolls vertically.\n */\n @property({ type: String, reflect: true })\n orientation: GridListOrientation = `grid`;\n\n /**\n * How the caption relates to the content — see {@link GridListCaptionStyle}.\n * - `hidden`: no caption.\n * - `separate`: detached label below the square, each highlighted on its own.\n * - `under` (default): one box, content on top, caption strip below it inside.\n * - `overlaid`: caption floats over the content.\n */\n @property({ type: String, attribute: `caption-style`, reflect: true })\n captionStyle: GridListCaptionStyle = `under`;\n\n /** Horizontal alignment of the caption text: `left`, `middle` (default), `right`. */\n @property({ type: String, attribute: `caption-align`, reflect: true })\n captionAlign: GridListCaptionAlign = `middle`;\n\n /** `overlaid` only — vertical placement: `top`, `middle`, `bottom` (default). */\n @property({ type: String, attribute: `caption-position`, reflect: true })\n captionPosition: GridListCaptionPosition = `bottom`;\n\n /** `overlaid` only — backdrop behind the caption: `scrim` (default), `gradient`, `blur`, `none`. */\n @property({ type: String, attribute: `caption-backdrop`, reflect: true })\n captionBackdrop: GridListCaptionBackdrop = `scrim`;\n\n /**\n * Height reserved for the caption in `separate` / `under` styles, in pixels.\n * Ignored by `overlaid` and `hidden`.\n */\n @property({ type: Number, attribute: `caption-height` })\n captionHeight = 24;\n\n @property({ type: String, attribute: `item-wrap` })\n itemWrap: `stop` | `wrap` = `stop`;\n\n /**\n * Predicate used by incremental filter-search (and callable directly). Items\n * for which it returns `false` are removed from layout and navigation.\n */\n @property({ attribute: false })\n filterPredicate: ((el: Element) => boolean) | undefined;\n\n /**\n * Space-separated subset of `navigate select filter` — limits which\n * incremental-search modes are offered (as commands and in-popover switches).\n * Unset ⇒ all three; empty ⇒ search disabled. See `docs/infra-incremental.md`.\n */\n @property({ type: String, attribute: `search-modes`, reflect: true })\n searchModes: string | undefined;\n\n @state() private _scrollTop = 0;\n @state() private _scrollLeft = 0;\n @state() private _viewportHeight = 0;\n @state() private _viewportWidth = 0;\n\n #viewportRef = createRef<HTMLDivElement>();\n\n #resizeObserver?: ResizeObserver;\n #mutationObserver?: MutationObserver;\n #scrollRaf = 0;\n #items: Element[] = [];\n #itemWrap: `stop` | `wrap` = `stop`;\n\n /** Items added mid-list that are still playing their enter animation. */\n #entering = new Set<Element>();\n /** Timer that ends the `[reflowing]` window opened by a mid-list insertion. */\n #reflowTimer = 0;\n\n /**\n * When cell geometry changes (zoom), the item nearest the viewport centre is\n * captured here in `willUpdate` and the scroll position is corrected in\n * `updated` so that item stays put — rather than the grid anchoring to its\n * top-left corner.\n */\n #zoomAnchor?: { index: number; lineFrac: number };\n\n /**\n * Per-item slot name. Each cell renders its own named `<slot>` and the\n * matching light-DOM child carries `slot=\"<name>\"`, so a child is projected\n * into exactly one cell. (A single unnamed slot would collapse every child\n * into the first cell.)\n */\n #slotNames = new WeakMap<Element, string>();\n #slotSeq = 0;\n\n readonly selection = new ListSelectionController<Element>({\n getOrderedItems: () => this._getVisibleItems(),\n isSelectable: () => true,\n getModes: () => ({ selectionMode: this.selectionMode, interactionMode: this.interactionMode }),\n getKey: keyForElement,\n onChange: (selected, previous) => {\n this._syncItemStates();\n // ListSelectionController isn't a reactive controller, so nudge Lit to\n // re-render the cells with updated `selected` classes.\n this.requestUpdate();\n this._dispatch<GridListSelectDetail>(`list-select`, {\n selected,\n previous,\n selectedKeys: this.selection.selectedKeys,\n });\n },\n });\n\n readonly tickled = new TickledController<Element>(this, {\n getItems: () =>\n this.#items.map(el => ({\n id: el,\n enabled: !el.hasAttribute(`not-checked`),\n })),\n onTickle: (id) => {\n if (id !== undefined) {\n this._dispatch<GridListTickleDetail>(`list-tickle`, { item: id });\n }\n },\n onStateChange: () => this._syncItemStates(),\n itemWrap: this.#itemWrap,\n });\n\n /** Incremental search (navigate / select / filter). See `docs/infra-incremental.md`. */\n readonly search = new ListSearchController<Element>(this, {\n adapter: createElementListSearchAdapter(this, {\n itemSelector: ITEM_SELECTOR,\n getLabel: el =>\n el.getAttribute(`data-label`)\n ?? el.querySelector(`[data-grid-list-caption]`)?.textContent?.trim()\n ?? el.getAttribute(`data-search-label`)\n ?? el.textContent?.trim()\n ?? ``,\n highlightKey: `grid-list-search`,\n }),\n });\n\n #searchRegistry: CommandRegistry<unknown> | undefined;\n #unregisterSearchCommands: (() => void) | undefined;\n\n /** Command registry carrying this grid's `list.search.*` commands. */\n get registry(): CommandRegistry<unknown> | undefined {\n return this.#searchRegistry;\n }\n\n /** Effective search modes: this component's capability (all three) ∩ the `search-modes` attribute. */\n #effectiveSearchModes(): ListSearchMode[] {\n const raw = this.searchModes?.trim();\n if (raw === undefined)\n return [...LIST_SEARCH_MODES];\n const requested = new Set(raw.split(/\\s+/));\n return LIST_SEARCH_MODES.filter(m => requested.has(m));\n }\n\n #syncSearchCommands(): void {\n if (!this.#searchRegistry)\n return;\n this.search.setModes(this.#effectiveSearchModes());\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = registerListSearchCommands(this.#searchRegistry, this.search);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute(`tabindex`)) {\n this.tabIndex = 0;\n }\n // Reflect caption defaults up-front so the `:host([caption-*])` style rules\n // apply even when the consumer never sets the attributes.\n for (const [attr, value] of [\n [`caption-style`, this.captionStyle],\n [`caption-align`, this.captionAlign],\n [`caption-position`, this.captionPosition],\n [`caption-backdrop`, this.captionBackdrop],\n ] as const) {\n if (!this.hasAttribute(attr)) {\n this.setAttribute(attr, value);\n }\n }\n this.addEventListener(`keydown`, this._onKeyDown as EventListener);\n this.#mutationObserver ??= new MutationObserver(records => this.#onChildrenChanged(records));\n this.#mutationObserver.observe(this, { childList: true, attributeFilter: [`hidden`] });\n this.#searchRegistry ??= createCommandRegistry();\n this.#syncSearchCommands();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`keydown`, this._onKeyDown as EventListener);\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n this.#mutationObserver?.disconnect();\n this.#cancelScrollRaf();\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = undefined;\n this.#searchRegistry = undefined;\n if (this.#reflowTimer) {\n clearTimeout(this.#reflowTimer);\n this.#reflowTimer = 0;\n }\n }\n\n #onChildrenChanged(records?: MutationRecord[]): void {\n const previousLength = this.#items.length;\n this.#syncItems();\n this._syncItemStates();\n this.#noteChildMutation(previousLength, records);\n this.requestUpdate();\n void this.updateComplete.then(() => this.#emitViewportChange());\n }\n\n /**\n * When the child list changes mid-list — not a first populate or a wholesale\n * replace — mark any newcomers for an enter animation and open a short\n * `[reflowing]` window so the cells that shift slide to their new position\n * instead of snapping. Removals get the same window (the survivors slide to\n * close the gap). The window is bounded in time so the transform transition\n * never bleeds into scroll virtualisation.\n *\n * Reads the `MutationRecord`s directly rather than diffing `#items`, because a\n * `requestUpdate()` between the DOM change and this callback (e.g. a caller\n * that clears the selection before removing) lets `updated()` re-sync `#items`\n * first, which would hide the change from a naive diff.\n */\n #noteChildMutation(previousLength: number, records?: MutationRecord[]): void {\n if (!this.hasUpdated || !records || records.length === 0)\n return;\n const currentSet = new Set(this.#items);\n const added: Element[] = [];\n let removedCount = 0;\n for (const record of records) {\n for (const node of record.addedNodes) {\n if (node.nodeType === Node.ELEMENT_NODE && currentSet.has(node as Element))\n added.push(node as Element);\n }\n for (const node of record.removedNodes) {\n if (node.nodeType === Node.ELEMENT_NODE)\n removedCount++;\n }\n }\n // Nothing to animate, a first populate, or a wholesale replace (every\n // current item is new) — leave it alone.\n if (added.length === 0 && removedCount === 0)\n return;\n if (previousLength === 0 && removedCount === 0)\n return;\n if (added.length > 0 && added.length === this.#items.length)\n return;\n for (const el of added)\n this.#entering.add(el);\n this.toggleAttribute(`reflowing`, true);\n if (this.#reflowTimer)\n clearTimeout(this.#reflowTimer);\n this.#reflowTimer = window.setTimeout(() => {\n this.#reflowTimer = 0;\n this.#entering.clear();\n this.toggleAttribute(`reflowing`, false);\n this.requestUpdate();\n }, REFLOW_WINDOW_MS);\n }\n\n #emitViewportChange(): void {\n this._dispatch<GridListViewportChangeDetail>(`grid-list-viewport-change`, {\n visibleKeys: this.visibleKeys(),\n });\n }\n\n protected override firstUpdated(): void {\n const el = this.#viewportRef.value;\n if (!el)\n return;\n this._viewportWidth = el.clientWidth;\n this._viewportHeight = el.clientHeight;\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n this._viewportWidth = entry.contentRect.width;\n this._viewportHeight = entry.contentRect.height;\n }\n });\n this.#resizeObserver.observe(el);\n this.#syncItems();\n this.requestUpdate();\n }\n\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has(`searchModes`)) {\n this.#syncSearchCommands();\n }\n if (changed.has(`filterPredicate`)) {\n this.#syncItems();\n }\n if (changed.has(`itemSize`) || changed.has(`gap`)) {\n this.itemSize = Math.max(MIN_ITEM_SIZE, Math.round(this.itemSize));\n this.gap = Math.max(0, Math.round(this.gap));\n }\n if (changed.has(`captionHeight`)) {\n this.captionHeight = Math.max(0, Math.round(this.captionHeight));\n }\n if (changed.has(`itemWrap`)) {\n this.#itemWrap = this.itemWrap;\n }\n\n const geometryChanged = changed.has(`itemSize`) || changed.has(`gap`)\n || changed.has(`captionStyle`) || changed.has(`captionHeight`)\n || changed.has(`orientation`);\n if (geometryChanged && this.hasUpdated && this.#items.length > 0) {\n const prevOrientation = (changed.get(`orientation`) as GridListOrientation | undefined) ?? this.orientation;\n const horizontal = prevOrientation === `row`;\n const prevOffset = horizontal ? this._scrollLeft : this._scrollTop;\n const prevExtent = horizontal ? this._viewportWidth : this._viewportHeight;\n if (prevExtent > 0 && prevOffset > 1) {\n const prevItemSize = (changed.get(`itemSize`) as number | undefined) ?? this.itemSize;\n const prevGap = (changed.get(`gap`) as number | undefined) ?? this.gap;\n const prevCaptionStyle = (changed.get(`captionStyle`) as GridListCaptionStyle | undefined) ?? this.captionStyle;\n const prevCaptionHeight = (changed.get(`captionHeight`) as number | undefined) ?? this.captionHeight;\n const prevBand = prevCaptionStyle === `separate` || prevCaptionStyle === `under`;\n const prevRowHeight = prevItemSize + (prevBand ? prevCaptionHeight : 0);\n const prev = computeGridWindow(\n this.#items.length,\n prevItemSize,\n prevRowHeight,\n prevGap,\n this._viewportWidth,\n this._viewportHeight,\n prevOffset,\n prevOrientation,\n );\n const mainStride = horizontal ? prev.colStride : prev.rowStride;\n const centerLine = (prevOffset + prevExtent / 2) / mainStride;\n const lineFloor = Math.max(0, Math.floor(centerLine));\n const index = horizontal\n ? Math.min(this.#items.length - 1, lineFloor)\n : Math.min(\n this.#items.length - 1,\n lineFloor * prev.cols + Math.max(0, Math.floor((prev.cols - 1) / 2)),\n );\n this.#zoomAnchor = { index, lineFrac: centerLine - lineFloor };\n }\n }\n }\n\n /** Full cell height: the square, plus a caption band in `separate` / `under`. */\n #rowHeight(): number {\n const captionBand = this.captionStyle === `separate` || this.captionStyle === `under`;\n return this.itemSize + (captionBand ? this.captionHeight : 0);\n }\n\n #captionFor(el: Element): string {\n return (\n el.getAttribute(`data-label`)\n ?? el.querySelector(`[data-grid-list-caption]`)?.textContent?.trim()\n ?? ``\n );\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n super.updated(changed);\n this.#syncItems();\n if (changed.has(`selectionMode`) || changed.has(`interactionMode`)) {\n this.selection.clearAnchor();\n }\n if (changed.has(`orientation`)) {\n // Reset the axis that's no longer scrollable so a later switch back\n // doesn't inherit a stale offset.\n const vp = this.#viewportRef.value;\n if (vp) {\n if (this.orientation === `row`) {\n vp.scrollTop = 0;\n this._scrollTop = 0;\n } else {\n vp.scrollLeft = 0;\n this._scrollLeft = 0;\n }\n }\n }\n this.#applyZoomAnchor();\n }\n\n /** Re-anchor the scroll so the item captured in `willUpdate` stays centred. */\n #applyZoomAnchor(): void {\n if (!this.#zoomAnchor)\n return;\n const { index, lineFrac } = this.#zoomAnchor;\n this.#zoomAnchor = undefined;\n\n const vp = this.#viewportRef.value;\n if (!vp)\n return;\n const win = this.#currentWindow();\n\n if (win.horizontal) {\n if (this._viewportWidth <= 0)\n return;\n const targetCenter = (index + lineFrac) * win.colStride;\n const maxScroll = Math.max(0, win.totalWidth - this._viewportWidth);\n const next = Math.min(maxScroll, Math.max(0, targetCenter - this._viewportWidth / 2));\n if (Math.abs(vp.scrollLeft - next) > 0.5) {\n vp.scrollLeft = next;\n this._scrollLeft = next;\n }\n return;\n }\n\n if (this._viewportHeight <= 0)\n return;\n const line = win.cols > 0 ? Math.floor(index / win.cols) : 0;\n const targetCenter = (line + lineFrac) * win.rowStride;\n const maxScroll = Math.max(0, win.totalHeight - this._viewportHeight);\n const next = Math.min(maxScroll, Math.max(0, targetCenter - this._viewportHeight / 2));\n if (Math.abs(vp.scrollTop - next) > 0.5) {\n vp.scrollTop = next;\n this._scrollTop = next;\n }\n }\n\n #syncItems(): void {\n this.#items = Array.from(this.querySelectorAll(ITEM_SELECTOR)).filter(el =>\n !(el as HTMLElement).hidden\n && (this.filterPredicate === undefined || this.filterPredicate(el)),\n );\n for (const el of this.#items) {\n const name = this.#slotNameFor(el);\n if (el.getAttribute(`slot`) !== name) {\n el.setAttribute(`slot`, name);\n }\n }\n }\n\n #slotNameFor(el: Element): string {\n let name = this.#slotNames.get(el);\n if (name === undefined) {\n this.#slotSeq += 1;\n name = `gl-item-${this.#slotSeq}`;\n this.#slotNames.set(el, name);\n }\n return name;\n }\n\n private _getVisibleItems(): Element[] {\n return this.#items.filter((el) => {\n if ((el as HTMLElement).hidden)\n return false;\n return true;\n });\n }\n\n get count(): number {\n return this.#items.length;\n }\n\n /**\n * Number of cells currently rendered in the shadow DOM. With virtualization\n * this is roughly the visible rows plus overscan, regardless of how large\n * `count` is — useful for demos/diagnostics.\n */\n get renderedCount(): number {\n return this.renderRoot.querySelectorAll(`.cell`).length;\n }\n\n get selectedItems(): ReadonlySet<Element> {\n return this.selection.selected;\n }\n\n /** The selection as stable `data-key` / `data-value` strings. */\n get selectedKeys(): ReadonlySet<string> {\n return this.selection.selectedKeys;\n }\n\n select(item: Element): void {\n this.selection.replace(item);\n }\n\n selectMany(items: Iterable<Element>): void {\n this.selection.selectMany(items);\n }\n\n deselect(item: Element): void {\n this.selection.deselect(item);\n }\n\n clearSelection(): void {\n this.selection.clear();\n }\n\n selectAll(): void {\n if (this.selection.canSelectAll()) {\n this.selection.selectAll();\n }\n }\n\n /**\n * Replace the selection with the items carrying these keys. Unknown keys are\n * ignored; survives the host rebuilding the item set. Requires each item to\n * have a `data-key` (or `data-value`).\n */\n selectKeys(keys: Iterable<string>): void {\n this.selection.selectKeys(keys, key => this.getItem(key));\n }\n\n /** Add items by key to the selection (multi-select modes only). */\n addSelectedKeys(keys: Iterable<string>): void {\n this.selection.addKeys(keys, key => this.getItem(key));\n }\n\n /** Remove items by key from the selection. */\n removeSelectedKeys(keys: Iterable<string>): void {\n this.selection.removeKeys(keys, key => this.getItem(key));\n }\n\n /** Move the cursor to the item with this key and scroll it into view. */\n focusKey(key: string): void {\n const el = this.getItem(key);\n if (!el)\n return;\n this.tickled.focus(el);\n this.#scrollItemIntoView(el);\n }\n\n /** The key of the item under the cursor, or `undefined`. */\n get tickledKey(): string | undefined {\n const id = this.tickled.tickledId;\n return id ? keyForElement(id) : undefined;\n }\n\n getItem(key: string): Element | undefined {\n return this.#items.find(el => keyForElement(el) === key);\n }\n\n getItemByIndex(index: number): Element | undefined {\n return this.#items[index];\n }\n\n getKey(item: Element): string | undefined {\n return keyForElement(item);\n }\n\n visibleKeys(): string[] {\n const win = this.#currentWindow();\n const slice = this.#items.slice(win.startIndex, win.endIndex);\n return slice\n .map(el => keyForElement(el))\n .filter((k): k is string => k !== undefined);\n }\n\n /** Adjust the scroll offset so `el` is fully within the viewport. */\n #scrollItemIntoView(el: Element): void {\n const index = this.#items.indexOf(el);\n const vp = this.#viewportRef.value;\n if (index < 0 || !vp)\n return;\n const win = this.#currentWindow();\n\n if (win.horizontal) {\n const left = index * win.colStride;\n const right = left + this.itemSize;\n const viewLeft = vp.scrollLeft;\n let next = viewLeft;\n if (left < viewLeft)\n next = left;\n else if (right > viewLeft + this._viewportWidth)\n next = right - this._viewportWidth;\n if (next !== viewLeft) {\n vp.scrollLeft = next;\n this._scrollLeft = next;\n }\n return;\n }\n\n const row = win.cols > 0 ? Math.floor(index / win.cols) : 0;\n const top = row * win.rowStride;\n const bottom = top + this.#rowHeight();\n const viewTop = vp.scrollTop;\n let next = viewTop;\n if (top < viewTop)\n next = top;\n else if (bottom > viewTop + this._viewportHeight)\n next = bottom - this._viewportHeight;\n if (next !== viewTop) {\n vp.scrollTop = next;\n this._scrollTop = next;\n }\n }\n\n private _syncItemStates(): void {\n for (const el of this.#items) {\n el.toggleAttribute(`data-tickled`, this.tickled.isTickled(el));\n el.toggleAttribute(`data-selected`, this.selection.selected.has(el));\n }\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n }\n\n private _dispatch<T>(name: string, detail: T): void {\n this.dispatchEvent(\n new CustomEvent<T>(name, {\n detail,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n protected override render(): ReturnType<typeof html> {\n const win = this.#currentWindow();\n const slice = this.#items.slice(win.startIndex, win.endIndex);\n const spacerStyle = win.horizontal\n ? `width:${win.totalWidth}px;height:100%`\n : `height:${win.totalHeight}px`;\n // Fade the edge that can still be scrolled towards (see ../styles/scroll-fade.ts).\n const scrollFade = win.horizontal ? `scroll-fade-x` : `scroll-fade-y`;\n return html`\n <div\n class=\"viewport ${scrollFade}\"\n part=\"viewport\"\n ${ref(this.#viewportRef)}\n data-input-mode=${this.tickled.inputMode}\n @scroll=${this.#onScroll}\n >\n <div class=\"spacer\" style=${spacerStyle}>\n ${repeat(\n slice,\n el => this.#slotNameFor(el),\n (el, i) => this.#renderCell(el, win.startIndex + i, win),\n )}\n </div>\n </div>\n ${this.search.renderField()}\n `;\n }\n\n #renderCell(el: Element, index: number, win: GridWindow): ReturnType<typeof html> {\n const selected = this.selection.selected.has(el);\n const tickled = this.tickled.isTickled(el);\n const entering = this.#entering.has(el);\n const style = this.captionStyle;\n const separate = style === `separate`;\n const caption = style === `hidden` ? `` : this.#captionFor(el);\n const showCaption = caption !== ``;\n const cellHeight = win.rowStride - this.gap;\n const x = win.horizontal ? index * win.colStride : columnOf(index, win.cols) * win.colStride;\n // `row`: a single row, vertically centred in the viewport.\n const y = win.horizontal\n ? Math.max(0, (this._viewportHeight - cellHeight) / 2)\n : rowOf(index, win.cols) * win.rowStride;\n const thumbStyle = separate ? `height:${this.itemSize}px` : ``;\n const captionCss = separate\n ? `height:${Math.max(0, this.captionHeight - 4)}px`\n : style === `under`\n ? `height:${this.captionHeight}px`\n : ``;\n return html`\n <div\n class=\"cell${selected ? ` selected` : ``}${tickled ? ` tickled` : ``}${entering ? ` entering` : ``}\"\n part=\"item\"\n style=\"width:${this.itemSize}px;height:${cellHeight}px;transform:translate(${x}px,${y}px)\"\n data-index=${index}\n @click=${(e: MouseEvent) => this.#onCellClick(e, el)}\n @dblclick=${() => this.#onCellActivate(el)}\n @pointerenter=${() => this.tickled.handlePointerEnter(el)}\n >\n <div class=\"thumb\" part=\"thumb\" style=${thumbStyle}>\n <slot name=${this.#slotNameFor(el)}></slot>\n </div>\n ${showCaption\n ? html`<div class=\"caption\" part=\"caption\" style=${captionCss}>${caption}</div>`\n : ``}\n </div>\n `;\n }\n\n #onScroll = (e: Event): void => {\n const el = e.target as HTMLDivElement;\n this.#cancelScrollRaf();\n this.#scrollRaf = requestAnimationFrame(() => {\n this.#scrollRaf = 0;\n this._scrollTop = el.scrollTop;\n this._scrollLeft = el.scrollLeft;\n this.#emitViewportChange();\n });\n };\n\n #cancelScrollRaf(): void {\n if (this.#scrollRaf !== 0) {\n cancelAnimationFrame(this.#scrollRaf);\n this.#scrollRaf = 0;\n }\n }\n\n #onCellClick(e: MouseEvent, item: Element): void {\n this.selection.handleClick(item, e);\n this._dispatch<GridListItemClickDetail>(`list-item-click`, { item });\n }\n\n #onCellActivate(item: Element): void {\n if (this.interactionMode !== `manual`) {\n this.selection.replace(item);\n }\n this._dispatch<GridListActivateDetail>(`list-activate`, { item });\n }\n\n #currentWindow(): GridWindow {\n return computeGridWindow(\n this.#items.length,\n this.itemSize,\n this.#rowHeight(),\n this.gap,\n this._viewportWidth,\n this._viewportHeight,\n this.orientation === `row` ? this._scrollLeft : this._scrollTop,\n this.orientation,\n );\n }\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if ((e.ctrlKey || e.metaKey) && e.key === `f`) {\n return;\n }\n if ((e.ctrlKey || e.metaKey) && e.key === `a`) {\n if (this.selection.canSelectAll()) {\n e.preventDefault();\n this.selection.selectAll();\n }\n return;\n }\n\n const count = this.#items.length;\n if (count === 0)\n return;\n\n const win = this.#currentWindow();\n const move = (delta: number): void => {\n const from = this.tickled.tickledId\n ? this.#items.indexOf(this.tickled.tickledId)\n : -1;\n const nextIndex = Math.max(0, Math.min(count - 1, from + delta));\n const next = this.#items[nextIndex];\n if (next) {\n this.tickled.handleKeyboardNavigation(next);\n this.#scrollItemIntoView(next);\n }\n };\n\n // In `grid` a vertical arrow jumps a whole row; in `row`/`column` every\n // arrow just steps one item along the single line.\n const perLine = this.orientation === `grid` ? win.cols : 1;\n\n switch (e.key) {\n case `ArrowLeft`:\n move(-1);\n break;\n case `ArrowRight`:\n move(1);\n break;\n case `ArrowUp`:\n move(-perLine);\n break;\n case `ArrowDown`:\n move(perLine);\n break;\n case `Home`:\n this.tickled.handleKeyboardNavigation(`first`);\n if (this.tickled.tickledId) {\n this.#scrollItemIntoView(this.tickled.tickledId);\n }\n break;\n case `End`:\n this.tickled.handleKeyboardNavigation(`last`);\n if (this.tickled.tickledId) {\n this.#scrollItemIntoView(this.tickled.tickledId);\n }\n break;\n case `PageUp`:\n case `PageDown`: {\n const mainExtent = win.horizontal ? this._viewportWidth : this._viewportHeight;\n const mainStride = win.horizontal ? win.colStride : win.rowStride;\n const visibleLines = Math.max(1, Math.floor(mainExtent / mainStride));\n move((e.key === `PageDown` ? 1 : -1) * visibleLines * perLine);\n break;\n }\n case `Enter`: {\n const id = this.tickled.tickledId;\n if (id) {\n e.preventDefault();\n this._dispatch<GridListItemClickDetail>(`list-item-click`, { item: id });\n this.#onCellActivate(id);\n }\n break;\n }\n case ` `: {\n const id = this.tickled.tickledId;\n if (id) {\n e.preventDefault();\n this.selection.handleSpace(id);\n }\n break;\n }\n case `Escape`:\n this.selection.clear();\n break;\n default:\n return;\n }\n e.preventDefault();\n };\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-grid-list': GridListElement;\n }\n}\n\nexport interface GridListElement {\n addEventListener<K extends keyof GridListFullElementEventMap>(\n type: K,\n listener: (this: GridListElement, ev: GridListFullElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n}\n"],"mappings":"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"}
|