@ixfx/components 0.13.1 → 0.13.2
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 +3 -0
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +28 -0
- package/bundle/index.js.map +1 -1
- package/dist/{flat-list-DEDG6epz.d.ts → flat-list-Ohxqsy0g.d.ts} +4 -1
- package/dist/flat-list-Ohxqsy0g.d.ts.map +1 -0
- package/dist/flat-list.d.ts +1 -1
- package/dist/flat-list.js +28 -0
- package/dist/flat-list.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/docs-user/flat-list.md +14 -2
- package/docs-user/index.json +2 -2
- package/package.json +1 -1
- package/dist/flat-list-DEDG6epz.d.ts.map +0 -1
|
@@ -91,6 +91,7 @@ interface FlatListElementEventMap {
|
|
|
91
91
|
* --flat-list-radius: var(--list-radius, var(--radius-s));
|
|
92
92
|
* --flat-list-crumb-padding: var(--space-xs);
|
|
93
93
|
* --flat-list-crumb-font-size: var(--text-s);
|
|
94
|
+
* --flat-list-toolbar-gap: var(--space-xs); // between the crumbs and slotted toolbar items
|
|
94
95
|
* --flat-list-chevron-gap: 0.4em; // space after the branch chevron
|
|
95
96
|
* --flat-list-marked-bg / --flat-list-marked-bar: the `marked-key` row
|
|
96
97
|
* --flat-list-empty-text: var(--surface-muted-text);
|
|
@@ -137,6 +138,8 @@ declare class FlatListElement extends LitElement {
|
|
|
137
138
|
emptyText: string;
|
|
138
139
|
/** Mirrors the inner list's `:focus-visible`, so the ring can go round the whole component. */
|
|
139
140
|
private _focusVisible;
|
|
141
|
+
/** Whether anything is slotted into the toolbar; an empty toolbar takes no space. */
|
|
142
|
+
private _hasToolbar;
|
|
140
143
|
private _rows;
|
|
141
144
|
private _loading;
|
|
142
145
|
/** The inner list, for registry / search commands and other advanced use. */
|
|
@@ -178,4 +181,4 @@ interface FlatListElement {
|
|
|
178
181
|
}
|
|
179
182
|
//#endregion
|
|
180
183
|
export { FlatListSelectEvent as _, FlatListContextMenuDetail as a, FlatListDropEvent as c, FlatListEditCommitDetail as d, FlatListEditCommitEvent as f, FlatListSelectDetail as g, FlatListNavigateEvent as h, FlatListBranchOrder as i, FlatListEditCancelDetail as l, FlatListNavigateDetail as m, FlatListActivateDetail as n, FlatListContextMenuEvent as o, FlatListElementEventMap as p, FlatListActivateEvent as r, FlatListDropDetail as s, FlatListElement as t, FlatListEditCancelEvent as u };
|
|
181
|
-
//# sourceMappingURL=flat-list-
|
|
184
|
+
//# sourceMappingURL=flat-list-Ohxqsy0g.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flat-list-Ohxqsy0g.d.ts","names":[],"sources":["../src/flat-list/types.ts","../src/flat-list/flat-list.ts"],"mappings":";;;;;;;;;KAGY;KAEA;;WAED;;WAEA;;WAEA,MAAM;;WAEN;;KAGC;WACD,UAAU,YAAY;WACtB,cAAc;WACd,UAAU,YAAY;;KAGrB;WACD,MAAM;;KAGL;;WAED,MAAM;WACN,cAAc;;KAGb;;WAED,MAAM;;WAEN,gBAAgB;WAChB;WACA;;KAGC;WACD,MAAM;WACN;;KAGC;WACD,MAAM;;KAGL,wBAAwB,YAAY;KACpC,sBAAsB,YAAY;KAClC,wBAAwB,YAAY;KAEpC,oBAAoB,YAAY;KAChC,2BAA2B,YAAY;KACvC,0BAA0B,YAAY;KACtC,0BAA0B,YAAY;UAEjC;EACf,sBAAsB;EACtB,oBAAoB;EACpB,sBAAsB;EACtB,kBAAkB;EAClB,0BAA0B;EAC1B,yBAAyB;EACzB,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCkFd,wBAAwB;;EAEnC,MAAM;EAGN,OAAO;;EAIP;;EAIA,cAAc;EAGd,iBAAiB;;EAIjB,QAAQ,GAAG,UAAU,GAAG;EAGxB,aAAa;EAGb,eAAe;EAGf,iBAAiB;EAGjB;EAGA;EAGA;;EAIA;;;;;EAOA,WAAW,MAAM,UAAU,cAAc;;;;;;EAQzC,gBAAgB,eAAe,MAAM;;EAIrC;;EAIA;;EAIA;EAGA;EAGA;;EAIA;;UAIQ;;UAGS;UAEA;UACA;;MAcb,QAAQ;;MAKR,YAAY;;EAKhB,SAAS,mBAAmB,OAAO;;;;;;;EAUnC,UAAU;;MAQN,eAAe;MAIf,iBAAiB,YAAY;;EAWjC,WAAW;;EASX,aAAa;;EASb;EAqBS;YAQU,WAAW,SAAS;YAyBpB,QAAQ,SAAS;YAySjB,wBAAM;SAuDT,sBAAM;;QAqGhB;YACI;IACR,kBAAkB;;;UAIL;EACf,iBAAiB,gBAAgB,yBAC/B,MAAM,GACN,WAAW,MAAM,iBAAiB,OAAO,wBAAwB,aACjE,oBAAoB;EAEtB,iBACE,cACA,UAAU,oCACV,oBAAoB"}
|
package/dist/flat-list.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as FlatListSelectEvent, a as FlatListContextMenuDetail, c as FlatListDropEvent, d as FlatListEditCommitDetail, f as FlatListEditCommitEvent, g as FlatListSelectDetail, h as FlatListNavigateEvent, i as FlatListBranchOrder, l as FlatListEditCancelDetail, m as FlatListNavigateDetail, n as FlatListActivateDetail, o as FlatListContextMenuEvent, p as FlatListElementEventMap, r as FlatListActivateEvent, s as FlatListDropDetail, t as FlatListElement, u as FlatListEditCancelEvent } from "./flat-list-
|
|
1
|
+
import { _ as FlatListSelectEvent, a as FlatListContextMenuDetail, c as FlatListDropEvent, d as FlatListEditCommitDetail, f as FlatListEditCommitEvent, g as FlatListSelectDetail, h as FlatListNavigateEvent, i as FlatListBranchOrder, l as FlatListEditCancelDetail, m as FlatListNavigateDetail, n as FlatListActivateDetail, o as FlatListContextMenuEvent, p as FlatListElementEventMap, r as FlatListActivateEvent, s as FlatListDropDetail, t as FlatListElement, u as FlatListEditCancelEvent } from "./flat-list-Ohxqsy0g.js";
|
|
2
2
|
export { type FlatListActivateDetail, type FlatListActivateEvent, type FlatListBranchOrder, type FlatListContextMenuDetail, type FlatListContextMenuEvent, type FlatListDropDetail, type FlatListDropEvent, type FlatListEditCancelDetail, type FlatListEditCancelEvent, type FlatListEditCommitDetail, type FlatListEditCommitEvent, FlatListElement, type FlatListElementEventMap, type FlatListNavigateDetail, type FlatListNavigateEvent, type FlatListSelectDetail, type FlatListSelectEvent };
|
package/dist/flat-list.js
CHANGED
|
@@ -72,6 +72,7 @@ let FlatListElement = class FlatListElement extends LitElement {
|
|
|
72
72
|
this.hideRoot = false;
|
|
73
73
|
this.emptyText = `Empty`;
|
|
74
74
|
this._focusVisible = false;
|
|
75
|
+
this._hasToolbar = false;
|
|
75
76
|
this._rows = [];
|
|
76
77
|
this._loading = false;
|
|
77
78
|
this.#lastPath = [];
|
|
@@ -163,6 +164,9 @@ let FlatListElement = class FlatListElement extends LitElement {
|
|
|
163
164
|
composed: true
|
|
164
165
|
}));
|
|
165
166
|
};
|
|
167
|
+
this.#onToolbarSlotChange = (e) => {
|
|
168
|
+
this._hasToolbar = e.target.assignedNodes({ flatten: true }).some((n) => n.nodeType === Node.ELEMENT_NODE || !!n.textContent?.trim());
|
|
169
|
+
};
|
|
166
170
|
this.#syncFocusVisible = () => {
|
|
167
171
|
this._focusVisible = this.list?.matches(`:focus-visible`) ?? false;
|
|
168
172
|
};
|
|
@@ -405,6 +409,7 @@ let FlatListElement = class FlatListElement extends LitElement {
|
|
|
405
409
|
#onListEditCancel;
|
|
406
410
|
#onListSelect;
|
|
407
411
|
#onListActivate;
|
|
412
|
+
#onToolbarSlotChange;
|
|
408
413
|
#syncFocusVisible;
|
|
409
414
|
#onKeyDown;
|
|
410
415
|
/** A crumb was chosen (or the Up button used): go to that node, or to its parent and select it if it is a leaf. */
|
|
@@ -456,6 +461,9 @@ let FlatListElement = class FlatListElement extends LitElement {
|
|
|
456
461
|
?hide-root=${this.hideRoot}
|
|
457
462
|
@select=${this.#onCrumbSelect}
|
|
458
463
|
></ixfx-crumb-navigation>
|
|
464
|
+
<div class="toolbar" part="toolbar" ?hidden=${!this._hasToolbar}>
|
|
465
|
+
<slot @slotchange=${this.#onToolbarSlotChange}></slot>
|
|
466
|
+
</div>
|
|
459
467
|
</div>
|
|
460
468
|
<div class="body">
|
|
461
469
|
<ixfx-vertical-list
|
|
@@ -506,12 +514,31 @@ let FlatListElement = class FlatListElement extends LitElement {
|
|
|
506
514
|
}
|
|
507
515
|
|
|
508
516
|
.crumbs {
|
|
517
|
+
display: flex;
|
|
518
|
+
align-items: center;
|
|
519
|
+
gap: var(--flat-list-toolbar-gap, var(--space-xs));
|
|
509
520
|
flex: none;
|
|
510
521
|
font-size: var(--flat-list-crumb-font-size, var(--text-s));
|
|
511
522
|
padding: var(--flat-list-crumb-padding, var(--space-xs));
|
|
512
523
|
border-bottom: 1px solid var(--flat-list-border, var(--list-border, var(--border)));
|
|
513
524
|
}
|
|
514
525
|
|
|
526
|
+
.crumbs ixfx-crumb-navigation {
|
|
527
|
+
flex: 1 1 0;
|
|
528
|
+
min-width: 0;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
.toolbar {
|
|
532
|
+
display: flex;
|
|
533
|
+
flex: none;
|
|
534
|
+
align-items: center;
|
|
535
|
+
gap: var(--flat-list-toolbar-gap, var(--space-xs));
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.toolbar[hidden] {
|
|
539
|
+
display: none;
|
|
540
|
+
}
|
|
541
|
+
|
|
515
542
|
.body {
|
|
516
543
|
position: relative;
|
|
517
544
|
flex: 1 1 auto;
|
|
@@ -645,6 +672,7 @@ __decorate([property({
|
|
|
645
672
|
reflect: true,
|
|
646
673
|
attribute: `data-focus-visible`
|
|
647
674
|
})], FlatListElement.prototype, "_focusVisible", void 0);
|
|
675
|
+
__decorate([state()], FlatListElement.prototype, "_hasToolbar", void 0);
|
|
648
676
|
__decorate([state()], FlatListElement.prototype, "_rows", void 0);
|
|
649
677
|
__decorate([state()], FlatListElement.prototype, "_loading", void 0);
|
|
650
678
|
FlatListElement = __decorate([safeCustomElement(`ixfx-flat-list`)], FlatListElement);
|
package/dist/flat-list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flat-list.js","names":["#nodeForElement","#nodeForKey","#selected","#root","#setPath","#pendingSelectKey","#settleList","#renderRow","#onChevronClick","#pendingFocusKey","#lastPath","#direction","#modelUnsubscribe","#loadController","#loadingNode","#refreshRows","#applyMarked","#load","#applyRows","#onCrumbSelect","#renderEditableRow","#renderPlainRow","#renderIcon","#renderBadge","#canDropOn","#validateEditKey","#onListDragOver","#onListDrop","#onListContextMenu","#onListEditCommit","#onListEditCancel","#onListSelect","#onListActivate","#onKeyDown","#syncFocusVisible","customElement"],"sources":["../src/flat-list/flat-list.ts"],"sourcesContent":["/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues } from 'lit';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type { LoadChildrenCallback, TreeFilterPredicate, TreeNode } from '../common/types.js';\nimport type { ListInteractionMode, ListSelectDetail, ListSelectionMode } from '../interaction/list-selection-types.js';\nimport type { ListContextMenuDetail, ListDropDetail, ListEditCancelDetail, ListEditCommitDetail } from '../vertical-list/types.js';\nimport type { VerticalListElement } from '../vertical-list/vertical-list.js';\nimport type {\n FlatListActivateDetail,\n FlatListBranchOrder,\n FlatListContextMenuDetail,\n FlatListDropDetail,\n FlatListEditCancelDetail,\n FlatListEditCommitDetail,\n FlatListElementEventMap,\n FlatListNavigateDetail,\n FlatListSelectDetail,\n} from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { collectDataResult } from '../common/data-provider.js';\nimport { appearanceAbsent, appearanceColor } from '../common/item-appearance.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../crumbs/crumb-navigation.js';\nimport '../icons/icon.js';\nimport '../vertical-list/vertical-list.js';\n\nexport type {\n FlatListActivateDetail,\n FlatListActivateEvent,\n FlatListBranchOrder,\n FlatListContextMenuDetail,\n FlatListContextMenuEvent,\n FlatListDropDetail,\n FlatListDropEvent,\n FlatListEditCancelDetail,\n FlatListEditCancelEvent,\n FlatListEditCommitDetail,\n FlatListEditCommitEvent,\n FlatListElementEventMap,\n FlatListNavigateDetail,\n FlatListNavigateEvent,\n FlatListSelectDetail,\n FlatListSelectEvent,\n} from './types.js';\n\n/** One row handed to the inner list: the node plus its (cached) branch-ness. */\ntype FlatRow = {\n readonly key: string;\n readonly node: TreeNode;\n readonly branch: boolean;\n};\n\n/**\n * A node with children, or whose children are still to be loaded.\n * `isLeaf: false` forces a branch even when `children` is `[]` (an empty\n * folder that can still be entered); `isLeaf: true` forces a leaf.\n */\nfunction isBranch(node: TreeNode): boolean {\n return node.item.isLeaf === false || (node.item.isLeaf !== true && node.children?.length !== 0);\n}\n\nfunction sameKeys(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((k, i) => k === b[i]);\n}\n\nfunction sameNodes(a: readonly FlatRow[], b: readonly FlatRow[]): boolean {\n return a.length === b.length && a.every((row, i) => row.node === b[i]!.node && row.branch === b[i]!.branch);\n}\n\n/**\n * Walk `keys` down from `root`, stopping at the first key that no longer\n * resolves. Returns the nodes visited (root first), so the valid path is\n * `nodes.length - 1` keys long.\n */\nfunction resolvePath(root: TreeNode | undefined, keys: readonly string[]): TreeNode[] {\n if (!root)\n return [];\n const nodes = [root];\n for (const key of keys) {\n const next = nodes.at(-1)!.children?.find(n => n.item.key === key);\n if (!next)\n break;\n nodes.push(next);\n }\n return nodes;\n}\n\n/** Key path (excluding root) to `target`, or `undefined` if it is not in the loaded tree. */\nfunction findKeyPath(root: TreeNode, target: TreeNode): string[] | undefined {\n if (root === target)\n return [];\n for (const child of root.children ?? []) {\n const sub = findKeyPath(child, target);\n if (sub)\n return [child.item.key, ...sub];\n }\n return undefined;\n}\n\nfunction orderRows(\n children: readonly TreeNode[],\n branchOrder: FlatListBranchOrder,\n sort: ((a: TreeNode, b: TreeNode) => number) | undefined,\n): FlatRow[] {\n const rows = children.map(node => ({ key: node.item.key, node, branch: isBranch(node) }));\n const sorted = sort ? [...rows].sort((a, b) => sort(a.node, b.node)) : rows;\n if (branchOrder === `mixed`)\n return sorted;\n // Array.prototype.filter is stable, so the sort/source order holds within each half.\n return [...sorted.filter(r => r.branch), ...sorted.filter(r => !r.branch)];\n}\n\n/**\n * Navigates a tree inside one flat list. Each level shows its branches and\n * leaves together in an `ixfx-vertical-list`; entering a branch swaps the list\n * for that branch's children, and an `ixfx-crumb-navigation` pinned above the\n * scroll area shows the path and jumps back up.\n *\n * Uses the same `TreeNode` / `TreeDataModel` data as `ixfx-crumb-navigation`\n * and `ixfx-tree-list`. As in crumb-navigation, lazily loaded children are\n * written back to `node.children`.\n *\n * Selection and keyboard behaviour is the inner list's. On top of that:\n * double-click / Enter / ArrowRight enter the cursor branch;\n * ArrowLeft / Backspace go up. Selection is cleared on every level change.\n *\n * Events (all bubble, composed)\n * - `flat-list-navigate` `{ path, previousPath, node, direction }`\n * - `flat-list-select` `{ selected: Set<TreeNode>, selectedKeys, previous }`\n * - `flat-list-activate` `{ node }` — a leaf was double-clicked / Enter pressed\n * The inner list's own `list-*` events also cross the shadow boundary.\n *\n * CSS variables (others, e.g. `--list-item-height`, pass through to the list)\n * --flat-list-bg: var(--list-bg, var(--surface-3));\n * --flat-list-text: var(--list-text, var(--surface-3-text));\n * --flat-list-border: var(--list-border, var(--border));\n * --flat-list-radius: var(--list-radius, var(--radius-s));\n * --flat-list-crumb-padding: var(--space-xs);\n * --flat-list-crumb-font-size: var(--text-s);\n * --flat-list-chevron-gap: 0.4em; // space after the branch chevron\n * --flat-list-marked-bg / --flat-list-marked-bar: the `marked-key` row\n * --flat-list-empty-text: var(--surface-muted-text);\n */\n@customElement(`ixfx-flat-list`)\nexport class FlatListElement extends LitElement {\n @property({ attribute: false })\n root: TreeNode | undefined;\n\n @property({ attribute: false })\n model: TreeDataModel | undefined;\n\n /** Keys from the root (excluded) to the level being shown. */\n @property({ attribute: false })\n path: readonly string[] = [];\n\n /** Lazily loads a branch's children when `node.children` is `undefined`. */\n @property({ attribute: false })\n loadChildren: LoadChildrenCallback | undefined;\n\n @property({ attribute: false })\n filterPredicate: TreeFilterPredicate | undefined;\n\n /** Orders nodes within the level (within each half when `branchOrder` is `first`). */\n @property({ attribute: false })\n sort: ((a: TreeNode, b: TreeNode) => number) | undefined;\n\n @property({ type: String, attribute: `branch-order`, reflect: true })\n branchOrder: FlatListBranchOrder = `first`;\n\n @property({ type: String, attribute: `selection-mode` })\n selectionMode: ListSelectionMode = `single`;\n\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: ListInteractionMode = `standard`;\n\n @property({ type: String, attribute: `item-wrap` })\n itemWrap: `stop` | `wrap` = `stop`;\n\n @property({ type: String, attribute: `search-modes`, reflect: true })\n searchModes: string | undefined;\n\n @property({ type: Boolean, attribute: `items-draggable`, reflect: true })\n itemsDraggable = false;\n\n /** Rows (and empty space) accept native drops. See `flat-list-drop`. */\n @property({ type: Boolean, attribute: `items-droppable`, reflect: true })\n itemsDroppable = false;\n\n /**\n * Refuse a drop before it is highlighted or reported. `node` is the row under\n * the drag, or the current level's node over empty space.\n */\n @property({ attribute: false })\n canDrop: ((node: TreeNode, dataTransfer: DataTransfer) => boolean) | undefined;\n\n /**\n * Opt in to in-place rename. Called with the typed text and the node when\n * the user commits; return `false` to reject it. Without it nothing can be\n * renamed and rows are plain text. Rows must also have `item.editable`.\n */\n @property({ attribute: false })\n validateEdit: ((value: string, node: TreeNode) => boolean) | undefined;\n\n /** Key of a node to keep visibly marked across level changes (unlike selection). */\n @property({ type: String, attribute: `marked-key`, reflect: true })\n markedKey: string | undefined;\n\n /** Only render the visible rows. Needs `itemHeight`. See `ixfx-vertical-list`. */\n @property({ type: Boolean, reflect: true })\n virtualize = false;\n\n /** Fixed row height in px, required for `virtualize`. */\n @property({ type: Number, attribute: `item-height` })\n itemHeight = 0;\n\n @property({ type: Boolean, attribute: `with-up`, reflect: true })\n withUp = true;\n\n @property({ type: Boolean, attribute: `hide-root`, reflect: true })\n hideRoot = false;\n\n /** Shown when the current level has no children. */\n @property({ type: String, attribute: `empty-text` })\n emptyText = `Empty`;\n\n /** Mirrors the inner list's `:focus-visible`, so the ring can go round the whole component. */\n @property({ type: Boolean, reflect: true, attribute: `data-focus-visible` })\n private _focusVisible = false;\n\n @state() private _rows: readonly FlatRow[] = [];\n @state() private _loading = false;\n\n #modelUnsubscribe: (() => void) | undefined;\n #loadController: AbortController | undefined;\n #loadingNode: TreeNode | undefined;\n #lastPath: readonly string[] = [];\n /** Branch key to put the cursor on after the next rows arrive (set when going up). */\n #pendingFocusKey: string | undefined;\n #selected: ReadonlySet<TreeNode> = new Set();\n #direction: FlatListNavigateDetail[`direction`] = `jump`;\n /** Leaf key to select once the list shows its level (set when a leaf crumb is chosen). */\n #pendingSelectKey: string | undefined;\n\n /** The inner list, for registry / search commands and other advanced use. */\n get list(): VerticalListElement | undefined {\n return this.renderRoot.querySelector(`ixfx-vertical-list`) ?? undefined;\n }\n\n /** Command registry carrying the inner list's `list.search.*` commands. */\n get registry(): VerticalListElement[`registry`] {\n return this.list?.registry;\n }\n\n /** Run a command on the inner list, e.g. `dispatch('list.search.filter')`. */\n dispatch(commandId: string, args?: Record<string, unknown>): void {\n this.list?.dispatch(commandId, args);\n }\n\n /**\n * Rename a row in place. Needs `validateEdit`, and only rows whose\n * `item.editable` is true can be edited. Ends with `flat-list-edit-commit` or `flat-list-edit-cancel`; the\n * label is not rewritten — update the tree in response. Returns false if\n * the row is unknown, not editable, or not on screen.\n */\n beginEdit(key: string): boolean {\n const node = this.#nodeForKey(key);\n if (!this.validateEdit || !node?.item.editable)\n return false;\n return this.list?.beginEdit(key) ?? false;\n }\n\n /** The node whose children are listed. */\n get currentNode(): TreeNode | undefined {\n return resolvePath(this.#root, this.path).at(-1);\n }\n\n get selectedNodes(): ReadonlySet<TreeNode> {\n return this.#selected;\n }\n\n get #root(): TreeNode | undefined {\n return this.model?.root ?? this.root;\n }\n\n // --- Navigation API ---\n\n /** Show the children of the node at this key path. Returns false if the path does not resolve. */\n navigateTo(keys: readonly string[]): boolean {\n const nodes = resolvePath(this.#root, keys);\n if (nodes.length !== keys.length + 1)\n return false;\n this.#setPath(keys, `jump`);\n return true;\n }\n\n /** Enter the child branch with this key. */\n navigateInto(key: string): boolean {\n const node = this.currentNode?.children?.find(n => n.item.key === key);\n if (!node || !isBranch(node))\n return false;\n this.#setPath([...this.path, key], `into`);\n return true;\n }\n\n /** Move to the parent level. Returns false at the root. */\n navigateUp(): boolean {\n if (this.path.length === 0)\n return false;\n this.#pendingFocusKey = this.path.at(-1);\n this.#setPath(this.path.slice(0, -1), `up`);\n return true;\n }\n\n #setPath(path: readonly string[], direction: FlatListNavigateDetail[`direction`]): void {\n if (sameKeys(path, this.path))\n return;\n this.#lastPath = this.path;\n this.#direction = direction;\n // A search over the old level makes no sense on the new one.\n this.list?.search.close();\n this.list?.clearSelection();\n this.path = path;\n }\n\n // --- Lifecycle ---\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n this.#loadController?.abort();\n this.#loadingNode = undefined;\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n if (changed.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = this.model?._subscribe((event) => {\n if (event.type === `invalidate` && event.key === this.currentNode?.item.key) {\n const node = this.currentNode;\n if (node)\n node.children = undefined;\n }\n this.requestUpdate();\n // Model data changed in place; recompute rows even though no property did.\n this.#refreshRows(true);\n });\n }\n\n // Keep `path` valid if the tree changed underneath it.\n const valid = resolvePath(this.#root, this.path).length - 1;\n if (this.#root && valid < this.path.length)\n this.path = this.path.slice(0, valid);\n\n const rowInputs = [`root`, `model`, `path`, `branchOrder`, `sort`, `filterPredicate`, `loadChildren`] as const;\n if (rowInputs.some(p => changed.has(p)))\n this.#refreshRows(changed.has(`root`) || changed.has(`model`) || changed.has(`loadChildren`));\n }\n\n protected override updated(changed: PropertyValues): void {\n if (changed.has(`path`) && !sameKeys(this.path, this.#lastPath) && this.#root) {\n const node = this.currentNode;\n if (node) {\n const previousPath = this.#lastPath;\n this.#lastPath = this.path;\n this.dispatchEvent(new CustomEvent<FlatListNavigateDetail>(`flat-list-navigate`, {\n detail: { path: this.path, previousPath, node, direction: this.#direction },\n bubbles: true,\n composed: true,\n }));\n this.#direction = `jump`;\n }\n }\n if (changed.has(`_rows`))\n void this.#settleList();\n if (changed.has(`_rows`) || changed.has(`markedKey`))\n void this.#applyMarked();\n }\n\n /** Recompute the level's rows, loading children first when they are not yet known. */\n #refreshRows(reload: boolean): void {\n const node = this.currentNode;\n if (!node) {\n this._rows = [];\n return;\n }\n if (node.children === undefined && (this.model || this.loadChildren) && (reload || this.#loadingNode !== node)) {\n void this.#load(node);\n return;\n }\n this.#applyRows(node);\n }\n\n #applyRows(node: TreeNode): void {\n const filter = this.filterPredicate;\n const depth = this.path.length;\n const children = (node.children ?? []).filter(c => !filter || filter(c, depth));\n const rows = orderRows(children, this.branchOrder, this.sort);\n if (!sameNodes(rows, this._rows))\n this._rows = rows;\n }\n\n async #load(node: TreeNode): Promise<void> {\n this.#loadController?.abort();\n const controller = new AbortController();\n this.#loadController = controller;\n this.#loadingNode = node;\n this._loading = true;\n this._rows = [];\n try {\n const depth = this.path.length;\n const children = this.model\n ? await this.model.getChildren(node, depth, controller.signal)\n : [...await collectDataResult(this.loadChildren!({ node, depth }, controller.signal), controller.signal)];\n if (controller.signal.aborted)\n return;\n node.children = [...children];\n } catch {\n if (controller.signal.aborted)\n return;\n node.children = [];\n }\n this.#loadingNode = undefined;\n this._loading = false;\n if (node === this.currentNode)\n this.#applyRows(node);\n }\n\n // --- Interaction ---\n\n #nodeForKey(key: string | undefined): TreeNode | undefined {\n return key === undefined ? undefined : this._rows.find(r => r.key === key)?.node;\n }\n\n /** A single click on a branch's chevron enters it, without selecting the row. */\n #onChevronClick(e: Event, node: TreeNode): void {\n e.stopPropagation();\n this.navigateInto(node.item.key);\n }\n\n #nodeForElement(el: Element | undefined): TreeNode | undefined {\n return el ? this.#nodeForKey(el.getAttribute(`data-key`) ?? undefined) : this.currentNode;\n }\n\n #canDropOn = (el: Element | undefined, dataTransfer: DataTransfer): boolean => {\n const node = this.#nodeForElement(el);\n return !!node && (this.canDrop?.(node, dataTransfer) ?? true);\n };\n\n /** Accept every drag that got past `canDrop`; the consumer only hears about the drop. */\n #onListDragOver = (e: CustomEvent<ListDropDetail>): void => {\n if (this.itemsDroppable)\n e.preventDefault();\n };\n\n #onListDrop = (e: CustomEvent<ListDropDetail>): void => {\n const node = this.#nodeForKey(e.detail.key) ?? this.currentNode;\n if (!node)\n return;\n this.dispatchEvent(new CustomEvent<FlatListDropDetail>(`flat-list-drop`, {\n detail: { node, dataTransfer: e.detail.dataTransfer },\n bubbles: true,\n composed: true,\n }));\n };\n\n #onListContextMenu = (e: CustomEvent<ListContextMenuDetail>): void => {\n const node = this.#nodeForKey(e.detail.key);\n if (!node)\n return;\n const nodes = [...e.detail.selectedKeys].map(k => this.#nodeForKey(k)).filter((n): n is TreeNode => n !== undefined);\n const proceed = this.dispatchEvent(new CustomEvent<FlatListContextMenuDetail>(`flat-list-context-menu`, {\n detail: { node, nodes, x: e.detail.x, y: e.detail.y },\n bubbles: true,\n composed: true,\n cancelable: true,\n }));\n if (!proceed)\n e.preventDefault();\n };\n\n #validateEditKey = (value: string, key: string | undefined): boolean => {\n const node = this.#nodeForKey(key);\n return !!node && (this.validateEdit?.(value, node) ?? false);\n };\n\n #onListEditCommit = (e: CustomEvent<ListEditCommitDetail>): void => {\n const node = this.#nodeForKey(e.detail.key);\n if (node) {\n this.dispatchEvent(new CustomEvent<FlatListEditCommitDetail>(`flat-list-edit-commit`, {\n detail: { node, value: e.detail.value },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n #onListEditCancel = (e: CustomEvent<ListEditCancelDetail>): void => {\n const node = this.#nodeForKey(e.detail.key);\n if (node) {\n this.dispatchEvent(new CustomEvent<FlatListEditCancelDetail>(`flat-list-edit-cancel`, {\n detail: { node },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n #onListSelect = (e: CustomEvent<ListSelectDetail>): void => {\n const previous = this.#selected;\n const nodes = [...e.detail.selectedKeys]\n .map(k => this.#nodeForKey(k))\n .filter((n): n is TreeNode => n !== undefined);\n this.#selected = new Set(nodes);\n this.dispatchEvent(new CustomEvent<FlatListSelectDetail>(`flat-list-select`, {\n detail: { selected: this.#selected, selectedKeys: e.detail.selectedKeys, previous },\n bubbles: true,\n composed: true,\n }));\n };\n\n #onListActivate = (e: CustomEvent<{ item: Element }>): void => {\n const key = e.detail.item.getAttribute(`data-key`) ?? undefined;\n const node = this.#nodeForKey(key);\n if (!node)\n return;\n if (isBranch(node)) {\n this.navigateInto(node.item.key);\n return;\n }\n this.dispatchEvent(new CustomEvent<FlatListActivateDetail>(`flat-list-activate`, {\n detail: { node },\n bubbles: true,\n composed: true,\n }));\n };\n\n #syncFocusVisible = (): void => {\n this._focusVisible = this.list?.matches(`:focus-visible`) ?? false;\n };\n\n #onKeyDown = (e: KeyboardEvent): void => {\n if (e.defaultPrevented || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey)\n return;\n // Leave the search overlay's text field alone.\n const origin = e.composedPath()[0];\n if (origin instanceof HTMLInputElement || origin instanceof HTMLTextAreaElement)\n return;\n\n if (e.key === `ArrowRight` || e.key === `ArrowLeft` || e.key === `Backspace`) {\n // The level is about to change under a resting pointer; hover must not steal the cursor.\n TickledController.ignoreHoverUntilPointerMoves();\n }\n\n if (e.key === `ArrowRight`) {\n const node = this.#nodeForKey(this.list?.tickledKey);\n if (node && isBranch(node)) {\n e.preventDefault();\n this.navigateInto(node.item.key);\n }\n } else if (e.key === `ArrowLeft` || e.key === `Backspace`) {\n if (this.navigateUp())\n e.preventDefault();\n }\n };\n\n /** A crumb was chosen (or the Up button used): go to that node, or to its parent and select it if it is a leaf. */\n #onCrumbSelect = (e: CustomEvent<{ selected: ReadonlySet<TreeNode> }>): void => {\n e.stopPropagation();\n const target = [...e.detail.selected].at(-1);\n const root = this.#root;\n if (!target || !root)\n return;\n const keys = findKeyPath(root, target);\n if (!keys)\n return;\n if (isBranch(target)) {\n const direction = keys.length < this.path.length && keys.every((k, i) => k === this.path[i]) ? `up` : `jump`;\n this.#setPath(keys, direction);\n } else {\n const levelPath = keys.slice(0, -1);\n const sameLevel = sameKeys(levelPath, this.path);\n this.#setPath(levelPath, `jump`);\n this.#pendingSelectKey = target.item.key;\n // Rows will not change when the leaf is already on this level.\n if (sameLevel)\n void this.#settleList();\n }\n };\n\n /** Flag the marked row. Rows are rebuilt with the level, so this runs after each rebuild. */\n async #applyMarked(): Promise<void> {\n const list = this.list;\n if (!list)\n return;\n await list.updateComplete;\n for (const row of list.querySelectorAll(`li[data-key]`))\n row.toggleAttribute(`data-marked`, row.getAttribute(`data-key`) === this.markedKey);\n }\n\n /** After the inner list has rebuilt, place the cursor / selection / focus. */\n async #settleList(): Promise<void> {\n const list = this.list;\n if (!list)\n return;\n const hadFocus = this.matches(`:focus-within`);\n await list.updateComplete;\n const select = this.#pendingSelectKey;\n const focusKey = this.#pendingFocusKey ?? select ?? this._rows[0]?.key;\n this.#pendingSelectKey = undefined;\n this.#pendingFocusKey = undefined;\n if (select)\n list.selectKeys([select]);\n if (focusKey !== undefined)\n list.focusKey(focusKey);\n if (hadFocus)\n list.focus();\n }\n\n // --- Rendering ---\n\n /** Two stable formatters, so toggling `validateEdit` rebuilds the rows with or without edit hooks. */\n #renderPlainRow = (row: unknown) => this.#renderRow(row, false);\n #renderEditableRow = (row: unknown) => this.#renderRow(row, true);\n\n #renderRow(row: unknown, editingEnabled: boolean) {\n const { node } = row as FlatRow;\n const textColor = appearanceColor(node.item.textColor);\n const editable = editingEnabled && node.item.editable === true;\n return html`<span class=\"label\" data-edit-label=${editable ? `` : nothing} data-edit-value=${editable ? node.item.label : nothing} style=${textColor ? `color:${textColor}` : nothing}>${node.item.label}</span>`;\n }\n\n #renderIcon = (row: unknown) => {\n const { node } = row as FlatRow;\n return node.item.icon ? html`<ixfx-icon name=${node.item.icon}></ixfx-icon>` : undefined;\n };\n\n #renderBadge = (row: unknown) => {\n const { node, branch } = row as FlatRow;\n const badge = appearanceAbsent(node.item.badge) ? nothing : node.item.badge;\n const textColor = appearanceColor(node.item.textColor);\n return html`${badge}${branch\n ? html`<span\n class=\"chevron\"\n aria-hidden=\"true\"\n style=${textColor ? `color:${textColor}` : nothing}\n @pointerdown=${(e: Event) => e.stopPropagation()}\n @click=${(e: Event) => this.#onChevronClick(e, node)}\n >›</span>`\n : nothing}`;\n };\n\n protected override render() {\n const root = this.#root;\n return html`\n <div class=\"crumbs\" part=\"crumbs\">\n <ixfx-crumb-navigation\n .root=${root}\n .selectedNode=${this.currentNode}\n .loadChildren=${this.loadChildren}\n selection-filter=\"all\"\n pad-ending\n leading-caret\n ?with-up=${this.withUp}\n ?hide-root=${this.hideRoot}\n @select=${this.#onCrumbSelect}\n ></ixfx-crumb-navigation>\n </div>\n <div class=\"body\">\n <ixfx-vertical-list\n .items=${this._rows}\n .formatter=${this.validateEdit ? this.#renderEditableRow : this.#renderPlainRow}\n .icon=${this.#renderIcon}\n .iconColor=${(row: unknown) => appearanceColor((row as FlatRow).node.item.iconColor)}\n .badge=${this.#renderBadge}\n key-property=\"key\"\n .selectionMode=${this.selectionMode}\n .interactionMode=${this.interactionMode}\n .itemWrap=${this.itemWrap}\n .searchModes=${this.searchModes}\n ?items-draggable=${this.itemsDraggable}\n ?items-droppable=${this.itemsDroppable}\n .canDrop=${this.#canDropOn}\n .editValidator=${this.#validateEditKey}\n .virtualize=${this.virtualize}\n .itemHeight=${this.itemHeight}\n @list-drag-over=${this.#onListDragOver}\n @list-drop=${this.#onListDrop}\n @list-context-menu=${this.#onListContextMenu}\n @list-edit-commit=${this.#onListEditCommit}\n @list-edit-cancel=${this.#onListEditCancel}\n @list-select=${this.#onListSelect}\n @list-activate=${this.#onListActivate}\n @keydown=${this.#onKeyDown}\n @focusin=${this.#syncFocusVisible}\n @focusout=${this.#syncFocusVisible}\n ></ixfx-vertical-list>\n ${this._rows.length === 0\n ? html`<div class=\"empty\" part=\"empty\">${this._loading ? `Loading…` : this.emptyText}</div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [themeFallbacks, css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n overflow: hidden;\n background: var(--flat-list-bg, var(--list-bg, var(--surface-3)));\n color: var(--flat-list-text, var(--list-text, var(--surface-3-text)));\n border: 1px solid var(--flat-list-border, var(--list-border, var(--border)));\n border-radius: var(--flat-list-radius, var(--list-radius, var(--radius-s)));\n }\n\n .crumbs {\n flex: none;\n font-size: var(--flat-list-crumb-font-size, var(--text-s));\n padding: var(--flat-list-crumb-padding, var(--space-xs));\n border-bottom: 1px solid var(--flat-list-border, var(--list-border, var(--border)));\n }\n\n .body {\n position: relative;\n flex: 1 1 auto;\n min-height: 0;\n }\n\n :host([data-focus-visible]) {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n ixfx-vertical-list {\n /* The ring is drawn round the whole component instead. */\n outline: none;\n /* Fill .body absolutely: a percentage height does not reliably resolve\n inside a flex item, and an unbounded list never scrolls the cursor into view. */\n position: absolute;\n inset: 0;\n --list-bg: transparent;\n --list-border: none;\n --list-radius: 0;\n }\n\n .empty {\n position: absolute;\n inset: 0;\n display: grid;\n place-items: center;\n pointer-events: none;\n color: var(--flat-list-empty-text, var(--surface-muted-text));\n }\n\n li[data-marked] {\n background: var(--flat-list-marked-bg, color-mix(in srgb, var(--accent) 18%, transparent));\n box-shadow: inset 3px 0 0 var(--flat-list-marked-bar, var(--accent));\n }\n\n .label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* Highlight rule for incremental search: the rows live in this shadow root,\n so the page-level ::highlight() rule cannot reach them. */\n ::highlight(vertical-list-search) {\n background: var(--accent);\n color: var(--accent-text, #fff);\n }\n\n .chevron {\n margin-inline-start: auto;\n padding-inline-start: 0.5em;\n padding-inline-end: var(--flat-list-chevron-gap, 0.4em);\n /* Inherit the row's text colour, so it follows selected / tickled states. */\n color: inherit;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-flat-list': FlatListElement;\n }\n}\n\nexport interface FlatListElement {\n addEventListener<K extends keyof FlatListElementEventMap>(\n type: K,\n listener: (this: FlatListElement, event: FlatListElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions\n ): void;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flat-list.js","names":["#nodeForElement","#nodeForKey","#selected","#root","#setPath","#pendingSelectKey","#settleList","#renderRow","#onChevronClick","#pendingFocusKey","#lastPath","#direction","#modelUnsubscribe","#loadController","#loadingNode","#refreshRows","#applyMarked","#load","#applyRows","#onCrumbSelect","#onToolbarSlotChange","#renderEditableRow","#renderPlainRow","#renderIcon","#renderBadge","#canDropOn","#validateEditKey","#onListDragOver","#onListDrop","#onListContextMenu","#onListEditCommit","#onListEditCancel","#onListSelect","#onListActivate","#onKeyDown","#syncFocusVisible","customElement"],"sources":["../src/flat-list/flat-list.ts"],"sourcesContent":["/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues } from 'lit';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type { LoadChildrenCallback, TreeFilterPredicate, TreeNode } from '../common/types.js';\nimport type { ListInteractionMode, ListSelectDetail, ListSelectionMode } from '../interaction/list-selection-types.js';\nimport type { ListContextMenuDetail, ListDropDetail, ListEditCancelDetail, ListEditCommitDetail } from '../vertical-list/types.js';\nimport type { VerticalListElement } from '../vertical-list/vertical-list.js';\nimport type {\n FlatListActivateDetail,\n FlatListBranchOrder,\n FlatListContextMenuDetail,\n FlatListDropDetail,\n FlatListEditCancelDetail,\n FlatListEditCommitDetail,\n FlatListElementEventMap,\n FlatListNavigateDetail,\n FlatListSelectDetail,\n} from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { collectDataResult } from '../common/data-provider.js';\nimport { appearanceAbsent, appearanceColor } from '../common/item-appearance.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../crumbs/crumb-navigation.js';\nimport '../icons/icon.js';\nimport '../vertical-list/vertical-list.js';\n\nexport type {\n FlatListActivateDetail,\n FlatListActivateEvent,\n FlatListBranchOrder,\n FlatListContextMenuDetail,\n FlatListContextMenuEvent,\n FlatListDropDetail,\n FlatListDropEvent,\n FlatListEditCancelDetail,\n FlatListEditCancelEvent,\n FlatListEditCommitDetail,\n FlatListEditCommitEvent,\n FlatListElementEventMap,\n FlatListNavigateDetail,\n FlatListNavigateEvent,\n FlatListSelectDetail,\n FlatListSelectEvent,\n} from './types.js';\n\n/** One row handed to the inner list: the node plus its (cached) branch-ness. */\ntype FlatRow = {\n readonly key: string;\n readonly node: TreeNode;\n readonly branch: boolean;\n};\n\n/**\n * A node with children, or whose children are still to be loaded.\n * `isLeaf: false` forces a branch even when `children` is `[]` (an empty\n * folder that can still be entered); `isLeaf: true` forces a leaf.\n */\nfunction isBranch(node: TreeNode): boolean {\n return node.item.isLeaf === false || (node.item.isLeaf !== true && node.children?.length !== 0);\n}\n\nfunction sameKeys(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((k, i) => k === b[i]);\n}\n\nfunction sameNodes(a: readonly FlatRow[], b: readonly FlatRow[]): boolean {\n return a.length === b.length && a.every((row, i) => row.node === b[i]!.node && row.branch === b[i]!.branch);\n}\n\n/**\n * Walk `keys` down from `root`, stopping at the first key that no longer\n * resolves. Returns the nodes visited (root first), so the valid path is\n * `nodes.length - 1` keys long.\n */\nfunction resolvePath(root: TreeNode | undefined, keys: readonly string[]): TreeNode[] {\n if (!root)\n return [];\n const nodes = [root];\n for (const key of keys) {\n const next = nodes.at(-1)!.children?.find(n => n.item.key === key);\n if (!next)\n break;\n nodes.push(next);\n }\n return nodes;\n}\n\n/** Key path (excluding root) to `target`, or `undefined` if it is not in the loaded tree. */\nfunction findKeyPath(root: TreeNode, target: TreeNode): string[] | undefined {\n if (root === target)\n return [];\n for (const child of root.children ?? []) {\n const sub = findKeyPath(child, target);\n if (sub)\n return [child.item.key, ...sub];\n }\n return undefined;\n}\n\nfunction orderRows(\n children: readonly TreeNode[],\n branchOrder: FlatListBranchOrder,\n sort: ((a: TreeNode, b: TreeNode) => number) | undefined,\n): FlatRow[] {\n const rows = children.map(node => ({ key: node.item.key, node, branch: isBranch(node) }));\n const sorted = sort ? [...rows].sort((a, b) => sort(a.node, b.node)) : rows;\n if (branchOrder === `mixed`)\n return sorted;\n // Array.prototype.filter is stable, so the sort/source order holds within each half.\n return [...sorted.filter(r => r.branch), ...sorted.filter(r => !r.branch)];\n}\n\n/**\n * Navigates a tree inside one flat list. Each level shows its branches and\n * leaves together in an `ixfx-vertical-list`; entering a branch swaps the list\n * for that branch's children, and an `ixfx-crumb-navigation` pinned above the\n * scroll area shows the path and jumps back up.\n *\n * Uses the same `TreeNode` / `TreeDataModel` data as `ixfx-crumb-navigation`\n * and `ixfx-tree-list`. As in crumb-navigation, lazily loaded children are\n * written back to `node.children`.\n *\n * Selection and keyboard behaviour is the inner list's. On top of that:\n * double-click / Enter / ArrowRight enter the cursor branch;\n * ArrowLeft / Backspace go up. Selection is cleared on every level change.\n *\n * Events (all bubble, composed)\n * - `flat-list-navigate` `{ path, previousPath, node, direction }`\n * - `flat-list-select` `{ selected: Set<TreeNode>, selectedKeys, previous }`\n * - `flat-list-activate` `{ node }` — a leaf was double-clicked / Enter pressed\n * The inner list's own `list-*` events also cross the shadow boundary.\n *\n * CSS variables (others, e.g. `--list-item-height`, pass through to the list)\n * --flat-list-bg: var(--list-bg, var(--surface-3));\n * --flat-list-text: var(--list-text, var(--surface-3-text));\n * --flat-list-border: var(--list-border, var(--border));\n * --flat-list-radius: var(--list-radius, var(--radius-s));\n * --flat-list-crumb-padding: var(--space-xs);\n * --flat-list-crumb-font-size: var(--text-s);\n * --flat-list-toolbar-gap: var(--space-xs); // between the crumbs and slotted toolbar items\n * --flat-list-chevron-gap: 0.4em; // space after the branch chevron\n * --flat-list-marked-bg / --flat-list-marked-bar: the `marked-key` row\n * --flat-list-empty-text: var(--surface-muted-text);\n */\n@customElement(`ixfx-flat-list`)\nexport class FlatListElement extends LitElement {\n @property({ attribute: false })\n root: TreeNode | undefined;\n\n @property({ attribute: false })\n model: TreeDataModel | undefined;\n\n /** Keys from the root (excluded) to the level being shown. */\n @property({ attribute: false })\n path: readonly string[] = [];\n\n /** Lazily loads a branch's children when `node.children` is `undefined`. */\n @property({ attribute: false })\n loadChildren: LoadChildrenCallback | undefined;\n\n @property({ attribute: false })\n filterPredicate: TreeFilterPredicate | undefined;\n\n /** Orders nodes within the level (within each half when `branchOrder` is `first`). */\n @property({ attribute: false })\n sort: ((a: TreeNode, b: TreeNode) => number) | undefined;\n\n @property({ type: String, attribute: `branch-order`, reflect: true })\n branchOrder: FlatListBranchOrder = `first`;\n\n @property({ type: String, attribute: `selection-mode` })\n selectionMode: ListSelectionMode = `single`;\n\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: ListInteractionMode = `standard`;\n\n @property({ type: String, attribute: `item-wrap` })\n itemWrap: `stop` | `wrap` = `stop`;\n\n @property({ type: String, attribute: `search-modes`, reflect: true })\n searchModes: string | undefined;\n\n @property({ type: Boolean, attribute: `items-draggable`, reflect: true })\n itemsDraggable = false;\n\n /** Rows (and empty space) accept native drops. See `flat-list-drop`. */\n @property({ type: Boolean, attribute: `items-droppable`, reflect: true })\n itemsDroppable = false;\n\n /**\n * Refuse a drop before it is highlighted or reported. `node` is the row under\n * the drag, or the current level's node over empty space.\n */\n @property({ attribute: false })\n canDrop: ((node: TreeNode, dataTransfer: DataTransfer) => boolean) | undefined;\n\n /**\n * Opt in to in-place rename. Called with the typed text and the node when\n * the user commits; return `false` to reject it. Without it nothing can be\n * renamed and rows are plain text. Rows must also have `item.editable`.\n */\n @property({ attribute: false })\n validateEdit: ((value: string, node: TreeNode) => boolean) | undefined;\n\n /** Key of a node to keep visibly marked across level changes (unlike selection). */\n @property({ type: String, attribute: `marked-key`, reflect: true })\n markedKey: string | undefined;\n\n /** Only render the visible rows. Needs `itemHeight`. See `ixfx-vertical-list`. */\n @property({ type: Boolean, reflect: true })\n virtualize = false;\n\n /** Fixed row height in px, required for `virtualize`. */\n @property({ type: Number, attribute: `item-height` })\n itemHeight = 0;\n\n @property({ type: Boolean, attribute: `with-up`, reflect: true })\n withUp = true;\n\n @property({ type: Boolean, attribute: `hide-root`, reflect: true })\n hideRoot = false;\n\n /** Shown when the current level has no children. */\n @property({ type: String, attribute: `empty-text` })\n emptyText = `Empty`;\n\n /** Mirrors the inner list's `:focus-visible`, so the ring can go round the whole component. */\n @property({ type: Boolean, reflect: true, attribute: `data-focus-visible` })\n private _focusVisible = false;\n\n /** Whether anything is slotted into the toolbar; an empty toolbar takes no space. */\n @state() private _hasToolbar = false;\n\n @state() private _rows: readonly FlatRow[] = [];\n @state() private _loading = false;\n\n #modelUnsubscribe: (() => void) | undefined;\n #loadController: AbortController | undefined;\n #loadingNode: TreeNode | undefined;\n #lastPath: readonly string[] = [];\n /** Branch key to put the cursor on after the next rows arrive (set when going up). */\n #pendingFocusKey: string | undefined;\n #selected: ReadonlySet<TreeNode> = new Set();\n #direction: FlatListNavigateDetail[`direction`] = `jump`;\n /** Leaf key to select once the list shows its level (set when a leaf crumb is chosen). */\n #pendingSelectKey: string | undefined;\n\n /** The inner list, for registry / search commands and other advanced use. */\n get list(): VerticalListElement | undefined {\n return this.renderRoot.querySelector(`ixfx-vertical-list`) ?? undefined;\n }\n\n /** Command registry carrying the inner list's `list.search.*` commands. */\n get registry(): VerticalListElement[`registry`] {\n return this.list?.registry;\n }\n\n /** Run a command on the inner list, e.g. `dispatch('list.search.filter')`. */\n dispatch(commandId: string, args?: Record<string, unknown>): void {\n this.list?.dispatch(commandId, args);\n }\n\n /**\n * Rename a row in place. Needs `validateEdit`, and only rows whose\n * `item.editable` is true can be edited. Ends with `flat-list-edit-commit` or `flat-list-edit-cancel`; the\n * label is not rewritten — update the tree in response. Returns false if\n * the row is unknown, not editable, or not on screen.\n */\n beginEdit(key: string): boolean {\n const node = this.#nodeForKey(key);\n if (!this.validateEdit || !node?.item.editable)\n return false;\n return this.list?.beginEdit(key) ?? false;\n }\n\n /** The node whose children are listed. */\n get currentNode(): TreeNode | undefined {\n return resolvePath(this.#root, this.path).at(-1);\n }\n\n get selectedNodes(): ReadonlySet<TreeNode> {\n return this.#selected;\n }\n\n get #root(): TreeNode | undefined {\n return this.model?.root ?? this.root;\n }\n\n // --- Navigation API ---\n\n /** Show the children of the node at this key path. Returns false if the path does not resolve. */\n navigateTo(keys: readonly string[]): boolean {\n const nodes = resolvePath(this.#root, keys);\n if (nodes.length !== keys.length + 1)\n return false;\n this.#setPath(keys, `jump`);\n return true;\n }\n\n /** Enter the child branch with this key. */\n navigateInto(key: string): boolean {\n const node = this.currentNode?.children?.find(n => n.item.key === key);\n if (!node || !isBranch(node))\n return false;\n this.#setPath([...this.path, key], `into`);\n return true;\n }\n\n /** Move to the parent level. Returns false at the root. */\n navigateUp(): boolean {\n if (this.path.length === 0)\n return false;\n this.#pendingFocusKey = this.path.at(-1);\n this.#setPath(this.path.slice(0, -1), `up`);\n return true;\n }\n\n #setPath(path: readonly string[], direction: FlatListNavigateDetail[`direction`]): void {\n if (sameKeys(path, this.path))\n return;\n this.#lastPath = this.path;\n this.#direction = direction;\n // A search over the old level makes no sense on the new one.\n this.list?.search.close();\n this.list?.clearSelection();\n this.path = path;\n }\n\n // --- Lifecycle ---\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n this.#loadController?.abort();\n this.#loadingNode = undefined;\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n if (changed.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = this.model?._subscribe((event) => {\n if (event.type === `invalidate` && event.key === this.currentNode?.item.key) {\n const node = this.currentNode;\n if (node)\n node.children = undefined;\n }\n this.requestUpdate();\n // Model data changed in place; recompute rows even though no property did.\n this.#refreshRows(true);\n });\n }\n\n // Keep `path` valid if the tree changed underneath it.\n const valid = resolvePath(this.#root, this.path).length - 1;\n if (this.#root && valid < this.path.length)\n this.path = this.path.slice(0, valid);\n\n const rowInputs = [`root`, `model`, `path`, `branchOrder`, `sort`, `filterPredicate`, `loadChildren`] as const;\n if (rowInputs.some(p => changed.has(p)))\n this.#refreshRows(changed.has(`root`) || changed.has(`model`) || changed.has(`loadChildren`));\n }\n\n protected override updated(changed: PropertyValues): void {\n if (changed.has(`path`) && !sameKeys(this.path, this.#lastPath) && this.#root) {\n const node = this.currentNode;\n if (node) {\n const previousPath = this.#lastPath;\n this.#lastPath = this.path;\n this.dispatchEvent(new CustomEvent<FlatListNavigateDetail>(`flat-list-navigate`, {\n detail: { path: this.path, previousPath, node, direction: this.#direction },\n bubbles: true,\n composed: true,\n }));\n this.#direction = `jump`;\n }\n }\n if (changed.has(`_rows`))\n void this.#settleList();\n if (changed.has(`_rows`) || changed.has(`markedKey`))\n void this.#applyMarked();\n }\n\n /** Recompute the level's rows, loading children first when they are not yet known. */\n #refreshRows(reload: boolean): void {\n const node = this.currentNode;\n if (!node) {\n this._rows = [];\n return;\n }\n if (node.children === undefined && (this.model || this.loadChildren) && (reload || this.#loadingNode !== node)) {\n void this.#load(node);\n return;\n }\n this.#applyRows(node);\n }\n\n #applyRows(node: TreeNode): void {\n const filter = this.filterPredicate;\n const depth = this.path.length;\n const children = (node.children ?? []).filter(c => !filter || filter(c, depth));\n const rows = orderRows(children, this.branchOrder, this.sort);\n if (!sameNodes(rows, this._rows))\n this._rows = rows;\n }\n\n async #load(node: TreeNode): Promise<void> {\n this.#loadController?.abort();\n const controller = new AbortController();\n this.#loadController = controller;\n this.#loadingNode = node;\n this._loading = true;\n this._rows = [];\n try {\n const depth = this.path.length;\n const children = this.model\n ? await this.model.getChildren(node, depth, controller.signal)\n : [...await collectDataResult(this.loadChildren!({ node, depth }, controller.signal), controller.signal)];\n if (controller.signal.aborted)\n return;\n node.children = [...children];\n } catch {\n if (controller.signal.aborted)\n return;\n node.children = [];\n }\n this.#loadingNode = undefined;\n this._loading = false;\n if (node === this.currentNode)\n this.#applyRows(node);\n }\n\n // --- Interaction ---\n\n #nodeForKey(key: string | undefined): TreeNode | undefined {\n return key === undefined ? undefined : this._rows.find(r => r.key === key)?.node;\n }\n\n /** A single click on a branch's chevron enters it, without selecting the row. */\n #onChevronClick(e: Event, node: TreeNode): void {\n e.stopPropagation();\n this.navigateInto(node.item.key);\n }\n\n #nodeForElement(el: Element | undefined): TreeNode | undefined {\n return el ? this.#nodeForKey(el.getAttribute(`data-key`) ?? undefined) : this.currentNode;\n }\n\n #canDropOn = (el: Element | undefined, dataTransfer: DataTransfer): boolean => {\n const node = this.#nodeForElement(el);\n return !!node && (this.canDrop?.(node, dataTransfer) ?? true);\n };\n\n /** Accept every drag that got past `canDrop`; the consumer only hears about the drop. */\n #onListDragOver = (e: CustomEvent<ListDropDetail>): void => {\n if (this.itemsDroppable)\n e.preventDefault();\n };\n\n #onListDrop = (e: CustomEvent<ListDropDetail>): void => {\n const node = this.#nodeForKey(e.detail.key) ?? this.currentNode;\n if (!node)\n return;\n this.dispatchEvent(new CustomEvent<FlatListDropDetail>(`flat-list-drop`, {\n detail: { node, dataTransfer: e.detail.dataTransfer },\n bubbles: true,\n composed: true,\n }));\n };\n\n #onListContextMenu = (e: CustomEvent<ListContextMenuDetail>): void => {\n const node = this.#nodeForKey(e.detail.key);\n if (!node)\n return;\n const nodes = [...e.detail.selectedKeys].map(k => this.#nodeForKey(k)).filter((n): n is TreeNode => n !== undefined);\n const proceed = this.dispatchEvent(new CustomEvent<FlatListContextMenuDetail>(`flat-list-context-menu`, {\n detail: { node, nodes, x: e.detail.x, y: e.detail.y },\n bubbles: true,\n composed: true,\n cancelable: true,\n }));\n if (!proceed)\n e.preventDefault();\n };\n\n #validateEditKey = (value: string, key: string | undefined): boolean => {\n const node = this.#nodeForKey(key);\n return !!node && (this.validateEdit?.(value, node) ?? false);\n };\n\n #onListEditCommit = (e: CustomEvent<ListEditCommitDetail>): void => {\n const node = this.#nodeForKey(e.detail.key);\n if (node) {\n this.dispatchEvent(new CustomEvent<FlatListEditCommitDetail>(`flat-list-edit-commit`, {\n detail: { node, value: e.detail.value },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n #onListEditCancel = (e: CustomEvent<ListEditCancelDetail>): void => {\n const node = this.#nodeForKey(e.detail.key);\n if (node) {\n this.dispatchEvent(new CustomEvent<FlatListEditCancelDetail>(`flat-list-edit-cancel`, {\n detail: { node },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n #onListSelect = (e: CustomEvent<ListSelectDetail>): void => {\n const previous = this.#selected;\n const nodes = [...e.detail.selectedKeys]\n .map(k => this.#nodeForKey(k))\n .filter((n): n is TreeNode => n !== undefined);\n this.#selected = new Set(nodes);\n this.dispatchEvent(new CustomEvent<FlatListSelectDetail>(`flat-list-select`, {\n detail: { selected: this.#selected, selectedKeys: e.detail.selectedKeys, previous },\n bubbles: true,\n composed: true,\n }));\n };\n\n #onListActivate = (e: CustomEvent<{ item: Element }>): void => {\n const key = e.detail.item.getAttribute(`data-key`) ?? undefined;\n const node = this.#nodeForKey(key);\n if (!node)\n return;\n if (isBranch(node)) {\n this.navigateInto(node.item.key);\n return;\n }\n this.dispatchEvent(new CustomEvent<FlatListActivateDetail>(`flat-list-activate`, {\n detail: { node },\n bubbles: true,\n composed: true,\n }));\n };\n\n #onToolbarSlotChange = (e: Event): void => {\n this._hasToolbar = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).some(n => n.nodeType === Node.ELEMENT_NODE || !!n.textContent?.trim());\n };\n\n #syncFocusVisible = (): void => {\n this._focusVisible = this.list?.matches(`:focus-visible`) ?? false;\n };\n\n #onKeyDown = (e: KeyboardEvent): void => {\n if (e.defaultPrevented || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey)\n return;\n // Leave the search overlay's text field alone.\n const origin = e.composedPath()[0];\n if (origin instanceof HTMLInputElement || origin instanceof HTMLTextAreaElement)\n return;\n\n if (e.key === `ArrowRight` || e.key === `ArrowLeft` || e.key === `Backspace`) {\n // The level is about to change under a resting pointer; hover must not steal the cursor.\n TickledController.ignoreHoverUntilPointerMoves();\n }\n\n if (e.key === `ArrowRight`) {\n const node = this.#nodeForKey(this.list?.tickledKey);\n if (node && isBranch(node)) {\n e.preventDefault();\n this.navigateInto(node.item.key);\n }\n } else if (e.key === `ArrowLeft` || e.key === `Backspace`) {\n if (this.navigateUp())\n e.preventDefault();\n }\n };\n\n /** A crumb was chosen (or the Up button used): go to that node, or to its parent and select it if it is a leaf. */\n #onCrumbSelect = (e: CustomEvent<{ selected: ReadonlySet<TreeNode> }>): void => {\n e.stopPropagation();\n const target = [...e.detail.selected].at(-1);\n const root = this.#root;\n if (!target || !root)\n return;\n const keys = findKeyPath(root, target);\n if (!keys)\n return;\n if (isBranch(target)) {\n const direction = keys.length < this.path.length && keys.every((k, i) => k === this.path[i]) ? `up` : `jump`;\n this.#setPath(keys, direction);\n } else {\n const levelPath = keys.slice(0, -1);\n const sameLevel = sameKeys(levelPath, this.path);\n this.#setPath(levelPath, `jump`);\n this.#pendingSelectKey = target.item.key;\n // Rows will not change when the leaf is already on this level.\n if (sameLevel)\n void this.#settleList();\n }\n };\n\n /** Flag the marked row. Rows are rebuilt with the level, so this runs after each rebuild. */\n async #applyMarked(): Promise<void> {\n const list = this.list;\n if (!list)\n return;\n await list.updateComplete;\n for (const row of list.querySelectorAll(`li[data-key]`))\n row.toggleAttribute(`data-marked`, row.getAttribute(`data-key`) === this.markedKey);\n }\n\n /** After the inner list has rebuilt, place the cursor / selection / focus. */\n async #settleList(): Promise<void> {\n const list = this.list;\n if (!list)\n return;\n const hadFocus = this.matches(`:focus-within`);\n await list.updateComplete;\n const select = this.#pendingSelectKey;\n const focusKey = this.#pendingFocusKey ?? select ?? this._rows[0]?.key;\n this.#pendingSelectKey = undefined;\n this.#pendingFocusKey = undefined;\n if (select)\n list.selectKeys([select]);\n if (focusKey !== undefined)\n list.focusKey(focusKey);\n if (hadFocus)\n list.focus();\n }\n\n // --- Rendering ---\n\n /** Two stable formatters, so toggling `validateEdit` rebuilds the rows with or without edit hooks. */\n #renderPlainRow = (row: unknown) => this.#renderRow(row, false);\n #renderEditableRow = (row: unknown) => this.#renderRow(row, true);\n\n #renderRow(row: unknown, editingEnabled: boolean) {\n const { node } = row as FlatRow;\n const textColor = appearanceColor(node.item.textColor);\n const editable = editingEnabled && node.item.editable === true;\n return html`<span class=\"label\" data-edit-label=${editable ? `` : nothing} data-edit-value=${editable ? node.item.label : nothing} style=${textColor ? `color:${textColor}` : nothing}>${node.item.label}</span>`;\n }\n\n #renderIcon = (row: unknown) => {\n const { node } = row as FlatRow;\n return node.item.icon ? html`<ixfx-icon name=${node.item.icon}></ixfx-icon>` : undefined;\n };\n\n #renderBadge = (row: unknown) => {\n const { node, branch } = row as FlatRow;\n const badge = appearanceAbsent(node.item.badge) ? nothing : node.item.badge;\n const textColor = appearanceColor(node.item.textColor);\n return html`${badge}${branch\n ? html`<span\n class=\"chevron\"\n aria-hidden=\"true\"\n style=${textColor ? `color:${textColor}` : nothing}\n @pointerdown=${(e: Event) => e.stopPropagation()}\n @click=${(e: Event) => this.#onChevronClick(e, node)}\n >›</span>`\n : nothing}`;\n };\n\n protected override render() {\n const root = this.#root;\n return html`\n <div class=\"crumbs\" part=\"crumbs\">\n <ixfx-crumb-navigation\n .root=${root}\n .selectedNode=${this.currentNode}\n .loadChildren=${this.loadChildren}\n selection-filter=\"all\"\n pad-ending\n leading-caret\n ?with-up=${this.withUp}\n ?hide-root=${this.hideRoot}\n @select=${this.#onCrumbSelect}\n ></ixfx-crumb-navigation>\n <div class=\"toolbar\" part=\"toolbar\" ?hidden=${!this._hasToolbar}>\n <slot @slotchange=${this.#onToolbarSlotChange}></slot>\n </div>\n </div>\n <div class=\"body\">\n <ixfx-vertical-list\n .items=${this._rows}\n .formatter=${this.validateEdit ? this.#renderEditableRow : this.#renderPlainRow}\n .icon=${this.#renderIcon}\n .iconColor=${(row: unknown) => appearanceColor((row as FlatRow).node.item.iconColor)}\n .badge=${this.#renderBadge}\n key-property=\"key\"\n .selectionMode=${this.selectionMode}\n .interactionMode=${this.interactionMode}\n .itemWrap=${this.itemWrap}\n .searchModes=${this.searchModes}\n ?items-draggable=${this.itemsDraggable}\n ?items-droppable=${this.itemsDroppable}\n .canDrop=${this.#canDropOn}\n .editValidator=${this.#validateEditKey}\n .virtualize=${this.virtualize}\n .itemHeight=${this.itemHeight}\n @list-drag-over=${this.#onListDragOver}\n @list-drop=${this.#onListDrop}\n @list-context-menu=${this.#onListContextMenu}\n @list-edit-commit=${this.#onListEditCommit}\n @list-edit-cancel=${this.#onListEditCancel}\n @list-select=${this.#onListSelect}\n @list-activate=${this.#onListActivate}\n @keydown=${this.#onKeyDown}\n @focusin=${this.#syncFocusVisible}\n @focusout=${this.#syncFocusVisible}\n ></ixfx-vertical-list>\n ${this._rows.length === 0\n ? html`<div class=\"empty\" part=\"empty\">${this._loading ? `Loading…` : this.emptyText}</div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [themeFallbacks, css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n overflow: hidden;\n background: var(--flat-list-bg, var(--list-bg, var(--surface-3)));\n color: var(--flat-list-text, var(--list-text, var(--surface-3-text)));\n border: 1px solid var(--flat-list-border, var(--list-border, var(--border)));\n border-radius: var(--flat-list-radius, var(--list-radius, var(--radius-s)));\n }\n\n .crumbs {\n display: flex;\n align-items: center;\n gap: var(--flat-list-toolbar-gap, var(--space-xs));\n flex: none;\n font-size: var(--flat-list-crumb-font-size, var(--text-s));\n padding: var(--flat-list-crumb-padding, var(--space-xs));\n border-bottom: 1px solid var(--flat-list-border, var(--list-border, var(--border)));\n }\n\n .crumbs ixfx-crumb-navigation {\n flex: 1 1 0;\n min-width: 0;\n }\n\n .toolbar {\n display: flex;\n flex: none;\n align-items: center;\n gap: var(--flat-list-toolbar-gap, var(--space-xs));\n }\n\n .toolbar[hidden] {\n display: none;\n }\n\n .body {\n position: relative;\n flex: 1 1 auto;\n min-height: 0;\n }\n\n :host([data-focus-visible]) {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n ixfx-vertical-list {\n /* The ring is drawn round the whole component instead. */\n outline: none;\n /* Fill .body absolutely: a percentage height does not reliably resolve\n inside a flex item, and an unbounded list never scrolls the cursor into view. */\n position: absolute;\n inset: 0;\n --list-bg: transparent;\n --list-border: none;\n --list-radius: 0;\n }\n\n .empty {\n position: absolute;\n inset: 0;\n display: grid;\n place-items: center;\n pointer-events: none;\n color: var(--flat-list-empty-text, var(--surface-muted-text));\n }\n\n li[data-marked] {\n background: var(--flat-list-marked-bg, color-mix(in srgb, var(--accent) 18%, transparent));\n box-shadow: inset 3px 0 0 var(--flat-list-marked-bar, var(--accent));\n }\n\n .label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* Highlight rule for incremental search: the rows live in this shadow root,\n so the page-level ::highlight() rule cannot reach them. */\n ::highlight(vertical-list-search) {\n background: var(--accent);\n color: var(--accent-text, #fff);\n }\n\n .chevron {\n margin-inline-start: auto;\n padding-inline-start: 0.5em;\n padding-inline-end: var(--flat-list-chevron-gap, 0.4em);\n /* Inherit the row's text colour, so it follows selected / tickled states. */\n color: inherit;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-flat-list': FlatListElement;\n }\n}\n\nexport interface FlatListElement {\n addEventListener<K extends keyof FlatListElementEventMap>(\n type: K,\n listener: (this: FlatListElement, event: FlatListElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions\n ): void;\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ import { a as ListContextMenuDetail, c as ListDragLeaveEvent, d as ListDropEvent
|
|
|
24
24
|
import { a as EditableMode, i as EditableLabelChangeEvent, n as EditableLabel, o as EntryMode, r as EditableLabelChangeDetail, t as DisplayTextLogic } from "./editable-label-rzXkjf1H.js";
|
|
25
25
|
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-C1xzr1z7.js";
|
|
26
26
|
import { ListGroupHeaderElement } from "./list-group-header.js";
|
|
27
|
-
import { _ as FlatListSelectEvent, a as FlatListContextMenuDetail, c as FlatListDropEvent, d as FlatListEditCommitDetail, f as FlatListEditCommitEvent, g as FlatListSelectDetail, h as FlatListNavigateEvent, i as FlatListBranchOrder, l as FlatListEditCancelDetail, m as FlatListNavigateDetail, n as FlatListActivateDetail, o as FlatListContextMenuEvent, p as FlatListElementEventMap, r as FlatListActivateEvent, s as FlatListDropDetail, t as FlatListElement, u as FlatListEditCancelEvent } from "./flat-list-
|
|
27
|
+
import { _ as FlatListSelectEvent, a as FlatListContextMenuDetail, c as FlatListDropEvent, d as FlatListEditCommitDetail, f as FlatListEditCommitEvent, g as FlatListSelectDetail, h as FlatListNavigateEvent, i as FlatListBranchOrder, l as FlatListEditCancelDetail, m as FlatListNavigateDetail, n as FlatListActivateDetail, o as FlatListContextMenuEvent, p as FlatListElementEventMap, r as FlatListActivateEvent, s as FlatListDropDetail, t as FlatListElement, u as FlatListEditCancelEvent } from "./flat-list-Ohxqsy0g.js";
|
|
28
28
|
import { FormElement } from "./form.js";
|
|
29
29
|
import { A as DragSelectRect, C as TreeKeyboardNavControllerConfig, D as ListSelectionGesture, E as ListSelectionControllerConfig, M as ListDragSelectControllerConfig, O as ListSelectionModes, S as TreeKeyboardNavController, T as ListSelectionController, _ as GridListTickleDetail, a as GridListCaptionBackdrop, b as GridListViewportChangeEvent, c as GridListDataAdapter, d as GridListItemClickDetail, f as GridListItemClickEvent, g as GridListSelectEvent, h as GridListSelectDetail, i as GridListCaptionAlign, j as ListDragSelectController, k as isMultiMode, l as GridListElementEventMap, m as GridListOrientation, n as GridListActivateDetail, o as GridListCaptionPosition, p as GridListItemEventDetail, r as GridListActivateEvent, s as GridListCaptionStyle, t as GridListElement, u as GridListFullElementEventMap, v as GridListTickleEvent, w as TreeKeyboardNavItemId, x as TreeKeyboardNavCallbacks, y as GridListViewportChangeDetail } from "./grid-list-pefLORIr.js";
|
|
30
30
|
import { n as ListNativeDragControllerConfig, t as ListNativeDragController } from "./list-native-drag-controller-ChIi3eK5.js";
|
package/docs-user/flat-list.md
CHANGED
|
@@ -103,8 +103,20 @@ Navigate / select / filter search works over the current level, as in [`ixfx-ver
|
|
|
103
103
|
|
|
104
104
|
## CSS variables
|
|
105
105
|
|
|
106
|
-
`--flat-list-bg`, `--flat-list-text`, `--flat-list-border`, `--flat-list-radius`, `--flat-list-crumb-padding`, `--flat-list-crumb-font-size` (default `--text-s`), `--flat-list-chevron-gap`, `--flat-list-marked-bg`, `--flat-list-marked-bar`, `--flat-list-empty-text`. Each falls back to the matching `--list-*` variable. Other `--list-*` variables (e.g. `--list-item-height`) reach the inner list.
|
|
106
|
+
`--flat-list-bg`, `--flat-list-text`, `--flat-list-border`, `--flat-list-radius`, `--flat-list-crumb-padding`, `--flat-list-crumb-font-size` (default `--text-s`), `--flat-list-toolbar-gap`, `--flat-list-chevron-gap`, `--flat-list-marked-bg`, `--flat-list-marked-bar`, `--flat-list-empty-text`. Each falls back to the matching `--list-*` variable. Other `--list-*` variables (e.g. `--list-item-height`) reach the inner list.
|
|
107
|
+
|
|
108
|
+
## Toolbar slot
|
|
109
|
+
|
|
110
|
+
Anything you put inside the element goes in a toolbar to the right of the crumb bar, which shrinks to make room. With nothing slotted, the crumbs use the full width.
|
|
111
|
+
|
|
112
|
+
```html
|
|
113
|
+
<ixfx-flat-list>
|
|
114
|
+
<ixfx-button>New Set</ixfx-button>
|
|
115
|
+
</ixfx-flat-list>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Space between items is `--flat-list-toolbar-gap`.
|
|
107
119
|
|
|
108
120
|
## CSS parts
|
|
109
121
|
|
|
110
|
-
`crumbs` (the bar above the list), `empty`.
|
|
122
|
+
`crumbs` (the bar above the list), `toolbar` (the slot's wrapper), `empty`.
|
package/docs-user/index.json
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flat-list-DEDG6epz.d.ts","names":[],"sources":["../src/flat-list/types.ts","../src/flat-list/flat-list.ts"],"mappings":";;;;;;;;;KAGY;KAEA;;WAED;;WAEA;;WAEA,MAAM;;WAEN;;KAGC;WACD,UAAU,YAAY;WACtB,cAAc;WACd,UAAU,YAAY;;KAGrB;WACD,MAAM;;KAGL;;WAED,MAAM;WACN,cAAc;;KAGb;;WAED,MAAM;;WAEN,gBAAgB;WAChB;WACA;;KAGC;WACD,MAAM;WACN;;KAGC;WACD,MAAM;;KAGL,wBAAwB,YAAY;KACpC,sBAAsB,YAAY;KAClC,wBAAwB,YAAY;KAEpC,oBAAoB,YAAY;KAChC,2BAA2B,YAAY;KACvC,0BAA0B,YAAY;KACtC,0BAA0B,YAAY;UAEjC;EACf,sBAAsB;EACtB,oBAAoB;EACpB,sBAAsB;EACtB,kBAAkB;EAClB,0BAA0B;EAC1B,yBAAyB;EACzB,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCiFd,wBAAwB;;EAEnC,MAAM;EAGN,OAAO;;EAIP;;EAIA,cAAc;EAGd,iBAAiB;;EAIjB,QAAQ,GAAG,UAAU,GAAG;EAGxB,aAAa;EAGb,eAAe;EAGf,iBAAiB;EAGjB;EAGA;EAGA;;EAIA;;;;;EAOA,WAAW,MAAM,UAAU,cAAc;;;;;;EAQzC,gBAAgB,eAAe,MAAM;;EAIrC;;EAIA;;EAIA;EAGA;EAGA;;EAIA;;UAIQ;UAES;UACA;;MAcb,QAAQ;;MAKR,YAAY;;EAKhB,SAAS,mBAAmB,OAAO;;;;;;;EAUnC,UAAU;;MAQN,eAAe;MAIf,iBAAiB,YAAY;;EAWjC,WAAW;;EASX,aAAa;;EASb;EAqBS;YAQU,WAAW,SAAS;YAyBpB,QAAQ,SAAS;YAqSjB,wBAAM;SAoDT,sBAAM;;QAkFhB;YACI;IACR,kBAAkB;;;UAIL;EACf,iBAAiB,gBAAgB,yBAC/B,MAAM,GACN,WAAW,MAAM,iBAAiB,OAAO,wBAAwB,aACjE,oBAAoB;EAEtB,iBACE,cACA,UAAU,oCACV,oBAAoB"}
|