@tailng-ui/primitives 0.39.0 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/lib/form/listbox/listbox.directive.d.ts +1 -0
- package/src/lib/form/listbox/listbox.directive.d.ts.map +1 -1
- package/src/lib/form/listbox/listbox.directive.js +7 -4
- package/src/lib/form/listbox/listbox.directive.js.map +1 -1
- package/src/lib/form/listbox/tokens.d.ts +5 -0
- package/src/lib/form/listbox/tokens.d.ts.map +1 -1
- package/src/lib/form/listbox/tokens.js +5 -0
- package/src/lib/form/listbox/tokens.js.map +1 -1
- package/src/lib/form/multi-autocomplete/tng-multi-autocomplete.listbox.d.ts.map +1 -1
- package/src/lib/form/multi-autocomplete/tng-multi-autocomplete.listbox.js +5 -1
- package/src/lib/form/multi-autocomplete/tng-multi-autocomplete.listbox.js.map +1 -1
- package/src/lib/navigation/menubar/tng-menubar.d.ts +1 -1
- package/src/lib/navigation/menubar/tng-menubar.d.ts.map +1 -1
- package/src/lib/navigation/menubar/tng-menubar.js +10 -40
- package/src/lib/navigation/menubar/tng-menubar.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailng-ui/primitives",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
19
|
"@angular/core": "^21.1.0",
|
|
20
|
-
"@tailng-ui/cdk": "^0.
|
|
20
|
+
"@tailng-ui/cdk": "^0.28.0",
|
|
21
21
|
"tslib": "^2.3.0"
|
|
22
22
|
},
|
|
23
23
|
"sideEffects": false
|
|
@@ -2,6 +2,7 @@ import * as i0 from "@angular/core";
|
|
|
2
2
|
export type ListboxValue<T> = T | readonly T[] | null;
|
|
3
3
|
export declare class TngListboxDirective<T> {
|
|
4
4
|
private readonly _forceMultiple;
|
|
5
|
+
private readonly focusOnPointerSelect;
|
|
5
6
|
private readonly preserveValueOnUnregister;
|
|
6
7
|
readonly multipleInput: import("@angular/core").InputSignal<boolean>;
|
|
7
8
|
readonly multiple: import("@angular/core").Signal<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listbox.directive.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/listbox.directive.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"listbox.directive.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/listbox.directive.ts"],"names":[],"mappings":";AAuBA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;AAEtD,qBAIa,mBAAmB,CAAC,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0D;IACzF,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CACqC;IAC1E,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CACsC;IAChF,QAAQ,CAAC,aAAa,+CAAgD;IACtE,QAAQ,CAAC,QAAQ,0CAA+D;IAEhF,WAAW,iEAAgD;IAC3D,SAAS,qDAA+B;IACxC,QAAQ,+CAAyB;IACjC,IAAI,+CAAwB;IAE5B;;;;OAIG;IACH,SAAS,+CAAwB;IAEjC,QAAQ,CAAC,KAAK,uDAAgC;IAE9C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAmC;IAEtD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,OAAO,CAA6D;IAC5E,OAAO,CAAC,UAAU,CAAsE;IACxF,OAAO,CAAC,QAAQ,CAA+B;IAO/C,IAAI,SAAa;IAEjB,IACI,SAAS,kBAEZ;IAED,IACI,YAAY,kBAEf;IAED,IACI,gBAAgB,kBAEnB;;IA2HD,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,wBAAwB;IAgBhC,OAAO,CAAC,wBAAwB;IAMhC,OAAO,CAAC,yBAAyB;IAejC,cAAc,CACZ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,OAAO,EACjB,IAAI,CAAC,EAAE,MAAM,EACb,EAAE,CAAC,EAAE,WAAW,GACf,IAAI;IAoBP,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAgBlC,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAyBzD,aAAa,CAAC,KAAK,EAAE,aAAa;IAyClC,aAAa;IAgBb,cAAc,CAAC,KAAK,EAAE,UAAU;IAchC,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO;IA2BhD,OAAO,CAAC,6BAA6B;IAsDrC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQ/B,eAAe,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO;IAYlC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAItB,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,YAAY,CAAC,IAAI,GAAE,OAAO,GAAG,MAAgB,GAAG,IAAI;IAQpD,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO;IAa/D,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQ3C,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAOpC,cAAc,IAAI,CAAC,GAAG,SAAS;yCA5f3B,mBAAmB;2CAAnB,mBAAmB;CAkgB/B"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Directive, ElementRef, HostBinding, HostListener, computed, effect, inject, input, model, signal, untracked, } from '@angular/core';
|
|
2
2
|
import { createListboxController } from '@tailng-ui/cdk';
|
|
3
|
-
import { TNG_LISTBOX, TNG_LISTBOX_FORCE_MULTIPLE, TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, } from './tokens';
|
|
3
|
+
import { TNG_LISTBOX, TNG_LISTBOX_FOCUS_ON_POINTER_SELECT, TNG_LISTBOX_FORCE_MULTIPLE, TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, } from './tokens';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
export class TngListboxDirective {
|
|
6
6
|
_forceMultiple = inject(TNG_LISTBOX_FORCE_MULTIPLE, { optional: true });
|
|
7
|
+
focusOnPointerSelect = inject(TNG_LISTBOX_FOCUS_ON_POINTER_SELECT, { optional: true }) ?? true;
|
|
7
8
|
preserveValueOnUnregister = inject(TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, { optional: true }) ?? false;
|
|
8
9
|
multipleInput = input(false, { ...(ngDevMode ? { debugName: "multipleInput" } : {}), alias: 'multiple' });
|
|
9
10
|
multiple = computed(() => this._forceMultiple ?? this.multipleInput(), ...(ngDevMode ? [{ debugName: "multiple" }] : []));
|
|
@@ -290,9 +291,11 @@ export class TngListboxDirective {
|
|
|
290
291
|
const ctrl = this.controller();
|
|
291
292
|
if (!ctrl)
|
|
292
293
|
return;
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
294
|
+
if (this.focusOnPointerSelect) {
|
|
295
|
+
// Pointer selection can transfer keyboard focus to this listbox so
|
|
296
|
+
// subsequent Arrow keys continue from the clicked list.
|
|
297
|
+
this.el.nativeElement.focus();
|
|
298
|
+
}
|
|
296
299
|
ctrl.handleClick(id, shiftKey);
|
|
297
300
|
this.syncActiveFromController();
|
|
298
301
|
this.syncExternalValueFromInternal(ctrl, true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listbox.directive.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/listbox.directive.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Directive,\n ElementRef,\n HostBinding,\n HostListener,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { createListboxController } from '@tailng-ui/cdk';\nimport type { TngListNavigationAction } from '@tailng-ui/cdk';\nimport {\n TNG_LISTBOX,\n TNG_LISTBOX_FORCE_MULTIPLE,\n TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER,\n} from './tokens';\n\nexport type ListboxValue<T> = T | readonly T[] | null;\n\n@Directive({\n selector: '[tngListbox]',\n providers: [{ provide: TNG_LISTBOX, useExisting: TngListboxDirective }],\n})\nexport class TngListboxDirective<T> {\n private readonly _forceMultiple = inject(TNG_LISTBOX_FORCE_MULTIPLE, { optional: true });\n private readonly preserveValueOnUnregister =\n inject(TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, { optional: true }) ?? false;\n readonly multipleInput = input<boolean>(false, { alias: 'multiple' });\n readonly multiple = computed(() => this._forceMultiple ?? this.multipleInput());\n\n orientation = input<'vertical' | 'horizontal'>('vertical');\n direction = input<'ltr' | 'rtl'>('ltr');\n disabled = input<boolean>(false);\n loop = input<boolean>(true);\n\n /**\n * Enable listbox typeahead (printable key moves active option by option text).\n * Default true for Select compatibility.\n * Autocomplete should set this to false (input owns typing/filtering).\n */\n typeahead = input<boolean>(true);\n\n readonly value = model<ListboxValue<T>>(null);\n\n private readonly el = inject(ElementRef<HTMLElement>);\n\n private idToElement = new Map<string, HTMLElement>();\n private options = signal<{ id: string; value: T; disabled: boolean }[]>([]);\n private controller = signal<ReturnType<typeof createListboxController<T>> | null>(null);\n private activeId = signal<string | null>(null);\n\n // ----------------------------------------------------\n // Host bindings\n // ----------------------------------------------------\n\n @HostBinding('attr.role')\n role = 'listbox';\n\n @HostBinding('attr.aria-multiselectable')\n get ariaMulti() {\n return this.multiple() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-disabled')\n get ariaDisabled() {\n return this.disabled() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-activedescendant')\n get activeDescendant() {\n return this.activeId();\n }\n\n // ----------------------------------------------------\n // Constructor\n // ----------------------------------------------------\n\n constructor() {\n const hostId = `tng-listbox-${Math.random().toString(36).slice(2)}`;\n\n // Controller creation effect\n effect(() => {\n const ctrl = createListboxController<T>({\n hostId,\n selectionMode: this.multiple() ? 'multiple' : 'single',\n orientation: this.orientation(),\n direction: this.direction(),\n disabled: this.disabled(),\n loop: this.loop(),\n });\n\n this.controller.set(ctrl);\n\n const opts = untracked(this.options);\n for (const option of opts) {\n ctrl.registerOption(option);\n }\n });\n\n // Controlled value sanitizer\n effect(() => {\n const isMulti = this.multiple();\n const opts = this.options();\n const external = this.value();\n\n if (opts.length === 0) {\n return;\n }\n\n if (!isMulti) {\n if (external === null) return;\n\n const v = external as T;\n const opt = this.findOptionByValue(v, opts);\n\n if (!opt && this.preserveValueOnUnregister) {\n return;\n }\n\n if (!opt || opt.disabled) {\n this.value.set(null);\n }\n return;\n }\n\n if (external === null) return;\n\n const arr = Array.isArray(external)\n ? (external as readonly T[])\n : ([external as T] as readonly T[]);\n\n const filtered = arr.filter((v) => {\n const opt = this.findOptionByValue(v, opts);\n\n if (!opt) {\n return this.preserveValueOnUnregister;\n }\n\n return !opt.disabled;\n });\n\n if (filtered.length !== arr.length) {\n this.value.set(filtered as readonly T[]);\n }\n });\n\n // External value -> controller selection\n effect(() => {\n const ctrl = this.controller();\n if (!ctrl) return;\n\n const opts = this.options();\n const external = this.value();\n\n const toIds = (v: ListboxValue<T>): string[] => {\n if (v === null) return [];\n const arr = Array.isArray(v) ? (v as readonly T[]) : ([v as T] as const);\n\n const ids: string[] = [];\n for (const val of arr) {\n const opt = opts.find((o) => Object.is(o.value, val));\n if (!opt) continue;\n if (opt.disabled) continue;\n ids.push(opt.id);\n }\n return ids;\n };\n\n const nextIds = toIds(external);\n\n if (nextIds.length === 0) {\n ctrl.clearSelection();\n return;\n }\n\n ctrl.setSelectedIds(nextIds);\n });\n\n // Scroll when active changes\n effect(() => {\n const id = this.activeId();\n if (!id) return;\n\n const el = this.idToElement.get(id);\n if (!el) return;\n\n el.scrollIntoView?.({ block: 'nearest' });\n });\n }\n\n // ----------------------------------------------------\n // Helpers\n // ----------------------------------------------------\n\n private findOptionByValue(\n value: T,\n opts: readonly { value: T; disabled: boolean }[],\n ) {\n return opts.find((o) => Object.is(o.value, value));\n }\n\n private isSelectableValue(\n value: T,\n opts: readonly { value: T; disabled: boolean }[],\n ): boolean {\n const opt = this.findOptionByValue(value, opts);\n return !!opt && !opt.disabled;\n }\n\n private syncDomOrderToController(): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n\n const root = this.el.nativeElement;\n const optionEls = Array.from(\n root.querySelectorAll('[role=\"option\"][id]'),\n ) as HTMLElement[];\n\n const ids = optionEls.map((x) => x.id).filter(Boolean);\n\n if (ids.length > 0) {\n ctrl.setItemOrder(ids);\n }\n }\n\n private syncActiveFromController(): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n this.activeId.set(ctrl.getActiveId());\n }\n\n private shouldSyncValueFromAction(action: TngListNavigationAction | null): boolean {\n if (!action) return false;\n if (action.extendSelection) return true;\n\n return (\n action.type === 'select-active' ||\n action.type === 'toggle-active' ||\n action.type === 'select-all'\n );\n }\n\n // ----------------------------------------------------\n // Option registration\n // ----------------------------------------------------\n\n registerOption(\n id: string,\n value: T,\n disabled: boolean,\n text?: string,\n el?: HTMLElement,\n ): void {\n if (el) {\n this.idToElement.set(id, el);\n }\n\n this.options.update((list) => {\n const idx = list.findIndex((x) => x.id === id);\n if (idx === -1) return [...list, { id, value, disabled }];\n const copy = list.slice();\n copy[idx] = { id, value, disabled };\n return copy;\n });\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.unregisterOption(id);\n ctrl.registerOption({ id, value, disabled, text });\n }\n\n unregisterOption(id: string): void {\n this.options.update((list) => list.filter((x) => x.id !== id));\n this.idToElement.delete(id);\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.unregisterOption(id);\n\n this.syncActiveFromController();\n\n if (!this.preserveValueOnUnregister) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n }\n\n updateOptionDisabled(id: string, disabled: boolean): void {\n let exists = false;\n\n this.options.update((list) =>\n list.map((o) => {\n if (o.id !== id) return o;\n exists = true;\n return { ...o, disabled };\n }),\n );\n\n if (!exists) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.setOptionDisabled(id, disabled);\n this.syncActiveFromController();\n }\n\n // ----------------------------------------------------\n // Events\n // ----------------------------------------------------\n\n @HostListener('keydown', ['$event'])\n handleKeydown(event: KeyboardEvent) {\n if (this.disabled()) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n this.syncDomOrderToController();\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n // ✅ Typeahead (optional)\n if (\n this.typeahead() &&\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n const moved = ctrl.typeahead(event.key);\n if (moved) {\n this.syncActiveFromController();\n event.preventDefault();\n return;\n }\n }\n\n const action = ctrl.handleKeyDown(event);\n this.syncActiveFromController();\n\n if (action?.preventDefault) {\n event.preventDefault();\n }\n\n if (this.shouldSyncValueFromAction(action)) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n }\n\n @HostListener('focusin')\n handleFocusIn() {\n if (this.disabled()) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n if (ctrl.getActiveId() !== null) {\n this.syncActiveFromController();\n return;\n }\n\n ctrl.handleKeyDown({ key: 'Home' });\n this.syncActiveFromController();\n }\n\n @HostListener('focusout', ['$event'])\n handleFocusOut(event: FocusEvent) {\n const nextTarget = event.relatedTarget;\n if (nextTarget instanceof Node && this.el.nativeElement.contains(nextTarget)) {\n return;\n }\n\n const ctrl = this.controller();\n if (!ctrl) return;\n if (ctrl.getActiveId() === null) return;\n\n ctrl.setActiveId(null);\n this.syncActiveFromController();\n }\n\n handleOptionClick(id: string, shiftKey?: boolean) {\n if (this.disabled()) return;\n\n this.syncDomOrderToController();\n\n const opt = this.options().find((o) => o.id === id);\n if (opt?.disabled) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n // Pointer selection should transfer keyboard focus to this listbox so\n // subsequent Arrow keys continue from the clicked list.\n this.el.nativeElement.focus();\n\n ctrl.handleClick(id, shiftKey);\n\n this.syncActiveFromController();\n this.syncExternalValueFromInternal(ctrl, true);\n }\n\n // ----------------------------------------------------\n // Selection sync\n // ----------------------------------------------------\n\n private syncExternalValueFromInternal(\n ctrl: ReturnType<typeof createListboxController<T>>,\n fromClick: boolean,\n ) {\n const selected = ctrl.getSelectedValues();\n\n if (this.multiple()) {\n if (!this.preserveValueOnUnregister) {\n this.value.set([...selected] as readonly T[]);\n return;\n }\n\n const opts = this.options();\n const current = this.value();\n const currentArr =\n current === null\n ? ([] as readonly T[])\n : Array.isArray(current)\n ? (current as readonly T[])\n : ([current as T] as const);\n\n const next: T[] = [];\n\n // Preserve hidden selections in their current order, and keep any currently\n // visible selections that remain selected after the interaction.\n for (const val of currentArr) {\n const isHidden = !opts.some((opt) => Object.is(opt.value, val));\n const isStillSelected = selected.some((entry) => Object.is(entry, val));\n\n if (isHidden || isStillSelected) {\n next.push(val);\n }\n }\n\n // Append newly selected visible values that were not already present.\n for (const val of selected) {\n const alreadyPresent = currentArr.some((entry) => Object.is(entry, val));\n if (!alreadyPresent) {\n next.push(val);\n }\n }\n\n this.value.set(next as readonly T[]);\n } else {\n const newVal = selected[0] ?? null;\n const current = this.value();\n this.value.set(newVal);\n if (fromClick && Object.is(newVal, current)) {\n this.value.set(null);\n this.value.set(newVal);\n }\n }\n }\n\n isSelected(id: string): boolean {\n const ctrl = this.controller();\n if (!ctrl) return false;\n \n // ✅ selection truth is IDs, not value equality\n return ctrl.getSelectedIds().includes(id);\n }\n\n isValueSelected(value: T): boolean {\n const selected = this.value();\n\n if (selected === null) return false;\n\n if (Array.isArray(selected)) {\n return selected.some((entry) => Object.is(entry, value));\n }\n\n return Object.is(selected, value);\n }\n\n isActive(id: string): boolean {\n return this.activeId() === id;\n }\n\n public getActiveId(): string | null {\n return this.activeId();\n }\n\n public ensureActive(pref: 'first' | 'last' = 'first'): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n if (ctrl.getActiveId() !== null) return;\n ctrl.handleKeyDown({ key: pref === 'last' ? 'End' : 'Home' });\n this.syncActiveFromController();\n }\n\n public handleKeyFromCombobox(key: string, shiftKey?: boolean): boolean {\n this.syncDomOrderToController();\n\n const ctrl = this.controller();\n if (!ctrl) return false;\n const action = ctrl.handleKeyDown({ key, shiftKey } as any);\n this.syncActiveFromController();\n if (this.shouldSyncValueFromAction(action)) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n return !!action;\n }\n\n public typeaheadFromCombobox(key: string): boolean {\n const ctrl = this.controller();\n if (!ctrl) return false;\n const moved = ctrl.typeahead(key);\n if (moved) this.syncActiveFromController();\n return moved;\n }\n\n public setActiveId(id: string | null): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n ctrl.setActiveId(id);\n this.syncActiveFromController();\n }\n\n public getActiveValue(): T | undefined {\n const active = this.activeId();\n if (!active) return undefined;\n const opt = this.options().find((o) => o.id === active);\n return opt?.value;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"listbox.directive.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/listbox.directive.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,UAAU,EACV,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,MAAM,EACN,KAAK,EACL,KAAK,EACL,MAAM,EACN,SAAS,GACV,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EACL,WAAW,EACX,mCAAmC,EACnC,0BAA0B,EAC1B,wCAAwC,GACzC,MAAM,UAAU,CAAC;;AAQlB,MAAM,OAAO,mBAAmB;IACb,cAAc,GAAG,MAAM,CAAC,0BAA0B,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,oBAAoB,GACnC,MAAM,CAAC,mCAAmC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC;IACzD,yBAAyB,GACxC,MAAM,CAAC,wCAAwC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC;IACvE,aAAa,GAAG,KAAK,CAAU,KAAK,0DAAI,KAAK,EAAE,UAAU,GAAG,CAAC;IAC7D,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,aAAa,EAAE,oDAAC,CAAC;IAEhF,WAAW,GAAG,KAAK,CAA4B,UAAU,uDAAC,CAAC;IAC3D,SAAS,GAAG,KAAK,CAAgB,KAAK,qDAAC,CAAC;IACxC,QAAQ,GAAG,KAAK,CAAU,KAAK,oDAAC,CAAC;IACjC,IAAI,GAAG,KAAK,CAAU,IAAI,gDAAC,CAAC;IAE5B;;;;OAIG;IACH,SAAS,GAAG,KAAK,CAAU,IAAI,qDAAC,CAAC;IAExB,KAAK,GAAG,KAAK,CAAkB,IAAI,iDAAC,CAAC;IAE7B,EAAE,GAAG,MAAM,CAAC,CAAA,UAAuB,CAAA,CAAC,CAAC;IAE9C,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7C,OAAO,GAAG,MAAM,CAAgD,EAAE,mDAAC,CAAC;IACpE,UAAU,GAAG,MAAM,CAAuD,IAAI,sDAAC,CAAC;IAChF,QAAQ,GAAG,MAAM,CAAgB,IAAI,oDAAC,CAAC;IAE/C,uDAAuD;IACvD,gBAAgB;IAChB,uDAAuD;IAGvD,IAAI,GAAG,SAAS,CAAC;IAEjB,IACI,SAAS;QACX,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAED,IACI,YAAY;QACd,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAED,IACI,gBAAgB;QAClB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,uDAAuD;IACvD,cAAc;IACd,uDAAuD;IAEvD;QACE,MAAM,MAAM,GAAG,eAAe,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAEpE,6BAA6B;QAC7B,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,IAAI,GAAG,uBAAuB,CAAI;gBACtC,MAAM;gBACN,aAAa,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;gBACtD,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;gBAC/B,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;gBAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;gBACzB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;aAClB,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE1B,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;gBAC1B,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAE9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,QAAQ,KAAK,IAAI;oBAAE,OAAO;gBAE9B,MAAM,CAAC,GAAG,QAAa,CAAC;gBACxB,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;gBAE5C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;oBAC3C,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;oBACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACvB,CAAC;gBACD,OAAO;YACT,CAAC;YAED,IAAI,QAAQ,KAAK,IAAI;gBAAE,OAAO;YAE9B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACjC,CAAC,CAAE,QAAyB;gBAC5B,CAAC,CAAE,CAAC,QAAa,CAAkB,CAAC;YAEtC,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;gBAChC,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;gBAE5C,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,OAAO,IAAI,CAAC,yBAAyB,CAAC;gBACxC,CAAC;gBAED,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YACvB,CAAC,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;gBACnC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAwB,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,yCAAyC;QACzC,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI;gBAAE,OAAO;YAElB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAE9B,MAAM,KAAK,GAAG,CAAC,CAAkB,EAAY,EAAE;gBAC7C,IAAI,CAAC,KAAK,IAAI;oBAAE,OAAO,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAkB,CAAC,CAAC,CAAE,CAAC,CAAM,CAAW,CAAC;gBAEzE,MAAM,GAAG,GAAa,EAAE,CAAC;gBACzB,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;oBACtB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;oBACtD,IAAI,CAAC,GAAG;wBAAE,SAAS;oBACnB,IAAI,GAAG,CAAC,QAAQ;wBAAE,SAAS;oBAC3B,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACnB,CAAC;gBACD,OAAO,GAAG,CAAC;YACb,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;YAEhC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC,EAAE;gBAAE,OAAO;YAEhB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpC,IAAI,CAAC,EAAE;gBAAE,OAAO;YAEhB,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,uDAAuD;IACvD,UAAU;IACV,uDAAuD;IAE/C,iBAAiB,CACvB,KAAQ,EACR,IAAgD;QAEhD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IACrD,CAAC;IAEO,iBAAiB,CACvB,KAAQ,EACR,IAAgD;QAEhD,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAChD,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEO,wBAAwB;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC;QACnC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAC1B,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAC5B,CAAC;QAEnB,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEvD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,wBAAwB;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACxC,CAAC;IAEO,yBAAyB,CAAC,MAAsC;QACtE,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,IAAI,MAAM,CAAC,eAAe;YAAE,OAAO,IAAI,CAAC;QAExC,OAAO,CACL,MAAM,CAAC,IAAI,KAAK,eAAe;YAC/B,MAAM,CAAC,IAAI,KAAK,eAAe;YAC/B,MAAM,CAAC,IAAI,KAAK,YAAY,CAC7B,CAAC;IACJ,CAAC;IAED,uDAAuD;IACvD,sBAAsB;IACtB,uDAAuD;IAEvD,cAAc,CACZ,EAAU,EACV,KAAQ,EACR,QAAiB,EACjB,IAAa,EACb,EAAgB;QAEhB,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/C,IAAI,GAAG,KAAK,CAAC,CAAC;gBAAE,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,gBAAgB,CAAC,EAAU;QACzB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAE1B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACpC,IAAI,CAAC,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,oBAAoB,CAAC,EAAU,EAAE,QAAiB;QAChD,IAAI,MAAM,GAAG,KAAK,CAAC;QAEnB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACb,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC1B,MAAM,GAAG,IAAI,CAAC;YACd,OAAO,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CACH,CAAC;QAEF,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAED,uDAAuD;IACvD,SAAS;IACT,uDAAuD;IAGvD,aAAa,CAAC,KAAoB;QAChC,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpB,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,yBAAyB;QACzB,IACE,IAAI,CAAC,SAAS,EAAE;YAChB,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;YACtB,CAAC,KAAK,CAAC,OAAO;YACd,CAAC,KAAK,CAAC,OAAO;YACd,CAAC,KAAK,CAAC,MAAM,EACb,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAChC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,MAAM,EAAE,cAAc,EAAE,CAAC;YAC3B,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,CAAC;QAED,IAAI,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAGD,aAAa;QACX,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO;QAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAChC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAGD,cAAc,CAAC,KAAiB;QAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC;QACvC,IAAI,UAAU,YAAY,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7E,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI;YAAE,OAAO;QAExC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAED,iBAAiB,CAAC,EAAU,EAAE,QAAkB;QAC9C,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO;QAE5B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,IAAI,GAAG,EAAE,QAAQ;YAAE,OAAO;QAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9B,mEAAmE;YACnE,wDAAwD;YACxD,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAChC,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAE/B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,CAAC,6BAA6B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,uDAAuD;IACvD,iBAAiB;IACjB,uDAAuD;IAE/C,6BAA6B,CACnC,IAAmD,EACnD,SAAkB;QAElB,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAE1C,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC;gBACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAiB,CAAC,CAAC;gBAC9C,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC7B,MAAM,UAAU,GACd,OAAO,KAAK,IAAI;gBACd,CAAC,CAAE,EAAmB;gBACtB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;oBACtB,CAAC,CAAE,OAAwB;oBAC3B,CAAC,CAAE,CAAC,OAAY,CAAW,CAAC;YAElC,MAAM,IAAI,GAAQ,EAAE,CAAC;YAErB,4EAA4E;YAC5E,iEAAiE;YACjE,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC7B,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;gBAChE,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;gBAExE,IAAI,QAAQ,IAAI,eAAe,EAAE,CAAC;oBAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC;YAED,sEAAsE;YACtE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;gBACzE,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAoB,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YACnC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACvB,IAAI,SAAS,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,UAAU,CAAC,EAAU;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAExB,+CAA+C;QAC/C,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,eAAe,CAAC,KAAQ;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAE9B,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAEpC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,QAAQ,CAAC,EAAU;QACjB,OAAO,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;IAChC,CAAC;IAEM,WAAW;QAChB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAEM,YAAY,CAAC,OAAyB,OAAO;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI;YAAE,OAAO;QACxC,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAEM,qBAAqB,CAAC,GAAW,EAAE,QAAkB;QAC1D,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAS,CAAC,CAAC;QAC5D,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAEM,qBAAqB,CAAC,GAAW;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,KAAK;YAAE,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC;IAEM,WAAW,CAAC,EAAiB;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACrB,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAEM,cAAc;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QACxD,OAAO,GAAG,EAAE,KAAK,CAAC;IACpB,CAAC;uGAjgBU,mBAAmB;2FAAnB,mBAAmB,izCAFnB,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC;;2FAE5D,mBAAmB;kBAJ/B,SAAS;mBAAC;oBACT,QAAQ,EAAE,cAAc;oBACxB,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,qBAAqB,EAAE,CAAC;iBACxE;;sBAmCE,WAAW;uBAAC,WAAW;;sBAGvB,WAAW;uBAAC,2BAA2B;;sBAKvC,WAAW;uBAAC,oBAAoB;;sBAKhC,WAAW;uBAAC,4BAA4B;;sBAoPxC,YAAY;uBAAC,SAAS,EAAE,CAAC,QAAQ,CAAC;;sBAyClC,YAAY;uBAAC,SAAS;;sBAgBtB,YAAY;uBAAC,UAAU,EAAE,CAAC,QAAQ,CAAC","sourcesContent":["import {\n Directive,\n ElementRef,\n HostBinding,\n HostListener,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { createListboxController } from '@tailng-ui/cdk';\nimport type { TngListNavigationAction } from '@tailng-ui/cdk';\nimport {\n TNG_LISTBOX,\n TNG_LISTBOX_FOCUS_ON_POINTER_SELECT,\n TNG_LISTBOX_FORCE_MULTIPLE,\n TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER,\n} from './tokens';\n\nexport type ListboxValue<T> = T | readonly T[] | null;\n\n@Directive({\n selector: '[tngListbox]',\n providers: [{ provide: TNG_LISTBOX, useExisting: TngListboxDirective }],\n})\nexport class TngListboxDirective<T> {\n private readonly _forceMultiple = inject(TNG_LISTBOX_FORCE_MULTIPLE, { optional: true });\n private readonly focusOnPointerSelect =\n inject(TNG_LISTBOX_FOCUS_ON_POINTER_SELECT, { optional: true }) ?? true;\n private readonly preserveValueOnUnregister =\n inject(TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, { optional: true }) ?? false;\n readonly multipleInput = input<boolean>(false, { alias: 'multiple' });\n readonly multiple = computed(() => this._forceMultiple ?? this.multipleInput());\n\n orientation = input<'vertical' | 'horizontal'>('vertical');\n direction = input<'ltr' | 'rtl'>('ltr');\n disabled = input<boolean>(false);\n loop = input<boolean>(true);\n\n /**\n * Enable listbox typeahead (printable key moves active option by option text).\n * Default true for Select compatibility.\n * Autocomplete should set this to false (input owns typing/filtering).\n */\n typeahead = input<boolean>(true);\n\n readonly value = model<ListboxValue<T>>(null);\n\n private readonly el = inject(ElementRef<HTMLElement>);\n\n private idToElement = new Map<string, HTMLElement>();\n private options = signal<{ id: string; value: T; disabled: boolean }[]>([]);\n private controller = signal<ReturnType<typeof createListboxController<T>> | null>(null);\n private activeId = signal<string | null>(null);\n\n // ----------------------------------------------------\n // Host bindings\n // ----------------------------------------------------\n\n @HostBinding('attr.role')\n role = 'listbox';\n\n @HostBinding('attr.aria-multiselectable')\n get ariaMulti() {\n return this.multiple() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-disabled')\n get ariaDisabled() {\n return this.disabled() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-activedescendant')\n get activeDescendant() {\n return this.activeId();\n }\n\n // ----------------------------------------------------\n // Constructor\n // ----------------------------------------------------\n\n constructor() {\n const hostId = `tng-listbox-${Math.random().toString(36).slice(2)}`;\n\n // Controller creation effect\n effect(() => {\n const ctrl = createListboxController<T>({\n hostId,\n selectionMode: this.multiple() ? 'multiple' : 'single',\n orientation: this.orientation(),\n direction: this.direction(),\n disabled: this.disabled(),\n loop: this.loop(),\n });\n\n this.controller.set(ctrl);\n\n const opts = untracked(this.options);\n for (const option of opts) {\n ctrl.registerOption(option);\n }\n });\n\n // Controlled value sanitizer\n effect(() => {\n const isMulti = this.multiple();\n const opts = this.options();\n const external = this.value();\n\n if (opts.length === 0) {\n return;\n }\n\n if (!isMulti) {\n if (external === null) return;\n\n const v = external as T;\n const opt = this.findOptionByValue(v, opts);\n\n if (!opt && this.preserveValueOnUnregister) {\n return;\n }\n\n if (!opt || opt.disabled) {\n this.value.set(null);\n }\n return;\n }\n\n if (external === null) return;\n\n const arr = Array.isArray(external)\n ? (external as readonly T[])\n : ([external as T] as readonly T[]);\n\n const filtered = arr.filter((v) => {\n const opt = this.findOptionByValue(v, opts);\n\n if (!opt) {\n return this.preserveValueOnUnregister;\n }\n\n return !opt.disabled;\n });\n\n if (filtered.length !== arr.length) {\n this.value.set(filtered as readonly T[]);\n }\n });\n\n // External value -> controller selection\n effect(() => {\n const ctrl = this.controller();\n if (!ctrl) return;\n\n const opts = this.options();\n const external = this.value();\n\n const toIds = (v: ListboxValue<T>): string[] => {\n if (v === null) return [];\n const arr = Array.isArray(v) ? (v as readonly T[]) : ([v as T] as const);\n\n const ids: string[] = [];\n for (const val of arr) {\n const opt = opts.find((o) => Object.is(o.value, val));\n if (!opt) continue;\n if (opt.disabled) continue;\n ids.push(opt.id);\n }\n return ids;\n };\n\n const nextIds = toIds(external);\n\n if (nextIds.length === 0) {\n ctrl.clearSelection();\n return;\n }\n\n ctrl.setSelectedIds(nextIds);\n });\n\n // Scroll when active changes\n effect(() => {\n const id = this.activeId();\n if (!id) return;\n\n const el = this.idToElement.get(id);\n if (!el) return;\n\n el.scrollIntoView?.({ block: 'nearest' });\n });\n }\n\n // ----------------------------------------------------\n // Helpers\n // ----------------------------------------------------\n\n private findOptionByValue(\n value: T,\n opts: readonly { value: T; disabled: boolean }[],\n ) {\n return opts.find((o) => Object.is(o.value, value));\n }\n\n private isSelectableValue(\n value: T,\n opts: readonly { value: T; disabled: boolean }[],\n ): boolean {\n const opt = this.findOptionByValue(value, opts);\n return !!opt && !opt.disabled;\n }\n\n private syncDomOrderToController(): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n\n const root = this.el.nativeElement;\n const optionEls = Array.from(\n root.querySelectorAll('[role=\"option\"][id]'),\n ) as HTMLElement[];\n\n const ids = optionEls.map((x) => x.id).filter(Boolean);\n\n if (ids.length > 0) {\n ctrl.setItemOrder(ids);\n }\n }\n\n private syncActiveFromController(): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n this.activeId.set(ctrl.getActiveId());\n }\n\n private shouldSyncValueFromAction(action: TngListNavigationAction | null): boolean {\n if (!action) return false;\n if (action.extendSelection) return true;\n\n return (\n action.type === 'select-active' ||\n action.type === 'toggle-active' ||\n action.type === 'select-all'\n );\n }\n\n // ----------------------------------------------------\n // Option registration\n // ----------------------------------------------------\n\n registerOption(\n id: string,\n value: T,\n disabled: boolean,\n text?: string,\n el?: HTMLElement,\n ): void {\n if (el) {\n this.idToElement.set(id, el);\n }\n\n this.options.update((list) => {\n const idx = list.findIndex((x) => x.id === id);\n if (idx === -1) return [...list, { id, value, disabled }];\n const copy = list.slice();\n copy[idx] = { id, value, disabled };\n return copy;\n });\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.unregisterOption(id);\n ctrl.registerOption({ id, value, disabled, text });\n }\n\n unregisterOption(id: string): void {\n this.options.update((list) => list.filter((x) => x.id !== id));\n this.idToElement.delete(id);\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.unregisterOption(id);\n\n this.syncActiveFromController();\n\n if (!this.preserveValueOnUnregister) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n }\n\n updateOptionDisabled(id: string, disabled: boolean): void {\n let exists = false;\n\n this.options.update((list) =>\n list.map((o) => {\n if (o.id !== id) return o;\n exists = true;\n return { ...o, disabled };\n }),\n );\n\n if (!exists) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.setOptionDisabled(id, disabled);\n this.syncActiveFromController();\n }\n\n // ----------------------------------------------------\n // Events\n // ----------------------------------------------------\n\n @HostListener('keydown', ['$event'])\n handleKeydown(event: KeyboardEvent) {\n if (this.disabled()) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n this.syncDomOrderToController();\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n // ✅ Typeahead (optional)\n if (\n this.typeahead() &&\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n const moved = ctrl.typeahead(event.key);\n if (moved) {\n this.syncActiveFromController();\n event.preventDefault();\n return;\n }\n }\n\n const action = ctrl.handleKeyDown(event);\n this.syncActiveFromController();\n\n if (action?.preventDefault) {\n event.preventDefault();\n }\n\n if (this.shouldSyncValueFromAction(action)) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n }\n\n @HostListener('focusin')\n handleFocusIn() {\n if (this.disabled()) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n if (ctrl.getActiveId() !== null) {\n this.syncActiveFromController();\n return;\n }\n\n ctrl.handleKeyDown({ key: 'Home' });\n this.syncActiveFromController();\n }\n\n @HostListener('focusout', ['$event'])\n handleFocusOut(event: FocusEvent) {\n const nextTarget = event.relatedTarget;\n if (nextTarget instanceof Node && this.el.nativeElement.contains(nextTarget)) {\n return;\n }\n\n const ctrl = this.controller();\n if (!ctrl) return;\n if (ctrl.getActiveId() === null) return;\n\n ctrl.setActiveId(null);\n this.syncActiveFromController();\n }\n\n handleOptionClick(id: string, shiftKey?: boolean) {\n if (this.disabled()) return;\n\n this.syncDomOrderToController();\n\n const opt = this.options().find((o) => o.id === id);\n if (opt?.disabled) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n if (this.focusOnPointerSelect) {\n // Pointer selection can transfer keyboard focus to this listbox so\n // subsequent Arrow keys continue from the clicked list.\n this.el.nativeElement.focus();\n }\n\n ctrl.handleClick(id, shiftKey);\n\n this.syncActiveFromController();\n this.syncExternalValueFromInternal(ctrl, true);\n }\n\n // ----------------------------------------------------\n // Selection sync\n // ----------------------------------------------------\n\n private syncExternalValueFromInternal(\n ctrl: ReturnType<typeof createListboxController<T>>,\n fromClick: boolean,\n ) {\n const selected = ctrl.getSelectedValues();\n\n if (this.multiple()) {\n if (!this.preserveValueOnUnregister) {\n this.value.set([...selected] as readonly T[]);\n return;\n }\n\n const opts = this.options();\n const current = this.value();\n const currentArr =\n current === null\n ? ([] as readonly T[])\n : Array.isArray(current)\n ? (current as readonly T[])\n : ([current as T] as const);\n\n const next: T[] = [];\n\n // Preserve hidden selections in their current order, and keep any currently\n // visible selections that remain selected after the interaction.\n for (const val of currentArr) {\n const isHidden = !opts.some((opt) => Object.is(opt.value, val));\n const isStillSelected = selected.some((entry) => Object.is(entry, val));\n\n if (isHidden || isStillSelected) {\n next.push(val);\n }\n }\n\n // Append newly selected visible values that were not already present.\n for (const val of selected) {\n const alreadyPresent = currentArr.some((entry) => Object.is(entry, val));\n if (!alreadyPresent) {\n next.push(val);\n }\n }\n\n this.value.set(next as readonly T[]);\n } else {\n const newVal = selected[0] ?? null;\n const current = this.value();\n this.value.set(newVal);\n if (fromClick && Object.is(newVal, current)) {\n this.value.set(null);\n this.value.set(newVal);\n }\n }\n }\n\n isSelected(id: string): boolean {\n const ctrl = this.controller();\n if (!ctrl) return false;\n \n // ✅ selection truth is IDs, not value equality\n return ctrl.getSelectedIds().includes(id);\n }\n\n isValueSelected(value: T): boolean {\n const selected = this.value();\n\n if (selected === null) return false;\n\n if (Array.isArray(selected)) {\n return selected.some((entry) => Object.is(entry, value));\n }\n\n return Object.is(selected, value);\n }\n\n isActive(id: string): boolean {\n return this.activeId() === id;\n }\n\n public getActiveId(): string | null {\n return this.activeId();\n }\n\n public ensureActive(pref: 'first' | 'last' = 'first'): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n if (ctrl.getActiveId() !== null) return;\n ctrl.handleKeyDown({ key: pref === 'last' ? 'End' : 'Home' });\n this.syncActiveFromController();\n }\n\n public handleKeyFromCombobox(key: string, shiftKey?: boolean): boolean {\n this.syncDomOrderToController();\n\n const ctrl = this.controller();\n if (!ctrl) return false;\n const action = ctrl.handleKeyDown({ key, shiftKey } as any);\n this.syncActiveFromController();\n if (this.shouldSyncValueFromAction(action)) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n return !!action;\n }\n\n public typeaheadFromCombobox(key: string): boolean {\n const ctrl = this.controller();\n if (!ctrl) return false;\n const moved = ctrl.typeahead(key);\n if (moved) this.syncActiveFromController();\n return moved;\n }\n\n public setActiveId(id: string | null): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n ctrl.setActiveId(id);\n this.syncActiveFromController();\n }\n\n public getActiveValue(): T | undefined {\n const active = this.activeId();\n if (!active) return undefined;\n const opt = this.options().find((o) => o.id === active);\n return opt?.value;\n }\n}\n"]}
|
|
@@ -5,6 +5,11 @@ export declare const TNG_LISTBOX: InjectionToken<TngListboxDirective<any>>;
|
|
|
5
5
|
export declare const TNG_LISTBOX_FORCE_TYPEAHEAD: InjectionToken<boolean>;
|
|
6
6
|
/** Optional override for listbox multiple behavior. If provided, wins over the input(). */
|
|
7
7
|
export declare const TNG_LISTBOX_FORCE_MULTIPLE: InjectionToken<boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* When true, pointer selection moves DOM focus to the listbox host so follow-up
|
|
10
|
+
* keyboard navigation continues from the clicked list. Defaults to true.
|
|
11
|
+
*/
|
|
12
|
+
export declare const TNG_LISTBOX_FOCUS_ON_POINTER_SELECT: InjectionToken<boolean>;
|
|
8
13
|
/**
|
|
9
14
|
* When true, unregistering options should not mutate the external listbox value.
|
|
10
15
|
* This is useful for filterable composites where options can temporarily unmount
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,eAAO,MAAM,WAAW,0CACqC,CAAC;AAE9D,4FAA4F;AAC5F,eAAO,MAAM,2BAA2B,yBACoB,CAAC;AAE7D,2FAA2F;AAC3F,eAAO,MAAM,0BAA0B,yBACoB,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,wCAAwC,yBACoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,eAAO,MAAM,WAAW,0CACqC,CAAC;AAE9D,4FAA4F;AAC5F,eAAO,MAAM,2BAA2B,yBACoB,CAAC;AAE7D,2FAA2F;AAC3F,eAAO,MAAM,0BAA0B,yBACoB,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,mCAAmC,yBACoB,CAAC;AAErE;;;;GAIG;AACH,eAAO,MAAM,wCAAwC,yBACoB,CAAC"}
|
|
@@ -4,6 +4,11 @@ export const TNG_LISTBOX = new InjectionToken('TNG_LISTBOX');
|
|
|
4
4
|
export const TNG_LISTBOX_FORCE_TYPEAHEAD = new InjectionToken('TNG_LISTBOX_FORCE_TYPEAHEAD');
|
|
5
5
|
/** Optional override for listbox multiple behavior. If provided, wins over the input(). */
|
|
6
6
|
export const TNG_LISTBOX_FORCE_MULTIPLE = new InjectionToken('TNG_LISTBOX_FORCE_MULTIPLE');
|
|
7
|
+
/**
|
|
8
|
+
* When true, pointer selection moves DOM focus to the listbox host so follow-up
|
|
9
|
+
* keyboard navigation continues from the clicked list. Defaults to true.
|
|
10
|
+
*/
|
|
11
|
+
export const TNG_LISTBOX_FOCUS_ON_POINTER_SELECT = new InjectionToken('TNG_LISTBOX_FOCUS_ON_POINTER_SELECT');
|
|
7
12
|
/**
|
|
8
13
|
* When true, unregistering options should not mutate the external listbox value.
|
|
9
14
|
* This is useful for filterable composites where options can temporarily unmount
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,MAAM,CAAC,MAAM,WAAW,GACtB,IAAI,cAAc,CAA2B,aAAa,CAAC,CAAC;AAE9D,4FAA4F;AAC5F,MAAM,CAAC,MAAM,2BAA2B,GACtC,IAAI,cAAc,CAAU,6BAA6B,CAAC,CAAC;AAE7D,2FAA2F;AAC3F,MAAM,CAAC,MAAM,0BAA0B,GACrC,IAAI,cAAc,CAAU,4BAA4B,CAAC,CAAC;AAE5D;;;;GAIG;AACH,MAAM,CAAC,MAAM,wCAAwC,GACnD,IAAI,cAAc,CAAU,0CAA0C,CAAC,CAAC","sourcesContent":["import { InjectionToken } from '@angular/core';\nimport type { TngListboxDirective } from './listbox.directive';\n\nexport const TNG_LISTBOX =\n new InjectionToken<TngListboxDirective<any>>('TNG_LISTBOX');\n\n/** Optional override for listbox typeahead behavior. If provided, wins over the input(). */\nexport const TNG_LISTBOX_FORCE_TYPEAHEAD =\n new InjectionToken<boolean>('TNG_LISTBOX_FORCE_TYPEAHEAD');\n\n/** Optional override for listbox multiple behavior. If provided, wins over the input(). */\nexport const TNG_LISTBOX_FORCE_MULTIPLE =\n new InjectionToken<boolean>('TNG_LISTBOX_FORCE_MULTIPLE');\n\n/**\n * When true, unregistering options should not mutate the external listbox value.\n * This is useful for filterable composites where options can temporarily unmount\n * while the controlled value should remain authoritative.\n */\nexport const TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER =\n new InjectionToken<boolean>('TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER');\n"]}
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,MAAM,CAAC,MAAM,WAAW,GACtB,IAAI,cAAc,CAA2B,aAAa,CAAC,CAAC;AAE9D,4FAA4F;AAC5F,MAAM,CAAC,MAAM,2BAA2B,GACtC,IAAI,cAAc,CAAU,6BAA6B,CAAC,CAAC;AAE7D,2FAA2F;AAC3F,MAAM,CAAC,MAAM,0BAA0B,GACrC,IAAI,cAAc,CAAU,4BAA4B,CAAC,CAAC;AAE5D;;;GAGG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAC9C,IAAI,cAAc,CAAU,qCAAqC,CAAC,CAAC;AAErE;;;;GAIG;AACH,MAAM,CAAC,MAAM,wCAAwC,GACnD,IAAI,cAAc,CAAU,0CAA0C,CAAC,CAAC","sourcesContent":["import { InjectionToken } from '@angular/core';\nimport type { TngListboxDirective } from './listbox.directive';\n\nexport const TNG_LISTBOX =\n new InjectionToken<TngListboxDirective<any>>('TNG_LISTBOX');\n\n/** Optional override for listbox typeahead behavior. If provided, wins over the input(). */\nexport const TNG_LISTBOX_FORCE_TYPEAHEAD =\n new InjectionToken<boolean>('TNG_LISTBOX_FORCE_TYPEAHEAD');\n\n/** Optional override for listbox multiple behavior. If provided, wins over the input(). */\nexport const TNG_LISTBOX_FORCE_MULTIPLE =\n new InjectionToken<boolean>('TNG_LISTBOX_FORCE_MULTIPLE');\n\n/**\n * When true, pointer selection moves DOM focus to the listbox host so follow-up\n * keyboard navigation continues from the clicked list. Defaults to true.\n */\nexport const TNG_LISTBOX_FOCUS_ON_POINTER_SELECT =\n new InjectionToken<boolean>('TNG_LISTBOX_FOCUS_ON_POINTER_SELECT');\n\n/**\n * When true, unregistering options should not mutate the external listbox value.\n * This is useful for filterable composites where options can temporarily unmount\n * while the controlled value should remain authoritative.\n */\nexport const TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER =\n new InjectionToken<boolean>('TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER');\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tng-multi-autocomplete.listbox.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/multi-autocomplete/tng-multi-autocomplete.listbox.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tng-multi-autocomplete.listbox.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/multi-autocomplete/tng-multi-autocomplete.listbox.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;;;;AAI7F,qBAmBa,2BAA2B,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,8BAA8B,CAAC,CAAC,CAAC;IAChG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2D;IACjF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkD;IAG1E,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAG,4BAA4B,CAAU;IAGpE,SAAS,CAAC,QAAQ,CAAC,EAAE,SAAqB;;IAuC1C,SAAS,IAAI,MAAM,GAAG,IAAI;IAI1B,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,YAAY,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAI3C,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO;IAInD,YAAY,IAAI,IAAI;IAUpB,SAAS,CAAC,oBAAoB,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,GAAG,IAAI;IAsBpE,QAAQ,CAAC,IAAI,SAAS,CAAC,EAAE;yCAhGd,2BAA2B;2CAA3B,2BAA2B;CAqGvC;AAED,qBASa,0BAA0B,CAAC,CAAC,GAAG,OAAO;IAEjD,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAG,2BAA2B,CAAU;yCAFxD,0BAA0B;2CAA1B,0BAA0B;CAGtC"}
|
|
@@ -3,7 +3,7 @@ import { DestroyRef, Directive, HostBinding, HostListener, effect, inject, untra
|
|
|
3
3
|
import { createTngIdFactory } from '@tailng-ui/cdk';
|
|
4
4
|
import { TngListboxDirective, } from '../listbox/listbox.directive';
|
|
5
5
|
import { TngOptionDirective } from '../listbox/option.directive';
|
|
6
|
-
import { TNG_LISTBOX_FORCE_MULTIPLE, TNG_LISTBOX_FORCE_TYPEAHEAD, TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, } from '../listbox/tokens';
|
|
6
|
+
import { TNG_LISTBOX_FOCUS_ON_POINTER_SELECT, TNG_LISTBOX_FORCE_MULTIPLE, TNG_LISTBOX_FORCE_TYPEAHEAD, TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, } from '../listbox/tokens';
|
|
7
7
|
import { TNG_MULTI_AUTOCOMPLETE } from './tng-multi-autocomplete.tokens';
|
|
8
8
|
import { TNG_MULTI_AUTOCOMPLETE_LISTBOX } from './tng-multi-autocomplete.listbox.tokens';
|
|
9
9
|
import * as i0 from "@angular/core";
|
|
@@ -95,6 +95,8 @@ export class TngMultiAutocompleteListbox {
|
|
|
95
95
|
// Multi-autocomplete typing happens in the input. Listbox must NOT typeahead.
|
|
96
96
|
{ provide: TNG_LISTBOX_FORCE_TYPEAHEAD, useValue: false },
|
|
97
97
|
{ provide: TNG_LISTBOX_FORCE_MULTIPLE, useValue: true },
|
|
98
|
+
// Keep focus on the trigger input so combobox Escape/typing semantics stay intact.
|
|
99
|
+
{ provide: TNG_LISTBOX_FOCUS_ON_POINTER_SELECT, useValue: false },
|
|
98
100
|
{ provide: TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, useValue: true },
|
|
99
101
|
], hostDirectives: [{ directive: i1.TngListboxDirective, inputs: ["orientation", "orientation", "direction", "direction", "disabled", "disabled", "loop", "loop", "value", "value"], outputs: ["valueChange", "valueChange"] }], ngImport: i0 });
|
|
100
102
|
}
|
|
@@ -107,6 +109,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
107
109
|
// Multi-autocomplete typing happens in the input. Listbox must NOT typeahead.
|
|
108
110
|
{ provide: TNG_LISTBOX_FORCE_TYPEAHEAD, useValue: false },
|
|
109
111
|
{ provide: TNG_LISTBOX_FORCE_MULTIPLE, useValue: true },
|
|
112
|
+
// Keep focus on the trigger input so combobox Escape/typing semantics stay intact.
|
|
113
|
+
{ provide: TNG_LISTBOX_FOCUS_ON_POINTER_SELECT, useValue: false },
|
|
110
114
|
{ provide: TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, useValue: true },
|
|
111
115
|
],
|
|
112
116
|
hostDirectives: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tng-multi-autocomplete.listbox.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/multi-autocomplete/tng-multi-autocomplete.listbox.ts"],"names":[],"mappings":"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","sourcesContent":["// libs/tailng-ui/primitives/src/lib/form/multi-autocomplete/tng-multi-autocomplete.listbox.ts\nimport {\n DestroyRef,\n Directive,\n HostBinding,\n HostListener,\n effect,\n inject,\n untracked,\n} from '@angular/core';\n\nimport { createTngIdFactory } from '@tailng-ui/cdk';\nimport {\n TngListboxDirective,\n} from '../listbox/listbox.directive';\nimport { TngOptionDirective } from '../listbox/option.directive';\nimport {\n TNG_LISTBOX_FORCE_MULTIPLE,\n TNG_LISTBOX_FORCE_TYPEAHEAD,\n TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER,\n} from '../listbox/tokens';\n\nimport { TNG_MULTI_AUTOCOMPLETE } from './tng-multi-autocomplete.tokens';\nimport type { TngMultiAutocomplete } from './tng-multi-autocomplete';\nimport { TNG_MULTI_AUTOCOMPLETE_LISTBOX } from './tng-multi-autocomplete.listbox.tokens';\nimport type { TngMultiAutocompleteListboxApi } from './tng-multi-autocomplete.listbox.types';\n\nconst createListboxId = createTngIdFactory('tng-multi-autocomplete-listbox');\n\n@Directive({\n selector: '[tngMultiAutocompleteListbox]',\n providers: [\n { provide: TNG_MULTI_AUTOCOMPLETE_LISTBOX, useExisting: TngMultiAutocompleteListbox },\n // Multi-autocomplete typing happens in the input. Listbox must NOT typeahead.\n { provide: TNG_LISTBOX_FORCE_TYPEAHEAD, useValue: false },\n { provide: TNG_LISTBOX_FORCE_MULTIPLE, useValue: true },\n { provide: TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, useValue: true },\n ],\n hostDirectives: [\n {\n directive: TngListboxDirective,\n inputs: ['orientation', 'direction', 'disabled', 'loop', 'value'],\n outputs: ['valueChange'],\n },\n ],\n})\nexport class TngMultiAutocompleteListbox<T = unknown> implements TngMultiAutocompleteListboxApi<T> {\n private readonly multi = inject<TngMultiAutocomplete<T>>(TNG_MULTI_AUTOCOMPLETE);\n private readonly destroyRef = inject(DestroyRef);\n private readonly listbox = inject(TngListboxDirective<T>, { self: true });\n\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'multi-autocomplete-listbox' as const;\n\n @HostBinding('attr.id')\n protected readonly id = createListboxId();\n\n constructor() {\n this.multi.setListboxId(this.id);\n this.multi.setListboxApi(this);\n\n // External multi.value -> listbox.value (keeps selection UI in sync)\n effect(() => {\n const v = this.multi.value(); // readonly T[]\n const current = untracked(() => this.listbox.value()); // ListboxValue<T>\n const currentArr = Array.isArray(current)\n ? (current as readonly T[])\n : current === null\n ? ([] as readonly T[])\n : ([current as T] as const);\n\n // compare by order + Object.is (good enough for now)\n if (\n currentArr.length === v.length &&\n v.every((val, i) => Object.is(val, currentArr[i]))\n ) {\n return;\n }\n\n this.listbox.value.set([...v] as readonly T[]);\n\n // External controlled value changes while closed should reset filtering state.\n if (!this.multi.open()) {\n this.multi.query.set('');\n this.multi.queryChange.emit('');\n }\n });\n\n this.destroyRef.onDestroy(() => {\n this.multi.setListboxId(null);\n this.multi.setListboxApi(null);\n });\n }\n\n getHostId(): string | null {\n return this.id ?? null;\n }\n\n getActiveId(): string | null {\n return this.listbox.getActiveId();\n }\n\n ensureActive(pref?: 'first' | 'last'): void {\n this.listbox.ensureActive(pref);\n }\n\n handleKey(key: string, shiftKey?: boolean): boolean {\n return this.listbox.handleKeyFromCombobox(key, shiftKey);\n }\n\n commitActive(): void {\n const value = this.listbox.getActiveValue();\n if (value === undefined) return;\n this.multi.toggle(value as T);\n this.listbox.setActiveId(null);\n this.multi.query.set('');\n this.multi.queryChange.emit('');\n }\n\n @HostListener('valueChange', ['$event'])\n protected onListboxValueChange(value: T | readonly T[] | null): void {\n if (this.multi.disabled()) return;\n\n const arr = value === null ? [] : Array.isArray(value) ? value : [value];\n\n // Option unregister/re-register during filtering can cause listbox to emit a fresh\n // array instance even when the logical selection did not change. Treat that as a\n // no-op so typing does not clear the controlled query.\n const current = this.multi.value();\n if (\n current.length === arr.length &&\n arr.every((val, i) => Object.is(val, current[i]))\n ) {\n return;\n }\n\n this.multi.value.set([...arr] as readonly T[]);\n this.listbox.setActiveId(null);\n this.multi.query.set('');\n this.multi.queryChange.emit('');\n }\n\n getValue?(): readonly T[] {\n const v = this.listbox.value();\n if (v === null) return [];\n return Array.isArray(v) ? (v as readonly T[]) : ([v as T] as const);\n }\n}\n\n@Directive({\n selector: '[tngMultiAutocompleteOption]',\n hostDirectives: [\n {\n directive: TngOptionDirective,\n inputs: ['tngValue', 'disabled'],\n },\n ],\n})\nexport class TngMultiAutocompleteOption<T = unknown> {\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'multi-autocomplete-option' as const;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tng-multi-autocomplete.listbox.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/multi-autocomplete/tng-multi-autocomplete.listbox.ts"],"names":[],"mappings":"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","sourcesContent":["// libs/tailng-ui/primitives/src/lib/form/multi-autocomplete/tng-multi-autocomplete.listbox.ts\nimport {\n DestroyRef,\n Directive,\n HostBinding,\n HostListener,\n effect,\n inject,\n untracked,\n} from '@angular/core';\n\nimport { createTngIdFactory } from '@tailng-ui/cdk';\nimport {\n TngListboxDirective,\n} from '../listbox/listbox.directive';\nimport { TngOptionDirective } from '../listbox/option.directive';\nimport {\n TNG_LISTBOX_FOCUS_ON_POINTER_SELECT,\n TNG_LISTBOX_FORCE_MULTIPLE,\n TNG_LISTBOX_FORCE_TYPEAHEAD,\n TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER,\n} from '../listbox/tokens';\n\nimport { TNG_MULTI_AUTOCOMPLETE } from './tng-multi-autocomplete.tokens';\nimport type { TngMultiAutocomplete } from './tng-multi-autocomplete';\nimport { TNG_MULTI_AUTOCOMPLETE_LISTBOX } from './tng-multi-autocomplete.listbox.tokens';\nimport type { TngMultiAutocompleteListboxApi } from './tng-multi-autocomplete.listbox.types';\n\nconst createListboxId = createTngIdFactory('tng-multi-autocomplete-listbox');\n\n@Directive({\n selector: '[tngMultiAutocompleteListbox]',\n providers: [\n { provide: TNG_MULTI_AUTOCOMPLETE_LISTBOX, useExisting: TngMultiAutocompleteListbox },\n // Multi-autocomplete typing happens in the input. Listbox must NOT typeahead.\n { provide: TNG_LISTBOX_FORCE_TYPEAHEAD, useValue: false },\n { provide: TNG_LISTBOX_FORCE_MULTIPLE, useValue: true },\n // Keep focus on the trigger input so combobox Escape/typing semantics stay intact.\n { provide: TNG_LISTBOX_FOCUS_ON_POINTER_SELECT, useValue: false },\n { provide: TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, useValue: true },\n ],\n hostDirectives: [\n {\n directive: TngListboxDirective,\n inputs: ['orientation', 'direction', 'disabled', 'loop', 'value'],\n outputs: ['valueChange'],\n },\n ],\n})\nexport class TngMultiAutocompleteListbox<T = unknown> implements TngMultiAutocompleteListboxApi<T> {\n private readonly multi = inject<TngMultiAutocomplete<T>>(TNG_MULTI_AUTOCOMPLETE);\n private readonly destroyRef = inject(DestroyRef);\n private readonly listbox = inject(TngListboxDirective<T>, { self: true });\n\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'multi-autocomplete-listbox' as const;\n\n @HostBinding('attr.id')\n protected readonly id = createListboxId();\n\n constructor() {\n this.multi.setListboxId(this.id);\n this.multi.setListboxApi(this);\n\n // External multi.value -> listbox.value (keeps selection UI in sync)\n effect(() => {\n const v = this.multi.value(); // readonly T[]\n const current = untracked(() => this.listbox.value()); // ListboxValue<T>\n const currentArr = Array.isArray(current)\n ? (current as readonly T[])\n : current === null\n ? ([] as readonly T[])\n : ([current as T] as const);\n\n // compare by order + Object.is (good enough for now)\n if (\n currentArr.length === v.length &&\n v.every((val, i) => Object.is(val, currentArr[i]))\n ) {\n return;\n }\n\n this.listbox.value.set([...v] as readonly T[]);\n\n // External controlled value changes while closed should reset filtering state.\n if (!this.multi.open()) {\n this.multi.query.set('');\n this.multi.queryChange.emit('');\n }\n });\n\n this.destroyRef.onDestroy(() => {\n this.multi.setListboxId(null);\n this.multi.setListboxApi(null);\n });\n }\n\n getHostId(): string | null {\n return this.id ?? null;\n }\n\n getActiveId(): string | null {\n return this.listbox.getActiveId();\n }\n\n ensureActive(pref?: 'first' | 'last'): void {\n this.listbox.ensureActive(pref);\n }\n\n handleKey(key: string, shiftKey?: boolean): boolean {\n return this.listbox.handleKeyFromCombobox(key, shiftKey);\n }\n\n commitActive(): void {\n const value = this.listbox.getActiveValue();\n if (value === undefined) return;\n this.multi.toggle(value as T);\n this.listbox.setActiveId(null);\n this.multi.query.set('');\n this.multi.queryChange.emit('');\n }\n\n @HostListener('valueChange', ['$event'])\n protected onListboxValueChange(value: T | readonly T[] | null): void {\n if (this.multi.disabled()) return;\n\n const arr = value === null ? [] : Array.isArray(value) ? value : [value];\n\n // Option unregister/re-register during filtering can cause listbox to emit a fresh\n // array instance even when the logical selection did not change. Treat that as a\n // no-op so typing does not clear the controlled query.\n const current = this.multi.value();\n if (\n current.length === arr.length &&\n arr.every((val, i) => Object.is(val, current[i]))\n ) {\n return;\n }\n\n this.multi.value.set([...arr] as readonly T[]);\n this.listbox.setActiveId(null);\n this.multi.query.set('');\n this.multi.queryChange.emit('');\n }\n\n getValue?(): readonly T[] {\n const v = this.listbox.value();\n if (v === null) return [];\n return Array.isArray(v) ? (v as readonly T[]) : ([v as T] as const);\n }\n}\n\n@Directive({\n selector: '[tngMultiAutocompleteOption]',\n hostDirectives: [\n {\n directive: TngOptionDirective,\n inputs: ['tngValue', 'disabled'],\n },\n ],\n})\nexport class TngMultiAutocompleteOption<T = unknown> {\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'multi-autocomplete-option' as const;\n}\n"]}
|
|
@@ -60,7 +60,7 @@ export declare class TngMenubarItem {
|
|
|
60
60
|
private syncOwnedMenuLink;
|
|
61
61
|
private syncAriaExpanded;
|
|
62
62
|
private syncMenuState;
|
|
63
|
-
private
|
|
63
|
+
private teardownOwnedMenuLink;
|
|
64
64
|
private syncHostId;
|
|
65
65
|
static ɵfac: i0.ɵɵFactoryDeclaration<TngMenubarItem, never>;
|
|
66
66
|
static ɵdir: i0.ɵɵDirectiveDeclaration<TngMenubarItem, "[tngMenubarItem]", ["tngMenubarItem"], { "ownedMenu": { "alias": "tngMenubarMenu"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tng-menubar.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/navigation/menubar/tng-menubar.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;;AAE3C,KAAK,kBAAkB,GAAG,WAAW,CAAC;AAItC,qBAIa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+C;IACvE,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,oBAAoB,CAA8C;IAE1E,QAAQ,CAAC,IAAI,+CAAwB;IAGrC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAG,SAAS,CAAU;IAGjD,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAG,SAAS,CAAU;IAG7C,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAG,YAAY,CAAU;IAE3D,QAAQ,IAAI,SAAS,kBAAkB,EAAE;IAMzC,eAAe,IAAI,SAAS,kBAAkB,EAAE;IAIhD,KAAK,IAAI,OAAO;IAShB,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAcpC,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAQ7C,WAAW,IAAI,OAAO;IAItB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO;IAIzC,kBAAkB,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IA+BpF,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAe7C,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI;IAcnF,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAWxC,WAAW,IAAI,IAAI;IAOnB,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,oBAAoB;yCAvKjB,UAAU;2CAAV,UAAU;CAmLtB;AAED,qBAIa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+C;IACvE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAC8C;IACzE,OAAO,CAAC,aAAa,CAAwB;IAE7C,QAAQ,CAAC,SAAS,sDAEf;IAGH,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAG,cAAc,CAAU;IAGtD,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAU;IAG9C,SAAS,CAAC,QAAQ,CAAC,EAAE,SAAmB;IAGxC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAM/B;IAGD,SAAS,KAAK,YAAY,IAAI,MAAM,GAAG,IAAI,CAE1C;IAGD,SAAS,KAAK,YAAY,IAAI,MAAM,GAAG,IAAI,CAE1C;IAGD,SAAS,KAAK,YAAY,IAAI,MAAM,GAAG,IAAI,CAE1C;IAED,QAAQ,IAAI,IAAI;IAOhB,SAAS,IAAI,IAAI;IAajB,WAAW,IAAI,IAAI;IAKnB,SAAS,CAAC,OAAO,IAAI,IAAI;IAWzB,SAAS,CAAC,aAAa,IAAI,IAAI;IAS/B,SAAS,CAAC,YAAY,IAAI,IAAI;IAgB9B,SAAS,CAAC,OAAO,IAAI,IAAI;IAKzB,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"tng-menubar.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/navigation/menubar/tng-menubar.ts"],"names":[],"mappings":"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"}
|
|
@@ -187,13 +187,13 @@ export class TngMenubarItem {
|
|
|
187
187
|
if (currentOwnedMenu === this.lastOwnedMenu) {
|
|
188
188
|
return;
|
|
189
189
|
}
|
|
190
|
-
this.
|
|
190
|
+
this.teardownOwnedMenuLink(this.lastOwnedMenu);
|
|
191
191
|
this.lastOwnedMenu = currentOwnedMenu;
|
|
192
192
|
this.syncOwnedMenuLink();
|
|
193
193
|
this.syncAriaExpanded();
|
|
194
194
|
}
|
|
195
195
|
ngOnDestroy() {
|
|
196
|
-
this.
|
|
196
|
+
this.teardownOwnedMenuLink(this.lastOwnedMenu);
|
|
197
197
|
}
|
|
198
198
|
onClick() {
|
|
199
199
|
if (this.ownedMenu() === null || this.isDisabled()) {
|
|
@@ -244,24 +244,9 @@ export class TngMenubarItem {
|
|
|
244
244
|
}
|
|
245
245
|
if (event.key === 'Tab') {
|
|
246
246
|
if (ownedMenu?.isOpen()) {
|
|
247
|
-
|
|
248
|
-
event.preventDefault();
|
|
249
|
-
}
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
const items = this.menubar.getEnabledItems();
|
|
253
|
-
const current = this.hostRef.nativeElement;
|
|
254
|
-
const currentIndex = items.indexOf(current);
|
|
255
|
-
if (currentIndex < 0 || items.length === 0) {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
const targetIndex = event.shiftKey ? currentIndex - 1 : currentIndex + 1;
|
|
259
|
-
const target = items[targetIndex];
|
|
260
|
-
if (target === undefined) {
|
|
247
|
+
this.closeOwnedMenu(false);
|
|
261
248
|
return;
|
|
262
249
|
}
|
|
263
|
-
event.preventDefault();
|
|
264
|
-
target.focus();
|
|
265
250
|
return;
|
|
266
251
|
}
|
|
267
252
|
if (ownedMenu?.isOpen() && (event.key === 'ArrowRight' || event.key === 'ArrowLeft')) {
|
|
@@ -385,7 +370,7 @@ export class TngMenubarItem {
|
|
|
385
370
|
ownedMenu.setTriggerElement(this.hostRef.nativeElement, () => this.syncMenuState());
|
|
386
371
|
ownedMenu.setRestoreFocusOnOutsideClick(true);
|
|
387
372
|
ownedMenu.setMenubarArrowHandler((key) => this.handleArrowFromOpenMenu(key));
|
|
388
|
-
ownedMenu.setMenubarTabHandler(
|
|
373
|
+
ownedMenu.setMenubarTabHandler(null);
|
|
389
374
|
}
|
|
390
375
|
syncAriaExpanded() {
|
|
391
376
|
const ownedMenu = this.ownedMenu();
|
|
@@ -399,29 +384,14 @@ export class TngMenubarItem {
|
|
|
399
384
|
this.syncAriaExpanded();
|
|
400
385
|
this.menubar.syncOpenItem(this);
|
|
401
386
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
const currentIndex = items.indexOf(current);
|
|
406
|
-
if (currentIndex < 0 || items.length === 0) {
|
|
407
|
-
return false;
|
|
408
|
-
}
|
|
409
|
-
const targetIndex = shiftKey ? currentIndex - 1 : currentIndex + 1;
|
|
410
|
-
const target = items[targetIndex];
|
|
411
|
-
if (target === undefined || target === current) {
|
|
412
|
-
this.closeOwnedMenu(false);
|
|
413
|
-
return false;
|
|
387
|
+
teardownOwnedMenuLink(ownedMenu) {
|
|
388
|
+
if (ownedMenu === null) {
|
|
389
|
+
return;
|
|
414
390
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
if (targetOwnsMenu) {
|
|
418
|
-
target.focus();
|
|
419
|
-
targetDirective.click();
|
|
420
|
-
return true;
|
|
391
|
+
if (ownedMenu.isOpen()) {
|
|
392
|
+
ownedMenu.close(false);
|
|
421
393
|
}
|
|
422
|
-
this.
|
|
423
|
-
target.focus();
|
|
424
|
-
return true;
|
|
394
|
+
ownedMenu.clearTriggerLink(this.hostRef.nativeElement);
|
|
425
395
|
}
|
|
426
396
|
syncHostId() {
|
|
427
397
|
if (this.hostRef.nativeElement.id === this.id) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tng-menubar.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/navigation/menubar/tng-menubar.ts"],"names":[],"mappings":"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","sourcesContent":["import { Directive, ElementRef, HostBinding, HostListener, inject, input } from '@angular/core';\nimport { createTngIdFactory } from '@tailng-ui/cdk';\n\nimport { TngMenu } from '../menu/tng-menu';\n\ntype MenubarItemElement = HTMLElement;\nconst createMenubarItemId = createTngIdFactory('tng-menubar-item');\nconst TYPEAHEAD_RESET_MS = 500;\n\n@Directive({\n selector: '[tngMenubar]',\n exportAs: 'tngMenubar',\n})\nexport class TngMenubar {\n private readonly hostRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private openItem: TngMenubarItem | null = null;\n private currentTabStopId: string | null = null;\n private typeaheadBuffer = '';\n private typeaheadResetHandle: ReturnType<typeof setTimeout> | null = null;\n\n readonly loop = input<boolean>(true);\n\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'menubar' as const;\n\n @HostBinding('attr.role')\n protected readonly role = 'menubar' as const;\n\n @HostBinding('attr.aria-orientation')\n protected readonly ariaOrientation = 'horizontal' as const;\n\n getItems(): readonly MenubarItemElement[] {\n return Array.from(\n this.hostRef.nativeElement.querySelectorAll<MenubarItemElement>('[tngMenubarItem]'),\n );\n }\n\n getEnabledItems(): readonly MenubarItemElement[] {\n return this.getItems().filter((item) => item.getAttribute('aria-disabled') !== 'true');\n }\n\n isRtl(): boolean {\n const host = this.hostRef.nativeElement;\n const nearestDir =\n host.closest<HTMLElement>('[dir]')?.getAttribute('dir') ??\n host.ownerDocument?.documentElement.getAttribute('dir');\n\n return nearestDir?.toLowerCase() === 'rtl';\n }\n\n getCurrentTabStopId(): string | null {\n const enabledItems = this.getEnabledItems();\n if (enabledItems.length === 0) {\n this.currentTabStopId = null;\n return null;\n }\n\n if (!enabledItems.some((item) => item.id === this.currentTabStopId)) {\n this.currentTabStopId = enabledItems[0]?.id ?? null;\n }\n\n return this.currentTabStopId;\n }\n\n setCurrentTabStop(item: TngMenubarItem): void {\n if (item.isDisabledItem()) {\n return;\n }\n\n this.currentTabStopId = item.getItemId();\n }\n\n hasOpenItem(): boolean {\n return this.openItem !== null;\n }\n\n isOpenItem(item: TngMenubarItem): boolean {\n return this.openItem === item;\n }\n\n findTypeaheadMatch(currentItem: HTMLElement, key: string): MenubarItemElement | null {\n const items = this.getEnabledItems();\n if (items.length === 0) {\n return null;\n }\n\n const normalizedKey = key.trim().toLowerCase();\n if (normalizedKey.length !== 1) {\n return null;\n }\n\n const repeatingSingleChar =\n this.typeaheadBuffer.length > 0 &&\n this.typeaheadBuffer.split('').every((char) => char === normalizedKey);\n\n let query = repeatingSingleChar ? normalizedKey : `${this.typeaheadBuffer}${normalizedKey}`;\n let match = this.findMatchingItem(items, currentItem, query, repeatingSingleChar);\n\n if (match === null && query !== normalizedKey) {\n query = normalizedKey;\n match = this.findMatchingItem(items, currentItem, query, true);\n }\n\n if (match === null) {\n return null;\n }\n\n this.resetTypeaheadBuffer(query);\n return match;\n }\n\n requestToggleMenu(item: TngMenubarItem): void {\n const ownedMenu = item.getOwnedMenu();\n if (ownedMenu === null || item.isDisabledItem()) {\n return;\n }\n\n if (ownedMenu.isOpen()) {\n item.closeOwnedMenu(false);\n item.focusSelf();\n return;\n }\n\n this.requestOpenMenu(item, 'none');\n }\n\n requestOpenMenu(item: TngMenubarItem, focusAction: 'none' | 'first' | 'last'): void {\n const ownedMenu = item.getOwnedMenu();\n if (ownedMenu === null || item.isDisabledItem()) {\n return;\n }\n\n if (this.openItem !== null && this.openItem !== item) {\n this.openItem.closeOwnedMenu(false);\n }\n\n this.openItem = item;\n item.openOwnedMenu(focusAction);\n }\n\n syncOpenItem(item: TngMenubarItem): void {\n if (item.getOwnedMenu()?.isOpen()) {\n this.openItem = item;\n return;\n }\n\n if (this.openItem === item) {\n this.openItem = null;\n }\n }\n\n ngOnDestroy(): void {\n if (this.typeaheadResetHandle !== null) {\n clearTimeout(this.typeaheadResetHandle);\n this.typeaheadResetHandle = null;\n }\n }\n\n private findMatchingItem(\n items: readonly MenubarItemElement[],\n currentItem: HTMLElement,\n query: string,\n cycleFromCurrentItem: boolean,\n ): MenubarItemElement | null {\n const currentIndex = items.indexOf(currentItem);\n const startIndex = cycleFromCurrentItem && currentIndex >= 0 ? (currentIndex + 1) % items.length : 0;\n\n for (let offset = 0; offset < items.length; offset += 1) {\n const index = (startIndex + offset) % items.length;\n const item = items[index];\n const label = item.textContent?.trim().toLowerCase() ?? '';\n\n if (label.startsWith(query)) {\n return item;\n }\n }\n\n return null;\n }\n\n private resetTypeaheadBuffer(nextBuffer: string): void {\n this.typeaheadBuffer = nextBuffer;\n\n if (this.typeaheadResetHandle !== null) {\n clearTimeout(this.typeaheadResetHandle);\n }\n\n this.typeaheadResetHandle = setTimeout(() => {\n this.typeaheadBuffer = '';\n this.typeaheadResetHandle = null;\n }, TYPEAHEAD_RESET_MS);\n }\n}\n\n@Directive({\n selector: '[tngMenubarItem]',\n exportAs: 'tngMenubarItem',\n})\nexport class TngMenubarItem {\n private readonly hostRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly menubar = inject(TngMenubar, { host: true });\n private readonly resolvedId =\n this.hostRef.nativeElement.getAttribute('id') ?? createMenubarItemId();\n private lastOwnedMenu: TngMenu | null = null;\n\n readonly ownedMenu = input<TngMenu | null>(null, {\n alias: 'tngMenubarMenu',\n });\n\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'menubar-item' as const;\n\n @HostBinding('attr.role')\n protected readonly role = 'menuitem' as const;\n\n @HostBinding('attr.id')\n protected readonly id = this.resolvedId;\n\n @HostBinding('attr.tabindex')\n protected get tabIndex(): string {\n if (this.isDisabled()) {\n return '-1';\n }\n\n return this.menubar.getCurrentTabStopId() === this.id ? '0' : '-1';\n }\n\n @HostBinding('attr.aria-disabled')\n protected get ariaDisabled(): 'true' | null {\n return this.isDisabled() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-haspopup')\n protected get ariaHaspopup(): 'menu' | null {\n return this.ownedMenu() === null ? null : 'menu';\n }\n\n @HostBinding('attr.aria-controls')\n protected get ariaControls(): string | null {\n return this.ownedMenu()?.id ?? null;\n }\n\n ngOnInit(): void {\n this.syncHostId();\n this.lastOwnedMenu = this.ownedMenu();\n this.syncOwnedMenuLink();\n this.syncAriaExpanded();\n }\n\n ngDoCheck(): void {\n this.syncHostId();\n const currentOwnedMenu = this.ownedMenu();\n if (currentOwnedMenu === this.lastOwnedMenu) {\n return;\n }\n\n this.lastOwnedMenu?.clearTriggerLink(this.hostRef.nativeElement);\n this.lastOwnedMenu = currentOwnedMenu;\n this.syncOwnedMenuLink();\n this.syncAriaExpanded();\n }\n\n ngOnDestroy(): void {\n this.lastOwnedMenu?.clearTriggerLink(this.hostRef.nativeElement);\n }\n\n @HostListener('click')\n protected onClick(): void {\n if (this.ownedMenu() === null || this.isDisabled()) {\n return;\n }\n\n this.focusSelf();\n this.syncOwnedMenuLink();\n this.menubar.requestToggleMenu(this);\n }\n\n @HostListener('pointerdown')\n protected onPointerdown(): void {\n if (this.isDisabled()) {\n return;\n }\n\n this.focusSelf();\n }\n\n @HostListener('mouseenter')\n protected onMouseenter(): void {\n if (this.isDisabled()) {\n return;\n }\n\n this.menubar.setCurrentTabStop(this);\n\n if (!this.menubar.hasOpenItem() || this.menubar.isOpenItem(this) || this.ownedMenu() === null) {\n return;\n }\n\n this.syncOwnedMenuLink();\n this.menubar.requestOpenMenu(this, 'none');\n }\n\n @HostListener('focus')\n protected onFocus(): void {\n this.menubar.setCurrentTabStop(this);\n }\n\n @HostListener('keydown', ['$event'])\n protected onKeydown(event: KeyboardEvent): void {\n const ownedMenu = this.ownedMenu();\n if (!this.isDisabled() && ownedMenu?.isOpen() && event.key === 'Escape') {\n event.preventDefault();\n this.closeOwnedMenu(true);\n return;\n }\n\n if (\n !this.isDisabled() &&\n ownedMenu !== null &&\n (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown' || event.key === 'ArrowUp')\n ) {\n event.preventDefault();\n this.syncOwnedMenuLink();\n\n if (ownedMenu.isOpen() && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {\n ownedMenu.focusPanelAndMoveActiveItem(event.key === 'ArrowDown' ? 'next' : 'prev');\n return;\n }\n\n this.menubar.requestOpenMenu(this, event.key === 'ArrowDown' ? 'first' : event.key === 'ArrowUp' ? 'last' : 'none');\n return;\n }\n\n if (event.key === 'Tab') {\n if (ownedMenu?.isOpen()) {\n if (this.handleTabFromOpenMenu(event.shiftKey)) {\n event.preventDefault();\n }\n return;\n }\n\n const items = this.menubar.getEnabledItems();\n const current = this.hostRef.nativeElement;\n const currentIndex = items.indexOf(current);\n\n if (currentIndex < 0 || items.length === 0) {\n return;\n }\n\n const targetIndex = event.shiftKey ? currentIndex - 1 : currentIndex + 1;\n const target = items[targetIndex];\n\n if (target === undefined) {\n return;\n }\n\n event.preventDefault();\n target.focus();\n return;\n }\n\n if (ownedMenu?.isOpen() && (event.key === 'ArrowRight' || event.key === 'ArrowLeft')) {\n event.preventDefault();\n this.handleArrowFromOpenMenu(event.key);\n return;\n }\n\n if (\n event.key !== 'ArrowRight' &&\n event.key !== 'ArrowLeft' &&\n event.key !== 'Home' &&\n event.key !== 'End'\n ) {\n if (event.key.length === 1 && !this.isDisabled()) {\n const match = this.menubar.findTypeaheadMatch(this.hostRef.nativeElement, event.key);\n if (match !== null) {\n event.preventDefault();\n match.focus();\n }\n }\n return;\n }\n\n const items = this.menubar.getEnabledItems();\n const current = this.hostRef.nativeElement;\n const currentIndex = items.indexOf(current);\n\n if (currentIndex < 0 || items.length === 0) {\n return;\n }\n\n event.preventDefault();\n\n if (event.key === 'Home') {\n items[0]?.focus();\n return;\n }\n\n if (event.key === 'End') {\n items[items.length - 1]?.focus();\n return;\n }\n\n const loop = this.menubar.loop();\n const moveToNext =\n event.key === (this.menubar.isRtl() ? 'ArrowLeft' : 'ArrowRight');\n const targetIndex =\n moveToNext\n ? currentIndex + 1 >= items.length\n ? loop\n ? 0\n : items.length - 1\n : currentIndex + 1\n : currentIndex - 1 < 0\n ? loop\n ? items.length - 1\n : 0\n : currentIndex - 1;\n\n items[targetIndex]?.focus();\n }\n\n isDisabledItem(): boolean {\n return this.isDisabled();\n }\n\n getOwnedMenu(): TngMenu | null {\n return this.ownedMenu();\n }\n\n openOwnedMenu(focusAction: 'none' | 'first' | 'last'): void {\n const ownedMenu = this.ownedMenu();\n if (ownedMenu === null) {\n return;\n }\n\n ownedMenu.open(focusAction);\n }\n\n closeOwnedMenu(restoreFocus: boolean): void {\n const ownedMenu = this.ownedMenu();\n if (ownedMenu === null) {\n return;\n }\n\n ownedMenu.close(restoreFocus);\n }\n\n focusSelf(): void {\n this.menubar.setCurrentTabStop(this);\n this.hostRef.nativeElement.focus();\n }\n\n getItemId(): string {\n return this.id;\n }\n\n handleArrowFromOpenMenu(key: 'ArrowRight' | 'ArrowLeft'): void {\n const items = this.menubar.getEnabledItems();\n const current = this.hostRef.nativeElement;\n const currentIndex = items.indexOf(current);\n\n if (currentIndex < 0 || items.length === 0) {\n return;\n }\n\n const moveToNext =\n key === (this.menubar.isRtl() ? 'ArrowLeft' : 'ArrowRight');\n const loop = this.menubar.loop();\n const targetIndex =\n moveToNext\n ? currentIndex + 1 >= items.length\n ? loop\n ? 0\n : items.length - 1\n : currentIndex + 1\n : currentIndex - 1 < 0\n ? loop\n ? items.length - 1\n : 0\n : currentIndex - 1;\n\n const target = items[targetIndex];\n if (target === undefined || target === current) {\n return;\n }\n\n const targetOwnsMenu = target.getAttribute('aria-haspopup') === 'menu';\n if (!targetOwnsMenu) {\n this.closeOwnedMenu(false);\n target.focus();\n return;\n }\n\n target.focus();\n target.click();\n }\n\n private isDisabled(): boolean {\n const element = this.hostRef.nativeElement as HTMLElement & {\n disabled?: boolean;\n };\n\n return element.disabled || element.hasAttribute('disabled');\n }\n\n private syncOwnedMenuLink(): void {\n const ownedMenu = this.ownedMenu();\n if (ownedMenu === null) {\n return;\n }\n\n this.syncHostId();\n ownedMenu.setTriggerElement(this.hostRef.nativeElement, () => this.syncMenuState());\n ownedMenu.setRestoreFocusOnOutsideClick(true);\n ownedMenu.setMenubarArrowHandler((key) => this.handleArrowFromOpenMenu(key));\n ownedMenu.setMenubarTabHandler((shiftKey) => this.handleTabFromOpenMenu(shiftKey));\n }\n\n private syncAriaExpanded(): void {\n const ownedMenu = this.ownedMenu();\n if (ownedMenu === null) {\n this.hostRef.nativeElement.removeAttribute('aria-expanded');\n return;\n }\n\n this.hostRef.nativeElement.setAttribute('aria-expanded', ownedMenu.isOpen() ? 'true' : 'false');\n }\n\n private syncMenuState(): void {\n this.syncAriaExpanded();\n this.menubar.syncOpenItem(this);\n }\n\n private handleTabFromOpenMenu(shiftKey: boolean): boolean {\n const items = this.menubar.getEnabledItems();\n const current = this.hostRef.nativeElement;\n const currentIndex = items.indexOf(current);\n\n if (currentIndex < 0 || items.length === 0) {\n return false;\n }\n\n const targetIndex = shiftKey ? currentIndex - 1 : currentIndex + 1;\n const target = items[targetIndex];\n\n if (target === undefined || target === current) {\n this.closeOwnedMenu(false);\n return false;\n }\n\n const targetDirective = (target as HTMLElement & { click(): void });\n const targetOwnsMenu = target.getAttribute('aria-haspopup') === 'menu';\n\n if (targetOwnsMenu) {\n target.focus();\n targetDirective.click();\n return true;\n }\n\n this.closeOwnedMenu(false);\n target.focus();\n return true;\n }\n\n private syncHostId(): void {\n if (this.hostRef.nativeElement.id === this.id) {\n return;\n }\n\n this.hostRef.nativeElement.id = this.id;\n }\n}\n\n/**\n * Wrap each owned {@link TngMenu} and its {@link TngMenubarItem} so absolutely\n * positioned menu panels anchor to this element. The menu contract positions\n * root menus with `top: calc(100% + …)`; that percentage resolves against the\n * nearest positioned ancestor — this host provides it (see theme menubar.css).\n */\n@Directive({\n selector: '[tngMenubarGroup]',\n exportAs: 'tngMenubarGroup',\n})\nexport class TngMenubarGroup {\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'menubar-group' as const;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tng-menubar.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/navigation/menubar/tng-menubar.ts"],"names":[],"mappings":"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","sourcesContent":["import { Directive, ElementRef, HostBinding, HostListener, inject, input } from '@angular/core';\nimport { createTngIdFactory } from '@tailng-ui/cdk';\n\nimport { TngMenu } from '../menu/tng-menu';\n\ntype MenubarItemElement = HTMLElement;\nconst createMenubarItemId = createTngIdFactory('tng-menubar-item');\nconst TYPEAHEAD_RESET_MS = 500;\n\n@Directive({\n selector: '[tngMenubar]',\n exportAs: 'tngMenubar',\n})\nexport class TngMenubar {\n private readonly hostRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private openItem: TngMenubarItem | null = null;\n private currentTabStopId: string | null = null;\n private typeaheadBuffer = '';\n private typeaheadResetHandle: ReturnType<typeof setTimeout> | null = null;\n\n readonly loop = input<boolean>(true);\n\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'menubar' as const;\n\n @HostBinding('attr.role')\n protected readonly role = 'menubar' as const;\n\n @HostBinding('attr.aria-orientation')\n protected readonly ariaOrientation = 'horizontal' as const;\n\n getItems(): readonly MenubarItemElement[] {\n return Array.from(\n this.hostRef.nativeElement.querySelectorAll<MenubarItemElement>('[tngMenubarItem]'),\n );\n }\n\n getEnabledItems(): readonly MenubarItemElement[] {\n return this.getItems().filter((item) => item.getAttribute('aria-disabled') !== 'true');\n }\n\n isRtl(): boolean {\n const host = this.hostRef.nativeElement;\n const nearestDir =\n host.closest<HTMLElement>('[dir]')?.getAttribute('dir') ??\n host.ownerDocument?.documentElement.getAttribute('dir');\n\n return nearestDir?.toLowerCase() === 'rtl';\n }\n\n getCurrentTabStopId(): string | null {\n const enabledItems = this.getEnabledItems();\n if (enabledItems.length === 0) {\n this.currentTabStopId = null;\n return null;\n }\n\n if (!enabledItems.some((item) => item.id === this.currentTabStopId)) {\n this.currentTabStopId = enabledItems[0]?.id ?? null;\n }\n\n return this.currentTabStopId;\n }\n\n setCurrentTabStop(item: TngMenubarItem): void {\n if (item.isDisabledItem()) {\n return;\n }\n\n this.currentTabStopId = item.getItemId();\n }\n\n hasOpenItem(): boolean {\n return this.openItem !== null;\n }\n\n isOpenItem(item: TngMenubarItem): boolean {\n return this.openItem === item;\n }\n\n findTypeaheadMatch(currentItem: HTMLElement, key: string): MenubarItemElement | null {\n const items = this.getEnabledItems();\n if (items.length === 0) {\n return null;\n }\n\n const normalizedKey = key.trim().toLowerCase();\n if (normalizedKey.length !== 1) {\n return null;\n }\n\n const repeatingSingleChar =\n this.typeaheadBuffer.length > 0 &&\n this.typeaheadBuffer.split('').every((char) => char === normalizedKey);\n\n let query = repeatingSingleChar ? normalizedKey : `${this.typeaheadBuffer}${normalizedKey}`;\n let match = this.findMatchingItem(items, currentItem, query, repeatingSingleChar);\n\n if (match === null && query !== normalizedKey) {\n query = normalizedKey;\n match = this.findMatchingItem(items, currentItem, query, true);\n }\n\n if (match === null) {\n return null;\n }\n\n this.resetTypeaheadBuffer(query);\n return match;\n }\n\n requestToggleMenu(item: TngMenubarItem): void {\n const ownedMenu = item.getOwnedMenu();\n if (ownedMenu === null || item.isDisabledItem()) {\n return;\n }\n\n if (ownedMenu.isOpen()) {\n item.closeOwnedMenu(false);\n item.focusSelf();\n return;\n }\n\n this.requestOpenMenu(item, 'none');\n }\n\n requestOpenMenu(item: TngMenubarItem, focusAction: 'none' | 'first' | 'last'): void {\n const ownedMenu = item.getOwnedMenu();\n if (ownedMenu === null || item.isDisabledItem()) {\n return;\n }\n\n if (this.openItem !== null && this.openItem !== item) {\n this.openItem.closeOwnedMenu(false);\n }\n\n this.openItem = item;\n item.openOwnedMenu(focusAction);\n }\n\n syncOpenItem(item: TngMenubarItem): void {\n if (item.getOwnedMenu()?.isOpen()) {\n this.openItem = item;\n return;\n }\n\n if (this.openItem === item) {\n this.openItem = null;\n }\n }\n\n ngOnDestroy(): void {\n if (this.typeaheadResetHandle !== null) {\n clearTimeout(this.typeaheadResetHandle);\n this.typeaheadResetHandle = null;\n }\n }\n\n private findMatchingItem(\n items: readonly MenubarItemElement[],\n currentItem: HTMLElement,\n query: string,\n cycleFromCurrentItem: boolean,\n ): MenubarItemElement | null {\n const currentIndex = items.indexOf(currentItem);\n const startIndex = cycleFromCurrentItem && currentIndex >= 0 ? (currentIndex + 1) % items.length : 0;\n\n for (let offset = 0; offset < items.length; offset += 1) {\n const index = (startIndex + offset) % items.length;\n const item = items[index];\n const label = item.textContent?.trim().toLowerCase() ?? '';\n\n if (label.startsWith(query)) {\n return item;\n }\n }\n\n return null;\n }\n\n private resetTypeaheadBuffer(nextBuffer: string): void {\n this.typeaheadBuffer = nextBuffer;\n\n if (this.typeaheadResetHandle !== null) {\n clearTimeout(this.typeaheadResetHandle);\n }\n\n this.typeaheadResetHandle = setTimeout(() => {\n this.typeaheadBuffer = '';\n this.typeaheadResetHandle = null;\n }, TYPEAHEAD_RESET_MS);\n }\n}\n\n@Directive({\n selector: '[tngMenubarItem]',\n exportAs: 'tngMenubarItem',\n})\nexport class TngMenubarItem {\n private readonly hostRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly menubar = inject(TngMenubar, { host: true });\n private readonly resolvedId =\n this.hostRef.nativeElement.getAttribute('id') ?? createMenubarItemId();\n private lastOwnedMenu: TngMenu | null = null;\n\n readonly ownedMenu = input<TngMenu | null>(null, {\n alias: 'tngMenubarMenu',\n });\n\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'menubar-item' as const;\n\n @HostBinding('attr.role')\n protected readonly role = 'menuitem' as const;\n\n @HostBinding('attr.id')\n protected readonly id = this.resolvedId;\n\n @HostBinding('attr.tabindex')\n protected get tabIndex(): string {\n if (this.isDisabled()) {\n return '-1';\n }\n\n return this.menubar.getCurrentTabStopId() === this.id ? '0' : '-1';\n }\n\n @HostBinding('attr.aria-disabled')\n protected get ariaDisabled(): 'true' | null {\n return this.isDisabled() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-haspopup')\n protected get ariaHaspopup(): 'menu' | null {\n return this.ownedMenu() === null ? null : 'menu';\n }\n\n @HostBinding('attr.aria-controls')\n protected get ariaControls(): string | null {\n return this.ownedMenu()?.id ?? null;\n }\n\n ngOnInit(): void {\n this.syncHostId();\n this.lastOwnedMenu = this.ownedMenu();\n this.syncOwnedMenuLink();\n this.syncAriaExpanded();\n }\n\n ngDoCheck(): void {\n this.syncHostId();\n const currentOwnedMenu = this.ownedMenu();\n if (currentOwnedMenu === this.lastOwnedMenu) {\n return;\n }\n\n this.teardownOwnedMenuLink(this.lastOwnedMenu);\n this.lastOwnedMenu = currentOwnedMenu;\n this.syncOwnedMenuLink();\n this.syncAriaExpanded();\n }\n\n ngOnDestroy(): void {\n this.teardownOwnedMenuLink(this.lastOwnedMenu);\n }\n\n @HostListener('click')\n protected onClick(): void {\n if (this.ownedMenu() === null || this.isDisabled()) {\n return;\n }\n\n this.focusSelf();\n this.syncOwnedMenuLink();\n this.menubar.requestToggleMenu(this);\n }\n\n @HostListener('pointerdown')\n protected onPointerdown(): void {\n if (this.isDisabled()) {\n return;\n }\n\n this.focusSelf();\n }\n\n @HostListener('mouseenter')\n protected onMouseenter(): void {\n if (this.isDisabled()) {\n return;\n }\n\n this.menubar.setCurrentTabStop(this);\n\n if (!this.menubar.hasOpenItem() || this.menubar.isOpenItem(this) || this.ownedMenu() === null) {\n return;\n }\n\n this.syncOwnedMenuLink();\n this.menubar.requestOpenMenu(this, 'none');\n }\n\n @HostListener('focus')\n protected onFocus(): void {\n this.menubar.setCurrentTabStop(this);\n }\n\n @HostListener('keydown', ['$event'])\n protected onKeydown(event: KeyboardEvent): void {\n const ownedMenu = this.ownedMenu();\n if (!this.isDisabled() && ownedMenu?.isOpen() && event.key === 'Escape') {\n event.preventDefault();\n this.closeOwnedMenu(true);\n return;\n }\n\n if (\n !this.isDisabled() &&\n ownedMenu !== null &&\n (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown' || event.key === 'ArrowUp')\n ) {\n event.preventDefault();\n this.syncOwnedMenuLink();\n\n if (ownedMenu.isOpen() && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {\n ownedMenu.focusPanelAndMoveActiveItem(event.key === 'ArrowDown' ? 'next' : 'prev');\n return;\n }\n\n this.menubar.requestOpenMenu(this, event.key === 'ArrowDown' ? 'first' : event.key === 'ArrowUp' ? 'last' : 'none');\n return;\n }\n\n if (event.key === 'Tab') {\n if (ownedMenu?.isOpen()) {\n this.closeOwnedMenu(false);\n return;\n }\n return;\n }\n\n if (ownedMenu?.isOpen() && (event.key === 'ArrowRight' || event.key === 'ArrowLeft')) {\n event.preventDefault();\n this.handleArrowFromOpenMenu(event.key);\n return;\n }\n\n if (\n event.key !== 'ArrowRight' &&\n event.key !== 'ArrowLeft' &&\n event.key !== 'Home' &&\n event.key !== 'End'\n ) {\n if (event.key.length === 1 && !this.isDisabled()) {\n const match = this.menubar.findTypeaheadMatch(this.hostRef.nativeElement, event.key);\n if (match !== null) {\n event.preventDefault();\n match.focus();\n }\n }\n return;\n }\n\n const items = this.menubar.getEnabledItems();\n const current = this.hostRef.nativeElement;\n const currentIndex = items.indexOf(current);\n\n if (currentIndex < 0 || items.length === 0) {\n return;\n }\n\n event.preventDefault();\n\n if (event.key === 'Home') {\n items[0]?.focus();\n return;\n }\n\n if (event.key === 'End') {\n items[items.length - 1]?.focus();\n return;\n }\n\n const loop = this.menubar.loop();\n const moveToNext =\n event.key === (this.menubar.isRtl() ? 'ArrowLeft' : 'ArrowRight');\n const targetIndex =\n moveToNext\n ? currentIndex + 1 >= items.length\n ? loop\n ? 0\n : items.length - 1\n : currentIndex + 1\n : currentIndex - 1 < 0\n ? loop\n ? items.length - 1\n : 0\n : currentIndex - 1;\n\n items[targetIndex]?.focus();\n }\n\n isDisabledItem(): boolean {\n return this.isDisabled();\n }\n\n getOwnedMenu(): TngMenu | null {\n return this.ownedMenu();\n }\n\n openOwnedMenu(focusAction: 'none' | 'first' | 'last'): void {\n const ownedMenu = this.ownedMenu();\n if (ownedMenu === null) {\n return;\n }\n\n ownedMenu.open(focusAction);\n }\n\n closeOwnedMenu(restoreFocus: boolean): void {\n const ownedMenu = this.ownedMenu();\n if (ownedMenu === null) {\n return;\n }\n\n ownedMenu.close(restoreFocus);\n }\n\n focusSelf(): void {\n this.menubar.setCurrentTabStop(this);\n this.hostRef.nativeElement.focus();\n }\n\n getItemId(): string {\n return this.id;\n }\n\n handleArrowFromOpenMenu(key: 'ArrowRight' | 'ArrowLeft'): void {\n const items = this.menubar.getEnabledItems();\n const current = this.hostRef.nativeElement;\n const currentIndex = items.indexOf(current);\n\n if (currentIndex < 0 || items.length === 0) {\n return;\n }\n\n const moveToNext =\n key === (this.menubar.isRtl() ? 'ArrowLeft' : 'ArrowRight');\n const loop = this.menubar.loop();\n const targetIndex =\n moveToNext\n ? currentIndex + 1 >= items.length\n ? loop\n ? 0\n : items.length - 1\n : currentIndex + 1\n : currentIndex - 1 < 0\n ? loop\n ? items.length - 1\n : 0\n : currentIndex - 1;\n\n const target = items[targetIndex];\n if (target === undefined || target === current) {\n return;\n }\n\n const targetOwnsMenu = target.getAttribute('aria-haspopup') === 'menu';\n if (!targetOwnsMenu) {\n this.closeOwnedMenu(false);\n target.focus();\n return;\n }\n\n target.focus();\n target.click();\n }\n\n private isDisabled(): boolean {\n const element = this.hostRef.nativeElement as HTMLElement & {\n disabled?: boolean;\n };\n\n return element.disabled || element.hasAttribute('disabled');\n }\n\n private syncOwnedMenuLink(): void {\n const ownedMenu = this.ownedMenu();\n if (ownedMenu === null) {\n return;\n }\n\n this.syncHostId();\n ownedMenu.setTriggerElement(this.hostRef.nativeElement, () => this.syncMenuState());\n ownedMenu.setRestoreFocusOnOutsideClick(true);\n ownedMenu.setMenubarArrowHandler((key) => this.handleArrowFromOpenMenu(key));\n ownedMenu.setMenubarTabHandler(null);\n }\n\n private syncAriaExpanded(): void {\n const ownedMenu = this.ownedMenu();\n if (ownedMenu === null) {\n this.hostRef.nativeElement.removeAttribute('aria-expanded');\n return;\n }\n\n this.hostRef.nativeElement.setAttribute('aria-expanded', ownedMenu.isOpen() ? 'true' : 'false');\n }\n\n private syncMenuState(): void {\n this.syncAriaExpanded();\n this.menubar.syncOpenItem(this);\n }\n\n private teardownOwnedMenuLink(ownedMenu: TngMenu | null): void {\n if (ownedMenu === null) {\n return;\n }\n\n if (ownedMenu.isOpen()) {\n ownedMenu.close(false);\n }\n\n ownedMenu.clearTriggerLink(this.hostRef.nativeElement);\n }\n\n private syncHostId(): void {\n if (this.hostRef.nativeElement.id === this.id) {\n return;\n }\n\n this.hostRef.nativeElement.id = this.id;\n }\n}\n\n/**\n * Wrap each owned {@link TngMenu} and its {@link TngMenubarItem} so absolutely\n * positioned menu panels anchor to this element. The menu contract positions\n * root menus with `top: calc(100% + …)`; that percentage resolves against the\n * nearest positioned ancestor — this host provides it (see theme menubar.css).\n */\n@Directive({\n selector: '[tngMenubarGroup]',\n exportAs: 'tngMenubarGroup',\n})\nexport class TngMenubarGroup {\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'menubar-group' as const;\n}\n"]}
|