@ixfx/components 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.d.ts +193 -8
- package/bundle/index.js +153 -152
- package/dist/{checked-select-BmwqpgGr.js → checked-select-DsQ-o9lI.js} +1 -1
- package/dist/checked-select.js +1 -1
- package/dist/{crumb-navigation-D7dAC0H-.js → crumb-navigation-09YFje6W.js} +2 -2
- package/dist/{crumb-navigation-Tm4fnsvN.d.ts → crumb-navigation-DOfOS7li.d.ts} +1 -1
- package/dist/crumbs.d.ts +1 -1
- package/dist/crumbs.js +1 -1
- package/dist/{data-grid-BcO3SMac.js → data-grid-BGmJbMCb.js} +4 -3
- package/dist/{data-grid-vasJtjFP.d.ts → data-grid-BQWmVYg0.d.ts} +8 -2
- package/dist/data-grid.d.ts +2 -2
- package/dist/data-grid.js +1 -1
- package/dist/{detail-list-E9WdMVbE.d.ts → detail-list-CfjoIl2N.d.ts} +9 -3
- package/dist/{detail-list-vPVwE1CP.js → detail-list-CrHASoAx.js} +2 -1
- package/dist/detail-list.d.ts +3 -3
- package/dist/detail-list.js +1 -1
- package/dist/{flat-list-CfutGqKY.d.ts → flat-list-C2z81bK6.d.ts} +5 -3
- package/dist/flat-list.d.ts +1 -1
- package/dist/flat-list.js +4 -2
- package/dist/{grid-list-Dg8hIiKO.d.ts → grid-list-Crv-hFJL.d.ts} +60 -4
- package/dist/{grid-list-BHo9TBxX.js → grid-list-DYU_z2K9.js} +258 -19
- package/dist/grid-list.d.ts +3 -3
- package/dist/grid-list.js +1 -1
- package/dist/incr-search.d.ts +1 -1
- package/dist/{index-CzhYJJsx.d.ts → index-BE0hk8xS.d.ts} +2 -2
- package/dist/{index-88ra6YHP.d.ts → index-BymYKGY-.d.ts} +3 -3
- package/dist/{index-CRLTVAyt.d.ts → index-Db5VGFR1.d.ts} +1 -1
- package/dist/index.d.ts +82 -20
- package/dist/index.js +293 -107
- package/dist/{interaction-8Kbbf6xN.js → interaction-BEcBIY0d.js} +1 -1
- package/dist/{list-native-drag-controller-ByftBooJ.js → list-native-drag-controller-Brk30s5d.js} +3 -0
- package/dist/{list-native-drag-controller-CgXKdmjr.d.ts → list-native-drag-controller-Cs-Tmtaa.d.ts} +1 -1
- package/dist/{menu-C3DhTjHx.js → menu-B6NFqEtm.js} +3 -3
- package/dist/{menu-item-BSxhlWnW.js → menu-item-D0zy1yax.js} +2 -2
- package/dist/menu.js +2 -2
- package/dist/{miller-DqDEaXqT.js → miller-B0qbnWwe.js} +1 -1
- package/dist/miller.d.ts +2 -2
- package/dist/miller.js +1 -1
- package/dist/narrowed-text.js +1 -1
- package/dist/{node-graph-DqEGv5QR.js → node-graph-D9iovxQp.js} +1 -1
- package/dist/node-graph.js +1 -1
- package/dist/{notification-pill-BiHEJk-o.d.ts → notification-pill-BJonE_wo.d.ts} +14 -1
- package/dist/notifier.d.ts +1 -1
- package/dist/select-horiz.js +1 -1
- package/dist/sunburst-tree.d.ts +1 -1
- package/dist/{sunbursttree-list-CsrmVSB8.d.ts → sunbursttree-list-XF7gBKod.d.ts} +2 -2
- package/dist/{tree-BP5fxvEX.js → tree-1CSNgw72.js} +2 -2
- package/dist/{tree-component-DNuzfo6R.d.ts → tree-component-BE7OEIiH.d.ts} +7 -1
- package/dist/tree.d.ts +2 -2
- package/dist/tree.js +1 -1
- package/dist/{vertical-list-B9z1lbjM.js → vertical-list-BNCRA_zy.js} +2 -1
- package/dist/{vertical-list-BzeXehBt.d.ts → vertical-list-Dyc5azxv.d.ts} +8 -2
- package/dist/vertical-list.d.ts +2 -2
- package/dist/vertical-list.js +1 -1
- package/docs-user/grid-list.md +70 -0
- package/docs-user/index.json +2 -2
- package/docs-user/notifier.md +28 -0
- package/package.json +3 -3
|
@@ -2,9 +2,9 @@ import { n as appearanceColor, t as appearanceAbsent } from "./item-appearance-F
|
|
|
2
2
|
import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-pnieYweS.js";
|
|
3
3
|
import { c as createElementListSearchAdapter, f as createDataListSearchAdapter, i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, u as keyForElement } from "./incr-search-C5114RxZ.js";
|
|
4
4
|
import { i as resolveGroupKey, r as partitionByGroup } from "./grouping-kENdqzSV.js";
|
|
5
|
-
import "./interaction-
|
|
5
|
+
import "./interaction-BEcBIY0d.js";
|
|
6
6
|
import { i as ListDragSelectController, n as gestureOf, t as ListSelectionController } from "./list-selection-controller-Dkh3m3hX.js";
|
|
7
|
-
import { a as listItemFadeKeyframes, t as ListNativeDragController } from "./list-native-drag-controller-
|
|
7
|
+
import { a as listItemFadeKeyframes, t as ListNativeDragController } from "./list-native-drag-controller-Brk30s5d.js";
|
|
8
8
|
import { i as sameKeySet, r as isPartialKey, t as PARTIAL_DESCRIPTION } from "./partial-keys-D4l_ede_.js";
|
|
9
9
|
import { c as keysAsFlags, f as withoutFlag, i as capFlags, l as keysToArray, o as flagsFromRecord, s as flagsToRecord, t as EMPTY_FLAGS } from "./pending-Afl4LT64.js";
|
|
10
10
|
import { n as createScrollHoverGuard } from "./scroll-hover-guard-BGAjtyXT.js";
|
|
@@ -19,7 +19,104 @@ import { LitElement, css, html, nothing } from "lit";
|
|
|
19
19
|
import { property, state } from "lit/decorators.js";
|
|
20
20
|
import { createCommandRegistry } from "@clinth/ui-commands";
|
|
21
21
|
import { repeat } from "lit/directives/repeat.js";
|
|
22
|
+
import { keyed } from "lit/directives/keyed.js";
|
|
22
23
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
24
|
+
// src/grid-list/grid-list-key-index.ts
|
|
25
|
+
var KeyIndex = class {
|
|
26
|
+
/** Key → raw index. The first occurrence of a key wins. */
|
|
27
|
+
#map = /* @__PURE__ */ new Map();
|
|
28
|
+
/** The items array the map was built from. */
|
|
29
|
+
#source = void 0;
|
|
30
|
+
/** The adapter the map was built with. */
|
|
31
|
+
#adapter = void 0;
|
|
32
|
+
/**
|
|
33
|
+
* Rebuild the map if `items` or `adapter` changed since it was built.
|
|
34
|
+
*
|
|
35
|
+
* The map is keyed on the identity of the array / adapter it was built from,
|
|
36
|
+
* so it stays correct even when the items are replaced between Lit update
|
|
37
|
+
* cycles (a host may assign `items` and then call `updateItem` before the
|
|
38
|
+
* update flushes).
|
|
39
|
+
*
|
|
40
|
+
* One pass — the adapter's `key` is called once per item.
|
|
41
|
+
*/
|
|
42
|
+
ensure(items, adapter) {
|
|
43
|
+
if (this.#source === items && this.#adapter === adapter) return;
|
|
44
|
+
if (!adapter) {
|
|
45
|
+
this.#map = /* @__PURE__ */ new Map();
|
|
46
|
+
this.#source = items;
|
|
47
|
+
this.#adapter = void 0;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const map = /* @__PURE__ */ new Map();
|
|
51
|
+
for (let i = 0; i < items.length; i++) {
|
|
52
|
+
const key = adapter.key(items[i], i);
|
|
53
|
+
if (!map.has(key)) map.set(key, i);
|
|
54
|
+
}
|
|
55
|
+
this.#map = map;
|
|
56
|
+
this.#source = items;
|
|
57
|
+
this.#adapter = adapter;
|
|
58
|
+
}
|
|
59
|
+
/** Raw index of `key`, or `-1`. O(1). */
|
|
60
|
+
get(key) {
|
|
61
|
+
return this.#map.get(key) ?? -1;
|
|
62
|
+
}
|
|
63
|
+
/** Whether `key` is known. */
|
|
64
|
+
has(key) {
|
|
65
|
+
return this.#map.has(key);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Record that `items` is now `next`, after `patch` updated the map.
|
|
69
|
+
*
|
|
70
|
+
* `patch` receives the live map so a mutation can adjust only the entries
|
|
71
|
+
* it touched. The map's "built from" pointer is updated to `next`, so the
|
|
72
|
+
* next {@link ensure} does not rebuild it.
|
|
73
|
+
*/
|
|
74
|
+
commit(next, patch) {
|
|
75
|
+
if (patch) patch(this.#map);
|
|
76
|
+
this.#source = next;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Update the map after the item at `idx` changed.
|
|
80
|
+
*
|
|
81
|
+
* `next` is the new array; `oldKey` is the key the item had before the
|
|
82
|
+
* change, and the new key is derived from the item. If the item kept its key
|
|
83
|
+
* the map is untouched. If it was re-keyed, the old entry is dropped and the
|
|
84
|
+
* new one added — but only when no *earlier* item already claims the new
|
|
85
|
+
* key, so "the first occurrence wins" still holds.
|
|
86
|
+
*/
|
|
87
|
+
rekey(next, idx, oldKey, item, adapter) {
|
|
88
|
+
const newKey = adapter.key(item, idx);
|
|
89
|
+
if (newKey === oldKey) return;
|
|
90
|
+
this.#map.delete(oldKey);
|
|
91
|
+
if (!this.#map.has(oldKey)) {
|
|
92
|
+
for (let i = idx + 1; i < next.length; i++) if (adapter.key(next[i], i) === oldKey) {
|
|
93
|
+
this.#map.set(oldKey, i);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (!this.#map.has(newKey)) this.#map.set(newKey, idx);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Rebuild the map from `items` — used after a removal, which shifts every
|
|
101
|
+
* later item down.
|
|
102
|
+
*/
|
|
103
|
+
rebuild(items, adapter) {
|
|
104
|
+
const map = /* @__PURE__ */ new Map();
|
|
105
|
+
for (let i = 0; i < items.length; i++) {
|
|
106
|
+
const key = adapter.key(items[i], i);
|
|
107
|
+
if (!map.has(key)) map.set(key, i);
|
|
108
|
+
}
|
|
109
|
+
this.#map = map;
|
|
110
|
+
this.#source = items;
|
|
111
|
+
}
|
|
112
|
+
/** Add the keys of `items`, which were appended at `base`. */
|
|
113
|
+
addAppended(items, base, adapter) {
|
|
114
|
+
for (let i = 0; i < items.length; i++) {
|
|
115
|
+
const key = adapter.key(items[i], base + i);
|
|
116
|
+
if (!this.#map.has(key)) this.#map.set(key, base + i);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
23
120
|
// src/grid-list/grid-list-layout.ts
|
|
24
121
|
/**
|
|
25
122
|
* `itemWidth` is the square's width; `rowHeight` is the full cell height
|
|
@@ -393,15 +490,25 @@ const SYNTHETIC_PREFIX = `gl-auto-`;
|
|
|
393
490
|
function isSyntheticKey(key) {
|
|
394
491
|
return key.startsWith(SYNTHETIC_PREFIX);
|
|
395
492
|
}
|
|
396
|
-
|
|
397
|
-
|
|
493
|
+
/**
|
|
494
|
+
* Warn about duplicate keys while building the key → raw index map, in a single
|
|
495
|
+
* pass. Avoids the throwaway key array `items.map(adapter.key)` used to build.
|
|
496
|
+
* The map keeps the **first** occurrence of each key, matching the
|
|
497
|
+
* "first occurrence wins" contract the warning states.
|
|
498
|
+
*/
|
|
499
|
+
function rawIndexByKey(items, keyOf) {
|
|
500
|
+
const index = /* @__PURE__ */ new Map();
|
|
398
501
|
const dupes = /* @__PURE__ */ new Set();
|
|
399
|
-
for (
|
|
400
|
-
|
|
401
|
-
if (
|
|
402
|
-
|
|
502
|
+
for (let i = 0; i < items.length; i++) {
|
|
503
|
+
const key = keyOf(items[i], i);
|
|
504
|
+
if (index.has(key)) {
|
|
505
|
+
if (!isSyntheticKey(key)) dupes.add(key);
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
index.set(key, i);
|
|
403
509
|
}
|
|
404
510
|
if (dupes.size > 0) console.warn(`ixfx-grid-list: duplicate item key(s) ${[...dupes].map((k) => `"${k}"`).join(`, `)} — the first occurrence wins for key-based operations.`);
|
|
511
|
+
return index;
|
|
405
512
|
}
|
|
406
513
|
/** Key → first effective index, built from `keys` (first occurrence wins on duplicates). */
|
|
407
514
|
function indexByKey(keys) {
|
|
@@ -421,6 +528,8 @@ var ElementGridListSource = class {
|
|
|
421
528
|
#effectiveIndices = [];
|
|
422
529
|
#keysCache;
|
|
423
530
|
#indexCache;
|
|
531
|
+
/** Key → raw index, rebuilt with the items (first occurrence wins). */
|
|
532
|
+
#rawIndexByKey = /* @__PURE__ */ new Map();
|
|
424
533
|
#grouping;
|
|
425
534
|
#groups = [];
|
|
426
535
|
#groupByKey = /* @__PURE__ */ new Map();
|
|
@@ -442,6 +551,9 @@ var ElementGridListSource = class {
|
|
|
442
551
|
this.#indexCache ??= indexByKey(this.keys());
|
|
443
552
|
return this.#indexCache.get(key) ?? -1;
|
|
444
553
|
}
|
|
554
|
+
rawIndexOfKey(key) {
|
|
555
|
+
return this.#rawIndexByKey.get(key) ?? -1;
|
|
556
|
+
}
|
|
445
557
|
keys() {
|
|
446
558
|
this.#keysCache ??= this.#effectiveIndices.map((i) => this.#itemKey(this.#items[i]));
|
|
447
559
|
return this.#keysCache;
|
|
@@ -489,7 +601,7 @@ var ElementGridListSource = class {
|
|
|
489
601
|
}
|
|
490
602
|
refresh() {
|
|
491
603
|
this.#items = Array.from(this.#host.querySelectorAll(ITEM_SELECTOR$1)).filter((el) => !el.hidden);
|
|
492
|
-
|
|
604
|
+
this.#rawIndexByKey = rawIndexByKey(this.#items, (el) => this.#itemKey(el));
|
|
493
605
|
this.#recomputeEffective();
|
|
494
606
|
}
|
|
495
607
|
/** Effective-order elements — the array `GridListElement` renders and slices. */
|
|
@@ -554,13 +666,20 @@ var DataGridListSource = class {
|
|
|
554
666
|
#effectiveIndices = [];
|
|
555
667
|
#keysCache;
|
|
556
668
|
#indexCache;
|
|
669
|
+
/**
|
|
670
|
+
* Key → **raw** index, built in one pass over the items. The first
|
|
671
|
+
* occurrence of a key wins (same contract as the duplicate-key warning).
|
|
672
|
+
* Lets `resolveKeyToData` and the host's `updateItem` find an item without
|
|
673
|
+
* an O(n) scan per call.
|
|
674
|
+
*/
|
|
675
|
+
#rawIndexByKey;
|
|
557
676
|
#grouping;
|
|
558
677
|
#groups = [];
|
|
559
678
|
#groupByKey = /* @__PURE__ */ new Map();
|
|
560
679
|
constructor(items, adapter) {
|
|
561
680
|
this.#items = items;
|
|
562
681
|
this.#adapter = adapter;
|
|
563
|
-
|
|
682
|
+
this.#rawIndexByKey = rawIndexByKey(items, (it, i) => adapter.key(it, i));
|
|
564
683
|
this.#recomputeEffective();
|
|
565
684
|
}
|
|
566
685
|
get count() {
|
|
@@ -647,8 +766,16 @@ var DataGridListSource = class {
|
|
|
647
766
|
}
|
|
648
767
|
resolveKeyToElement(_key) {}
|
|
649
768
|
resolveKeyToData(key) {
|
|
650
|
-
const idx = this.#
|
|
651
|
-
return idx
|
|
769
|
+
const idx = this.#rawIndexByKey.get(key);
|
|
770
|
+
return idx === void 0 ? void 0 : this.#items[idx];
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Raw (unfiltered) index of `key`, or `-1`. O(1) — the key → raw index map
|
|
774
|
+
* is built in one pass over the items. The first occurrence of a duplicate
|
|
775
|
+
* key wins.
|
|
776
|
+
*/
|
|
777
|
+
rawIndexOfKey(key) {
|
|
778
|
+
return this.#rawIndexByKey.get(key) ?? -1;
|
|
652
779
|
}
|
|
653
780
|
#recomputeEffective() {
|
|
654
781
|
const effective = [];
|
|
@@ -964,6 +1091,8 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
964
1091
|
}
|
|
965
1092
|
});
|
|
966
1093
|
this.#groupByChanged = false;
|
|
1094
|
+
this.#keyIndex = new KeyIndex();
|
|
1095
|
+
this.#cellRevisions = /* @__PURE__ */ new Map();
|
|
967
1096
|
this.#resolveKey = (key) => this.#source.indexOfKey(key) >= 0 ? key : void 0;
|
|
968
1097
|
this.#markedTickled = /* @__PURE__ */ new Set();
|
|
969
1098
|
this.#markedSelected = /* @__PURE__ */ new Set();
|
|
@@ -1893,13 +2022,17 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
1893
2022
|
const dataModeChanged = changed.has(`items`) || changed.has(`itemAdapter`);
|
|
1894
2023
|
if (dataModeChanged) {
|
|
1895
2024
|
this.#zoomAnchor = void 0;
|
|
2025
|
+
this.#ensureRawIndex();
|
|
1896
2026
|
const prevKeys = this.#source?.keys() ?? [];
|
|
1897
2027
|
const modeFlipped = this.itemAdapter !== void 0 !== this.#source instanceof DataGridListSource;
|
|
1898
2028
|
this.#rebuildSource();
|
|
1899
2029
|
const nextKeys = this.#source.keys();
|
|
1900
2030
|
const nextKeySet = new Set(nextKeys);
|
|
1901
2031
|
const removedKeys = prevKeys.filter((k) => !nextKeySet.has(k));
|
|
1902
|
-
if (removedKeys.length > 0)
|
|
2032
|
+
if (removedKeys.length > 0) {
|
|
2033
|
+
this.#demoteGone(removedKeys);
|
|
2034
|
+
for (const key of removedKeys) this.#cellRevisions.delete(key);
|
|
2035
|
+
}
|
|
1903
2036
|
const tickledId = this.tickled.tickledId;
|
|
1904
2037
|
if (tickledId && !nextKeySet.has(tickledId)) this.#demoteFocus(tickledId);
|
|
1905
2038
|
this._syncItemStates();
|
|
@@ -2199,11 +2332,19 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
2199
2332
|
/**
|
|
2200
2333
|
* Data mode only: raw index of `key` in `this.items`, or `-1`. Data-mode keys
|
|
2201
2334
|
* come straight from the adapter, so this is exact even under a filter/search.
|
|
2335
|
+
*
|
|
2336
|
+
* O(1) — backed by {@link #keyIndex}, a key → raw index map kept in sync
|
|
2337
|
+
* with `items`.
|
|
2202
2338
|
*/
|
|
2203
2339
|
#rawIndexOfKey(key) {
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2340
|
+
this.#ensureRawIndex();
|
|
2341
|
+
return this.#keyIndex.get(key);
|
|
2342
|
+
}
|
|
2343
|
+
/** Key → raw index for the current `items`. See `grid-list-key-index.ts`. */
|
|
2344
|
+
#keyIndex;
|
|
2345
|
+
/** Rebuild the key → raw index map if `items` / `itemAdapter` changed. */
|
|
2346
|
+
#ensureRawIndex() {
|
|
2347
|
+
this.#keyIndex.ensure(this.items, this.itemAdapter);
|
|
2207
2348
|
}
|
|
2208
2349
|
/**
|
|
2209
2350
|
* Data mode: replace the whole item array. Selection and cursor keep any key
|
|
@@ -2220,23 +2361,104 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
2220
2361
|
* A no-op in element mode.
|
|
2221
2362
|
*/
|
|
2222
2363
|
appendItems(items) {
|
|
2223
|
-
if (this.itemAdapter && items.length > 0)
|
|
2364
|
+
if (this.itemAdapter && items.length > 0) {
|
|
2365
|
+
const base = this.items.length;
|
|
2366
|
+
const next = [...this.items, ...items];
|
|
2367
|
+
this.#ensureRawIndex();
|
|
2368
|
+
this.#keyIndex.addAppended(items, base, this.itemAdapter);
|
|
2369
|
+
this.#keyIndex.commit(next);
|
|
2370
|
+
this.items = next;
|
|
2371
|
+
}
|
|
2224
2372
|
}
|
|
2225
2373
|
/**
|
|
2226
2374
|
* Data mode: replace the item carrying `key`. A visible cell re-renders in
|
|
2227
2375
|
* place (the keyed subtree is kept); an offscreen item shows its new content
|
|
2228
2376
|
* when scrolled into view. Scroll and selection are untouched. Unknown keys
|
|
2229
2377
|
* are ignored.
|
|
2378
|
+
*
|
|
2379
|
+
* Passing the **same object** that is already at `key` is a no-op: the
|
|
2380
|
+
* `items` array is left untouched (same identity) and nothing is emitted.
|
|
2381
|
+
* Use {@link refreshItem} to re-render a cell without changing the data.
|
|
2382
|
+
*
|
|
2383
|
+
* Updating many items one by one? Use {@link updateItems} — it applies them
|
|
2384
|
+
* with a single array copy and a single rebuild.
|
|
2230
2385
|
*/
|
|
2231
2386
|
updateItem(key, item) {
|
|
2232
2387
|
if (!this.itemAdapter) return;
|
|
2233
2388
|
const idx = this.#rawIndexOfKey(key);
|
|
2234
2389
|
if (idx < 0) return;
|
|
2390
|
+
if (this.items[idx] === item) return;
|
|
2235
2391
|
const next = [...this.items];
|
|
2236
2392
|
next[idx] = item;
|
|
2393
|
+
this.#ensureRawIndex();
|
|
2394
|
+
this.#keyIndex.rekey(next, idx, key, item, this.itemAdapter);
|
|
2395
|
+
this.#keyIndex.commit(next);
|
|
2237
2396
|
this.items = next;
|
|
2238
2397
|
}
|
|
2239
2398
|
/**
|
|
2399
|
+
* Data mode: replace several items at once — the batched form of
|
|
2400
|
+
* {@link updateItem}.
|
|
2401
|
+
*
|
|
2402
|
+
* `entries` is an array of `{ key, item }` pairs (a `Map<key, item>` is
|
|
2403
|
+
* accepted too). All the replacements are applied with **one** array copy
|
|
2404
|
+
* and **one** source rebuild, so a host that must refresh n rows does not
|
|
2405
|
+
* pay n copies and n scans.
|
|
2406
|
+
*
|
|
2407
|
+
* Semantics match n sequential {@link updateItem} calls:
|
|
2408
|
+
* - unknown keys are ignored;
|
|
2409
|
+
* - an entry whose `item` is the identical object already at that key is
|
|
2410
|
+
* skipped (it cannot change anything);
|
|
2411
|
+
* - selection, cursor and scroll are untouched;
|
|
2412
|
+
* - if no entry changes anything, `items` is left untouched (same identity)
|
|
2413
|
+
* and nothing is emitted.
|
|
2414
|
+
*/
|
|
2415
|
+
updateItems(entries) {
|
|
2416
|
+
if (!this.itemAdapter) return;
|
|
2417
|
+
const pairs = [];
|
|
2418
|
+
for (const entry of entries) if (Array.isArray(entry)) pairs.push([entry[0], entry[1]]);
|
|
2419
|
+
else pairs.push([entry.key, entry.item]);
|
|
2420
|
+
if (pairs.length === 0) return;
|
|
2421
|
+
this.#ensureRawIndex();
|
|
2422
|
+
const next = [...this.items];
|
|
2423
|
+
const touched = [];
|
|
2424
|
+
for (const [key, item] of pairs) {
|
|
2425
|
+
const idx = this.#keyIndex.get(key);
|
|
2426
|
+
if (idx < 0) continue;
|
|
2427
|
+
if (next[idx] === item) continue;
|
|
2428
|
+
next[idx] = item;
|
|
2429
|
+
touched.push([
|
|
2430
|
+
idx,
|
|
2431
|
+
key,
|
|
2432
|
+
item
|
|
2433
|
+
]);
|
|
2434
|
+
}
|
|
2435
|
+
if (touched.length === 0) return;
|
|
2436
|
+
for (const [idx, key, item] of touched) this.#keyIndex.rekey(next, idx, key, item, this.itemAdapter);
|
|
2437
|
+
this.#keyIndex.commit(next);
|
|
2438
|
+
this.items = next;
|
|
2439
|
+
}
|
|
2440
|
+
/**
|
|
2441
|
+
* Data mode: re-render the cell for `key` without touching `items`.
|
|
2442
|
+
*
|
|
2443
|
+
* Use this when the *data* is unchanged but the cell should be redrawn — for
|
|
2444
|
+
* example after mutating something the adapter reads from outside the item
|
|
2445
|
+
* (a thumbnail's load state). The `items` array keeps its identity, so the
|
|
2446
|
+
* collection is not copied and no source rebuild is triggered.
|
|
2447
|
+
*
|
|
2448
|
+
* The adapter's `render` is called again for that cell on the next render,
|
|
2449
|
+
* so the cell picks up the new state. Other cells are left alone.
|
|
2450
|
+
*
|
|
2451
|
+
* Unknown keys are ignored. A no-op in element mode.
|
|
2452
|
+
*/
|
|
2453
|
+
refreshItem(key) {
|
|
2454
|
+
if (!this.itemAdapter) return;
|
|
2455
|
+
if (this.#rawIndexOfKey(key) < 0) return;
|
|
2456
|
+
this.#cellRevisions.set(key, (this.#cellRevisions.get(key) ?? 0) + 1);
|
|
2457
|
+
this.requestUpdate();
|
|
2458
|
+
}
|
|
2459
|
+
/** Per-key revision, bumped by {@link refreshItem}. */
|
|
2460
|
+
#cellRevisions;
|
|
2461
|
+
/**
|
|
2240
2462
|
* Data mode: remove the items carrying these keys. Removed keys leave the
|
|
2241
2463
|
* selection and cursor silently (via the `items` change) and are held as
|
|
2242
2464
|
* pending view state. A no-op in element mode.
|
|
@@ -2245,7 +2467,12 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
2245
2467
|
if (!this.itemAdapter) return;
|
|
2246
2468
|
const adapter = this.itemAdapter;
|
|
2247
2469
|
const keySet = new Set(keys);
|
|
2248
|
-
|
|
2470
|
+
const kept = this.items.filter((it, i) => !keySet.has(adapter.key(it, i)));
|
|
2471
|
+
if (kept.length === this.items.length) return;
|
|
2472
|
+
this.#ensureRawIndex();
|
|
2473
|
+
this.#keyIndex.rebuild(kept, adapter);
|
|
2474
|
+
this.#keyIndex.commit(kept);
|
|
2475
|
+
this.items = kept;
|
|
2249
2476
|
}
|
|
2250
2477
|
/**
|
|
2251
2478
|
* Data mode: drop every item. Selection and cursor are reset and one
|
|
@@ -2708,13 +2935,24 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
2708
2935
|
>
|
|
2709
2936
|
<div class="content${icon === void 0 ? `` : ` has-icon`}" part="content">
|
|
2710
2937
|
${icon === void 0 ? nothing : html`<span class="cell-icon" part="icon" style=${this.#colorStyle(this.#source.iconColorAt(index))}>${icon}</span>`}
|
|
2711
|
-
${this.#
|
|
2938
|
+
${this.#renderCellBody(index, key)}
|
|
2712
2939
|
</div>
|
|
2713
2940
|
${showCaption ? this.#renderCaption(caption, captionCss, tickled, this.#source.badgeAt(index), this.#source.textColorAt(index)) : ``}
|
|
2714
2941
|
</div>
|
|
2715
2942
|
`;
|
|
2716
2943
|
}
|
|
2717
2944
|
/**
|
|
2945
|
+
* The cell's content, keyed by the cell's revision so {@link refreshItem}
|
|
2946
|
+
* can force it to be re-evaluated (and its DOM re-created) even though
|
|
2947
|
+
* `items` did not change. Without a revision change the content is bound
|
|
2948
|
+
* normally, so Lit keeps it in place.
|
|
2949
|
+
*/
|
|
2950
|
+
#renderCellBody(index, key) {
|
|
2951
|
+
const revision = this.#cellRevisions.get(key);
|
|
2952
|
+
if (revision === void 0) return this.#source.renderCellContent(index);
|
|
2953
|
+
return keyed(revision, this.#source.renderCellContent(index));
|
|
2954
|
+
}
|
|
2955
|
+
/**
|
|
2718
2956
|
* A tickled cell swaps its plain label for an `ixfx-pan-text` in loop mode
|
|
2719
2957
|
* so a truncated label scrolls instead of staying an ellipsis. Unticked
|
|
2720
2958
|
* cells keep the cheap plain-text caption.
|
|
@@ -3008,6 +3246,7 @@ __decorate([property({
|
|
|
3008
3246
|
reflect: true
|
|
3009
3247
|
})], GridListElement.prototype, "marqueeFromCellBlank", void 0);
|
|
3010
3248
|
__decorate([property({ attribute: false })], GridListElement.prototype, "dragPreviewRenderer", void 0);
|
|
3249
|
+
__decorate([property({ attribute: false })], GridListElement.prototype, "writeDataTransfer", void 0);
|
|
3011
3250
|
__decorate([property({ attribute: false })], GridListElement.prototype, "dragPreviewSource", void 0);
|
|
3012
3251
|
__decorate([property({
|
|
3013
3252
|
type: String,
|
package/dist/grid-list.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as
|
|
2
|
-
import { _ as
|
|
1
|
+
import { B as ListDragSource, F as ListDragEntry, H as ListNativeDragStartEvent, I as ListDragPreview, L as ListDragPreviewContext, R as ListDragPreviewRenderer, V as ListNativeDragStartDetail } from "./tree-component-BE7OEIiH.js";
|
|
2
|
+
import { S as GridListViewportChangeEvent, _ as GridListSelectDetail, a as GridListCaptionAlign, b as GridListTickleEvent, c as GridListCaptionStyle, d as GridListFullElementEventMap, f as GridListItemClickDetail, g as GridListOrientation, h as GridListItemUpdate, i as GridListActivateEvent, l as GridListDataAdapter, m as GridListItemEventDetail, n as GridListViewState, o as GridListCaptionBackdrop, p as GridListItemClickEvent, r as GridListActivateDetail, s as GridListCaptionPosition, t as GridListElement, u as GridListElementEventMap, v as GridListSelectEvent, x as GridListViewportChangeDetail, y as GridListTickleDetail } from "./grid-list-Crv-hFJL.js";
|
|
3
3
|
import { h as ListSelectionMode, i as ListInteractionMode } from "./list-selection-types-CKTt7Rrw.js";
|
|
4
4
|
import { i as ListGroupChangeEvent, l as ListGroupToggleDetail, n as ListGroupBy, o as ListGroupInfo, r as ListGroupChangeDetail, s as ListGroupLabel, u as ListGroupToggleEvent } from "./grouping-OoQ8WaKc.js";
|
|
5
|
-
export { type GridListActivateDetail, type GridListActivateEvent, type GridListCaptionAlign, type GridListCaptionBackdrop, type GridListCaptionPosition, type GridListCaptionStyle, type GridListDataAdapter, GridListElement, type GridListElementEventMap, type GridListFullElementEventMap, type GridListItemClickDetail, type GridListItemClickEvent, type GridListItemEventDetail, type GridListOrientation, type GridListSelectDetail, type GridListSelectEvent, type GridListTickleDetail, type GridListTickleEvent, type GridListViewState, type GridListViewportChangeDetail, type GridListViewportChangeEvent, type ListDragEntry, type ListDragPreview, type ListDragPreviewContext, type ListDragPreviewRenderer, type ListDragSource, type ListGroupBy, type ListGroupChangeDetail, type ListGroupChangeEvent, type ListGroupInfo, type ListGroupLabel, type ListGroupToggleDetail, type ListGroupToggleEvent, type ListInteractionMode, type ListNativeDragStartDetail, type ListNativeDragStartEvent, type ListSelectionMode };
|
|
5
|
+
export { type GridListActivateDetail, type GridListActivateEvent, type GridListCaptionAlign, type GridListCaptionBackdrop, type GridListCaptionPosition, type GridListCaptionStyle, type GridListDataAdapter, GridListElement, type GridListElementEventMap, type GridListFullElementEventMap, type GridListItemClickDetail, type GridListItemClickEvent, type GridListItemEventDetail, type GridListItemUpdate, type GridListOrientation, type GridListSelectDetail, type GridListSelectEvent, type GridListTickleDetail, type GridListTickleEvent, type GridListViewState, type GridListViewportChangeDetail, type GridListViewportChangeEvent, type ListDragEntry, type ListDragPreview, type ListDragPreviewContext, type ListDragPreviewRenderer, type ListDragSource, type ListGroupBy, type ListGroupChangeDetail, type ListGroupChangeEvent, type ListGroupInfo, type ListGroupLabel, type ListGroupToggleDetail, type ListGroupToggleEvent, type ListInteractionMode, type ListNativeDragStartDetail, type ListNativeDragStartEvent, type ListSelectionMode };
|
package/dist/grid-list.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import "./list-group-header.js";
|
|
2
|
-
export { t as GridListElement } from "./grid-list-
|
|
2
|
+
export { t as GridListElement } from "./grid-list-DYU_z2K9.js";
|
package/dist/incr-search.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as FuzzySearch, C as ListSearchControllerOptions, D as IncrSearchTreeOptions, E as IncrSearchTreeController, F as IncrSearchChangeCallback, I as IncrSearchOptions, L as IncrSearchResult, M as HighlightOptions, N as HighlightTarget, O as createAcCompletionProvider, P as IncrSearch, R as IncrSearchState, S as ListSearchController, T as ListSearchMode, _ as DataListSearchAdapterOptions, a as RegisterListSearchCommandsOptions, b as LIST_SEARCH_MODES, c as applyHighlights, d as createFuzzySearch, f as ElementIncrSearch, g as createElementListSearchAdapter, h as ElementListSearchHost, i as LIST_SEARCH_COMMAND_IDS, j as FuzzySearchOptions, k as ElementIncrSearchOptions, l as buildHighlightTargets, m as ElementListSearchAdapterOptions, n as createTreeListSearchAdapter, o as registerListSearchCommands, p as createElementIncrSearch, r as listSearchStyles, s as createIncrSearch, t as TreeListSearchAdapterOptions, u as clearHighlights, v as DataListSearchItem, w as ListSearchHost, x as ListSearchAdapter, y as createDataListSearchAdapter } from "./index-
|
|
1
|
+
import { A as FuzzySearch, C as ListSearchControllerOptions, D as IncrSearchTreeOptions, E as IncrSearchTreeController, F as IncrSearchChangeCallback, I as IncrSearchOptions, L as IncrSearchResult, M as HighlightOptions, N as HighlightTarget, O as createAcCompletionProvider, P as IncrSearch, R as IncrSearchState, S as ListSearchController, T as ListSearchMode, _ as DataListSearchAdapterOptions, a as RegisterListSearchCommandsOptions, b as LIST_SEARCH_MODES, c as applyHighlights, d as createFuzzySearch, f as ElementIncrSearch, g as createElementListSearchAdapter, h as ElementListSearchHost, i as LIST_SEARCH_COMMAND_IDS, j as FuzzySearchOptions, k as ElementIncrSearchOptions, l as buildHighlightTargets, m as ElementListSearchAdapterOptions, n as createTreeListSearchAdapter, o as registerListSearchCommands, p as createElementIncrSearch, r as listSearchStyles, s as createIncrSearch, t as TreeListSearchAdapterOptions, u as clearHighlights, v as DataListSearchItem, w as ListSearchHost, x as ListSearchAdapter, y as createDataListSearchAdapter } from "./index-Db5VGFR1.js";
|
|
2
2
|
export { type DataListSearchAdapterOptions, type DataListSearchItem, type ElementIncrSearch, type ElementIncrSearchOptions, type ElementListSearchAdapterOptions, type ElementListSearchHost, type FuzzySearch, type FuzzySearchOptions, type HighlightOptions, type HighlightTarget, type IncrSearch, type IncrSearchChangeCallback, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, type IncrSearchTreeOptions as IncrSearchMillerOptions, type IncrSearchTreeOptions, type IncrSearchOptions, type IncrSearchResult, type IncrSearchState, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, type ListSearchAdapter, ListSearchController, type ListSearchControllerOptions, type ListSearchHost, type ListSearchMode, type RegisterListSearchCommandsOptions, type TreeListSearchAdapterOptions, applyHighlights, buildHighlightTargets, clearHighlights, createAcCompletionProvider, createDataListSearchAdapter, createElementIncrSearch, createElementListSearchAdapter, createFuzzySearch, createIncrSearch, createTreeListSearchAdapter, listSearchStyles, registerListSearchCommands };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { E as TreeSearchHost, M as TreeDataModel, a as TreeComponent, i as TreeCollapseEvent, j as TreeTickleEvent, k as TreeSelectEvent, n as TreeActivateEvent, o as TreeComponentEventMap, w as TreeNavigateOptions, x as TreeItemClickEvent, y as TreeExpandEvent } from "./tree-component-
|
|
1
|
+
import { E as TreeSearchHost, M as TreeDataModel, a as TreeComponent, i as TreeCollapseEvent, j as TreeTickleEvent, k as TreeSelectEvent, n as TreeActivateEvent, o as TreeComponentEventMap, w as TreeNavigateOptions, x as TreeItemClickEvent, y as TreeExpandEvent } from "./tree-component-BE7OEIiH.js";
|
|
2
2
|
import { a as TreeItem, n as TreeExclusivity, o as TreeNode, r as TreeFilterPredicate, s as TreeSelectionFilter, t as LoadChildrenCallback } from "./types-6hpXRKt7.js";
|
|
3
3
|
import { a as ViewStateBase, n as ScrollState, t as GetViewStateOptions } from "./types-16GC5k1z.js";
|
|
4
4
|
import { m as ListSelectKeysDetail, u as ListSelectIntentDetail } from "./list-selection-types-CKTt7Rrw.js";
|
|
5
5
|
import "./index-Cdcek1Oj.js";
|
|
6
|
-
import { S as ListSearchController } from "./index-
|
|
6
|
+
import { S as ListSearchController } from "./index-Db5VGFR1.js";
|
|
7
7
|
import { n as TickledController } from "./tickled-controller-DSPoG551.js";
|
|
8
8
|
import { LitElement, PropertyValues, TemplateResult, nothing } from "lit";
|
|
9
9
|
import { CommandRegistry } from "@clinth/ui-commands";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as TreeItemDblClickEvent, D as TreeSelectAllOptions, E as TreeSearchHost, M as TreeDataModel, R as ListDragPreviewRenderer, V as ListNativeDragStartDetail, _ as TreeDropTarget, a as TreeComponent, c as TreeDragContext, d as TreeDragStartEvent, h as TreeDropEvent, i as TreeCollapseEvent, j as TreeTickleEvent, k as TreeSelectEvent, l as TreeDragEndEvent, m as TreeDropDetail, n as TreeActivateEvent, o as TreeComponentEventMap, p as TreeDropContext, s as TreeDndMode, u as TreeDragOverEvent, w as TreeNavigateOptions, x as TreeItemClickEvent, y as TreeExpandEvent, z as ListDragPreviewSourceResolver } from "./tree-component-BE7OEIiH.js";
|
|
2
2
|
import { a as TreeItem, i as TreeInteractionMode, n as TreeExclusivity, o as TreeNode, r as TreeFilterPredicate, s as TreeSelectionFilter, t as LoadChildrenCallback } from "./types-6hpXRKt7.js";
|
|
3
3
|
import { a as ViewStateBase, t as GetViewStateOptions } from "./types-16GC5k1z.js";
|
|
4
4
|
import { m as ListSelectKeysDetail, p as ListSelectIntentSource, u as ListSelectIntentDetail } from "./list-selection-types-CKTt7Rrw.js";
|
|
5
5
|
import "./index-Cdcek1Oj.js";
|
|
6
|
-
import { S as ListSearchController } from "./index-
|
|
7
|
-
import { t as ListNativeDragController } from "./list-native-drag-controller-
|
|
6
|
+
import { S as ListSearchController } from "./index-Db5VGFR1.js";
|
|
7
|
+
import { t as ListNativeDragController } from "./list-native-drag-controller-Cs-Tmtaa.js";
|
|
8
8
|
import { n as TickledController } from "./tickled-controller-DSPoG551.js";
|
|
9
9
|
import { LitElement, PropertyValues, ReactiveController, ReactiveControllerHost, TemplateResult, nothing } from "lit";
|
|
10
10
|
import { CommandRegistry } from "@clinth/ui-commands";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as TreeSearchHost } from "./tree-component-
|
|
1
|
+
import { E as TreeSearchHost } from "./tree-component-BE7OEIiH.js";
|
|
2
2
|
import { o as TreeNode } from "./types-6hpXRKt7.js";
|
|
3
3
|
import { p as ListSelectIntentSource } from "./list-selection-types-CKTt7Rrw.js";
|
|
4
4
|
import "./icon-Bhz0c6Yf.js";
|