@xui/tree-select 2.0.0-alpha.16 → 2.0.0-alpha.17
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/README.md
CHANGED
|
@@ -127,7 +127,7 @@ The full token reference, rendered in both themes, is the **Design tokens** page
|
|
|
127
127
|
|
|
128
128
|
**Date & time** — [`@xui/date-input`](https://www.npmjs.com/package/@xui/date-input) · [`@xui/date-picker`](https://www.npmjs.com/package/@xui/date-picker) · [`@xui/date-range-input`](https://www.npmjs.com/package/@xui/date-range-input) · [`@xui/date-range-picker`](https://www.npmjs.com/package/@xui/date-range-picker) · [`@xui/time-picker`](https://www.npmjs.com/package/@xui/time-picker) · [`@xui/timezone-select`](https://www.npmjs.com/package/@xui/timezone-select)
|
|
129
129
|
|
|
130
|
-
**Data display** — [`@xui/avatar`](https://www.npmjs.com/package/@xui/avatar) · [`@xui/
|
|
130
|
+
**Data display** — [`@xui/avatar`](https://www.npmjs.com/package/@xui/avatar) · [`@xui/card`](https://www.npmjs.com/package/@xui/card) · [`@xui/card-list`](https://www.npmjs.com/package/@xui/card-list) · [`@xui/carousel`](https://www.npmjs.com/package/@xui/carousel) · [`@xui/data-table`](https://www.npmjs.com/package/@xui/data-table) · [`@xui/descriptions`](https://www.npmjs.com/package/@xui/descriptions) · [`@xui/entity-title`](https://www.npmjs.com/package/@xui/entity-title) · [`@xui/kbd`](https://www.npmjs.com/package/@xui/kbd) · [`@xui/statistic`](https://www.npmjs.com/package/@xui/statistic) · [`@xui/status`](https://www.npmjs.com/package/@xui/status) · [`@xui/table`](https://www.npmjs.com/package/@xui/table) · [`@xui/tag`](https://www.npmjs.com/package/@xui/tag) · [`@xui/timeline`](https://www.npmjs.com/package/@xui/timeline) · [`@xui/tree`](https://www.npmjs.com/package/@xui/tree)
|
|
131
131
|
|
|
132
132
|
**Navigation** — [`@xui/breadcrumb`](https://www.npmjs.com/package/@xui/breadcrumb) · [`@xui/menubar`](https://www.npmjs.com/package/@xui/menubar) · [`@xui/navbar`](https://www.npmjs.com/package/@xui/navbar) · [`@xui/navigation-menu`](https://www.npmjs.com/package/@xui/navigation-menu) · [`@xui/pagination`](https://www.npmjs.com/package/@xui/pagination) · [`@xui/panel-stack`](https://www.npmjs.com/package/@xui/panel-stack) · [`@xui/steps`](https://www.npmjs.com/package/@xui/steps) · [`@xui/tabs`](https://www.npmjs.com/package/@xui/tabs)
|
|
133
133
|
|
|
@@ -5,6 +5,7 @@ import { injectXDirection, uniqueId } from '@xui/core/a11y';
|
|
|
5
5
|
import { createXValueAccessor, provideXValueAccessor } from '@xui/core/forms';
|
|
6
6
|
import { injectXOverlay } from '@xui/core/overlay';
|
|
7
7
|
import { collectExpandedIds, flattenVisibleTree, treeKeyAction, toggleExpandedId } from '@xui/core/tree';
|
|
8
|
+
import { tagVariants } from '@xui/tag';
|
|
8
9
|
|
|
9
10
|
const toTreeNode = (node) => ({
|
|
10
11
|
id: node.value,
|
|
@@ -254,6 +255,16 @@ class XuiTreeSelect {
|
|
|
254
255
|
...(ngDevMode ? [{ debugName: "triggerClass" }] : /* istanbul ignore next */ []));
|
|
255
256
|
panelClass = computed(() => xui('border-border bg-surface-overlay max-h-72 w-full overflow-auto rounded-lg border p-1 shadow-overlay'), /* @ts-ignore */
|
|
256
257
|
...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
|
|
258
|
+
/**
|
|
259
|
+
* A selected value reads as a tag, matching the chips xui-multi-select shows for the same job.
|
|
260
|
+
*
|
|
261
|
+
* It borrows the variant map rather than rendering an xui-tag: the trigger is a button, and a
|
|
262
|
+
* tag's remove control is a button too, which may not nest inside one. What the hand-rolled chip
|
|
263
|
+
* had instead was bg-surface-inset, the same colour the dark theme gives the trigger's
|
|
264
|
+
* bg-surface, and no border — so a selection read as bare text.
|
|
265
|
+
*/
|
|
266
|
+
chipClass = computed(() => xui(tagVariants({ minimal: true, color: 'primary' })), /* @ts-ignore */
|
|
267
|
+
...(ngDevMode ? [{ debugName: "chipClass" }] : /* istanbul ignore next */ []));
|
|
257
268
|
/**
|
|
258
269
|
* The expand caret. It is drawn pointing right, so a collapsed node has to be
|
|
259
270
|
* flipped in RTL to keep pointing "further in"; expanded always points down.
|
|
@@ -290,9 +301,7 @@ class XuiTreeSelect {
|
|
|
290
301
|
@if (selectedValues().length) {
|
|
291
302
|
<span class="flex flex-wrap gap-1">
|
|
292
303
|
@for (val of selectedValues(); track val) {
|
|
293
|
-
<span
|
|
294
|
-
class="bg-surface-inset text-foreground inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs"
|
|
295
|
-
>
|
|
304
|
+
<span [class]="chipClass()">
|
|
296
305
|
{{ labelOf(val) }}
|
|
297
306
|
<!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
|
|
298
307
|
<span class="hover:text-error cursor-pointer" (click)="removeChip(val, $event)">×</span>
|
|
@@ -390,9 +399,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
390
399
|
@if (selectedValues().length) {
|
|
391
400
|
<span class="flex flex-wrap gap-1">
|
|
392
401
|
@for (val of selectedValues(); track val) {
|
|
393
|
-
<span
|
|
394
|
-
class="bg-surface-inset text-foreground inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs"
|
|
395
|
-
>
|
|
402
|
+
<span [class]="chipClass()">
|
|
396
403
|
{{ labelOf(val) }}
|
|
397
404
|
<!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
|
|
398
405
|
<span class="hover:text-error cursor-pointer" (click)="removeChip(val, $event)">×</span>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xui-tree-select.mjs","sources":["../../../../../../libs/ui/tree-select/xui/src/lib/tree-select.ts","../../../../../../libs/ui/tree-select/xui/src/index.ts","../../../../../../libs/ui/tree-select/xui/src/xui-tree-select.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n input,\n linkedSignal,\n model,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport type { ControlValueAccessor } from '@angular/forms';\nimport { xui } from '@xui/core';\nimport { injectXDirection, uniqueId } from '@xui/core/a11y';\nimport { createXValueAccessor, provideXValueAccessor } from '@xui/core/forms';\nimport { injectXOverlay, type XOverlayRef } from '@xui/core/overlay';\nimport {\n collectExpandedIds,\n flattenVisibleTree,\n toggleExpandedId,\n treeKeyAction,\n type XTreeNode,\n type XTreeNodeId\n} from '@xui/core/tree';\nimport type { ClassValue } from 'clsx';\n\n/**\n * A node in the tree-select panel — the shared {@link XTreeNode} shape, keyed\n * by `value` instead of `id`.\n */\nexport interface XuiTreeSelectNode extends Omit<XTreeNode, 'id' | 'children' | 'data'> {\n /** The option value; doubles as the node's identity in the tree. */\n value: string;\n children?: XuiTreeSelectNode[];\n}\n\n/** The headless tree node backing a {@link XuiTreeSelectNode}. */\ntype PanelNode = XTreeNode<XuiTreeSelectNode>;\n\nconst toTreeNode = (node: XuiTreeSelectNode): PanelNode => ({\n id: node.value,\n label: node.label,\n isExpanded: node.isExpanded,\n hasCaret: node.hasCaret,\n disabled: node.disabled,\n children: node.children?.map(toTreeNode),\n data: node\n});\n\n/**\n * A select whose options are a tree. Single-select binds `value`; with\n * `multiple`, `value` is a string array shown as removable chips. Branches\n * expand/collapse; leaf (or any) nodes are selectable.\n *\n * The panel follows the APG tree keyboard contract from the trigger:\n * Up/Down move the active row, the inline-end/-start arrows (RTL-aware)\n * expand/collapse or step in/out, Home/End jump, Enter/Space select and\n * Escape closes.\n *\n * ```html\n * <xui-tree-select [nodes]=\"tree\" [(value)]=\"picked\" placeholder=\"Pick a node\" />\n * ```\n */\n@Component({\n selector: 'xui-tree-select',\n template: `\n <button\n #trigger\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"tree\"\n [class]=\"triggerClass()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? panelId : null\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (multiple()) {\n @if (selectedValues().length) {\n <span class=\"flex flex-wrap gap-1\">\n @for (val of selectedValues(); track val) {\n <span\n class=\"bg-surface-inset text-foreground inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs\"\n >\n {{ labelOf(val) }}\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <span class=\"hover:text-error cursor-pointer\" (click)=\"removeChip(val, $event)\">×</span>\n </span>\n }\n </span>\n } @else {\n <span class=\"text-foreground-muted\">{{ placeholder() }}</span>\n }\n } @else {\n <span [class]=\"displayLabel() ? 'text-foreground' : 'text-foreground-muted'\">{{\n displayLabel() || placeholder()\n }}</span>\n }\n <svg viewBox=\"0 0 24 24\" class=\"text-foreground-muted ms-auto h-4 w-4 shrink-0\" fill=\"none\">\n <path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <ng-template #panel>\n <div [class]=\"panelClass()\" role=\"tree\" [id]=\"panelId\">\n @for (row of rows(); track row.node.id; let i = $index) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n role=\"treeitem\"\n [id]=\"rowId(i)\"\n [class]=\"rowClass(row.node)\"\n [style.padding-inline-start.px]=\"8 + row.level * 16\"\n [attr.aria-expanded]=\"row.expandable ? expanded().has(row.node.id) : null\"\n [attr.aria-selected]=\"isSelected(row.node.data!.value)\"\n [attr.aria-disabled]=\"row.node.disabled || null\"\n [attr.aria-level]=\"row.level + 1\"\n (click)=\"pick(row.node.data!)\"\n >\n @if (row.expandable) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <span\n class=\"hover:text-foreground text-foreground-muted -ms-1 flex h-4 w-4 items-center justify-center\"\n (click)=\"toggleExpand(row.node.id, $event)\"\n >\n <svg viewBox=\"0 0 24 24\" [class]=\"caretClass(expanded().has(row.node.id))\" fill=\"none\">\n <path\n d=\"M9 6l6 6-6 6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n } @else {\n <span class=\"w-3\"></span>\n }\n @if (multiple()) {\n <span [class]=\"checkboxClass(isSelected(row.node.data!.value))\">\n @if (isSelected(row.node.data!.value)) {\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3\" fill=\"none\">\n <path\n d=\"M20 6 9 17l-5-5\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n </span>\n }\n <span class=\"truncate\">{{ row.node.label }}</span>\n </div>\n }\n </div>\n </ng-template>\n `,\n host: {\n '[class]': 'computedClass()'\n },\n providers: [provideXValueAccessor(() => XuiTreeSelect)],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n})\nexport class XuiTreeSelect implements ControlValueAccessor {\n protected readonly direction = injectXDirection();\n protected readonly panelId = uniqueId('xui-tree-select-panel');\n private readonly overlay = injectXOverlay();\n private readonly trigger = viewChild.required<ElementRef<HTMLElement>>('trigger');\n private readonly panel = viewChild.required<TemplateRef<unknown>>('panel');\n private ref: XOverlayRef | null = null;\n\n readonly class = input<ClassValue>('');\n readonly nodes = input<XuiTreeSelectNode[]>([]);\n readonly value = model<string | string[] | null>(null);\n readonly multiple = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n readonly placeholder = input<string>('Select');\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n protected readonly cva = createXValueAccessor<string | string[] | null>({\n onWrite: value => this.value.set(value ?? null),\n disabled: this.disabled\n });\n protected readonly isDisabled = this.cva.disabled;\n\n /** Whether the panel has ever been open — so the initial closed state is not \"touched\". */\n private hasOpened = false;\n\n protected readonly open = signal(false);\n\n /** The shared headless tree, keyed by each node's `value`. */\n private readonly tree = computed<PanelNode[]>(() => this.nodes().map(toTreeNode));\n\n /** Expanded branch values; reseeded from `isExpanded` when the nodes change. */\n protected readonly expanded = linkedSignal<PanelNode[], Set<XTreeNodeId>>({\n source: this.tree,\n computation: nodes => collectExpandedIds(nodes)\n });\n\n /** The visible rows of the panel, flattened in visual order. */\n protected readonly rows = computed(() => flattenVisibleTree(this.tree(), this.expanded()));\n\n /** The keyboard-active row's value (the trigger keeps DOM focus). */\n protected readonly activeValue = signal<string | null>(null);\n\n protected readonly activeDescendant = computed(() => {\n if (!this.open()) {\n return null;\n }\n const index = this.rows().findIndex(row => row.node.id === this.activeValue());\n return index >= 0 ? this.rowId(index) : null;\n });\n\n private readonly byValue = computed(() => {\n const map = new Map<string, XuiTreeSelectNode>();\n const walk = (list: XuiTreeSelectNode[]): void => {\n for (const node of list) {\n map.set(node.value, node);\n if (node.children) {\n walk(node.children);\n }\n }\n };\n walk(this.nodes());\n return map;\n });\n\n protected readonly selectedValues = computed(() => {\n const value = this.value();\n return Array.isArray(value) ? value : value != null ? [value] : [];\n });\n\n /** The single-select label (empty in multiple mode or when unset). */\n protected readonly displayLabel = computed(() => {\n const value = this.value();\n return typeof value === 'string' && value ? this.labelOf(value) : '';\n });\n\n constructor() {\n // The `open` signal is the single source of truth; the overlay follows it.\n effect(() => {\n const open = this.open();\n\n untracked(() => (open ? this.attach() : this.detach()));\n });\n\n // Mark the control touched once the panel closes after having been open.\n effect(() => {\n if (this.open()) {\n this.hasOpened = true;\n } else if (this.hasOpened) {\n untracked(() => this.cva.markTouched());\n }\n });\n }\n\n private attach(): void {\n if (this.ref) {\n return;\n }\n\n // DOM focus stays on the trigger (the combobox contract points at rows via\n // `aria-activedescendant`), so the overlay must not trap, steal or restore\n // focus. Outside clicks dismiss through the overlay's click-phase check, so\n // an outside press that starts a drag does not close the panel early.\n const ref = this.overlay.open(this.panel(), {\n origin: this.trigger().nativeElement,\n placement: 'bottom-start',\n offset: 4,\n matchOriginWidth: true,\n restoreFocus: false\n });\n\n this.ref = ref;\n\n // The overlay can close itself (Escape, outside click). Fold that back into\n // `open` so the model never lies about what is on screen; a stale ref's late\n // close must not clobber a panel that was reopened in the meantime.\n void ref.closed.then(() => {\n if (this.ref === ref) {\n this.ref = null;\n untracked(() => this.open.set(false));\n }\n });\n }\n\n private detach(): void {\n // Null synchronously so a reopen in the same tick does not see a stale ref.\n const ref = this.ref;\n this.ref = null;\n ref?.close();\n }\n\n protected rowId(index: number): string {\n return `${this.panelId}-row-${index}`;\n }\n\n protected labelOf(value: string | null): string {\n return (value != null && this.byValue().get(value)?.label) || '';\n }\n\n protected isSelected(value: string): boolean {\n return this.selectedValues().includes(value);\n }\n\n protected toggle(): void {\n if (this.isDisabled()) {\n return;\n }\n if (this.open()) {\n this.open.set(false);\n } else {\n this.openPanel();\n }\n }\n\n private openPanel(): void {\n this.open.set(true);\n // Land the active row on the (first) selected value, else the first row.\n const rows = this.rows();\n const selected = this.selectedValues();\n const active = rows.find(row => selected.includes(String(row.node.id))) ?? rows[0];\n this.activeValue.set(active ? String(active.node.id) : null);\n }\n\n protected onTriggerKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return;\n }\n\n if (!this.open()) {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.openPanel();\n }\n return;\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n this.open.set(false);\n return;\n }\n if (event.key === 'Tab') {\n this.open.set(false);\n return;\n }\n\n const rows = this.rows();\n const index = rows.findIndex(row => row.node.id === this.activeValue());\n const action = treeKeyAction(event.key, this.direction(), rows, index, this.expanded());\n\n if (!action) {\n return;\n }\n event.preventDefault();\n\n switch (action.kind) {\n case 'focus':\n this.activeValue.set(String(action.node.id));\n break;\n case 'expand':\n case 'collapse':\n this.expanded.update(set => toggleExpandedId(set, action.node.id));\n break;\n case 'select':\n this.pick(action.node.data!);\n break;\n }\n }\n\n protected toggleExpand(id: XTreeNodeId, event: Event): void {\n event.stopPropagation();\n this.expanded.update(set => toggleExpandedId(set, id));\n }\n\n protected pick(node: XuiTreeSelectNode): void {\n if (node.disabled || this.isDisabled()) {\n return;\n }\n this.activeValue.set(node.value);\n if (this.multiple()) {\n const current = this.selectedValues();\n const next = current.includes(node.value) ? current.filter(v => v !== node.value) : [...current, node.value];\n this.value.set(next);\n this.cva.notifyChange(next);\n } else {\n this.value.set(node.value);\n this.cva.notifyChange(node.value);\n this.open.set(false);\n }\n }\n\n protected removeChip(value: string, event: Event): void {\n event.stopPropagation();\n if (this.isDisabled()) {\n return;\n }\n const next = this.selectedValues().filter(v => v !== value);\n this.value.set(next);\n this.cva.notifyChange(next);\n }\n\n protected readonly computedClass = computed(() => xui('block', this.class()));\n protected readonly triggerClass = computed(() =>\n xui(\n 'border-border bg-surface text-foreground flex min-h-(--control-height-md) w-full items-center gap-1 rounded-md border px-(--control-padding-md) py-1 text-sm outline-none focus-visible:border-primary disabled:opacity-50'\n )\n );\n protected readonly panelClass = computed(() =>\n xui('border-border bg-surface-overlay max-h-72 w-full overflow-auto rounded-lg border p-1 shadow-overlay')\n );\n\n /**\n * The expand caret. It is drawn pointing right, so a collapsed node has to be\n * flipped in RTL to keep pointing \"further in\"; expanded always points down.\n */\n protected caretClass(expanded: boolean): string {\n return xui('h-3.5 w-3.5 transition-transform', expanded ? 'rotate-90' : this.direction() === 'rtl' && 'rotate-180');\n }\n\n protected rowClass(node: PanelNode): string {\n return xui(\n 'flex cursor-pointer items-center gap-1.5 rounded px-1.5 py-1 text-sm select-none',\n node.disabled ? 'text-foreground-subtle cursor-not-allowed' : 'hover:bg-surface-inset',\n node.id === this.activeValue() && 'bg-surface-inset',\n !this.multiple() && this.isSelected(node.data!.value) && 'bg-primary/10 text-primary'\n );\n }\n\n protected checkboxClass(selected: boolean): string {\n return xui(\n 'flex h-4 w-4 items-center justify-center rounded border',\n selected ? 'bg-primary border-primary text-primary-foreground' : 'border-border'\n );\n }\n\n readonly writeValue = this.cva.writeValue;\n readonly registerOnChange = this.cva.registerOnChange;\n readonly registerOnTouched = this.cva.registerOnTouched;\n readonly setDisabledState = this.cva.setDisabledState;\n}\n","import { XuiTreeSelect } from './lib/tree-select';\n\nexport * from './lib/tree-select';\n\nexport const XuiTreeSelectImports = [XuiTreeSelect] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"xui-tree-select.mjs","sources":["../../../../../../libs/ui/tree-select/xui/src/lib/tree-select.ts","../../../../../../libs/ui/tree-select/xui/src/index.ts","../../../../../../libs/ui/tree-select/xui/src/xui-tree-select.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n input,\n linkedSignal,\n model,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport type { ControlValueAccessor } from '@angular/forms';\nimport { xui } from '@xui/core';\nimport { injectXDirection, uniqueId } from '@xui/core/a11y';\nimport { createXValueAccessor, provideXValueAccessor } from '@xui/core/forms';\nimport { injectXOverlay, type XOverlayRef } from '@xui/core/overlay';\nimport {\n collectExpandedIds,\n flattenVisibleTree,\n toggleExpandedId,\n treeKeyAction,\n type XTreeNode,\n type XTreeNodeId\n} from '@xui/core/tree';\nimport { tagVariants } from '@xui/tag';\nimport type { ClassValue } from 'clsx';\n\n/**\n * A node in the tree-select panel — the shared {@link XTreeNode} shape, keyed\n * by `value` instead of `id`.\n */\nexport interface XuiTreeSelectNode extends Omit<XTreeNode, 'id' | 'children' | 'data'> {\n /** The option value; doubles as the node's identity in the tree. */\n value: string;\n children?: XuiTreeSelectNode[];\n}\n\n/** The headless tree node backing a {@link XuiTreeSelectNode}. */\ntype PanelNode = XTreeNode<XuiTreeSelectNode>;\n\nconst toTreeNode = (node: XuiTreeSelectNode): PanelNode => ({\n id: node.value,\n label: node.label,\n isExpanded: node.isExpanded,\n hasCaret: node.hasCaret,\n disabled: node.disabled,\n children: node.children?.map(toTreeNode),\n data: node\n});\n\n/**\n * A select whose options are a tree. Single-select binds `value`; with\n * `multiple`, `value` is a string array shown as removable chips. Branches\n * expand/collapse; leaf (or any) nodes are selectable.\n *\n * The panel follows the APG tree keyboard contract from the trigger:\n * Up/Down move the active row, the inline-end/-start arrows (RTL-aware)\n * expand/collapse or step in/out, Home/End jump, Enter/Space select and\n * Escape closes.\n *\n * ```html\n * <xui-tree-select [nodes]=\"tree\" [(value)]=\"picked\" placeholder=\"Pick a node\" />\n * ```\n */\n@Component({\n selector: 'xui-tree-select',\n template: `\n <button\n #trigger\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"tree\"\n [class]=\"triggerClass()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? panelId : null\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (multiple()) {\n @if (selectedValues().length) {\n <span class=\"flex flex-wrap gap-1\">\n @for (val of selectedValues(); track val) {\n <span [class]=\"chipClass()\">\n {{ labelOf(val) }}\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <span class=\"hover:text-error cursor-pointer\" (click)=\"removeChip(val, $event)\">×</span>\n </span>\n }\n </span>\n } @else {\n <span class=\"text-foreground-muted\">{{ placeholder() }}</span>\n }\n } @else {\n <span [class]=\"displayLabel() ? 'text-foreground' : 'text-foreground-muted'\">{{\n displayLabel() || placeholder()\n }}</span>\n }\n <svg viewBox=\"0 0 24 24\" class=\"text-foreground-muted ms-auto h-4 w-4 shrink-0\" fill=\"none\">\n <path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <ng-template #panel>\n <div [class]=\"panelClass()\" role=\"tree\" [id]=\"panelId\">\n @for (row of rows(); track row.node.id; let i = $index) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n role=\"treeitem\"\n [id]=\"rowId(i)\"\n [class]=\"rowClass(row.node)\"\n [style.padding-inline-start.px]=\"8 + row.level * 16\"\n [attr.aria-expanded]=\"row.expandable ? expanded().has(row.node.id) : null\"\n [attr.aria-selected]=\"isSelected(row.node.data!.value)\"\n [attr.aria-disabled]=\"row.node.disabled || null\"\n [attr.aria-level]=\"row.level + 1\"\n (click)=\"pick(row.node.data!)\"\n >\n @if (row.expandable) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <span\n class=\"hover:text-foreground text-foreground-muted -ms-1 flex h-4 w-4 items-center justify-center\"\n (click)=\"toggleExpand(row.node.id, $event)\"\n >\n <svg viewBox=\"0 0 24 24\" [class]=\"caretClass(expanded().has(row.node.id))\" fill=\"none\">\n <path\n d=\"M9 6l6 6-6 6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n } @else {\n <span class=\"w-3\"></span>\n }\n @if (multiple()) {\n <span [class]=\"checkboxClass(isSelected(row.node.data!.value))\">\n @if (isSelected(row.node.data!.value)) {\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3\" fill=\"none\">\n <path\n d=\"M20 6 9 17l-5-5\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n </span>\n }\n <span class=\"truncate\">{{ row.node.label }}</span>\n </div>\n }\n </div>\n </ng-template>\n `,\n host: {\n '[class]': 'computedClass()'\n },\n providers: [provideXValueAccessor(() => XuiTreeSelect)],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n})\nexport class XuiTreeSelect implements ControlValueAccessor {\n protected readonly direction = injectXDirection();\n protected readonly panelId = uniqueId('xui-tree-select-panel');\n private readonly overlay = injectXOverlay();\n private readonly trigger = viewChild.required<ElementRef<HTMLElement>>('trigger');\n private readonly panel = viewChild.required<TemplateRef<unknown>>('panel');\n private ref: XOverlayRef | null = null;\n\n readonly class = input<ClassValue>('');\n readonly nodes = input<XuiTreeSelectNode[]>([]);\n readonly value = model<string | string[] | null>(null);\n readonly multiple = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n readonly placeholder = input<string>('Select');\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n protected readonly cva = createXValueAccessor<string | string[] | null>({\n onWrite: value => this.value.set(value ?? null),\n disabled: this.disabled\n });\n protected readonly isDisabled = this.cva.disabled;\n\n /** Whether the panel has ever been open — so the initial closed state is not \"touched\". */\n private hasOpened = false;\n\n protected readonly open = signal(false);\n\n /** The shared headless tree, keyed by each node's `value`. */\n private readonly tree = computed<PanelNode[]>(() => this.nodes().map(toTreeNode));\n\n /** Expanded branch values; reseeded from `isExpanded` when the nodes change. */\n protected readonly expanded = linkedSignal<PanelNode[], Set<XTreeNodeId>>({\n source: this.tree,\n computation: nodes => collectExpandedIds(nodes)\n });\n\n /** The visible rows of the panel, flattened in visual order. */\n protected readonly rows = computed(() => flattenVisibleTree(this.tree(), this.expanded()));\n\n /** The keyboard-active row's value (the trigger keeps DOM focus). */\n protected readonly activeValue = signal<string | null>(null);\n\n protected readonly activeDescendant = computed(() => {\n if (!this.open()) {\n return null;\n }\n const index = this.rows().findIndex(row => row.node.id === this.activeValue());\n return index >= 0 ? this.rowId(index) : null;\n });\n\n private readonly byValue = computed(() => {\n const map = new Map<string, XuiTreeSelectNode>();\n const walk = (list: XuiTreeSelectNode[]): void => {\n for (const node of list) {\n map.set(node.value, node);\n if (node.children) {\n walk(node.children);\n }\n }\n };\n walk(this.nodes());\n return map;\n });\n\n protected readonly selectedValues = computed(() => {\n const value = this.value();\n return Array.isArray(value) ? value : value != null ? [value] : [];\n });\n\n /** The single-select label (empty in multiple mode or when unset). */\n protected readonly displayLabel = computed(() => {\n const value = this.value();\n return typeof value === 'string' && value ? this.labelOf(value) : '';\n });\n\n constructor() {\n // The `open` signal is the single source of truth; the overlay follows it.\n effect(() => {\n const open = this.open();\n\n untracked(() => (open ? this.attach() : this.detach()));\n });\n\n // Mark the control touched once the panel closes after having been open.\n effect(() => {\n if (this.open()) {\n this.hasOpened = true;\n } else if (this.hasOpened) {\n untracked(() => this.cva.markTouched());\n }\n });\n }\n\n private attach(): void {\n if (this.ref) {\n return;\n }\n\n // DOM focus stays on the trigger (the combobox contract points at rows via\n // `aria-activedescendant`), so the overlay must not trap, steal or restore\n // focus. Outside clicks dismiss through the overlay's click-phase check, so\n // an outside press that starts a drag does not close the panel early.\n const ref = this.overlay.open(this.panel(), {\n origin: this.trigger().nativeElement,\n placement: 'bottom-start',\n offset: 4,\n matchOriginWidth: true,\n restoreFocus: false\n });\n\n this.ref = ref;\n\n // The overlay can close itself (Escape, outside click). Fold that back into\n // `open` so the model never lies about what is on screen; a stale ref's late\n // close must not clobber a panel that was reopened in the meantime.\n void ref.closed.then(() => {\n if (this.ref === ref) {\n this.ref = null;\n untracked(() => this.open.set(false));\n }\n });\n }\n\n private detach(): void {\n // Null synchronously so a reopen in the same tick does not see a stale ref.\n const ref = this.ref;\n this.ref = null;\n ref?.close();\n }\n\n protected rowId(index: number): string {\n return `${this.panelId}-row-${index}`;\n }\n\n protected labelOf(value: string | null): string {\n return (value != null && this.byValue().get(value)?.label) || '';\n }\n\n protected isSelected(value: string): boolean {\n return this.selectedValues().includes(value);\n }\n\n protected toggle(): void {\n if (this.isDisabled()) {\n return;\n }\n if (this.open()) {\n this.open.set(false);\n } else {\n this.openPanel();\n }\n }\n\n private openPanel(): void {\n this.open.set(true);\n // Land the active row on the (first) selected value, else the first row.\n const rows = this.rows();\n const selected = this.selectedValues();\n const active = rows.find(row => selected.includes(String(row.node.id))) ?? rows[0];\n this.activeValue.set(active ? String(active.node.id) : null);\n }\n\n protected onTriggerKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return;\n }\n\n if (!this.open()) {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.openPanel();\n }\n return;\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n this.open.set(false);\n return;\n }\n if (event.key === 'Tab') {\n this.open.set(false);\n return;\n }\n\n const rows = this.rows();\n const index = rows.findIndex(row => row.node.id === this.activeValue());\n const action = treeKeyAction(event.key, this.direction(), rows, index, this.expanded());\n\n if (!action) {\n return;\n }\n event.preventDefault();\n\n switch (action.kind) {\n case 'focus':\n this.activeValue.set(String(action.node.id));\n break;\n case 'expand':\n case 'collapse':\n this.expanded.update(set => toggleExpandedId(set, action.node.id));\n break;\n case 'select':\n this.pick(action.node.data!);\n break;\n }\n }\n\n protected toggleExpand(id: XTreeNodeId, event: Event): void {\n event.stopPropagation();\n this.expanded.update(set => toggleExpandedId(set, id));\n }\n\n protected pick(node: XuiTreeSelectNode): void {\n if (node.disabled || this.isDisabled()) {\n return;\n }\n this.activeValue.set(node.value);\n if (this.multiple()) {\n const current = this.selectedValues();\n const next = current.includes(node.value) ? current.filter(v => v !== node.value) : [...current, node.value];\n this.value.set(next);\n this.cva.notifyChange(next);\n } else {\n this.value.set(node.value);\n this.cva.notifyChange(node.value);\n this.open.set(false);\n }\n }\n\n protected removeChip(value: string, event: Event): void {\n event.stopPropagation();\n if (this.isDisabled()) {\n return;\n }\n const next = this.selectedValues().filter(v => v !== value);\n this.value.set(next);\n this.cva.notifyChange(next);\n }\n\n protected readonly computedClass = computed(() => xui('block', this.class()));\n protected readonly triggerClass = computed(() =>\n xui(\n 'border-border bg-surface text-foreground flex min-h-(--control-height-md) w-full items-center gap-1 rounded-md border px-(--control-padding-md) py-1 text-sm outline-none focus-visible:border-primary disabled:opacity-50'\n )\n );\n protected readonly panelClass = computed(() =>\n xui('border-border bg-surface-overlay max-h-72 w-full overflow-auto rounded-lg border p-1 shadow-overlay')\n );\n\n /**\n * A selected value reads as a tag, matching the chips xui-multi-select shows for the same job.\n *\n * It borrows the variant map rather than rendering an xui-tag: the trigger is a button, and a\n * tag's remove control is a button too, which may not nest inside one. What the hand-rolled chip\n * had instead was bg-surface-inset, the same colour the dark theme gives the trigger's\n * bg-surface, and no border — so a selection read as bare text.\n */\n protected readonly chipClass = computed(() => xui(tagVariants({ minimal: true, color: 'primary' })));\n\n /**\n * The expand caret. It is drawn pointing right, so a collapsed node has to be\n * flipped in RTL to keep pointing \"further in\"; expanded always points down.\n */\n protected caretClass(expanded: boolean): string {\n return xui('h-3.5 w-3.5 transition-transform', expanded ? 'rotate-90' : this.direction() === 'rtl' && 'rotate-180');\n }\n\n protected rowClass(node: PanelNode): string {\n return xui(\n 'flex cursor-pointer items-center gap-1.5 rounded px-1.5 py-1 text-sm select-none',\n node.disabled ? 'text-foreground-subtle cursor-not-allowed' : 'hover:bg-surface-inset',\n node.id === this.activeValue() && 'bg-surface-inset',\n !this.multiple() && this.isSelected(node.data!.value) && 'bg-primary/10 text-primary'\n );\n }\n\n protected checkboxClass(selected: boolean): string {\n return xui(\n 'flex h-4 w-4 items-center justify-center rounded border',\n selected ? 'bg-primary border-primary text-primary-foreground' : 'border-border'\n );\n }\n\n readonly writeValue = this.cva.writeValue;\n readonly registerOnChange = this.cva.registerOnChange;\n readonly registerOnTouched = this.cva.registerOnTouched;\n readonly setDisabledState = this.cva.setDisabledState;\n}\n","import { XuiTreeSelect } from './lib/tree-select';\n\nexport * from './lib/tree-select';\n\nexport const XuiTreeSelectImports = [XuiTreeSelect] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xui/tree-select",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.17",
|
|
4
4
|
"description": "Modern Angular 22 UI Library based on TailwindCSS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"@angular/cdk": "22",
|
|
40
40
|
"@angular/core": "22",
|
|
41
41
|
"@angular/forms": "22",
|
|
42
|
-
"@xui/core": "2.0.0-alpha.
|
|
42
|
+
"@xui/core": "2.0.0-alpha.17",
|
|
43
|
+
"@xui/tag": "2.0.0-alpha.17",
|
|
43
44
|
"clsx": "^2.1.1"
|
|
44
45
|
},
|
|
45
46
|
"publishConfig": {
|
|
@@ -78,6 +78,15 @@ declare class XuiTreeSelect implements ControlValueAccessor {
|
|
|
78
78
|
protected readonly computedClass: _angular_core.Signal<string>;
|
|
79
79
|
protected readonly triggerClass: _angular_core.Signal<string>;
|
|
80
80
|
protected readonly panelClass: _angular_core.Signal<string>;
|
|
81
|
+
/**
|
|
82
|
+
* A selected value reads as a tag, matching the chips xui-multi-select shows for the same job.
|
|
83
|
+
*
|
|
84
|
+
* It borrows the variant map rather than rendering an xui-tag: the trigger is a button, and a
|
|
85
|
+
* tag's remove control is a button too, which may not nest inside one. What the hand-rolled chip
|
|
86
|
+
* had instead was bg-surface-inset, the same colour the dark theme gives the trigger's
|
|
87
|
+
* bg-surface, and no border — so a selection read as bare text.
|
|
88
|
+
*/
|
|
89
|
+
protected readonly chipClass: _angular_core.Signal<string>;
|
|
81
90
|
/**
|
|
82
91
|
* The expand caret. It is drawn pointing right, so a collapsed node has to be
|
|
83
92
|
* flipped in RTL to keep pointing "further in"; expanded always points down.
|