@star-ng/ui 0.1.0 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"star-ng-ui-select.mjs","names":[],"sources":["../../../projects/star-ng/select/cascade-select.ts","../../../projects/star-ng/select/option-list-base.ts","../../../projects/star-ng/select/multi-select.ts","../../../projects/star-ng/select/select.ts"],"sourcesContent":["import { _IdGenerator } from '@angular/cdk/a11y';\nimport { CdkMenuTrigger } from '@angular/cdk/menu';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n model,\n output,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\nimport {\n optionText,\n readOption,\n STAR_UI_TEXT,\n StarDirectionService,\n StarOptionKey,\n} from '@star-ng/ui/core';\nimport { STAR_MENU_POSITIONS, StarMenu, StarMenuInDialog, StarMenuItem } from '@star-ng/ui/menu';\n\ninterface Leaf<TOption, TValue> {\n readonly option: TOption;\n readonly value: TValue;\n /** Labels from the top level to the leaf. */\n readonly path: readonly string[];\n}\n\n/**\n * Cascade select (PrimeNG `p-cascadeselect`): choose one leaf of nested options, for example\n * country → state → city. The popup is a menu with submenus (CDK Menu: arrow keys, typeahead,\n * Escape). The value is the leaf (`optionValue`, or the whole option).\n *\n * ```html\n * <star-cascade-select [options]=\"countries\" optionLabel=\"name\" optionChildren=\"children\"\n * optionValue=\"code\" [(value)]=\"city\" showPath />\n * ```\n */\n@Component({\n selector: 'star-cascade-select',\n imports: [CdkMenuTrigger, StarMenu, StarMenuInDialog],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'star-select star-cascade',\n '[class.star-select--disabled]': 'disabled()',\n '[class.star-select--invalid]': 'invalid() && touched()',\n '[class.star-select--sm]': \"size() === 'sm'\",\n },\n template: `\n <div class=\"star-select__control\">\n <button\n #trigger=\"cdkMenuTriggerFor\"\n type=\"button\"\n class=\"star-select__trigger star-cascade__trigger\"\n [id]=\"inputId()\"\n [cdkMenuTriggerFor]=\"menu.template()\"\n [cdkMenuTriggerData]=\"{ $implicit: menuItems() }\"\n [cdkMenuPosition]=\"positions\"\n [disabled]=\"disabled() || readonly()\"\n [attr.aria-label]=\"triggerName()\"\n [attr.aria-invalid]=\"(invalid() && touched()) || null\"\n (cdkMenuClosed)=\"touch.emit()\"\n >\n @if (selected(); as leaf) {\n <span class=\"star-select__value\">{{ display(leaf) }}</span>\n } @else {\n <span class=\"star-select__placeholder\">{{\n placeholder() ?? text.selectPlaceholder\n }}</span>\n }\n </button>\n @if (showClear() && selected() && !disabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"star-select__icon-btn\"\n [attr.aria-label]=\"text.clear\"\n (click)=\"clear()\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n <i class=\"ph-bold ph-caret-down star-select__caret\" aria-hidden=\"true\"></i>\n </div>\n <star-menu #menu [ariaLabel]=\"ariaLabel()\" />\n `,\n})\nexport class StarCascadeSelect<\n TOption,\n TValue = TOption,\n> implements FormValueControl<TValue | null> {\n /** Keeps the CDK direction (overlays and menus) in step with `<html dir>`. */\n private readonly directionSync = inject(StarDirectionService);\n protected readonly text = inject(STAR_UI_TEXT);\n protected readonly positions = STAR_MENU_POSITIONS;\n\n readonly value = model<TValue | null>(null);\n readonly options = input<readonly TOption[]>([]);\n readonly optionLabel = input<StarOptionKey<TOption> | null>(null);\n /** Value stored in the form, read from the leaf. Omit to store the whole leaf option. */\n readonly optionValue = input<StarOptionKey<TOption> | null>(null);\n /** Property (or function) with the child options. An option without children is a leaf. */\n readonly optionChildren = input<StarOptionKey<TOption, readonly TOption[] | null | undefined>>(\n 'children' as StarOptionKey<TOption, readonly TOption[] | null | undefined>,\n );\n readonly optionDisabled = input<StarOptionKey<TOption> | null>(null);\n readonly compareWith = input<(a: TValue, b: TValue) => boolean>(Object.is);\n readonly placeholder = input<string | null>(null);\n /** Show the whole path (\"Germany / Bavaria / Munich\") instead of the leaf label. */\n readonly showPath = input(false, { transform: booleanAttribute });\n readonly showClear = input(false, { transform: booleanAttribute });\n readonly size = input<'sm' | 'md'>('md');\n readonly ariaLabel = input<string | null>(null);\n readonly inputId = input(inject(_IdGenerator).getId('star-cascade-'));\n\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly readonly = input(false, { transform: booleanAttribute });\n readonly required = input(false, { transform: booleanAttribute });\n readonly invalid = input(false, { transform: booleanAttribute });\n readonly touched = input(false, { transform: booleanAttribute });\n readonly touch = output<void>();\n /** The user chose a leaf. */\n readonly optionSelect = output<TOption>();\n\n private childrenOf(option: TOption): readonly TOption[] {\n const children = readOption(option, this.optionChildren());\n return Array.isArray(children) ? (children as readonly TOption[]) : [];\n }\n\n private labelOf(option: TOption): string {\n return optionText(option, this.optionLabel() ?? null);\n }\n\n /** Every leaf with its path, in display order. */\n private readonly leaves = computed(() => {\n const out: Leaf<TOption, TValue>[] = [];\n const walk = (options: readonly TOption[], path: readonly string[]) => {\n for (const option of options) {\n const next = [...path, this.labelOf(option)];\n const children = this.childrenOf(option);\n if (children.length) walk(children, next);\n else {\n out.push({\n option,\n value: readOption(option, this.optionValue()) as TValue,\n path: next,\n });\n }\n }\n };\n walk(this.options(), []);\n return out;\n });\n\n protected readonly selected = computed(() => {\n const value = this.value();\n if (value === null || value === undefined) return null;\n return this.leaves().find((leaf) => this.compareWith()(leaf.value, value)) ?? null;\n });\n\n /** The options as menu items: a parent opens a submenu, a leaf sets the value. */\n protected readonly menuItems = computed<readonly StarMenuItem[]>(() => {\n const disabledKey = this.optionDisabled();\n const selected = this.selected()?.option;\n const build = (options: readonly TOption[]): StarMenuItem[] =>\n options.map((option) => {\n const children = this.childrenOf(option);\n const disabled = disabledKey ? !!readOption(option, disabledKey) : false;\n return children.length\n ? { label: this.labelOf(option), disabled, items: build(children) }\n : {\n label: this.labelOf(option),\n disabled,\n icon: option === selected ? 'ph-bold ph-check' : undefined,\n command: () => this.choose(option),\n };\n });\n return build(this.options());\n });\n\n /**\n * Accessible name of the trigger button: the label and the text on the button, so the visible\n * text is part of the name (WCAG 2.5.3). `null` without `ariaLabel`: a `star-field` label then\n * names the button.\n */\n protected readonly triggerName = computed(() => {\n const label = this.ariaLabel();\n if (!label) return null;\n const leaf = this.selected();\n return `${label}: ${leaf ? this.display(leaf) : (this.placeholder() ?? this.text.selectPlaceholder)}`;\n });\n\n protected display(leaf: Leaf<TOption, TValue>): string {\n return this.showPath() ? leaf.path.join(' / ') : (leaf.path.at(-1) ?? '');\n }\n\n private choose(option: TOption): void {\n this.value.set(readOption(option, this.optionValue()) as TValue);\n this.optionSelect.emit(option);\n }\n\n clear(): void {\n this.value.set(null);\n }\n}\n","import { _IdGenerator } from '@angular/cdk/a11y';\nimport { ConnectedPosition } from '@angular/cdk/overlay';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n input,\n output,\n signal,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport {\n matchesFilter,\n optionText,\n readOption,\n STAR_UI_TEXT,\n StarDirectionService,\n StarOptionKey,\n} from '@star-ng/ui/core';\n\n/** Context of the custom option template: `<ng-template starOption let-option let-selected=\"selected\">`. */\nexport interface StarOptionContext<T> {\n readonly $implicit: T;\n readonly selected: boolean;\n readonly index: number;\n}\n\n/** Custom option row template for `star-select` and `star-multi-select`. */\n@Directive({ selector: 'ng-template[starOption]' })\nexport class StarOptionTemplate<T = unknown> {\n /** Optional: pass the options array to type `let-option` in strict templates. */\n readonly starOptionOf = input<readonly T[] | null>(null);\n readonly template = inject<TemplateRef<StarOptionContext<T>>>(TemplateRef);\n\n static ngTemplateContextGuard<T>(\n _dir: StarOptionTemplate<T>,\n _ctx: unknown,\n ): _ctx is StarOptionContext<T> {\n return true;\n }\n}\n\n/** One rendered line of the option list: a group heading or an option. */\nexport type StarListRow<T> =\n | { readonly kind: 'group'; readonly key: string; readonly label: string; readonly id: string }\n | {\n readonly kind: 'option';\n readonly key: string;\n readonly option: T;\n /** Index in the visible options (keyboard order). */\n readonly index: number;\n readonly groupId: string | null;\n };\n\n/** Lines rendered above and below the lines in view with `virtualScroll`. */\nconst VIRTUAL_BUFFER = 6;\n/** List height in pixels before the first scroll event gives the real height. */\nconst VIRTUAL_FALLBACK_HEIGHT = 256;\n\nconst PANEL_POSITIONS: ConnectedPosition[] = [\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 6 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -6 },\n];\n\n/**\n * Shared state and keyboard model of the dropdown list controls (WAI-ARIA combobox +\n * listbox with `aria-activedescendant`). Subclasses add the selection model.\n */\n@Directive()\nexport abstract class StarOptionListBase<TOption, TValue> {\n /** Keeps the CDK direction (overlays and menus) in step with `<html dir>`. */\n private readonly directionSync = inject(StarDirectionService);\n protected readonly text = inject(STAR_UI_TEXT);\n private readonly ids = inject(_IdGenerator);\n\n readonly options = input<readonly TOption[]>([]);\n readonly optionLabel = input<StarOptionKey<TOption> | null>(null);\n /** Value stored in the form. Omit to store the whole option. */\n readonly optionValue = input<StarOptionKey<TOption> | null>(null);\n readonly optionDisabled = input<StarOptionKey<TOption> | null>(null);\n /** Equality for values (default `Object.is`). Use for object values from the server. */\n readonly compareWith = input<(a: TValue, b: TValue) => boolean>(Object.is);\n /**\n * Group heading of an option (property name or function). Options with the same heading\n * show together under it, in the order in which the headings first appear.\n */\n readonly optionGroup = input<StarOptionKey<TOption> | null>(null);\n /**\n * Renders only the lines in view, for long option lists. Every line has the height\n * `virtualItemSize` and option text stays on one line.\n */\n readonly virtualScroll = input(false, { transform: booleanAttribute });\n /** Line height in pixels with `virtualScroll`. */\n readonly virtualItemSize = input(40);\n\n readonly placeholder = input<string | null>(null);\n readonly filter = input(false, { transform: booleanAttribute });\n readonly filterPlaceholder = input<string | null>(null);\n readonly showClear = input(false, { transform: booleanAttribute });\n readonly loading = input(false, { transform: booleanAttribute });\n readonly emptyMessage = input<string | null>(null);\n readonly scrollHeight = input('16rem');\n readonly size = input<'sm' | 'md'>('md');\n readonly ariaLabel = input<string | null>(null);\n readonly ariaLabelledBy = input<string | null>(null);\n readonly inputId = input(this.ids.getId('star-select-'));\n\n // Signal Forms state (bound by [formField]).\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly readonly = input(false, { transform: booleanAttribute });\n readonly required = input(false, { transform: booleanAttribute });\n readonly invalid = input(false, { transform: booleanAttribute });\n readonly touched = input(false, { transform: booleanAttribute });\n readonly name = input('');\n\n readonly touch = output<void>();\n readonly opened = output<void>();\n readonly closed = output<void>();\n readonly filterChange = output<string>();\n\n protected readonly optionTemplate = contentChild(StarOptionTemplate);\n protected readonly trigger = viewChild.required<ElementRef<HTMLElement>>('trigger');\n private readonly filterInput = viewChild<ElementRef<HTMLInputElement>>('filterInput');\n\n protected readonly positions = PANEL_POSITIONS;\n protected readonly listId = this.ids.getId('star-listbox-');\n protected readonly open = signal(false);\n protected readonly filterValue = signal('');\n protected readonly activeIndex = signal(-1);\n protected readonly showInvalid = computed(() => this.invalid() && this.touched());\n protected readonly interactive = computed(() => !this.disabled() && !this.readonly());\n\n protected readonly visibleOptions = computed(() => {\n const query = this.filterValue();\n const all = this.options();\n const options =\n !this.filter() || !query\n ? all\n : all.filter((option) => matchesFilter(this.labelOf(option), query));\n return this.groupedOrder(options);\n });\n\n /** With `optionGroup`: keeps each group together, in the order the groups first appear. */\n protected groupedOrder(options: readonly TOption[]): readonly TOption[] {\n if (!this.optionGroup()) return options;\n const order = new Map<string, number>();\n for (const option of options) {\n const group = this.groupOf(option);\n if (!order.has(group)) order.set(group, order.size);\n }\n return options\n .map((option, index) => ({ option, index, rank: order.get(this.groupOf(option)) ?? 0 }))\n .sort((a, b) => a.rank - b.rank || a.index - b.index)\n .map(({ option }) => option);\n }\n\n /** Group headings and options, in display order. */\n protected readonly rows = computed<readonly StarListRow<TOption>[]>(() => {\n const grouped = !!this.optionGroup();\n const rows: StarListRow<TOption>[] = [];\n let current: string | null = null;\n let groupId: string | null = null;\n this.visibleOptions().forEach((option, index) => {\n if (grouped) {\n const label = this.groupOf(option);\n if (label !== current) {\n current = label;\n groupId = `${this.listId}-group-${rows.length}`;\n rows.push({ kind: 'group', key: `g:${label}`, label, id: groupId });\n }\n }\n rows.push({ kind: 'option', key: `o:${index}`, option, index, groupId });\n });\n return rows;\n });\n\n private readonly listScrollTop = signal(0);\n private readonly listHeight = signal(0);\n\n /** First and last rendered line, and the heights of the lines left out. */\n protected readonly virtualWindow = computed(() => {\n const count = this.rows().length;\n if (!this.virtualScroll()) return { start: 0, end: count, before: 0, after: 0 };\n const size = Math.max(1, this.virtualItemSize());\n const visible = Math.ceil((this.listHeight() || VIRTUAL_FALLBACK_HEIGHT) / size);\n const first = Math.min(Math.floor(this.listScrollTop() / size), Math.max(0, count - visible));\n const start = Math.max(0, first - VIRTUAL_BUFFER);\n const end = Math.min(count, first + visible + VIRTUAL_BUFFER);\n return { start, end, before: start * size, after: (count - end) * size };\n });\n\n protected readonly renderedRows = computed(() => {\n const rows = this.rows();\n const { start, end } = this.virtualWindow();\n return start === 0 && end === rows.length ? rows : rows.slice(start, end);\n });\n\n protected onListScroll(event: Event): void {\n if (!this.virtualScroll()) return;\n const list = event.target as HTMLElement;\n this.listScrollTop.set(list.scrollTop);\n this.listHeight.set(list.clientHeight);\n }\n\n protected readonly activeId = computed(() =>\n this.open() && this.activeIndex() >= 0 ? this.optionId(this.activeIndex()) : null,\n );\n\n protected readonly emptyText = computed(() =>\n this.filterValue()\n ? this.text.emptyFilterMessage\n : (this.emptyMessage() ?? this.text.emptyMessage),\n );\n\n private typeahead = '';\n private typeaheadTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => clearTimeout(this.typeaheadTimer));\n }\n\n /** True when the option is part of the current value. */\n protected abstract isSelected(option: TOption): boolean;\n /** Applies the user's choice of an option. */\n protected abstract choose(option: TOption): void;\n /** Index to highlight when the panel opens. */\n protected abstract initialActiveIndex(): number;\n /** Whether choosing an option closes the panel. */\n protected abstract readonly closeOnChoose: boolean;\n\n labelOf(option: TOption): string {\n return optionText(option, this.optionLabel() ?? null);\n }\n\n protected groupOf(option: TOption): string {\n const key = this.optionGroup();\n const group = key ? readOption(option, key) : null;\n return group === null || group === undefined ? '' : String(group);\n }\n\n protected valueOf(option: TOption): TValue {\n return readOption(option, this.optionValue()) as TValue;\n }\n\n protected isDisabled(option: TOption): boolean {\n const key = this.optionDisabled();\n return key ? !!readOption(option, key) : false;\n }\n\n protected equals(a: TValue, b: TValue): boolean {\n return this.compareWith()(a, b);\n }\n\n protected optionId(index: number): string {\n return `${this.listId}-${index}`;\n }\n\n protected optionContext(option: TOption, index: number): StarOptionContext<TOption> {\n return { $implicit: option, selected: this.isSelected(option), index };\n }\n\n openPanel(): void {\n if (!this.interactive() || this.open()) return;\n this.open.set(true);\n this.activeIndex.set(this.initialActiveIndex());\n this.opened.emit();\n }\n\n closePanel(focusTrigger = true): void {\n if (!this.open()) return;\n this.open.set(false);\n this.activeIndex.set(-1);\n this.listScrollTop.set(0);\n if (this.filterValue()) {\n this.filterValue.set('');\n this.filterChange.emit('');\n }\n if (focusTrigger) this.trigger().nativeElement.focus();\n this.closed.emit();\n }\n\n protected toggle(): void {\n if (this.open()) this.closePanel();\n else this.openPanel();\n }\n\n focus(options?: FocusOptions): void {\n this.trigger().nativeElement.focus(options);\n }\n\n protected onPanelAttached(): void {\n this.filterInput()?.nativeElement.focus();\n this.scrollActiveIntoView();\n }\n\n protected onOutsideClick(event: MouseEvent): void {\n // Clicks on the trigger are handled by its own (click) toggle.\n if (this.trigger().nativeElement.contains(event.target as Node)) return;\n this.closePanel(false);\n this.touch.emit();\n }\n\n /** Keeps focus on the trigger (or filter) while the user clicks inside the panel. */\n protected onPanelMousedown(event: MouseEvent): void {\n if (!(event.target instanceof HTMLInputElement)) event.preventDefault();\n }\n\n protected onTriggerBlur(): void {\n if (!this.open()) this.touch.emit();\n }\n\n protected onFilterInput(value: string): void {\n this.filterValue.set(value);\n this.filterChange.emit(value);\n this.listScrollTop.set(0);\n this.activeIndex.set(this.firstEnabledFrom(0, 1));\n }\n\n protected onOptionClick(option: TOption, index: number): void {\n if (this.isDisabled(option)) return;\n this.activeIndex.set(index);\n this.choose(option);\n if (this.closeOnChoose) this.closePanel();\n }\n\n /** Keyboard model for both the trigger and the filter input. */\n protected onKeydown(event: KeyboardEvent): void {\n if (!this.interactive()) return;\n const open = this.open();\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp': {\n event.preventDefault();\n if (!open) {\n this.openPanel();\n return;\n }\n const step = event.key === 'ArrowDown' ? 1 : -1;\n if (event.altKey && step === -1) {\n this.chooseActive();\n this.closePanel();\n return;\n }\n this.moveActive(step);\n return;\n }\n case 'Home':\n case 'End':\n if (!open) return;\n event.preventDefault();\n this.activeIndex.set(\n event.key === 'Home'\n ? this.firstEnabledFrom(0, 1)\n : this.firstEnabledFrom(this.visibleOptions().length - 1, -1),\n );\n this.scrollActiveIntoView();\n return;\n case 'Enter':\n event.preventDefault();\n if (!open) this.openPanel();\n else this.chooseActive(this.closeOnChoose);\n return;\n case ' ':\n // Space types into the filter field.\n if (event.target instanceof HTMLInputElement) return;\n event.preventDefault();\n if (!open) this.openPanel();\n else this.chooseActive(this.closeOnChoose);\n return;\n case 'Escape':\n if (open) {\n event.preventDefault();\n event.stopPropagation();\n this.closePanel();\n }\n return;\n case 'Tab':\n if (open) this.closePanel(false);\n return;\n default:\n if (\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey &&\n !(event.target instanceof HTMLInputElement)\n ) {\n this.runTypeahead(event.key);\n }\n }\n }\n\n private chooseActive(thenClose = false): void {\n const option = this.visibleOptions()[this.activeIndex()];\n if (option === undefined || this.isDisabled(option)) return;\n this.choose(option);\n if (thenClose) this.closePanel();\n }\n\n private moveActive(step: 1 | -1): void {\n const count = this.visibleOptions().length;\n if (!count) return;\n const start = this.activeIndex() < 0 ? (step === 1 ? 0 : count - 1) : this.activeIndex() + step;\n const next = this.firstEnabledFrom(Math.min(Math.max(start, 0), count - 1), step);\n if (next >= 0) this.activeIndex.set(next);\n this.scrollActiveIntoView();\n }\n\n protected firstEnabledFrom(start: number, step: 1 | -1): number {\n const options = this.visibleOptions();\n for (let i = start; i >= 0 && i < options.length; i += step) {\n if (!this.isDisabled(options[i])) return i;\n }\n return -1;\n }\n\n /** Type a letter to jump to the next option whose label starts with the typed text. */\n private runTypeahead(char: string): void {\n clearTimeout(this.typeaheadTimer);\n this.typeahead += char.toLocaleLowerCase();\n this.typeaheadTimer = setTimeout(() => (this.typeahead = ''), 500);\n const options = this.visibleOptions();\n const start = Math.max(this.activeIndex(), 0);\n const ordered = [...options.keys()].map(\n (i) => (start + (this.typeahead.length === 1 ? 1 : 0) + i) % options.length,\n );\n const match = ordered.find(\n (i) =>\n !this.isDisabled(options[i]) &&\n this.labelOf(options[i]).toLocaleLowerCase().startsWith(this.typeahead),\n );\n if (match === undefined) return;\n this.activeIndex.set(match);\n if (!this.open() && this.closeOnChoose) this.choose(options[match]);\n this.scrollActiveIntoView();\n }\n\n private scrollActiveIntoView(): void {\n const id = this.activeId();\n if (!id) return;\n if (this.virtualScroll()) {\n // The active line may not be rendered yet: move the list so its position is in view.\n const active = this.activeIndex();\n const line = this.rows().findIndex((row) => row.kind === 'option' && row.index === active);\n const list = this.trigger().nativeElement.ownerDocument.getElementById(this.listId);\n if (line < 0 || !list) return;\n const size = Math.max(1, this.virtualItemSize());\n const height = list.clientHeight || VIRTUAL_FALLBACK_HEIGHT;\n const top = line * size;\n let scrollTop = this.listScrollTop();\n if (top < scrollTop) scrollTop = top;\n else if (top + size > scrollTop + height) scrollTop = top + size - height;\n this.listScrollTop.set(scrollTop);\n this.listHeight.set(height);\n queueMicrotask(() => (list.scrollTop = scrollTop));\n return;\n }\n queueMicrotask(() =>\n this.trigger()\n .nativeElement.ownerDocument.getElementById(id)\n ?.scrollIntoView?.({ block: 'nearest' }),\n );\n }\n}\n","import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input, model } from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\nimport { StarOptionListBase } from './option-list-base';\n\n/**\n * Multiple-choice dropdown (PrimeNG `p-multiselect`): checkbox list, \"select all\", filter,\n * chip or comma display, `maxSelectedLabels`, `selectionLimit` and clear. Same keyboard model\n * as `star-select`; Enter / Space toggle the active option and keep the panel open.\n *\n * `<star-multi-select [options]=\"tags\" optionLabel=\"name\" optionValue=\"id\" [(value)]=\"ids\" display=\"chip\" filter />`\n */\n@Component({\n selector: 'star-multi-select',\n imports: [CdkConnectedOverlay, CdkOverlayOrigin, NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'star-select star-select--multi',\n '[class.star-select--open]': 'open()',\n '[class.star-select--disabled]': 'disabled()',\n '[class.star-select--invalid]': 'showInvalid()',\n '[class.star-select--sm]': \"size() === 'sm'\",\n },\n template: `\n <div class=\"star-select__control\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\n <div\n #trigger\n class=\"star-select__trigger\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [id]=\"inputId()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? listId : null\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-readonly]=\"readonly() || null\"\n (click)=\"toggle()\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onTriggerBlur()\"\n >\n @if (selectedOptions().length === 0) {\n <span class=\"star-select__placeholder\">{{\n placeholder() ?? text.selectPlaceholder\n }}</span>\n } @else if (collapsed()) {\n <span class=\"star-select__value\">{{ text.selectedItems(selectedOptions().length) }}</span>\n } @else if (display() === 'chip') {\n <span class=\"star-select__chips\">\n @for (option of selectedOptions(); track $index) {\n <span class=\"star-chip star-chip--sm\">\n {{ labelOf(option) }}\n @if (interactive()) {\n <button\n type=\"button\"\n class=\"star-chip__remove\"\n tabindex=\"-1\"\n [attr.aria-label]=\"text.removeItem(labelOf(option))\"\n (click)=\"$event.stopPropagation(); remove(option)\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n </span>\n }\n </span>\n } @else {\n <span class=\"star-select__value\">{{ selectedLabels() }}</span>\n }\n </div>\n @if (showClear() && selectedOptions().length && interactive()) {\n <button\n type=\"button\"\n class=\"star-select__icon-btn\"\n [attr.aria-label]=\"text.clear\"\n (click)=\"clear()\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (loading()) {\n <i\n class=\"ph-bold ph-spinner-gap star-spin star-select__caret\"\n role=\"img\"\n [attr.aria-label]=\"text.loading\"\n ></i>\n } @else {\n <i class=\"ph-bold ph-caret-down star-select__caret\" aria-hidden=\"true\"></i>\n }\n </div>\n\n <ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayUsePopover=\"inline\"\n cdkConnectedOverlayMatchWidth\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n (attach)=\"onPanelAttached()\"\n (detach)=\"closePanel(false)\"\n (overlayOutsideClick)=\"onOutsideClick($event)\"\n >\n <div class=\"star-panel\" (mousedown)=\"onPanelMousedown($event)\">\n @if (showToggleAll() || filter()) {\n <div class=\"star-panel__filter\">\n @if (showToggleAll() && !selectionLimit()) {\n <button\n type=\"button\"\n class=\"star-panel__toggle-all\"\n role=\"checkbox\"\n tabindex=\"-1\"\n [attr.aria-checked]=\"allState()\"\n [attr.aria-label]=\"text.selectAll\"\n (click)=\"toggleAll()\"\n >\n <span class=\"star-check__box\" aria-hidden=\"true\">\n @if (allState() === 'mixed') {\n <i class=\"ph-bold ph-minus\"></i>\n } @else if (allState() === true) {\n <i class=\"ph-bold ph-check\"></i>\n }\n </span>\n </button>\n }\n @if (filter()) {\n <i class=\"ph-bold ph-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n #filterInput\n type=\"text\"\n class=\"star-input star-input--sm\"\n role=\"searchbox\"\n autocomplete=\"off\"\n [value]=\"filterValue()\"\n [attr.placeholder]=\"filterPlaceholder() ?? text.filterPlaceholder\"\n [attr.aria-label]=\"filterPlaceholder() ?? text.filterPlaceholder\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-activedescendant]=\"activeId()\"\n (input)=\"onFilterInput(filterInput.value)\"\n (keydown)=\"onKeydown($event)\"\n />\n } @else {\n <span class=\"star-panel__toggle-label\">{{ text.selectAll }}</span>\n }\n </div>\n }\n <ul\n class=\"star-listbox\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [id]=\"listId\"\n [class.star-listbox--virtual]=\"virtualScroll()\"\n [style.--star-item-size.px]=\"virtualScroll() ? virtualItemSize() : null\"\n [style.max-height]=\"scrollHeight()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n (scroll)=\"onListScroll($event)\"\n >\n @if (virtualWindow().before) {\n <li\n class=\"star-listbox__spacer\"\n role=\"presentation\"\n [style.height.px]=\"virtualWindow().before\"\n ></li>\n }\n @for (row of renderedRows(); track row.key) {\n @if (row.kind === 'group') {\n <li class=\"star-listbox__group\" role=\"presentation\" [id]=\"row.id\">{{ row.label }}</li>\n } @else {\n @let option = row.option;\n @let i = row.index;\n <!-- Keyboard is handled on the combobox via aria-activedescendant (WAI-ARIA combobox pattern). -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <li\n class=\"star-listbox__option\"\n role=\"option\"\n [id]=\"optionId(i)\"\n [class.star-listbox__option--active]=\"activeIndex() === i\"\n [class.star-listbox__option--selected]=\"isSelected(option)\"\n [attr.aria-selected]=\"isSelected(option)\"\n [attr.aria-disabled]=\"isDisabled(option) || null\"\n [attr.aria-describedby]=\"row.groupId\"\n [attr.aria-setsize]=\"virtualScroll() ? visibleOptions().length : null\"\n [attr.aria-posinset]=\"virtualScroll() ? i + 1 : null\"\n (click)=\"onOptionClick(option, i)\"\n (mousemove)=\"isDisabled(option) || activeIndex.set(i)\"\n >\n <span class=\"star-check__box\" aria-hidden=\"true\">\n @if (isSelected(option)) {\n <i class=\"ph-bold ph-check\"></i>\n }\n </span>\n <span class=\"star-listbox__label\">\n @if (optionTemplate(); as custom) {\n <ng-container\n *ngTemplateOutlet=\"custom.template; context: optionContext(option, i)\"\n />\n } @else {\n {{ labelOf(option) }}\n }\n </span>\n </li>\n }\n } @empty {\n <li class=\"star-listbox__empty\" role=\"presentation\">{{ emptyText() }}</li>\n }\n @if (virtualWindow().after) {\n <li\n class=\"star-listbox__spacer\"\n role=\"presentation\"\n [style.height.px]=\"virtualWindow().after\"\n ></li>\n }\n </ul>\n </div>\n </ng-template>\n `,\n})\nexport class StarMultiSelect<TOption = unknown, TValue = TOption>\n extends StarOptionListBase<TOption, TValue>\n implements FormValueControl<readonly TValue[]>\n{\n readonly value = model<readonly TValue[]>([]);\n /** `comma`: \"A, B, C\". `chip`: removable chips. */\n readonly display = input<'comma' | 'chip'>('comma');\n /** Above this count the trigger shows \"{n} items selected\". */\n readonly maxSelectedLabels = input(3);\n /** Maximum number of selected items (0 = no limit). Hides \"select all\". */\n readonly selectionLimit = input(0);\n readonly showToggleAll = input(true);\n\n protected readonly closeOnChoose = false;\n\n protected readonly selectedOptions = computed(() =>\n this.options().filter((option) => this.isSelected(option)),\n );\n protected readonly collapsed = computed(\n () => this.selectedOptions().length > this.maxSelectedLabels(),\n );\n protected readonly selectedLabels = computed(() =>\n this.selectedOptions()\n .map((option) => this.labelOf(option))\n .join(', '),\n );\n\n private readonly selectableVisible = computed(() =>\n this.visibleOptions().filter((option) => !this.isDisabled(option)),\n );\n\n /** `true`, `false` or `'mixed'` for the \"select all\" box (over visible, enabled options). */\n protected readonly allState = computed<boolean | 'mixed'>(() => {\n const options = this.selectableVisible();\n const selected = options.filter((option) => this.isSelected(option)).length;\n if (!options.length || selected === 0) return false;\n return selected === options.length ? true : 'mixed';\n });\n\n protected isSelected(option: TOption): boolean {\n const optionValue = this.valueOf(option);\n return this.value().some((value) => this.equals(value, optionValue));\n }\n\n protected choose(option: TOption): void {\n if (this.isSelected(option)) {\n this.remove(option);\n return;\n }\n const limit = this.selectionLimit();\n if (limit > 0 && this.value().length >= limit) return;\n this.value.update((values) => [...values, this.valueOf(option)]);\n }\n\n protected initialActiveIndex(): number {\n return this.firstEnabledFrom(0, 1);\n }\n\n remove(option: TOption): void {\n const optionValue = this.valueOf(option);\n this.value.update((values) => values.filter((value) => !this.equals(value, optionValue)));\n }\n\n protected toggleAll(): void {\n const options = this.selectableVisible();\n if (this.allState() === true) {\n const visibleValues = options.map((option) => this.valueOf(option));\n this.value.update((values) =>\n values.filter((value) => !visibleValues.some((visible) => this.equals(visible, value))),\n );\n return;\n }\n const additions = options\n .filter((option) => !this.isSelected(option))\n .map((option) => this.valueOf(option));\n this.value.update((values) => [...values, ...additions]);\n }\n\n clear(): void {\n this.value.set([]);\n this.focus();\n }\n}\n","import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, model } from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\nimport { StarOptionListBase } from './option-list-base';\n\n/**\n * Single-choice dropdown (PrimeNG `p-select`): typed options, `optionLabel` / `optionValue` /\n * `optionDisabled`, filter, clear button, loading state, typeahead and full keyboard support\n * (WAI-ARIA select-only combobox). The panel is a native popover, so it also works inside\n * modal `star-dialog`s.\n *\n * ```html\n * <star-select [options]=\"countries\" optionLabel=\"name\" optionValue=\"code\"\n * [formField]=\"form.country\" filter showClear placeholder=\"Country\" />\n * ```\n */\n@Component({\n selector: 'star-select',\n imports: [CdkConnectedOverlay, CdkOverlayOrigin, NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'star-select',\n '[class.star-select--open]': 'open()',\n '[class.star-select--disabled]': 'disabled()',\n '[class.star-select--invalid]': 'showInvalid()',\n '[class.star-select--sm]': \"size() === 'sm'\",\n },\n template: `\n <div class=\"star-select__control\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\n <div\n #trigger\n class=\"star-select__trigger\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [id]=\"inputId()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? listId : null\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-readonly]=\"readonly() || null\"\n (click)=\"toggle()\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onTriggerBlur()\"\n >\n @if (selectedOption(); as option) {\n <span class=\"star-select__value\">{{ labelOf(option) }}</span>\n } @else {\n <span class=\"star-select__placeholder\">{{\n placeholder() ?? text.selectPlaceholder\n }}</span>\n }\n </div>\n @if (showClear() && selectedOption() !== undefined && interactive()) {\n <button\n type=\"button\"\n class=\"star-select__icon-btn\"\n [attr.aria-label]=\"text.clear\"\n (click)=\"clear()\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (loading()) {\n <i\n class=\"ph-bold ph-spinner-gap star-spin star-select__caret\"\n role=\"img\"\n [attr.aria-label]=\"text.loading\"\n ></i>\n } @else {\n <i class=\"ph-bold ph-caret-down star-select__caret\" aria-hidden=\"true\"></i>\n }\n </div>\n\n <ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayUsePopover=\"inline\"\n cdkConnectedOverlayMatchWidth\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n (attach)=\"onPanelAttached()\"\n (detach)=\"closePanel(false)\"\n (overlayOutsideClick)=\"onOutsideClick($event)\"\n >\n <div class=\"star-panel\" (mousedown)=\"onPanelMousedown($event)\">\n @if (filter()) {\n <div class=\"star-panel__filter\">\n <i class=\"ph-bold ph-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n #filterInput\n type=\"text\"\n class=\"star-input star-input--sm\"\n role=\"searchbox\"\n autocomplete=\"off\"\n [value]=\"filterValue()\"\n [attr.placeholder]=\"filterPlaceholder() ?? text.filterPlaceholder\"\n [attr.aria-label]=\"filterPlaceholder() ?? text.filterPlaceholder\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-activedescendant]=\"activeId()\"\n (input)=\"onFilterInput(filterInput.value)\"\n (keydown)=\"onKeydown($event)\"\n />\n </div>\n }\n <ul\n class=\"star-listbox\"\n role=\"listbox\"\n [id]=\"listId\"\n [class.star-listbox--virtual]=\"virtualScroll()\"\n [style.--star-item-size.px]=\"virtualScroll() ? virtualItemSize() : null\"\n [style.max-height]=\"scrollHeight()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n (scroll)=\"onListScroll($event)\"\n >\n @if (virtualWindow().before) {\n <li\n class=\"star-listbox__spacer\"\n role=\"presentation\"\n [style.height.px]=\"virtualWindow().before\"\n ></li>\n }\n @for (row of renderedRows(); track row.key) {\n @if (row.kind === 'group') {\n <li class=\"star-listbox__group\" role=\"presentation\" [id]=\"row.id\">{{ row.label }}</li>\n } @else {\n @let option = row.option;\n @let i = row.index;\n <!-- Keyboard is handled on the combobox via aria-activedescendant (WAI-ARIA combobox pattern). -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <li\n class=\"star-listbox__option\"\n role=\"option\"\n [id]=\"optionId(i)\"\n [class.star-listbox__option--active]=\"activeIndex() === i\"\n [class.star-listbox__option--selected]=\"isSelected(option)\"\n [attr.aria-selected]=\"isSelected(option)\"\n [attr.aria-disabled]=\"isDisabled(option) || null\"\n [attr.aria-describedby]=\"row.groupId\"\n [attr.aria-setsize]=\"virtualScroll() ? visibleOptions().length : null\"\n [attr.aria-posinset]=\"virtualScroll() ? i + 1 : null\"\n (click)=\"onOptionClick(option, i)\"\n (mousemove)=\"isDisabled(option) || activeIndex.set(i)\"\n >\n <span class=\"star-listbox__label\">\n @if (optionTemplate(); as custom) {\n <ng-container\n *ngTemplateOutlet=\"custom.template; context: optionContext(option, i)\"\n />\n } @else {\n {{ labelOf(option) }}\n }\n </span>\n @if (isSelected(option)) {\n <i class=\"ph-bold ph-check star-listbox__check\" aria-hidden=\"true\"></i>\n }\n </li>\n }\n } @empty {\n <li class=\"star-listbox__empty\" role=\"presentation\">{{ emptyText() }}</li>\n }\n @if (virtualWindow().after) {\n <li\n class=\"star-listbox__spacer\"\n role=\"presentation\"\n [style.height.px]=\"virtualWindow().after\"\n ></li>\n }\n </ul>\n </div>\n </ng-template>\n `,\n})\nexport class StarSelect<TOption = unknown, TValue = TOption>\n extends StarOptionListBase<TOption, TValue>\n implements FormValueControl<TValue | null>\n{\n readonly value = model<TValue | null>(null);\n\n protected readonly closeOnChoose = true;\n\n /** The option that matches the current value, or `undefined`. */\n protected readonly selectedOption = computed(() => {\n const value = this.value();\n if (value === null) return undefined;\n return this.options().find((option) => this.equals(this.valueOf(option), value));\n });\n\n protected isSelected(option: TOption): boolean {\n const value = this.value();\n return value !== null && this.equals(this.valueOf(option), value);\n }\n\n protected choose(option: TOption): void {\n this.value.set(this.valueOf(option));\n }\n\n protected initialActiveIndex(): number {\n const index = this.visibleOptions().findIndex((option) => this.isSelected(option));\n return index >= 0 ? index : this.firstEnabledFrom(0, 1);\n }\n\n clear(): void {\n this.value.set(null);\n this.focus();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"star-ng-ui-select.mjs","names":[],"sources":["../../../projects/star-ng/select/cascade-select.ts","../../../projects/star-ng/select/option-list-base.ts","../../../projects/star-ng/select/multi-select.ts","../../../projects/star-ng/select/select.ts"],"sourcesContent":["import { _IdGenerator } from '@angular/cdk/a11y';\nimport { CdkMenuTrigger } from '@angular/cdk/menu';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n model,\n output,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\nimport {\n optionText,\n readOption,\n STAR_UI_TEXT,\n StarDirectionService,\n StarOptionKey,\n} from '@star-ng/ui/core';\nimport { STAR_MENU_POSITIONS, StarMenu, StarMenuInDialog, StarMenuItem } from '@star-ng/ui/menu';\n\ninterface Leaf<TOption, TValue> {\n readonly option: TOption;\n readonly value: TValue;\n /** Labels from the top level to the leaf. */\n readonly path: readonly string[];\n}\n\n/**\n * Cascade select (PrimeNG `p-cascadeselect`): choose one leaf of nested options, for example\n * country → state → city. The popup is a menu with submenus (CDK Menu: arrow keys, typeahead,\n * Escape). The value is the leaf (`optionValue`, or the whole option).\n *\n * ```html\n * <star-cascade-select [options]=\"countries\" optionLabel=\"name\" optionChildren=\"children\"\n * optionValue=\"code\" [(value)]=\"city\" showPath />\n * ```\n */\n@Component({\n selector: 'star-cascade-select',\n imports: [CdkMenuTrigger, StarMenu, StarMenuInDialog],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'star-select star-cascade',\n '[class.star-select--disabled]': 'disabled()',\n '[class.star-select--invalid]': 'invalid() && touched()',\n '[class.star-select--sm]': \"size() === 'sm'\",\n },\n template: `\n <div class=\"star-select__control\">\n <button\n #trigger=\"cdkMenuTriggerFor\"\n type=\"button\"\n class=\"star-select__trigger star-cascade__trigger\"\n [id]=\"inputId()\"\n [cdkMenuTriggerFor]=\"menu.template()\"\n [cdkMenuTriggerData]=\"{ $implicit: menuItems() }\"\n [cdkMenuPosition]=\"positions\"\n [disabled]=\"disabled() || readonly()\"\n [attr.aria-label]=\"triggerName()\"\n [attr.aria-invalid]=\"(invalid() && touched()) || null\"\n (cdkMenuClosed)=\"touch.emit()\"\n >\n @if (selected(); as leaf) {\n <span class=\"star-select__value\">{{ display(leaf) }}</span>\n } @else {\n <span class=\"star-select__placeholder\">{{\n placeholder() ?? text.selectPlaceholder\n }}</span>\n }\n </button>\n @if (showClear() && selected() && !disabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"star-select__icon-btn\"\n [attr.aria-label]=\"text.clear\"\n (click)=\"clear()\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n <i class=\"ph-bold ph-caret-down star-select__caret\" aria-hidden=\"true\"></i>\n </div>\n <star-menu #menu [ariaLabel]=\"ariaLabel()\" />\n `,\n})\nexport class StarCascadeSelect<\n TOption,\n TValue = TOption,\n> implements FormValueControl<TValue | null> {\n /** Keeps the CDK direction (overlays and menus) in step with `<html dir>`. */\n private readonly directionSync = inject(StarDirectionService);\n protected readonly text = inject(STAR_UI_TEXT);\n protected readonly positions = STAR_MENU_POSITIONS;\n\n readonly value = model<TValue | null>(null);\n readonly options = input<readonly TOption[]>([]);\n readonly optionLabel = input<StarOptionKey<TOption> | null>(null);\n /** Value stored in the form, read from the leaf. Omit to store the whole leaf option. */\n readonly optionValue = input<StarOptionKey<TOption> | null>(null);\n /** Property (or function) with the child options. An option without children is a leaf. */\n readonly optionChildren = input<StarOptionKey<TOption, readonly TOption[] | null | undefined>>(\n 'children' as StarOptionKey<TOption, readonly TOption[] | null | undefined>,\n );\n readonly optionDisabled = input<StarOptionKey<TOption> | null>(null);\n readonly compareWith = input<(a: TValue, b: TValue) => boolean>(Object.is);\n readonly placeholder = input<string | null>(null);\n /** Show the whole path (\"Germany / Bavaria / Munich\") instead of the leaf label. */\n readonly showPath = input(false, { transform: booleanAttribute });\n readonly showClear = input(false, { transform: booleanAttribute });\n readonly size = input<'sm' | 'md'>('md');\n readonly ariaLabel = input<string | null>(null);\n readonly inputId = input(inject(_IdGenerator).getId('star-cascade-'));\n\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly readonly = input(false, { transform: booleanAttribute });\n readonly required = input(false, { transform: booleanAttribute });\n readonly invalid = input(false, { transform: booleanAttribute });\n readonly touched = input(false, { transform: booleanAttribute });\n readonly touch = output<void>();\n /** The user chose a leaf. */\n readonly optionSelect = output<TOption>();\n\n private childrenOf(option: TOption): readonly TOption[] {\n const children = readOption(option, this.optionChildren());\n return Array.isArray(children) ? (children as readonly TOption[]) : [];\n }\n\n private labelOf(option: TOption): string {\n return optionText(option, this.optionLabel() ?? null);\n }\n\n /** Every leaf with its path, in display order. */\n private readonly leaves = computed(() => {\n const out: Leaf<TOption, TValue>[] = [];\n const walk = (options: readonly TOption[], path: readonly string[]) => {\n for (const option of options) {\n const next = [...path, this.labelOf(option)];\n const children = this.childrenOf(option);\n if (children.length) walk(children, next);\n else {\n out.push({\n option,\n value: readOption(option, this.optionValue()) as TValue,\n path: next,\n });\n }\n }\n };\n walk(this.options(), []);\n return out;\n });\n\n protected readonly selected = computed(() => {\n const value = this.value();\n if (value === null || value === undefined) return null;\n return this.leaves().find((leaf) => this.compareWith()(leaf.value, value)) ?? null;\n });\n\n /** The options as menu items: a parent opens a submenu, a leaf sets the value. */\n protected readonly menuItems = computed<readonly StarMenuItem[]>(() => {\n const disabledKey = this.optionDisabled();\n const selected = this.selected()?.option;\n const build = (options: readonly TOption[]): StarMenuItem[] =>\n options.map((option) => {\n const children = this.childrenOf(option);\n const disabled = disabledKey ? !!readOption(option, disabledKey) : false;\n return children.length\n ? { label: this.labelOf(option), disabled, items: build(children) }\n : {\n label: this.labelOf(option),\n disabled,\n icon: option === selected ? 'ph-bold ph-check' : undefined,\n command: () => this.choose(option),\n };\n });\n return build(this.options());\n });\n\n /**\n * Accessible name of the trigger button: the label and the text on the button, so the visible\n * text is part of the name (WCAG 2.5.3). `null` without `ariaLabel`: a `star-field` label then\n * names the button.\n */\n protected readonly triggerName = computed(() => {\n const label = this.ariaLabel();\n if (!label) return null;\n const leaf = this.selected();\n return `${label}: ${leaf ? this.display(leaf) : (this.placeholder() ?? this.text.selectPlaceholder)}`;\n });\n\n protected display(leaf: Leaf<TOption, TValue>): string {\n return this.showPath() ? leaf.path.join(' / ') : (leaf.path.at(-1) ?? '');\n }\n\n private choose(option: TOption): void {\n this.value.set(readOption(option, this.optionValue()) as TValue);\n this.optionSelect.emit(option);\n }\n\n clear(): void {\n this.value.set(null);\n }\n}\n","import { _IdGenerator } from '@angular/cdk/a11y';\nimport { ConnectedPosition } from '@angular/cdk/overlay';\nimport { DOCUMENT } from '@angular/common';\nimport {\n afterNextRender,\n booleanAttribute,\n computed,\n contentChild,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n Injector,\n input,\n output,\n signal,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport {\n matchesFilter,\n optionText,\n readOption,\n STAR_UI_TEXT,\n StarDirectionService,\n starListKeyboardTarget,\n starListLayout,\n starListPageSize,\n starListRevealOffset,\n starListRevealRows,\n starListRowRendered,\n StarOptionKey,\n StarWindowRow,\n} from '@star-ng/ui/core';\n\n/** Context of the custom option template: `<ng-template starOption let-option let-selected=\"selected\">`. */\nexport interface StarOptionContext<T> {\n readonly $implicit: T;\n readonly selected: boolean;\n readonly index: number;\n}\n\n/** Custom option row template for `star-select` and `star-multi-select`. */\n@Directive({ selector: 'ng-template[starOption]' })\nexport class StarOptionTemplate<T = unknown> {\n /** Optional: pass the options array to type `let-option` in strict templates. */\n readonly starOptionOf = input<readonly T[] | null>(null);\n readonly template = inject<TemplateRef<StarOptionContext<T>>>(TemplateRef);\n\n static ngTemplateContextGuard<T>(\n _dir: StarOptionTemplate<T>,\n _ctx: unknown,\n ): _ctx is StarOptionContext<T> {\n return true;\n }\n}\n\n/** One rendered line of the option list: a group heading or an option. */\nexport type StarListRow<T> = StarWindowRow<T>;\n\n/** Lines rendered above and below the lines in view with `virtualScroll`. */\nconst VIRTUAL_BUFFER = 6;\n/** List height in pixels before the first scroll event gives the real height. */\nconst VIRTUAL_FALLBACK_HEIGHT = 256;\n\nconst PANEL_POSITIONS: ConnectedPosition[] = [\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 6 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -6 },\n];\n\n/**\n * Shared state and keyboard model of the dropdown list controls (WAI-ARIA combobox +\n * listbox with `aria-activedescendant`). Subclasses add the selection model.\n */\n@Directive()\nexport abstract class StarOptionListBase<TOption, TValue> {\n /** Keeps the CDK direction (overlays and menus) in step with `<html dir>`. */\n private readonly directionSync = inject(StarDirectionService);\n protected readonly text = inject(STAR_UI_TEXT);\n private readonly ids = inject(_IdGenerator);\n private readonly document = inject(DOCUMENT);\n private readonly injector = inject(Injector);\n\n readonly options = input<readonly TOption[]>([]);\n readonly optionLabel = input<StarOptionKey<TOption> | null>(null);\n /** Value stored in the form. Omit to store the whole option. */\n readonly optionValue = input<StarOptionKey<TOption> | null>(null);\n readonly optionDisabled = input<StarOptionKey<TOption> | null>(null);\n /** Equality for values (default `Object.is`). Use for object values from the server. */\n readonly compareWith = input<(a: TValue, b: TValue) => boolean>(Object.is);\n /**\n * Group heading of an option (property name or function). Options with the same heading\n * show together under it, in the order in which the headings first appear.\n */\n readonly optionGroup = input<StarOptionKey<TOption> | null>(null);\n /**\n * Renders only the lines in view, for long option lists. Every line has the height\n * `virtualItemSize` and option text stays on one line. Keys and type-ahead work over all\n * options, also those that are not in the DOM. Page up and Page down move by the lines in view.\n * Each option has `aria-setsize` and `aria-posinset` for the whole list, and\n * `aria-activedescendant` only names an option that is in the DOM.\n */\n readonly virtualScroll = input(false, { transform: booleanAttribute });\n /** Line height in pixels with `virtualScroll`. */\n readonly virtualItemSize = input(40);\n\n readonly placeholder = input<string | null>(null);\n readonly filter = input(false, { transform: booleanAttribute });\n readonly filterPlaceholder = input<string | null>(null);\n readonly showClear = input(false, { transform: booleanAttribute });\n readonly loading = input(false, { transform: booleanAttribute });\n readonly emptyMessage = input<string | null>(null);\n readonly scrollHeight = input('16rem');\n readonly size = input<'sm' | 'md'>('md');\n readonly ariaLabel = input<string | null>(null);\n readonly ariaLabelledBy = input<string | null>(null);\n readonly inputId = input(this.ids.getId('star-select-'));\n\n // Signal Forms state (bound by [formField]).\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly readonly = input(false, { transform: booleanAttribute });\n readonly required = input(false, { transform: booleanAttribute });\n readonly invalid = input(false, { transform: booleanAttribute });\n readonly touched = input(false, { transform: booleanAttribute });\n readonly name = input('');\n\n readonly touch = output<void>();\n readonly opened = output<void>();\n readonly closed = output<void>();\n readonly filterChange = output<string>();\n\n protected readonly optionTemplate = contentChild(StarOptionTemplate);\n protected readonly trigger = viewChild.required<ElementRef<HTMLElement>>('trigger');\n private readonly filterInput = viewChild<ElementRef<HTMLInputElement>>('filterInput');\n\n protected readonly positions = PANEL_POSITIONS;\n protected readonly listId = this.ids.getId('star-listbox-');\n protected readonly open = signal(false);\n protected readonly filterValue = signal('');\n protected readonly activeIndex = signal(-1);\n protected readonly showInvalid = computed(() => this.invalid() && this.touched());\n protected readonly interactive = computed(() => !this.disabled() && !this.readonly());\n\n protected readonly visibleOptions = computed(() => {\n const query = this.filterValue();\n const all = this.options();\n const options =\n !this.filter() || !query\n ? all\n : all.filter((option) => matchesFilter(this.labelOf(option), query));\n return this.groupedOrder(options);\n });\n\n /** With `optionGroup`: keeps each group together, in the order the groups first appear. */\n protected groupedOrder(options: readonly TOption[]): readonly TOption[] {\n if (!this.optionGroup()) return options;\n const order = new Map<string, number>();\n for (const option of options) {\n const group = this.groupOf(option);\n if (!order.has(group)) order.set(group, order.size);\n }\n return options\n .map((option, index) => ({ option, index, rank: order.get(this.groupOf(option)) ?? 0 }))\n .sort((a, b) => a.rank - b.rank || a.index - b.index)\n .map(({ option }) => option);\n }\n\n /** Group headings and options in display order, and the row of each option. */\n protected readonly layout = computed(() =>\n starListLayout(\n this.visibleOptions(),\n this.optionGroup() ? (option) => this.groupOf(option) : null,\n this.listId,\n ),\n );\n\n /** Group headings and options, in display order. */\n protected readonly rows = computed<readonly StarListRow<TOption>[]>(() => this.layout().rows);\n\n private readonly listScrollTop = signal(0);\n private readonly listHeight = signal(0);\n\n /** First and last rendered line, and the heights of the lines left out. */\n protected readonly virtualWindow = computed(() => {\n const count = this.rows().length;\n if (!this.virtualScroll()) return { start: 0, end: count, before: 0, after: 0 };\n const size = Math.max(1, this.virtualItemSize());\n const visible = Math.ceil((this.listHeight() || VIRTUAL_FALLBACK_HEIGHT) / size);\n const first = Math.min(Math.floor(this.listScrollTop() / size), Math.max(0, count - visible));\n const start = Math.max(0, first - VIRTUAL_BUFFER);\n const end = Math.min(count, first + visible + VIRTUAL_BUFFER);\n return { start, end, before: start * size, after: (count - end) * size };\n });\n\n protected readonly renderedRows = computed(() => {\n const rows = this.rows();\n const { start, end } = this.virtualWindow();\n return start === 0 && end === rows.length ? rows : rows.slice(start, end);\n });\n\n protected onListScroll(event: Event): void {\n if (!this.virtualScroll()) return;\n const list = event.target as HTMLElement;\n this.listScrollTop.set(list.scrollTop);\n this.listHeight.set(list.clientHeight);\n }\n\n /** `aria-activedescendant` only names an option that is in the DOM. */\n protected readonly activeId = computed(() => {\n const index = this.activeIndex();\n if (!this.open() || index < 0) return null;\n const row = this.layout().rowOfOption[index];\n return row !== undefined && starListRowRendered(row, this.virtualWindow())\n ? this.optionId(index)\n : null;\n });\n\n /** The heading of the group, only while its row is in the DOM (the id must exist). */\n protected describedBy(row: Extract<StarListRow<TOption>, { kind: 'option' }>): string | null {\n return row.groupId !== null && starListRowRendered(row.groupRow, this.virtualWindow())\n ? row.groupId\n : null;\n }\n\n protected readonly emptyText = computed(() =>\n this.filterValue()\n ? this.text.emptyFilterMessage\n : (this.emptyMessage() ?? this.text.emptyMessage),\n );\n\n private typeahead = '';\n private typeaheadTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => clearTimeout(this.typeaheadTimer));\n }\n\n /** True when the option is part of the current value. */\n protected abstract isSelected(option: TOption): boolean;\n /** Applies the user's choice of an option. */\n protected abstract choose(option: TOption): void;\n /** Index to highlight when the panel opens. */\n protected abstract initialActiveIndex(): number;\n /** Whether choosing an option closes the panel. */\n protected abstract readonly closeOnChoose: boolean;\n\n labelOf(option: TOption): string {\n return optionText(option, this.optionLabel() ?? null);\n }\n\n protected groupOf(option: TOption): string {\n const key = this.optionGroup();\n const group = key ? readOption(option, key) : null;\n return group === null || group === undefined ? '' : String(group);\n }\n\n protected valueOf(option: TOption): TValue {\n return readOption(option, this.optionValue()) as TValue;\n }\n\n protected isDisabled(option: TOption): boolean {\n const key = this.optionDisabled();\n return key ? !!readOption(option, key) : false;\n }\n\n protected equals(a: TValue, b: TValue): boolean {\n return this.compareWith()(a, b);\n }\n\n protected optionId(index: number): string {\n return `${this.listId}-${index}`;\n }\n\n protected optionContext(option: TOption, index: number): StarOptionContext<TOption> {\n return { $implicit: option, selected: this.isSelected(option), index };\n }\n\n openPanel(): void {\n if (!this.interactive() || this.open()) return;\n this.open.set(true);\n this.activeIndex.set(this.initialActiveIndex());\n this.opened.emit();\n }\n\n closePanel(focusTrigger = true): void {\n if (!this.open()) return;\n this.open.set(false);\n this.activeIndex.set(-1);\n this.listScrollTop.set(0);\n if (this.filterValue()) {\n this.filterValue.set('');\n this.filterChange.emit('');\n }\n if (focusTrigger) this.trigger().nativeElement.focus();\n this.closed.emit();\n }\n\n protected toggle(): void {\n if (this.open()) this.closePanel();\n else this.openPanel();\n }\n\n focus(options?: FocusOptions): void {\n this.trigger().nativeElement.focus(options);\n }\n\n protected onPanelAttached(): void {\n this.filterInput()?.nativeElement.focus();\n // The window needs the real list height before the first scroll event.\n const height = this.listElement()?.clientHeight;\n if (this.virtualScroll() && height) this.listHeight.set(height);\n this.scrollActiveIntoView();\n // The panel may attach before its list is drawn: the list is there after the next render.\n if (this.virtualScroll()) {\n afterNextRender(\n () => {\n const list = this.listElement();\n if (list?.clientHeight) this.listHeight.set(list.clientHeight);\n this.scrollActiveIntoView();\n },\n { injector: this.injector },\n );\n }\n }\n\n protected onOutsideClick(event: MouseEvent): void {\n // Clicks on the trigger are handled by its own (click) toggle.\n if (this.trigger().nativeElement.contains(event.target as Node)) return;\n this.closePanel(false);\n this.touch.emit();\n }\n\n /** Keeps focus on the trigger (or filter) while the user clicks inside the panel. */\n protected onPanelMousedown(event: MouseEvent): void {\n if (!(event.target instanceof HTMLInputElement)) event.preventDefault();\n }\n\n protected onTriggerBlur(): void {\n if (!this.open()) this.touch.emit();\n }\n\n protected onFilterInput(value: string): void {\n this.filterValue.set(value);\n this.filterChange.emit(value);\n this.resetScroll();\n this.activeIndex.set(this.firstEnabledFrom(0, 1));\n }\n\n /**\n * Shows the list from its top. The window and the scroll position of the element change\n * together: a new list that is still long would else keep the old position of the element\n * while the window draws its first lines.\n */\n protected resetScroll(): void {\n this.listScrollTop.set(0);\n const list = this.listElement();\n if (list) list.scrollTop = 0;\n }\n\n protected onOptionClick(option: TOption, index: number): void {\n if (this.isDisabled(option)) return;\n this.activeIndex.set(index);\n this.choose(option);\n if (this.closeOnChoose) this.closePanel();\n }\n\n /** Keyboard model for both the trigger and the filter input. */\n protected onKeydown(event: KeyboardEvent): void {\n if (!this.interactive()) return;\n const open = this.open();\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp': {\n event.preventDefault();\n if (!open) {\n this.openPanel();\n return;\n }\n const step = event.key === 'ArrowDown' ? 1 : -1;\n if (event.altKey && step === -1) {\n this.chooseActive();\n this.closePanel();\n return;\n }\n this.moveActive(step);\n return;\n }\n case 'Home':\n case 'End':\n if (!open) return;\n event.preventDefault();\n this.activeIndex.set(\n event.key === 'Home'\n ? this.firstEnabledFrom(0, 1)\n : this.firstEnabledFrom(this.visibleOptions().length - 1, -1),\n );\n this.scrollActiveIntoView();\n return;\n case 'PageDown':\n case 'PageUp':\n // Without `virtualScroll` the list is short enough to scroll by arrow keys.\n if (!open || !this.virtualScroll()) return;\n event.preventDefault();\n this.movePage(event.key === 'PageDown' ? 1 : -1);\n return;\n case 'Enter':\n event.preventDefault();\n if (!open) this.openPanel();\n else this.chooseActive(this.closeOnChoose);\n return;\n case ' ':\n // Space types into the filter field.\n if (event.target instanceof HTMLInputElement) return;\n event.preventDefault();\n // While the user types ahead, Space is part of the text (\"Order 5000\").\n if (this.typeahead) {\n this.runTypeahead(' ');\n return;\n }\n if (!open) this.openPanel();\n else this.chooseActive(this.closeOnChoose);\n return;\n case 'Escape':\n if (open) {\n event.preventDefault();\n event.stopPropagation();\n this.closePanel();\n }\n return;\n case 'Tab':\n if (open) this.closePanel(false);\n return;\n default:\n if (\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey &&\n !(event.target instanceof HTMLInputElement)\n ) {\n this.runTypeahead(event.key);\n }\n }\n }\n\n private chooseActive(thenClose = false): void {\n const option = this.visibleOptions()[this.activeIndex()];\n if (option === undefined || this.isDisabled(option)) return;\n this.choose(option);\n if (thenClose) this.closePanel();\n }\n\n private moveActive(step: 1 | -1): void {\n const count = this.visibleOptions().length;\n if (!count) return;\n const start = this.activeIndex() < 0 ? (step === 1 ? 0 : count - 1) : this.activeIndex() + step;\n const next = this.firstEnabledFrom(Math.min(Math.max(start, 0), count - 1), step);\n if (next >= 0) this.activeIndex.set(next);\n this.scrollActiveIntoView();\n }\n\n /** Page up / Page down: moves the active option by the lines in view, over all options. */\n private movePage(step: 1 | -1): void {\n const count = this.visibleOptions().length;\n const height = this.listElement()?.clientHeight || VIRTUAL_FALLBACK_HEIGHT;\n const target = starListKeyboardTarget(\n step === 1 ? 'PageDown' : 'PageUp',\n this.activeIndex(),\n count,\n starListPageSize(height, this.virtualItemSize()),\n );\n // A disabled option is skipped, in the direction of the key and then back.\n const next = this.firstEnabledFrom(target, step);\n const found = next >= 0 ? next : this.firstEnabledFrom(target, step === 1 ? -1 : 1);\n if (found >= 0) this.activeIndex.set(found);\n this.scrollActiveIntoView();\n }\n\n protected firstEnabledFrom(start: number, step: 1 | -1): number {\n const options = this.visibleOptions();\n for (let i = start; i >= 0 && i < options.length; i += step) {\n if (!this.isDisabled(options[i])) return i;\n }\n return -1;\n }\n\n /** Type a letter to jump to the next option whose label starts with the typed text. */\n private runTypeahead(char: string): void {\n clearTimeout(this.typeaheadTimer);\n this.typeahead += char.toLocaleLowerCase();\n this.typeaheadTimer = setTimeout(() => (this.typeahead = ''), 500);\n const options = this.visibleOptions();\n const start = Math.max(this.activeIndex(), 0);\n const ordered = [...options.keys()].map(\n (i) => (start + (this.typeahead.length === 1 ? 1 : 0) + i) % options.length,\n );\n const match = ordered.find(\n (i) =>\n !this.isDisabled(options[i]) &&\n this.labelOf(options[i]).toLocaleLowerCase().startsWith(this.typeahead),\n );\n if (match === undefined) return;\n this.activeIndex.set(match);\n if (!this.open() && this.closeOnChoose) this.choose(options[match]);\n this.scrollActiveIntoView();\n }\n\n /** The list element in the panel (the panel is outside the host, in the overlay). */\n private listElement(): HTMLElement | null {\n return this.document.getElementById(this.listId);\n }\n\n /**\n * Moves the list element to the offset of the window. A list that has just opened may not be\n * able to take it yet: it may be too short until its window is drawn, or not laid out until\n * the popover shows. The browser then keeps the old offset and sends no scroll event, so the\n * window would draw lines that the element does not show. Try again for some frames, until the\n * element is there or the user scrolls.\n */\n private applyScroll(list: HTMLElement, offset: number, frames: number): void {\n if (!list.isConnected || this.listScrollTop() !== offset) return;\n list.scrollTop = offset;\n if (frames > 0 && Math.abs(list.scrollTop - offset) > 1) {\n this.document.defaultView?.requestAnimationFrame?.(() =>\n this.applyScroll(list, offset, frames - 1),\n );\n }\n }\n\n private scrollActiveIntoView(): void {\n if (!this.open() || this.activeIndex() < 0) return;\n if (this.virtualScroll()) {\n // The active line may not be rendered yet: move the list so its position is in view.\n const list = this.listElement();\n const layout = this.layout();\n if (!list || layout.rowOfOption[this.activeIndex()] === undefined) return;\n const height = list.clientHeight || VIRTUAL_FALLBACK_HEIGHT;\n // The lines start below the padding of the list: without it the last line is cut off.\n const inset = parseFloat(getComputedStyle(list).paddingTop) || 0;\n const [first, last] = starListRevealRows(layout, this.activeIndex());\n const offset = starListRevealOffset(\n first,\n last,\n Math.max(1, this.virtualItemSize()),\n // The element knows where it is. The window can be ahead of it for a moment.\n list.clientHeight ? list.scrollTop : this.listScrollTop(),\n height,\n inset,\n );\n this.listHeight.set(height);\n if (offset === null) return;\n this.listScrollTop.set(offset);\n queueMicrotask(() => this.applyScroll(list, offset, 12));\n return;\n }\n const id = this.activeId();\n if (!id) return;\n queueMicrotask(() => this.document.getElementById(id)?.scrollIntoView?.({ block: 'nearest' }));\n }\n}\n","import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input, model } from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\nimport { StarOptionListBase } from './option-list-base';\n\n/**\n * Multiple-choice dropdown (PrimeNG `p-multiselect`): checkbox list, \"select all\", filter,\n * chip or comma display, `maxSelectedLabels`, `selectionLimit` and clear. Same keyboard model\n * as `star-select`; Enter / Space toggle the active option and keep the panel open.\n *\n * `<star-multi-select [options]=\"tags\" optionLabel=\"name\" optionValue=\"id\" [(value)]=\"ids\" display=\"chip\" filter />`\n */\n@Component({\n selector: 'star-multi-select',\n imports: [CdkConnectedOverlay, CdkOverlayOrigin, NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'star-select star-select--multi',\n '[class.star-select--open]': 'open()',\n '[class.star-select--disabled]': 'disabled()',\n '[class.star-select--invalid]': 'showInvalid()',\n '[class.star-select--sm]': \"size() === 'sm'\",\n },\n template: `\n <div class=\"star-select__control\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\n <div\n #trigger\n class=\"star-select__trigger\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [id]=\"inputId()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? listId : null\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-readonly]=\"readonly() || null\"\n (click)=\"toggle()\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onTriggerBlur()\"\n >\n @if (selectedOptions().length === 0) {\n <span class=\"star-select__placeholder\">{{\n placeholder() ?? text.selectPlaceholder\n }}</span>\n } @else if (collapsed()) {\n <span class=\"star-select__value\">{{ text.selectedItems(selectedOptions().length) }}</span>\n } @else if (display() === 'chip') {\n <span class=\"star-select__chips\">\n @for (option of selectedOptions(); track $index) {\n <span class=\"star-chip star-chip--sm\">\n {{ labelOf(option) }}\n @if (interactive()) {\n <button\n type=\"button\"\n class=\"star-chip__remove\"\n tabindex=\"-1\"\n [attr.aria-label]=\"text.removeItem(labelOf(option))\"\n (click)=\"$event.stopPropagation(); remove(option)\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n </span>\n }\n </span>\n } @else {\n <span class=\"star-select__value\">{{ selectedLabels() }}</span>\n }\n </div>\n @if (showClear() && selectedOptions().length && interactive()) {\n <button\n type=\"button\"\n class=\"star-select__icon-btn\"\n [attr.aria-label]=\"text.clear\"\n (click)=\"clear()\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (loading()) {\n <i\n class=\"ph-bold ph-spinner-gap star-spin star-select__caret\"\n role=\"img\"\n [attr.aria-label]=\"text.loading\"\n ></i>\n } @else {\n <i class=\"ph-bold ph-caret-down star-select__caret\" aria-hidden=\"true\"></i>\n }\n </div>\n\n <ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayUsePopover=\"inline\"\n cdkConnectedOverlayMatchWidth\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n (attach)=\"onPanelAttached()\"\n (detach)=\"closePanel(false)\"\n (overlayOutsideClick)=\"onOutsideClick($event)\"\n >\n <div class=\"star-panel\" (mousedown)=\"onPanelMousedown($event)\">\n @if (showToggleAll() || filter()) {\n <div class=\"star-panel__filter\">\n @if (showToggleAll() && !selectionLimit()) {\n <button\n type=\"button\"\n class=\"star-panel__toggle-all\"\n role=\"checkbox\"\n tabindex=\"-1\"\n [attr.aria-checked]=\"allState()\"\n [attr.aria-label]=\"text.selectAll\"\n (click)=\"toggleAll()\"\n >\n <span class=\"star-check__box\" aria-hidden=\"true\">\n @if (allState() === 'mixed') {\n <i class=\"ph-bold ph-minus\"></i>\n } @else if (allState() === true) {\n <i class=\"ph-bold ph-check\"></i>\n }\n </span>\n </button>\n }\n @if (filter()) {\n <i class=\"ph-bold ph-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n #filterInput\n type=\"text\"\n class=\"star-input star-input--sm\"\n role=\"searchbox\"\n autocomplete=\"off\"\n [value]=\"filterValue()\"\n [attr.placeholder]=\"filterPlaceholder() ?? text.filterPlaceholder\"\n [attr.aria-label]=\"filterPlaceholder() ?? text.filterPlaceholder\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-activedescendant]=\"activeId()\"\n (input)=\"onFilterInput(filterInput.value)\"\n (keydown)=\"onKeydown($event)\"\n />\n } @else {\n <span class=\"star-panel__toggle-label\">{{ text.selectAll }}</span>\n }\n </div>\n }\n <ul\n class=\"star-listbox\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [id]=\"listId\"\n [class.star-listbox--virtual]=\"virtualScroll()\"\n [style.--star-item-size.px]=\"virtualScroll() ? virtualItemSize() : null\"\n [style.max-height]=\"scrollHeight()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n (scroll)=\"onListScroll($event)\"\n >\n @if (virtualWindow().before) {\n <li\n class=\"star-listbox__spacer\"\n role=\"presentation\"\n [style.height.px]=\"virtualWindow().before\"\n ></li>\n }\n @for (row of renderedRows(); track row.key) {\n @if (row.kind === 'group') {\n <li class=\"star-listbox__group\" role=\"presentation\" [id]=\"row.id\">{{ row.label }}</li>\n } @else {\n @let option = row.option;\n @let i = row.index;\n <!-- Keyboard is handled on the combobox via aria-activedescendant (WAI-ARIA combobox pattern). -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <li\n class=\"star-listbox__option\"\n role=\"option\"\n [id]=\"optionId(i)\"\n [class.star-listbox__option--active]=\"activeIndex() === i\"\n [class.star-listbox__option--selected]=\"isSelected(option)\"\n [attr.aria-selected]=\"isSelected(option)\"\n [attr.aria-disabled]=\"isDisabled(option) || null\"\n [attr.aria-describedby]=\"describedBy(row)\"\n [attr.aria-setsize]=\"virtualScroll() ? visibleOptions().length : null\"\n [attr.aria-posinset]=\"virtualScroll() ? i + 1 : null\"\n (click)=\"onOptionClick(option, i)\"\n (mousemove)=\"isDisabled(option) || activeIndex.set(i)\"\n >\n <span class=\"star-check__box\" aria-hidden=\"true\">\n @if (isSelected(option)) {\n <i class=\"ph-bold ph-check\"></i>\n }\n </span>\n <span class=\"star-listbox__label\">\n @if (optionTemplate(); as custom) {\n <ng-container\n *ngTemplateOutlet=\"custom.template; context: optionContext(option, i)\"\n />\n } @else {\n {{ labelOf(option) }}\n }\n </span>\n </li>\n }\n } @empty {\n <li class=\"star-listbox__empty\" role=\"presentation\">{{ emptyText() }}</li>\n }\n @if (virtualWindow().after) {\n <li\n class=\"star-listbox__spacer\"\n role=\"presentation\"\n [style.height.px]=\"virtualWindow().after\"\n ></li>\n }\n </ul>\n </div>\n </ng-template>\n `,\n})\nexport class StarMultiSelect<TOption = unknown, TValue = TOption>\n extends StarOptionListBase<TOption, TValue>\n implements FormValueControl<readonly TValue[]>\n{\n readonly value = model<readonly TValue[]>([]);\n /** `comma`: \"A, B, C\". `chip`: removable chips. */\n readonly display = input<'comma' | 'chip'>('comma');\n /** Above this count the trigger shows \"{n} items selected\". */\n readonly maxSelectedLabels = input(3);\n /** Maximum number of selected items (0 = no limit). Hides \"select all\". */\n readonly selectionLimit = input(0);\n readonly showToggleAll = input(true);\n\n protected readonly closeOnChoose = false;\n\n protected readonly selectedOptions = computed(() =>\n this.options().filter((option) => this.isSelected(option)),\n );\n protected readonly collapsed = computed(\n () => this.selectedOptions().length > this.maxSelectedLabels(),\n );\n protected readonly selectedLabels = computed(() =>\n this.selectedOptions()\n .map((option) => this.labelOf(option))\n .join(', '),\n );\n\n private readonly selectableVisible = computed(() =>\n this.visibleOptions().filter((option) => !this.isDisabled(option)),\n );\n\n /** `true`, `false` or `'mixed'` for the \"select all\" box (over visible, enabled options). */\n protected readonly allState = computed<boolean | 'mixed'>(() => {\n const options = this.selectableVisible();\n const selected = options.filter((option) => this.isSelected(option)).length;\n if (!options.length || selected === 0) return false;\n return selected === options.length ? true : 'mixed';\n });\n\n /**\n * The chosen values in a `Set`, for the default `compareWith`. A lookup then costs one step and\n * not one scan of the value: with 10,000 chosen options a scan per option took seconds.\n */\n private readonly chosenSet = computed(() =>\n this.compareWith() === Object.is ? new Set<TValue>(this.value()) : null,\n );\n\n protected isSelected(option: TOption): boolean {\n const optionValue = this.valueOf(option);\n const chosen = this.chosenSet();\n return chosen\n ? chosen.has(optionValue)\n : this.value().some((value) => this.equals(value, optionValue));\n }\n\n protected choose(option: TOption): void {\n if (this.isSelected(option)) {\n this.remove(option);\n return;\n }\n const limit = this.selectionLimit();\n if (limit > 0 && this.value().length >= limit) return;\n this.value.update((values) => [...values, this.valueOf(option)]);\n }\n\n protected initialActiveIndex(): number {\n return this.firstEnabledFrom(0, 1);\n }\n\n remove(option: TOption): void {\n const optionValue = this.valueOf(option);\n this.value.update((values) => values.filter((value) => !this.equals(value, optionValue)));\n }\n\n protected toggleAll(): void {\n const options = this.selectableVisible();\n if (this.allState() === true) {\n const visibleValues = options.map((option) => this.valueOf(option));\n const visibleSet = this.compareWith() === Object.is ? new Set<TValue>(visibleValues) : null;\n this.value.update((values) =>\n values.filter((value) =>\n visibleSet\n ? !visibleSet.has(value)\n : !visibleValues.some((visible) => this.equals(visible, value)),\n ),\n );\n return;\n }\n const additions = options\n .filter((option) => !this.isSelected(option))\n .map((option) => this.valueOf(option));\n this.value.update((values) => [...values, ...additions]);\n }\n\n clear(): void {\n this.value.set([]);\n this.focus();\n }\n}\n","import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, model } from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\nimport { StarOptionListBase } from './option-list-base';\n\n/**\n * Single-choice dropdown (PrimeNG `p-select`): typed options, `optionLabel` / `optionValue` /\n * `optionDisabled`, filter, clear button, loading state, typeahead and full keyboard support\n * (WAI-ARIA select-only combobox). The panel is a native popover, so it also works inside\n * modal `star-dialog`s.\n *\n * ```html\n * <star-select [options]=\"countries\" optionLabel=\"name\" optionValue=\"code\"\n * [formField]=\"form.country\" filter showClear placeholder=\"Country\" />\n * ```\n */\n@Component({\n selector: 'star-select',\n imports: [CdkConnectedOverlay, CdkOverlayOrigin, NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'star-select',\n '[class.star-select--open]': 'open()',\n '[class.star-select--disabled]': 'disabled()',\n '[class.star-select--invalid]': 'showInvalid()',\n '[class.star-select--sm]': \"size() === 'sm'\",\n },\n template: `\n <div class=\"star-select__control\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\n <div\n #trigger\n class=\"star-select__trigger\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [id]=\"inputId()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? listId : null\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-readonly]=\"readonly() || null\"\n (click)=\"toggle()\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onTriggerBlur()\"\n >\n @if (selectedOption(); as option) {\n <span class=\"star-select__value\">{{ labelOf(option) }}</span>\n } @else {\n <span class=\"star-select__placeholder\">{{\n placeholder() ?? text.selectPlaceholder\n }}</span>\n }\n </div>\n @if (showClear() && selectedOption() !== undefined && interactive()) {\n <button\n type=\"button\"\n class=\"star-select__icon-btn\"\n [attr.aria-label]=\"text.clear\"\n (click)=\"clear()\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (loading()) {\n <i\n class=\"ph-bold ph-spinner-gap star-spin star-select__caret\"\n role=\"img\"\n [attr.aria-label]=\"text.loading\"\n ></i>\n } @else {\n <i class=\"ph-bold ph-caret-down star-select__caret\" aria-hidden=\"true\"></i>\n }\n </div>\n\n <ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayUsePopover=\"inline\"\n cdkConnectedOverlayMatchWidth\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n (attach)=\"onPanelAttached()\"\n (detach)=\"closePanel(false)\"\n (overlayOutsideClick)=\"onOutsideClick($event)\"\n >\n <div class=\"star-panel\" (mousedown)=\"onPanelMousedown($event)\">\n @if (filter()) {\n <div class=\"star-panel__filter\">\n <i class=\"ph-bold ph-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n #filterInput\n type=\"text\"\n class=\"star-input star-input--sm\"\n role=\"searchbox\"\n autocomplete=\"off\"\n [value]=\"filterValue()\"\n [attr.placeholder]=\"filterPlaceholder() ?? text.filterPlaceholder\"\n [attr.aria-label]=\"filterPlaceholder() ?? text.filterPlaceholder\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-activedescendant]=\"activeId()\"\n (input)=\"onFilterInput(filterInput.value)\"\n (keydown)=\"onKeydown($event)\"\n />\n </div>\n }\n <ul\n class=\"star-listbox\"\n role=\"listbox\"\n [id]=\"listId\"\n [class.star-listbox--virtual]=\"virtualScroll()\"\n [style.--star-item-size.px]=\"virtualScroll() ? virtualItemSize() : null\"\n [style.max-height]=\"scrollHeight()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n (scroll)=\"onListScroll($event)\"\n >\n @if (virtualWindow().before) {\n <li\n class=\"star-listbox__spacer\"\n role=\"presentation\"\n [style.height.px]=\"virtualWindow().before\"\n ></li>\n }\n @for (row of renderedRows(); track row.key) {\n @if (row.kind === 'group') {\n <li class=\"star-listbox__group\" role=\"presentation\" [id]=\"row.id\">{{ row.label }}</li>\n } @else {\n @let option = row.option;\n @let i = row.index;\n <!-- Keyboard is handled on the combobox via aria-activedescendant (WAI-ARIA combobox pattern). -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <li\n class=\"star-listbox__option\"\n role=\"option\"\n [id]=\"optionId(i)\"\n [class.star-listbox__option--active]=\"activeIndex() === i\"\n [class.star-listbox__option--selected]=\"isSelected(option)\"\n [attr.aria-selected]=\"isSelected(option)\"\n [attr.aria-disabled]=\"isDisabled(option) || null\"\n [attr.aria-describedby]=\"describedBy(row)\"\n [attr.aria-setsize]=\"virtualScroll() ? visibleOptions().length : null\"\n [attr.aria-posinset]=\"virtualScroll() ? i + 1 : null\"\n (click)=\"onOptionClick(option, i)\"\n (mousemove)=\"isDisabled(option) || activeIndex.set(i)\"\n >\n <span class=\"star-listbox__label\">\n @if (optionTemplate(); as custom) {\n <ng-container\n *ngTemplateOutlet=\"custom.template; context: optionContext(option, i)\"\n />\n } @else {\n {{ labelOf(option) }}\n }\n </span>\n @if (isSelected(option)) {\n <i class=\"ph-bold ph-check star-listbox__check\" aria-hidden=\"true\"></i>\n }\n </li>\n }\n } @empty {\n <li class=\"star-listbox__empty\" role=\"presentation\">{{ emptyText() }}</li>\n }\n @if (virtualWindow().after) {\n <li\n class=\"star-listbox__spacer\"\n role=\"presentation\"\n [style.height.px]=\"virtualWindow().after\"\n ></li>\n }\n </ul>\n </div>\n </ng-template>\n `,\n})\nexport class StarSelect<TOption = unknown, TValue = TOption>\n extends StarOptionListBase<TOption, TValue>\n implements FormValueControl<TValue | null>\n{\n readonly value = model<TValue | null>(null);\n\n protected readonly closeOnChoose = true;\n\n /** The option that matches the current value, or `undefined`. */\n protected readonly selectedOption = computed(() => {\n const value = this.value();\n if (value === null) return undefined;\n return this.options().find((option) => this.equals(this.valueOf(option), value));\n });\n\n protected isSelected(option: TOption): boolean {\n const value = this.value();\n return value !== null && this.equals(this.valueOf(option), value);\n }\n\n protected choose(option: TOption): void {\n this.value.set(this.valueOf(option));\n }\n\n protected initialActiveIndex(): number {\n const index = this.visibleOptions().findIndex((option) => this.isSelected(option));\n return index >= 0 ? index : this.firstEnabledFrom(0, 1);\n }\n\n clear(): void {\n this.value.set(null);\n this.focus();\n }\n}\n"],"mappings":"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"}
@@ -186,53 +186,100 @@ function printFitStyle(widths, columns = []) {
186
186
  }
187
187
  return css;
188
188
  }
189
+ function addPrintStyle(doc, css = "") {
190
+ const Sheet = doc.defaultView?.CSSStyleSheet;
191
+ if (Sheet && "adoptedStyleSheets" in doc && typeof Sheet.prototype.replaceSync === "function") try {
192
+ const sheet = new Sheet();
193
+ sheet.replaceSync(css);
194
+ doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, sheet];
195
+ return {
196
+ set: (text) => sheet.replaceSync(text),
197
+ remove: () => {
198
+ doc.adoptedStyleSheets = doc.adoptedStyleSheets.filter((other) => other !== sheet);
199
+ }
200
+ };
201
+ } catch {}
202
+ const element = doc.createElement("style");
203
+ element.textContent = css;
204
+ doc.head.append(element);
205
+ return {
206
+ set: (text) => {
207
+ element.textContent = text;
208
+ },
209
+ remove: () => element.remove()
210
+ };
211
+ }
212
+ function stylePrintDocument(doc) {
213
+ addPrintStyle(doc, PRINT_STYLE);
214
+ }
189
215
  function fitPrintDocument(doc) {
190
216
  const table = doc.querySelector("table");
191
217
  if (!table) return {
192
218
  widths: [],
193
219
  columns: []
194
220
  };
195
- const probe = doc.createElement("style");
196
- doc.head.append(probe);
221
+ const probe = addPrintStyle(doc);
197
222
  const lastWhole = PRINT_FIT_STEPS.findIndex((step) => step.anywhere) - 1;
198
223
  let columns = [];
199
224
  const widths = PRINT_FIT_STEPS.map((step, index) => {
200
- probe.textContent = `table{width:1px}${fitRules(step, "table")}`;
225
+ probe.set(`table{width:1px}${fitRules(step, "table")}`);
201
226
  if (index === lastWhole) columns = Array.from(table.querySelectorAll("thead th"), (cell) => Math.ceil(cell.getBoundingClientRect().width));
202
227
  return Math.ceil(table.getBoundingClientRect().width);
203
228
  });
204
229
  probe.remove();
205
230
  const css = printFitStyle(widths, columns);
206
- if (css) {
207
- const style = doc.createElement("style");
208
- style.textContent = css;
209
- doc.head.append(style);
210
- }
231
+ if (css) addPrintStyle(doc, css);
211
232
  return {
212
233
  widths,
213
234
  columns
214
235
  };
215
236
  }
216
- function buildPrintDocument(title, headers, rows) {
217
- const escape = (value) => escapeXml(String(value));
218
- const cellClass = (value) => {
219
- const text = String(value);
220
- const classes = [typeof value === "number" ? "n" : "", typeof value !== "number" && text.length <= LONG_WORD && !/\s/.test(text) ? "s" : ""].filter(Boolean);
221
- return classes.length ? ` class="${classes.join(" ")}"` : "";
237
+ function printColumnAlign(align, values) {
238
+ if (align) return align;
239
+ return values.length > 0 && values.every((value) => typeof value === "number") ? "end" : "start";
240
+ }
241
+ function printContext(host, doc) {
242
+ const find = (name, accept) => {
243
+ for (let node = host; node; node = node.parentElement) {
244
+ const value = node.getAttribute(name)?.trim();
245
+ if (value && accept(value)) return value;
246
+ }
247
+ const root = doc.documentElement.getAttribute(name)?.trim();
248
+ return root && accept(root) ? root : void 0;
222
249
  };
223
- const numberColumn = (index) => rows.length > 0 && rows.every((row) => typeof row[index] === "number");
224
- return `<!doctype html><html><head><meta charset="utf-8"><title>${escape(title)}</title><style>
225
- body{font:12px/1.4 system-ui,sans-serif;color:#000;margin:16px}
250
+ const lang = find("lang", (value) => /^[A-Za-z0-9-]+$/.test(value));
251
+ const dir = find("dir", (value) => /^(ltr|rtl)$/i.test(value))?.toLowerCase();
252
+ return {
253
+ ...lang ? { lang } : {},
254
+ ...dir ? { dir } : {}
255
+ };
256
+ }
257
+ const PRINT_STYLE = `body{font:12px/1.4 system-ui,sans-serif;color:#000;margin:16px}
226
258
  h1{font-size:16px;margin:0 0 12px;overflow-wrap:anywhere}
227
259
  .fit{container-type:inline-size}
228
260
  table{width:100%;border-collapse:collapse}
229
- th,td{padding:4px 8px;border:1px solid #999;text-align:left;vertical-align:top;overflow-wrap:break-word}
261
+ th,td{padding:4px 8px;border:1px solid #999;text-align:start;vertical-align:top;overflow-wrap:break-word}
230
262
  th{background:#eee}
231
- th.n,td.n{text-align:right}
263
+ th.c,td.c{text-align:center}
264
+ th.e,td.e{text-align:end}
232
265
  td.s{white-space:nowrap}
233
266
  thead{display:table-header-group}
234
- tr{break-inside:avoid}
235
- </style></head><body><h1>${escape(title)}</h1><div class="fit"><table><thead><tr>${headers.map((header, index) => `<th scope="col"${numberColumn(index) ? " class=\"n\"" : ""}>${printable(header)}</th>`).join("")}</tr></thead><tbody>${rows.map((row) => `<tr>${row.map((value) => `<td${cellClass(value)}>${printable(value)}</td>`).join("")}</tr>`).join("")}</tbody></table></div></body></html>`;
267
+ tr{break-inside:avoid}`;
268
+ function buildPrintDocument(title, headers, rows, options = {}) {
269
+ const escape = (value) => escapeXml(String(value));
270
+ const alignClass = (align) => align === "end" ? "e" : align === "center" ? "c" : "";
271
+ const cellClass = (value, index) => {
272
+ const text = String(value);
273
+ const column = options.align?.[index];
274
+ const classes = [column ? alignClass(column) : typeof value === "number" ? "e" : "", typeof value !== "number" && text.length <= LONG_WORD && !/\s/.test(text) ? "s" : ""].filter(Boolean);
275
+ return classes.length ? ` class="${classes.join(" ")}"` : "";
276
+ };
277
+ const numberColumn = (index) => rows.length > 0 && rows.every((row) => typeof row[index] === "number");
278
+ const headerClass = (index) => {
279
+ const align = options.align?.[index] ?? (numberColumn(index) ? "end" : "start");
280
+ return alignClass(align) ? ` class="${alignClass(align)}"` : "";
281
+ };
282
+ return `<!doctype html><html${(options.lang ? ` lang="${escapeXml(options.lang)}"` : "") + (options.dir ? ` dir="${options.dir === "rtl" ? "rtl" : "ltr"}"` : "")}><head><meta charset="utf-8"><title>${escape(title)}</title></head><body><h1>${escape(title)}</h1><div class="fit"><table><thead><tr>${headers.map((header, index) => `<th scope="col"${headerClass(index)}>${printable(header)}</th>`).join("")}</tr></thead><tbody>${rows.map((row) => `<tr>${row.map((value, index) => `<td${cellClass(value, index)}>${printable(value)}</td>`).join("")}</tr>`).join("")}</tbody></table></div></body></html>`;
236
283
  }
237
284
  var HeightTree = class {
238
285
  heights;
@@ -1495,10 +1542,17 @@ var StarTable = class StarTable {
1495
1542
  const frame = this.document.createElement("iframe");
1496
1543
  frame.setAttribute("aria-hidden", "true");
1497
1544
  frame.style.cssText = "position:fixed;width:0;height:0;border:0;visibility:hidden";
1498
- frame.srcdoc = buildPrintDocument(options.title ?? this.ariaLabel() ?? "", columns.map((column) => column.header), rows.map((row) => columns.map((column) => this.exportCell(row, column))));
1545
+ frame.srcdoc = buildPrintDocument(options.title ?? this.ariaLabel() ?? "", columns.map((column) => column.header), rows.map((row) => columns.map((column) => this.exportCell(row, column))), {
1546
+ align: columns.map((column) => printColumnAlign(column.align, rows.map((row) => {
1547
+ const cell = this.exportCell(row, column);
1548
+ return typeof cell === "number" ? cell : this.cellValue(row, column);
1549
+ }))),
1550
+ ...printContext(this.host.nativeElement, this.document)
1551
+ });
1499
1552
  frame.addEventListener("load", () => {
1500
1553
  const view = frame.contentWindow;
1501
1554
  if (!view) return;
1555
+ stylePrintDocument(view.document);
1502
1556
  fitPrintDocument(view.document);
1503
1557
  view.addEventListener("afterprint", () => frame.remove());
1504
1558
  view.focus();
@@ -3472,6 +3526,6 @@ i0.ɵɵngDeclareClassMetadata({
3472
3526
  }]
3473
3527
  }
3474
3528
  });
3475
- export { PRINT_FIT_STEPS, StarCellTemplate, StarRowExpansionTemplate, StarTable, buildPrintDocument, buildXlsx, fitPrintDocument, printFitStyle };
3529
+ export { PRINT_FIT_STEPS, PRINT_STYLE, StarCellTemplate, StarRowExpansionTemplate, StarTable, addPrintStyle, buildPrintDocument, buildXlsx, fitPrintDocument, printColumnAlign, printContext, printFitStyle, stylePrintDocument };
3476
3530
 
3477
3531
  //# sourceMappingURL=star-ng-ui-table.mjs.map