@raqm/ui 0.1.1 → 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.
Files changed (96) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +87 -126
  3. package/fesm2022/raqm-ui-badge.mjs +3 -1
  4. package/fesm2022/raqm-ui-badge.mjs.map +1 -1
  5. package/fesm2022/raqm-ui-calendar.mjs +79 -12
  6. package/fesm2022/raqm-ui-calendar.mjs.map +1 -1
  7. package/fesm2022/raqm-ui-combobox.mjs +47 -23
  8. package/fesm2022/raqm-ui-combobox.mjs.map +1 -1
  9. package/fesm2022/raqm-ui-command.mjs +60 -12
  10. package/fesm2022/raqm-ui-command.mjs.map +1 -1
  11. package/fesm2022/raqm-ui-dialog.mjs +1 -3
  12. package/fesm2022/raqm-ui-dialog.mjs.map +1 -1
  13. package/fesm2022/raqm-ui-icon.mjs +160 -0
  14. package/fesm2022/raqm-ui-icon.mjs.map +1 -0
  15. package/fesm2022/raqm-ui-input-otp.mjs +7 -4
  16. package/fesm2022/raqm-ui-input-otp.mjs.map +1 -1
  17. package/fesm2022/raqm-ui-overlay-internal.mjs +15 -5
  18. package/fesm2022/raqm-ui-overlay-internal.mjs.map +1 -1
  19. package/fesm2022/raqm-ui-popover.mjs +51 -19
  20. package/fesm2022/raqm-ui-popover.mjs.map +1 -1
  21. package/fesm2022/raqm-ui-resizable.mjs +14 -4
  22. package/fesm2022/raqm-ui-resizable.mjs.map +1 -1
  23. package/fesm2022/raqm-ui-scroll-area.mjs +85 -29
  24. package/fesm2022/raqm-ui-scroll-area.mjs.map +1 -1
  25. package/fesm2022/raqm-ui-select.mjs +46 -19
  26. package/fesm2022/raqm-ui-select.mjs.map +1 -1
  27. package/fesm2022/raqm-ui-sidebar.mjs +13 -3
  28. package/fesm2022/raqm-ui-sidebar.mjs.map +1 -1
  29. package/fesm2022/raqm-ui-slider.mjs +59 -12
  30. package/fesm2022/raqm-ui-slider.mjs.map +1 -1
  31. package/fesm2022/raqm-ui-toast.mjs +60 -20
  32. package/fesm2022/raqm-ui-toast.mjs.map +1 -1
  33. package/fesm2022/raqm-ui-tooltip.mjs +28 -3
  34. package/fesm2022/raqm-ui-tooltip.mjs.map +1 -1
  35. package/fesm2022/raqm-ui.mjs +1 -0
  36. package/package.json +53 -20
  37. package/styles/accordion.css +1 -0
  38. package/styles/alert-dialog.css +1 -0
  39. package/styles/alert.css +1 -0
  40. package/styles/attachment.css +1 -0
  41. package/styles/avatar.css +1 -0
  42. package/styles/badge.css +1 -0
  43. package/styles/base.css +1 -0
  44. package/styles/button-group.css +1 -0
  45. package/styles/button.css +1 -0
  46. package/styles/checkbox.css +1 -0
  47. package/styles/combobox.css +1 -0
  48. package/styles/command.css +1 -0
  49. package/styles/common.css +17 -0
  50. package/styles/context-menu.css +1 -0
  51. package/styles/dialog.css +1 -0
  52. package/styles/drawer.css +1 -0
  53. package/styles/dropdown-menu.css +1 -0
  54. package/styles/empty.css +1 -0
  55. package/styles/field-parts.css +1 -0
  56. package/styles/field-relationships.css +1 -0
  57. package/styles/input-group-button.css +1 -0
  58. package/styles/input-group-relationships.css +1 -0
  59. package/styles/input-otp.css +1 -0
  60. package/styles/input.css +1 -0
  61. package/styles/item.css +1 -0
  62. package/styles/kbd.css +1 -0
  63. package/styles/menubar.css +1 -0
  64. package/styles/native-select.css +1 -0
  65. package/styles/navigation-menu.css +1 -0
  66. package/styles/overlay.css +1 -0
  67. package/styles/pagination.css +1 -0
  68. package/styles/popover.css +1 -0
  69. package/styles/questionnaire.css +1 -0
  70. package/styles/radio-group.css +1 -0
  71. package/styles/resizable.css +1 -0
  72. package/styles/sheet.css +1 -0
  73. package/styles/sidebar.css +1 -0
  74. package/styles/spinner.css +1 -0
  75. package/styles/switch.css +1 -0
  76. package/styles/table.css +1 -0
  77. package/styles/tabs.css +1 -0
  78. package/styles/textarea.css +1 -0
  79. package/styles/theme.css +50 -4324
  80. package/styles/toggle-group.css +1 -0
  81. package/styles/toggle.css +1 -0
  82. package/styles/tooltip.css +1 -0
  83. package/types/raqm-ui-calendar.d.ts +1 -0
  84. package/types/raqm-ui-combobox.d.ts +8 -4
  85. package/types/raqm-ui-command.d.ts +4 -0
  86. package/types/raqm-ui-dialog.d.ts +7 -1
  87. package/types/raqm-ui-icon.d.ts +65 -0
  88. package/types/raqm-ui-input-otp.d.ts +1 -0
  89. package/types/raqm-ui-resizable.d.ts +4 -0
  90. package/types/raqm-ui-scroll-area.d.ts +11 -0
  91. package/types/raqm-ui-slider.d.ts +1 -1
  92. package/types/raqm-ui-toast.d.ts +6 -0
  93. package/types/raqm-ui.d.ts +1 -0
  94. package/fesm2022/raqm-ui-carousel.mjs +0 -410
  95. package/fesm2022/raqm-ui-carousel.mjs.map +0 -1
  96. package/types/raqm-ui-carousel.d.ts +0 -81
@@ -1 +1 @@
1
- {"version":3,"file":"raqm-ui-combobox.mjs","names":[],"sources":["../../../projects/ui/combobox/combobox-model.ts","../../../projects/ui/combobox/combobox-control.ts","../../../projects/ui/combobox/combobox-effects.ts","../../../projects/ui/combobox/combobox-field.ts","../../../projects/ui/combobox/combobox-keyboard.ts","../../../projects/ui/combobox/combobox-overlay.ts","../../../projects/ui/combobox/combobox-popup.ts","../../../projects/ui/combobox/combobox.directive.ts","../../../projects/ui/combobox/combobox-view.ts","../../../projects/ui/combobox/combobox-view-state.ts","../../../projects/ui/combobox/combobox.component.ts","../../../projects/ui/combobox/combobox.component.html"],"sourcesContent":["// Combobox value model, query matching and the duplicate-value guard.\r\n\r\nimport { isDevMode } from '@angular/core';\r\n\r\nimport { RaqmComboboxOption } from './combobox.types';\r\n\r\nexport type RaqmComboboxModel = readonly string[] | string | null;\r\n\r\nexport type RaqmComboboxMode = 'multiple' | 'popup' | 'inline';\r\n\r\n// Built once (construction is expensive); locale-aware, case/diacritic-insensitive search.\r\nconst collator = new Intl.Collator(undefined, {\r\n usage: 'search',\r\n sensitivity: 'base',\r\n ignorePunctuation: true,\r\n});\r\n\r\nexport function labelContains(label: string, query: string): boolean {\r\n if (!query) {\r\n return true;\r\n }\r\n for (let i = 0; i <= label.length - query.length; i += 1) {\r\n if (collator.compare(label.slice(i, i + query.length), query) === 0) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n// Non-arrays become empty; non-strings and duplicates are dropped, order kept.\r\nexport function normalizeMultiple(value: unknown): string[] {\r\n if (!Array.isArray(value)) {\r\n return [];\r\n }\r\n const result: string[] = [];\r\n for (const member of value) {\r\n if (typeof member === 'string' && !result.includes(member)) {\r\n result.push(member);\r\n }\r\n }\r\n return result;\r\n}\r\n\r\nexport function normalizePopup(value: unknown): string | null {\r\n return typeof value === 'string' ? value : null;\r\n}\r\n\r\nexport function normalizeModel(value: unknown, mode: RaqmComboboxMode): RaqmComboboxModel {\r\n return mode === 'multiple' ? normalizeMultiple(value) : normalizePopup(value);\r\n}\r\n\r\n// Development-only guard; option values must be unique.\r\nexport function reportDuplicateValues(items: readonly RaqmComboboxOption[]): void {\r\n if (!isDevMode()) {\r\n return;\r\n }\r\n const seen = new Set<string>();\r\n const duplicates = new Set<string>();\r\n for (const item of items) {\r\n if (seen.has(item.value)) {\r\n duplicates.add(item.value);\r\n } else {\r\n seen.add(item.value);\r\n }\r\n }\r\n if (duplicates.size > 0) {\r\n console.error(\r\n `[raqm-combobox] Duplicate option value(s) ${[...duplicates]\r\n .map((value) => JSON.stringify(value))\r\n .join(', ')}; Combobox option values must be unique.`,\r\n );\r\n }\r\n}\r\n","// Combobox value: the Forms accessor and the single selection path.\r\n\r\nimport { ControlValueAccessor } from '@angular/forms';\r\nimport { Signal, signal } from '@angular/core';\r\n\r\nimport { RaqmComboboxMode, RaqmComboboxModel, normalizeModel } from './combobox-model';\r\nimport { RaqmComboboxOption } from './combobox.types';\r\n\r\nexport interface RaqmComboboxControlHost {\r\n mode(): RaqmComboboxMode;\r\n selected(): RaqmComboboxModel;\r\n /** Writes the normalised value without emitting. */\r\n setSelected(value: RaqmComboboxModel): void;\r\n query(): string;\r\n disabled(): boolean;\r\n selectionRemovable(): boolean;\r\n close(touched: boolean): void;\r\n /** Emits the committed value to the consumer. */\r\n publish(value: RaqmComboboxModel): void;\r\n}\r\n\r\nexport class RaqmComboboxControl implements ControlValueAccessor {\r\n private readonly cvaDisabled = signal(false);\r\n\r\n private onChange: ((value: RaqmComboboxModel) => void) | undefined;\r\n private onTouched: (() => void) | undefined;\r\n\r\n /** Forms-driven disabled state, ORed with the explicit input by the caller. */\r\n readonly disabled: Signal<boolean> = this.cvaDisabled.asReadonly();\r\n\r\n constructor(private readonly host: RaqmComboboxControlHost) {}\r\n\r\n /** Writes an external value without emitting or marking touched; normalised per mode. */\r\n writeValue(value: unknown): void {\r\n this.host.setSelected(normalizeModel(value, this.host.mode()));\r\n }\r\n\r\n registerOnChange(fn: (value: RaqmComboboxModel) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n /** ORs a Forms disabled state with the explicit input and closes the popup. */\r\n setDisabledState(isDisabled: boolean): void {\r\n this.cvaDisabled.set(isDisabled);\r\n if (isDisabled) {\r\n this.host.close(false);\r\n }\r\n }\r\n\r\n // One selection path for pointer and keyboard; a repeated single value emits nothing.\r\n commit(item: RaqmComboboxOption): void {\r\n if (this.host.disabled() || item.disabled === true) {\r\n return;\r\n }\r\n if (this.host.mode() === 'multiple') {\r\n const selected = this.host.selected();\r\n const current = Array.isArray(selected) ? (selected as readonly string[]) : [];\r\n const next = current.includes(item.value)\r\n ? current.filter((value) => value !== item.value)\r\n : [...current, item.value];\r\n this.emit(next);\r\n // Stays open on an unfiltered toggle; closes when a filter had been typed.\r\n if (this.host.query().trim() === '') {\r\n return;\r\n }\r\n this.host.close(true);\r\n return;\r\n }\r\n const next = item.value;\r\n // The same scalar emits nothing; a fresh scalar emits once and closes.\r\n if (this.host.selected() === next) {\r\n this.host.close(true);\r\n return;\r\n }\r\n // Replacing a disabled selection would remove it; external value writes bypass this guard.\r\n if (!this.host.selectionRemovable()) {\r\n return;\r\n }\r\n this.emit(next);\r\n this.host.close(true);\r\n }\r\n\r\n /** Stores and publishes a committed value; never called while typing. */\r\n emit(next: RaqmComboboxModel): void {\r\n const normalized = normalizeModel(next, this.host.mode());\r\n this.host.setSelected(normalized);\r\n this.onChange?.(normalized);\r\n this.host.publish(normalized);\r\n }\r\n\r\n touch(): void {\r\n this.onTouched?.();\r\n }\r\n}\r\n","// Combobox effects: presentation reset, the duplicate guard and active descendant upkeep.\r\n\r\nimport { effect, untracked } from '@angular/core';\r\n\r\nimport { RaqmComboboxMode, reportDuplicateValues } from './combobox-model';\r\nimport { RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxOptionView } from './combobox-view';\r\n\r\nexport interface RaqmComboboxEffectsHost {\r\n mode(): RaqmComboboxMode;\r\n popupWidth(): string | null;\r\n alignOffset(): number;\r\n dir(): 'ltr' | 'rtl' | undefined;\r\n open(): boolean;\r\n reposition(): void;\r\n flatItems(): readonly RaqmComboboxOption[];\r\n views(): readonly RaqmComboboxOptionView[];\r\n disabled(): boolean;\r\n selectionRemovable(): boolean;\r\n autoHighlight(): boolean;\r\n close(): void;\r\n reconcile(views: readonly RaqmComboboxOptionView[]): void;\r\n resetForMode(): void;\r\n}\r\n\r\nexport function connectComboboxEffects(host: RaqmComboboxEffectsHost): void {\r\n let lastMode: RaqmComboboxMode | undefined;\r\n\r\n // Resets state on a real presentation change; `selected` re-normalises without emitting.\r\n effect(() => {\r\n const mode = host.mode();\r\n if (mode === lastMode) {\r\n return;\r\n }\r\n const isFirstRender = lastMode === undefined;\r\n lastMode = mode;\r\n untracked(() => {\r\n if (!isFirstRender) {\r\n host.resetForMode();\r\n }\r\n });\r\n });\r\n\r\n // Development-only duplicate-value guard, re-run whenever the items change.\r\n effect(() => reportDuplicateValues(host.flatItems()));\r\n\r\n // Consumer placement changes reach an already-open overlay too.\r\n effect(() => {\r\n host.popupWidth();\r\n host.alignOffset();\r\n host.dir();\r\n if (host.open()) {\r\n untracked(() => host.reposition());\r\n }\r\n });\r\n\r\n // Keeps the active descendant honest after filtering/removal; a fresh query re-marks the first result.\r\n effect(() => {\r\n const views = host.views();\r\n const disabled = host.disabled();\r\n host.selectionRemovable();\r\n host.autoHighlight();\r\n host.open();\r\n if (disabled) {\r\n untracked(() => host.close());\r\n return;\r\n }\r\n untracked(() => host.reconcile(views));\r\n });\r\n}\r\n","// Combobox field: the editable control, chips, pointer presses and focus movement.\r\n\r\nimport { signal } from '@angular/core';\r\n\r\nimport { InteractivityChecker } from '@angular/cdk/a11y';\r\n\r\nimport { RaqmComboboxModel } from './combobox-model';\r\nimport { RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxChipView, RaqmComboboxOptionView } from './combobox-view';\r\n\r\n// Descendants that keep their own activation instead of the chip field's press handler.\r\nconst INTERACTIVE_SELECTOR =\r\n 'button, a[href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\r\n\r\nexport interface RaqmComboboxFieldHost {\r\n open(): boolean;\r\n disabled(): boolean;\r\n selectionRemovable(): boolean;\r\n chipViews(): readonly RaqmComboboxChipView[];\r\n optionViews(): readonly RaqmComboboxOptionView[];\r\n activeId(): string | null;\r\n selected(): RaqmComboboxModel;\r\n isOptionDisabled(item: RaqmComboboxOption): boolean;\r\n trigger(): HTMLButtonElement | null;\r\n element(): HTMLElement;\r\n overlayElement(): HTMLElement | undefined;\r\n openPopup(): void;\r\n close(touched: boolean, restoreFocus?: boolean): void;\r\n select(item: RaqmComboboxOption): void;\r\n emit(value: RaqmComboboxModel): void;\r\n resetActive(): void;\r\n reconcileActive(): void;\r\n markTouched(): void;\r\n activateOption(index: number): void;\r\n}\r\n\r\nexport class RaqmComboboxField {\r\n // Search text, deliberately separate from the selected value.\r\n readonly query = signal<string>('');\r\n\r\n // Raw IME text, bound instead of the query so composing never filters or interrupts.\r\n readonly composingValue = signal<string | null>(null);\r\n\r\n // Set while the overlay is disposed, so its focus loss is not taken for a departure.\r\n suppressBlurTouched = false;\r\n\r\n // True inside an IME composition, so a composing Enter never commits.\r\n private composing = false;\r\n\r\n constructor(\r\n private readonly host: RaqmComboboxFieldHost,\r\n private readonly document: Document,\r\n private readonly interactivityChecker: InteractivityChecker,\r\n ) {}\r\n\r\n get isComposing(): boolean {\r\n return this.composing;\r\n }\r\n\r\n /** Clears the query and any composition text on close. */\r\n reset(): void {\r\n this.query.set('');\r\n this.composingValue.set(null);\r\n }\r\n\r\n /** Clears only the query; a CDK detach leaves composition text untouched. */\r\n resetQuery(): void {\r\n this.query.set('');\r\n }\r\n\r\n // Keeps a chip-field press in the input: focuses the control and opens the popup.\r\n onChipsPointerDown(event: PointerEvent): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n // Interactive descendants keep their own activation and caret placement.\r\n const target = event.target as Element | null;\r\n if (target?.closest(INTERACTIVE_SELECTOR)) {\r\n return;\r\n }\r\n event.preventDefault();\r\n this.focusInput();\r\n if (!this.host.open()) {\r\n this.host.openPopup();\r\n }\r\n }\r\n\r\n // Never prevented, so the native caret placement survives.\r\n onInputPointerDown(): void {\r\n if (this.host.disabled() || this.host.open()) {\r\n return;\r\n }\r\n this.host.openPopup();\r\n }\r\n\r\n onInlineFocus(event: FocusEvent): void {\r\n if (this.host.open() || this.host.disabled()) {\r\n return;\r\n }\r\n (event.target as HTMLInputElement).select();\r\n }\r\n\r\n // Emits `null` once, marks touched and returns focus to the field.\r\n onClearClick(event: MouseEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (this.host.disabled() || !this.host.selectionRemovable()) {\r\n return;\r\n }\r\n this.host.emit(null);\r\n this.host.markTouched();\r\n this.focusInput();\r\n }\r\n\r\n onTriggerClick(): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n if (this.host.open()) {\r\n this.host.close(true);\r\n } else {\r\n this.host.openPopup();\r\n }\r\n }\r\n\r\n // Touched only on a genuine departure from the host or popup, never on internal transitions.\r\n onFocusOut(event: FocusEvent): void {\r\n if (this.suppressBlurTouched) {\r\n return;\r\n }\r\n const next = event.relatedTarget as Node | null;\r\n const overlayElement = this.host.overlayElement();\r\n if (next && (this.host.element().contains(next) || overlayElement?.contains(next) === true)) {\r\n return;\r\n }\r\n if (this.host.open()) {\r\n this.host.close(true, false);\r\n } else {\r\n this.host.markTouched();\r\n }\r\n }\r\n\r\n // Updates the query and highlight, never emits; during IME only raw text is mirrored.\r\n onInput(event: Event): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n const input = event.target as HTMLInputElement;\r\n if (this.composing) {\r\n this.composingValue.set(input.value);\r\n return;\r\n }\r\n this.query.set(input.value);\r\n this.applyQueryHighlight(input.value);\r\n }\r\n\r\n onCompositionStart(event: CompositionEvent): void {\r\n this.composing = true;\r\n this.composingValue.set((event.target as HTMLInputElement).value);\r\n }\r\n\r\n onCompositionEnd(event: CompositionEvent): void {\r\n this.composing = false;\r\n this.composingValue.set(null);\r\n const input = event.target as HTMLInputElement;\r\n this.query.set(input.value);\r\n this.applyQueryHighlight(input.value);\r\n }\r\n\r\n // Hover makes the row active so pointer and keyboard agree; touch is ignored.\r\n onOptionPointerMove(view: RaqmComboboxOptionView, event: PointerEvent): void {\r\n if (event.pointerType === 'touch') {\r\n return;\r\n }\r\n if (this.host.isOptionDisabled(view.item) || this.host.activeId() === view.id) {\r\n return;\r\n }\r\n const index = this.host.optionViews().findIndex((candidate) => candidate.id === view.id);\r\n if (index === -1) {\r\n return;\r\n }\r\n this.host.activateOption(index);\r\n }\r\n\r\n // Clears the active option on leaving the list, so the next ArrowDown restarts from the top.\r\n onOptionPointerLeave(event: PointerEvent): void {\r\n if (event.pointerType === 'touch') {\r\n return;\r\n }\r\n const related = event.relatedTarget;\r\n if (related instanceof Element && related.closest('.raqm-combobox-option')) {\r\n return;\r\n }\r\n this.host.resetActive();\r\n }\r\n\r\n onOptionClick(item: RaqmComboboxOption): void {\r\n if (this.host.isOptionDisabled(item)) {\r\n return;\r\n }\r\n this.host.select(item);\r\n }\r\n\r\n isSelected(item: RaqmComboboxOption): boolean {\r\n const value = this.host.selected();\r\n if (Array.isArray(value)) {\r\n return value.includes(item.value);\r\n }\r\n return value === item.value;\r\n }\r\n\r\n // The portal sits at the document end, so the next tab stop is found explicitly from the trigger.\r\n leavePopupByTab(event: KeyboardEvent): void {\r\n const trigger = this.host.trigger();\r\n if (!trigger) return;\r\n const overlay = this.host.overlayElement();\r\n const candidates = Array.from(\r\n this.document.querySelectorAll<HTMLElement>(\r\n 'a[href], button, input, select, textarea, [tabindex], [contenteditable=\"true\"]',\r\n ),\r\n ).filter(\r\n (element) => !overlay?.contains(element) && this.interactivityChecker.isTabbable(element),\r\n );\r\n // Positive tabindex precedes zero in sequential focus order; sort stably.\r\n candidates.sort((a, b) => (a.tabIndex || Infinity) - (b.tabIndex || Infinity));\r\n const index = candidates.indexOf(trigger);\r\n const target = index < 0 ? undefined : candidates[index + (event.shiftKey ? -1 : 1)];\r\n if (target) {\r\n event.preventDefault();\r\n target.focus();\r\n this.host.close(true, false);\r\n } else {\r\n trigger.focus();\r\n this.host.close(true, false);\r\n }\r\n }\r\n\r\n onChipRemoveClick(index: number, event: MouseEvent): void {\r\n event.stopPropagation();\r\n this.removeAt(index);\r\n }\r\n\r\n // Removes the chip and restores focus to a neighbour, or the input, if its button held focus.\r\n removeAt(index: number): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n const chip = this.host.chipViews()[index];\r\n if (!chip || !chip.removable) {\r\n return;\r\n }\r\n const removeButton = this.chipButton(index);\r\n const heldFocus =\r\n removeButton !== null && this.host.element().ownerDocument.activeElement === removeButton;\r\n const selected = this.host.selected();\r\n const current = Array.isArray(selected) ? selected : [];\r\n // A removed value that is the active option must not leave a stale active descendant.\r\n const activeView = this.host.optionViews().find((view) => view.item.value === chip.value);\r\n if (activeView && this.host.activeId() === activeView.id) {\r\n this.host.resetActive();\r\n }\r\n this.host.emit(current.filter((value) => value !== chip.value));\r\n if (heldFocus) {\r\n const remaining = this.host.chipViews();\r\n if (remaining.length === 0) {\r\n this.focusInput();\r\n } else {\r\n this.focusChip(Math.min(index, remaining.length - 1));\r\n }\r\n }\r\n }\r\n\r\n focusInput(): void {\r\n const input = this.inputElement();\r\n if (input && !input.disabled) {\r\n input.focus();\r\n }\r\n }\r\n\r\n focusChip(index: number): void {\r\n const button = this.chipButton(index);\r\n if (button && !button.disabled) {\r\n button.focus();\r\n }\r\n }\r\n\r\n restoreTriggerFocus(): void {\r\n const trigger = this.host.trigger();\r\n if (trigger && !trigger.disabled) {\r\n trigger.focus();\r\n }\r\n }\r\n\r\n // Preserves the active option by value; falls back to the first enabled match per autoHighlight.\r\n private applyQueryHighlight(value: string): void {\r\n if (value.trim() !== '' && !this.host.open()) {\r\n this.host.openPopup();\r\n }\r\n this.host.reconcileActive();\r\n }\r\n\r\n // The one editable control: in the host for multiple/inline, in the overlay for popup.\r\n private inputElement(): HTMLInputElement | null {\r\n const inHost = this.host.element().querySelector<HTMLInputElement>('.raqm-combobox-input');\r\n if (inHost) {\r\n return inHost;\r\n }\r\n return (\r\n this.host.overlayElement()?.querySelector<HTMLInputElement>('.raqm-combobox-input') ?? null\r\n );\r\n }\r\n\r\n private chipButton(index: number): HTMLButtonElement | null {\r\n const buttons = this.host\r\n .element()\r\n .querySelectorAll<HTMLButtonElement>('.raqm-combobox-chip-remove');\r\n return buttons[index] ?? null;\r\n }\r\n}\r\n","// Combobox keyboard: the active option, the key manager and every key path.\r\n\r\nimport { Injector, computed, signal } from '@angular/core';\r\n\r\nimport { ActiveDescendantKeyManager, Highlightable } from '@angular/cdk/a11y';\r\n\r\nimport { RaqmComboboxMode } from './combobox-model';\r\nimport { RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxOptionView } from './combobox-view';\r\n\r\nexport interface RaqmComboboxKeyboardHost {\r\n /** Current option views, in render order. */\r\n views(): readonly RaqmComboboxOptionView[];\r\n open(): boolean;\r\n disabled(): boolean;\r\n /** True inside an IME composition, so a composing key never commits. */\r\n composing(): boolean;\r\n mode(): RaqmComboboxMode;\r\n autoHighlight(): boolean;\r\n query(): string;\r\n direction(): 'ltr' | 'rtl';\r\n isOptionDisabled(item: RaqmComboboxOption): boolean;\r\n chipCount(): number;\r\n scrollTo(id: string | null): void;\r\n openPopup(): void;\r\n close(touched: boolean): void;\r\n select(item: RaqmComboboxOption): void;\r\n removeChip(index: number): void;\r\n focusChip(index: number): void;\r\n focusInput(): void;\r\n /** The portal sits at the document end, so the next tab stop is found by the caller. */\r\n leavePopupByTab(event: KeyboardEvent): void;\r\n}\r\n\r\n// Key-manager wrapper: the active row is tracked as an id, never written to the DOM.\r\nclass RaqmComboboxOptionRef implements Highlightable {\r\n constructor(\r\n readonly view: RaqmComboboxOptionView,\r\n private readonly activate: (ref: RaqmComboboxOptionRef) => void,\r\n private readonly isDisabled: (item: RaqmComboboxOption) => boolean,\r\n ) {}\r\n\r\n get disabled(): boolean {\r\n return this.isDisabled(this.view.item);\r\n }\r\n\r\n getLabel(): string {\r\n return this.view.item.label;\r\n }\r\n\r\n setActiveStyles(): void {\r\n this.activate(this);\r\n }\r\n\r\n setInactiveStyles(): void {}\r\n}\r\n\r\nexport class RaqmComboboxKeyboard {\r\n private keyManager: ActiveDescendantKeyManager<RaqmComboboxOptionRef> | undefined;\r\n\r\n // Set for a pointer-origin activation, so hover updates ARIA without scrolling the list.\r\n private suppressActivationScroll = false;\r\n\r\n // The active option's value; drives the highlight and `aria-activedescendant`.\r\n private readonly activeValue = signal<string | null>(null);\r\n\r\n readonly activeId = computed(() => {\r\n if (!this.host.open() || this.host.disabled()) return null;\r\n const value = this.activeValue();\r\n return (\r\n this.host\r\n .views()\r\n .find((view) => view.item.value === value && !this.host.isOptionDisabled(view.item))?.id ??\r\n null\r\n );\r\n });\r\n\r\n // Rebuilt only when filtered items or ids change, so navigation never invalidates the active item.\r\n private readonly optionRefs = computed<RaqmComboboxOptionRef[]>(() =>\r\n this.host.views().map(\r\n (view) =>\r\n new RaqmComboboxOptionRef(\r\n view,\r\n (ref) => {\r\n this.activeValue.set(ref.view.item.value);\r\n // Keep the active row visible, except for pointer activation, which suppresses scrolling.\r\n if (!this.suppressActivationScroll) {\r\n this.host.scrollTo(ref.view.id);\r\n }\r\n },\r\n (item) => this.host.isOptionDisabled(item),\r\n ),\r\n ),\r\n );\r\n\r\n constructor(\r\n private readonly host: RaqmComboboxKeyboardHost,\r\n private readonly injector: Injector,\r\n ) {}\r\n\r\n /**\r\n * Creates the key manager once `items` is bound; building it in the constructor would read the\r\n * required `items` input before Angular binds it (`NG0950`).\r\n */\r\n init(): void {\r\n this.keyManager = new ActiveDescendantKeyManager<RaqmComboboxOptionRef>(\r\n this.optionRefs,\r\n this.injector,\r\n )\r\n .withWrap(false)\r\n .withVerticalOrientation(true)\r\n .withHomeAndEnd(true);\r\n }\r\n\r\n destroy(): void {\r\n this.keyManager?.destroy();\r\n }\r\n\r\n // Opens on ArrowDown/ArrowUp from the closed trigger (the native button covers Enter/Space).\r\n onTriggerKeydown(event: KeyboardEvent): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\r\n event.preventDefault();\r\n if (!this.host.open()) {\r\n this.host.openPopup();\r\n }\r\n }\r\n }\r\n\r\n // Single keyboard path for both presentations; chip navigation runs first in `multiple`.\r\n onKeydown(event: KeyboardEvent): void {\r\n if (this.host.mode() === 'multiple' && this.handleChipNavigation(event)) {\r\n return;\r\n }\r\n // A composing key (or the legacy 229) never commits.\r\n if (this.host.composing() || event.isComposing || event.keyCode === 229) {\r\n return;\r\n }\r\n switch (event.key) {\r\n case 'Escape':\r\n // Escape closes without clearing the selection.\r\n if (this.host.open()) {\r\n event.preventDefault();\r\n this.host.close(true);\r\n }\r\n return;\r\n case 'Tab':\r\n if (this.host.mode() === 'popup' && this.host.open()) this.host.leavePopupByTab(event);\r\n return;\r\n case 'Enter': {\r\n // A single Enter commits the active result.\r\n if (!this.host.open()) {\r\n return;\r\n }\r\n this.reconcile(this.host.views());\r\n const active = this.host.views().find((view) => view.item.value === this.activeValue());\r\n if (active && !this.host.isOptionDisabled(active.item) && !this.host.disabled()) {\r\n event.preventDefault();\r\n this.host.select(active.item);\r\n }\r\n return;\r\n }\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n // Arrows navigate results, opening first, never the selected values.\r\n event.preventDefault();\r\n if (!this.host.open()) {\r\n this.host.openPopup();\r\n } else {\r\n this.reconcile(this.host.views());\r\n this.keyManager?.onKeydown(event);\r\n }\r\n return;\r\n case 'Home':\r\n case 'End':\r\n // Home/End navigate results while open; otherwise the native caret is left untouched.\r\n if (this.host.open()) {\r\n event.preventDefault();\r\n this.reconcile(this.host.views());\r\n this.keyManager?.onKeydown(event);\r\n }\r\n return;\r\n default:\r\n return;\r\n }\r\n }\r\n\r\n // Backspace/Delete remove, RTL-aware arrows move between chips, printable keys refocus the input.\r\n onChipKeydown(index: number, event: KeyboardEvent): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n const rtl = this.host.direction() === 'rtl';\r\n const previousKey = rtl ? 'ArrowRight' : 'ArrowLeft';\r\n const nextKey = rtl ? 'ArrowLeft' : 'ArrowRight';\r\n switch (event.key) {\r\n case 'Backspace':\r\n case 'Delete':\r\n event.preventDefault();\r\n this.host.removeChip(index);\r\n return;\r\n case previousKey:\r\n event.preventDefault();\r\n if (index > 0) {\r\n this.host.focusChip(index - 1);\r\n } else {\r\n this.host.focusInput();\r\n }\r\n return;\r\n case nextKey:\r\n event.preventDefault();\r\n if (index < this.host.chipCount() - 1) {\r\n this.host.focusChip(index + 1);\r\n } else {\r\n this.host.focusInput();\r\n }\r\n return;\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n if (!this.host.open()) {\r\n this.host.openPopup();\r\n }\r\n return;\r\n default:\r\n if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {\r\n this.host.focusInput();\r\n }\r\n return;\r\n }\r\n }\r\n\r\n /** Moves the active option; pointer activation never scrolls. */\r\n activateIndex(index: number, scroll: boolean): void {\r\n if (!this.keyManager) {\r\n return;\r\n }\r\n if (scroll) {\r\n this.keyManager.setActiveItem(index);\r\n return;\r\n }\r\n // Hover never scrolls; cleared in `finally` so a throw cannot leave scrolling off.\r\n this.suppressActivationScroll = true;\r\n try {\r\n this.keyManager.setActiveItem(index);\r\n } finally {\r\n this.suppressActivationScroll = false;\r\n }\r\n }\r\n\r\n /** Marks the first enabled result active; an all-disabled list is left untouched. */\r\n activateFirst(): void {\r\n const index = this.host.views().findIndex((view) => !this.host.isOptionDisabled(view.item));\r\n if (index === -1) {\r\n return;\r\n }\r\n this.keyManager?.setActiveItem(index);\r\n }\r\n\r\n // CDK keeps old wrappers when items are replaced; rebind by stable value, never by index.\r\n reconcile(views: readonly RaqmComboboxOptionView[]): void {\r\n if (!this.host.open() || this.host.disabled() || !this.keyManager) {\r\n return;\r\n }\r\n const value = this.activeValue();\r\n const index =\r\n value === null\r\n ? -1\r\n : views.findIndex(\r\n (view) => view.item.value === value && !this.host.isOptionDisabled(view.item),\r\n );\r\n if (index >= 0) {\r\n const current = this.optionRefs()[index];\r\n if (this.keyManager.activeItem !== current) this.keyManager.setActiveItem(index);\r\n return;\r\n }\r\n this.reset();\r\n if (this.host.autoHighlight() && this.host.query().trim() !== '') {\r\n this.activateFirst();\r\n }\r\n }\r\n\r\n // Clears item and `activeId` together; an absent `aria-activedescendant` is valid ARIA 1.2.\r\n reset(): void {\r\n this.keyManager?.setActiveItem(-1);\r\n this.activeValue.set(null);\r\n }\r\n\r\n // ArrowLeft at the caret start focuses the last chip; Backspace on an empty field removes it.\r\n private handleChipNavigation(event: KeyboardEvent): boolean {\r\n if (this.host.chipCount() === 0) {\r\n return false;\r\n }\r\n const rtl = this.host.direction() === 'rtl';\r\n const previousKey = rtl ? 'ArrowRight' : 'ArrowLeft';\r\n const input = event.currentTarget as HTMLInputElement;\r\n const caret = input.selectionStart ?? 0;\r\n if (event.key === previousKey && caret === 0) {\r\n event.preventDefault();\r\n this.host.focusChip(this.host.chipCount() - 1);\r\n return true;\r\n }\r\n if (event.key === 'Backspace' && input.value === '') {\r\n event.preventDefault();\r\n this.host.removeChip(this.host.chipCount() - 1);\r\n return true;\r\n }\r\n return false;\r\n }\r\n}\r\n","// Combobox popup pane: creation, positioning, direction and the viewport clamp.\r\n\r\nimport { TemplateRef, ViewContainerRef, signal } from '@angular/core';\r\n\r\nimport { Directionality } from '@angular/cdk/bidi';\r\nimport {\r\n ConnectedPosition,\r\n FlexibleConnectedPositionStrategy,\r\n Overlay,\r\n OverlayConfig,\r\n OverlayRef,\r\n} from '@angular/cdk/overlay';\r\nimport { TemplatePortal } from '@angular/cdk/portal';\r\nimport { ViewportRuler } from '@angular/cdk/scrolling';\r\n\r\nimport { registerOverlayOwnership } from '@raqm/ui/overlay-internal';\r\n\r\n// Gap between the anchor and the popup, in CSS pixels.\r\nconst OVERLAY_GAP = 6;\r\n\r\n// Minimum distance kept from every viewport edge, in CSS pixels.\r\nconst VIEWPORT_MARGIN = 10;\r\n\r\nexport interface RaqmComboboxOverlayHost {\r\n /** The control element; a press inside it is not \"outside\". */\r\n readonly element: HTMLElement;\r\n /** Nearest ancestor direction stream, when one exists. */\r\n readonly directionality: Directionality | null;\r\n /** The element the pane anchors to for the current mode. */\r\n anchor(): HTMLElement | null;\r\n /** The listbox template attached to the pane. */\r\n template(): TemplateRef<unknown>;\r\n /** Current resolved direction. */\r\n direction(): 'ltr' | 'rtl';\r\n /** Consumer width; `null` follows the anchor. */\r\n width(): string | null;\r\n /** Inline-axis offset in CSS pixels. */\r\n alignOffset(): number;\r\n /** A press outside the pane and the control asks to close. */\r\n onOutside(): void;\r\n /** The CDK detached the pane, so the caller syncs its state. */\r\n onDetached(): void;\r\n}\r\n\r\nexport class RaqmComboboxOverlay {\r\n private overlayRef: OverlayRef | undefined;\r\n private releaseOverlayOwnership: (() => void) | undefined;\r\n private outsideSubscription: { unsubscribe(): void } | undefined;\r\n private detachSubscription: { unsubscribe(): void } | undefined;\r\n // Re-applied on resize so the pane re-clamps before the CDK's own throttled pass.\r\n private positionStrategy: FlexibleConnectedPositionStrategy | undefined;\r\n private resizeSubscription: { unsubscribe(): void } | undefined;\r\n private directionSubscription: { unsubscribe(): void } | undefined;\r\n private directionObserver: MutationObserver | undefined;\r\n\r\n readonly open = signal(false);\r\n readonly dir = signal<'ltr' | 'rtl'>('ltr');\r\n\r\n constructor(\r\n private readonly overlay: Overlay,\r\n private readonly viewportRuler: ViewportRuler,\r\n private readonly viewContainerRef: ViewContainerRef,\r\n private readonly host: RaqmComboboxOverlayHost,\r\n ) {}\r\n\r\n get element(): HTMLElement | undefined {\r\n return this.overlayRef?.overlayElement;\r\n }\r\n\r\n get hasPane(): boolean {\r\n return this.overlayRef !== undefined;\r\n }\r\n\r\n /** Creates and attaches the pane; `false` when the mode has no anchor yet. */\r\n openLayer(): boolean {\r\n const anchor = this.host.anchor();\r\n if (!anchor) {\r\n return false;\r\n }\r\n\r\n const direction = this.host.direction();\r\n this.dir.set(direction);\r\n const anchorWidth = anchor.getBoundingClientRect().width;\r\n // Anchor width unless the consumer supplies one.\r\n const width = this.host.width() || anchorWidth;\r\n\r\n const strategy = this.overlay\r\n .position()\r\n .flexibleConnectedTo(anchor)\r\n .withPositions(this.positions())\r\n // Non-modal: repositions on scroll/resize and never locks the page.\r\n .withFlexibleDimensions(true)\r\n .withGrowAfterOpen(true)\r\n .withPush(true)\r\n .withViewportMargin(VIEWPORT_MARGIN);\r\n\r\n const config: OverlayConfig = {\r\n positionStrategy: strategy,\r\n // Reposition rather than block: the page scrolls under the pane, which stays anchored.\r\n scrollStrategy: this.overlay.scrollStrategies.reposition(),\r\n // No backdrop: the control stays clickable while the list is open.\r\n hasBackdrop: false,\r\n panelClass: 'raqm-combobox-overlay-pane',\r\n // A route change disposes the overlay rather than orphaning it.\r\n disposeOnNavigation: true,\r\n width,\r\n direction,\r\n };\r\n\r\n this.positionStrategy = strategy;\r\n this.overlayRef = this.overlay.create(config);\r\n // Published for the SCSS clamp in `combobox-relationships.scss`; single source of truth.\r\n this.overlayRef.overlayElement.style.setProperty(\r\n '--raqm-combobox-viewport-margin',\r\n `${VIEWPORT_MARGIN}px`,\r\n );\r\n // Anchor-side height for the SCSS cap; a cap, never a floor, so `max-h-72` still wins.\r\n this.applyAvailableHeight();\r\n this.overlayRef.attach(new TemplatePortal(this.host.template(), this.viewContainerRef));\r\n this.releaseOverlayOwnership = registerOverlayOwnership(anchor, this.overlayRef);\r\n\r\n this.open.set(true);\r\n this.observeDirection();\r\n\r\n // A press on the control itself is not \"outside\", so the input stays interactive.\r\n this.outsideSubscription = this.overlayRef.outsidePointerEvents().subscribe((event) => {\r\n const target = event.target as Node | null;\r\n if (target && this.host.element.contains(target)) {\r\n return;\r\n }\r\n this.host.onOutside();\r\n });\r\n this.detachSubscription = this.overlayRef.detachments().subscribe(() => this.host.onDetached());\r\n // Un-throttled resize pass: reposition and re-cap before the CDK's own throttled pass.\r\n this.resizeSubscription = this.viewportRuler.change(0).subscribe(() => {\r\n this.updateDirection();\r\n this.applyAnchorWidth();\r\n this.applyAvailableHeight();\r\n this.positionStrategy?.apply();\r\n });\r\n return true;\r\n }\r\n\r\n /** Re-reads direction, anchor width and positions for an open pane. */\r\n reposition(): void {\r\n this.updateDirection();\r\n this.applyAnchorWidth();\r\n this.positionStrategy?.withPositions(this.positions());\r\n this.positionStrategy?.apply();\r\n }\r\n\r\n /** Unsubscribes, releases ownership and clears the pane; returns it for the caller to dispose. */\r\n detach(): OverlayRef | undefined {\r\n const overlayRef = this.overlayRef;\r\n this.stopObservingDirection();\r\n this.releaseOverlayOwnership?.();\r\n this.releaseOverlayOwnership = undefined;\r\n // Unsubscribe before disposing, so our own dispose cannot re-enter the detach handler.\r\n this.outsideSubscription?.unsubscribe();\r\n this.outsideSubscription = undefined;\r\n this.detachSubscription?.unsubscribe();\r\n this.detachSubscription = undefined;\r\n this.resizeSubscription?.unsubscribe();\r\n this.resizeSubscription = undefined;\r\n this.positionStrategy = undefined;\r\n this.overlayRef = undefined;\r\n this.open.set(false);\r\n return overlayRef;\r\n }\r\n\r\n // One bounded assignment, no polling. Bounding-rect deltas are used because `offsetTop` measures\r\n // against `offsetParent` (the positioned popup), not the scroller.\r\n scrollOptionIntoView(id: string | null): void {\r\n const overlayRef = this.overlayRef;\r\n if (!overlayRef || !id) {\r\n return;\r\n }\r\n const list = overlayRef.overlayElement.querySelector<HTMLElement>('.raqm-combobox-list');\r\n const row = Array.from(\r\n overlayRef.overlayElement.querySelectorAll<HTMLElement>('.raqm-combobox-option'),\r\n ).find((option) => option.id === id);\r\n if (!list || !row) {\r\n return;\r\n }\r\n const listRect = list.getBoundingClientRect();\r\n const rowRect = row.getBoundingClientRect();\r\n // Row edge in the scroller's content coordinate system (padding-box origin).\r\n const rowTop = rowRect.top - listRect.top - list.clientTop + list.scrollTop;\r\n const rowBottom = rowRect.bottom - listRect.top - list.clientTop + list.scrollTop;\r\n const viewTop = list.scrollTop;\r\n const viewBottom = viewTop + list.clientHeight;\r\n let target: number | null = null;\r\n if (rowTop < viewTop) {\r\n target = rowTop;\r\n } else if (rowBottom > viewBottom) {\r\n target = rowBottom - list.clientHeight;\r\n }\r\n if (target === null) {\r\n return;\r\n }\r\n const maxScrollTop = Math.max(list.scrollHeight - list.clientHeight, 0);\r\n list.scrollTop = Math.min(Math.max(target, 0), maxScrollTop);\r\n }\r\n\r\n // Below the anchor first, flipping above on collision with the same gap.\r\n private positions(): ConnectedPosition[] {\r\n const offset = Number.isFinite(this.host.alignOffset()) ? this.host.alignOffset() : 0;\r\n const offsetX = this.dir() === 'rtl' ? -offset : offset;\r\n return [\r\n {\r\n originX: 'start',\r\n originY: 'bottom',\r\n overlayX: 'start',\r\n overlayY: 'top',\r\n offsetY: OVERLAY_GAP,\r\n offsetX,\r\n },\r\n {\r\n originX: 'start',\r\n originY: 'top',\r\n overlayX: 'start',\r\n overlayY: 'bottom',\r\n offsetY: -OVERLAY_GAP,\r\n offsetX,\r\n },\r\n ];\r\n }\r\n\r\n // Observed only while the popup exists; explicit `dir` changes go through `reposition`.\r\n private observeDirection(): void {\r\n this.directionSubscription = this.host.directionality?.change.subscribe(() =>\r\n this.updateDirection(),\r\n );\r\n if (typeof MutationObserver === 'undefined') return;\r\n this.directionObserver = new MutationObserver(() => this.updateDirection());\r\n for (\r\n let element: HTMLElement | null = this.host.element;\r\n element;\r\n element = element.parentElement\r\n ) {\r\n this.directionObserver.observe(element, {\r\n attributes: true,\r\n attributeFilter: ['dir', 'class', 'style'],\r\n });\r\n }\r\n }\r\n\r\n private updateDirection(): void {\r\n const ref = this.overlayRef;\r\n if (!ref) return;\r\n const direction = this.host.direction();\r\n if (direction === this.dir()) return;\r\n this.dir.set(direction);\r\n ref.setDirection(direction);\r\n this.positionStrategy?.withPositions(this.positions());\r\n ref.updatePosition();\r\n }\r\n\r\n private stopObservingDirection(): void {\r\n this.directionObserver?.disconnect();\r\n this.directionObserver = undefined;\r\n this.directionSubscription?.unsubscribe();\r\n this.directionSubscription = undefined;\r\n }\r\n\r\n private applyAnchorWidth(): void {\r\n const overlayRef = this.overlayRef;\r\n const anchor = this.host.anchor();\r\n if (!overlayRef || !anchor || !anchor.isConnected) {\r\n return;\r\n }\r\n const width = this.host.width();\r\n const anchorWidth = anchor.getBoundingClientRect().width;\r\n if (!width && (!Number.isFinite(anchorWidth) || anchorWidth <= 0)) {\r\n return;\r\n }\r\n overlayRef.updateSize({ width: width || `${anchorWidth}px` });\r\n }\r\n\r\n // Publishes `--raqm-combobox-available-height`: the roomier anchor side, as a cap and never a floor.\r\n private applyAvailableHeight(): void {\r\n const overlayRef = this.overlayRef;\r\n const anchor = this.host.anchor();\r\n if (!overlayRef || !anchor) {\r\n return;\r\n }\r\n const anchorRect = anchor.getBoundingClientRect();\r\n const viewportHeight = this.viewportRuler.getViewportSize().height;\r\n const below = viewportHeight - anchorRect.bottom - OVERLAY_GAP - VIEWPORT_MARGIN;\r\n const above = anchorRect.top - OVERLAY_GAP - VIEWPORT_MARGIN;\r\n const available = Math.max(below, above, 0);\r\n overlayRef.overlayElement.style.setProperty(\r\n '--raqm-combobox-available-height',\r\n `${available}px`,\r\n );\r\n }\r\n}\r\n\r\n// Direction precedence: explicit `dir`, computed style, then the injected CDK value.\r\nexport function resolveComboboxDirection(\r\n dir: 'ltr' | 'rtl' | undefined,\r\n element: HTMLElement,\r\n directionality: Directionality | null,\r\n): 'ltr' | 'rtl' {\r\n if (dir === 'ltr' || dir === 'rtl') {\r\n return dir;\r\n }\r\n const computed = getComputedStyle(element).direction;\r\n if (computed === 'rtl' || computed === 'ltr') {\r\n return computed;\r\n }\r\n return directionality?.value ?? 'ltr';\r\n}\r\n","// Combobox popup orchestration: open policy, close teardown and the focus handoff.\r\n\r\nimport { RaqmComboboxField } from './combobox-field';\r\nimport { RaqmComboboxKeyboard } from './combobox-keyboard';\r\nimport { RaqmComboboxMode } from './combobox-model';\r\nimport { RaqmComboboxOverlay } from './combobox-overlay';\r\n\r\nexport interface RaqmComboboxPopupHost {\r\n readonly layer: RaqmComboboxOverlay;\r\n readonly keyboard: RaqmComboboxKeyboard;\r\n readonly field: RaqmComboboxField;\r\n mode(): RaqmComboboxMode;\r\n disabled(): boolean;\r\n autoHighlight(): boolean;\r\n query(): string;\r\n /** Marks the control touched after a committed close. */\r\n touched(): void;\r\n}\r\n\r\nexport class RaqmComboboxPopup {\r\n constructor(private readonly host: RaqmComboboxPopupHost) {}\r\n\r\n /** Opens the pane and applies the presentation's focus policy. */\r\n show(): void {\r\n if (this.host.layer.open() || this.host.disabled()) {\r\n return;\r\n }\r\n if (!this.host.layer.openLayer()) {\r\n return;\r\n }\r\n\r\n this.host.keyboard.reset();\r\n if (this.host.mode() === 'popup') {\r\n // The Popup's control lives inside the popup; focus it on open.\r\n this.host.field.focusInput();\r\n } else if (this.host.mode() === 'inline') {\r\n this.host.field.focusInput();\r\n } else if (this.host.autoHighlight() && this.host.query().trim() !== '') {\r\n this.host.keyboard.activateFirst();\r\n }\r\n }\r\n\r\n // Idempotent while closed, so a focus-out close plus the outside press mark touched once.\r\n close(touched: boolean, restoreFocus = true): void {\r\n if (!this.host.layer.open() && !this.host.layer.hasPane) {\r\n return;\r\n }\r\n this.destroy(restoreFocus);\r\n if (touched) {\r\n this.host.touched();\r\n }\r\n }\r\n\r\n // Unsubscribes, disposes and resets transient state. Only Popup restores focus to its trigger: the\r\n // Inline input already holds it, and a genuine departure must not be fought. The popup has no\r\n // enter/exit animation (`animate-none!`), so disposal is synchronous.\r\n destroy(restoreFocus: boolean): void {\r\n const wasOpen = this.host.layer.open();\r\n const overlayRef = this.host.layer.detach();\r\n this.host.keyboard.reset();\r\n this.host.field.reset();\r\n // Disposing the focused input fires a focusout; suppress it, it is not a departure.\r\n this.host.field.suppressBlurTouched = true;\r\n overlayRef?.dispose();\r\n this.host.field.suppressBlurTouched = false;\r\n if (restoreFocus && wasOpen && this.host.mode() === 'popup') {\r\n this.host.field.restoreTriggerFocus();\r\n }\r\n }\r\n\r\n /** A CDK detach; query and active state reset, composition text is left alone. */\r\n handleDetached(): void {\r\n this.host.layer.detach();\r\n this.host.keyboard.reset();\r\n this.host.field.resetQuery();\r\n }\r\n\r\n /** A presentation change drops the pane and every transient field value. */\r\n resetForMode(): void {\r\n this.destroy(false);\r\n this.host.field.resetQuery();\r\n this.host.keyboard.reset();\r\n }\r\n}\r\n","// Combobox projected templates: the option row and the inline start addon.\r\n\r\nimport { Directive, TemplateRef, inject } from '@angular/core';\r\n\r\nimport { RaqmComboboxItemContext } from './combobox.types';\r\n\r\n/**\r\n * Projected item template for a popup row; renders with the option context (`$implicit`/`item`,\r\n * `selected`, `active`) and must stay noninteractive — the option `label` remains the accessible name.\r\n */\r\n@Directive({\r\n selector: 'ng-template[raqm-combobox-item]',\r\n exportAs: 'raqmComboboxItem',\r\n})\r\nexport class RaqmComboboxItemDirective {\r\n readonly template = inject<TemplateRef<RaqmComboboxItemContext>>(TemplateRef);\r\n}\r\n\r\n/**\r\n * Projected start-addon template for the inline presentation; its content is passive and\r\n * application-owned.\r\n */\r\n@Directive({\r\n selector: 'ng-template[raqm-combobox-prefix]',\r\n exportAs: 'raqmComboboxPrefix',\r\n})\r\nexport class RaqmComboboxPrefixDirective {\r\n readonly template = inject<TemplateRef<unknown>>(TemplateRef);\r\n}\r\n","// Combobox view model: option identity, filtering and the shapes the template renders.\r\n\r\nimport { RaqmComboboxEntry, RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxMode, RaqmComboboxModel, labelContains } from './combobox-model';\r\n\r\nexport interface RaqmComboboxOptionView {\r\n readonly item: RaqmComboboxOption;\r\n readonly id: string;\r\n readonly index: number;\r\n}\r\n\r\nexport interface RaqmComboboxRenderEntry {\r\n label: string | null;\r\n id: string;\r\n options: RaqmComboboxOptionView[];\r\n separatorBefore: boolean;\r\n}\r\n\r\nexport interface RaqmComboboxChipView {\r\n readonly value: string;\r\n readonly label: string;\r\n readonly removable: boolean;\r\n}\r\n\r\nexport function flattenItems(items: readonly RaqmComboboxEntry[]): readonly RaqmComboboxOption[] {\r\n return items.flatMap((entry) => ('options' in entry ? entry.options : [entry]));\r\n}\r\n\r\n// Multiple filters every label; the single-value modes also keep the selected option while it matches.\r\nexport function filterOptions(\r\n items: readonly RaqmComboboxOption[],\r\n query: string,\r\n mode: RaqmComboboxMode,\r\n selectedLabel: string | null,\r\n): readonly RaqmComboboxOption[] {\r\n if (mode !== 'multiple') {\r\n if (!query) {\r\n return items;\r\n }\r\n return items.filter((item) => {\r\n if (\r\n selectedLabel !== null &&\r\n selectedLabel.length === query.length &&\r\n labelContains(selectedLabel, query)\r\n ) {\r\n return true;\r\n }\r\n return labelContains(item.label, query);\r\n });\r\n }\r\n return items.filter((item) => labelContains(item.label, query));\r\n}\r\n\r\n// UTF-16 code units, so an option keeps its DOM identity across filtering.\r\nexport function optionDomId(inputId: string, value: string): string {\r\n const encoded = Array.from({ length: value.length }, (_, i) =>\r\n value.charCodeAt(i).toString(16).padStart(4, '0'),\r\n ).join('');\r\n return `${inputId}-option-${encoded}`;\r\n}\r\n\r\nexport function buildOptionViews(\r\n items: readonly RaqmComboboxOption[],\r\n inputId: string,\r\n): readonly RaqmComboboxOptionView[] {\r\n return items.map((item, index) => ({\r\n item,\r\n id: optionDomId(inputId, item.value),\r\n index,\r\n }));\r\n}\r\n\r\nexport function buildRenderEntries(\r\n items: readonly RaqmComboboxEntry[],\r\n views: readonly RaqmComboboxOptionView[],\r\n listboxId: string,\r\n): readonly RaqmComboboxRenderEntry[] {\r\n const byValue = new Map(views.map((view) => [view.item.value, view]));\r\n return items.flatMap<RaqmComboboxRenderEntry>((entry, index) => {\r\n if ('options' in entry) {\r\n const options = entry.options.flatMap((item) => {\r\n const view = byValue.get(item.value);\r\n return view ? [view] : [];\r\n });\r\n return options.length\r\n ? [\r\n {\r\n label: entry.label,\r\n id: `${listboxId}-group-${index}`,\r\n options,\r\n separatorBefore: entry.separatorBefore === true,\r\n },\r\n ]\r\n : [];\r\n }\r\n const view = byValue.get(entry.value);\r\n return view ? [{ label: null, id: '', options: [view], separatorBefore: false }] : [];\r\n });\r\n}\r\n\r\n// Label of the single-value selection; an unknown value falls back to its own string.\r\nexport function buildSelectedLabel(\r\n selected: RaqmComboboxModel,\r\n items: readonly RaqmComboboxOption[],\r\n): string | null {\r\n if (typeof selected !== 'string') {\r\n return null;\r\n }\r\n const match = items.find((item) => item.value === selected);\r\n return match ? match.label : selected;\r\n}\r\n\r\nexport function buildSelectionRemovable(\r\n selected: RaqmComboboxModel,\r\n items: readonly RaqmComboboxOption[],\r\n): boolean {\r\n return typeof selected !== 'string' || !items.find((item) => item.value === selected)?.disabled;\r\n}\r\n\r\nexport function buildChipViews(\r\n selected: RaqmComboboxModel,\r\n items: readonly RaqmComboboxOption[],\r\n): readonly RaqmComboboxChipView[] {\r\n if (!Array.isArray(selected)) {\r\n return [];\r\n }\r\n return selected.map((value) => {\r\n const match = items.find((item) => item.value === value);\r\n return {\r\n value,\r\n label: match ? match.label : value,\r\n // A disabled option's chip may not be removed; an unknown chip may.\r\n removable: match ? match.disabled !== true : true,\r\n };\r\n });\r\n}\r\n","// Combobox derived state: control ids, filtering and the render shapes.\r\n\r\nimport { computed } from '@angular/core';\r\n\r\nimport { RaqmComboboxMode, RaqmComboboxModel } from './combobox-model';\r\nimport { RaqmComboboxEntry } from './combobox.types';\r\nimport {\r\n buildChipViews,\r\n buildOptionViews,\r\n buildRenderEntries,\r\n buildSelectedLabel,\r\n buildSelectionRemovable,\r\n filterOptions,\r\n flattenItems,\r\n} from './combobox-view';\r\n\r\nexport interface RaqmComboboxViewStateHost {\r\n items(): readonly RaqmComboboxEntry[];\r\n selected(): RaqmComboboxModel;\r\n mode(): RaqmComboboxMode;\r\n inputId(): string;\r\n autoId(): string;\r\n labelledBy(): string | undefined;\r\n label(): string | undefined;\r\n open(): boolean;\r\n query(): string;\r\n composingValue(): string | null;\r\n}\r\n\r\nexport class RaqmComboboxViewState {\r\n readonly resolvedInputId = computed(() => this.host.inputId() || this.host.autoId());\r\n\r\n readonly labelId = computed(() => `${this.resolvedInputId()}-label`);\r\n\r\n /** Id of the popup listbox, referenced by the control's `aria-controls`. */\r\n readonly listboxId = computed(() => `${this.resolvedInputId()}-listbox`);\r\n\r\n readonly popupId = computed(() => `${this.resolvedInputId()}-popup`);\r\n\r\n readonly searchId = computed(() => `${this.resolvedInputId()}-search`);\r\n\r\n // Explicit `labelledBy` wins, else the internal label; the placeholder never names the control.\r\n readonly inputLabelledBy = computed<string | null>(\r\n () => this.host.labelledBy() ?? (this.host.label() ? this.labelId() : null),\r\n );\r\n\r\n readonly flatItems = computed(() => flattenItems(this.host.items()));\r\n\r\n // Multiple filters every label; the single-value modes also keep the selected option while it matches.\r\n readonly filteredItems = computed(() =>\r\n filterOptions(this.flatItems(), this.host.query(), this.host.mode(), this.selectedLabel()),\r\n );\r\n\r\n readonly optionViews = computed(() =>\r\n buildOptionViews(this.filteredItems(), this.resolvedInputId()),\r\n );\r\n\r\n readonly renderEntries = computed(() =>\r\n buildRenderEntries(this.host.items(), this.optionViews(), this.listboxId()),\r\n );\r\n\r\n // Label of the single-value selection; an unknown value falls back to its own string.\r\n readonly selectedLabel = computed<string | null>(() =>\r\n buildSelectedLabel(this.host.selected(), this.flatItems()),\r\n );\r\n\r\n readonly selectionRemovable = computed(() =>\r\n buildSelectionRemovable(this.host.selected(), this.flatItems()),\r\n );\r\n\r\n // Inline field: composition/query while open, selected label while closed.\r\n readonly inlineValue = computed<string>(() => {\r\n const composing = this.host.composingValue();\r\n if (composing !== null) {\r\n return composing;\r\n }\r\n return this.host.open() ? this.host.query() : (this.selectedLabel() ?? '');\r\n });\r\n\r\n readonly chipViews = computed(() => buildChipViews(this.host.selected(), this.flatItems()));\r\n\r\n constructor(private readonly host: RaqmComboboxViewStateHost) {}\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n Injector,\r\n OnDestroy,\r\n OnInit,\r\n Signal,\r\n TemplateRef,\r\n ViewContainerRef,\r\n WritableSignal,\r\n booleanAttribute,\r\n computed,\r\n contentChild,\r\n forwardRef,\r\n inject,\r\n input,\r\n linkedSignal,\r\n output,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { DOCUMENT, NgTemplateOutlet } from '@angular/common';\r\n\r\nimport { InteractivityChecker } from '@angular/cdk/a11y';\r\nimport { Directionality } from '@angular/cdk/bidi';\r\nimport { Overlay } from '@angular/cdk/overlay';\r\nimport { ViewportRuler } from '@angular/cdk/scrolling';\r\n\r\nimport { RaqmButton } from '@raqm/ui/button';\r\nimport { RaqmInput } from '@raqm/ui/input';\r\nimport { RaqmInputGroup } from '@raqm/ui/input-group';\r\n\r\nimport { RaqmComboboxControl } from './combobox-control';\r\nimport { connectComboboxEffects } from './combobox-effects';\r\nimport { RaqmComboboxField } from './combobox-field';\r\nimport { RaqmComboboxKeyboard } from './combobox-keyboard';\r\nimport { RaqmComboboxMode, RaqmComboboxModel, normalizeModel } from './combobox-model';\r\nimport { RaqmComboboxOverlay, resolveComboboxDirection } from './combobox-overlay';\r\nimport { RaqmComboboxPopup } from './combobox-popup';\r\nimport { RaqmComboboxItemDirective, RaqmComboboxPrefixDirective } from './combobox.directive';\r\nimport { RaqmComboboxEntry, RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxViewState } from './combobox-view-state';\r\n\r\nlet nextComboboxId = 0;\r\n\r\n/**\r\n * A searchable combobox in `multiple`, `popup` and `inline` presentations.\r\n *\r\n * @remarks\r\n * The host has no ARIA role or tab stop; the single `input[raqm-input]` is the `role=\"combobox\"`\r\n * control and the popup an overlay `role=\"listbox\"`. Bind one controller only: `writeValue` neither\r\n * emits nor marks touched, a user change emits once, and option values are unique strings.\r\n */\r\n@Component({\r\n selector: 'raqm-combobox',\r\n imports: [RaqmButton, RaqmInput, RaqmInputGroup, NgTemplateOutlet],\r\n templateUrl: './combobox.component.html',\r\n styleUrl: './combobox.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n providers: [\r\n // Forms accessor; `value`/`valueChange` remain the plain two-way API.\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => RaqmCombobox),\r\n multi: true,\r\n },\r\n ],\r\n host: {\r\n class: 'raqm-combobox',\r\n '[attr.data-raqm-mode]': 'mode()',\r\n '[attr.data-raqm-disabled]': 'effectiveDisabled() ? \"true\" : null',\r\n '[attr.data-raqm-invalid]': 'invalid() ? \"true\" : null',\r\n '[attr.data-raqm-open]': 'open() ? \"true\" : null',\r\n },\r\n})\r\nexport class RaqmCombobox implements ControlValueAccessor, OnInit, OnDestroy {\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n private readonly document = inject(DOCUMENT);\r\n private readonly interactivityChecker = inject(InteractivityChecker);\r\n\r\n private readonly overlay = inject(Overlay);\r\n\r\n // Un-throttled resize stream that re-applies the open pane's position and clamp.\r\n private readonly viewportRuler = inject(ViewportRuler);\r\n\r\n private readonly viewContainerRef = inject(ViewContainerRef);\r\n\r\n // Captured so the key manager can be built in `ngOnInit`, which has no injection context.\r\n private readonly injector = inject(Injector);\r\n\r\n private readonly directionality = inject(Directionality, { optional: true });\r\n\r\n private readonly popupTemplate = viewChild.required('popup', {\r\n read: TemplateRef,\r\n });\r\n\r\n private readonly itemTemplateDirective = contentChild(RaqmComboboxItemDirective);\r\n private readonly inlinePrefixDirective = contentChild(RaqmComboboxPrefixDirective);\r\n\r\n private readonly chipsRef = viewChild<ElementRef<HTMLElement>>('chips');\r\n\r\n // `read: ElementRef` is required: `#trigger` sits on the `<button raqm-button>` host.\r\n private readonly triggerRef = viewChild('trigger', {\r\n read: ElementRef<HTMLButtonElement>,\r\n });\r\n\r\n private readonly inlineGroupRef = viewChild('inlineGroup', {\r\n read: ElementRef<HTMLElement>,\r\n });\r\n\r\n private readonly autoId = `raqm-combobox-${++nextComboboxId}`;\r\n\r\n readonly mode = input<RaqmComboboxMode>('multiple');\r\n\r\n readonly items = input.required<readonly RaqmComboboxEntry[]>();\r\n\r\n /** Inline-only passive content in the input group's start addon. */\r\n readonly inlinePrefix = computed(() => this.inlinePrefixDirective()?.template ?? null);\r\n\r\n /** Noninteractive option content; the option label stays the accessible name. */\r\n readonly itemTemplate = computed(() => this.itemTemplateDirective()?.template ?? null);\r\n\r\n /** Popup pane width; `null` follows the anchor width. */\r\n readonly popupWidth = input<string | null>(null);\r\n\r\n /** Inline-axis offset in CSS pixels; negative moves toward inline-start. */\r\n readonly popupAlignOffset = input<number>(0);\r\n\r\n /** A string array in `multiple`, a scalar otherwise. */\r\n readonly value = input<readonly string[] | string | null>(null);\r\n\r\n /** Emits once per committed user change, never while typing. */\r\n readonly valueChange = output<readonly string[] | string | null>();\r\n\r\n /** Explicit disabled state, ORed with a Forms-driven one. */\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n\r\n /** Application-owned invalid state; drives `aria-invalid`. */\r\n readonly invalid = input(false, { transform: booleanAttribute });\r\n\r\n /** Id of the real editable control; generated when absent. */\r\n readonly inputId = input<string>('');\r\n\r\n /** Optional internal label text, rendered as a `<label [for]>`. */\r\n readonly label = input<string | undefined>(undefined);\r\n\r\n /** External label id(s); takes precedence over `label`. */\r\n readonly labelledBy = input<string | undefined>(undefined);\r\n\r\n readonly describedBy = input<string | undefined>(undefined);\r\n\r\n /** Text shown when no item matches the query (multiple/popup). */\r\n readonly placeholder = input<string>('');\r\n\r\n readonly searchPlaceholder = input<string | null>(null);\r\n\r\n readonly emptyText = input<string | null>(null);\r\n\r\n /** Accessible name of a chip's remove button. */\r\n readonly removeLabel = input<string | null>(null);\r\n\r\n /** Explicit direction; falls back to the nearest ancestor. */\r\n readonly dir = input<'ltr' | 'rtl' | undefined>(undefined);\r\n\r\n /** Marks the first match active when typing or opening. */\r\n readonly autoHighlight = input(true, { transform: booleanAttribute });\r\n\r\n /** Inline only: renders the inline-end chevron trigger. */\r\n readonly showTrigger = input(true, { transform: booleanAttribute });\r\n\r\n /** Inline only: replaces the trigger with a clear button while a value exists. */\r\n readonly showClear = input(false, { transform: booleanAttribute });\r\n\r\n readonly clearLabel = input<string | null>(null);\r\n\r\n readonly triggerLabel = input<string | null>(null);\r\n\r\n // Re-derived from `value`/`mode`, so a controlled binding re-asserts ownership of the user's pick.\r\n readonly selected = linkedSignal<RaqmComboboxModel>(() =>\r\n normalizeModel(this.value(), this.mode()),\r\n );\r\n\r\n private readonly view: RaqmComboboxViewState = new RaqmComboboxViewState({\r\n items: () => this.items(),\r\n selected: () => this.selected(),\r\n mode: () => this.mode(),\r\n inputId: () => this.inputId(),\r\n autoId: () => this.autoId,\r\n labelledBy: () => this.labelledBy(),\r\n label: () => this.label(),\r\n open: () => this.open(),\r\n query: () => this.query(),\r\n composingValue: () => this.composingValue(),\r\n });\r\n\r\n readonly resolvedInputId: Signal<string> = this.view.resolvedInputId;\r\n\r\n readonly labelId: Signal<string> = this.view.labelId;\r\n\r\n /** Id of the popup listbox, referenced by the control's `aria-controls`. */\r\n readonly listboxId: Signal<string> = this.view.listboxId;\r\n\r\n readonly popupId: Signal<string> = this.view.popupId;\r\n\r\n readonly searchId: Signal<string> = this.view.searchId;\r\n\r\n readonly inputLabelledBy: Signal<string | null> = this.view.inputLabelledBy;\r\n\r\n readonly flatItems = this.view.flatItems;\r\n\r\n readonly filteredItems = this.view.filteredItems;\r\n\r\n readonly optionViews = this.view.optionViews;\r\n\r\n readonly renderEntries = this.view.renderEntries;\r\n\r\n readonly selectedLabel = this.view.selectedLabel;\r\n\r\n readonly selectionRemovable = this.view.selectionRemovable;\r\n\r\n readonly inlineValue = this.view.inlineValue;\r\n\r\n readonly chipViews = this.view.chipViews;\r\n\r\n private readonly control: RaqmComboboxControl = new RaqmComboboxControl({\r\n mode: () => this.mode(),\r\n selected: () => this.selected(),\r\n setSelected: (value) => this.selected.set(value),\r\n query: () => this.query(),\r\n disabled: () => this.effectiveDisabled(),\r\n selectionRemovable: () => this.selectionRemovable(),\r\n close: (touched) => this.popup.close(touched),\r\n publish: (value) => this.valueChange.emit(value),\r\n });\r\n\r\n readonly effectiveDisabled: Signal<boolean> = computed(\r\n () => this.disabled() || this.control.disabled(),\r\n );\r\n\r\n protected readonly field: RaqmComboboxField = new RaqmComboboxField(\r\n {\r\n open: () => this.open(),\r\n disabled: () => this.effectiveDisabled(),\r\n selectionRemovable: () => this.selectionRemovable(),\r\n chipViews: () => this.chipViews(),\r\n optionViews: () => this.optionViews(),\r\n activeId: () => this.activeId(),\r\n selected: () => this.selected(),\r\n isOptionDisabled: (item) => this.isOptionDisabled(item),\r\n trigger: () => this.triggerRef()?.nativeElement ?? null,\r\n element: () => this.host.nativeElement,\r\n overlayElement: () => this.layer.element,\r\n openPopup: () => this.popup.show(),\r\n close: (touched, restoreFocus) => this.popup.close(touched, restoreFocus),\r\n select: (item) => this.control.commit(item),\r\n emit: (value) => this.control.emit(value),\r\n resetActive: () => this.keyboard.reset(),\r\n reconcileActive: () => this.keyboard.reconcile(this.optionViews()),\r\n markTouched: () => this.control.touch(),\r\n activateOption: (index) => this.keyboard.activateIndex(index, false),\r\n },\r\n this.document,\r\n this.interactivityChecker,\r\n );\r\n\r\n protected readonly keyboard: RaqmComboboxKeyboard = new RaqmComboboxKeyboard(\r\n {\r\n views: () => this.optionViews(),\r\n open: () => this.open(),\r\n disabled: () => this.effectiveDisabled(),\r\n composing: () => this.field.isComposing,\r\n mode: () => this.mode(),\r\n autoHighlight: () => this.autoHighlight(),\r\n query: () => this.query(),\r\n direction: () =>\r\n resolveComboboxDirection(this.dir(), this.host.nativeElement, this.directionality),\r\n isOptionDisabled: (item) => this.isOptionDisabled(item),\r\n chipCount: () => this.chipViews().length,\r\n scrollTo: (id) => this.layer.scrollOptionIntoView(id),\r\n openPopup: () => this.popup.show(),\r\n close: (touched) => this.popup.close(touched),\r\n select: (item) => this.control.commit(item),\r\n removeChip: (index) => this.field.removeAt(index),\r\n focusChip: (index) => this.field.focusChip(index),\r\n focusInput: () => this.field.focusInput(),\r\n leavePopupByTab: (event) => this.field.leavePopupByTab(event),\r\n },\r\n this.injector,\r\n );\r\n\r\n private readonly layer: RaqmComboboxOverlay = new RaqmComboboxOverlay(\r\n this.overlay,\r\n this.viewportRuler,\r\n this.viewContainerRef,\r\n {\r\n element: this.host.nativeElement,\r\n directionality: this.directionality,\r\n anchor: () =>\r\n this.mode() === 'popup'\r\n ? (this.triggerRef()?.nativeElement ?? null)\r\n : this.mode() === 'inline'\r\n ? (this.inlineGroupRef()?.nativeElement ?? null)\r\n : (this.chipsRef()?.nativeElement ?? null),\r\n template: () => this.popupTemplate(),\r\n direction: () =>\r\n resolveComboboxDirection(this.dir(), this.host.nativeElement, this.directionality),\r\n width: () => this.popupWidth(),\r\n alignOffset: () => this.popupAlignOffset(),\r\n onOutside: () => this.popup.close(true, false),\r\n onDetached: () => this.popup.handleDetached(),\r\n },\r\n );\r\n\r\n private readonly popup: RaqmComboboxPopup = new RaqmComboboxPopup({\r\n layer: this.layer,\r\n keyboard: this.keyboard,\r\n field: this.field,\r\n mode: () => this.mode(),\r\n disabled: () => this.effectiveDisabled(),\r\n autoHighlight: () => this.autoHighlight(),\r\n query: () => this.query(),\r\n touched: () => this.control.touch(),\r\n });\r\n\r\n readonly open: WritableSignal<boolean> = this.layer.open;\r\n\r\n readonly overlayDir: WritableSignal<'ltr' | 'rtl'> = this.layer.dir;\r\n\r\n readonly activeId: Signal<string | null> = this.keyboard.activeId;\r\n\r\n // Search text, deliberately separate from the selected value.\r\n readonly query: WritableSignal<string> = this.field.query;\r\n\r\n // Raw IME text, bound instead of the query so composing never filters or interrupts.\r\n readonly composingValue: WritableSignal<string | null> = this.field.composingValue;\r\n\r\n constructor() {\r\n connectComboboxEffects({\r\n mode: () => this.mode(),\r\n popupWidth: () => this.popupWidth(),\r\n alignOffset: () => this.popupAlignOffset(),\r\n dir: () => this.dir(),\r\n open: () => this.open(),\r\n reposition: () => this.layer.reposition(),\r\n flatItems: () => this.flatItems(),\r\n views: () => this.optionViews(),\r\n disabled: () => this.effectiveDisabled(),\r\n selectionRemovable: () => this.selectionRemovable(),\r\n autoHighlight: () => this.autoHighlight(),\r\n close: () => this.popup.close(false),\r\n reconcile: (views) => this.keyboard.reconcile(views),\r\n resetForMode: () => this.popup.resetForMode(),\r\n });\r\n }\r\n\r\n /**\r\n * Creates the key manager once `items` is bound; building it in the constructor would read the\r\n * required `items` input before Angular binds it (`NG0950`).\r\n */\r\n ngOnInit(): void {\r\n this.keyboard.init();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.keyboard.destroy();\r\n this.popup.destroy(false);\r\n }\r\n\r\n isOptionDisabled(item: RaqmComboboxOption): boolean {\r\n return item.disabled === true || (this.mode() !== 'multiple' && !this.selectionRemovable());\r\n }\r\n\r\n /** Writes an external value without emitting or marking touched; normalised per mode. */\r\n writeValue(value: unknown): void {\r\n this.control.writeValue(value);\r\n }\r\n\r\n registerOnChange(fn: (value: RaqmComboboxModel) => void): void {\r\n this.control.registerOnChange(fn);\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.control.registerOnTouched(fn);\r\n }\r\n\r\n /** ORs a Forms disabled state with the explicit input and closes the popup. */\r\n setDisabledState(isDisabled: boolean): void {\r\n this.control.setDisabledState(isDisabled);\r\n }\r\n}\r\n","@if (label(); as labelText) {\r\n <!-- `for` targets the real control id, not the custom-element host. -->\r\n <label class=\"raqm-combobox-label\" [attr.for]=\"resolvedInputId()\" [attr.id]=\"labelId()\">\r\n {{ labelText }}\r\n </label>\r\n}\r\n\r\n@if (mode() === 'multiple') {\r\n <!-- Multiple chip field: the overlay anchor, owning the focus and invalid boundary. -->\r\n <div\r\n #chips\r\n class=\"raqm-combobox-chips\"\r\n [attr.data-raqm-invalid]=\"invalid() ? 'true' : null\"\r\n (pointerdown)=\"field.onChipsPointerDown($event)\"\r\n >\r\n @for (chip of chipViews(); track chip.value) {\r\n <span class=\"raqm-combobox-chip\">\r\n <span class=\"raqm-combobox-chip-label\">{{ chip.label }}</span>\r\n <button\r\n raqm-button=\"ghost\"\r\n type=\"button\"\r\n icon-extra-small\r\n class=\"raqm-combobox-chip-remove\"\r\n [disabled]=\"effectiveDisabled() || !chip.removable\"\r\n [attr.aria-label]=\"removeLabel() ? removeLabel() + ' ' + chip.label : null\"\r\n (click)=\"field.onChipRemoveClick($index, $event)\"\r\n (keydown)=\"keyboard.onChipKeydown($index, $event)\"\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"M18 6 6 18\" />\r\n <path d=\"m6 6 12 12\" />\r\n </svg>\r\n </button>\r\n </span>\r\n }\r\n\r\n <!-- The one editable control; `role=\"combobox\"` and `aria-activedescendant` wire the listbox. -->\r\n <input\r\n raqm-input\r\n type=\"text\"\r\n class=\"raqm-combobox-input raqm-combobox-chip-input\"\r\n role=\"combobox\"\r\n aria-haspopup=\"listbox\"\r\n aria-autocomplete=\"list\"\r\n autocomplete=\"off\"\r\n [attr.id]=\"resolvedInputId()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"open() ? listboxId() : null\"\r\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.aria-describedby]=\"describedBy() ?? null\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [attr.placeholder]=\"placeholder()\"\r\n [disabled]=\"effectiveDisabled()\"\r\n [value]=\"composingValue() ?? query()\"\r\n (pointerdown)=\"field.onInputPointerDown()\"\r\n (input)=\"field.onInput($event)\"\r\n (compositionstart)=\"field.onCompositionStart($event)\"\r\n (compositionend)=\"field.onCompositionEnd($event)\"\r\n (keydown)=\"keyboard.onKeydown($event)\"\r\n (focusout)=\"field.onFocusOut($event)\"\r\n />\r\n </div>\r\n} @else if (mode() === 'inline') {\r\n <!-- Inline: the Input Group is the anchor; the clear button replaces the chevron trigger. -->\r\n <raqm-input-group #inlineGroup class=\"raqm-combobox-inline\">\r\n @if (inlinePrefix(); as prefix) {\r\n <raqm-input-group-addon align=\"inline-start\">\r\n <ng-container [ngTemplateOutlet]=\"prefix\" />\r\n </raqm-input-group-addon>\r\n }\r\n <input\r\n raqm-input\r\n type=\"text\"\r\n class=\"raqm-combobox-input\"\r\n role=\"combobox\"\r\n aria-haspopup=\"listbox\"\r\n aria-autocomplete=\"list\"\r\n autocomplete=\"off\"\r\n [attr.id]=\"resolvedInputId()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"open() ? listboxId() : null\"\r\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.aria-describedby]=\"describedBy() ?? null\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [attr.placeholder]=\"placeholder()\"\r\n [disabled]=\"effectiveDisabled()\"\r\n [value]=\"inlineValue()\"\r\n (focus)=\"field.onInlineFocus($event)\"\r\n (pointerdown)=\"field.onInputPointerDown()\"\r\n (input)=\"field.onInput($event)\"\r\n (compositionstart)=\"field.onCompositionStart($event)\"\r\n (compositionend)=\"field.onCompositionEnd($event)\"\r\n (keydown)=\"keyboard.onKeydown($event)\"\r\n (focusout)=\"field.onFocusOut($event)\"\r\n />\r\n <raqm-input-group-addon align=\"inline-end\">\r\n @if (showClear() && selectedLabel() !== null) {\r\n <button\r\n raqm-button=\"ghost\"\r\n raqm-input-group-button\r\n type=\"button\"\r\n icon-extra-small\r\n class=\"raqm-combobox-clear\"\r\n [attr.aria-label]=\"clearLabel()\"\r\n [disabled]=\"effectiveDisabled() || !selectionRemovable()\"\r\n (click)=\"field.onClearClick($event)\"\r\n >\r\n <svg\r\n class=\"raqm-combobox-clear-icon\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"M18 6 6 18\" />\r\n <path d=\"m6 6 12 12\" />\r\n </svg>\r\n </button>\r\n } @else if (showTrigger()) {\r\n <button\r\n raqm-button=\"ghost\"\r\n raqm-input-group-button\r\n type=\"button\"\r\n icon-extra-small\r\n class=\"raqm-combobox-inline-trigger\"\r\n aria-haspopup=\"listbox\"\r\n [attr.aria-label]=\"triggerLabel()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"open() ? listboxId() : null\"\r\n [disabled]=\"effectiveDisabled()\"\r\n (click)=\"field.onTriggerClick()\"\r\n (keydown)=\"keyboard.onTriggerKeydown($event)\"\r\n >\r\n <svg\r\n class=\"raqm-combobox-trigger-icon\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n </button>\r\n }\r\n </raqm-input-group-addon>\r\n </raqm-input-group>\r\n} @else {\r\n <!-- Popup trigger; it never holds focus while the search field does. -->\r\n <button\r\n raqm-button=\"outline\"\r\n #trigger\r\n type=\"button\"\r\n class=\"raqm-combobox-trigger\"\r\n role=\"combobox\"\r\n aria-haspopup=\"listbox\"\r\n [attr.id]=\"resolvedInputId()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"open() ? listboxId() : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.aria-describedby]=\"describedBy() ?? null\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [disabled]=\"effectiveDisabled()\"\r\n (click)=\"field.onTriggerClick()\"\r\n (keydown)=\"keyboard.onTriggerKeydown($event)\"\r\n (focusout)=\"field.onFocusOut($event)\"\r\n >\r\n <span class=\"raqm-combobox-trigger-value\">{{ selectedLabel() ?? placeholder() }}</span>\r\n <svg\r\n class=\"raqm-combobox-trigger-icon\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n </button>\r\n}\r\n\r\n<!-- Instantiated into a CDK overlay from this view, so component styles apply. -->\r\n<ng-template #popup>\r\n <div\r\n class=\"raqm-combobox-popup\"\r\n [attr.id]=\"popupId()\"\r\n [attr.dir]=\"overlayDir()\"\r\n [attr.data-raqm-anchor]=\"mode()\"\r\n >\r\n @if (mode() === 'popup') {\r\n <!-- Inner search field; deliberately no inner trigger or clear. -->\r\n <raqm-input-group class=\"raqm-combobox-search\">\r\n <input\r\n raqm-input\r\n type=\"text\"\r\n class=\"raqm-combobox-input raqm-combobox-search-input\"\r\n role=\"combobox\"\r\n aria-haspopup=\"listbox\"\r\n aria-autocomplete=\"list\"\r\n autocomplete=\"off\"\r\n [attr.id]=\"searchId()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"listboxId()\"\r\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.aria-describedby]=\"describedBy() ?? null\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [attr.placeholder]=\"searchPlaceholder()\"\r\n [disabled]=\"effectiveDisabled()\"\r\n [value]=\"composingValue() ?? query()\"\r\n (input)=\"field.onInput($event)\"\r\n (compositionstart)=\"field.onCompositionStart($event)\"\r\n (compositionend)=\"field.onCompositionEnd($event)\"\r\n (keydown)=\"keyboard.onKeydown($event)\"\r\n (focusout)=\"field.onFocusOut($event)\"\r\n />\r\n <raqm-input-group-addon align=\"inline-end\"></raqm-input-group-addon>\r\n </raqm-input-group>\r\n }\r\n\r\n <!-- No-results message; the list collapses to zero padding while it shows. -->\r\n @if (filteredItems().length === 0 && emptyText(); as emptyMessage) {\r\n <div class=\"raqm-combobox-empty\">{{ emptyMessage }}</div>\r\n }\r\n\r\n <!-- Real listbox; `aria-multiselectable` only in Multiple. -->\r\n <div\r\n class=\"raqm-combobox-list\"\r\n role=\"listbox\"\r\n [attr.id]=\"listboxId()\"\r\n [attr.aria-multiselectable]=\"mode() === 'multiple' ? 'true' : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.data-raqm-empty]=\"filteredItems().length === 0 ? '' : null\"\r\n >\r\n @for (entry of renderEntries(); track $index) {\r\n @if (entry.separatorBefore && !$first) {\r\n <div class=\"raqm-combobox-separator\" role=\"presentation\" aria-hidden=\"true\"></div>\r\n }\r\n @if (entry.label !== null) {\r\n <div role=\"group\" [attr.aria-labelledby]=\"entry.id\">\r\n <div class=\"raqm-combobox-group-label\" [attr.id]=\"entry.id\">{{ entry.label }}</div>\r\n @for (view of entry.options; track view.id) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"option\"\r\n [ngTemplateOutletContext]=\"{ $implicit: view }\"\r\n />\r\n }\r\n </div>\r\n } @else {\r\n @for (view of entry.options; track view.id) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"option\"\r\n [ngTemplateOutletContext]=\"{ $implicit: view }\"\r\n />\r\n }\r\n }\r\n }\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #option let-view>\r\n <div\r\n class=\"raqm-combobox-option\"\r\n role=\"option\"\r\n [attr.id]=\"view.id\"\r\n [attr.aria-selected]=\"field.isSelected(view.item) ? 'true' : 'false'\"\r\n [attr.aria-disabled]=\"isOptionDisabled(view.item) ? 'true' : null\"\r\n [attr.aria-label]=\"view.item.label\"\r\n [attr.aria-describedby]=\"view.item.description ? view.id + '-description' : null\"\r\n [class.raqm-combobox-option--active]=\"view.id === activeId()\"\r\n [attr.data-raqm-highlighted]=\"view.id === activeId() ? '' : null\"\r\n (pointerdown)=\"$event.preventDefault()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n (pointermove)=\"field.onOptionPointerMove(view, $event)\"\r\n (pointerleave)=\"field.onOptionPointerLeave($event)\"\r\n (click)=\"field.onOptionClick(view.item)\"\r\n >\r\n @if (view.item.description) {\r\n <span class=\"raqm-combobox-option-description\" [attr.id]=\"view.id + '-description'\">{{\r\n view.item.description\r\n }}</span>\r\n }\r\n <span class=\"raqm-combobox-option-indicator\" aria-hidden=\"true\">\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"M20 6 9 17l-5-5\" />\r\n </svg>\r\n </span>\r\n <span class=\"raqm-combobox-option-text\">\r\n @if (itemTemplate(); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: view.item,\r\n item: view.item,\r\n selected: field.isSelected(view.item),\r\n active: view.id === activeId(),\r\n }\"\r\n />\r\n } @else {\r\n {{ view.item.label }}\r\n }\r\n </span>\r\n </div>\r\n</ng-template>\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"raqm-ui-combobox.mjs","names":[],"sources":["../../../projects/ui/combobox/combobox-model.ts","../../../projects/ui/combobox/combobox-control.ts","../../../projects/ui/combobox/combobox-effects.ts","../../../projects/ui/combobox/combobox-field.ts","../../../projects/ui/combobox/combobox-keyboard.ts","../../../projects/ui/combobox/combobox-overlay.ts","../../../projects/ui/combobox/combobox-popup.ts","../../../projects/ui/combobox/combobox.directive.ts","../../../projects/ui/combobox/combobox-view.ts","../../../projects/ui/combobox/combobox-view-state.ts","../../../projects/ui/combobox/combobox.component.ts","../../../projects/ui/combobox/combobox.component.html"],"sourcesContent":["// Combobox value model, query matching and the duplicate-value guard.\r\n\r\nimport { isDevMode } from '@angular/core';\r\n\r\nimport { RaqmComboboxOption } from './combobox.types';\r\n\r\nexport type RaqmComboboxModel = readonly string[] | string | null;\r\n\r\nexport type RaqmComboboxMode = 'multiple' | 'popup' | 'inline';\r\n\r\n// Built once (construction is expensive); locale-aware, case/diacritic-insensitive search.\r\nconst collator = new Intl.Collator(undefined, {\r\n usage: 'search',\r\n sensitivity: 'base',\r\n ignorePunctuation: true,\r\n});\r\n\r\nexport function labelContains(label: string, query: string): boolean {\r\n if (!query) {\r\n return true;\r\n }\r\n for (let i = 0; i <= label.length - query.length; i += 1) {\r\n if (collator.compare(label.slice(i, i + query.length), query) === 0) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n// Non-arrays become empty; non-strings and duplicates are dropped, order kept.\r\nexport function normalizeMultiple(value: unknown): string[] {\r\n if (!Array.isArray(value)) {\r\n return [];\r\n }\r\n const result: string[] = [];\r\n for (const member of value) {\r\n if (typeof member === 'string' && !result.includes(member)) {\r\n result.push(member);\r\n }\r\n }\r\n return result;\r\n}\r\n\r\nexport function normalizePopup(value: unknown): string | null {\r\n return typeof value === 'string' ? value : null;\r\n}\r\n\r\nexport function normalizeModel(value: unknown, mode: RaqmComboboxMode): RaqmComboboxModel {\r\n return mode === 'multiple' ? normalizeMultiple(value) : normalizePopup(value);\r\n}\r\n\r\n// Development-only guard; option values must be unique.\r\nexport function reportDuplicateValues(items: readonly RaqmComboboxOption[]): void {\r\n if (!isDevMode()) {\r\n return;\r\n }\r\n const seen = new Set<string>();\r\n const duplicates = new Set<string>();\r\n for (const item of items) {\r\n if (seen.has(item.value)) {\r\n duplicates.add(item.value);\r\n } else {\r\n seen.add(item.value);\r\n }\r\n }\r\n if (duplicates.size > 0) {\r\n console.error(\r\n `[raqm-combobox] Duplicate option value(s) ${[...duplicates]\r\n .map((value) => JSON.stringify(value))\r\n .join(', ')}; Combobox option values must be unique.`,\r\n );\r\n }\r\n}\r\n","// Combobox value: the Forms accessor and the single selection path.\r\n\r\nimport { ControlValueAccessor } from '@angular/forms';\r\nimport { Signal, signal } from '@angular/core';\r\n\r\nimport { RaqmComboboxMode, RaqmComboboxModel, normalizeModel } from './combobox-model';\r\nimport { RaqmComboboxOption } from './combobox.types';\r\n\r\nexport interface RaqmComboboxControlHost {\r\n mode(): RaqmComboboxMode;\r\n selected(): RaqmComboboxModel;\r\n /** Writes the normalised value without emitting. */\r\n setSelected(value: RaqmComboboxModel): void;\r\n query(): string;\r\n disabled(): boolean;\r\n selectionRemovable(): boolean;\r\n close(touched: boolean): void;\r\n /** Emits the committed value to the consumer. */\r\n publish(value: RaqmComboboxModel): void;\r\n}\r\n\r\nexport class RaqmComboboxControl implements ControlValueAccessor {\r\n private readonly cvaDisabled = signal(false);\r\n\r\n private onChange: ((value: RaqmComboboxModel) => void) | undefined;\r\n private onTouched: (() => void) | undefined;\r\n\r\n /** Forms-driven disabled state, ORed with the explicit input by the caller. */\r\n readonly disabled: Signal<boolean> = this.cvaDisabled.asReadonly();\r\n\r\n constructor(private readonly host: RaqmComboboxControlHost) {}\r\n\r\n /** Writes an external value without emitting or marking touched; normalised per mode. */\r\n writeValue(value: unknown): void {\r\n this.host.setSelected(normalizeModel(value, this.host.mode()));\r\n }\r\n\r\n registerOnChange(fn: (value: RaqmComboboxModel) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n /** ORs a Forms disabled state with the explicit input and closes the popup. */\r\n setDisabledState(isDisabled: boolean): void {\r\n this.cvaDisabled.set(isDisabled);\r\n if (isDisabled) {\r\n this.host.close(false);\r\n }\r\n }\r\n\r\n // One selection path for pointer and keyboard; a repeated single value emits nothing.\r\n commit(item: RaqmComboboxOption): void {\r\n if (this.host.disabled() || item.disabled === true) {\r\n return;\r\n }\r\n if (this.host.mode() === 'multiple') {\r\n const selected = this.host.selected();\r\n const current = Array.isArray(selected) ? (selected as readonly string[]) : [];\r\n const next = current.includes(item.value)\r\n ? current.filter((value) => value !== item.value)\r\n : [...current, item.value];\r\n this.emit(next);\r\n // Stays open on an unfiltered toggle; closes when a filter had been typed.\r\n if (this.host.query().trim() === '') {\r\n return;\r\n }\r\n this.host.close(true);\r\n return;\r\n }\r\n const next = item.value;\r\n // The same scalar emits nothing; a fresh scalar emits once and closes.\r\n if (this.host.selected() === next) {\r\n this.host.close(true);\r\n return;\r\n }\r\n // Replacing a disabled selection would remove it; external value writes bypass this guard.\r\n if (!this.host.selectionRemovable()) {\r\n return;\r\n }\r\n this.emit(next);\r\n this.host.close(true);\r\n }\r\n\r\n /** Stores and publishes a committed value; never called while typing. */\r\n emit(next: RaqmComboboxModel): void {\r\n const normalized = normalizeModel(next, this.host.mode());\r\n this.host.setSelected(normalized);\r\n this.onChange?.(normalized);\r\n this.host.publish(normalized);\r\n }\r\n\r\n touch(): void {\r\n this.onTouched?.();\r\n }\r\n}\r\n","// Combobox effects: presentation reset, the duplicate guard and active descendant upkeep.\r\n\r\nimport { effect, untracked } from '@angular/core';\r\n\r\nimport { RaqmComboboxMode, reportDuplicateValues } from './combobox-model';\r\nimport { RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxOptionView } from './combobox-view';\r\n\r\nexport interface RaqmComboboxEffectsHost {\r\n mode(): RaqmComboboxMode;\r\n popupWidth(): string | null;\r\n alignOffset(): number;\r\n dir(): 'ltr' | 'rtl' | undefined;\r\n open(): boolean;\r\n reposition(): void;\r\n flatItems(): readonly RaqmComboboxOption[];\r\n views(): readonly RaqmComboboxOptionView[];\r\n disabled(): boolean;\r\n selectionRemovable(): boolean;\r\n autoHighlight(): boolean;\r\n close(): void;\r\n reconcile(views: readonly RaqmComboboxOptionView[]): void;\r\n resetForMode(): void;\r\n}\r\n\r\nexport function connectComboboxEffects(host: RaqmComboboxEffectsHost): void {\r\n let lastMode: RaqmComboboxMode | undefined;\r\n\r\n // Resets state on a real presentation change; `selected` re-normalises without emitting.\r\n effect(() => {\r\n const mode = host.mode();\r\n if (mode === lastMode) {\r\n return;\r\n }\r\n const isFirstRender = lastMode === undefined;\r\n lastMode = mode;\r\n untracked(() => {\r\n if (!isFirstRender) {\r\n host.resetForMode();\r\n }\r\n });\r\n });\r\n\r\n // Development-only duplicate-value guard, re-run whenever the items change.\r\n effect(() => reportDuplicateValues(host.flatItems()));\r\n\r\n // Consumer placement changes reach an already-open overlay too.\r\n effect(() => {\r\n host.popupWidth();\r\n host.alignOffset();\r\n host.dir();\r\n if (host.open()) {\r\n untracked(() => host.reposition());\r\n }\r\n });\r\n\r\n // Keeps the active descendant honest after filtering/removal; a fresh query re-marks the first result.\r\n effect(() => {\r\n const views = host.views();\r\n const disabled = host.disabled();\r\n host.selectionRemovable();\r\n host.autoHighlight();\r\n host.open();\r\n if (disabled) {\r\n untracked(() => host.close());\r\n return;\r\n }\r\n untracked(() => host.reconcile(views));\r\n });\r\n}\r\n","// Combobox field: the editable control, chips, pointer presses and focus movement.\r\n\r\nimport { signal } from '@angular/core';\r\n\r\nimport { InteractivityChecker } from '@angular/cdk/a11y';\r\n\r\nimport { RaqmComboboxModel } from './combobox-model';\r\nimport { RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxChipView, RaqmComboboxOptionView } from './combobox-view';\r\n\r\n// Descendants that keep their own activation instead of the chip field's press handler.\r\nconst INTERACTIVE_SELECTOR =\r\n 'button, a[href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\r\n\r\nexport interface RaqmComboboxFieldHost {\r\n open(): boolean;\r\n disabled(): boolean;\r\n selectionRemovable(): boolean;\r\n chipViews(): readonly RaqmComboboxChipView[];\r\n optionViews(): readonly RaqmComboboxOptionView[];\r\n activeId(): string | null;\r\n selected(): RaqmComboboxModel;\r\n /** Precomputed selection membership, so per-option checks are O(1). */\r\n selectedValues(): ReadonlySet<string>;\r\n isOptionDisabled(item: RaqmComboboxOption): boolean;\r\n trigger(): HTMLButtonElement | null;\r\n element(): HTMLElement;\r\n overlayElement(): HTMLElement | undefined;\r\n openPopup(): void;\r\n close(touched: boolean, restoreFocus?: boolean): void;\r\n select(item: RaqmComboboxOption): void;\r\n emit(value: RaqmComboboxModel): void;\r\n resetActive(): void;\r\n reconcileActive(): void;\r\n markTouched(): void;\r\n activateOption(index: number): void;\r\n}\r\n\r\nexport class RaqmComboboxField {\r\n // Search text, deliberately separate from the selected value.\r\n readonly query = signal<string>('');\r\n\r\n // Raw IME text, bound instead of the query so composing never filters or interrupts.\r\n readonly composingValue = signal<string | null>(null);\r\n\r\n // Set while the overlay is disposed, so its focus loss is not taken for a departure.\r\n suppressBlurTouched = false;\r\n\r\n // True inside an IME composition, so a composing Enter never commits.\r\n private composing = false;\r\n\r\n constructor(\r\n private readonly host: RaqmComboboxFieldHost,\r\n private readonly document: Document,\r\n private readonly interactivityChecker: InteractivityChecker,\r\n ) {}\r\n\r\n get isComposing(): boolean {\r\n return this.composing;\r\n }\r\n\r\n /** Clears the query and any composition text on close. */\r\n reset(): void {\r\n this.query.set('');\r\n this.composingValue.set(null);\r\n }\r\n\r\n /** Clears only the query; a CDK detach leaves composition text untouched. */\r\n resetQuery(): void {\r\n this.query.set('');\r\n }\r\n\r\n // Keeps a chip-field press in the input: focuses the control and opens the popup.\r\n onChipsPointerDown(event: PointerEvent): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n // Interactive descendants keep their own activation and caret placement.\r\n const target = event.target as Element | null;\r\n if (target?.closest(INTERACTIVE_SELECTOR)) {\r\n return;\r\n }\r\n event.preventDefault();\r\n this.focusInput();\r\n if (!this.host.open()) {\r\n this.host.openPopup();\r\n }\r\n }\r\n\r\n // Never prevented, so the native caret placement survives.\r\n onInputPointerDown(): void {\r\n if (this.host.disabled() || this.host.open()) {\r\n return;\r\n }\r\n this.host.openPopup();\r\n }\r\n\r\n onInlineFocus(event: FocusEvent): void {\r\n if (this.host.open() || this.host.disabled()) {\r\n return;\r\n }\r\n (event.target as HTMLInputElement).select();\r\n }\r\n\r\n // Emits `null` once, marks touched and returns focus to the field.\r\n onClearClick(event: MouseEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (this.host.disabled() || !this.host.selectionRemovable()) {\r\n return;\r\n }\r\n this.host.emit(null);\r\n this.host.markTouched();\r\n this.focusInput();\r\n }\r\n\r\n onTriggerClick(): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n if (this.host.open()) {\r\n this.host.close(true);\r\n } else {\r\n this.host.openPopup();\r\n }\r\n }\r\n\r\n // Touched only on a genuine departure from the host or popup, never on internal transitions.\r\n onFocusOut(event: FocusEvent): void {\r\n if (this.suppressBlurTouched) {\r\n return;\r\n }\r\n const next = event.relatedTarget as Node | null;\r\n const overlayElement = this.host.overlayElement();\r\n if (next && (this.host.element().contains(next) || overlayElement?.contains(next) === true)) {\r\n return;\r\n }\r\n if (this.host.open()) {\r\n this.host.close(true, false);\r\n } else {\r\n this.host.markTouched();\r\n }\r\n }\r\n\r\n // Updates the query and highlight, never emits; during IME only raw text is mirrored.\r\n onInput(event: Event): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n const input = event.target as HTMLInputElement;\r\n if (this.composing) {\r\n this.composingValue.set(input.value);\r\n return;\r\n }\r\n this.query.set(input.value);\r\n this.applyQueryHighlight(input.value);\r\n }\r\n\r\n onCompositionStart(event: CompositionEvent): void {\r\n this.composing = true;\r\n this.composingValue.set((event.target as HTMLInputElement).value);\r\n }\r\n\r\n onCompositionEnd(event: CompositionEvent): void {\r\n this.composing = false;\r\n this.composingValue.set(null);\r\n const input = event.target as HTMLInputElement;\r\n this.query.set(input.value);\r\n this.applyQueryHighlight(input.value);\r\n }\r\n\r\n // Hover makes the row active so pointer and keyboard agree; touch is ignored.\r\n onOptionPointerMove(view: RaqmComboboxOptionView, event: PointerEvent): void {\r\n if (event.pointerType === 'touch') {\r\n return;\r\n }\r\n if (this.host.isOptionDisabled(view.item) || this.host.activeId() === view.id) {\r\n return;\r\n }\r\n // The view carries its own index; verify it still points at this view before activating.\r\n if (this.host.optionViews()[view.index]?.id !== view.id) {\r\n return;\r\n }\r\n this.host.activateOption(view.index);\r\n }\r\n\r\n // Clears the active option on leaving the list, so the next ArrowDown restarts from the top.\r\n onOptionPointerLeave(event: PointerEvent): void {\r\n if (event.pointerType === 'touch') {\r\n return;\r\n }\r\n const related = event.relatedTarget;\r\n if (related instanceof Element && related.closest('.raqm-combobox-option')) {\r\n return;\r\n }\r\n this.host.resetActive();\r\n }\r\n\r\n onOptionClick(item: RaqmComboboxOption): void {\r\n if (this.host.isOptionDisabled(item)) {\r\n return;\r\n }\r\n this.host.select(item);\r\n }\r\n\r\n isSelected(item: RaqmComboboxOption): boolean {\r\n return this.host.selectedValues().has(item.value);\r\n }\r\n\r\n // The portal sits at the document end, so the next tab stop is found explicitly from the trigger.\r\n leavePopupByTab(event: KeyboardEvent): void {\r\n const trigger = this.host.trigger();\r\n if (!trigger) return;\r\n const overlay = this.host.overlayElement();\r\n const candidates = Array.from(\r\n this.document.querySelectorAll<HTMLElement>(\r\n 'a[href], button, input, select, textarea, [tabindex], [contenteditable=\"true\"]',\r\n ),\r\n ).filter(\r\n (element) => !overlay?.contains(element) && this.interactivityChecker.isTabbable(element),\r\n );\r\n // Positive tabindex precedes zero in sequential focus order; sort stably.\r\n candidates.sort((a, b) => (a.tabIndex || Infinity) - (b.tabIndex || Infinity));\r\n const index = candidates.indexOf(trigger);\r\n const target = index < 0 ? undefined : candidates[index + (event.shiftKey ? -1 : 1)];\r\n if (target) {\r\n event.preventDefault();\r\n target.focus();\r\n this.host.close(true, false);\r\n } else {\r\n trigger.focus();\r\n this.host.close(true, false);\r\n }\r\n }\r\n\r\n onChipRemoveClick(index: number, event: MouseEvent): void {\r\n event.stopPropagation();\r\n this.removeAt(index);\r\n }\r\n\r\n // Removes the chip and restores focus to a neighbour, or the input, if its button held focus.\r\n removeAt(index: number): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n const chip = this.host.chipViews()[index];\r\n if (!chip || !chip.removable) {\r\n return;\r\n }\r\n const removeButton = this.chipButton(index);\r\n const heldFocus =\r\n removeButton !== null && this.host.element().ownerDocument.activeElement === removeButton;\r\n const selected = this.host.selected();\r\n const current = Array.isArray(selected) ? selected : [];\r\n // A removed value that is the active option must not leave a stale active descendant.\r\n const activeView = this.host.optionViews().find((view) => view.item.value === chip.value);\r\n if (activeView && this.host.activeId() === activeView.id) {\r\n this.host.resetActive();\r\n }\r\n this.host.emit(current.filter((value) => value !== chip.value));\r\n if (heldFocus) {\r\n const remaining = this.host.chipViews();\r\n if (remaining.length === 0) {\r\n this.focusInput();\r\n } else {\r\n this.focusChip(Math.min(index, remaining.length - 1));\r\n }\r\n }\r\n }\r\n\r\n focusInput(): void {\r\n const input = this.inputElement();\r\n if (input && !input.disabled) {\r\n input.focus();\r\n }\r\n }\r\n\r\n focusChip(index: number): void {\r\n const button = this.chipButton(index);\r\n if (button && !button.disabled) {\r\n button.focus();\r\n }\r\n }\r\n\r\n restoreTriggerFocus(): void {\r\n const trigger = this.host.trigger();\r\n if (trigger && !trigger.disabled) {\r\n trigger.focus();\r\n }\r\n }\r\n\r\n // Preserves the active option by value; falls back to the first enabled match per autoHighlight.\r\n private applyQueryHighlight(value: string): void {\r\n if (value.trim() !== '' && !this.host.open()) {\r\n this.host.openPopup();\r\n }\r\n this.host.reconcileActive();\r\n }\r\n\r\n // The one editable control: in the host for multiple/inline, in the overlay for popup.\r\n private inputElement(): HTMLInputElement | null {\r\n const inHost = this.host.element().querySelector<HTMLInputElement>('.raqm-combobox-input');\r\n if (inHost) {\r\n return inHost;\r\n }\r\n return (\r\n this.host.overlayElement()?.querySelector<HTMLInputElement>('.raqm-combobox-input') ?? null\r\n );\r\n }\r\n\r\n private chipButton(index: number): HTMLButtonElement | null {\r\n const buttons = this.host\r\n .element()\r\n .querySelectorAll<HTMLButtonElement>('.raqm-combobox-chip-remove');\r\n return buttons[index] ?? null;\r\n }\r\n}\r\n","// Combobox keyboard: the active option, the key manager and every key path.\r\n\r\nimport { Injector, computed, signal } from '@angular/core';\r\n\r\nimport { ActiveDescendantKeyManager, Highlightable } from '@angular/cdk/a11y';\r\n\r\nimport { RaqmComboboxMode } from './combobox-model';\r\nimport { RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxOptionView } from './combobox-view';\r\n\r\nexport interface RaqmComboboxKeyboardHost {\r\n /** Current option views, in render order. */\r\n views(): readonly RaqmComboboxOptionView[];\r\n open(): boolean;\r\n disabled(): boolean;\r\n /** True inside an IME composition, so a composing key never commits. */\r\n composing(): boolean;\r\n mode(): RaqmComboboxMode;\r\n autoHighlight(): boolean;\r\n query(): string;\r\n direction(): 'ltr' | 'rtl';\r\n isOptionDisabled(item: RaqmComboboxOption): boolean;\r\n chipCount(): number;\r\n scrollTo(id: string | null): void;\r\n openPopup(): void;\r\n close(touched: boolean): void;\r\n select(item: RaqmComboboxOption): void;\r\n removeChip(index: number): void;\r\n focusChip(index: number): void;\r\n focusInput(): void;\r\n /** The portal sits at the document end, so the next tab stop is found by the caller. */\r\n leavePopupByTab(event: KeyboardEvent): void;\r\n}\r\n\r\n// Key-manager wrapper: the active row is tracked as an id, never written to the DOM.\r\nclass RaqmComboboxOptionRef implements Highlightable {\r\n constructor(\r\n readonly view: RaqmComboboxOptionView,\r\n private readonly activate: (ref: RaqmComboboxOptionRef) => void,\r\n private readonly isDisabled: (item: RaqmComboboxOption) => boolean,\r\n ) {}\r\n\r\n get disabled(): boolean {\r\n return this.isDisabled(this.view.item);\r\n }\r\n\r\n getLabel(): string {\r\n return this.view.item.label;\r\n }\r\n\r\n setActiveStyles(): void {\r\n this.activate(this);\r\n }\r\n\r\n setInactiveStyles(): void {}\r\n}\r\n\r\nexport class RaqmComboboxKeyboard {\r\n private keyManager: ActiveDescendantKeyManager<RaqmComboboxOptionRef> | undefined;\r\n\r\n // Set for a pointer-origin activation, so hover updates ARIA without scrolling the list.\r\n private suppressActivationScroll = false;\r\n\r\n // The active option's value; drives the highlight and `aria-activedescendant`.\r\n private readonly activeValue = signal<string | null>(null);\r\n\r\n readonly activeId = computed(() => {\r\n if (!this.host.open() || this.host.disabled()) return null;\r\n const value = this.activeValue();\r\n return (\r\n this.host\r\n .views()\r\n .find((view) => view.item.value === value && !this.host.isOptionDisabled(view.item))?.id ??\r\n null\r\n );\r\n });\r\n\r\n // Rebuilt only when filtered items or ids change, so navigation never invalidates the active item.\r\n private readonly optionRefs = computed<RaqmComboboxOptionRef[]>(() =>\r\n this.host.views().map(\r\n (view) =>\r\n new RaqmComboboxOptionRef(\r\n view,\r\n (ref) => {\r\n this.activeValue.set(ref.view.item.value);\r\n // Keep the active row visible, except for pointer activation, which suppresses scrolling.\r\n if (!this.suppressActivationScroll) {\r\n this.host.scrollTo(ref.view.id);\r\n }\r\n },\r\n (item) => this.host.isOptionDisabled(item),\r\n ),\r\n ),\r\n );\r\n\r\n constructor(\r\n private readonly host: RaqmComboboxKeyboardHost,\r\n private readonly injector: Injector,\r\n ) {}\r\n\r\n /**\r\n * Creates the key manager once `items` is bound; building it in the constructor would read the\r\n * required `items` input before Angular binds it (`NG0950`).\r\n */\r\n init(): void {\r\n this.keyManager = new ActiveDescendantKeyManager<RaqmComboboxOptionRef>(\r\n this.optionRefs,\r\n this.injector,\r\n )\r\n .withWrap(false)\r\n .withVerticalOrientation(true)\r\n .withHomeAndEnd(true);\r\n }\r\n\r\n destroy(): void {\r\n this.keyManager?.destroy();\r\n }\r\n\r\n // Opens on ArrowDown/ArrowUp from the closed trigger (the native button covers Enter/Space).\r\n onTriggerKeydown(event: KeyboardEvent): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\r\n event.preventDefault();\r\n if (!this.host.open()) {\r\n this.host.openPopup();\r\n }\r\n }\r\n }\r\n\r\n // Single keyboard path for both presentations; chip navigation runs first in `multiple`.\r\n onKeydown(event: KeyboardEvent): void {\r\n if (this.host.mode() === 'multiple' && this.handleChipNavigation(event)) {\r\n return;\r\n }\r\n // A composing key (or the legacy 229) never commits.\r\n if (this.host.composing() || event.isComposing || event.keyCode === 229) {\r\n return;\r\n }\r\n switch (event.key) {\r\n case 'Escape':\r\n // Escape closes without clearing the selection.\r\n if (this.host.open()) {\r\n event.preventDefault();\r\n this.host.close(true);\r\n }\r\n return;\r\n case 'Tab':\r\n if (this.host.mode() === 'popup' && this.host.open()) this.host.leavePopupByTab(event);\r\n return;\r\n case 'Enter': {\r\n // A single Enter commits the active result.\r\n if (!this.host.open()) {\r\n return;\r\n }\r\n this.reconcile(this.host.views());\r\n const active = this.host.views().find((view) => view.item.value === this.activeValue());\r\n if (active && !this.host.isOptionDisabled(active.item) && !this.host.disabled()) {\r\n event.preventDefault();\r\n this.host.select(active.item);\r\n }\r\n return;\r\n }\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n // Arrows navigate results, opening first, never the selected values.\r\n event.preventDefault();\r\n if (!this.host.open()) {\r\n this.host.openPopup();\r\n } else {\r\n this.reconcile(this.host.views());\r\n this.keyManager?.onKeydown(event);\r\n }\r\n return;\r\n case 'Home':\r\n case 'End':\r\n // Home/End navigate results while open; otherwise the native caret is left untouched.\r\n if (this.host.open()) {\r\n event.preventDefault();\r\n this.reconcile(this.host.views());\r\n this.keyManager?.onKeydown(event);\r\n }\r\n return;\r\n default:\r\n return;\r\n }\r\n }\r\n\r\n // Backspace/Delete remove, RTL-aware arrows move between chips, printable keys refocus the input.\r\n onChipKeydown(index: number, event: KeyboardEvent): void {\r\n if (this.host.disabled()) {\r\n return;\r\n }\r\n const rtl = this.host.direction() === 'rtl';\r\n const previousKey = rtl ? 'ArrowRight' : 'ArrowLeft';\r\n const nextKey = rtl ? 'ArrowLeft' : 'ArrowRight';\r\n switch (event.key) {\r\n case 'Backspace':\r\n case 'Delete':\r\n event.preventDefault();\r\n this.host.removeChip(index);\r\n return;\r\n case previousKey:\r\n event.preventDefault();\r\n if (index > 0) {\r\n this.host.focusChip(index - 1);\r\n } else {\r\n this.host.focusInput();\r\n }\r\n return;\r\n case nextKey:\r\n event.preventDefault();\r\n if (index < this.host.chipCount() - 1) {\r\n this.host.focusChip(index + 1);\r\n } else {\r\n this.host.focusInput();\r\n }\r\n return;\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n if (!this.host.open()) {\r\n this.host.openPopup();\r\n }\r\n return;\r\n default:\r\n if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {\r\n this.host.focusInput();\r\n }\r\n return;\r\n }\r\n }\r\n\r\n /** Moves the active option; pointer activation never scrolls. */\r\n activateIndex(index: number, scroll: boolean): void {\r\n if (!this.keyManager) {\r\n return;\r\n }\r\n if (scroll) {\r\n this.keyManager.setActiveItem(index);\r\n return;\r\n }\r\n // Hover never scrolls; cleared in `finally` so a throw cannot leave scrolling off.\r\n this.suppressActivationScroll = true;\r\n try {\r\n this.keyManager.setActiveItem(index);\r\n } finally {\r\n this.suppressActivationScroll = false;\r\n }\r\n }\r\n\r\n /** Marks the first enabled result active; an all-disabled list is left untouched. */\r\n activateFirst(): void {\r\n const index = this.host.views().findIndex((view) => !this.host.isOptionDisabled(view.item));\r\n if (index === -1) {\r\n return;\r\n }\r\n this.keyManager?.setActiveItem(index);\r\n }\r\n\r\n // CDK keeps old wrappers when items are replaced; rebind by stable value, never by index.\r\n reconcile(views: readonly RaqmComboboxOptionView[]): void {\r\n if (!this.host.open() || this.host.disabled() || !this.keyManager) {\r\n return;\r\n }\r\n const value = this.activeValue();\r\n const index =\r\n value === null\r\n ? -1\r\n : views.findIndex(\r\n (view) => view.item.value === value && !this.host.isOptionDisabled(view.item),\r\n );\r\n if (index >= 0) {\r\n const current = this.optionRefs()[index];\r\n if (this.keyManager.activeItem !== current) this.keyManager.setActiveItem(index);\r\n return;\r\n }\r\n this.reset();\r\n if (this.host.autoHighlight() && this.host.query().trim() !== '') {\r\n this.activateFirst();\r\n }\r\n }\r\n\r\n // Clears item and `activeId` together; an absent `aria-activedescendant` is valid ARIA 1.2.\r\n reset(): void {\r\n this.keyManager?.setActiveItem(-1);\r\n this.activeValue.set(null);\r\n }\r\n\r\n // ArrowLeft at the caret start focuses the last chip; Backspace on an empty field removes it.\r\n private handleChipNavigation(event: KeyboardEvent): boolean {\r\n if (this.host.chipCount() === 0) {\r\n return false;\r\n }\r\n const rtl = this.host.direction() === 'rtl';\r\n const previousKey = rtl ? 'ArrowRight' : 'ArrowLeft';\r\n const input = event.currentTarget as HTMLInputElement;\r\n const caret = input.selectionStart ?? 0;\r\n if (event.key === previousKey && caret === 0) {\r\n event.preventDefault();\r\n this.host.focusChip(this.host.chipCount() - 1);\r\n return true;\r\n }\r\n if (event.key === 'Backspace' && input.value === '') {\r\n event.preventDefault();\r\n this.host.removeChip(this.host.chipCount() - 1);\r\n return true;\r\n }\r\n return false;\r\n }\r\n}\r\n","// Combobox popup pane: creation, positioning, direction and the viewport clamp.\r\n\r\nimport { TemplateRef, ViewContainerRef, signal } from '@angular/core';\r\n\r\nimport { Directionality } from '@angular/cdk/bidi';\r\nimport {\r\n ConnectedPosition,\r\n FlexibleConnectedPositionStrategy,\r\n Overlay,\r\n OverlayConfig,\r\n OverlayRef,\r\n} from '@angular/cdk/overlay';\r\nimport { TemplatePortal } from '@angular/cdk/portal';\r\nimport { ViewportRuler } from '@angular/cdk/scrolling';\r\n\r\nimport { registerOverlayOwnership } from '@raqm/ui/overlay-internal';\r\n\r\n// Gap between the anchor and the popup, in CSS pixels.\r\nconst OVERLAY_GAP = 6;\r\n\r\n// Minimum distance kept from every viewport edge, in CSS pixels.\r\nconst VIEWPORT_MARGIN = 10;\r\n\r\nexport interface RaqmComboboxOverlayHost {\r\n /** The control element; a press inside it is not \"outside\". */\r\n readonly element: HTMLElement;\r\n /** Nearest ancestor direction stream, when one exists. */\r\n readonly directionality: Directionality | null;\r\n /** The element the pane anchors to for the current mode. */\r\n anchor(): HTMLElement | null;\r\n /** The listbox template attached to the pane. */\r\n template(): TemplateRef<unknown>;\r\n /** Current resolved direction. */\r\n direction(): 'ltr' | 'rtl';\r\n /** Consumer width; `null` follows the anchor. */\r\n width(): string | null;\r\n /** Inline-axis offset in CSS pixels. */\r\n alignOffset(): number;\r\n /** A press outside the pane and the control asks to close. */\r\n onOutside(): void;\r\n /** The CDK detached the pane, so the caller syncs its state. */\r\n onDetached(): void;\r\n}\r\n\r\nexport class RaqmComboboxOverlay {\r\n private overlayRef: OverlayRef | undefined;\r\n private releaseOverlayOwnership: (() => void) | undefined;\r\n private outsideSubscription: { unsubscribe(): void } | undefined;\r\n private detachSubscription: { unsubscribe(): void } | undefined;\r\n // Re-applied on resize so the pane re-clamps before the CDK's own throttled pass.\r\n private positionStrategy: FlexibleConnectedPositionStrategy | undefined;\r\n private resizeSubscription: { unsubscribe(): void } | undefined;\r\n private directionSubscription: { unsubscribe(): void } | undefined;\r\n private directionObserver: MutationObserver | undefined;\r\n\r\n readonly open = signal(false);\r\n readonly dir = signal<'ltr' | 'rtl'>('ltr');\r\n\r\n constructor(\r\n private readonly overlay: Overlay,\r\n private readonly viewportRuler: ViewportRuler,\r\n private readonly viewContainerRef: ViewContainerRef,\r\n private readonly host: RaqmComboboxOverlayHost,\r\n ) {}\r\n\r\n get element(): HTMLElement | undefined {\r\n return this.overlayRef?.overlayElement;\r\n }\r\n\r\n get hasPane(): boolean {\r\n return this.overlayRef !== undefined;\r\n }\r\n\r\n /** Creates and attaches the pane; `false` when the mode has no anchor yet. */\r\n openLayer(): boolean {\r\n const anchor = this.host.anchor();\r\n if (!anchor) {\r\n return false;\r\n }\r\n\r\n const direction = this.host.direction();\r\n this.dir.set(direction);\r\n const anchorWidth = anchor.getBoundingClientRect().width;\r\n // Anchor width unless the consumer supplies one.\r\n const width = this.host.width() || anchorWidth;\r\n\r\n const strategy = this.overlay\r\n .position()\r\n .flexibleConnectedTo(anchor)\r\n .withPositions(this.positions())\r\n // Non-modal: repositions on scroll/resize and never locks the page.\r\n .withFlexibleDimensions(true)\r\n .withGrowAfterOpen(true)\r\n .withPush(true)\r\n .withViewportMargin(VIEWPORT_MARGIN);\r\n\r\n const config: OverlayConfig = {\r\n positionStrategy: strategy,\r\n // Reposition rather than block: the page scrolls under the pane, which stays anchored.\r\n scrollStrategy: this.overlay.scrollStrategies.reposition(),\r\n // No backdrop: the control stays clickable while the list is open.\r\n hasBackdrop: false,\r\n panelClass: 'raqm-combobox-overlay-pane',\r\n // A route change disposes the overlay rather than orphaning it.\r\n disposeOnNavigation: true,\r\n width,\r\n direction,\r\n };\r\n\r\n this.positionStrategy = strategy;\r\n this.overlayRef = this.overlay.create(config);\r\n // Published for the SCSS clamp in `combobox-relationships.scss`; single source of truth.\r\n this.overlayRef.overlayElement.style.setProperty(\r\n '--raqm-combobox-viewport-margin',\r\n `${VIEWPORT_MARGIN}px`,\r\n );\r\n // Anchor-side height for the SCSS cap; a cap, never a floor, so `max-h-72` still wins.\r\n this.applyAvailableHeight();\r\n this.overlayRef.attach(new TemplatePortal(this.host.template(), this.viewContainerRef));\r\n this.releaseOverlayOwnership = registerOverlayOwnership(anchor, this.overlayRef);\r\n\r\n this.open.set(true);\r\n this.observeDirection();\r\n\r\n // A press on the control itself is not \"outside\", so the input stays interactive.\r\n this.outsideSubscription = this.overlayRef.outsidePointerEvents().subscribe((event) => {\r\n const target = event.target as Node | null;\r\n if (target && this.host.element.contains(target)) {\r\n return;\r\n }\r\n this.host.onOutside();\r\n });\r\n this.detachSubscription = this.overlayRef.detachments().subscribe(() => this.host.onDetached());\r\n // Un-throttled resize pass: reposition and re-cap before the CDK's own throttled pass.\r\n this.resizeSubscription = this.viewportRuler.change(0).subscribe(() => {\r\n this.updateDirection();\r\n this.applyAnchorWidth();\r\n this.applyAvailableHeight();\r\n this.positionStrategy?.apply();\r\n });\r\n return true;\r\n }\r\n\r\n /** Re-reads direction, anchor width and positions for an open pane. */\r\n reposition(): void {\r\n this.updateDirection();\r\n this.applyAnchorWidth();\r\n this.positionStrategy?.withPositions(this.positions());\r\n this.positionStrategy?.apply();\r\n }\r\n\r\n /** Unsubscribes, releases ownership and clears the pane; returns it for the caller to dispose. */\r\n detach(): OverlayRef | undefined {\r\n const overlayRef = this.overlayRef;\r\n this.stopObservingDirection();\r\n this.releaseOverlayOwnership?.();\r\n this.releaseOverlayOwnership = undefined;\r\n // Unsubscribe before disposing, so our own dispose cannot re-enter the detach handler.\r\n this.outsideSubscription?.unsubscribe();\r\n this.outsideSubscription = undefined;\r\n this.detachSubscription?.unsubscribe();\r\n this.detachSubscription = undefined;\r\n this.resizeSubscription?.unsubscribe();\r\n this.resizeSubscription = undefined;\r\n this.positionStrategy = undefined;\r\n this.overlayRef = undefined;\r\n this.open.set(false);\r\n return overlayRef;\r\n }\r\n\r\n // One bounded assignment, no polling. Bounding-rect deltas are used because `offsetTop` measures\r\n // against `offsetParent` (the positioned popup), not the scroller.\r\n scrollOptionIntoView(id: string | null): void {\r\n const overlayRef = this.overlayRef;\r\n if (!overlayRef || !id) {\r\n return;\r\n }\r\n const list = overlayRef.overlayElement.querySelector<HTMLElement>('.raqm-combobox-list');\r\n const row = Array.from(\r\n overlayRef.overlayElement.querySelectorAll<HTMLElement>('.raqm-combobox-option'),\r\n ).find((option) => option.id === id);\r\n if (!list || !row) {\r\n return;\r\n }\r\n const listRect = list.getBoundingClientRect();\r\n const rowRect = row.getBoundingClientRect();\r\n // Row edge in the scroller's content coordinate system (padding-box origin).\r\n const rowTop = rowRect.top - listRect.top - list.clientTop + list.scrollTop;\r\n const rowBottom = rowRect.bottom - listRect.top - list.clientTop + list.scrollTop;\r\n const viewTop = list.scrollTop;\r\n const viewBottom = viewTop + list.clientHeight;\r\n let target: number | null = null;\r\n if (rowTop < viewTop) {\r\n target = rowTop;\r\n } else if (rowBottom > viewBottom) {\r\n target = rowBottom - list.clientHeight;\r\n }\r\n if (target === null) {\r\n return;\r\n }\r\n const maxScrollTop = Math.max(list.scrollHeight - list.clientHeight, 0);\r\n list.scrollTop = Math.min(Math.max(target, 0), maxScrollTop);\r\n }\r\n\r\n // Below the anchor first, flipping above on collision with the same gap.\r\n private positions(): ConnectedPosition[] {\r\n const offset = Number.isFinite(this.host.alignOffset()) ? this.host.alignOffset() : 0;\r\n const offsetX = this.dir() === 'rtl' ? -offset : offset;\r\n return [\r\n {\r\n originX: 'start',\r\n originY: 'bottom',\r\n overlayX: 'start',\r\n overlayY: 'top',\r\n offsetY: OVERLAY_GAP,\r\n offsetX,\r\n },\r\n {\r\n originX: 'start',\r\n originY: 'top',\r\n overlayX: 'start',\r\n overlayY: 'bottom',\r\n offsetY: -OVERLAY_GAP,\r\n offsetX,\r\n },\r\n ];\r\n }\r\n\r\n // Observed only while the popup exists; explicit `dir` changes go through `reposition`.\r\n private observeDirection(): void {\r\n this.directionSubscription = this.host.directionality?.change.subscribe(() =>\r\n this.updateDirection(),\r\n );\r\n if (typeof MutationObserver === 'undefined') return;\r\n this.directionObserver = new MutationObserver(() => this.updateDirection());\r\n for (\r\n let element: HTMLElement | null = this.host.element;\r\n element;\r\n element = element.parentElement\r\n ) {\r\n this.directionObserver.observe(element, {\r\n attributes: true,\r\n attributeFilter: ['dir', 'class', 'style'],\r\n });\r\n }\r\n }\r\n\r\n private updateDirection(): void {\r\n const ref = this.overlayRef;\r\n if (!ref) return;\r\n const direction = this.host.direction();\r\n if (direction === this.dir()) return;\r\n this.dir.set(direction);\r\n ref.setDirection(direction);\r\n this.positionStrategy?.withPositions(this.positions());\r\n ref.updatePosition();\r\n }\r\n\r\n private stopObservingDirection(): void {\r\n this.directionObserver?.disconnect();\r\n this.directionObserver = undefined;\r\n this.directionSubscription?.unsubscribe();\r\n this.directionSubscription = undefined;\r\n }\r\n\r\n private applyAnchorWidth(): void {\r\n const overlayRef = this.overlayRef;\r\n const anchor = this.host.anchor();\r\n if (!overlayRef || !anchor || !anchor.isConnected) {\r\n return;\r\n }\r\n const width = this.host.width();\r\n const anchorWidth = anchor.getBoundingClientRect().width;\r\n if (!width && (!Number.isFinite(anchorWidth) || anchorWidth <= 0)) {\r\n return;\r\n }\r\n overlayRef.updateSize({ width: width || `${anchorWidth}px` });\r\n }\r\n\r\n // Publishes `--raqm-combobox-available-height`: the roomier anchor side, as a cap and never a floor.\r\n private applyAvailableHeight(): void {\r\n const overlayRef = this.overlayRef;\r\n const anchor = this.host.anchor();\r\n if (!overlayRef || !anchor) {\r\n return;\r\n }\r\n const anchorRect = anchor.getBoundingClientRect();\r\n const viewportHeight = this.viewportRuler.getViewportSize().height;\r\n const below = viewportHeight - anchorRect.bottom - OVERLAY_GAP - VIEWPORT_MARGIN;\r\n const above = anchorRect.top - OVERLAY_GAP - VIEWPORT_MARGIN;\r\n const available = Math.max(below, above, 0);\r\n overlayRef.overlayElement.style.setProperty(\r\n '--raqm-combobox-available-height',\r\n `${available}px`,\r\n );\r\n }\r\n}\r\n\r\n// Direction precedence: explicit `dir`, computed style, then the injected CDK value.\r\nexport function resolveComboboxDirection(\r\n dir: 'ltr' | 'rtl' | undefined,\r\n element: HTMLElement,\r\n directionality: Directionality | null,\r\n): 'ltr' | 'rtl' {\r\n if (dir === 'ltr' || dir === 'rtl') {\r\n return dir;\r\n }\r\n const computed = getComputedStyle(element).direction;\r\n if (computed === 'rtl' || computed === 'ltr') {\r\n return computed;\r\n }\r\n return directionality?.value ?? 'ltr';\r\n}\r\n","// Combobox popup orchestration: open policy, close teardown and the focus handoff.\r\n\r\nimport { RaqmComboboxField } from './combobox-field';\r\nimport { RaqmComboboxKeyboard } from './combobox-keyboard';\r\nimport { RaqmComboboxMode } from './combobox-model';\r\nimport { RaqmComboboxOverlay } from './combobox-overlay';\r\n\r\nexport interface RaqmComboboxPopupHost {\r\n readonly layer: RaqmComboboxOverlay;\r\n readonly keyboard: RaqmComboboxKeyboard;\r\n readonly field: RaqmComboboxField;\r\n mode(): RaqmComboboxMode;\r\n disabled(): boolean;\r\n autoHighlight(): boolean;\r\n query(): string;\r\n /** Marks the control touched after a committed close. */\r\n touched(): void;\r\n}\r\n\r\nexport class RaqmComboboxPopup {\r\n constructor(private readonly host: RaqmComboboxPopupHost) {}\r\n\r\n /** Opens the pane and applies the presentation's focus policy. */\r\n show(): void {\r\n if (this.host.layer.open() || this.host.disabled()) {\r\n return;\r\n }\r\n if (!this.host.layer.openLayer()) {\r\n return;\r\n }\r\n\r\n this.host.keyboard.reset();\r\n if (this.host.mode() === 'popup') {\r\n // The Popup's control lives inside the popup; focus it on open.\r\n this.host.field.focusInput();\r\n } else if (this.host.mode() === 'inline') {\r\n this.host.field.focusInput();\r\n } else if (this.host.autoHighlight() && this.host.query().trim() !== '') {\r\n this.host.keyboard.activateFirst();\r\n }\r\n }\r\n\r\n // Idempotent while closed, so a focus-out close plus the outside press mark touched once.\r\n close(touched: boolean, restoreFocus = true): void {\r\n if (!this.host.layer.open() && !this.host.layer.hasPane) {\r\n return;\r\n }\r\n this.destroy(restoreFocus);\r\n if (touched) {\r\n this.host.touched();\r\n }\r\n }\r\n\r\n // Unsubscribes, disposes and resets transient state. Only Popup restores focus to its trigger: the\r\n // Inline input already holds it, and a genuine departure must not be fought. The popup has no\r\n // enter/exit animation (`animate-none!`), so disposal is synchronous.\r\n destroy(restoreFocus: boolean): void {\r\n const wasOpen = this.host.layer.open();\r\n const overlayRef = this.host.layer.detach();\r\n this.host.keyboard.reset();\r\n this.host.field.reset();\r\n // Disposing the focused input fires a focusout; suppress it, it is not a departure.\r\n this.host.field.suppressBlurTouched = true;\r\n overlayRef?.dispose();\r\n this.host.field.suppressBlurTouched = false;\r\n if (restoreFocus && wasOpen && this.host.mode() === 'popup') {\r\n this.host.field.restoreTriggerFocus();\r\n }\r\n }\r\n\r\n /** A CDK detach; query and active state reset, composition text is left alone. */\r\n handleDetached(): void {\r\n this.host.layer.detach();\r\n this.host.keyboard.reset();\r\n this.host.field.resetQuery();\r\n }\r\n\r\n /** A presentation change drops the pane and every transient field value. */\r\n resetForMode(): void {\r\n this.destroy(false);\r\n this.host.field.resetQuery();\r\n this.host.keyboard.reset();\r\n }\r\n}\r\n","// Combobox projected templates: the option row and the inline start addon.\r\n\r\nimport { Directive, TemplateRef, inject } from '@angular/core';\r\n\r\nimport { RaqmComboboxItemContext } from './combobox.types';\r\n\r\n/**\r\n * Projected item template for a popup row; renders with the option context (`$implicit`/`item`,\r\n * `selected`, `active`) and must stay noninteractive — the option `label` remains the accessible name.\r\n */\r\n@Directive({\r\n selector: 'ng-template[raqm-combobox-item]',\r\n exportAs: 'raqmComboboxItem',\r\n})\r\nexport class RaqmComboboxItemDirective {\r\n readonly template = inject<TemplateRef<RaqmComboboxItemContext>>(TemplateRef);\r\n}\r\n\r\n/**\r\n * Projected start-addon template for the inline presentation; its content is passive and\r\n * application-owned.\r\n */\r\n@Directive({\r\n selector: 'ng-template[raqm-combobox-prefix]',\r\n exportAs: 'raqmComboboxPrefix',\r\n})\r\nexport class RaqmComboboxPrefixDirective {\r\n readonly template = inject<TemplateRef<unknown>>(TemplateRef);\r\n}\r\n","// Combobox view model: option identity, filtering and the shapes the template renders.\r\n\r\nimport { RaqmComboboxEntry, RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxMode, RaqmComboboxModel, labelContains } from './combobox-model';\r\n\r\nexport interface RaqmComboboxOptionView {\r\n readonly item: RaqmComboboxOption;\r\n readonly id: string;\r\n readonly index: number;\r\n}\r\n\r\nexport interface RaqmComboboxRenderEntry {\r\n label: string | null;\r\n id: string;\r\n options: RaqmComboboxOptionView[];\r\n separatorBefore: boolean;\r\n}\r\n\r\nexport interface RaqmComboboxChipView {\r\n readonly value: string;\r\n readonly label: string;\r\n readonly removable: boolean;\r\n}\r\n\r\nexport function flattenItems(items: readonly RaqmComboboxEntry[]): readonly RaqmComboboxOption[] {\r\n return items.flatMap((entry) => ('options' in entry ? entry.options : [entry]));\r\n}\r\n\r\n// Multiple filters every label; the single-value modes also keep the selected option while it matches.\r\nexport function filterOptions(\r\n items: readonly RaqmComboboxOption[],\r\n query: string,\r\n mode: RaqmComboboxMode,\r\n selectedLabel: string | null,\r\n): readonly RaqmComboboxOption[] {\r\n if (mode !== 'multiple') {\r\n if (!query) {\r\n return items;\r\n }\r\n // Hoisted out of the filter: this label/query check does not vary per item.\r\n const selectedMatches =\r\n selectedLabel !== null &&\r\n selectedLabel.length === query.length &&\r\n labelContains(selectedLabel, query);\r\n return items.filter((item) => selectedMatches || labelContains(item.label, query));\r\n }\r\n return items.filter((item) => labelContains(item.label, query));\r\n}\r\n\r\n// UTF-16 code units, so an option keeps its DOM identity across filtering.\r\nexport function optionDomId(inputId: string, value: string): string {\r\n const encoded = Array.from({ length: value.length }, (_, i) =>\r\n value.charCodeAt(i).toString(16).padStart(4, '0'),\r\n ).join('');\r\n return `${inputId}-option-${encoded}`;\r\n}\r\n\r\n// Memoised per input id: refiltering reuses an option's id instead of re-encoding every value.\r\nconst OPTION_ID_CACHE_LIMIT = 1000;\r\n\r\nexport function createOptionIdResolver(inputId: string): (value: string) => string {\r\n const cache = new Map<string, string>();\r\n return (value) => {\r\n const cached = cache.get(value);\r\n if (cached !== undefined) {\r\n return cached;\r\n }\r\n if (cache.size >= OPTION_ID_CACHE_LIMIT) {\r\n // Bounded: a very large or churning list re-encodes rather than growing without limit.\r\n cache.clear();\r\n }\r\n const id = optionDomId(inputId, value);\r\n cache.set(value, id);\r\n return id;\r\n };\r\n}\r\n\r\nexport function buildOptionViews(\r\n items: readonly RaqmComboboxOption[],\r\n optionIdFor: (value: string) => string,\r\n): readonly RaqmComboboxOptionView[] {\r\n return items.map((item, index) => ({\r\n item,\r\n id: optionIdFor(item.value),\r\n index,\r\n }));\r\n}\r\n\r\nexport function buildRenderEntries(\r\n items: readonly RaqmComboboxEntry[],\r\n views: readonly RaqmComboboxOptionView[],\r\n listboxId: string,\r\n): readonly RaqmComboboxRenderEntry[] {\r\n const byValue = new Map(views.map((view) => [view.item.value, view]));\r\n return items.flatMap<RaqmComboboxRenderEntry>((entry, index) => {\r\n if ('options' in entry) {\r\n const options = entry.options.flatMap((item) => {\r\n const view = byValue.get(item.value);\r\n return view ? [view] : [];\r\n });\r\n return options.length\r\n ? [\r\n {\r\n label: entry.label,\r\n id: `${listboxId}-group-${index}`,\r\n options,\r\n separatorBefore: entry.separatorBefore === true,\r\n },\r\n ]\r\n : [];\r\n }\r\n const view = byValue.get(entry.value);\r\n return view ? [{ label: null, id: '', options: [view], separatorBefore: false }] : [];\r\n });\r\n}\r\n\r\n// First occurrence wins, matching the previous `find` lookups for duplicate (invalid) values.\r\nexport function indexOptionsByValue(\r\n items: readonly RaqmComboboxOption[],\r\n): ReadonlyMap<string, RaqmComboboxOption> {\r\n const byValue = new Map<string, RaqmComboboxOption>();\r\n for (const item of items) {\r\n if (!byValue.has(item.value)) {\r\n byValue.set(item.value, item);\r\n }\r\n }\r\n return byValue;\r\n}\r\n\r\n// Label of the single-value selection; an unknown value falls back to its own string.\r\nexport function buildSelectedLabel(\r\n selected: RaqmComboboxModel,\r\n itemsByValue: ReadonlyMap<string, RaqmComboboxOption>,\r\n): string | null {\r\n if (typeof selected !== 'string') {\r\n return null;\r\n }\r\n const match = itemsByValue.get(selected);\r\n return match ? match.label : selected;\r\n}\r\n\r\nexport function buildSelectionRemovable(\r\n selected: RaqmComboboxModel,\r\n itemsByValue: ReadonlyMap<string, RaqmComboboxOption>,\r\n): boolean {\r\n return typeof selected !== 'string' || itemsByValue.get(selected)?.disabled !== true;\r\n}\r\n\r\nexport function buildChipViews(\r\n selected: RaqmComboboxModel,\r\n itemsByValue: ReadonlyMap<string, RaqmComboboxOption>,\r\n): readonly RaqmComboboxChipView[] {\r\n if (!Array.isArray(selected)) {\r\n return [];\r\n }\r\n return selected.map((value) => {\r\n const match = itemsByValue.get(value);\r\n return {\r\n value,\r\n label: match ? match.label : value,\r\n // A disabled option's chip may not be removed; an unknown chip may.\r\n removable: match ? match.disabled !== true : true,\r\n };\r\n });\r\n}\r\n","// Combobox derived state: control ids, filtering and the render shapes.\r\n\r\nimport { computed } from '@angular/core';\r\n\r\nimport { RaqmComboboxMode, RaqmComboboxModel } from './combobox-model';\r\nimport { RaqmComboboxEntry } from './combobox.types';\r\nimport {\r\n buildChipViews,\r\n buildOptionViews,\r\n buildRenderEntries,\r\n buildSelectedLabel,\r\n buildSelectionRemovable,\r\n createOptionIdResolver,\r\n filterOptions,\r\n flattenItems,\r\n indexOptionsByValue,\r\n} from './combobox-view';\r\n\r\nexport interface RaqmComboboxViewStateHost {\r\n items(): readonly RaqmComboboxEntry[];\r\n selected(): RaqmComboboxModel;\r\n mode(): RaqmComboboxMode;\r\n inputId(): string;\r\n autoId(): string;\r\n labelledBy(): string | undefined;\r\n label(): string | undefined;\r\n open(): boolean;\r\n query(): string;\r\n composingValue(): string | null;\r\n}\r\n\r\nexport class RaqmComboboxViewState {\r\n readonly resolvedInputId = computed(() => this.host.inputId() || this.host.autoId());\r\n\r\n readonly labelId = computed(() => `${this.resolvedInputId()}-label`);\r\n\r\n /** Id of the popup listbox, referenced by the control's `aria-controls`. */\r\n readonly listboxId = computed(() => `${this.resolvedInputId()}-listbox`);\r\n\r\n readonly popupId = computed(() => `${this.resolvedInputId()}-popup`);\r\n\r\n readonly searchId = computed(() => `${this.resolvedInputId()}-search`);\r\n\r\n // Explicit `labelledBy` wins, else the internal label; the placeholder never names the control.\r\n readonly inputLabelledBy = computed<string | null>(\r\n () => this.host.labelledBy() ?? (this.host.label() ? this.labelId() : null),\r\n );\r\n\r\n readonly flatItems = computed(() => flattenItems(this.host.items()));\r\n\r\n // Value lookups shared by the selected label, removability and chips instead of O(n) `find`s.\r\n private readonly itemsByValue = computed(() => indexOptionsByValue(this.flatItems()));\r\n\r\n readonly selectedValues = computed<ReadonlySet<string>>(() => {\r\n const selected = this.host.selected();\r\n if (Array.isArray(selected)) {\r\n return new Set(selected);\r\n }\r\n return new Set(selected === null ? [] : [selected]);\r\n });\r\n\r\n // Multiple filters every label; the single-value modes also keep the selected option while it matches.\r\n readonly filteredItems = computed(() => {\r\n const mode = this.host.mode();\r\n // Multiple never reads the selected label, so a selection change must not refilter the list.\r\n const selectedLabel = mode === 'multiple' ? null : this.selectedLabel();\r\n return filterOptions(this.flatItems(), this.host.query(), mode, selectedLabel);\r\n });\r\n\r\n // IDs survive refiltering, so option rows keep their DOM identity and active descendant.\r\n private readonly optionIdFor = computed(() => createOptionIdResolver(this.resolvedInputId()));\r\n\r\n readonly optionViews = computed(() => buildOptionViews(this.filteredItems(), this.optionIdFor()));\r\n\r\n readonly renderEntries = computed(() =>\r\n buildRenderEntries(this.host.items(), this.optionViews(), this.listboxId()),\r\n );\r\n\r\n // Label of the single-value selection; an unknown value falls back to its own string.\r\n readonly selectedLabel = computed<string | null>(() =>\r\n buildSelectedLabel(this.host.selected(), this.itemsByValue()),\r\n );\r\n\r\n readonly selectionRemovable = computed(() =>\r\n buildSelectionRemovable(this.host.selected(), this.itemsByValue()),\r\n );\r\n\r\n // Inline field: composition/query while open, selected label while closed.\r\n readonly inlineValue = computed<string>(() => {\r\n const composing = this.host.composingValue();\r\n if (composing !== null) {\r\n return composing;\r\n }\r\n return this.host.open() ? this.host.query() : (this.selectedLabel() ?? '');\r\n });\r\n\r\n readonly chipViews = computed(() => buildChipViews(this.host.selected(), this.itemsByValue()));\r\n\r\n constructor(private readonly host: RaqmComboboxViewStateHost) {}\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n Injector,\r\n OnDestroy,\r\n OnInit,\r\n Signal,\r\n TemplateRef,\r\n ViewContainerRef,\r\n WritableSignal,\r\n booleanAttribute,\r\n computed,\r\n contentChild,\r\n forwardRef,\r\n inject,\r\n input,\r\n linkedSignal,\r\n output,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { DOCUMENT, NgTemplateOutlet } from '@angular/common';\r\n\r\nimport { InteractivityChecker } from '@angular/cdk/a11y';\r\nimport { Directionality } from '@angular/cdk/bidi';\r\nimport { Overlay } from '@angular/cdk/overlay';\r\nimport { ViewportRuler } from '@angular/cdk/scrolling';\r\n\r\nimport { RaqmButton } from '@raqm/ui/button';\r\nimport { RaqmInput } from '@raqm/ui/input';\r\nimport { RaqmInputGroup } from '@raqm/ui/input-group';\r\n\r\nimport { RaqmComboboxControl } from './combobox-control';\r\nimport { connectComboboxEffects } from './combobox-effects';\r\nimport { RaqmComboboxField } from './combobox-field';\r\nimport { RaqmComboboxKeyboard } from './combobox-keyboard';\r\nimport { RaqmComboboxMode, RaqmComboboxModel, normalizeModel } from './combobox-model';\r\nimport { RaqmComboboxOverlay, resolveComboboxDirection } from './combobox-overlay';\r\nimport { RaqmComboboxPopup } from './combobox-popup';\r\nimport { RaqmComboboxItemDirective, RaqmComboboxPrefixDirective } from './combobox.directive';\r\nimport { RaqmComboboxEntry, RaqmComboboxOption } from './combobox.types';\r\nimport { RaqmComboboxViewState } from './combobox-view-state';\r\n\r\nlet nextComboboxId = 0;\r\n\r\n/**\r\n * A searchable combobox in `multiple`, `popup` and `inline` presentations.\r\n *\r\n * @remarks\r\n * The host has no ARIA role or tab stop; the single `input[raqm-input]` is the `role=\"combobox\"`\r\n * control and the popup an overlay `role=\"listbox\"`. Bind one controller only: `writeValue` neither\r\n * emits nor marks touched, a user change emits once, and option values are unique strings.\r\n */\r\n@Component({\r\n selector: 'raqm-combobox',\r\n imports: [RaqmButton, RaqmInput, RaqmInputGroup, NgTemplateOutlet],\r\n templateUrl: './combobox.component.html',\r\n styleUrl: './combobox.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n providers: [\r\n // Forms accessor; `value`/`valueChange` remain the plain two-way API.\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => RaqmCombobox),\r\n multi: true,\r\n },\r\n ],\r\n host: {\r\n class: 'raqm-combobox',\r\n '[attr.data-raqm-mode]': 'mode()',\r\n '[attr.data-raqm-disabled]': 'effectiveDisabled() ? \"true\" : null',\r\n '[attr.data-raqm-invalid]': 'invalid() ? \"true\" : null',\r\n '[attr.data-raqm-open]': 'open() ? \"true\" : null',\r\n },\r\n})\r\nexport class RaqmCombobox implements ControlValueAccessor, OnInit, OnDestroy {\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n private readonly document = inject(DOCUMENT);\r\n private readonly interactivityChecker = inject(InteractivityChecker);\r\n\r\n private readonly overlay = inject(Overlay);\r\n\r\n // Un-throttled resize stream that re-applies the open pane's position and clamp.\r\n private readonly viewportRuler = inject(ViewportRuler);\r\n\r\n private readonly viewContainerRef = inject(ViewContainerRef);\r\n\r\n // Captured so the key manager can be built in `ngOnInit`, which has no injection context.\r\n private readonly injector = inject(Injector);\r\n\r\n private readonly directionality = inject(Directionality, { optional: true });\r\n\r\n private readonly popupTemplate = viewChild.required('popup', {\r\n read: TemplateRef,\r\n });\r\n\r\n private readonly itemTemplateDirective = contentChild(RaqmComboboxItemDirective);\r\n private readonly inlinePrefixDirective = contentChild(RaqmComboboxPrefixDirective);\r\n\r\n private readonly chipsRef = viewChild<ElementRef<HTMLElement>>('chips');\r\n\r\n // `read: ElementRef` is required: `#trigger` sits on the `<button raqm-button>` host.\r\n private readonly triggerRef = viewChild('trigger', {\r\n read: ElementRef<HTMLButtonElement>,\r\n });\r\n\r\n private readonly inlineGroupRef = viewChild('inlineGroup', {\r\n read: ElementRef<HTMLElement>,\r\n });\r\n\r\n private readonly autoId = `raqm-combobox-${++nextComboboxId}`;\r\n\r\n readonly mode = input<RaqmComboboxMode>('multiple');\r\n\r\n readonly items = input.required<readonly RaqmComboboxEntry[]>();\r\n\r\n /** Inline-only passive content in the input group's start addon. */\r\n readonly inlinePrefix = computed(() => this.inlinePrefixDirective()?.template ?? null);\r\n\r\n /** Noninteractive option content; the option label stays the accessible name. */\r\n readonly itemTemplate = computed(() => this.itemTemplateDirective()?.template ?? null);\r\n\r\n /** Popup pane width; `null` follows the anchor width. */\r\n readonly popupWidth = input<string | null>(null);\r\n\r\n /** Inline-axis offset in CSS pixels; negative moves toward inline-start. */\r\n readonly popupAlignOffset = input<number>(0);\r\n\r\n /** A string array in `multiple`, a scalar otherwise. */\r\n readonly value = input<readonly string[] | string | null>(null);\r\n\r\n /** Emits once per committed user change, never while typing. */\r\n readonly valueChange = output<readonly string[] | string | null>();\r\n\r\n /** Explicit disabled state, ORed with a Forms-driven one. */\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n\r\n /** Application-owned invalid state; drives `aria-invalid`. */\r\n readonly invalid = input(false, { transform: booleanAttribute });\r\n\r\n /** Id of the real editable control; generated when absent. */\r\n readonly inputId = input<string>('');\r\n\r\n /** Optional internal label text, rendered as a `<label [for]>`. */\r\n readonly label = input<string | undefined>(undefined);\r\n\r\n /** External label id(s); takes precedence over `label`. */\r\n readonly labelledBy = input<string | undefined>(undefined);\r\n\r\n readonly describedBy = input<string | undefined>(undefined);\r\n\r\n /** Text shown when no item matches the query (multiple/popup). */\r\n readonly placeholder = input<string>('');\r\n\r\n readonly searchPlaceholder = input<string | null>(null);\r\n\r\n readonly emptyText = input<string | null>(null);\r\n\r\n /** Accessible name of a chip's remove button. */\r\n readonly removeLabel = input<string | null>(null);\r\n\r\n /** Explicit direction; falls back to the nearest ancestor. */\r\n readonly dir = input<'ltr' | 'rtl' | undefined>(undefined);\r\n\r\n /** Marks the first match active when typing or opening. */\r\n readonly autoHighlight = input(true, { transform: booleanAttribute });\r\n\r\n /** Inline only: renders the inline-end chevron trigger. */\r\n readonly showTrigger = input(true, { transform: booleanAttribute });\r\n\r\n /** Inline only: replaces the trigger with a clear button while a value exists. */\r\n readonly showClear = input(false, { transform: booleanAttribute });\r\n\r\n readonly clearLabel = input<string | null>(null);\r\n\r\n readonly triggerLabel = input<string | null>(null);\r\n\r\n // Re-derived from `value`/`mode`, so a controlled binding re-asserts ownership of the user's pick.\r\n readonly selected = linkedSignal<RaqmComboboxModel>(() =>\r\n normalizeModel(this.value(), this.mode()),\r\n );\r\n\r\n private readonly view: RaqmComboboxViewState = new RaqmComboboxViewState({\r\n items: () => this.items(),\r\n selected: () => this.selected(),\r\n mode: () => this.mode(),\r\n inputId: () => this.inputId(),\r\n autoId: () => this.autoId,\r\n labelledBy: () => this.labelledBy(),\r\n label: () => this.label(),\r\n open: () => this.open(),\r\n query: () => this.query(),\r\n composingValue: () => this.composingValue(),\r\n });\r\n\r\n readonly resolvedInputId: Signal<string> = this.view.resolvedInputId;\r\n\r\n readonly labelId: Signal<string> = this.view.labelId;\r\n\r\n /** Id of the popup listbox, referenced by the control's `aria-controls`. */\r\n readonly listboxId: Signal<string> = this.view.listboxId;\r\n\r\n readonly popupId: Signal<string> = this.view.popupId;\r\n\r\n readonly searchId: Signal<string> = this.view.searchId;\r\n\r\n readonly inputLabelledBy: Signal<string | null> = this.view.inputLabelledBy;\r\n\r\n readonly flatItems = this.view.flatItems;\r\n\r\n readonly filteredItems = this.view.filteredItems;\r\n\r\n readonly optionViews = this.view.optionViews;\r\n\r\n readonly renderEntries = this.view.renderEntries;\r\n\r\n readonly selectedLabel = this.view.selectedLabel;\r\n\r\n readonly selectionRemovable = this.view.selectionRemovable;\r\n\r\n readonly inlineValue = this.view.inlineValue;\r\n\r\n readonly chipViews = this.view.chipViews;\r\n\r\n private readonly control: RaqmComboboxControl = new RaqmComboboxControl({\r\n mode: () => this.mode(),\r\n selected: () => this.selected(),\r\n setSelected: (value) => this.selected.set(value),\r\n query: () => this.query(),\r\n disabled: () => this.effectiveDisabled(),\r\n selectionRemovable: () => this.selectionRemovable(),\r\n close: (touched) => this.popup.close(touched),\r\n publish: (value) => this.valueChange.emit(value),\r\n });\r\n\r\n readonly effectiveDisabled: Signal<boolean> = computed(\r\n () => this.disabled() || this.control.disabled(),\r\n );\r\n\r\n protected readonly field: RaqmComboboxField = new RaqmComboboxField(\r\n {\r\n open: () => this.open(),\r\n disabled: () => this.effectiveDisabled(),\r\n selectionRemovable: () => this.selectionRemovable(),\r\n chipViews: () => this.chipViews(),\r\n optionViews: () => this.optionViews(),\r\n activeId: () => this.activeId(),\r\n selected: () => this.selected(),\r\n selectedValues: () => this.view.selectedValues(),\r\n isOptionDisabled: (item) => this.isOptionDisabled(item),\r\n trigger: () => this.triggerRef()?.nativeElement ?? null,\r\n element: () => this.host.nativeElement,\r\n overlayElement: () => this.layer.element,\r\n openPopup: () => this.popup.show(),\r\n close: (touched, restoreFocus) => this.popup.close(touched, restoreFocus),\r\n select: (item) => this.control.commit(item),\r\n emit: (value) => this.control.emit(value),\r\n resetActive: () => this.keyboard.reset(),\r\n reconcileActive: () => this.keyboard.reconcile(this.optionViews()),\r\n markTouched: () => this.control.touch(),\r\n activateOption: (index) => this.keyboard.activateIndex(index, false),\r\n },\r\n this.document,\r\n this.interactivityChecker,\r\n );\r\n\r\n protected readonly keyboard: RaqmComboboxKeyboard = new RaqmComboboxKeyboard(\r\n {\r\n views: () => this.optionViews(),\r\n open: () => this.open(),\r\n disabled: () => this.effectiveDisabled(),\r\n composing: () => this.field.isComposing,\r\n mode: () => this.mode(),\r\n autoHighlight: () => this.autoHighlight(),\r\n query: () => this.query(),\r\n direction: () =>\r\n resolveComboboxDirection(this.dir(), this.host.nativeElement, this.directionality),\r\n isOptionDisabled: (item) => this.isOptionDisabled(item),\r\n chipCount: () => this.chipViews().length,\r\n scrollTo: (id) => this.layer.scrollOptionIntoView(id),\r\n openPopup: () => this.popup.show(),\r\n close: (touched) => this.popup.close(touched),\r\n select: (item) => this.control.commit(item),\r\n removeChip: (index) => this.field.removeAt(index),\r\n focusChip: (index) => this.field.focusChip(index),\r\n focusInput: () => this.field.focusInput(),\r\n leavePopupByTab: (event) => this.field.leavePopupByTab(event),\r\n },\r\n this.injector,\r\n );\r\n\r\n private readonly layer: RaqmComboboxOverlay = new RaqmComboboxOverlay(\r\n this.overlay,\r\n this.viewportRuler,\r\n this.viewContainerRef,\r\n {\r\n element: this.host.nativeElement,\r\n directionality: this.directionality,\r\n anchor: () =>\r\n this.mode() === 'popup'\r\n ? (this.triggerRef()?.nativeElement ?? null)\r\n : this.mode() === 'inline'\r\n ? (this.inlineGroupRef()?.nativeElement ?? null)\r\n : (this.chipsRef()?.nativeElement ?? null),\r\n template: () => this.popupTemplate(),\r\n direction: () =>\r\n resolveComboboxDirection(this.dir(), this.host.nativeElement, this.directionality),\r\n width: () => this.popupWidth(),\r\n alignOffset: () => this.popupAlignOffset(),\r\n onOutside: () => this.popup.close(true, false),\r\n onDetached: () => this.popup.handleDetached(),\r\n },\r\n );\r\n\r\n private readonly popup: RaqmComboboxPopup = new RaqmComboboxPopup({\r\n layer: this.layer,\r\n keyboard: this.keyboard,\r\n field: this.field,\r\n mode: () => this.mode(),\r\n disabled: () => this.effectiveDisabled(),\r\n autoHighlight: () => this.autoHighlight(),\r\n query: () => this.query(),\r\n touched: () => this.control.touch(),\r\n });\r\n\r\n readonly open: WritableSignal<boolean> = this.layer.open;\r\n\r\n readonly overlayDir: WritableSignal<'ltr' | 'rtl'> = this.layer.dir;\r\n\r\n readonly activeId: Signal<string | null> = this.keyboard.activeId;\r\n\r\n // Search text, deliberately separate from the selected value.\r\n readonly query: WritableSignal<string> = this.field.query;\r\n\r\n // Raw IME text, bound instead of the query so composing never filters or interrupts.\r\n readonly composingValue: WritableSignal<string | null> = this.field.composingValue;\r\n\r\n constructor() {\r\n connectComboboxEffects({\r\n mode: () => this.mode(),\r\n popupWidth: () => this.popupWidth(),\r\n alignOffset: () => this.popupAlignOffset(),\r\n dir: () => this.dir(),\r\n open: () => this.open(),\r\n reposition: () => this.layer.reposition(),\r\n flatItems: () => this.flatItems(),\r\n views: () => this.optionViews(),\r\n disabled: () => this.effectiveDisabled(),\r\n selectionRemovable: () => this.selectionRemovable(),\r\n autoHighlight: () => this.autoHighlight(),\r\n close: () => this.popup.close(false),\r\n reconcile: (views) => this.keyboard.reconcile(views),\r\n resetForMode: () => this.popup.resetForMode(),\r\n });\r\n }\r\n\r\n /**\r\n * Creates the key manager once `items` is bound; building it in the constructor would read the\r\n * required `items` input before Angular binds it (`NG0950`).\r\n */\r\n ngOnInit(): void {\r\n this.keyboard.init();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.keyboard.destroy();\r\n this.popup.destroy(false);\r\n }\r\n\r\n isOptionDisabled(item: RaqmComboboxOption): boolean {\r\n return item.disabled === true || (this.mode() !== 'multiple' && !this.selectionRemovable());\r\n }\r\n\r\n /** Writes an external value without emitting or marking touched; normalised per mode. */\r\n writeValue(value: unknown): void {\r\n this.control.writeValue(value);\r\n }\r\n\r\n registerOnChange(fn: (value: RaqmComboboxModel) => void): void {\r\n this.control.registerOnChange(fn);\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.control.registerOnTouched(fn);\r\n }\r\n\r\n /** ORs a Forms disabled state with the explicit input and closes the popup. */\r\n setDisabledState(isDisabled: boolean): void {\r\n this.control.setDisabledState(isDisabled);\r\n }\r\n}\r\n","@if (label(); as labelText) {\r\n <!-- `for` targets the real control id, not the custom-element host. -->\r\n <label class=\"raqm-combobox-label\" [attr.for]=\"resolvedInputId()\" [attr.id]=\"labelId()\">\r\n {{ labelText }}\r\n </label>\r\n}\r\n\r\n@if (mode() === 'multiple') {\r\n <!-- Multiple chip field: the overlay anchor, owning the focus and invalid boundary. -->\r\n <div\r\n #chips\r\n class=\"raqm-combobox-chips\"\r\n [attr.data-raqm-invalid]=\"invalid() ? 'true' : null\"\r\n (pointerdown)=\"field.onChipsPointerDown($event)\"\r\n >\r\n @for (chip of chipViews(); track chip.value) {\r\n <span class=\"raqm-combobox-chip\">\r\n <span class=\"raqm-combobox-chip-label\">{{ chip.label }}</span>\r\n <button\r\n raqm-button=\"ghost\"\r\n type=\"button\"\r\n icon-extra-small\r\n class=\"raqm-combobox-chip-remove\"\r\n [disabled]=\"effectiveDisabled() || !chip.removable\"\r\n [attr.aria-label]=\"removeLabel() ? removeLabel() + ' ' + chip.label : null\"\r\n (click)=\"field.onChipRemoveClick($index, $event)\"\r\n (keydown)=\"keyboard.onChipKeydown($index, $event)\"\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"M18 6 6 18\" />\r\n <path d=\"m6 6 12 12\" />\r\n </svg>\r\n </button>\r\n </span>\r\n }\r\n\r\n <!-- The one editable control; `role=\"combobox\"` and `aria-activedescendant` wire the listbox. -->\r\n <input\r\n raqm-input\r\n type=\"text\"\r\n class=\"raqm-combobox-input raqm-combobox-chip-input\"\r\n role=\"combobox\"\r\n aria-haspopup=\"listbox\"\r\n aria-autocomplete=\"list\"\r\n autocomplete=\"off\"\r\n [attr.id]=\"resolvedInputId()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"open() ? listboxId() : null\"\r\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.aria-describedby]=\"describedBy() ?? null\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [attr.placeholder]=\"placeholder()\"\r\n [disabled]=\"effectiveDisabled()\"\r\n [value]=\"composingValue() ?? query()\"\r\n (pointerdown)=\"field.onInputPointerDown()\"\r\n (input)=\"field.onInput($event)\"\r\n (compositionstart)=\"field.onCompositionStart($event)\"\r\n (compositionend)=\"field.onCompositionEnd($event)\"\r\n (keydown)=\"keyboard.onKeydown($event)\"\r\n (focusout)=\"field.onFocusOut($event)\"\r\n />\r\n </div>\r\n} @else if (mode() === 'inline') {\r\n <!-- Inline: the Input Group is the anchor; the clear button replaces the chevron trigger. -->\r\n <raqm-input-group #inlineGroup class=\"raqm-combobox-inline\">\r\n @if (inlinePrefix(); as prefix) {\r\n <raqm-input-group-addon align=\"inline-start\">\r\n <ng-container [ngTemplateOutlet]=\"prefix\" />\r\n </raqm-input-group-addon>\r\n }\r\n <input\r\n raqm-input\r\n type=\"text\"\r\n class=\"raqm-combobox-input\"\r\n role=\"combobox\"\r\n aria-haspopup=\"listbox\"\r\n aria-autocomplete=\"list\"\r\n autocomplete=\"off\"\r\n [attr.id]=\"resolvedInputId()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"open() ? listboxId() : null\"\r\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.aria-describedby]=\"describedBy() ?? null\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [attr.placeholder]=\"placeholder()\"\r\n [disabled]=\"effectiveDisabled()\"\r\n [value]=\"inlineValue()\"\r\n (focus)=\"field.onInlineFocus($event)\"\r\n (pointerdown)=\"field.onInputPointerDown()\"\r\n (input)=\"field.onInput($event)\"\r\n (compositionstart)=\"field.onCompositionStart($event)\"\r\n (compositionend)=\"field.onCompositionEnd($event)\"\r\n (keydown)=\"keyboard.onKeydown($event)\"\r\n (focusout)=\"field.onFocusOut($event)\"\r\n />\r\n <raqm-input-group-addon align=\"inline-end\">\r\n @if (showClear() && selectedLabel() !== null) {\r\n <button\r\n raqm-button=\"ghost\"\r\n raqm-input-group-button\r\n type=\"button\"\r\n icon-extra-small\r\n class=\"raqm-combobox-clear\"\r\n [attr.aria-label]=\"clearLabel()\"\r\n [disabled]=\"effectiveDisabled() || !selectionRemovable()\"\r\n (click)=\"field.onClearClick($event)\"\r\n >\r\n <svg\r\n class=\"raqm-combobox-clear-icon\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"M18 6 6 18\" />\r\n <path d=\"m6 6 12 12\" />\r\n </svg>\r\n </button>\r\n } @else if (showTrigger()) {\r\n <button\r\n raqm-button=\"ghost\"\r\n raqm-input-group-button\r\n type=\"button\"\r\n icon-extra-small\r\n class=\"raqm-combobox-inline-trigger\"\r\n aria-haspopup=\"listbox\"\r\n [attr.aria-label]=\"triggerLabel()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"open() ? listboxId() : null\"\r\n [disabled]=\"effectiveDisabled()\"\r\n (click)=\"field.onTriggerClick()\"\r\n (keydown)=\"keyboard.onTriggerKeydown($event)\"\r\n >\r\n <svg\r\n class=\"raqm-combobox-trigger-icon\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n </button>\r\n }\r\n </raqm-input-group-addon>\r\n </raqm-input-group>\r\n} @else {\r\n <!-- Popup trigger; it never holds focus while the search field does. -->\r\n <button\r\n raqm-button=\"outline\"\r\n #trigger\r\n type=\"button\"\r\n class=\"raqm-combobox-trigger\"\r\n role=\"combobox\"\r\n aria-haspopup=\"listbox\"\r\n [attr.id]=\"resolvedInputId()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"open() ? listboxId() : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.aria-describedby]=\"describedBy() ?? null\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [disabled]=\"effectiveDisabled()\"\r\n (click)=\"field.onTriggerClick()\"\r\n (keydown)=\"keyboard.onTriggerKeydown($event)\"\r\n (focusout)=\"field.onFocusOut($event)\"\r\n >\r\n <span class=\"raqm-combobox-trigger-value\">{{ selectedLabel() ?? placeholder() }}</span>\r\n <svg\r\n class=\"raqm-combobox-trigger-icon\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n </button>\r\n}\r\n\r\n<!-- Instantiated into a CDK overlay from this view, so component styles apply. -->\r\n<ng-template #popup>\r\n <div\r\n class=\"raqm-combobox-popup\"\r\n [attr.id]=\"popupId()\"\r\n [attr.dir]=\"overlayDir()\"\r\n [attr.data-raqm-anchor]=\"mode()\"\r\n >\r\n @if (mode() === 'popup') {\r\n <!-- Inner search field; deliberately no inner trigger or clear. -->\r\n <raqm-input-group class=\"raqm-combobox-search\">\r\n <input\r\n raqm-input\r\n type=\"text\"\r\n class=\"raqm-combobox-input raqm-combobox-search-input\"\r\n role=\"combobox\"\r\n aria-haspopup=\"listbox\"\r\n aria-autocomplete=\"list\"\r\n autocomplete=\"off\"\r\n [attr.id]=\"searchId()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"listboxId()\"\r\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.aria-describedby]=\"describedBy() ?? null\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [attr.placeholder]=\"searchPlaceholder()\"\r\n [disabled]=\"effectiveDisabled()\"\r\n [value]=\"composingValue() ?? query()\"\r\n (input)=\"field.onInput($event)\"\r\n (compositionstart)=\"field.onCompositionStart($event)\"\r\n (compositionend)=\"field.onCompositionEnd($event)\"\r\n (keydown)=\"keyboard.onKeydown($event)\"\r\n (focusout)=\"field.onFocusOut($event)\"\r\n />\r\n <raqm-input-group-addon align=\"inline-end\"></raqm-input-group-addon>\r\n </raqm-input-group>\r\n }\r\n\r\n <!-- No-results message; the list collapses to zero padding while it shows. -->\r\n @if (filteredItems().length === 0 && emptyText(); as emptyMessage) {\r\n <div class=\"raqm-combobox-empty\">{{ emptyMessage }}</div>\r\n }\r\n\r\n <!-- Real listbox; `aria-multiselectable` only in Multiple. -->\r\n <div\r\n class=\"raqm-combobox-list\"\r\n role=\"listbox\"\r\n [attr.id]=\"listboxId()\"\r\n [attr.aria-multiselectable]=\"mode() === 'multiple' ? 'true' : null\"\r\n [attr.aria-labelledby]=\"inputLabelledBy()\"\r\n [attr.data-raqm-empty]=\"filteredItems().length === 0 ? '' : null\"\r\n >\r\n @for (entry of renderEntries(); track $index) {\r\n @if (entry.separatorBefore && !$first) {\r\n <div class=\"raqm-combobox-separator\" role=\"presentation\" aria-hidden=\"true\"></div>\r\n }\r\n @if (entry.label !== null) {\r\n <div role=\"group\" [attr.aria-labelledby]=\"entry.id\">\r\n <div class=\"raqm-combobox-group-label\" [attr.id]=\"entry.id\">{{ entry.label }}</div>\r\n @for (view of entry.options; track view.id) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"option\"\r\n [ngTemplateOutletContext]=\"{ $implicit: view }\"\r\n />\r\n }\r\n </div>\r\n } @else {\r\n @for (view of entry.options; track view.id) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"option\"\r\n [ngTemplateOutletContext]=\"{ $implicit: view }\"\r\n />\r\n }\r\n }\r\n }\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #option let-view>\r\n <div\r\n class=\"raqm-combobox-option\"\r\n role=\"option\"\r\n [attr.id]=\"view.id\"\r\n [attr.aria-selected]=\"field.isSelected(view.item) ? 'true' : 'false'\"\r\n [attr.aria-disabled]=\"isOptionDisabled(view.item) ? 'true' : null\"\r\n [attr.aria-label]=\"view.item.label\"\r\n [attr.aria-describedby]=\"view.item.description ? view.id + '-description' : null\"\r\n [class.raqm-combobox-option--active]=\"view.id === activeId()\"\r\n [attr.data-raqm-highlighted]=\"view.id === activeId() ? '' : null\"\r\n (pointerdown)=\"$event.preventDefault()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n (pointermove)=\"field.onOptionPointerMove(view, $event)\"\r\n (pointerleave)=\"field.onOptionPointerLeave($event)\"\r\n (click)=\"field.onOptionClick(view.item)\"\r\n >\r\n @if (view.item.description) {\r\n <span class=\"raqm-combobox-option-description\" [attr.id]=\"view.id + '-description'\">{{\r\n view.item.description\r\n }}</span>\r\n }\r\n <span class=\"raqm-combobox-option-indicator\" aria-hidden=\"true\">\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"M20 6 9 17l-5-5\" />\r\n </svg>\r\n </span>\r\n <span class=\"raqm-combobox-option-text\">\r\n @if (itemTemplate(); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: view.item,\r\n item: view.item,\r\n selected: field.isSelected(view.item),\r\n active: view.id === activeId(),\r\n }\"\r\n />\r\n } @else {\r\n {{ view.item.label }}\r\n }\r\n </span>\r\n </div>\r\n</ng-template>\r\n"],"mappings":"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"}