@ixfx/components 0.11.6 → 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 +213 -2
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +1766 -165
- package/bundle/index.js.map +1 -1
- package/dist/checkbox.d.ts +3 -0
- package/dist/checkbox.d.ts.map +1 -1
- package/dist/checkbox.js +24 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/checked-select-CglRukbP.d.ts +59 -0
- package/dist/checked-select-CglRukbP.d.ts.map +1 -0
- package/dist/checked-select-Dejl13qd.js +604 -0
- package/dist/checked-select-Dejl13qd.js.map +1 -0
- package/dist/checked-select.d.ts +2 -0
- package/dist/checked-select.js +3 -0
- package/dist/{detail-list-CmdCxddo.d.ts → detail-list-lE_5UWVl.d.ts} +36 -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 +293 -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/{hex-editor-BiRfwTz1.js → hex-editor-DiYpgIKs.js} +2 -2
- package/dist/{hex-editor-BiRfwTz1.js.map → hex-editor-DiYpgIKs.js.map} +1 -1
- package/dist/hex.js +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -6
- 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/plots.js +1 -1
- package/dist/vertical-list.js +1 -1
- package/dist/{xy-axis-COKw338Q.js → xy-axis-CyMd_Bn1.js} +2 -2
- package/dist/{xy-axis-COKw338Q.js.map → xy-axis-CyMd_Bn1.js.map} +1 -1
- package/docs-user/README.md +2 -0
- package/docs-user/checked-select.md +63 -0
- package/docs-user/detail-list.md +28 -0
- package/docs-user/grid-list.md +35 -3
- package/docs-user/index.json +12 -2
- package/docs-user/list-group-header.md +14 -0
- package/docs-user/llms.txt +2 -0
- package/llms.txt +2 -0
- package/package.json +9 -1
- package/dist/detail-list-CmdCxddo.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
|
@@ -3,8 +3,10 @@ import { r as IDataProvider } from "./data-provider-BAn_-oR1.js";
|
|
|
3
3
|
import { F as ListDragPreviewSourceResolver, P as ListDragPreviewRenderer, R as ListNativeDragStartEvent } from "./tree-component-DukLqesg.js";
|
|
4
4
|
import { n as ListViewportChangeEvent } from "./list-viewport-types-BRZsLcvp.js";
|
|
5
5
|
import { S as ListSearchController } from "./index-CMsmZ6Or.js";
|
|
6
|
+
import { a as ListGroupEventMap, o as ListGroupInfo, s as ListGroupLabel } from "./grouping-CUKgmkMm.js";
|
|
6
7
|
import { i as ListInteractionMode, l as ListSelectionMode, r as ListElementEventMap } from "./list-selection-types-PjKdhF-a.js";
|
|
7
8
|
import { n as CustomCheckboxOptions, t as AddItemOptions } from "./vertical-list-DTp-UIUE.js";
|
|
9
|
+
import "./list-group-header.js";
|
|
8
10
|
import { LitElement, PropertyValues } from "lit";
|
|
9
11
|
import { CommandId, CommandRegistry } from "@clinth/ui-commands";
|
|
10
12
|
//#region src/detail-list/types.d.ts
|
|
@@ -20,6 +22,12 @@ type DetailSortItem = {
|
|
|
20
22
|
type DetailSortComparator = (a: DetailSortItem, b: DetailSortItem) => number;
|
|
21
23
|
/** Turns one object item into row content — a plain string or a DOM node. */
|
|
22
24
|
type DetailFormatter = (item: unknown, index: number) => string | Node;
|
|
25
|
+
/**
|
|
26
|
+
* How a detail list derives an item's group key: a property name (object
|
|
27
|
+
* items) or `data-<name>` attribute, or a function of the item's data (`undefined`
|
|
28
|
+
* for declarative rows) and its `<li>` element.
|
|
29
|
+
*/
|
|
30
|
+
type DetailGroupBy = string | ((data: unknown, el: Element) => string);
|
|
23
31
|
//#endregion
|
|
24
32
|
//#region src/detail-list/detail-list.d.ts
|
|
25
33
|
/**
|
|
@@ -95,6 +103,21 @@ declare class DetailListElement extends LitElement {
|
|
|
95
103
|
*/
|
|
96
104
|
dragPreviewRenderer: ListDragPreviewRenderer<Element> | undefined;
|
|
97
105
|
dragPreviewSource: ListDragPreviewSourceResolver<Element> | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* Group rows under collapsible headers that flow inline in the columns. A
|
|
108
|
+
* string names an item property (object items) or a `data-<name>` attribute;
|
|
109
|
+
* a function derives the key from `(data, element)`. `null` = ungrouped.
|
|
110
|
+
* Groups appear in first-encounter order (after sorting and filtering).
|
|
111
|
+
*/
|
|
112
|
+
groupBy: DetailGroupBy | null;
|
|
113
|
+
/** Header label for a group. Defaults to the key (`(none)` for the empty key). */
|
|
114
|
+
groupLabel: ListGroupLabel | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* Let selection span groups. When `false` (default) selecting in one group
|
|
117
|
+
* clears the others and Shift-range / select-all stay inside one group.
|
|
118
|
+
*/
|
|
119
|
+
crossGroupSelection: boolean;
|
|
120
|
+
private _collapsedGroups;
|
|
98
121
|
private _listEl;
|
|
99
122
|
private readonly selection;
|
|
100
123
|
private tickled;
|
|
@@ -106,6 +129,7 @@ declare class DetailListElement extends LitElement {
|
|
|
106
129
|
connectedCallback(): void;
|
|
107
130
|
disconnectedCallback(): void;
|
|
108
131
|
firstUpdated(): void;
|
|
132
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
109
133
|
updated(changed: PropertyValues): void;
|
|
110
134
|
/** The most recently selected item, or `undefined` if nothing is selected. */
|
|
111
135
|
get selectedItem(): Element | undefined;
|
|
@@ -170,6 +194,13 @@ declare class DetailListElement extends LitElement {
|
|
|
170
194
|
/** Move the cursor to the item with this key and scroll it into view. */
|
|
171
195
|
focusKey(key: string): void;
|
|
172
196
|
selectedFilter(kind: `selected` | `checked` | `either`): Generator<Element>;
|
|
197
|
+
/** Groups in display order (empty when ungrouped). */
|
|
198
|
+
get groups(): readonly ListGroupInfo[];
|
|
199
|
+
/** Collapse or expand one group. Fires `list-group-toggle` when the state changes. */
|
|
200
|
+
setGroupCollapsed(groupKey: string, collapsed: boolean): void;
|
|
201
|
+
toggleGroup(groupKey: string): void;
|
|
202
|
+
collapseAllGroups(): void;
|
|
203
|
+
expandAllGroups(): void;
|
|
173
204
|
private _getVisibleItems;
|
|
174
205
|
/**
|
|
175
206
|
* Set the column width to fit the widest visible item.
|
|
@@ -199,6 +230,8 @@ declare class DetailListElement extends LitElement {
|
|
|
199
230
|
private _dispatchCancelable;
|
|
200
231
|
private _onPointerOver;
|
|
201
232
|
private _onPointerLeave;
|
|
233
|
+
/** Restores hover transitions once the pointer takes over from the keyboard. */
|
|
234
|
+
private _endKeyboardNav;
|
|
202
235
|
private _onKeyDown;
|
|
203
236
|
private _onClick;
|
|
204
237
|
private _onDblClick;
|
|
@@ -213,10 +246,10 @@ declare global {
|
|
|
213
246
|
}
|
|
214
247
|
interface HTMLElementEventMap extends DetailListElementEventMap {}
|
|
215
248
|
}
|
|
216
|
-
interface DetailListElementEventMap extends ListElementEventMap {
|
|
249
|
+
interface DetailListElementEventMap extends ListElementEventMap, ListGroupEventMap {
|
|
217
250
|
'detail-list-viewport-change': ListViewportChangeEvent;
|
|
218
251
|
'list-native-drag-start': ListNativeDragStartEvent<Element>;
|
|
219
252
|
}
|
|
220
253
|
//#endregion
|
|
221
|
-
export {
|
|
222
|
-
//# sourceMappingURL=detail-list-
|
|
254
|
+
export { DetailSortComparator as a, DetailGroupBy as i, DetailListElementEventMap as n, DetailSortItem as o, DetailFormatter as r, DetailSortMode as s, DetailListElement as t };
|
|
255
|
+
//# sourceMappingURL=detail-list-lE_5UWVl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detail-list-lE_5UWVl.d.ts","names":[],"sources":["../src/detail-list/types.ts","../src/detail-list/detail-list.ts"],"mappings":";;;;;;;;;;;;;KACY;;KAGA;WACD,SAAS;WACT;WACA;;;KAIC,wBAAwB,GAAG,gBAAgB,GAAG;;KAG9C,mBAAmB,eAAe,2BAA2B;;;;;;KAc7D,2BAA2B,eAAe,IAAI;;;;;;;;;;;;;;;;;;;;cCkI7C,0BAA0B;;EAErC,eAAe;EAGf,iBAAiB;EAGjB,MAAM;EAGN;EAGA,gBAAgB;EAGhB;EAGA,UAAU;EAGV;EAGA,WAAW;EAGX;;;;;EAOA;;;;;EAOA;;;;;;EAQA;EAGA;EAGA,mBAAmB,IAAI;;;;;;EAQvB;;EAIA,oBAAoB,gCAAgC;;;;;;EAQpD;;;;;;EAQA;;;;;EAOA,qBAAqB,wBAAwB;EAG7C,mBAAmB,8BAA8B;;;;;;;EASjD,SAAS;;EAIT,YAAY;;;;;EAOZ;UAEiB;UAGT;mBAiCS;UAqBT;UAyFA;;WAoGC,QAAM,qBAAA;;MAYX,YAAY;EAoBP;EAkEA;EA+BA;YASU,WAAW,SAAS;EAS9B,QAAQ,SAAS;;MA+DtB,gBAAgB;;MAKhB,iBAAiB,YAAY;;;;;;EASjC;EAIA,QAAQ,MAAM,kBAAkB,UAAU;;;;;EAwB1C,WAAW,MAAM,UAAU;;EAY3B,YAAY,OAAO,SAAS,WAAW;EAIvC;;;;;EAcA,SAAS,gBAAgB;;;;;EAiBzB,YAAY,MAAM;;;;;;;;;;EAalB;;;;;;EAsBA,SAAS,WAAW,WAAW,OAAO;EAItC,OAAO,MAAM;EAIb,WAAW,OAAO,SAAS;EAI3B,SAAS,MAAM;EAIf;EAIA;;MAQI,gBAAgB;;MAKhB;;EAMJ,WAAW,MAAM;;EAKjB,gBAAgB,MAAM;;EAKtB,mBAAmB,MAAM;;EAKzB,SAAS;EAgBP,eAAe,0CAA0C,UAAU;;MA8VjE,mBAAmB;;EAKvB,kBAAkB,kBAAkB;EAYpC,YAAY;EAIZ;EAKA;UAwRQ;;;;;;;;;EAoBF,kBAAkB;UAwBhB;;UAOA;UA2DA;UAiBA;;;;;;;UA2DA;;UAoBA;UAcA;UAYA;UAQA;UA6DA;UAMA;;UAKA;UAIA;UA+EA;UAiBA;UAMA;UAUA;SAUQ,sBAAM;EAyKb,wBAAM;;QAsBT;YACI;IACR,oBAAoB;;YAGZ,4BAA4B;;UAGvB,kCAAkC,qBAAqB;EACtE,+BAA+B;EAC/B,0BAA0B,yBAAyB"}
|
package/dist/detail-list.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { I as ListDragSource, L as ListNativeDragStartDetail, M as ListDragPreview, N as ListDragPreviewContext, P as ListDragPreviewRenderer, R as ListNativeDragStartEvent, j as ListDragEntry } from "./tree-component-DukLqesg.js";
|
|
2
2
|
import { n as ListViewportChangeEvent, t as ListViewportChangeDetail } from "./list-viewport-types-BRZsLcvp.js";
|
|
3
|
+
import { i as ListGroupChangeEvent, l as ListGroupToggleDetail, n as ListGroupBy, o as ListGroupInfo, r as ListGroupChangeDetail, s as ListGroupLabel, u as ListGroupToggleEvent } from "./grouping-CUKgmkMm.js";
|
|
3
4
|
import { n as CustomCheckboxOptions, t as AddItemOptions } from "./vertical-list-DTp-UIUE.js";
|
|
4
|
-
import { a as
|
|
5
|
-
export { type AddItemOptions, type CustomCheckboxOptions, type DetailFormatter, DetailListElement, DetailListElementEventMap, type DetailSortComparator, type DetailSortItem, type DetailSortMode, type ListDragEntry, type ListDragPreview, type ListDragPreviewContext, type ListDragPreviewRenderer, type ListDragSource, type ListNativeDragStartDetail, type ListNativeDragStartEvent, type ListViewportChangeDetail, type ListViewportChangeEvent };
|
|
5
|
+
import { a as DetailSortComparator, i as DetailGroupBy, n as DetailListElementEventMap, o as DetailSortItem, r as DetailFormatter, s as DetailSortMode, t as DetailListElement } from "./detail-list-lE_5UWVl.js";
|
|
6
|
+
export { type AddItemOptions, type CustomCheckboxOptions, type DetailFormatter, type DetailGroupBy, DetailListElement, DetailListElementEventMap, type DetailSortComparator, type DetailSortItem, type DetailSortMode, type ListDragEntry, type ListDragPreview, type ListDragPreviewContext, type ListDragPreviewRenderer, type ListDragSource, type ListGroupBy, type ListGroupChangeDetail, type ListGroupChangeEvent, type ListGroupInfo, type ListGroupLabel, type ListGroupToggleDetail, type ListGroupToggleEvent, type ListNativeDragStartDetail, type ListNativeDragStartEvent, type ListViewportChangeDetail, type ListViewportChangeEvent };
|
package/dist/detail-list.js
CHANGED
|
@@ -4,17 +4,29 @@ import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js"
|
|
|
4
4
|
import "./icon-1gpwtPx8.js";
|
|
5
5
|
import { t as DataController } from "./data-controller-DOlmqNKb.js";
|
|
6
6
|
import { c as createElementListSearchAdapter, i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, u as keyForElement } from "./incr-search-D91M4Ozq.js";
|
|
7
|
+
import { a as toGroupKey, r as partitionByGroup } from "./grouping-RYPnHkrS.js";
|
|
7
8
|
import { t as ListNativeDragController } from "./list-native-drag-controller-B9xO0XWn.js";
|
|
8
|
-
import { r as ListDragSelectController, t as ListSelectionController } from "./list-selection-controller-
|
|
9
|
+
import { r as ListDragSelectController, t as ListSelectionController } from "./list-selection-controller-BeE70lbB.js";
|
|
9
10
|
import { n as animateListItemIn, r as animateListItemOut } from "./list-item-animation-BUoEKi5s.js";
|
|
10
11
|
import { t as scrollFadeStyles } from "./scroll-fade-BrNUIYnm.js";
|
|
11
12
|
import { n as appearanceColor, t as appearanceAbsent } from "./item-appearance-BjcMyauw.js";
|
|
13
|
+
import "./list-group-header.js";
|
|
12
14
|
import { LitElement, css, html, nothing, render } from "lit";
|
|
13
|
-
import { property, query } from "lit/decorators.js";
|
|
15
|
+
import { property, query, state } from "lit/decorators.js";
|
|
14
16
|
import { createCommandRegistry } from "@clinth/ui-commands";
|
|
15
17
|
//#region src/detail-list/detail-list.ts
|
|
16
18
|
const ITEM_SELECTOR = `:scope > li`;
|
|
19
|
+
const GROUP_HEADER_ATTR = `data-ixfx-group-header`;
|
|
20
|
+
const GROUP_COLLAPSED_ATTR = `data-group-collapsed`;
|
|
17
21
|
const SEARCH_HIGHLIGHT_KEY = `detail-list-search`;
|
|
22
|
+
const NAV_KEYS = /* @__PURE__ */ new Set([
|
|
23
|
+
`ArrowDown`,
|
|
24
|
+
`ArrowUp`,
|
|
25
|
+
`ArrowLeft`,
|
|
26
|
+
`ArrowRight`,
|
|
27
|
+
`Home`,
|
|
28
|
+
`End`
|
|
29
|
+
]);
|
|
18
30
|
const LABEL_SPAN_CSS = `overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0`;
|
|
19
31
|
/**
|
|
20
32
|
* Layout for the per-item badge wrapper `#ensureBadge` adds. Applied as inline
|
|
@@ -63,14 +75,26 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
63
75
|
this.keyProperty = ``;
|
|
64
76
|
this.itemWrap = `stop`;
|
|
65
77
|
this.itemsDraggable = false;
|
|
78
|
+
this.groupBy = null;
|
|
79
|
+
this.crossGroupSelection = false;
|
|
80
|
+
this._collapsedGroups = /* @__PURE__ */ new Set();
|
|
66
81
|
this.#itemData = /* @__PURE__ */ new WeakMap();
|
|
67
82
|
this.#grid = [];
|
|
68
83
|
this.#positions = /* @__PURE__ */ new Map();
|
|
84
|
+
this.#tops = /* @__PURE__ */ new Map();
|
|
69
85
|
this.#geometryScheduled = false;
|
|
70
86
|
this.#sortRaf = 0;
|
|
71
87
|
this.#viewportScrollRaf = 0;
|
|
72
88
|
this.#animatedItems = /* @__PURE__ */ new WeakSet();
|
|
73
89
|
this.#builtFromProvider = [];
|
|
90
|
+
this.#groupIndex = /* @__PURE__ */ new Map();
|
|
91
|
+
this.#groupList = [];
|
|
92
|
+
this.#headerEls = /* @__PURE__ */ new Map();
|
|
93
|
+
this.#seq = /* @__PURE__ */ new WeakMap();
|
|
94
|
+
this.#seqNext = 0;
|
|
95
|
+
this.#wasGrouped = false;
|
|
96
|
+
this.#groupsScheduled = false;
|
|
97
|
+
this.#groupByChanged = false;
|
|
74
98
|
this.#providerBuilt = 0;
|
|
75
99
|
this.#data = new DataController(this);
|
|
76
100
|
this.selection = new ListSelectionController({
|
|
@@ -81,6 +105,12 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
81
105
|
interactionMode: this.interactionMode
|
|
82
106
|
}),
|
|
83
107
|
getKey: keyForElement,
|
|
108
|
+
getGroupKey: (el) => this.#groupIndex.get(el) ?? null,
|
|
109
|
+
crossGroupSelection: () => this.crossGroupSelection,
|
|
110
|
+
getFallbackGroupKey: () => {
|
|
111
|
+
const t = this.tickled.tickledId;
|
|
112
|
+
return t ? this.#groupIndex.get(t) ?? null : null;
|
|
113
|
+
},
|
|
84
114
|
onChange: (selected, previous) => {
|
|
85
115
|
this._syncItemStates();
|
|
86
116
|
this._dispatch(`list-select`, {
|
|
@@ -162,6 +192,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
162
192
|
if (this._listEl) this._listEl.scrollLeft += dx;
|
|
163
193
|
},
|
|
164
194
|
shouldStart: (event) => {
|
|
195
|
+
if (this.#findGroupHeader(event.composedPath())) return false;
|
|
165
196
|
this.#blankItemPressPending = this.itemsDraggable && this.#isBlankItemPress(event);
|
|
166
197
|
return !this.itemsDraggable || this.#blankItemPressPending;
|
|
167
198
|
}
|
|
@@ -185,6 +216,9 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
185
216
|
this._onPointerLeave = (e) => {
|
|
186
217
|
this.tickled.handlePointerLeave(e);
|
|
187
218
|
};
|
|
219
|
+
this._endKeyboardNav = () => {
|
|
220
|
+
this.removeAttribute(`data-keyboard-nav`);
|
|
221
|
+
};
|
|
188
222
|
this._onKeyDown = (e) => {
|
|
189
223
|
if (this.search.isOpen) return;
|
|
190
224
|
if ((e.ctrlKey || e.metaKey) && e.key === `a`) {
|
|
@@ -194,6 +228,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
194
228
|
}
|
|
195
229
|
return;
|
|
196
230
|
}
|
|
231
|
+
if (NAV_KEYS.has(e.key)) this.setAttribute(`data-keyboard-nav`, ``);
|
|
197
232
|
switch (e.key) {
|
|
198
233
|
case `ArrowDown`:
|
|
199
234
|
e.preventDefault();
|
|
@@ -249,7 +284,13 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
249
284
|
};
|
|
250
285
|
this._onClick = (e) => {
|
|
251
286
|
if (this.#dragSelect.isDragging || this.#nativeDrag.isDragging || this.#postDragSuppressTimer !== 0) return;
|
|
252
|
-
const
|
|
287
|
+
const path = e.composedPath();
|
|
288
|
+
const header = this.#findGroupHeader(path);
|
|
289
|
+
if (header) {
|
|
290
|
+
this.toggleGroup(header.dataset.groupKey ?? ``);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const item = this._findListItem(path);
|
|
253
294
|
if (!item) return;
|
|
254
295
|
this.focus();
|
|
255
296
|
this._dispatch(`list-item-click`, { item });
|
|
@@ -268,6 +309,8 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
268
309
|
#itemData;
|
|
269
310
|
#grid;
|
|
270
311
|
#positions;
|
|
312
|
+
/** Viewport-relative `top` per item at the last geometry pass — lines rows up across columns. */
|
|
313
|
+
#tops;
|
|
271
314
|
#geometryScheduled;
|
|
272
315
|
#sortRaf;
|
|
273
316
|
#viewportScrollRaf;
|
|
@@ -279,6 +322,17 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
279
322
|
/** Items that have already played (or been skipped for) their enter animation. */
|
|
280
323
|
#animatedItems;
|
|
281
324
|
#builtFromProvider;
|
|
325
|
+
/** Element → group key, for the selection controller. Empty while ungrouped. */
|
|
326
|
+
#groupIndex;
|
|
327
|
+
#groupList;
|
|
328
|
+
#headerEls;
|
|
329
|
+
/** Insertion sequence per item, so regrouping starts from the original order. */
|
|
330
|
+
#seq;
|
|
331
|
+
#seqNext;
|
|
332
|
+
#wasGrouped;
|
|
333
|
+
#groupsScheduled;
|
|
334
|
+
#groupByChanged;
|
|
335
|
+
#groupObserver;
|
|
282
336
|
#providerBuilt;
|
|
283
337
|
#data;
|
|
284
338
|
#nativeDragging;
|
|
@@ -382,6 +436,8 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
382
436
|
this.addEventListener(`pointerover`, this._onPointerOver);
|
|
383
437
|
this.addEventListener(`pointerleave`, this._onPointerLeave);
|
|
384
438
|
this.addEventListener(`keydown`, this._onKeyDown);
|
|
439
|
+
this.addEventListener(`pointermove`, this._endKeyboardNav);
|
|
440
|
+
this.addEventListener(`pointerdown`, this._endKeyboardNav);
|
|
385
441
|
this.addEventListener(`click`, this._onClick);
|
|
386
442
|
this.addEventListener(`dblclick`, this._onDblClick);
|
|
387
443
|
this.addEventListener(`wheel`, this._onWheel);
|
|
@@ -393,6 +449,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
393
449
|
this.#processChildren();
|
|
394
450
|
this.#animateChildMutations(records);
|
|
395
451
|
this.#scheduleGeometry();
|
|
452
|
+
this.#scheduleGroups();
|
|
396
453
|
});
|
|
397
454
|
this.#mutationObserver.observe(this, {
|
|
398
455
|
childList: true,
|
|
@@ -402,6 +459,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
402
459
|
for (const el of this.querySelectorAll(ITEM_SELECTOR)) this.#animatedItems.add(el);
|
|
403
460
|
this.#searchRegistry ??= createCommandRegistry();
|
|
404
461
|
this.#syncSearchCommands();
|
|
462
|
+
this.#scheduleGroups();
|
|
405
463
|
}
|
|
406
464
|
/**
|
|
407
465
|
* Collapse-in items appended to the light DOM (however they got there). A bulk
|
|
@@ -428,6 +486,8 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
428
486
|
this.removeEventListener(`pointerover`, this._onPointerOver);
|
|
429
487
|
this.removeEventListener(`pointerleave`, this._onPointerLeave);
|
|
430
488
|
this.removeEventListener(`keydown`, this._onKeyDown);
|
|
489
|
+
this.removeEventListener(`pointermove`, this._endKeyboardNav);
|
|
490
|
+
this.removeEventListener(`pointerdown`, this._endKeyboardNav);
|
|
431
491
|
this.removeEventListener(`click`, this._onClick);
|
|
432
492
|
this.removeEventListener(`dblclick`, this._onDblClick);
|
|
433
493
|
this.removeEventListener(`wheel`, this._onWheel);
|
|
@@ -441,6 +501,8 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
441
501
|
this.#resizeObserver = void 0;
|
|
442
502
|
this.#mutationObserver?.disconnect();
|
|
443
503
|
this.#mutationObserver = void 0;
|
|
504
|
+
this.#groupObserver?.disconnect();
|
|
505
|
+
this.#groupObserver = void 0;
|
|
444
506
|
this.#unregisterSearchCommands?.();
|
|
445
507
|
this.#unregisterSearchCommands = void 0;
|
|
446
508
|
this.#searchRegistry = void 0;
|
|
@@ -455,8 +517,22 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
455
517
|
this.#recomputeGeometry();
|
|
456
518
|
this._syncNativeDraggable();
|
|
457
519
|
}
|
|
520
|
+
willUpdate(changed) {
|
|
521
|
+
super.willUpdate(changed);
|
|
522
|
+
if (changed.has(`groupBy`) && this.hasUpdated) {
|
|
523
|
+
if (this._collapsedGroups.size > 0) this._collapsedGroups = /* @__PURE__ */ new Set();
|
|
524
|
+
this.#groupByChanged = true;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
458
527
|
updated(changed) {
|
|
459
528
|
super.updated(changed);
|
|
529
|
+
if (changed.has(`groupBy`) || changed.has(`groupLabel`) || changed.has(`_collapsedGroups`)) {
|
|
530
|
+
this.#scheduleGroups();
|
|
531
|
+
if (this.#groupByChanged) {
|
|
532
|
+
this.#groupByChanged = false;
|
|
533
|
+
this._dispatch(`list-group-change`, { groupBy: this.groupBy });
|
|
534
|
+
}
|
|
535
|
+
}
|
|
460
536
|
if (changed.has(`searchModes`)) this.#syncSearchCommands();
|
|
461
537
|
if (changed.has(`provider`)) {
|
|
462
538
|
this.#builtFromProvider = [];
|
|
@@ -473,6 +549,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
473
549
|
if (changed.has(`filterPredicate`)) {
|
|
474
550
|
this.#applyFilterPredicate();
|
|
475
551
|
this.#scheduleGeometry();
|
|
552
|
+
this.#scheduleGroups();
|
|
476
553
|
}
|
|
477
554
|
if (changed.has(`interactionMode`)) {
|
|
478
555
|
this.selection.clearAnchor();
|
|
@@ -512,6 +589,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
512
589
|
this.#ensureIcon(el);
|
|
513
590
|
if (this.sort !== `none`) this.#applySort();
|
|
514
591
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
592
|
+
this.#scheduleGroups();
|
|
515
593
|
}
|
|
516
594
|
/**
|
|
517
595
|
* Collapse + fade `item` out, then detach it; the rows after it slide up to
|
|
@@ -521,6 +599,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
521
599
|
this.selection.deselect(item);
|
|
522
600
|
return animateListItemOut(item).then(() => {
|
|
523
601
|
item.remove();
|
|
602
|
+
this.#scheduleGroups();
|
|
524
603
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
525
604
|
this.#recomputeGeometry();
|
|
526
605
|
});
|
|
@@ -531,6 +610,8 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
531
610
|
}
|
|
532
611
|
clearItems() {
|
|
533
612
|
this.replaceChildren();
|
|
613
|
+
this.#headerEls.clear();
|
|
614
|
+
this.#scheduleGroups();
|
|
534
615
|
this.selection.reset();
|
|
535
616
|
this.#builtFromProvider = [];
|
|
536
617
|
this.#providerBuilt = 0;
|
|
@@ -548,6 +629,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
548
629
|
}
|
|
549
630
|
if (this.sort !== `none`) this.#applySort();
|
|
550
631
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
632
|
+
this.#scheduleGroups();
|
|
551
633
|
}
|
|
552
634
|
/**
|
|
553
635
|
* Get the source object behind an `<li>` built from an `items` array or
|
|
@@ -667,6 +749,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
667
749
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
668
750
|
this._syncItemStates();
|
|
669
751
|
this.#scheduleGeometry();
|
|
752
|
+
this.#scheduleGroups();
|
|
670
753
|
}
|
|
671
754
|
#createItemEl(item, index) {
|
|
672
755
|
const li = document.createElement(`li`);
|
|
@@ -718,6 +801,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
718
801
|
if (this.interactionMode === `checked`) this._syncCheckboxes();
|
|
719
802
|
this._syncItemStates();
|
|
720
803
|
this.#scheduleGeometry();
|
|
804
|
+
this.#scheduleGroups();
|
|
721
805
|
} else {
|
|
722
806
|
this.#providerBuilt = 0;
|
|
723
807
|
this.#rebuildFromObjects(items);
|
|
@@ -736,6 +820,16 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
736
820
|
if (this.sort === `none`) return;
|
|
737
821
|
const rows = [...this.querySelectorAll(ITEM_SELECTOR)];
|
|
738
822
|
if (rows.length < 2) return;
|
|
823
|
+
if (this.#groupingActive()) {
|
|
824
|
+
this.#scheduleGroups();
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
for (const el of this.#sortRows(rows)) this.appendChild(el);
|
|
828
|
+
this.#scheduleGeometry();
|
|
829
|
+
this.#scheduleGroups();
|
|
830
|
+
}
|
|
831
|
+
/** Stable sort of `rows` by the current `sort` / `sortBy` / `sortComparator`. */
|
|
832
|
+
#sortRows(rows) {
|
|
739
833
|
const dir = this.sort === `descending` ? -1 : 1;
|
|
740
834
|
const meta = (el) => ({
|
|
741
835
|
element: el,
|
|
@@ -765,9 +859,147 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
765
859
|
i
|
|
766
860
|
}));
|
|
767
861
|
indexed.sort((a, b) => cmp(a.el, b.el) * dir || a.i - b.i);
|
|
768
|
-
|
|
862
|
+
return indexed.map(({ el }) => el);
|
|
863
|
+
}
|
|
864
|
+
#groupingActive() {
|
|
865
|
+
return this.groupBy !== null && this.groupBy !== void 0 && this.groupBy !== ``;
|
|
866
|
+
}
|
|
867
|
+
/** Coalesce regrouping to one pass per microtask (streaming batches, search keystrokes). */
|
|
868
|
+
#scheduleGroups() {
|
|
869
|
+
if (this.#groupsScheduled || !this.#groupingActive() && !this.#wasGrouped) return;
|
|
870
|
+
this.#groupsScheduled = true;
|
|
871
|
+
queueMicrotask(() => {
|
|
872
|
+
this.#groupsScheduled = false;
|
|
873
|
+
this.#syncGroups();
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
#groupValue(el, name) {
|
|
877
|
+
return this.#propertyValue(this.getItemData(el), name) ?? el.getAttribute(`data-${name}`);
|
|
878
|
+
}
|
|
879
|
+
#groupKeyOf(el) {
|
|
880
|
+
const by = this.groupBy;
|
|
881
|
+
if (typeof by === `string`) return toGroupKey(this.#groupValue(el, by));
|
|
882
|
+
return toGroupKey(by(this.getItemData(el), el));
|
|
883
|
+
}
|
|
884
|
+
#isItemVisible(el) {
|
|
885
|
+
return !el.hidden && (!this.filterPredicate || this.filterPredicate(el));
|
|
886
|
+
}
|
|
887
|
+
#headerFor(key) {
|
|
888
|
+
let header = this.#headerEls.get(key);
|
|
889
|
+
if (!header) {
|
|
890
|
+
header = document.createElement(`ixfx-list-group-header`);
|
|
891
|
+
header.setAttribute(GROUP_HEADER_ATTR, ``);
|
|
892
|
+
header.dataset.groupKey = key;
|
|
893
|
+
this.#headerEls.set(key, header);
|
|
894
|
+
}
|
|
895
|
+
return header;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Bring the light DOM into grouped order: original order → sort → partition
|
|
899
|
+
* into contiguous groups, each preceded by a header row. Idempotent — it only
|
|
900
|
+
* touches the DOM when the order actually changes, so it never loops through
|
|
901
|
+
* the mutation observer. Ungrouping restores the original (sorted) order.
|
|
902
|
+
*/
|
|
903
|
+
#syncGroups() {
|
|
904
|
+
const active = this.#groupingActive();
|
|
905
|
+
if (!active && !this.#wasGrouped) return;
|
|
906
|
+
const items = [...this.querySelectorAll(ITEM_SELECTOR)];
|
|
907
|
+
for (const el of items) if (!this.#seq.has(el)) this.#seq.set(el, this.#seqNext++);
|
|
908
|
+
let ordered = items.toSorted((a, b) => this.#seq.get(a) - this.#seq.get(b));
|
|
909
|
+
if (this.sort !== `none` && ordered.length > 1) ordered = this.#sortRows(ordered);
|
|
910
|
+
const nodes = [];
|
|
911
|
+
const info = [];
|
|
912
|
+
const index = /* @__PURE__ */ new Map();
|
|
913
|
+
const liveHeaders = /* @__PURE__ */ new Set();
|
|
914
|
+
if (active) {
|
|
915
|
+
const label = this.groupLabel;
|
|
916
|
+
const parts = partitionByGroup(ordered, (el) => this.#groupKeyOf(el), label ? (key, els) => label(key, els.map((el) => this.getItemData(el) ?? el)) : void 0);
|
|
917
|
+
for (const part of parts) {
|
|
918
|
+
const count = part.items.filter((el) => this.#isItemVisible(el)).length;
|
|
919
|
+
const collapsed = count > 0 && this._collapsedGroups.has(part.key);
|
|
920
|
+
if (count > 0) {
|
|
921
|
+
const header = this.#headerFor(part.key);
|
|
922
|
+
header.label = part.label;
|
|
923
|
+
header.count = count;
|
|
924
|
+
header.collapsed = collapsed;
|
|
925
|
+
liveHeaders.add(part.key);
|
|
926
|
+
nodes.push(header);
|
|
927
|
+
info.push({
|
|
928
|
+
key: part.key,
|
|
929
|
+
label: part.label,
|
|
930
|
+
count,
|
|
931
|
+
collapsed: this._collapsedGroups.has(part.key)
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
for (const el of part.items) {
|
|
935
|
+
index.set(el, part.key);
|
|
936
|
+
el.toggleAttribute(GROUP_COLLAPSED_ATTR, collapsed);
|
|
937
|
+
nodes.push(el);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
} else {
|
|
941
|
+
for (const el of ordered) el.removeAttribute(GROUP_COLLAPSED_ATTR);
|
|
942
|
+
nodes.push(...ordered);
|
|
943
|
+
}
|
|
944
|
+
for (const [key, header] of this.#headerEls) if (!liveHeaders.has(key)) {
|
|
945
|
+
header.remove();
|
|
946
|
+
this.#headerEls.delete(key);
|
|
947
|
+
}
|
|
948
|
+
this.#groupIndex = index;
|
|
949
|
+
this.#groupList = info;
|
|
950
|
+
this.#wasGrouped = active;
|
|
951
|
+
const current = [...this.children].filter((c) => c.matches(`li`) || c.hasAttribute(GROUP_HEADER_ATTR));
|
|
952
|
+
if (current.length !== nodes.length || current.some((c, i) => c !== nodes[i])) this.append(...nodes);
|
|
953
|
+
if (this.tickled.tickledId?.hasAttribute(GROUP_COLLAPSED_ATTR)) this.tickled.focus(void 0);
|
|
954
|
+
this.#syncGroupObserver(active);
|
|
769
955
|
this.#scheduleGeometry();
|
|
770
956
|
}
|
|
957
|
+
/** Filter-search hides rows via `hidden` on the `<li>`s — regroup when that changes. */
|
|
958
|
+
#syncGroupObserver(active) {
|
|
959
|
+
if (!active) {
|
|
960
|
+
this.#groupObserver?.disconnect();
|
|
961
|
+
this.#groupObserver = void 0;
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
if (this.#groupObserver || !this.isConnected) return;
|
|
965
|
+
this.#groupObserver = new MutationObserver(() => this.#scheduleGroups());
|
|
966
|
+
this.#groupObserver.observe(this, {
|
|
967
|
+
subtree: true,
|
|
968
|
+
attributes: true,
|
|
969
|
+
attributeFilter: [`hidden`]
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
/** Groups in display order (empty when ungrouped). */
|
|
973
|
+
get groups() {
|
|
974
|
+
return this.#groupList;
|
|
975
|
+
}
|
|
976
|
+
/** Collapse or expand one group. Fires `list-group-toggle` when the state changes. */
|
|
977
|
+
setGroupCollapsed(groupKey, collapsed) {
|
|
978
|
+
if (this._collapsedGroups.has(groupKey) === collapsed) return;
|
|
979
|
+
const next = new Set(this._collapsedGroups);
|
|
980
|
+
if (collapsed) next.add(groupKey);
|
|
981
|
+
else next.delete(groupKey);
|
|
982
|
+
this._collapsedGroups = next;
|
|
983
|
+
this._dispatch(`list-group-toggle`, {
|
|
984
|
+
groupKey,
|
|
985
|
+
collapsed
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
toggleGroup(groupKey) {
|
|
989
|
+
this.setGroupCollapsed(groupKey, !this._collapsedGroups.has(groupKey));
|
|
990
|
+
}
|
|
991
|
+
collapseAllGroups() {
|
|
992
|
+
for (const g of this.#groupList) this.setGroupCollapsed(g.key, true);
|
|
993
|
+
}
|
|
994
|
+
expandAllGroups() {
|
|
995
|
+
for (const key of [...this._collapsedGroups]) this.setGroupCollapsed(key, false);
|
|
996
|
+
}
|
|
997
|
+
#findGroupHeader(path) {
|
|
998
|
+
for (const target of path) {
|
|
999
|
+
if (target === this) break;
|
|
1000
|
+
if (target instanceof HTMLElement && target.parentElement === this && target.hasAttribute(GROUP_HEADER_ATTR)) return target;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
771
1003
|
#scheduleGeometry() {
|
|
772
1004
|
if (this.#geometryScheduled) return;
|
|
773
1005
|
this.#geometryScheduled = true;
|
|
@@ -779,11 +1011,13 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
779
1011
|
#recomputeGeometry() {
|
|
780
1012
|
this.#grid = [];
|
|
781
1013
|
this.#positions.clear();
|
|
1014
|
+
this.#tops.clear();
|
|
782
1015
|
if (!this.isConnected) return;
|
|
783
1016
|
const columns = [];
|
|
784
1017
|
for (const el of this._getVisibleItems()) {
|
|
785
1018
|
const rect = el.getBoundingClientRect();
|
|
786
1019
|
if (rect.width === 0 && rect.height === 0) continue;
|
|
1020
|
+
this.#tops.set(el, rect.top);
|
|
787
1021
|
let ci = columns.findIndex((c) => Math.abs(c.left - rect.left) <= 1);
|
|
788
1022
|
if (ci === -1) {
|
|
789
1023
|
columns.push({
|
|
@@ -904,6 +1138,30 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
904
1138
|
const next = this.#findNextCheckable(cur.col, cur.row, 0, -1);
|
|
905
1139
|
if (next) this.#navigateTo(next);
|
|
906
1140
|
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Left/Right target. Ungrouped lists keep the row-index rule. Grouped lists
|
|
1143
|
+
* have headers at arbitrary heights, so an item's row index no longer equals
|
|
1144
|
+
* its visual row — pick the item in the neighbouring column whose top is
|
|
1145
|
+
* nearest the cursor's (ties go to the upper one).
|
|
1146
|
+
*/
|
|
1147
|
+
#horizontalTarget(from, dir) {
|
|
1148
|
+
if (this.#groupList.length === 0) return this.#findNextCheckable(from.col, from.row, dir, 0);
|
|
1149
|
+
const column = this.#grid[from.col + dir];
|
|
1150
|
+
const current = this.tickled.tickledId;
|
|
1151
|
+
const top = current ? this.#tops.get(current) : void 0;
|
|
1152
|
+
if (!column || top === void 0) return void 0;
|
|
1153
|
+
let best;
|
|
1154
|
+
let bestDelta = Number.POSITIVE_INFINITY;
|
|
1155
|
+
for (const el of column) {
|
|
1156
|
+
if (!this._isCheckable(el)) continue;
|
|
1157
|
+
const delta = Math.abs((this.#tops.get(el) ?? Number.POSITIVE_INFINITY) - top);
|
|
1158
|
+
if (delta < bestDelta) {
|
|
1159
|
+
best = el;
|
|
1160
|
+
bestDelta = delta;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
return best;
|
|
1164
|
+
}
|
|
907
1165
|
#navigateRight() {
|
|
908
1166
|
this.#recomputeGeometry();
|
|
909
1167
|
const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : void 0;
|
|
@@ -911,7 +1169,7 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
911
1169
|
this.#navigateTo(this.#findFirstCheckable());
|
|
912
1170
|
return;
|
|
913
1171
|
}
|
|
914
|
-
const next = this.#
|
|
1172
|
+
const next = this.#horizontalTarget(cur, 1);
|
|
915
1173
|
if (next) this.#navigateTo(next);
|
|
916
1174
|
else if (this.itemWrap === `wrap`) this.#navigateTo(this.#findFirstCheckable());
|
|
917
1175
|
}
|
|
@@ -922,13 +1180,14 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
922
1180
|
this.#navigateTo(this.#findFirstCheckable());
|
|
923
1181
|
return;
|
|
924
1182
|
}
|
|
925
|
-
const next = this.#
|
|
1183
|
+
const next = this.#horizontalTarget(cur, -1);
|
|
926
1184
|
if (next) this.#navigateTo(next);
|
|
927
1185
|
else if (this.itemWrap === `wrap`) this.#navigateTo(this.#findLastCheckable());
|
|
928
1186
|
}
|
|
929
1187
|
_getVisibleItems() {
|
|
930
1188
|
return Array.from(this.querySelectorAll(ITEM_SELECTOR)).filter((el) => {
|
|
931
1189
|
if (el.hidden) return false;
|
|
1190
|
+
if (el.hasAttribute(GROUP_COLLAPSED_ATTR)) return false;
|
|
932
1191
|
if (this.filterPredicate && !this.filterPredicate(el)) return false;
|
|
933
1192
|
return true;
|
|
934
1193
|
});
|
|
@@ -1217,6 +1476,20 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
1217
1476
|
display: none !important;
|
|
1218
1477
|
}
|
|
1219
1478
|
|
|
1479
|
+
/* Rows of a collapsed group leave the flow; their header stays. */
|
|
1480
|
+
::slotted([data-group-collapsed]) {
|
|
1481
|
+
display: none !important;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
/* Group headers are rows in the column flow, the same size as an item. */
|
|
1485
|
+
::slotted(ixfx-list-group-header) {
|
|
1486
|
+
box-sizing: border-box;
|
|
1487
|
+
flex: none;
|
|
1488
|
+
width: var(--detail-list-column-width, 220px);
|
|
1489
|
+
height: var(--detail-list-item-height, 28px);
|
|
1490
|
+
--list-group-header-height: var(--detail-list-group-header-height, var(--detail-list-item-height, 28px));
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1220
1493
|
::slotted(li) {
|
|
1221
1494
|
box-sizing: border-box;
|
|
1222
1495
|
display: flex;
|
|
@@ -1232,6 +1505,12 @@ let DetailListElement = class DetailListElement extends LitElement {
|
|
|
1232
1505
|
outline: 1px solid transparent;
|
|
1233
1506
|
}
|
|
1234
1507
|
|
|
1508
|
+
/* While navigating by keyboard, key-repeat outpaces the 0.1s fade so the
|
|
1509
|
+
cursor smears across rows. Snap instead. */
|
|
1510
|
+
:host([data-keyboard-nav]) ::slotted(li) {
|
|
1511
|
+
transition: none;
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1235
1514
|
/* In checked mode, only the checkbox column is clickable; the row body
|
|
1236
1515
|
gets a default cursor so it doesn't suggest otherwise. */
|
|
1237
1516
|
:host([interaction-mode="checked"]) ::slotted(li) {
|
|
@@ -1387,6 +1666,14 @@ __decorate([property({
|
|
|
1387
1666
|
})], DetailListElement.prototype, "itemsDraggable", void 0);
|
|
1388
1667
|
__decorate([property({ attribute: false })], DetailListElement.prototype, "dragPreviewRenderer", void 0);
|
|
1389
1668
|
__decorate([property({ attribute: false })], DetailListElement.prototype, "dragPreviewSource", void 0);
|
|
1669
|
+
__decorate([property({ attribute: `group-by` })], DetailListElement.prototype, "groupBy", void 0);
|
|
1670
|
+
__decorate([property({ attribute: false })], DetailListElement.prototype, "groupLabel", void 0);
|
|
1671
|
+
__decorate([property({
|
|
1672
|
+
type: Boolean,
|
|
1673
|
+
attribute: `cross-group-selection`,
|
|
1674
|
+
reflect: true
|
|
1675
|
+
})], DetailListElement.prototype, "crossGroupSelection", void 0);
|
|
1676
|
+
__decorate([state()], DetailListElement.prototype, "_collapsedGroups", void 0);
|
|
1390
1677
|
__decorate([query(`ul`)], DetailListElement.prototype, "_listEl", void 0);
|
|
1391
1678
|
DetailListElement = __decorate([safeCustomElement(`ixfx-detail-list`)], DetailListElement);
|
|
1392
1679
|
//#endregion
|