@ixfx/components 0.11.7 → 0.11.8
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 +153 -2
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +1129 -164
- package/bundle/index.js.map +1 -1
- package/dist/{detail-list-CgkOHYOa.d.ts → detail-list-lE_5UWVl.d.ts} +34 -3
- package/dist/detail-list-lE_5UWVl.d.ts.map +1 -0
- package/dist/detail-list.d.ts +3 -2
- package/dist/detail-list.js +271 -6
- package/dist/detail-list.js.map +1 -1
- package/dist/{grid-list-D6AfWfwn.d.ts → grid-list-Bc-RkDoO.d.ts} +42 -1
- package/dist/grid-list-Bc-RkDoO.d.ts.map +1 -0
- package/dist/{grid-list-3fGhdaFA.js → grid-list-Bwaf61is.js} +659 -158
- package/dist/grid-list-Bwaf61is.js.map +1 -0
- package/dist/grid-list.d.ts +3 -2
- package/dist/grid-list.js +2 -1
- package/dist/grouping-CUKgmkMm.d.ts +63 -0
- package/dist/grouping-CUKgmkMm.d.ts.map +1 -0
- package/dist/grouping-RYPnHkrS.js +53 -0
- package/dist/grouping-RYPnHkrS.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/list-group-header.d.ts +26 -0
- package/dist/list-group-header.d.ts.map +1 -0
- package/dist/list-group-header.js +122 -0
- package/dist/list-group-header.js.map +1 -0
- package/dist/{list-selection-controller-SA4piSBi.js → list-selection-controller-BeE70lbB.js} +42 -4
- package/dist/list-selection-controller-BeE70lbB.js.map +1 -0
- package/dist/vertical-list.js +1 -1
- package/docs-user/README.md +1 -0
- package/docs-user/detail-list.md +28 -0
- package/docs-user/grid-list.md +35 -3
- package/docs-user/index.json +7 -2
- package/docs-user/list-group-header.md +14 -0
- package/docs-user/llms.txt +1 -0
- package/llms.txt +1 -0
- package/package.json +5 -1
- package/dist/detail-list-CgkOHYOa.d.ts.map +0 -1
- package/dist/grid-list-3fGhdaFA.js.map +0 -1
- package/dist/grid-list-D6AfWfwn.d.ts.map +0 -1
- package/dist/list-selection-controller-SA4piSBi.js.map +0 -1
package/bundle/index.js
CHANGED
|
@@ -5549,6 +5549,56 @@ __decorate([state()], RadioGroup.prototype, "_icons", void 0);
|
|
|
5549
5549
|
__decorate([query(`slot`)], RadioGroup.prototype, "_slot", void 0);
|
|
5550
5550
|
RadioGroup = __decorate([safeCustomElement(`ixfx-radio-group`)], RadioGroup);
|
|
5551
5551
|
//#endregion
|
|
5552
|
+
//#region src/interaction/grouping.ts
|
|
5553
|
+
/** Label shown for the empty group key. */
|
|
5554
|
+
const EMPTY_GROUP_LABEL = `(none)`;
|
|
5555
|
+
/** Default header label: the key, or `(none)` for the empty key. */
|
|
5556
|
+
function defaultGroupLabel(key) {
|
|
5557
|
+
return key === `` ? EMPTY_GROUP_LABEL : key;
|
|
5558
|
+
}
|
|
5559
|
+
/** Coerce a raw group value to a key, as data-grid does. */
|
|
5560
|
+
function toGroupKey(value) {
|
|
5561
|
+
return String(value ?? ``);
|
|
5562
|
+
}
|
|
5563
|
+
/**
|
|
5564
|
+
* Group key for `item`. A string `groupBy` is resolved through `readNamed`
|
|
5565
|
+
* (property or `data-*` lookup, supplied by the host); a function is called.
|
|
5566
|
+
*/
|
|
5567
|
+
function resolveGroupKey(groupBy, item, index, readNamed) {
|
|
5568
|
+
if (typeof groupBy === `string`) return toGroupKey(readNamed(item, groupBy));
|
|
5569
|
+
return toGroupKey(groupBy(item, index));
|
|
5570
|
+
}
|
|
5571
|
+
/**
|
|
5572
|
+
* Split `items` into groups in first-encounter order. Single pass, O(n).
|
|
5573
|
+
* Item order within a group is preserved.
|
|
5574
|
+
*/
|
|
5575
|
+
function partitionByGroup(items, keyOf, labelOf) {
|
|
5576
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
5577
|
+
for (let i = 0; i < items.length; i++) {
|
|
5578
|
+
const key = keyOf(items[i], i);
|
|
5579
|
+
const existing = byKey.get(key);
|
|
5580
|
+
if (existing) existing.items.push(items[i]);
|
|
5581
|
+
else byKey.set(key, {
|
|
5582
|
+
key,
|
|
5583
|
+
items: [items[i]],
|
|
5584
|
+
firstIndex: i
|
|
5585
|
+
});
|
|
5586
|
+
}
|
|
5587
|
+
return [...byKey.values()].map((g) => ({
|
|
5588
|
+
key: g.key,
|
|
5589
|
+
items: g.items,
|
|
5590
|
+
firstIndex: g.firstIndex,
|
|
5591
|
+
label: labelOf ? labelOf(g.key, g.items) : defaultGroupLabel(g.key)
|
|
5592
|
+
}));
|
|
5593
|
+
}
|
|
5594
|
+
/** Immutable toggle of `key` in `set`. */
|
|
5595
|
+
function toggleInSet(set, key) {
|
|
5596
|
+
const next = new Set(set);
|
|
5597
|
+
if (next.has(key)) next.delete(key);
|
|
5598
|
+
else next.add(key);
|
|
5599
|
+
return next;
|
|
5600
|
+
}
|
|
5601
|
+
//#endregion
|
|
5552
5602
|
//#region src/interaction/list-drag-preview-default.ts
|
|
5553
5603
|
const CARD_DEFAULT = 72;
|
|
5554
5604
|
const CARD_MIN = 48;
|
|
@@ -6670,6 +6720,10 @@ var ListSelectionController = class {
|
|
|
6670
6720
|
if (next.has(item)) next.delete(item);
|
|
6671
6721
|
else {
|
|
6672
6722
|
if (!this.canSelectMultiple()) next.clear();
|
|
6723
|
+
if (this.#clamped()) {
|
|
6724
|
+
const g = this.#groupOf(item);
|
|
6725
|
+
for (const other of [...next]) if (this.#groupOf(other) !== g) next.delete(other);
|
|
6726
|
+
}
|
|
6673
6727
|
next.add(item);
|
|
6674
6728
|
}
|
|
6675
6729
|
this.#apply(next);
|
|
@@ -6688,6 +6742,22 @@ var ListSelectionController = class {
|
|
|
6688
6742
|
this.replace(item);
|
|
6689
6743
|
return;
|
|
6690
6744
|
}
|
|
6745
|
+
if (this.#clamped()) {
|
|
6746
|
+
const group = this.#groupOf(this.#anchor);
|
|
6747
|
+
if (group !== this.#groupOf(item)) {
|
|
6748
|
+
this.replace(item);
|
|
6749
|
+
return;
|
|
6750
|
+
}
|
|
6751
|
+
const inGroup = ordered.filter((t) => this.#groupOf(t) === group);
|
|
6752
|
+
const a = inGroup.indexOf(this.#anchor);
|
|
6753
|
+
const b = inGroup.indexOf(item);
|
|
6754
|
+
if (a === -1 || b === -1) {
|
|
6755
|
+
this.replace(item);
|
|
6756
|
+
return;
|
|
6757
|
+
}
|
|
6758
|
+
this.#apply(new Set(inGroup.slice(Math.min(a, b), Math.max(a, b) + 1).filter((t) => this.#config.isSelectable(t))));
|
|
6759
|
+
return;
|
|
6760
|
+
}
|
|
6691
6761
|
const start = Math.min(anchorIdx, targetIdx);
|
|
6692
6762
|
const end = Math.max(anchorIdx, targetIdx);
|
|
6693
6763
|
this.#apply(new Set(ordered.slice(start, end + 1).filter((t) => this.#config.isSelectable(t))));
|
|
@@ -6699,8 +6769,12 @@ var ListSelectionController = class {
|
|
|
6699
6769
|
}
|
|
6700
6770
|
/** Select every ordered item that passes `isSelectable`. */
|
|
6701
6771
|
selectAll() {
|
|
6702
|
-
|
|
6772
|
+
let ordered = this.#config.getOrderedItems();
|
|
6703
6773
|
if (ordered.length === 0) return;
|
|
6774
|
+
if (this.#clamped()) {
|
|
6775
|
+
const group = (this.#anchor === void 0 ? null : this.#groupOf(this.#anchor)) ?? this.#config.getFallbackGroupKey?.() ?? null;
|
|
6776
|
+
if (group !== null) ordered = ordered.filter((t) => this.#groupOf(t) === group);
|
|
6777
|
+
}
|
|
6704
6778
|
const next = new Set(ordered.filter((t) => this.#config.isSelectable(t)));
|
|
6705
6779
|
if (next.size === 0) return;
|
|
6706
6780
|
this.#apply(next);
|
|
@@ -6712,7 +6786,7 @@ var ListSelectionController = class {
|
|
|
6712
6786
|
selectMany(items) {
|
|
6713
6787
|
const { selectionMode } = this.#config.getModes();
|
|
6714
6788
|
if (selectionMode !== `multiple`) throw new Error(`selectMany requires selectionMode="multiple" (current: "${selectionMode}")`);
|
|
6715
|
-
const next = new Set([...items].filter((t) => this.#config.isSelectable(t)));
|
|
6789
|
+
const next = this.#clampToFirstGroup(new Set([...items].filter((t) => this.#config.isSelectable(t))));
|
|
6716
6790
|
if (next.size === 0) return;
|
|
6717
6791
|
this.#anchor = [...next].at(-1);
|
|
6718
6792
|
this.#apply(next);
|
|
@@ -6737,7 +6811,7 @@ var ListSelectionController = class {
|
|
|
6737
6811
|
*/
|
|
6738
6812
|
applyDragSelection(items) {
|
|
6739
6813
|
if (!this.canDragSelect()) return;
|
|
6740
|
-
const next = new Set([...items].filter((t) => this.#config.isSelectable(t)));
|
|
6814
|
+
const next = this.#clampToFirstGroup(new Set([...items].filter((t) => this.#config.isSelectable(t))));
|
|
6741
6815
|
if (next.size === 0 && this.#selected.size === 0) return;
|
|
6742
6816
|
this.#anchor = [...next].at(-1);
|
|
6743
6817
|
this.#apply(next);
|
|
@@ -6866,6 +6940,20 @@ var ListSelectionController = class {
|
|
|
6866
6940
|
this.#selected = new Set(items);
|
|
6867
6941
|
this.#anchor = anchor;
|
|
6868
6942
|
}
|
|
6943
|
+
/** Whether gestures must stay inside one group. */
|
|
6944
|
+
#clamped() {
|
|
6945
|
+
return this.#config.getGroupKey !== void 0 && !(this.#config.crossGroupSelection?.() ?? false);
|
|
6946
|
+
}
|
|
6947
|
+
#groupOf(item) {
|
|
6948
|
+
return this.#config.getGroupKey?.(item) ?? null;
|
|
6949
|
+
}
|
|
6950
|
+
/** Keep only items in the group of the first item (in display order) when clamped. */
|
|
6951
|
+
#clampToFirstGroup(items) {
|
|
6952
|
+
if (!this.#clamped() || items.size === 0) return new Set(items);
|
|
6953
|
+
const first = this.#config.getOrderedItems().find((t) => items.has(t)) ?? [...items][0];
|
|
6954
|
+
const group = this.#groupOf(first);
|
|
6955
|
+
return new Set([...items].filter((t) => this.#groupOf(t) === group));
|
|
6956
|
+
}
|
|
6869
6957
|
#apply(next) {
|
|
6870
6958
|
const previous = this.#selected;
|
|
6871
6959
|
this.#selected = next;
|
|
@@ -17173,8 +17261,125 @@ __decorate([state()], DataTableElement.prototype, "_detailIndex", void 0);
|
|
|
17173
17261
|
__decorate([state()], DataTableElement.prototype, "_stacked", void 0);
|
|
17174
17262
|
DataTableElement = __decorate([safeCustomElement(`ixfx-data-table`)], DataTableElement);
|
|
17175
17263
|
//#endregion
|
|
17264
|
+
//#region src/list-group-header/list-group-header.ts
|
|
17265
|
+
let ListGroupHeaderElement = class ListGroupHeaderElement extends LitElement {
|
|
17266
|
+
constructor(..._args) {
|
|
17267
|
+
super(..._args);
|
|
17268
|
+
this.label = ``;
|
|
17269
|
+
this.count = 0;
|
|
17270
|
+
this.collapsed = false;
|
|
17271
|
+
this.orientation = `horizontal`;
|
|
17272
|
+
}
|
|
17273
|
+
static {
|
|
17274
|
+
this.styles = css`
|
|
17275
|
+
:host {
|
|
17276
|
+
--_height: var(--list-group-header-height, 28px);
|
|
17277
|
+
--_border: var(--list-group-header-border, var(--border));
|
|
17278
|
+
|
|
17279
|
+
display: flex;
|
|
17280
|
+
align-items: center;
|
|
17281
|
+
gap: var(--space-s);
|
|
17282
|
+
box-sizing: border-box;
|
|
17283
|
+
min-height: var(--_height);
|
|
17284
|
+
padding: 0 var(--space-s);
|
|
17285
|
+
background: transparent;
|
|
17286
|
+
color: var(--list-group-header-text, var(--surface-3-text));
|
|
17287
|
+
border-bottom: 1px solid var(--_border);
|
|
17288
|
+
font-weight: 600;
|
|
17289
|
+
cursor: pointer;
|
|
17290
|
+
user-select: none;
|
|
17291
|
+
}
|
|
17292
|
+
|
|
17293
|
+
.caret {
|
|
17294
|
+
display: inline-flex;
|
|
17295
|
+
transition: transform 0.15s;
|
|
17296
|
+
}
|
|
17297
|
+
|
|
17298
|
+
:host([collapsed]) .caret {
|
|
17299
|
+
transform: rotate(-90deg);
|
|
17300
|
+
}
|
|
17301
|
+
|
|
17302
|
+
.count {
|
|
17303
|
+
opacity: 0.6;
|
|
17304
|
+
font-weight: 400;
|
|
17305
|
+
font-size: 0.9em;
|
|
17306
|
+
}
|
|
17307
|
+
|
|
17308
|
+
.label {
|
|
17309
|
+
overflow: hidden;
|
|
17310
|
+
text-overflow: ellipsis;
|
|
17311
|
+
white-space: nowrap;
|
|
17312
|
+
min-width: 0;
|
|
17313
|
+
}
|
|
17314
|
+
|
|
17315
|
+
.divider {
|
|
17316
|
+
flex: 1;
|
|
17317
|
+
height: 1px;
|
|
17318
|
+
background: var(--_border);
|
|
17319
|
+
margin-left: var(--space-s);
|
|
17320
|
+
}
|
|
17321
|
+
|
|
17322
|
+
/* Single-row (grid-list \`row\` orientation) layout: a narrow column cell. */
|
|
17323
|
+
:host([orientation="vertical"]) {
|
|
17324
|
+
flex-direction: column;
|
|
17325
|
+
justify-content: flex-start;
|
|
17326
|
+
padding: var(--space-s) 0;
|
|
17327
|
+
border-bottom: 0;
|
|
17328
|
+
border-right: 1px solid var(--_border);
|
|
17329
|
+
min-height: 0;
|
|
17330
|
+
}
|
|
17331
|
+
|
|
17332
|
+
:host([orientation="vertical"]) .divider {
|
|
17333
|
+
width: 1px;
|
|
17334
|
+
height: auto;
|
|
17335
|
+
margin-left: 0;
|
|
17336
|
+
margin-top: var(--space-s);
|
|
17337
|
+
}
|
|
17338
|
+
|
|
17339
|
+
@media (prefers-reduced-motion: reduce) {
|
|
17340
|
+
.caret { transition: none; }
|
|
17341
|
+
}
|
|
17342
|
+
`;
|
|
17343
|
+
}
|
|
17344
|
+
connectedCallback() {
|
|
17345
|
+
super.connectedCallback();
|
|
17346
|
+
this.setAttribute(`role`, `button`);
|
|
17347
|
+
}
|
|
17348
|
+
willUpdate() {
|
|
17349
|
+
this.setAttribute(`aria-expanded`, this.collapsed ? `false` : `true`);
|
|
17350
|
+
this.setAttribute(`aria-label`, `${this.label}, ${this.count} ${this.count === 1 ? `item` : `items`}`);
|
|
17351
|
+
}
|
|
17352
|
+
render() {
|
|
17353
|
+
return html`
|
|
17354
|
+
<span class="caret"><ixfx-icon name="chevron-down" size="12"></ixfx-icon></span>
|
|
17355
|
+
<span class="label" part="label">${this.label}</span>
|
|
17356
|
+
<span class="count" part="count">(${this.count})</span>
|
|
17357
|
+
<span class="divider" part="divider"></span>
|
|
17358
|
+
`;
|
|
17359
|
+
}
|
|
17360
|
+
};
|
|
17361
|
+
__decorate([property({
|
|
17362
|
+
type: String,
|
|
17363
|
+
reflect: true
|
|
17364
|
+
})], ListGroupHeaderElement.prototype, "label", void 0);
|
|
17365
|
+
__decorate([property({
|
|
17366
|
+
type: Number,
|
|
17367
|
+
reflect: true
|
|
17368
|
+
})], ListGroupHeaderElement.prototype, "count", void 0);
|
|
17369
|
+
__decorate([property({
|
|
17370
|
+
type: Boolean,
|
|
17371
|
+
reflect: true
|
|
17372
|
+
})], ListGroupHeaderElement.prototype, "collapsed", void 0);
|
|
17373
|
+
__decorate([property({
|
|
17374
|
+
type: String,
|
|
17375
|
+
reflect: true
|
|
17376
|
+
})], ListGroupHeaderElement.prototype, "orientation", void 0);
|
|
17377
|
+
ListGroupHeaderElement = __decorate([safeCustomElement(`ixfx-list-group-header`)], ListGroupHeaderElement);
|
|
17378
|
+
//#endregion
|
|
17176
17379
|
//#region src/detail-list/detail-list.ts
|
|
17177
17380
|
const ITEM_SELECTOR$3 = `:scope > li`;
|
|
17381
|
+
const GROUP_HEADER_ATTR = `data-ixfx-group-header`;
|
|
17382
|
+
const GROUP_COLLAPSED_ATTR = `data-group-collapsed`;
|
|
17178
17383
|
const SEARCH_HIGHLIGHT_KEY = `detail-list-search`;
|
|
17179
17384
|
const NAV_KEYS = /* @__PURE__ */ new Set([
|
|
17180
17385
|
`ArrowDown`,
|
|
@@ -17232,14 +17437,26 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17232
17437
|
this.keyProperty = ``;
|
|
17233
17438
|
this.itemWrap = `stop`;
|
|
17234
17439
|
this.itemsDraggable = false;
|
|
17440
|
+
this.groupBy = null;
|
|
17441
|
+
this.crossGroupSelection = false;
|
|
17442
|
+
this._collapsedGroups = /* @__PURE__ */ new Set();
|
|
17235
17443
|
this.#itemData = /* @__PURE__ */ new WeakMap();
|
|
17236
17444
|
this.#grid = [];
|
|
17237
17445
|
this.#positions = /* @__PURE__ */ new Map();
|
|
17446
|
+
this.#tops = /* @__PURE__ */ new Map();
|
|
17238
17447
|
this.#geometryScheduled = false;
|
|
17239
17448
|
this.#sortRaf = 0;
|
|
17240
17449
|
this.#viewportScrollRaf = 0;
|
|
17241
17450
|
this.#animatedItems = /* @__PURE__ */ new WeakSet();
|
|
17242
17451
|
this.#builtFromProvider = [];
|
|
17452
|
+
this.#groupIndex = /* @__PURE__ */ new Map();
|
|
17453
|
+
this.#groupList = [];
|
|
17454
|
+
this.#headerEls = /* @__PURE__ */ new Map();
|
|
17455
|
+
this.#seq = /* @__PURE__ */ new WeakMap();
|
|
17456
|
+
this.#seqNext = 0;
|
|
17457
|
+
this.#wasGrouped = false;
|
|
17458
|
+
this.#groupsScheduled = false;
|
|
17459
|
+
this.#groupByChanged = false;
|
|
17243
17460
|
this.#providerBuilt = 0;
|
|
17244
17461
|
this.#data = new DataController(this);
|
|
17245
17462
|
this.selection = new ListSelectionController({
|
|
@@ -17250,6 +17467,12 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17250
17467
|
interactionMode: this.interactionMode
|
|
17251
17468
|
}),
|
|
17252
17469
|
getKey: keyForElement,
|
|
17470
|
+
getGroupKey: (el) => this.#groupIndex.get(el) ?? null,
|
|
17471
|
+
crossGroupSelection: () => this.crossGroupSelection,
|
|
17472
|
+
getFallbackGroupKey: () => {
|
|
17473
|
+
const t = this.tickled.tickledId;
|
|
17474
|
+
return t ? this.#groupIndex.get(t) ?? null : null;
|
|
17475
|
+
},
|
|
17253
17476
|
onChange: (selected, previous) => {
|
|
17254
17477
|
this._syncItemStates();
|
|
17255
17478
|
this._dispatch(`list-select`, {
|
|
@@ -17331,6 +17554,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17331
17554
|
if (this._listEl) this._listEl.scrollLeft += dx;
|
|
17332
17555
|
},
|
|
17333
17556
|
shouldStart: (event) => {
|
|
17557
|
+
if (this.#findGroupHeader(event.composedPath())) return false;
|
|
17334
17558
|
this.#blankItemPressPending = this.itemsDraggable && this.#isBlankItemPress(event);
|
|
17335
17559
|
return !this.itemsDraggable || this.#blankItemPressPending;
|
|
17336
17560
|
}
|
|
@@ -17422,7 +17646,13 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17422
17646
|
};
|
|
17423
17647
|
this._onClick = (e) => {
|
|
17424
17648
|
if (this.#dragSelect.isDragging || this.#nativeDrag.isDragging || this.#postDragSuppressTimer !== 0) return;
|
|
17425
|
-
const
|
|
17649
|
+
const path = e.composedPath();
|
|
17650
|
+
const header = this.#findGroupHeader(path);
|
|
17651
|
+
if (header) {
|
|
17652
|
+
this.toggleGroup(header.dataset.groupKey ?? ``);
|
|
17653
|
+
return;
|
|
17654
|
+
}
|
|
17655
|
+
const item = this._findListItem(path);
|
|
17426
17656
|
if (!item) return;
|
|
17427
17657
|
this.focus();
|
|
17428
17658
|
this._dispatch(`list-item-click`, { item });
|
|
@@ -17441,6 +17671,8 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17441
17671
|
#itemData;
|
|
17442
17672
|
#grid;
|
|
17443
17673
|
#positions;
|
|
17674
|
+
/** Viewport-relative `top` per item at the last geometry pass — lines rows up across columns. */
|
|
17675
|
+
#tops;
|
|
17444
17676
|
#geometryScheduled;
|
|
17445
17677
|
#sortRaf;
|
|
17446
17678
|
#viewportScrollRaf;
|
|
@@ -17452,6 +17684,17 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17452
17684
|
/** Items that have already played (or been skipped for) their enter animation. */
|
|
17453
17685
|
#animatedItems;
|
|
17454
17686
|
#builtFromProvider;
|
|
17687
|
+
/** Element → group key, for the selection controller. Empty while ungrouped. */
|
|
17688
|
+
#groupIndex;
|
|
17689
|
+
#groupList;
|
|
17690
|
+
#headerEls;
|
|
17691
|
+
/** Insertion sequence per item, so regrouping starts from the original order. */
|
|
17692
|
+
#seq;
|
|
17693
|
+
#seqNext;
|
|
17694
|
+
#wasGrouped;
|
|
17695
|
+
#groupsScheduled;
|
|
17696
|
+
#groupByChanged;
|
|
17697
|
+
#groupObserver;
|
|
17455
17698
|
#providerBuilt;
|
|
17456
17699
|
#data;
|
|
17457
17700
|
#nativeDragging;
|
|
@@ -17568,6 +17811,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17568
17811
|
this.#processChildren();
|
|
17569
17812
|
this.#animateChildMutations(records);
|
|
17570
17813
|
this.#scheduleGeometry();
|
|
17814
|
+
this.#scheduleGroups();
|
|
17571
17815
|
});
|
|
17572
17816
|
this.#mutationObserver.observe(this, {
|
|
17573
17817
|
childList: true,
|
|
@@ -17577,6 +17821,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17577
17821
|
for (const el of this.querySelectorAll(ITEM_SELECTOR$3)) this.#animatedItems.add(el);
|
|
17578
17822
|
this.#searchRegistry ??= createCommandRegistry();
|
|
17579
17823
|
this.#syncSearchCommands();
|
|
17824
|
+
this.#scheduleGroups();
|
|
17580
17825
|
}
|
|
17581
17826
|
/**
|
|
17582
17827
|
* Collapse-in items appended to the light DOM (however they got there). A bulk
|
|
@@ -17618,6 +17863,8 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17618
17863
|
this.#resizeObserver = void 0;
|
|
17619
17864
|
this.#mutationObserver?.disconnect();
|
|
17620
17865
|
this.#mutationObserver = void 0;
|
|
17866
|
+
this.#groupObserver?.disconnect();
|
|
17867
|
+
this.#groupObserver = void 0;
|
|
17621
17868
|
this.#unregisterSearchCommands?.();
|
|
17622
17869
|
this.#unregisterSearchCommands = void 0;
|
|
17623
17870
|
this.#searchRegistry = void 0;
|
|
@@ -17632,8 +17879,22 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17632
17879
|
this.#recomputeGeometry();
|
|
17633
17880
|
this._syncNativeDraggable();
|
|
17634
17881
|
}
|
|
17882
|
+
willUpdate(changed) {
|
|
17883
|
+
super.willUpdate(changed);
|
|
17884
|
+
if (changed.has(`groupBy`) && this.hasUpdated) {
|
|
17885
|
+
if (this._collapsedGroups.size > 0) this._collapsedGroups = /* @__PURE__ */ new Set();
|
|
17886
|
+
this.#groupByChanged = true;
|
|
17887
|
+
}
|
|
17888
|
+
}
|
|
17635
17889
|
updated(changed) {
|
|
17636
17890
|
super.updated(changed);
|
|
17891
|
+
if (changed.has(`groupBy`) || changed.has(`groupLabel`) || changed.has(`_collapsedGroups`)) {
|
|
17892
|
+
this.#scheduleGroups();
|
|
17893
|
+
if (this.#groupByChanged) {
|
|
17894
|
+
this.#groupByChanged = false;
|
|
17895
|
+
this._dispatch(`list-group-change`, { groupBy: this.groupBy });
|
|
17896
|
+
}
|
|
17897
|
+
}
|
|
17637
17898
|
if (changed.has(`searchModes`)) this.#syncSearchCommands();
|
|
17638
17899
|
if (changed.has(`provider`)) {
|
|
17639
17900
|
this.#builtFromProvider = [];
|
|
@@ -17650,6 +17911,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17650
17911
|
if (changed.has(`filterPredicate`)) {
|
|
17651
17912
|
this.#applyFilterPredicate();
|
|
17652
17913
|
this.#scheduleGeometry();
|
|
17914
|
+
this.#scheduleGroups();
|
|
17653
17915
|
}
|
|
17654
17916
|
if (changed.has(`interactionMode`)) {
|
|
17655
17917
|
this.selection.clearAnchor();
|
|
@@ -17689,6 +17951,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17689
17951
|
this.#ensureIcon(el);
|
|
17690
17952
|
if (this.sort !== `none`) this.#applySort();
|
|
17691
17953
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
17954
|
+
this.#scheduleGroups();
|
|
17692
17955
|
}
|
|
17693
17956
|
/**
|
|
17694
17957
|
* Collapse + fade `item` out, then detach it; the rows after it slide up to
|
|
@@ -17698,6 +17961,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17698
17961
|
this.selection.deselect(item);
|
|
17699
17962
|
return animateListItemOut(item).then(() => {
|
|
17700
17963
|
item.remove();
|
|
17964
|
+
this.#scheduleGroups();
|
|
17701
17965
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
17702
17966
|
this.#recomputeGeometry();
|
|
17703
17967
|
});
|
|
@@ -17708,6 +17972,8 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17708
17972
|
}
|
|
17709
17973
|
clearItems() {
|
|
17710
17974
|
this.replaceChildren();
|
|
17975
|
+
this.#headerEls.clear();
|
|
17976
|
+
this.#scheduleGroups();
|
|
17711
17977
|
this.selection.reset();
|
|
17712
17978
|
this.#builtFromProvider = [];
|
|
17713
17979
|
this.#providerBuilt = 0;
|
|
@@ -17725,6 +17991,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17725
17991
|
}
|
|
17726
17992
|
if (this.sort !== `none`) this.#applySort();
|
|
17727
17993
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
17994
|
+
this.#scheduleGroups();
|
|
17728
17995
|
}
|
|
17729
17996
|
/**
|
|
17730
17997
|
* Get the source object behind an `<li>` built from an `items` array or
|
|
@@ -17844,6 +18111,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17844
18111
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
17845
18112
|
this._syncItemStates();
|
|
17846
18113
|
this.#scheduleGeometry();
|
|
18114
|
+
this.#scheduleGroups();
|
|
17847
18115
|
}
|
|
17848
18116
|
#createItemEl(item, index) {
|
|
17849
18117
|
const li = document.createElement(`li`);
|
|
@@ -17895,6 +18163,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17895
18163
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
17896
18164
|
this._syncItemStates();
|
|
17897
18165
|
this.#scheduleGeometry();
|
|
18166
|
+
this.#scheduleGroups();
|
|
17898
18167
|
} else {
|
|
17899
18168
|
this.#providerBuilt = 0;
|
|
17900
18169
|
this.#rebuildFromObjects(items);
|
|
@@ -17913,6 +18182,16 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17913
18182
|
if (this.sort === `none`) return;
|
|
17914
18183
|
const rows = [...this.querySelectorAll(ITEM_SELECTOR$3)];
|
|
17915
18184
|
if (rows.length < 2) return;
|
|
18185
|
+
if (this.#groupingActive()) {
|
|
18186
|
+
this.#scheduleGroups();
|
|
18187
|
+
return;
|
|
18188
|
+
}
|
|
18189
|
+
for (const el of this.#sortRows(rows)) this.appendChild(el);
|
|
18190
|
+
this.#scheduleGeometry();
|
|
18191
|
+
this.#scheduleGroups();
|
|
18192
|
+
}
|
|
18193
|
+
/** Stable sort of `rows` by the current `sort` / `sortBy` / `sortComparator`. */
|
|
18194
|
+
#sortRows(rows) {
|
|
17916
18195
|
const dir = this.sort === `descending` ? -1 : 1;
|
|
17917
18196
|
const meta = (el) => ({
|
|
17918
18197
|
element: el,
|
|
@@ -17942,9 +18221,147 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17942
18221
|
i
|
|
17943
18222
|
}));
|
|
17944
18223
|
indexed.sort((a, b) => cmp(a.el, b.el) * dir || a.i - b.i);
|
|
17945
|
-
|
|
18224
|
+
return indexed.map(({ el }) => el);
|
|
18225
|
+
}
|
|
18226
|
+
#groupingActive() {
|
|
18227
|
+
return this.groupBy !== null && this.groupBy !== void 0 && this.groupBy !== ``;
|
|
18228
|
+
}
|
|
18229
|
+
/** Coalesce regrouping to one pass per microtask (streaming batches, search keystrokes). */
|
|
18230
|
+
#scheduleGroups() {
|
|
18231
|
+
if (this.#groupsScheduled || !this.#groupingActive() && !this.#wasGrouped) return;
|
|
18232
|
+
this.#groupsScheduled = true;
|
|
18233
|
+
queueMicrotask(() => {
|
|
18234
|
+
this.#groupsScheduled = false;
|
|
18235
|
+
this.#syncGroups();
|
|
18236
|
+
});
|
|
18237
|
+
}
|
|
18238
|
+
#groupValue(el, name) {
|
|
18239
|
+
return this.#propertyValue(this.getItemData(el), name) ?? el.getAttribute(`data-${name}`);
|
|
18240
|
+
}
|
|
18241
|
+
#groupKeyOf(el) {
|
|
18242
|
+
const by = this.groupBy;
|
|
18243
|
+
if (typeof by === `string`) return toGroupKey(this.#groupValue(el, by));
|
|
18244
|
+
return toGroupKey(by(this.getItemData(el), el));
|
|
18245
|
+
}
|
|
18246
|
+
#isItemVisible(el) {
|
|
18247
|
+
return !el.hidden && (!this.filterPredicate || this.filterPredicate(el));
|
|
18248
|
+
}
|
|
18249
|
+
#headerFor(key) {
|
|
18250
|
+
let header = this.#headerEls.get(key);
|
|
18251
|
+
if (!header) {
|
|
18252
|
+
header = document.createElement(`ixfx-list-group-header`);
|
|
18253
|
+
header.setAttribute(GROUP_HEADER_ATTR, ``);
|
|
18254
|
+
header.dataset.groupKey = key;
|
|
18255
|
+
this.#headerEls.set(key, header);
|
|
18256
|
+
}
|
|
18257
|
+
return header;
|
|
18258
|
+
}
|
|
18259
|
+
/**
|
|
18260
|
+
* Bring the light DOM into grouped order: original order → sort → partition
|
|
18261
|
+
* into contiguous groups, each preceded by a header row. Idempotent — it only
|
|
18262
|
+
* touches the DOM when the order actually changes, so it never loops through
|
|
18263
|
+
* the mutation observer. Ungrouping restores the original (sorted) order.
|
|
18264
|
+
*/
|
|
18265
|
+
#syncGroups() {
|
|
18266
|
+
const active = this.#groupingActive();
|
|
18267
|
+
if (!active && !this.#wasGrouped) return;
|
|
18268
|
+
const items = [...this.querySelectorAll(ITEM_SELECTOR$3)];
|
|
18269
|
+
for (const el of items) if (!this.#seq.has(el)) this.#seq.set(el, this.#seqNext++);
|
|
18270
|
+
let ordered = items.toSorted((a, b) => this.#seq.get(a) - this.#seq.get(b));
|
|
18271
|
+
if (this.sort !== `none` && ordered.length > 1) ordered = this.#sortRows(ordered);
|
|
18272
|
+
const nodes = [];
|
|
18273
|
+
const info = [];
|
|
18274
|
+
const index = /* @__PURE__ */ new Map();
|
|
18275
|
+
const liveHeaders = /* @__PURE__ */ new Set();
|
|
18276
|
+
if (active) {
|
|
18277
|
+
const label = this.groupLabel;
|
|
18278
|
+
const parts = partitionByGroup(ordered, (el) => this.#groupKeyOf(el), label ? (key, els) => label(key, els.map((el) => this.getItemData(el) ?? el)) : void 0);
|
|
18279
|
+
for (const part of parts) {
|
|
18280
|
+
const count = part.items.filter((el) => this.#isItemVisible(el)).length;
|
|
18281
|
+
const collapsed = count > 0 && this._collapsedGroups.has(part.key);
|
|
18282
|
+
if (count > 0) {
|
|
18283
|
+
const header = this.#headerFor(part.key);
|
|
18284
|
+
header.label = part.label;
|
|
18285
|
+
header.count = count;
|
|
18286
|
+
header.collapsed = collapsed;
|
|
18287
|
+
liveHeaders.add(part.key);
|
|
18288
|
+
nodes.push(header);
|
|
18289
|
+
info.push({
|
|
18290
|
+
key: part.key,
|
|
18291
|
+
label: part.label,
|
|
18292
|
+
count,
|
|
18293
|
+
collapsed: this._collapsedGroups.has(part.key)
|
|
18294
|
+
});
|
|
18295
|
+
}
|
|
18296
|
+
for (const el of part.items) {
|
|
18297
|
+
index.set(el, part.key);
|
|
18298
|
+
el.toggleAttribute(GROUP_COLLAPSED_ATTR, collapsed);
|
|
18299
|
+
nodes.push(el);
|
|
18300
|
+
}
|
|
18301
|
+
}
|
|
18302
|
+
} else {
|
|
18303
|
+
for (const el of ordered) el.removeAttribute(GROUP_COLLAPSED_ATTR);
|
|
18304
|
+
nodes.push(...ordered);
|
|
18305
|
+
}
|
|
18306
|
+
for (const [key, header] of this.#headerEls) if (!liveHeaders.has(key)) {
|
|
18307
|
+
header.remove();
|
|
18308
|
+
this.#headerEls.delete(key);
|
|
18309
|
+
}
|
|
18310
|
+
this.#groupIndex = index;
|
|
18311
|
+
this.#groupList = info;
|
|
18312
|
+
this.#wasGrouped = active;
|
|
18313
|
+
const current = [...this.children].filter((c) => c.matches(`li`) || c.hasAttribute(GROUP_HEADER_ATTR));
|
|
18314
|
+
if (current.length !== nodes.length || current.some((c, i) => c !== nodes[i])) this.append(...nodes);
|
|
18315
|
+
if (this.tickled.tickledId?.hasAttribute(GROUP_COLLAPSED_ATTR)) this.tickled.focus(void 0);
|
|
18316
|
+
this.#syncGroupObserver(active);
|
|
17946
18317
|
this.#scheduleGeometry();
|
|
17947
18318
|
}
|
|
18319
|
+
/** Filter-search hides rows via `hidden` on the `<li>`s — regroup when that changes. */
|
|
18320
|
+
#syncGroupObserver(active) {
|
|
18321
|
+
if (!active) {
|
|
18322
|
+
this.#groupObserver?.disconnect();
|
|
18323
|
+
this.#groupObserver = void 0;
|
|
18324
|
+
return;
|
|
18325
|
+
}
|
|
18326
|
+
if (this.#groupObserver || !this.isConnected) return;
|
|
18327
|
+
this.#groupObserver = new MutationObserver(() => this.#scheduleGroups());
|
|
18328
|
+
this.#groupObserver.observe(this, {
|
|
18329
|
+
subtree: true,
|
|
18330
|
+
attributes: true,
|
|
18331
|
+
attributeFilter: [`hidden`]
|
|
18332
|
+
});
|
|
18333
|
+
}
|
|
18334
|
+
/** Groups in display order (empty when ungrouped). */
|
|
18335
|
+
get groups() {
|
|
18336
|
+
return this.#groupList;
|
|
18337
|
+
}
|
|
18338
|
+
/** Collapse or expand one group. Fires `list-group-toggle` when the state changes. */
|
|
18339
|
+
setGroupCollapsed(groupKey, collapsed) {
|
|
18340
|
+
if (this._collapsedGroups.has(groupKey) === collapsed) return;
|
|
18341
|
+
const next = new Set(this._collapsedGroups);
|
|
18342
|
+
if (collapsed) next.add(groupKey);
|
|
18343
|
+
else next.delete(groupKey);
|
|
18344
|
+
this._collapsedGroups = next;
|
|
18345
|
+
this._dispatch(`list-group-toggle`, {
|
|
18346
|
+
groupKey,
|
|
18347
|
+
collapsed
|
|
18348
|
+
});
|
|
18349
|
+
}
|
|
18350
|
+
toggleGroup(groupKey) {
|
|
18351
|
+
this.setGroupCollapsed(groupKey, !this._collapsedGroups.has(groupKey));
|
|
18352
|
+
}
|
|
18353
|
+
collapseAllGroups() {
|
|
18354
|
+
for (const g of this.#groupList) this.setGroupCollapsed(g.key, true);
|
|
18355
|
+
}
|
|
18356
|
+
expandAllGroups() {
|
|
18357
|
+
for (const key of [...this._collapsedGroups]) this.setGroupCollapsed(key, false);
|
|
18358
|
+
}
|
|
18359
|
+
#findGroupHeader(path) {
|
|
18360
|
+
for (const target of path) {
|
|
18361
|
+
if (target === this) break;
|
|
18362
|
+
if (target instanceof HTMLElement && target.parentElement === this && target.hasAttribute(GROUP_HEADER_ATTR)) return target;
|
|
18363
|
+
}
|
|
18364
|
+
}
|
|
17948
18365
|
#scheduleGeometry() {
|
|
17949
18366
|
if (this.#geometryScheduled) return;
|
|
17950
18367
|
this.#geometryScheduled = true;
|
|
@@ -17956,11 +18373,13 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
17956
18373
|
#recomputeGeometry() {
|
|
17957
18374
|
this.#grid = [];
|
|
17958
18375
|
this.#positions.clear();
|
|
18376
|
+
this.#tops.clear();
|
|
17959
18377
|
if (!this.isConnected) return;
|
|
17960
18378
|
const columns = [];
|
|
17961
18379
|
for (const el of this._getVisibleItems()) {
|
|
17962
18380
|
const rect = el.getBoundingClientRect();
|
|
17963
18381
|
if (rect.width === 0 && rect.height === 0) continue;
|
|
18382
|
+
this.#tops.set(el, rect.top);
|
|
17964
18383
|
let ci = columns.findIndex((c) => Math.abs(c.left - rect.left) <= 1);
|
|
17965
18384
|
if (ci === -1) {
|
|
17966
18385
|
columns.push({
|
|
@@ -18081,6 +18500,30 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
18081
18500
|
const next = this.#findNextCheckable(cur.col, cur.row, 0, -1);
|
|
18082
18501
|
if (next) this.#navigateTo(next);
|
|
18083
18502
|
}
|
|
18503
|
+
/**
|
|
18504
|
+
* Left/Right target. Ungrouped lists keep the row-index rule. Grouped lists
|
|
18505
|
+
* have headers at arbitrary heights, so an item's row index no longer equals
|
|
18506
|
+
* its visual row — pick the item in the neighbouring column whose top is
|
|
18507
|
+
* nearest the cursor's (ties go to the upper one).
|
|
18508
|
+
*/
|
|
18509
|
+
#horizontalTarget(from, dir) {
|
|
18510
|
+
if (this.#groupList.length === 0) return this.#findNextCheckable(from.col, from.row, dir, 0);
|
|
18511
|
+
const column = this.#grid[from.col + dir];
|
|
18512
|
+
const current = this.tickled.tickledId;
|
|
18513
|
+
const top = current ? this.#tops.get(current) : void 0;
|
|
18514
|
+
if (!column || top === void 0) return void 0;
|
|
18515
|
+
let best;
|
|
18516
|
+
let bestDelta = Number.POSITIVE_INFINITY;
|
|
18517
|
+
for (const el of column) {
|
|
18518
|
+
if (!this._isCheckable(el)) continue;
|
|
18519
|
+
const delta = Math.abs((this.#tops.get(el) ?? Number.POSITIVE_INFINITY) - top);
|
|
18520
|
+
if (delta < bestDelta) {
|
|
18521
|
+
best = el;
|
|
18522
|
+
bestDelta = delta;
|
|
18523
|
+
}
|
|
18524
|
+
}
|
|
18525
|
+
return best;
|
|
18526
|
+
}
|
|
18084
18527
|
#navigateRight() {
|
|
18085
18528
|
this.#recomputeGeometry();
|
|
18086
18529
|
const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : void 0;
|
|
@@ -18088,7 +18531,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
18088
18531
|
this.#navigateTo(this.#findFirstCheckable());
|
|
18089
18532
|
return;
|
|
18090
18533
|
}
|
|
18091
|
-
const next = this.#
|
|
18534
|
+
const next = this.#horizontalTarget(cur, 1);
|
|
18092
18535
|
if (next) this.#navigateTo(next);
|
|
18093
18536
|
else if (this.itemWrap === `wrap`) this.#navigateTo(this.#findFirstCheckable());
|
|
18094
18537
|
}
|
|
@@ -18099,13 +18542,14 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
18099
18542
|
this.#navigateTo(this.#findFirstCheckable());
|
|
18100
18543
|
return;
|
|
18101
18544
|
}
|
|
18102
|
-
const next = this.#
|
|
18545
|
+
const next = this.#horizontalTarget(cur, -1);
|
|
18103
18546
|
if (next) this.#navigateTo(next);
|
|
18104
18547
|
else if (this.itemWrap === `wrap`) this.#navigateTo(this.#findLastCheckable());
|
|
18105
18548
|
}
|
|
18106
18549
|
_getVisibleItems() {
|
|
18107
18550
|
return Array.from(this.querySelectorAll(ITEM_SELECTOR$3)).filter((el) => {
|
|
18108
18551
|
if (el.hidden) return false;
|
|
18552
|
+
if (el.hasAttribute(GROUP_COLLAPSED_ATTR)) return false;
|
|
18109
18553
|
if (this.filterPredicate && !this.filterPredicate(el)) return false;
|
|
18110
18554
|
return true;
|
|
18111
18555
|
});
|
|
@@ -18394,6 +18838,20 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
18394
18838
|
display: none !important;
|
|
18395
18839
|
}
|
|
18396
18840
|
|
|
18841
|
+
/* Rows of a collapsed group leave the flow; their header stays. */
|
|
18842
|
+
::slotted([data-group-collapsed]) {
|
|
18843
|
+
display: none !important;
|
|
18844
|
+
}
|
|
18845
|
+
|
|
18846
|
+
/* Group headers are rows in the column flow, the same size as an item. */
|
|
18847
|
+
::slotted(ixfx-list-group-header) {
|
|
18848
|
+
box-sizing: border-box;
|
|
18849
|
+
flex: none;
|
|
18850
|
+
width: var(--detail-list-column-width, 220px);
|
|
18851
|
+
height: var(--detail-list-item-height, 28px);
|
|
18852
|
+
--list-group-header-height: var(--detail-list-group-header-height, var(--detail-list-item-height, 28px));
|
|
18853
|
+
}
|
|
18854
|
+
|
|
18397
18855
|
::slotted(li) {
|
|
18398
18856
|
box-sizing: border-box;
|
|
18399
18857
|
display: flex;
|
|
@@ -18570,6 +19028,14 @@ __decorate([property({
|
|
|
18570
19028
|
})], DetailListElement.prototype, "itemsDraggable", void 0);
|
|
18571
19029
|
__decorate([property({ attribute: false })], DetailListElement.prototype, "dragPreviewRenderer", void 0);
|
|
18572
19030
|
__decorate([property({ attribute: false })], DetailListElement.prototype, "dragPreviewSource", void 0);
|
|
19031
|
+
__decorate([property({ attribute: `group-by` })], DetailListElement.prototype, "groupBy", void 0);
|
|
19032
|
+
__decorate([property({ attribute: false })], DetailListElement.prototype, "groupLabel", void 0);
|
|
19033
|
+
__decorate([property({
|
|
19034
|
+
type: Boolean,
|
|
19035
|
+
attribute: `cross-group-selection`,
|
|
19036
|
+
reflect: true
|
|
19037
|
+
})], DetailListElement.prototype, "crossGroupSelection", void 0);
|
|
19038
|
+
__decorate([state()], DetailListElement.prototype, "_collapsedGroups", void 0);
|
|
18573
19039
|
__decorate([query(`ul`)], DetailListElement.prototype, "_listEl", void 0);
|
|
18574
19040
|
DetailListElement = __decorate([safeCustomElement(`ixfx-detail-list`)], DetailListElement);
|
|
18575
19041
|
//#endregion
|
|
@@ -24209,7 +24675,374 @@ let FormElement = class FormElement extends LitElement {
|
|
|
24209
24675
|
};
|
|
24210
24676
|
FormElement = __decorate([safeCustomElement(`ixfx-form`)], FormElement);
|
|
24211
24677
|
//#endregion
|
|
24678
|
+
//#region src/grid-list/grid-list-layout.ts
|
|
24679
|
+
/**
|
|
24680
|
+
* `itemWidth` is the square's width; `rowHeight` is the full cell height
|
|
24681
|
+
* (square, plus the caption band in `separate` / `under` styles).
|
|
24682
|
+
* `scrollOffset` is `scrollTop` for `grid`/`column` and `scrollLeft` for `row`.
|
|
24683
|
+
*/
|
|
24684
|
+
function computeGridWindow(count, itemWidth, rowHeight, gap, viewportWidth, viewportHeight, scrollOffset, orientation, overscan = 2) {
|
|
24685
|
+
const w = Math.max(1, itemWidth);
|
|
24686
|
+
const h = Math.max(1, rowHeight);
|
|
24687
|
+
const g = Math.max(0, gap);
|
|
24688
|
+
const colStride = w + g;
|
|
24689
|
+
const rowStride = h + g;
|
|
24690
|
+
const offset = Math.max(0, scrollOffset);
|
|
24691
|
+
if (orientation === `row`) {
|
|
24692
|
+
const rows = count === 0 ? 0 : 1;
|
|
24693
|
+
const totalWidth = count === 0 ? 0 : (count - 1) * colStride + w;
|
|
24694
|
+
if (count === 0 || viewportWidth <= 0) return {
|
|
24695
|
+
cols: count,
|
|
24696
|
+
rows,
|
|
24697
|
+
totalHeight: 0,
|
|
24698
|
+
totalWidth,
|
|
24699
|
+
startIndex: 0,
|
|
24700
|
+
endIndex: 0,
|
|
24701
|
+
colStride,
|
|
24702
|
+
rowStride,
|
|
24703
|
+
horizontal: true
|
|
24704
|
+
};
|
|
24705
|
+
const firstVisible = Math.max(0, Math.floor(offset / colStride));
|
|
24706
|
+
const lastVisible = Math.ceil((offset + viewportWidth) / colStride);
|
|
24707
|
+
return {
|
|
24708
|
+
cols: count,
|
|
24709
|
+
rows,
|
|
24710
|
+
totalHeight: 0,
|
|
24711
|
+
totalWidth,
|
|
24712
|
+
startIndex: Math.max(0, firstVisible - overscan),
|
|
24713
|
+
endIndex: Math.min(count, lastVisible + overscan),
|
|
24714
|
+
colStride,
|
|
24715
|
+
rowStride,
|
|
24716
|
+
horizontal: true
|
|
24717
|
+
};
|
|
24718
|
+
}
|
|
24719
|
+
const cols = orientation === `column` ? 1 : Math.max(1, Math.floor((Math.max(0, viewportWidth) + g) / colStride));
|
|
24720
|
+
const rows = count === 0 ? 0 : Math.ceil(count / cols);
|
|
24721
|
+
const totalHeight = rows === 0 ? 0 : (rows - 1) * rowStride + h;
|
|
24722
|
+
if (count === 0 || viewportHeight <= 0) return {
|
|
24723
|
+
cols,
|
|
24724
|
+
rows,
|
|
24725
|
+
totalHeight,
|
|
24726
|
+
totalWidth: 0,
|
|
24727
|
+
startIndex: 0,
|
|
24728
|
+
endIndex: 0,
|
|
24729
|
+
colStride,
|
|
24730
|
+
rowStride,
|
|
24731
|
+
horizontal: false
|
|
24732
|
+
};
|
|
24733
|
+
const firstVisibleRow = Math.max(0, Math.floor(offset / rowStride));
|
|
24734
|
+
const lastVisibleRow = Math.ceil((offset + viewportHeight) / rowStride);
|
|
24735
|
+
const rowStart = Math.max(0, firstVisibleRow - overscan);
|
|
24736
|
+
const rowEnd = Math.min(rows, lastVisibleRow + overscan);
|
|
24737
|
+
return {
|
|
24738
|
+
cols,
|
|
24739
|
+
rows,
|
|
24740
|
+
totalHeight,
|
|
24741
|
+
totalWidth: 0,
|
|
24742
|
+
startIndex: rowStart * cols,
|
|
24743
|
+
endIndex: Math.min(count, rowEnd * cols),
|
|
24744
|
+
colStride,
|
|
24745
|
+
rowStride,
|
|
24746
|
+
horizontal: false
|
|
24747
|
+
};
|
|
24748
|
+
}
|
|
24749
|
+
function buildSections(p, cols, stride, itemExtent) {
|
|
24750
|
+
const g = Math.max(0, p.gap);
|
|
24751
|
+
const horizontal = p.orientation === `row`;
|
|
24752
|
+
const lineCount = (n) => horizontal ? n : Math.ceil(n / cols);
|
|
24753
|
+
const extentFor = (n) => n === 0 ? 0 : (lineCount(n) - 1) * stride + itemExtent;
|
|
24754
|
+
if (!p.groups) {
|
|
24755
|
+
const end = extentFor(p.count);
|
|
24756
|
+
return {
|
|
24757
|
+
sections: [{
|
|
24758
|
+
group: void 0,
|
|
24759
|
+
first: 0,
|
|
24760
|
+
count: p.count,
|
|
24761
|
+
headerOffset: 0,
|
|
24762
|
+
itemsOffset: 0,
|
|
24763
|
+
end
|
|
24764
|
+
}],
|
|
24765
|
+
total: end,
|
|
24766
|
+
count: p.count
|
|
24767
|
+
};
|
|
24768
|
+
}
|
|
24769
|
+
const headerSize = horizontal ? p.headerWidth : p.headerHeight;
|
|
24770
|
+
const sections = [];
|
|
24771
|
+
let cursor = 0;
|
|
24772
|
+
let first = 0;
|
|
24773
|
+
for (const group of p.groups) {
|
|
24774
|
+
const count = group.collapsed ? 0 : group.count;
|
|
24775
|
+
const itemsOffset = cursor + headerSize + g;
|
|
24776
|
+
const end = count === 0 ? cursor + headerSize : itemsOffset + extentFor(count);
|
|
24777
|
+
sections.push({
|
|
24778
|
+
group,
|
|
24779
|
+
first,
|
|
24780
|
+
count,
|
|
24781
|
+
headerOffset: cursor,
|
|
24782
|
+
itemsOffset,
|
|
24783
|
+
end
|
|
24784
|
+
});
|
|
24785
|
+
first += count;
|
|
24786
|
+
cursor = end + g;
|
|
24787
|
+
}
|
|
24788
|
+
return {
|
|
24789
|
+
sections,
|
|
24790
|
+
total: sections.length === 0 ? 0 : sections[sections.length - 1].end,
|
|
24791
|
+
count: first
|
|
24792
|
+
};
|
|
24793
|
+
}
|
|
24794
|
+
/** Index of the last section whose `headerOffset` is <= `offset` (0 when before all). */
|
|
24795
|
+
function sectionAtOffset(sections, offset) {
|
|
24796
|
+
let lo = 0;
|
|
24797
|
+
let hi = sections.length - 1;
|
|
24798
|
+
while (lo < hi) {
|
|
24799
|
+
const mid = lo + hi + 1 >> 1;
|
|
24800
|
+
if (sections[mid].headerOffset <= offset) lo = mid;
|
|
24801
|
+
else hi = mid - 1;
|
|
24802
|
+
}
|
|
24803
|
+
return lo;
|
|
24804
|
+
}
|
|
24805
|
+
/** Index of the section holding effective item `index` (skips empty sections). */
|
|
24806
|
+
function sectionOfIndex(sections, index) {
|
|
24807
|
+
let lo = 0;
|
|
24808
|
+
let hi = sections.length - 1;
|
|
24809
|
+
while (lo < hi) {
|
|
24810
|
+
const mid = lo + hi + 1 >> 1;
|
|
24811
|
+
if (sections[mid].first <= index) lo = mid;
|
|
24812
|
+
else hi = mid - 1;
|
|
24813
|
+
}
|
|
24814
|
+
let s = lo;
|
|
24815
|
+
while (s < sections.length - 1 && sections[s].count === 0) s++;
|
|
24816
|
+
return s;
|
|
24817
|
+
}
|
|
24818
|
+
function buildLayout(p) {
|
|
24819
|
+
const horizontal = p.orientation === `row`;
|
|
24820
|
+
const w = Math.max(1, p.itemWidth);
|
|
24821
|
+
const h = Math.max(1, p.rowHeight);
|
|
24822
|
+
const g = Math.max(0, p.gap);
|
|
24823
|
+
const colStride = w + g;
|
|
24824
|
+
const rowStride = h + g;
|
|
24825
|
+
const cols = horizontal ? 1 : p.orientation === `column` ? 1 : Math.max(1, Math.floor((Math.max(0, p.viewportWidth) + g) / colStride));
|
|
24826
|
+
const stride = horizontal ? colStride : rowStride;
|
|
24827
|
+
const itemExtent = horizontal ? w : h;
|
|
24828
|
+
const { sections, total, count } = buildSections(p, cols, stride, itemExtent);
|
|
24829
|
+
const grouped = p.groups !== void 0;
|
|
24830
|
+
const headerSize = horizontal ? p.headerWidth : p.headerHeight;
|
|
24831
|
+
const viewportMain = horizontal ? p.viewportWidth : p.viewportHeight;
|
|
24832
|
+
const cellHeight = rowStride - g;
|
|
24833
|
+
const rowY = Math.max(0, (p.viewportHeight - cellHeight) / 2);
|
|
24834
|
+
const positionOf = (index) => {
|
|
24835
|
+
const si = sectionOfIndex(sections, index);
|
|
24836
|
+
const s = sections[si];
|
|
24837
|
+
const local = Math.max(0, index - s.first);
|
|
24838
|
+
if (horizontal) return {
|
|
24839
|
+
x: s.itemsOffset + local * colStride,
|
|
24840
|
+
y: rowY,
|
|
24841
|
+
col: 0,
|
|
24842
|
+
line: local,
|
|
24843
|
+
section: si
|
|
24844
|
+
};
|
|
24845
|
+
const col = cols <= 1 ? 0 : local % cols;
|
|
24846
|
+
const line = cols <= 1 ? local : Math.floor(local / cols);
|
|
24847
|
+
return {
|
|
24848
|
+
x: col * colStride,
|
|
24849
|
+
y: s.itemsOffset + line * rowStride,
|
|
24850
|
+
col,
|
|
24851
|
+
line,
|
|
24852
|
+
section: si
|
|
24853
|
+
};
|
|
24854
|
+
};
|
|
24855
|
+
const window = (offset, overscan = 2) => {
|
|
24856
|
+
const off = Math.max(0, offset);
|
|
24857
|
+
const headers = [];
|
|
24858
|
+
const ranges = [];
|
|
24859
|
+
const lo = off - overscan * stride;
|
|
24860
|
+
const hi = off + viewportMain + overscan * stride;
|
|
24861
|
+
let firstSection = 0;
|
|
24862
|
+
if (sections.length > 1) {
|
|
24863
|
+
let a = 0;
|
|
24864
|
+
let b = sections.length - 1;
|
|
24865
|
+
while (a < b) {
|
|
24866
|
+
const mid = a + b >> 1;
|
|
24867
|
+
if (sections[mid].end >= lo) b = mid;
|
|
24868
|
+
else a = mid + 1;
|
|
24869
|
+
}
|
|
24870
|
+
firstSection = a;
|
|
24871
|
+
}
|
|
24872
|
+
if (viewportMain > 0) for (let si = firstSection; si < sections.length; si++) {
|
|
24873
|
+
const s = sections[si];
|
|
24874
|
+
if (s.headerOffset > hi) break;
|
|
24875
|
+
if (s.group && s.headerOffset + headerSize >= lo) headers.push({
|
|
24876
|
+
key: s.group.key,
|
|
24877
|
+
label: s.group.label,
|
|
24878
|
+
count: s.group.count,
|
|
24879
|
+
collapsed: s.group.collapsed,
|
|
24880
|
+
offset: s.headerOffset,
|
|
24881
|
+
size: headerSize
|
|
24882
|
+
});
|
|
24883
|
+
if (s.count === 0) continue;
|
|
24884
|
+
const rel = off - s.itemsOffset;
|
|
24885
|
+
const viewport = rel < 0 ? viewportMain + rel : viewportMain;
|
|
24886
|
+
if (viewport <= 0) continue;
|
|
24887
|
+
const sw = computeGridWindow(s.count, w, h, g, horizontal ? viewport : p.viewportWidth, horizontal ? p.viewportHeight : viewport, Math.max(0, rel), p.orientation, overscan);
|
|
24888
|
+
if (sw.endIndex > sw.startIndex) ranges.push([s.first + sw.startIndex, s.first + sw.endIndex]);
|
|
24889
|
+
}
|
|
24890
|
+
return {
|
|
24891
|
+
cols: horizontal ? count : cols,
|
|
24892
|
+
rows: 0,
|
|
24893
|
+
totalHeight: horizontal ? 0 : total,
|
|
24894
|
+
totalWidth: horizontal ? total : 0,
|
|
24895
|
+
startIndex: ranges.length > 0 ? ranges[0][0] : 0,
|
|
24896
|
+
endIndex: ranges.length > 0 ? ranges[ranges.length - 1][1] : 0,
|
|
24897
|
+
colStride,
|
|
24898
|
+
rowStride,
|
|
24899
|
+
horizontal,
|
|
24900
|
+
headers,
|
|
24901
|
+
ranges
|
|
24902
|
+
};
|
|
24903
|
+
};
|
|
24904
|
+
const extentOf = (index) => {
|
|
24905
|
+
const { line, section } = positionOf(index);
|
|
24906
|
+
const s = sections[section];
|
|
24907
|
+
const start = s.itemsOffset + line * stride;
|
|
24908
|
+
return [line === 0 && s.group ? s.headerOffset : start, start + itemExtent];
|
|
24909
|
+
};
|
|
24910
|
+
const neighbour = (index, dLine) => {
|
|
24911
|
+
if (count === 0) return index;
|
|
24912
|
+
const si = sectionOfIndex(sections, index);
|
|
24913
|
+
const s = sections[si];
|
|
24914
|
+
const local = index - s.first;
|
|
24915
|
+
const col = local % cols;
|
|
24916
|
+
if (dLine > 0) {
|
|
24917
|
+
const t = local + cols;
|
|
24918
|
+
if (t <= s.count - 1) return s.first + t;
|
|
24919
|
+
const lastLine = Math.floor((s.count - 1) / cols);
|
|
24920
|
+
if (Math.floor(local / cols) < lastLine) return s.first + s.count - 1;
|
|
24921
|
+
for (let n = si + 1; n < sections.length; n++) if (sections[n].count > 0) return sections[n].first + Math.min(col, sections[n].count - 1);
|
|
24922
|
+
return s.first + s.count - 1;
|
|
24923
|
+
}
|
|
24924
|
+
const t = local - cols;
|
|
24925
|
+
if (t >= 0) return s.first + t;
|
|
24926
|
+
for (let n = si - 1; n >= 0; n--) {
|
|
24927
|
+
const prev = sections[n];
|
|
24928
|
+
if (prev.count > 0) {
|
|
24929
|
+
const line = Math.floor((prev.count - 1) / cols);
|
|
24930
|
+
return prev.first + Math.min(line * cols + col, prev.count - 1);
|
|
24931
|
+
}
|
|
24932
|
+
}
|
|
24933
|
+
return s.first;
|
|
24934
|
+
};
|
|
24935
|
+
const hitTest = (x0, x1, y0, y1) => {
|
|
24936
|
+
const out = [];
|
|
24937
|
+
if (count === 0) return out;
|
|
24938
|
+
const main0 = horizontal ? x0 : y0;
|
|
24939
|
+
const main1 = horizontal ? x1 : y1;
|
|
24940
|
+
const start = sectionAtOffset(sections, main0 - stride);
|
|
24941
|
+
for (let si = Math.max(0, start); si < sections.length; si++) {
|
|
24942
|
+
const s = sections[si];
|
|
24943
|
+
if (s.itemsOffset > main1) break;
|
|
24944
|
+
if (s.count === 0 || s.end < main0) continue;
|
|
24945
|
+
if (horizontal) {
|
|
24946
|
+
const a = Math.max(0, Math.floor((x0 - s.itemsOffset) / colStride));
|
|
24947
|
+
const b = Math.min(s.count - 1, Math.floor((x1 - s.itemsOffset) / colStride));
|
|
24948
|
+
for (let i = a; i <= b; i++) out.push(s.first + i);
|
|
24949
|
+
} else {
|
|
24950
|
+
const colLo = Math.max(0, Math.floor(x0 / colStride));
|
|
24951
|
+
const colHi = Math.min(cols - 1, Math.floor(x1 / colStride));
|
|
24952
|
+
const rowLo = Math.max(0, Math.floor((y0 - s.itemsOffset) / rowStride));
|
|
24953
|
+
const rowHi = Math.floor((y1 - s.itemsOffset) / rowStride);
|
|
24954
|
+
for (let row = rowLo; row <= rowHi; row++) for (let col = colLo; col <= colHi; col++) {
|
|
24955
|
+
const local = row * cols + col;
|
|
24956
|
+
if (local >= 0 && local < s.count) out.push(s.first + local);
|
|
24957
|
+
}
|
|
24958
|
+
}
|
|
24959
|
+
}
|
|
24960
|
+
return out;
|
|
24961
|
+
};
|
|
24962
|
+
const anchorAt = (mainOffset) => {
|
|
24963
|
+
if (count === 0) return {
|
|
24964
|
+
index: 0,
|
|
24965
|
+
lineFrac: 0
|
|
24966
|
+
};
|
|
24967
|
+
let si = sectionAtOffset(sections, mainOffset);
|
|
24968
|
+
while (si < sections.length - 1 && sections[si].count === 0) si++;
|
|
24969
|
+
const s = sections[si];
|
|
24970
|
+
if (s.count === 0) return {
|
|
24971
|
+
index: 0,
|
|
24972
|
+
lineFrac: 0
|
|
24973
|
+
};
|
|
24974
|
+
const centreLine = Math.max(0, mainOffset - s.itemsOffset) / stride;
|
|
24975
|
+
const lineFloor = Math.max(0, Math.floor(centreLine));
|
|
24976
|
+
const local = horizontal ? Math.min(s.count - 1, lineFloor) : Math.min(s.count - 1, lineFloor * cols + Math.max(0, Math.floor((cols - 1) / 2)));
|
|
24977
|
+
return {
|
|
24978
|
+
index: s.first + local,
|
|
24979
|
+
lineFrac: centreLine - lineFloor
|
|
24980
|
+
};
|
|
24981
|
+
};
|
|
24982
|
+
const offsetOfAnchor = (index, lineFrac) => {
|
|
24983
|
+
const { line, section } = positionOf(index);
|
|
24984
|
+
return sections[section].itemsOffset + (line + lineFrac) * stride;
|
|
24985
|
+
};
|
|
24986
|
+
const snapTarget = (offset) => {
|
|
24987
|
+
const si = sectionAtOffset(sections, offset);
|
|
24988
|
+
const s = sections[si];
|
|
24989
|
+
let rel = Math.round((offset - s.itemsOffset) / stride);
|
|
24990
|
+
if (grouped) {
|
|
24991
|
+
const lines = s.count === 0 ? 0 : horizontal ? s.count : Math.ceil(s.count / cols);
|
|
24992
|
+
rel = Math.max(0, Math.min(Math.max(0, lines - 1), rel));
|
|
24993
|
+
}
|
|
24994
|
+
const candidates = [s.itemsOffset + rel * stride];
|
|
24995
|
+
if (grouped) {
|
|
24996
|
+
candidates.push(s.headerOffset);
|
|
24997
|
+
if (si + 1 < sections.length) candidates.push(sections[si + 1].headerOffset);
|
|
24998
|
+
}
|
|
24999
|
+
return candidates.reduce((best, c) => Math.abs(c - offset) < Math.abs(best - offset) ? c : best);
|
|
25000
|
+
};
|
|
25001
|
+
return {
|
|
25002
|
+
horizontal,
|
|
25003
|
+
cols,
|
|
25004
|
+
colStride,
|
|
25005
|
+
rowStride,
|
|
25006
|
+
grouped,
|
|
25007
|
+
count,
|
|
25008
|
+
totalExtent: total,
|
|
25009
|
+
window,
|
|
25010
|
+
positionOf,
|
|
25011
|
+
extentOf,
|
|
25012
|
+
neighbour,
|
|
25013
|
+
hitTest,
|
|
25014
|
+
anchorAt,
|
|
25015
|
+
offsetOfAnchor,
|
|
25016
|
+
snapTarget
|
|
25017
|
+
};
|
|
25018
|
+
}
|
|
25019
|
+
//#endregion
|
|
24212
25020
|
//#region src/grid-list/grid-list-source.ts
|
|
25021
|
+
/** Reorder `effective` raw indices into contiguous groups, dropping collapsed ones. */
|
|
25022
|
+
function applyGrouping(effective, cfg, keyOfRaw) {
|
|
25023
|
+
const parts = partitionByGroup(effective, (raw) => cfg.groupKeyOf(raw), cfg.labelOf ? (key, raws) => cfg.labelOf(key, raws.map((r) => cfg.itemAt(r))) : void 0);
|
|
25024
|
+
const order = [];
|
|
25025
|
+
const groups = [];
|
|
25026
|
+
const groupByKey = /* @__PURE__ */ new Map();
|
|
25027
|
+
for (const part of parts) {
|
|
25028
|
+
const collapsed = cfg.collapsed.has(part.key);
|
|
25029
|
+
groups.push({
|
|
25030
|
+
key: part.key,
|
|
25031
|
+
label: part.label,
|
|
25032
|
+
count: part.items.length,
|
|
25033
|
+
collapsed
|
|
25034
|
+
});
|
|
25035
|
+
for (const raw of part.items) {
|
|
25036
|
+
groupByKey.set(keyOfRaw(raw), part.key);
|
|
25037
|
+
if (!collapsed) order.push(raw);
|
|
25038
|
+
}
|
|
25039
|
+
}
|
|
25040
|
+
return {
|
|
25041
|
+
order,
|
|
25042
|
+
groups,
|
|
25043
|
+
groupByKey
|
|
25044
|
+
};
|
|
25045
|
+
}
|
|
24213
25046
|
const ITEM_SELECTOR$2 = `:scope > *`;
|
|
24214
25047
|
const SYNTHETIC_PREFIX = `gl-auto-`;
|
|
24215
25048
|
/** Whether `key` is an auto-assigned key for a keyless light-DOM item. */
|
|
@@ -24236,6 +25069,9 @@ var ElementGridListSource = class {
|
|
|
24236
25069
|
#searchKeys;
|
|
24237
25070
|
#effectiveIndices = [];
|
|
24238
25071
|
#keysCache;
|
|
25072
|
+
#grouping;
|
|
25073
|
+
#groups = [];
|
|
25074
|
+
#groupByKey = /* @__PURE__ */ new Map();
|
|
24239
25075
|
constructor(host) {
|
|
24240
25076
|
this.#host = host;
|
|
24241
25077
|
this.refresh();
|
|
@@ -24288,6 +25124,16 @@ var ElementGridListSource = class {
|
|
|
24288
25124
|
if (`searchKeys` in opts) this.#searchKeys = opts.searchKeys;
|
|
24289
25125
|
this.#recomputeEffective();
|
|
24290
25126
|
}
|
|
25127
|
+
setGrouping(config) {
|
|
25128
|
+
this.#grouping = config;
|
|
25129
|
+
this.#recomputeEffective();
|
|
25130
|
+
}
|
|
25131
|
+
groups() {
|
|
25132
|
+
return this.#groups;
|
|
25133
|
+
}
|
|
25134
|
+
groupKeyOfKey(key) {
|
|
25135
|
+
return this.#groupByKey.get(key) ?? null;
|
|
25136
|
+
}
|
|
24291
25137
|
refresh() {
|
|
24292
25138
|
this.#items = Array.from(this.#host.querySelectorAll(ITEM_SELECTOR$2)).filter((el) => !el.hidden);
|
|
24293
25139
|
for (const el of this.#items) {
|
|
@@ -24330,9 +25176,21 @@ var ElementGridListSource = class {
|
|
|
24330
25176
|
}
|
|
24331
25177
|
effective.push(i);
|
|
24332
25178
|
}
|
|
24333
|
-
this.#
|
|
25179
|
+
this.#applyGroupingTo(effective);
|
|
24334
25180
|
this.#keysCache = void 0;
|
|
24335
25181
|
}
|
|
25182
|
+
#applyGroupingTo(effective) {
|
|
25183
|
+
if (this.#grouping === void 0) {
|
|
25184
|
+
this.#effectiveIndices = effective;
|
|
25185
|
+
this.#groups = [];
|
|
25186
|
+
this.#groupByKey = /* @__PURE__ */ new Map();
|
|
25187
|
+
return;
|
|
25188
|
+
}
|
|
25189
|
+
const grouped = applyGrouping(effective, this.#grouping, (raw) => this.#itemKey(this.#items[raw]));
|
|
25190
|
+
this.#effectiveIndices = grouped.order;
|
|
25191
|
+
this.#groups = grouped.groups;
|
|
25192
|
+
this.#groupByKey = grouped.groupByKey;
|
|
25193
|
+
}
|
|
24336
25194
|
#itemKey(el) {
|
|
24337
25195
|
const userKey = keyForElement(el);
|
|
24338
25196
|
if (userKey !== void 0) return userKey;
|
|
@@ -24355,6 +25213,9 @@ var DataGridListSource = class {
|
|
|
24355
25213
|
#searchKeys;
|
|
24356
25214
|
#effectiveIndices = [];
|
|
24357
25215
|
#keysCache;
|
|
25216
|
+
#grouping;
|
|
25217
|
+
#groups = [];
|
|
25218
|
+
#groupByKey = /* @__PURE__ */ new Map();
|
|
24358
25219
|
constructor(items, adapter) {
|
|
24359
25220
|
this.#items = items;
|
|
24360
25221
|
this.#adapter = adapter;
|
|
@@ -24420,6 +25281,16 @@ var DataGridListSource = class {
|
|
|
24420
25281
|
if (`searchKeys` in opts) this.#searchKeys = opts.searchKeys;
|
|
24421
25282
|
this.#recomputeEffective();
|
|
24422
25283
|
}
|
|
25284
|
+
setGrouping(config) {
|
|
25285
|
+
this.#grouping = config;
|
|
25286
|
+
this.#recomputeEffective();
|
|
25287
|
+
}
|
|
25288
|
+
groups() {
|
|
25289
|
+
return this.#groups;
|
|
25290
|
+
}
|
|
25291
|
+
groupKeyOfKey(key) {
|
|
25292
|
+
return this.#groupByKey.get(key) ?? null;
|
|
25293
|
+
}
|
|
24423
25294
|
refresh() {
|
|
24424
25295
|
this.#recomputeEffective();
|
|
24425
25296
|
}
|
|
@@ -24444,7 +25315,16 @@ var DataGridListSource = class {
|
|
|
24444
25315
|
if (this.#searchKeys !== void 0 && !this.#searchKeys.has(this.#adapter.key(this.#items[i], i))) continue;
|
|
24445
25316
|
effective.push(i);
|
|
24446
25317
|
}
|
|
24447
|
-
this.#
|
|
25318
|
+
if (this.#grouping === void 0) {
|
|
25319
|
+
this.#effectiveIndices = effective;
|
|
25320
|
+
this.#groups = [];
|
|
25321
|
+
this.#groupByKey = /* @__PURE__ */ new Map();
|
|
25322
|
+
} else {
|
|
25323
|
+
const grouped = applyGrouping(effective, this.#grouping, (raw) => this.#adapter.key(this.#items[raw], raw));
|
|
25324
|
+
this.#effectiveIndices = grouped.order;
|
|
25325
|
+
this.#groups = grouped.groups;
|
|
25326
|
+
this.#groupByKey = grouped.groupByKey;
|
|
25327
|
+
}
|
|
24448
25328
|
this.#keysCache = void 0;
|
|
24449
25329
|
}
|
|
24450
25330
|
};
|
|
@@ -24460,76 +25340,11 @@ const SNAP_DEBOUNCE_MS = 120;
|
|
|
24460
25340
|
* to finish. Kept a touch above the default `--grid-list-item-move-duration`.
|
|
24461
25341
|
*/
|
|
24462
25342
|
const REFLOW_WINDOW_MS = 320;
|
|
24463
|
-
function
|
|
24464
|
-
|
|
24465
|
-
const h = Math.max(1, rowHeight);
|
|
24466
|
-
const g = Math.max(0, gap);
|
|
24467
|
-
const colStride = w + g;
|
|
24468
|
-
const rowStride = h + g;
|
|
24469
|
-
const offset = Math.max(0, scrollOffset);
|
|
24470
|
-
if (orientation === `row`) {
|
|
24471
|
-
const rows = count === 0 ? 0 : 1;
|
|
24472
|
-
const totalWidth = count === 0 ? 0 : (count - 1) * colStride + w;
|
|
24473
|
-
if (count === 0 || viewportWidth <= 0) return {
|
|
24474
|
-
cols: count,
|
|
24475
|
-
rows,
|
|
24476
|
-
totalHeight: 0,
|
|
24477
|
-
totalWidth,
|
|
24478
|
-
startIndex: 0,
|
|
24479
|
-
endIndex: 0,
|
|
24480
|
-
colStride,
|
|
24481
|
-
rowStride,
|
|
24482
|
-
horizontal: true
|
|
24483
|
-
};
|
|
24484
|
-
const firstVisible = Math.max(0, Math.floor(offset / colStride));
|
|
24485
|
-
const lastVisible = Math.ceil((offset + viewportWidth) / colStride);
|
|
24486
|
-
return {
|
|
24487
|
-
cols: count,
|
|
24488
|
-
rows,
|
|
24489
|
-
totalHeight: 0,
|
|
24490
|
-
totalWidth,
|
|
24491
|
-
startIndex: Math.max(0, firstVisible - overscan),
|
|
24492
|
-
endIndex: Math.min(count, lastVisible + overscan),
|
|
24493
|
-
colStride,
|
|
24494
|
-
rowStride,
|
|
24495
|
-
horizontal: true
|
|
24496
|
-
};
|
|
24497
|
-
}
|
|
24498
|
-
const cols = orientation === `column` ? 1 : Math.max(1, Math.floor((Math.max(0, viewportWidth) + g) / colStride));
|
|
24499
|
-
const rows = count === 0 ? 0 : Math.ceil(count / cols);
|
|
24500
|
-
const totalHeight = rows === 0 ? 0 : (rows - 1) * rowStride + h;
|
|
24501
|
-
if (count === 0 || viewportHeight <= 0) return {
|
|
24502
|
-
cols,
|
|
24503
|
-
rows,
|
|
24504
|
-
totalHeight,
|
|
24505
|
-
totalWidth: 0,
|
|
24506
|
-
startIndex: 0,
|
|
24507
|
-
endIndex: 0,
|
|
24508
|
-
colStride,
|
|
24509
|
-
rowStride,
|
|
24510
|
-
horizontal: false
|
|
24511
|
-
};
|
|
24512
|
-
const firstVisibleRow = Math.max(0, Math.floor(offset / rowStride));
|
|
24513
|
-
const lastVisibleRow = Math.ceil((offset + viewportHeight) / rowStride);
|
|
24514
|
-
const rowStart = Math.max(0, firstVisibleRow - overscan);
|
|
24515
|
-
const rowEnd = Math.min(rows, lastVisibleRow + overscan);
|
|
24516
|
-
return {
|
|
24517
|
-
cols,
|
|
24518
|
-
rows,
|
|
24519
|
-
totalHeight,
|
|
24520
|
-
totalWidth: 0,
|
|
24521
|
-
startIndex: rowStart * cols,
|
|
24522
|
-
endIndex: Math.min(count, rowEnd * cols),
|
|
24523
|
-
colStride,
|
|
24524
|
-
rowStride,
|
|
24525
|
-
horizontal: false
|
|
24526
|
-
};
|
|
25343
|
+
function readProperty(item, name) {
|
|
25344
|
+
return typeof item === `object` && item !== null ? item[name] : void 0;
|
|
24527
25345
|
}
|
|
24528
|
-
function
|
|
24529
|
-
return
|
|
24530
|
-
}
|
|
24531
|
-
function rowOf(index, cols) {
|
|
24532
|
-
return cols <= 1 ? index : Math.floor(index / cols);
|
|
25346
|
+
function readAttribute(el, name) {
|
|
25347
|
+
return el.getAttribute(`data-${name}`);
|
|
24533
25348
|
}
|
|
24534
25349
|
/** Shallow key-array equality, treating `undefined` (never dispatched) as different. */
|
|
24535
25350
|
function sameKeys$1(a, b) {
|
|
@@ -24557,6 +25372,11 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
24557
25372
|
this.marqueeFromCellBlank = false;
|
|
24558
25373
|
this.snapToItem = false;
|
|
24559
25374
|
this.items = [];
|
|
25375
|
+
this.groupBy = null;
|
|
25376
|
+
this.crossGroupSelection = false;
|
|
25377
|
+
this.groupHeaderHeight = 28;
|
|
25378
|
+
this.groupHeaderWidth = 120;
|
|
25379
|
+
this._collapsedGroups = /* @__PURE__ */ new Set();
|
|
24560
25380
|
this._scrollTop = 0;
|
|
24561
25381
|
this._scrollLeft = 0;
|
|
24562
25382
|
this._viewportHeight = 0;
|
|
@@ -24581,6 +25401,12 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
24581
25401
|
interactionMode: this.interactionMode
|
|
24582
25402
|
}),
|
|
24583
25403
|
getKey: (k) => k,
|
|
25404
|
+
getGroupKey: (k) => this.groupBy === null ? null : this.#source.groupKeyOfKey(k),
|
|
25405
|
+
crossGroupSelection: () => this.crossGroupSelection,
|
|
25406
|
+
getFallbackGroupKey: () => {
|
|
25407
|
+
const k = this.tickled.tickledId;
|
|
25408
|
+
return k !== void 0 && this.groupBy !== null ? this.#source.groupKeyOfKey(k) : null;
|
|
25409
|
+
},
|
|
24584
25410
|
onChange: (selected, previous) => {
|
|
24585
25411
|
this._syncItemStates();
|
|
24586
25412
|
this.requestUpdate();
|
|
@@ -24678,10 +25504,11 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
24678
25504
|
},
|
|
24679
25505
|
shouldStart: (event) => {
|
|
24680
25506
|
if (this.marqueeFromCellBlank && this.#isCellBlankPress(event)) return true;
|
|
24681
|
-
for (const node of event.composedPath()) if (node instanceof Element && node.classList.contains(`cell`)) return false;
|
|
25507
|
+
for (const node of event.composedPath()) if (node instanceof Element && (node.classList.contains(`cell`) || node.classList.contains(`group-header`))) return false;
|
|
24682
25508
|
return true;
|
|
24683
25509
|
}
|
|
24684
25510
|
});
|
|
25511
|
+
this.#groupByChanged = false;
|
|
24685
25512
|
this.#selectedSnapshot = /* @__PURE__ */ new Set();
|
|
24686
25513
|
this.#onScroll = (e) => {
|
|
24687
25514
|
const el = e.target;
|
|
@@ -24731,15 +25558,25 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
24731
25558
|
const count = this.#source.count;
|
|
24732
25559
|
if (count === 0) return;
|
|
24733
25560
|
const win = this.#currentWindow();
|
|
24734
|
-
const
|
|
24735
|
-
|
|
24736
|
-
|
|
25561
|
+
const layout = this.#layout();
|
|
25562
|
+
const current = () => this.tickled.tickledId ? this.#source.indexOfKey(this.tickled.tickledId) : -1;
|
|
25563
|
+
const goto = (nextIndex) => {
|
|
24737
25564
|
const nextKey = this.#source.keyAt(nextIndex);
|
|
24738
25565
|
if (nextKey) {
|
|
24739
25566
|
this.tickled.handleKeyboardNavigation(nextKey);
|
|
24740
25567
|
this.#scrollItemIntoView(nextKey);
|
|
24741
25568
|
}
|
|
24742
25569
|
};
|
|
25570
|
+
const move = (delta) => goto(Math.max(0, Math.min(count - 1, current() + delta)));
|
|
25571
|
+
const moveLines = (dir, lines = 1) => {
|
|
25572
|
+
let index = current();
|
|
25573
|
+
if (index < 0) {
|
|
25574
|
+
move(dir * lines * win.cols);
|
|
25575
|
+
return;
|
|
25576
|
+
}
|
|
25577
|
+
for (let i = 0; i < lines; i++) index = layout.neighbour(index, dir);
|
|
25578
|
+
goto(index);
|
|
25579
|
+
};
|
|
24743
25580
|
const perLine = this.orientation === `grid` ? win.cols : 1;
|
|
24744
25581
|
switch (e.key) {
|
|
24745
25582
|
case `ArrowLeft`:
|
|
@@ -24749,10 +25586,12 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
24749
25586
|
move(1);
|
|
24750
25587
|
break;
|
|
24751
25588
|
case `ArrowUp`:
|
|
24752
|
-
|
|
25589
|
+
if (this.orientation === `grid`) moveLines(-1);
|
|
25590
|
+
else move(-perLine);
|
|
24753
25591
|
break;
|
|
24754
25592
|
case `ArrowDown`:
|
|
24755
|
-
|
|
25593
|
+
if (this.orientation === `grid`) moveLines(1);
|
|
25594
|
+
else move(perLine);
|
|
24756
25595
|
break;
|
|
24757
25596
|
case `Home`:
|
|
24758
25597
|
this.tickled.handleKeyboardNavigation(`first`);
|
|
@@ -24767,7 +25606,8 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
24767
25606
|
const mainExtent = win.horizontal ? this._viewportWidth : this._viewportHeight;
|
|
24768
25607
|
const mainStride = win.horizontal ? win.colStride : win.rowStride;
|
|
24769
25608
|
const visibleLines = Math.max(1, Math.floor(mainExtent / mainStride));
|
|
24770
|
-
|
|
25609
|
+
if (this.orientation === `grid`) moveLines(e.key === `PageDown` ? 1 : -1, visibleLines);
|
|
25610
|
+
else move((e.key === `PageDown` ? 1 : -1) * visibleLines * perLine);
|
|
24771
25611
|
break;
|
|
24772
25612
|
}
|
|
24773
25613
|
case `Enter`: {
|
|
@@ -24848,6 +25688,11 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
24848
25688
|
position: relative;
|
|
24849
25689
|
width: 100%;
|
|
24850
25690
|
}
|
|
25691
|
+
.group-header {
|
|
25692
|
+
position: absolute;
|
|
25693
|
+
inset: 0 auto auto 0;
|
|
25694
|
+
z-index: 1;
|
|
25695
|
+
}
|
|
24851
25696
|
.cell {
|
|
24852
25697
|
position: absolute;
|
|
24853
25698
|
inset: 0 auto auto 0;
|
|
@@ -25141,6 +25986,9 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25141
25986
|
specificity. Survivors slide to their new slot; a freshly inserted cell
|
|
25142
25987
|
also fades in. (A removed item's element is already gone, so there's
|
|
25143
25988
|
nothing left to fade — the gap simply closes as the others slide.) */
|
|
25989
|
+
:host([reflowing]) .group-header {
|
|
25990
|
+
transition: transform var(--grid-list-item-move-duration, 200ms) cubic-bezier(0.2, 0, 0, 1);
|
|
25991
|
+
}
|
|
25144
25992
|
:host([reflowing]) .cell {
|
|
25145
25993
|
transition:
|
|
25146
25994
|
transform var(--grid-list-item-move-duration, 200ms) cubic-bezier(0.2, 0, 0, 1),
|
|
@@ -25151,6 +25999,7 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25151
25999
|
animation: ixfx-list-item-in var(--grid-list-item-move-duration, 200ms) ease both;
|
|
25152
26000
|
}
|
|
25153
26001
|
@media (prefers-reduced-motion: reduce) {
|
|
26002
|
+
:host([reflowing]) .group-header { transition: none; }
|
|
25154
26003
|
:host([reflowing]) .cell { transition: background var(--transition), border-color var(--transition); }
|
|
25155
26004
|
.cell.entering { animation: none; }
|
|
25156
26005
|
}
|
|
@@ -25292,31 +26141,13 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25292
26141
|
* so virtualized off-screen items are covered without DOM measurement.
|
|
25293
26142
|
*/
|
|
25294
26143
|
#marqueeHitTest(rect) {
|
|
25295
|
-
|
|
25296
|
-
if (count === 0) return [];
|
|
26144
|
+
if (this.#source.count === 0) return [];
|
|
25297
26145
|
const horizontal = this.orientation === `row`;
|
|
25298
|
-
const
|
|
25299
|
-
const
|
|
25300
|
-
|
|
25301
|
-
|
|
25302
|
-
|
|
25303
|
-
const lo = Math.max(0, Math.floor(x0 / win.colStride));
|
|
25304
|
-
const hi = Math.min(count - 1, Math.floor(x1 / win.colStride));
|
|
25305
|
-
for (let i = lo; i <= hi; i++) out.push(i);
|
|
25306
|
-
} else {
|
|
25307
|
-
const x0 = rect.x + this._scrollLeft;
|
|
25308
|
-
const x1 = x0 + rect.width;
|
|
25309
|
-
const y0 = rect.y + this._scrollTop;
|
|
25310
|
-
const y1 = y0 + rect.height;
|
|
25311
|
-
const colLo = Math.max(0, Math.floor(x0 / win.colStride));
|
|
25312
|
-
const colHi = Math.min(win.cols - 1, Math.floor(x1 / win.colStride));
|
|
25313
|
-
const rowLo = Math.max(0, Math.floor(y0 / win.rowStride));
|
|
25314
|
-
const rowHi = Math.floor(y1 / win.rowStride);
|
|
25315
|
-
for (let row = rowLo; row <= rowHi; row++) for (let col = colLo; col <= colHi; col++) {
|
|
25316
|
-
const index = row * win.cols + col;
|
|
25317
|
-
if (index >= 0 && index < count) out.push(index);
|
|
25318
|
-
}
|
|
25319
|
-
}
|
|
26146
|
+
const x0 = rect.x + this._scrollLeft;
|
|
26147
|
+
const x1 = x0 + rect.width;
|
|
26148
|
+
const y0 = horizontal ? 0 : rect.y + this._scrollTop;
|
|
26149
|
+
const y1 = horizontal ? 0 : y0 + rect.height;
|
|
26150
|
+
const out = this.#layout().hitTest(x0, x1, y0, y1);
|
|
25320
26151
|
const keys = [];
|
|
25321
26152
|
for (const index of out) {
|
|
25322
26153
|
const key = this.#source.keyAt(index);
|
|
@@ -25466,6 +26297,10 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25466
26297
|
if (previousLength === 0 && removedCount === 0) return;
|
|
25467
26298
|
if (added.length > 0 && added.length === this.#items.length) return;
|
|
25468
26299
|
for (const el of added) this.#entering.add(el);
|
|
26300
|
+
this.#openReflowWindow();
|
|
26301
|
+
}
|
|
26302
|
+
/** Open (or extend) the `[reflowing]` window so moved cells and headers slide. */
|
|
26303
|
+
#openReflowWindow() {
|
|
25469
26304
|
this.toggleAttribute(`reflowing`, true);
|
|
25470
26305
|
if (this.#reflowTimer) clearTimeout(this.#reflowTimer);
|
|
25471
26306
|
this.#reflowTimer = window.setTimeout(() => {
|
|
@@ -25522,6 +26357,7 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25522
26357
|
this.#sourceElement = new ElementGridListSource(this);
|
|
25523
26358
|
this.#source = this.#sourceElement;
|
|
25524
26359
|
}
|
|
26360
|
+
this.#source.setGrouping(this.#groupingConfig());
|
|
25525
26361
|
this.#applyFilters();
|
|
25526
26362
|
if (this.#searchFilterKeys) this.#source.setFilters({ searchKeys: this.#searchFilterKeys });
|
|
25527
26363
|
}
|
|
@@ -25563,6 +26399,17 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25563
26399
|
}
|
|
25564
26400
|
this.search?.refresh();
|
|
25565
26401
|
}
|
|
26402
|
+
const groupsChanged = changed.has(`groupBy`) || changed.has(`groupLabel`) || changed.has(`_collapsedGroups`);
|
|
26403
|
+
if (groupsChanged && this.hasUpdated) {
|
|
26404
|
+
if (changed.has(`groupBy`)) {
|
|
26405
|
+
if (this._collapsedGroups.size > 0) this._collapsedGroups = /* @__PURE__ */ new Set();
|
|
26406
|
+
this.#groupByChanged = true;
|
|
26407
|
+
}
|
|
26408
|
+
this.#applyGroupingToSource();
|
|
26409
|
+
this.#dropUnreachableCursor();
|
|
26410
|
+
this.#openReflowWindow();
|
|
26411
|
+
this.updateComplete.then(() => this.#emitViewportChange());
|
|
26412
|
+
} else if (groupsChanged) this.#applyGroupingToSource();
|
|
25566
26413
|
if (changed.has(`itemSize`) || changed.has(`gap`)) {
|
|
25567
26414
|
this.itemSize = Math.max(MIN_ITEM_SIZE, Math.round(this.itemSize));
|
|
25568
26415
|
this.gap = Math.max(0, Math.round(this.gap));
|
|
@@ -25583,6 +26430,62 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25583
26430
|
}
|
|
25584
26431
|
}
|
|
25585
26432
|
}
|
|
26433
|
+
#groupByChanged;
|
|
26434
|
+
/** Grouping config for the active source, or `undefined` when ungrouped. */
|
|
26435
|
+
#groupingConfig() {
|
|
26436
|
+
const by = this.groupBy;
|
|
26437
|
+
if (by === null || by === void 0 || by === ``) return void 0;
|
|
26438
|
+
const collapsed = this._collapsedGroups;
|
|
26439
|
+
const src = this.#source;
|
|
26440
|
+
if (src instanceof DataGridListSource) return {
|
|
26441
|
+
groupKeyOf: (raw) => resolveGroupKey(by, src.rawItemAt(raw), raw, readProperty),
|
|
26442
|
+
itemAt: (raw) => src.rawItemAt(raw),
|
|
26443
|
+
labelOf: this.groupLabel,
|
|
26444
|
+
collapsed
|
|
26445
|
+
};
|
|
26446
|
+
const elements = src;
|
|
26447
|
+
return {
|
|
26448
|
+
groupKeyOf: (raw) => resolveGroupKey(by, elements.rawElementAt(raw), raw, readAttribute),
|
|
26449
|
+
itemAt: (raw) => elements.rawElementAt(raw),
|
|
26450
|
+
labelOf: this.groupLabel,
|
|
26451
|
+
collapsed
|
|
26452
|
+
};
|
|
26453
|
+
}
|
|
26454
|
+
/** Push the current grouping into the source and refresh the element-mode item cache. */
|
|
26455
|
+
#applyGroupingToSource() {
|
|
26456
|
+
this.#source.setGrouping(this.#groupingConfig());
|
|
26457
|
+
if (this.#source instanceof ElementGridListSource) this.#items = this.#source.effectiveElements();
|
|
26458
|
+
}
|
|
26459
|
+
/** The cursor can't stay on an item that a collapsed group just removed. */
|
|
26460
|
+
#dropUnreachableCursor() {
|
|
26461
|
+
const id = this.tickled.tickledId;
|
|
26462
|
+
if (id !== void 0 && this.#source.indexOfKey(id) < 0) this.tickled.focus(void 0);
|
|
26463
|
+
}
|
|
26464
|
+
/** Groups in display order (empty when ungrouped). */
|
|
26465
|
+
get groups() {
|
|
26466
|
+
return this.groupBy === null ? [] : this.#source.groups();
|
|
26467
|
+
}
|
|
26468
|
+
/** Collapse or expand one group. Fires `list-group-toggle` when the state changes. */
|
|
26469
|
+
setGroupCollapsed(groupKey, collapsed) {
|
|
26470
|
+
if (this._collapsedGroups.has(groupKey) === collapsed) return;
|
|
26471
|
+
const next = new Set(this._collapsedGroups);
|
|
26472
|
+
if (collapsed) next.add(groupKey);
|
|
26473
|
+
else next.delete(groupKey);
|
|
26474
|
+
this._collapsedGroups = next;
|
|
26475
|
+
this._dispatch(`list-group-toggle`, {
|
|
26476
|
+
groupKey,
|
|
26477
|
+
collapsed
|
|
26478
|
+
});
|
|
26479
|
+
}
|
|
26480
|
+
toggleGroup(groupKey) {
|
|
26481
|
+
this.setGroupCollapsed(groupKey, !this._collapsedGroups.has(groupKey));
|
|
26482
|
+
}
|
|
26483
|
+
collapseAllGroups() {
|
|
26484
|
+
for (const g of this.groups) this.setGroupCollapsed(g.key, true);
|
|
26485
|
+
}
|
|
26486
|
+
expandAllGroups() {
|
|
26487
|
+
for (const key of [...this._collapsedGroups]) this.setGroupCollapsed(key, false);
|
|
26488
|
+
}
|
|
25586
26489
|
#syncAriaMultiselectable() {
|
|
25587
26490
|
this.setAttribute(`aria-multiselectable`, this.selection.canSelectMultiple() ? `true` : `false`);
|
|
25588
26491
|
}
|
|
@@ -25622,6 +26525,10 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25622
26525
|
}
|
|
25623
26526
|
this.#applyZoomAnchor();
|
|
25624
26527
|
this.#activateTickledPan();
|
|
26528
|
+
if (this.#groupByChanged) {
|
|
26529
|
+
this.#groupByChanged = false;
|
|
26530
|
+
this._dispatch(`list-group-change`, { groupBy: this.groupBy });
|
|
26531
|
+
}
|
|
25625
26532
|
}
|
|
25626
26533
|
/** Re-anchor the scroll so the item captured in `willUpdate` stays centred. */
|
|
25627
26534
|
#applyZoomAnchor() {
|
|
@@ -25630,41 +26537,33 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25630
26537
|
this.#zoomAnchor = void 0;
|
|
25631
26538
|
const vp = this.#viewportRef.value;
|
|
25632
26539
|
if (!vp) return;
|
|
25633
|
-
const
|
|
25634
|
-
|
|
25635
|
-
|
|
25636
|
-
|
|
25637
|
-
|
|
25638
|
-
|
|
26540
|
+
const layout = this.#layout();
|
|
26541
|
+
const horizontal = layout.horizontal;
|
|
26542
|
+
const extent = horizontal ? this._viewportWidth : this._viewportHeight;
|
|
26543
|
+
if (extent <= 0) return;
|
|
26544
|
+
const targetCenter = layout.offsetOfAnchor(index, lineFrac);
|
|
26545
|
+
const maxScroll = Math.max(0, layout.totalExtent - extent);
|
|
26546
|
+
const next = Math.min(maxScroll, Math.max(0, targetCenter - extent / 2));
|
|
26547
|
+
if (horizontal) {
|
|
25639
26548
|
if (Math.abs(vp.scrollLeft - next) > .5) {
|
|
25640
26549
|
vp.scrollLeft = next;
|
|
25641
26550
|
this._scrollLeft = next;
|
|
25642
26551
|
}
|
|
25643
|
-
|
|
25644
|
-
}
|
|
25645
|
-
if (this._viewportHeight <= 0) return;
|
|
25646
|
-
const targetCenter = ((win.cols > 0 ? Math.floor(index / win.cols) : 0) + lineFrac) * win.rowStride;
|
|
25647
|
-
const maxScroll = Math.max(0, win.totalHeight - this._viewportHeight);
|
|
25648
|
-
const next = Math.min(maxScroll, Math.max(0, targetCenter - this._viewportHeight / 2));
|
|
25649
|
-
if (Math.abs(vp.scrollTop - next) > .5) {
|
|
26552
|
+
} else if (Math.abs(vp.scrollTop - next) > .5) {
|
|
25650
26553
|
vp.scrollTop = next;
|
|
25651
26554
|
this._scrollTop = next;
|
|
25652
26555
|
}
|
|
25653
26556
|
}
|
|
25654
26557
|
#captureCentreAnchor(prevOffset, prevExtent, prevItemSize, prevGap, prevCaptionStyle, prevCaptionHeight, prevOrientation) {
|
|
25655
|
-
|
|
25656
|
-
if (count === 0) return;
|
|
26558
|
+
if ((this.#source?.count ?? 0) === 0) return;
|
|
25657
26559
|
const prevRowHeight = prevItemSize + (prevCaptionStyle === `separate` || prevCaptionStyle === `under` ? prevCaptionHeight : 0);
|
|
25658
|
-
const
|
|
25659
|
-
|
|
25660
|
-
|
|
25661
|
-
|
|
25662
|
-
|
|
25663
|
-
|
|
25664
|
-
this.#zoomAnchor =
|
|
25665
|
-
index,
|
|
25666
|
-
lineFrac: centerLine - lineFloor
|
|
25667
|
-
};
|
|
26560
|
+
const prev = this.#buildLayout({
|
|
26561
|
+
itemWidth: prevItemSize,
|
|
26562
|
+
rowHeight: prevRowHeight,
|
|
26563
|
+
gap: prevGap,
|
|
26564
|
+
orientation: prevOrientation
|
|
26565
|
+
});
|
|
26566
|
+
this.#zoomAnchor = prev.anchorAt(prevOffset + prevExtent / 2);
|
|
25668
26567
|
}
|
|
25669
26568
|
/**
|
|
25670
26569
|
* Re-read the viewport after an ancestor's visibility/layout changed.
|
|
@@ -25878,37 +26777,75 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25878
26777
|
return this.#windowKeys(this.#currentWindow(true));
|
|
25879
26778
|
}
|
|
25880
26779
|
#windowKeys(win) {
|
|
25881
|
-
|
|
26780
|
+
const keys = this.#source.keys();
|
|
26781
|
+
const out = [];
|
|
26782
|
+
for (const [start, end] of win.ranges) for (let i = start; i < end; i++) if (!isSyntheticKey(keys[i])) out.push(keys[i]);
|
|
26783
|
+
return out;
|
|
26784
|
+
}
|
|
26785
|
+
/** Layout params for the current geometry, with optional overrides (used for zoom anchoring). */
|
|
26786
|
+
#layoutParams(over = {}) {
|
|
26787
|
+
return {
|
|
26788
|
+
count: this.#source.count,
|
|
26789
|
+
groups: this.groupBy === null ? void 0 : this.#source.groups(),
|
|
26790
|
+
itemWidth: this.itemSize,
|
|
26791
|
+
rowHeight: this.#rowHeight(),
|
|
26792
|
+
gap: this.gap,
|
|
26793
|
+
viewportWidth: this._viewportWidth,
|
|
26794
|
+
viewportHeight: this._viewportHeight,
|
|
26795
|
+
orientation: this.orientation,
|
|
26796
|
+
headerHeight: this.groupHeaderHeight,
|
|
26797
|
+
headerWidth: this.groupHeaderWidth,
|
|
26798
|
+
...over
|
|
26799
|
+
};
|
|
26800
|
+
}
|
|
26801
|
+
#buildLayout(over = {}) {
|
|
26802
|
+
return buildLayout(this.#layoutParams(over));
|
|
26803
|
+
}
|
|
26804
|
+
#layoutCache;
|
|
26805
|
+
/** The current layout, rebuilt only when its inputs change (never per scroll). */
|
|
26806
|
+
#layout() {
|
|
26807
|
+
const params = this.#layoutParams();
|
|
26808
|
+
const cached = this.#layoutCache;
|
|
26809
|
+
if (cached) {
|
|
26810
|
+
const a = cached.params;
|
|
26811
|
+
let same = a.groups === params.groups;
|
|
26812
|
+
for (const k of Object.keys(params)) {
|
|
26813
|
+
if (!same) break;
|
|
26814
|
+
same = a[k] === params[k];
|
|
26815
|
+
}
|
|
26816
|
+
if (same) return cached.layout;
|
|
26817
|
+
}
|
|
26818
|
+
const layout = buildLayout(params);
|
|
26819
|
+
this.#layoutCache = {
|
|
26820
|
+
params,
|
|
26821
|
+
layout
|
|
26822
|
+
};
|
|
26823
|
+
return layout;
|
|
25882
26824
|
}
|
|
25883
26825
|
#currentWindow(noOverscan = false) {
|
|
25884
|
-
|
|
25885
|
-
return computeGridWindow(this.#source.count, this.itemSize, this.#rowHeight(), this.gap, this._viewportWidth, this._viewportHeight, this.orientation === `row` ? this._scrollLeft : this._scrollTop, this.orientation, overscan);
|
|
26826
|
+
return this.#layout().window(this.orientation === `row` ? this._scrollLeft : this._scrollTop, noOverscan ? 0 : 2);
|
|
25886
26827
|
}
|
|
25887
26828
|
/** Adjust the scroll offset so `key` is fully within the viewport. */
|
|
25888
26829
|
#scrollItemIntoView(key) {
|
|
25889
26830
|
const index = this.#source.indexOfKey(key);
|
|
25890
26831
|
const vp = this.#viewportRef.value;
|
|
25891
26832
|
if (index < 0 || !vp) return;
|
|
25892
|
-
const
|
|
25893
|
-
if (
|
|
25894
|
-
const left = index * win.colStride;
|
|
25895
|
-
const right = left + this.itemSize;
|
|
26833
|
+
const [start, end] = this.#layout().extentOf(index);
|
|
26834
|
+
if (this.orientation === `row`) {
|
|
25896
26835
|
const viewLeft = vp.scrollLeft;
|
|
25897
26836
|
let next = viewLeft;
|
|
25898
|
-
if (
|
|
25899
|
-
else if (
|
|
26837
|
+
if (start < viewLeft) next = start;
|
|
26838
|
+
else if (end > viewLeft + this._viewportWidth) next = end - this._viewportWidth;
|
|
25900
26839
|
if (next !== viewLeft) {
|
|
25901
26840
|
vp.scrollLeft = next;
|
|
25902
26841
|
this._scrollLeft = next;
|
|
25903
26842
|
}
|
|
25904
26843
|
return;
|
|
25905
26844
|
}
|
|
25906
|
-
const top = (win.cols > 0 ? Math.floor(index / win.cols) : 0) * win.rowStride;
|
|
25907
|
-
const bottom = top + this.#rowHeight();
|
|
25908
26845
|
const viewTop = vp.scrollTop;
|
|
25909
26846
|
let next = viewTop;
|
|
25910
|
-
if (
|
|
25911
|
-
else if (
|
|
26847
|
+
if (start < viewTop) next = start;
|
|
26848
|
+
else if (end > viewTop + this._viewportHeight) next = end - this._viewportHeight;
|
|
25912
26849
|
if (next !== viewTop) {
|
|
25913
26850
|
vp.scrollTop = next;
|
|
25914
26851
|
this._scrollTop = next;
|
|
@@ -25982,6 +26919,7 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25982
26919
|
>
|
|
25983
26920
|
<div class="spacer" style=${spacerStyle}>
|
|
25984
26921
|
${this.#source instanceof DataGridListSource ? this.#renderDataCells(win) : this.#renderElementCells(win)}
|
|
26922
|
+
${this.#renderHeaders(win)}
|
|
25985
26923
|
</div>
|
|
25986
26924
|
${this.#marqueeRect ? html`<div class="marquee" part="marquee" style=${this.#marqueeStyle(this.#marqueeRect)}></div>` : ``}
|
|
25987
26925
|
</div>
|
|
@@ -25989,7 +26927,7 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
25989
26927
|
`;
|
|
25990
26928
|
}
|
|
25991
26929
|
#renderDataCells(win) {
|
|
25992
|
-
const slice = Array.from({ length:
|
|
26930
|
+
const slice = win.ranges.flatMap(([start, end]) => Array.from({ length: end - start }, (_, i) => start + i));
|
|
25993
26931
|
return repeat(slice, (index) => this.#source.keyAt(index), (index) => this.#renderDataCell(index, win));
|
|
25994
26932
|
}
|
|
25995
26933
|
#renderDataCell(index, win) {
|
|
@@ -26004,8 +26942,7 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
26004
26942
|
const caption = style === `hidden` ? `` : this.#source.labelAt(index);
|
|
26005
26943
|
const showCaption = caption !== ``;
|
|
26006
26944
|
const cellHeight = win.rowStride - this.gap;
|
|
26007
|
-
const x
|
|
26008
|
-
const y = win.horizontal ? Math.max(0, (this._viewportHeight - cellHeight) / 2) : rowOf(index, win.cols) * win.rowStride;
|
|
26945
|
+
const { x, y } = this.#layout().positionOf(index);
|
|
26009
26946
|
const captionCss = separate ? `height:${Math.max(0, this.captionHeight - 4)}px` : style === `under` ? `height:${this.captionHeight}px` : ``;
|
|
26010
26947
|
const rawIcon = this.#source.iconAt(index);
|
|
26011
26948
|
const icon = appearanceAbsent(rawIcon) ? void 0 : rawIcon;
|
|
@@ -26091,8 +27028,25 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
26091
27028
|
current.startLoop?.();
|
|
26092
27029
|
}
|
|
26093
27030
|
#renderElementCells(win) {
|
|
26094
|
-
const slice =
|
|
26095
|
-
return repeat(slice, (
|
|
27031
|
+
const slice = win.ranges.flatMap(([start, end]) => Array.from({ length: end - start }, (_, i) => start + i));
|
|
27032
|
+
return repeat(slice, (index) => this.#source.keyAt(index), (index) => this.#renderCell(this.#items[index], index, win));
|
|
27033
|
+
}
|
|
27034
|
+
#renderHeaders(win) {
|
|
27035
|
+
if (win.headers.length === 0) return nothing;
|
|
27036
|
+
const horizontal = win.horizontal;
|
|
27037
|
+
return repeat(win.headers, (h) => `__group__${h.key}`, (h) => html`
|
|
27038
|
+
<ixfx-list-group-header
|
|
27039
|
+
class="group-header"
|
|
27040
|
+
part="group-header"
|
|
27041
|
+
data-group-key=${h.key}
|
|
27042
|
+
label=${h.label}
|
|
27043
|
+
count=${h.count}
|
|
27044
|
+
orientation=${horizontal ? `vertical` : `horizontal`}
|
|
27045
|
+
?collapsed=${h.collapsed}
|
|
27046
|
+
style=${horizontal ? `width:${h.size}px;height:100%;transform:translate(${h.offset}px,0)` : `width:100%;height:${h.size}px;transform:translate(0,${h.offset}px)`}
|
|
27047
|
+
@click=${() => this.toggleGroup(h.key)}
|
|
27048
|
+
></ixfx-list-group-header>
|
|
27049
|
+
`);
|
|
26096
27050
|
}
|
|
26097
27051
|
#renderCell(el, index, win) {
|
|
26098
27052
|
const key = this.#source.keyAt(index);
|
|
@@ -26107,8 +27061,7 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
26107
27061
|
const caption = style === `hidden` ? `` : this.#captionFor(el);
|
|
26108
27062
|
const showCaption = caption !== ``;
|
|
26109
27063
|
const cellHeight = win.rowStride - this.gap;
|
|
26110
|
-
const x
|
|
26111
|
-
const y = win.horizontal ? Math.max(0, (this._viewportHeight - cellHeight) / 2) : rowOf(index, win.cols) * win.rowStride;
|
|
27064
|
+
const { x, y } = this.#layout().positionOf(index);
|
|
26112
27065
|
const thumbStyle = separate ? `height:${this.itemSize}px` : ``;
|
|
26113
27066
|
const captionCss = separate ? `height:${Math.max(0, this.captionHeight - 4)}px` : style === `under` ? `height:${this.captionHeight}px` : ``;
|
|
26114
27067
|
return html`
|
|
@@ -26207,16 +27160,12 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
26207
27160
|
#snapToNearestLine() {
|
|
26208
27161
|
const vp = this.#viewportRef.value;
|
|
26209
27162
|
if (!vp) return;
|
|
26210
|
-
const
|
|
26211
|
-
const horizontal =
|
|
26212
|
-
const stride = horizontal ? win.colStride : win.rowStride;
|
|
26213
|
-
if (stride <= 0) return;
|
|
27163
|
+
const layout = this.#layout();
|
|
27164
|
+
const horizontal = layout.horizontal;
|
|
26214
27165
|
const offset = horizontal ? vp.scrollLeft : vp.scrollTop;
|
|
26215
|
-
const extent = horizontal ? win.totalWidth : win.totalHeight;
|
|
26216
27166
|
const viewportExtent = horizontal ? this._viewportWidth : this._viewportHeight;
|
|
26217
|
-
const maxScroll = Math.max(0,
|
|
26218
|
-
const
|
|
26219
|
-
const target = Math.min(maxScroll, Math.max(0, index * stride));
|
|
27167
|
+
const maxScroll = Math.max(0, layout.totalExtent - viewportExtent);
|
|
27168
|
+
const target = Math.min(maxScroll, Math.max(0, layout.snapTarget(offset)));
|
|
26220
27169
|
if (Math.abs(target - offset) < .5) return;
|
|
26221
27170
|
vp.scrollTo(horizontal ? {
|
|
26222
27171
|
left: target,
|
|
@@ -26244,7 +27193,7 @@ let GridListElement = class GridListElement extends LitElement {
|
|
|
26244
27193
|
if (mode === `manual`) return;
|
|
26245
27194
|
if (this.selectionMode === `none` && mode !== `checked` && mode !== `sticky`) return;
|
|
26246
27195
|
if (this.#dragSelect.isDragging || this.#nativeDragging || this.#nativeDrag.isDragging || this.#postDragSuppressTimer !== 0) return;
|
|
26247
|
-
for (const node of e.composedPath()) if (node instanceof Element && node.classList.contains(`cell`)) return;
|
|
27196
|
+
for (const node of e.composedPath()) if (node instanceof Element && (node.classList.contains(`cell`) || node.classList.contains(`group-header`))) return;
|
|
26248
27197
|
this.selection.clear();
|
|
26249
27198
|
}
|
|
26250
27199
|
#startPostDragSuppressTimer() {
|
|
@@ -26345,6 +27294,22 @@ __decorate([property({
|
|
|
26345
27294
|
})], GridListElement.prototype, "snapToItem", void 0);
|
|
26346
27295
|
__decorate([property({ attribute: false })], GridListElement.prototype, "items", void 0);
|
|
26347
27296
|
__decorate([property({ attribute: false })], GridListElement.prototype, "itemAdapter", void 0);
|
|
27297
|
+
__decorate([property({ attribute: `group-by` })], GridListElement.prototype, "groupBy", void 0);
|
|
27298
|
+
__decorate([property({ attribute: false })], GridListElement.prototype, "groupLabel", void 0);
|
|
27299
|
+
__decorate([property({
|
|
27300
|
+
type: Boolean,
|
|
27301
|
+
attribute: `cross-group-selection`,
|
|
27302
|
+
reflect: true
|
|
27303
|
+
})], GridListElement.prototype, "crossGroupSelection", void 0);
|
|
27304
|
+
__decorate([property({
|
|
27305
|
+
type: Number,
|
|
27306
|
+
attribute: `group-header-height`
|
|
27307
|
+
})], GridListElement.prototype, "groupHeaderHeight", void 0);
|
|
27308
|
+
__decorate([property({
|
|
27309
|
+
type: Number,
|
|
27310
|
+
attribute: `group-header-width`
|
|
27311
|
+
})], GridListElement.prototype, "groupHeaderWidth", void 0);
|
|
27312
|
+
__decorate([state()], GridListElement.prototype, "_collapsedGroups", void 0);
|
|
26348
27313
|
__decorate([state()], GridListElement.prototype, "_scrollTop", void 0);
|
|
26349
27314
|
__decorate([state()], GridListElement.prototype, "_scrollLeft", void 0);
|
|
26350
27315
|
__decorate([state()], GridListElement.prototype, "_viewportHeight", void 0);
|
|
@@ -53949,6 +54914,6 @@ function init() {
|
|
|
53949
54914
|
console.log(`Init`);
|
|
53950
54915
|
}
|
|
53951
54916
|
//#endregion
|
|
53952
|
-
export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, CheckedSelect, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DEFAULT_SIBLING_SPACING, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, HyperbolicTreeListElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IcicleTreeListElement, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListNativeDragController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, MulticolListElement, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, ShapefillValueElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeDropController, TreeKeyboardNavController, TreeListElement, TreemapListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applyIsometry, applySnapshot, applyTreeDrop, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, captionForEntry, clampToDisk, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, composeIsometry, computeCanonicalPositions, computeColour, computeHyperbolicLayout, computeIcicleLayout, computeLeafGeoms, computeTreemapLayout, createAcCompletionProvider, createDataListSearchAdapter, createDefaultListDragPreview, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, decomposeViewIsometry, distribute, dropTargetFor, euclideanRadiusForHyperbolicDistance, extractStack, findHyperbolicIdOf, findHyperbolicKeyPath, findHyperbolicNode, findHyperbolicPath, findHyperbolicPathById, findIcicleNode, findIciclePath, findNode, findPanelNode, findParentOf, findStackOf, findStackPathByName, findTreemapNode, findTreemapPath, geodesicInterpolate, geodesicPath, geodesicSegment, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, hyperbolicBranchId, hyperbolicChildIds, hyperbolicDistanceForEuclideanRadius, hyperbolicIdDepth, hyperbolicRelativeFrame, iconBus, identityIsometry, init, insertBeside, invertIsometry, isDragging, isHyperbolicDescendantId, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, mobiusAdd, mobiusFromOrigin, mobiusToOrigin, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, norm, normalise, normaliseValue, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, poincareDistance, pointerOverAnyHost, prefersReducedMotion, preserveRestoreWeights, pruneDraggedDescendants, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, rotationIsometry, serializeLayout, setActive, setIconFont, setPanelRestoreWeight, startListItemOutAnimation, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toSnapshot, toolbarGapIndex, translationFromOrigin, viewIsometry, walk, wrapRoot };
|
|
54917
|
+
export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, CheckedSelect, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DEFAULT_SIBLING_SPACING, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EMPTY_GROUP_LABEL, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, HyperbolicTreeListElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IcicleTreeListElement, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListGroupHeaderElement, ListNativeDragController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, MulticolListElement, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, ShapefillValueElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeDropController, TreeKeyboardNavController, TreeListElement, TreemapListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applyIsometry, applySnapshot, applyTreeDrop, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, captionForEntry, clampToDisk, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, composeIsometry, computeCanonicalPositions, computeColour, computeHyperbolicLayout, computeIcicleLayout, computeLeafGeoms, computeTreemapLayout, createAcCompletionProvider, createDataListSearchAdapter, createDefaultListDragPreview, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, decomposeViewIsometry, defaultGroupLabel, distribute, dropTargetFor, euclideanRadiusForHyperbolicDistance, extractStack, findHyperbolicIdOf, findHyperbolicKeyPath, findHyperbolicNode, findHyperbolicPath, findHyperbolicPathById, findIcicleNode, findIciclePath, findNode, findPanelNode, findParentOf, findStackOf, findStackPathByName, findTreemapNode, findTreemapPath, geodesicInterpolate, geodesicPath, geodesicSegment, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, hyperbolicBranchId, hyperbolicChildIds, hyperbolicDistanceForEuclideanRadius, hyperbolicIdDepth, hyperbolicRelativeFrame, iconBus, identityIsometry, init, insertBeside, invertIsometry, isDragging, isHyperbolicDescendantId, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, mobiusAdd, mobiusFromOrigin, mobiusToOrigin, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, norm, normalise, normaliseValue, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, partitionByGroup, poincareDistance, pointerOverAnyHost, prefersReducedMotion, preserveRestoreWeights, pruneDraggedDescendants, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveGroupKey, resolveLeafPath, resolveTracks, rotationIsometry, serializeLayout, setActive, setIconFont, setPanelRestoreWeight, startListItemOutAnimation, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toGroupKey, toSnapshot, toggleInSet, toolbarGapIndex, translationFromOrigin, viewIsometry, walk, wrapRoot };
|
|
53953
54918
|
|
|
53954
54919
|
//# sourceMappingURL=index.js.map
|