@raintonic/formaui 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -3
- package/LICENSE +21 -0
- package/README.md +80 -26
- package/fesm2022/raintonic-formaui-components-accordion.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-accordion.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-alert.mjs +24 -5
- package/fesm2022/raintonic-formaui-components-alert.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs +38 -9
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-badge.mjs +45 -31
- package/fesm2022/raintonic-formaui-components-badge.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-big-menu.mjs +23 -5
- package/fesm2022/raintonic-formaui-components-big-menu.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-breadcrumb.mjs +24 -7
- package/fesm2022/raintonic-formaui-components-breadcrumb.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-button-group.mjs +6 -6
- package/fesm2022/raintonic-formaui-components-button-group.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-button.mjs +63 -17
- package/fesm2022/raintonic-formaui-components-button.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-card.mjs +8 -8
- package/fesm2022/raintonic-formaui-components-card.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-checkbox.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-checkbox.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-data-table.mjs +67 -9
- package/fesm2022/raintonic-formaui-components-data-table.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-date-picker.mjs +63 -16
- package/fesm2022/raintonic-formaui-components-date-picker.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-drawer.mjs +19 -4
- package/fesm2022/raintonic-formaui-components-drawer.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-file-upload.mjs +25 -5
- package/fesm2022/raintonic-formaui-components-file-upload.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-form-field.mjs +21 -6
- package/fesm2022/raintonic-formaui-components-form-field.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-icon.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-icon.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-input.mjs +1 -1
- package/fesm2022/raintonic-formaui-components-input.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-list.mjs +4 -4
- package/fesm2022/raintonic-formaui-components-list.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-menu.mjs +4 -4
- package/fesm2022/raintonic-formaui-components-menu.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-number-input.mjs +20 -5
- package/fesm2022/raintonic-formaui-components-number-input.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-paginator.mjs +27 -7
- package/fesm2022/raintonic-formaui-components-paginator.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-password-input.mjs +23 -5
- package/fesm2022/raintonic-formaui-components-password-input.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-popover.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-popover.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-progressbar.mjs +32 -7
- package/fesm2022/raintonic-formaui-components-progressbar.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-radio.mjs +6 -5
- package/fesm2022/raintonic-formaui-components-radio.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-select.mjs +19 -4
- package/fesm2022/raintonic-formaui-components-select.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-side-panel.mjs +19 -4
- package/fesm2022/raintonic-formaui-components-side-panel.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-sidebar.mjs +23 -5
- package/fesm2022/raintonic-formaui-components-sidebar.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-skeleton.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-skeleton.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-slider.mjs +23 -5
- package/fesm2022/raintonic-formaui-components-slider.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-spinner.mjs +24 -7
- package/fesm2022/raintonic-formaui-components-spinner.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-stepper.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-stepper.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tab.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-tab.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tag.mjs +21 -4
- package/fesm2022/raintonic-formaui-components-tag.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-time-picker.mjs +26 -7
- package/fesm2022/raintonic-formaui-components-time-picker.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-toggle.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-toggle.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-toolbar.mjs +41 -7
- package/fesm2022/raintonic-formaui-components-toolbar.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tooltip.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-tooltip.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tree-table.mjs +35 -6
- package/fesm2022/raintonic-formaui-components-tree-table.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tree.mjs +23 -5
- package/fesm2022/raintonic-formaui-components-tree.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-core.mjs +25 -1
- package/fesm2022/raintonic-formaui-core.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-services-dialog.mjs +3 -3
- package/fesm2022/raintonic-formaui-services-dialog.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-services-notification.mjs +2 -2
- package/fesm2022/raintonic-formaui-services-notification.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-services-theme.mjs +3 -3
- package/fesm2022/raintonic-formaui-services-theme.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-test-utils.mjs +21 -16
- package/fesm2022/raintonic-formaui-test-utils.mjs.map +1 -1
- package/fesm2022/raintonic-formaui.mjs +1 -1
- package/fesm2022/raintonic-formaui.mjs.map +1 -1
- package/llms-full.txt +34 -25
- package/llms.txt +1 -2
- package/package.json +1 -5
- package/styles/index.scss +2 -2
- package/styles/partials/_motion.scss +25 -0
- package/styles/partials/_theme.scss +6 -5
- package/styles/partials/components/_button.scss +361 -367
- package/styles/partials/themes/_dark.scss +14 -0
- package/styles/partials/themes/_light.scss +14 -0
- package/types/raintonic-formaui-components-alert.d.ts +11 -1
- package/types/raintonic-formaui-components-alert.d.ts.map +1 -1
- package/types/raintonic-formaui-components-autocomplete.d.ts +25 -7
- package/types/raintonic-formaui-components-autocomplete.d.ts.map +1 -1
- package/types/raintonic-formaui-components-badge.d.ts +20 -9
- package/types/raintonic-formaui-components-badge.d.ts.map +1 -1
- package/types/raintonic-formaui-components-big-menu.d.ts +12 -1
- package/types/raintonic-formaui-components-big-menu.d.ts.map +1 -1
- package/types/raintonic-formaui-components-breadcrumb.d.ts +11 -2
- package/types/raintonic-formaui-components-breadcrumb.d.ts.map +1 -1
- package/types/raintonic-formaui-components-button-group.d.ts +6 -6
- package/types/raintonic-formaui-components-button.d.ts +9 -7
- package/types/raintonic-formaui-components-button.d.ts.map +1 -1
- package/types/raintonic-formaui-components-card.d.ts +4 -4
- package/types/raintonic-formaui-components-checkbox.d.ts +1 -1
- package/types/raintonic-formaui-components-data-table.d.ts +56 -16
- package/types/raintonic-formaui-components-data-table.d.ts.map +1 -1
- package/types/raintonic-formaui-components-date-picker.d.ts +32 -4
- package/types/raintonic-formaui-components-date-picker.d.ts.map +1 -1
- package/types/raintonic-formaui-components-drawer.d.ts +10 -1
- package/types/raintonic-formaui-components-drawer.d.ts.map +1 -1
- package/types/raintonic-formaui-components-file-upload.d.ts +12 -1
- package/types/raintonic-formaui-components-file-upload.d.ts.map +1 -1
- package/types/raintonic-formaui-components-form-field.d.ts +12 -2
- package/types/raintonic-formaui-components-form-field.d.ts.map +1 -1
- package/types/raintonic-formaui-components-input.d.ts +1 -1
- package/types/raintonic-formaui-components-number-input.d.ts +11 -2
- package/types/raintonic-formaui-components-number-input.d.ts.map +1 -1
- package/types/raintonic-formaui-components-paginator.d.ts +13 -1
- package/types/raintonic-formaui-components-paginator.d.ts.map +1 -1
- package/types/raintonic-formaui-components-password-input.d.ts +12 -2
- package/types/raintonic-formaui-components-password-input.d.ts.map +1 -1
- package/types/raintonic-formaui-components-progressbar.d.ts +14 -1
- package/types/raintonic-formaui-components-progressbar.d.ts.map +1 -1
- package/types/raintonic-formaui-components-radio.d.ts +2 -1
- package/types/raintonic-formaui-components-radio.d.ts.map +1 -1
- package/types/raintonic-formaui-components-select.d.ts.map +1 -1
- package/types/raintonic-formaui-components-side-panel.d.ts +10 -1
- package/types/raintonic-formaui-components-side-panel.d.ts.map +1 -1
- package/types/raintonic-formaui-components-sidebar.d.ts +12 -1
- package/types/raintonic-formaui-components-sidebar.d.ts.map +1 -1
- package/types/raintonic-formaui-components-slider.d.ts +12 -1
- package/types/raintonic-formaui-components-slider.d.ts.map +1 -1
- package/types/raintonic-formaui-components-spinner.d.ts +12 -2
- package/types/raintonic-formaui-components-spinner.d.ts.map +1 -1
- package/types/raintonic-formaui-components-tag.d.ts +10 -1
- package/types/raintonic-formaui-components-tag.d.ts.map +1 -1
- package/types/raintonic-formaui-components-time-picker.d.ts +14 -2
- package/types/raintonic-formaui-components-time-picker.d.ts.map +1 -1
- package/types/raintonic-formaui-components-toggle.d.ts +1 -1
- package/types/raintonic-formaui-components-toolbar.d.ts +22 -4
- package/types/raintonic-formaui-components-toolbar.d.ts.map +1 -1
- package/types/raintonic-formaui-components-tree-table.d.ts +29 -4
- package/types/raintonic-formaui-components-tree-table.d.ts.map +1 -1
- package/types/raintonic-formaui-components-tree.d.ts +12 -1
- package/types/raintonic-formaui-components-tree.d.ts.map +1 -1
- package/types/raintonic-formaui-core.d.ts +19 -2
- package/types/raintonic-formaui-core.d.ts.map +1 -1
- package/types/raintonic-formaui-services-dialog.d.ts +1 -1
- package/types/raintonic-formaui-services-theme.d.ts +3 -3
- package/types/raintonic-formaui-test-utils.d.ts +15 -2
- package/types/raintonic-formaui-test-utils.d.ts.map +1 -1
- package/types/raintonic-formaui.d.ts +1 -1
- package/fesm2022/raintonic-formaui-components-dynamic-form.mjs +0 -266
- package/fesm2022/raintonic-formaui-components-dynamic-form.mjs.map +0 -1
- package/types/raintonic-formaui-components-dynamic-form.d.ts +0 -412
- package/types/raintonic-formaui-components-dynamic-form.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raintonic-formaui-components-select.mjs","sources":["../../../lib/components/select/select-tokens.ts","../../../lib/components/select/option.component.ts","../../../lib/components/select/select.component.ts","../../../lib/components/select/select.component.html","../../../lib/components/select/raintonic-formaui-components-select.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\n\r\n/**\r\n * Interface representing the parent select contract that options need.\r\n * Used to break the circular dependency between select and option components.\r\n */\r\nexport interface FuiSelectParent {\r\n multiple(): boolean;\r\n _onOptionSelected(option: any): void;\r\n}\r\n\r\n/**\r\n * Injection token used to provide the parent select to options.\r\n */\r\nexport const FUI_SELECT = new InjectionToken<FuiSelectParent>('FUI_SELECT');\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n InputSignal,\r\n OutputEmitterRef,\r\n ElementRef,\r\n inject,\r\n signal,\r\n WritableSignal,\r\n HostListener,\r\n OnDestroy,\r\n AfterViewInit,\r\n} from '@angular/core';\r\n\r\nimport { Subject } from 'rxjs';\r\nimport { FUI_SELECT } from './select-tokens';\r\n\r\n/**\r\n * # FuiOption Component\r\n *\r\n * Individual option component for use within fui-select.\r\n * Works like Angular Material's mat-option with full accessibility support.\r\n *\r\n * ## Features\r\n * - Disabled state support\r\n * - Selection state management\r\n * - Full accessibility support (ARIA attributes)\r\n * - Keyboard navigation support\r\n * - Custom content projection\r\n * - Smooth hover animations\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Option\r\n * ```html\r\n * <fui-select placeholder=\"Select a status\">\r\n * <fui-option value=\"active\">Active</fui-option>\r\n * <fui-option value=\"inactive\">Inactive</fui-option>\r\n * <fui-option value=\"pending\" [disabled]=\"true\">Pending (Disabled)</fui-option>\r\n * </fui-select>\r\n * ```\r\n *\r\n * ### Option with Custom Content\r\n * ```html\r\n * <fui-select placeholder=\"Select a country\">\r\n * <fui-option value=\"us\">\r\n * <fui-icon name=\"flag-us\"></fui-icon>\r\n * United States\r\n * </fui-option>\r\n * <fui-option value=\"ca\">\r\n * <fui-icon name=\"flag-ca\"></fui-icon>\r\n * Canada\r\n * </fui-option>\r\n * </fui-select>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-option',\r\n standalone: true,\r\n imports: [],\r\n template: `\r\n @if (_showCheckmark()) {\r\n <span class=\"fui-option__checkmark\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\r\n <path d=\"M6.5 11.5L3 8l1-1 2.5 2.5L12 4l1 1z\" />\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"fui-option__content\">\r\n <ng-content></ng-content>\r\n </span>\r\n `,\r\n styleUrls: ['./option.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-option',\r\n '[class.fui-option--selected]': '_selected()',\r\n '[class.fui-option--disabled]': 'disabled()',\r\n '[class.fui-option--active]': '_active()',\r\n role: 'option',\r\n '[attr.id]': 'id',\r\n '[attr.aria-selected]': '_selected()',\r\n '[attr.aria-disabled]': 'disabled()',\r\n '[attr.tabindex]': '-1',\r\n },\r\n})\r\nexport class FuiOptionComponent implements OnDestroy, AfterViewInit {\r\n static nextId = 0;\r\n\r\n /**\r\n * The value of the option\r\n */\r\n readonly value: InputSignal<unknown> = input<unknown>(undefined);\r\n\r\n /**\r\n * Whether the option is disabled\r\n * @default false\r\n */\r\n readonly disabled: InputSignal<boolean> = input(false);\r\n\r\n /**\r\n * Event emitted when the option is selected\r\n */\r\n readonly selectionChange: OutputEmitterRef<{ source: FuiOptionComponent; value: unknown }> = output();\r\n\r\n // Internal state\r\n readonly _selected: WritableSignal<boolean> = signal(false);\r\n readonly _active: WritableSignal<boolean> = signal(false);\r\n readonly stateChanges = new Subject<void>();\r\n\r\n // Element reference\r\n private readonly _element: ElementRef<HTMLElement> = inject(ElementRef);\r\n\r\n // Parent select (optional - may not exist if used standalone)\r\n private readonly _parentSelect = inject(FUI_SELECT, { optional: true });\r\n\r\n // Unique ID\r\n readonly id = `fui-option-${FuiOptionComponent.nextId++}`;\r\n\r\n // Show checkmark only in multiple mode when selected\r\n readonly _showCheckmark = signal(false);\r\n\r\n ngAfterViewInit(): void {\r\n // Update checkmark visibility based on parent select's multiple mode\r\n this._updateCheckmarkVisibility();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stateChanges.complete();\r\n }\r\n\r\n // View value (text content)\r\n get viewValue(): string {\r\n return (this._element.nativeElement.textContent || '').trim();\r\n }\r\n\r\n @HostListener('click', ['$event'])\r\n _handleClick(event: Event): void {\r\n if (!this.disabled()) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n // Notify parent select\r\n if (this._parentSelect) {\r\n this._parentSelect._onOptionSelected(this);\r\n } else {\r\n // Standalone usage - emit event\r\n this._emitSelectionChangeEvent();\r\n }\r\n }\r\n }\r\n\r\n @HostListener('mouseenter')\r\n _handleMouseEnter(): void {\r\n if (!this.disabled()) {\r\n this._active.set(true);\r\n }\r\n }\r\n\r\n @HostListener('mouseleave')\r\n _handleMouseLeave(): void {\r\n this._active.set(false);\r\n }\r\n\r\n /**\r\n * Selects the option\r\n */\r\n select(): void {\r\n if (!this._selected()) {\r\n this._selected.set(true);\r\n this._updateCheckmarkVisibility();\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n /**\r\n * Deselects the option\r\n */\r\n deselect(): void {\r\n if (this._selected()) {\r\n this._selected.set(false);\r\n this._updateCheckmarkVisibility();\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n /**\r\n * Sets the option as active (keyboard navigation)\r\n */\r\n setActive(): void {\r\n if (!this._active()) {\r\n this._active.set(true);\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n /**\r\n * Sets the option as inactive\r\n */\r\n setInactive(): void {\r\n if (this._active()) {\r\n this._active.set(false);\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n /**\r\n * Sets focus onto this option\r\n */\r\n focus(): void {\r\n const element = this._element.nativeElement;\r\n if (typeof element.focus === 'function') {\r\n element.focus();\r\n }\r\n }\r\n\r\n /**\r\n * Gets the label to be used when displaying the option\r\n */\r\n getLabel(): string {\r\n return this.viewValue;\r\n }\r\n\r\n /**\r\n * Gets the host element\r\n */\r\n _getHostElement(): HTMLElement {\r\n return this._element.nativeElement;\r\n }\r\n\r\n /** Update checkmark visibility based on selection and multiple mode */\r\n private _updateCheckmarkVisibility(): void {\r\n const isMultiple = this._parentSelect?.multiple() ?? false;\r\n this._showCheckmark.set(isMultiple && this._selected());\r\n }\r\n\r\n /** Emits the selection change event */\r\n private _emitSelectionChangeEvent(): void {\r\n this.selectionChange.emit({ source: this, value: this.value() });\r\n }\r\n}\r\n","import {\r\n AfterContentInit,\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n contentChildren,\r\n DoCheck,\r\n effect,\r\n ElementRef,\r\n inject,\r\n NgZone,\r\n input,\r\n InputSignal,\r\n OnDestroy,\r\n output,\r\n OutputEmitterRef,\r\n signal,\r\n Signal,\r\n ViewChild,\r\n ViewEncapsulation,\r\n WritableSignal,\r\n} from '@angular/core';\r\n\r\nimport {\r\n ControlValueAccessor,\r\n FormGroupDirective,\r\n NG_VALUE_ACCESSOR,\r\n NgControl,\r\n NgForm,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { fromEvent, Subject, Subscription } from 'rxjs';\r\nimport { filter } from 'rxjs/operators';\r\nimport { injectNgControl, updateErrorState, syncRequiredState, syncNgControlDisabled } from '@raintonic/formaui/cdk/form-field';\r\nimport { FUI_FORM_FIELD_CONTROL, FuiFormFieldControl } from '@raintonic/formaui/core';\r\nimport { DefaultErrorStateMatcher, ErrorStateMatcher } from '@raintonic/formaui/core';\r\nimport { FuiOptionComponent } from './option.component';\r\nimport { FuiConnectedPosition, FuiOverlayRef, FuiOverlayService } from '@raintonic/formaui/cdk/overlay';\r\nimport { FUI_SELECT } from './select-tokens';\r\n\r\n/**\r\n * Available select sizes\r\n */\r\nexport type FuiSelectSize = 'sm' | 'md' | 'lg';\r\n\r\n/**\r\n * Available select variants following Carbon Design System patterns\r\n */\r\nexport type FuiSelectVariant = 'outlined' | 'filled';\r\n\r\n/**\r\n * Selection change event object emitted when the select's selection changes\r\n */\r\nexport interface FuiSelectChange {\r\n source: FuiSelectComponent;\r\n value: unknown;\r\n}\r\n\r\n/**\r\n * # fui-select Component\r\n *\r\n * A select component designed to work seamlessly with fui-form-field.\r\n * Similar to Angular Material's mat-select integration with mat-form-field.\r\n * Provides full Reactive Forms support with validation and error handling.\r\n *\r\n * ## Features\r\n * - Works inside fui-form-field like mat-select\r\n * - Full Reactive Forms integration (ControlValueAccessor)\r\n * - Multiple selection support\r\n * - Options via projected content (fui-option)\r\n * - Disabled and readonly states\r\n * - Full accessibility support\r\n * - Full keyboard navigation (Arrow keys, Enter, Space, Escape, Home, End)\r\n * - Type-ahead search functionality\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Select with Form Field\r\n * ```html\r\n * <fui-form-field>\r\n * <label>Country</label>\r\n * <fui-select placeholder=\"Select a country\">\r\n * <fui-option value=\"us\">United States</fui-option>\r\n * <fui-option value=\"ca\">Canada</fui-option>\r\n * <fui-option value=\"mx\">Mexico</fui-option>\r\n * </fui-select>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### With Reactive Forms and Validation\r\n * ```html\r\n * <form [formGroup]=\"form\">\r\n * <fui-form-field>\r\n * <label>Country</label>\r\n * <fui-select formControlName=\"country\" placeholder=\"Select a country\">\r\n * <fui-option value=\"us\">United States</fui-option>\r\n * <fui-option value=\"ca\">Canada</fui-option>\r\n * </fui-select>\r\n * <fui-error *ngIf=\"form.get('country')?.hasError('required')\">\r\n * Country is required\r\n * </fui-error>\r\n * </fui-form-field>\r\n * </form>\r\n * ```\r\n *\r\n * ### Multiple Selection\r\n * ```html\r\n * <fui-form-field>\r\n * <label>Skills</label>\r\n * <fui-select formControlName=\"skills\" [multiple]=\"true\">\r\n * <fui-option value=\"js\">JavaScript</fui-option>\r\n * <fui-option value=\"ts\">TypeScript</fui-option>\r\n * <fui-option value=\"py\">Python</fui-option>\r\n * </fui-select>\r\n * </fui-form-field>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-select',\r\n standalone: true,\r\n imports: [ReactiveFormsModule],\r\n templateUrl: './select.component.html',\r\n styleUrls: ['./select.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-select',\r\n '[attr.id]': 'id',\r\n '[class.fui-select--open]': 'panelOpen()',\r\n '[class.fui-select--disabled]': 'disabled()',\r\n '[class.fui-select--multiple]': 'multiple()',\r\n '[class.fui-select--readonly]': '_readOnly()',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: FuiSelectComponent,\r\n multi: true,\r\n },\r\n {\r\n provide: FUI_FORM_FIELD_CONTROL,\r\n useExisting: FuiSelectComponent,\r\n },\r\n {\r\n provide: FUI_SELECT,\r\n useExisting: FuiSelectComponent,\r\n },\r\n ],\r\n})\r\nexport class FuiSelectComponent\r\n implements ControlValueAccessor, FuiFormFieldControl, DoCheck, OnDestroy, AfterContentInit\r\n{\r\n // Static properties\r\n static nextId = 0;\r\n readonly controlType = 'fui-select';\r\n\r\n // Inputs using new signal-based API\r\n readonly placeholderInput: InputSignal<string> = input('', { alias: 'placeholder' });\r\n readonly disabledInput: InputSignal<boolean> = input(false, { alias: 'disabled' });\r\n readonly readonly: InputSignal<boolean> = input(false);\r\n readonly multiple: InputSignal<boolean> = input(false);\r\n readonly errorStateMatcher: InputSignal<ErrorStateMatcher | null> = input<ErrorStateMatcher | null>(null);\r\n\r\n /**\r\n * Whether to compare option values using object identity or deep equality\r\n */\r\n readonly compareWith: InputSignal<(o1: unknown, o2: unknown) => boolean> = input<\r\n (o1: unknown, o2: unknown) => boolean\r\n >((o1, o2) => o1 === o2);\r\n\r\n // Outputs\r\n readonly valueChange: OutputEmitterRef<unknown> = output<unknown>();\r\n readonly selectionChange: OutputEmitterRef<FuiSelectChange> = output<FuiSelectChange>();\r\n readonly openedChange: OutputEmitterRef<boolean> = output<boolean>();\r\n\r\n // Internal state signals\r\n private readonly _value: WritableSignal<unknown> = signal(null);\r\n private readonly _focused: WritableSignal<boolean> = signal(false);\r\n private readonly _disabled: WritableSignal<boolean> = signal(false);\r\n readonly _readOnly: WritableSignal<boolean> = signal(false);\r\n\r\n // FuiFormFieldControl implementation\r\n readonly stateChanges = new Subject<void>();\r\n private _uid = `fui-select-${FuiSelectComponent.nextId++}`;\r\n _ariaDescribedby: string | null = null;\r\n\r\n // Error state\r\n private readonly _errorState: WritableSignal<boolean> = signal(false);\r\n readonly errorState = this._errorState;\r\n\r\n // Form control references\r\n private _parentForm = inject(NgForm, { optional: true });\r\n private _parentFormGroup = inject(FormGroupDirective, { optional: true });\r\n private _defaultErrorStateMatcher = inject(DefaultErrorStateMatcher);\r\n private readonly _ngControlRef = injectNgControl();\r\n get ngControl(): NgControl | null {\r\n return this._ngControlRef.ngControl;\r\n }\r\n\r\n // Interface implementation\r\n readonly placeholder = computed(() => this.placeholderInput());\r\n private readonly _required: WritableSignal<boolean> = signal(false);\r\n readonly required = this._required;\r\n\r\n readonly value = this._value;\r\n\r\n readonly focused = this._focused;\r\n\r\n private readonly _ngControlDisabled: WritableSignal<boolean> = signal(false);\r\n readonly disabled = computed(() => this._disabled() || this.disabledInput() || this._ngControlDisabled());\r\n\r\n readonly empty = computed(() => {\r\n const val = this._value();\r\n return val === null || val === undefined || (this.isArray(val) && val.length === 0);\r\n });\r\n\r\n readonly id = this._uid;\r\n\r\n // ViewChild for trigger and panel\r\n @ViewChild('trigger', { static: false }) trigger?: ElementRef<HTMLDivElement>;\r\n @ViewChild('panel', { static: false }) panel?: ElementRef<HTMLDivElement>;\r\n\r\n // ContentChildren for options\r\n readonly options = contentChildren(FuiOptionComponent, { descendants: true });\r\n\r\n // Panel open/close state\r\n readonly panelOpen = signal(false);\r\n\r\n // Active option index for keyboard navigation\r\n private readonly _activeOptionIndex: WritableSignal<number> = signal(-1);\r\n readonly activeOptionIndex = this._activeOptionIndex.asReadonly();\r\n\r\n // Live announcement for screen readers\r\n readonly _liveAnnouncement: WritableSignal<string> = signal('');\r\n\r\n // Overlay reference\r\n private _overlayRef: FuiOverlayRef | null = null;\r\n private _overlaySubscriptions = new Subscription();\r\n\r\n // Services\r\n private readonly _overlayService = inject(FuiOverlayService);\r\n private readonly _elementRef = inject(ElementRef);\r\n private readonly _document = inject(DOCUMENT);\r\n private readonly _ngZone = inject(NgZone);\r\n private _outsideClickSub?: Subscription;\r\n\r\n // Type-ahead search\r\n private _typeaheadBuffer = '';\r\n private _typeaheadTimeout: ReturnType<typeof setTimeout> | null = null;\r\n private readonly TYPE_AHEAD_DEBOUNCE = 200;\r\n\r\n // ControlValueAccessor callbacks\r\n private _onChange: (value: unknown) => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n private _onTouched: () => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n\r\n // Computed properties\r\n readonly displayValue: Signal<string> = computed(() => {\r\n const currentValue = this.value();\r\n const opts = this.options();\r\n\r\n if (currentValue === null || currentValue === undefined) {\r\n return '';\r\n }\r\n\r\n // Filter out options that don't have a value set yet\r\n const validOpts = opts.filter((opt) => opt.value() !== undefined);\r\n\r\n if (this.multiple()) {\r\n if (this.isArray(currentValue)) {\r\n const selectedOptions = validOpts.filter((opt) =>\r\n currentValue.some((v: unknown) => this.compareWith()(v, opt.value())),\r\n );\r\n return selectedOptions.map((opt) => opt.getLabel()).join(', ');\r\n }\r\n return '';\r\n } else {\r\n const selectedOption = validOpts.find((opt) => this.compareWith()(opt.value(), currentValue));\r\n return selectedOption ? selectedOption.getLabel() : String(currentValue);\r\n }\r\n });\r\n\r\n constructor() {\r\n // Set valueAccessor after NgControl is resolved\r\n void Promise.resolve().then(() => {\r\n if (this._ngControlRef.ngControl) {\r\n this._ngControlRef.ngControl.valueAccessor = this;\r\n }\r\n });\r\n\r\n // Effect to emit state changes\r\n effect(() => {\r\n // Track all reactive inputs and internal signals\r\n this.placeholderInput();\r\n this.readonly();\r\n this.disabledInput();\r\n this.multiple();\r\n this.errorStateMatcher();\r\n this._focused();\r\n this._disabled();\r\n this._value();\r\n this._ngControlDisabled();\r\n this._required();\r\n this._errorState();\r\n\r\n // Emit state change\r\n this.stateChanges.next();\r\n });\r\n\r\n // Effect to update options selected state when value or options change\r\n effect(() => {\r\n const currentValue = this._value();\r\n const opts = this.options();\r\n const isMultiple = this.multiple();\r\n const compareFn = this.compareWith();\r\n\r\n opts.forEach((option) => {\r\n const optValue = option.value();\r\n // Skip options that don't have a value set yet\r\n if (optValue === undefined) {\r\n return;\r\n }\r\n let isSelected = false;\r\n\r\n if (isMultiple && this.isArray(currentValue)) {\r\n isSelected = currentValue.some((v: unknown) => compareFn(v, optValue));\r\n } else {\r\n isSelected = compareFn(currentValue, optValue);\r\n }\r\n\r\n if (isSelected) {\r\n option.select();\r\n } else {\r\n option.deselect();\r\n }\r\n });\r\n\r\n // Notify form-field that state may have changed (for display value updates)\r\n this.stateChanges.next();\r\n });\r\n }\r\n\r\n ngDoCheck(): void {\r\n if (this.ngControl) {\r\n updateErrorState(\r\n this.ngControl,\r\n this._errorState,\r\n this.errorStateMatcher(),\r\n this._defaultErrorStateMatcher,\r\n this._parentForm,\r\n this._parentFormGroup,\r\n this.stateChanges,\r\n );\r\n syncRequiredState(this.ngControl, this._required, this.stateChanges);\r\n syncNgControlDisabled(this.ngControl, this._ngControlDisabled, this.stateChanges);\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stateChanges.complete();\r\n this._outsideClickSub?.unsubscribe();\r\n this._disposeOverlay();\r\n if (this._typeaheadTimeout) {\r\n clearTimeout(this._typeaheadTimeout);\r\n }\r\n }\r\n\r\n ngAfterContentInit(): void {\r\n // Set up initial selection based on value\r\n this._syncOptionsSelection();\r\n }\r\n\r\n // ControlValueAccessor implementation\r\n writeValue(value: unknown): void {\r\n this._value.set(value ?? null);\r\n //this._syncOptionsSelection();\r\n this.stateChanges.next();\r\n }\r\n\r\n registerOnChange(fn: (value: unknown) => 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 setDisabledState(isDisabled: boolean): void {\r\n this._disabled.set(isDisabled);\r\n this.stateChanges.next();\r\n }\r\n\r\n // FuiFormFieldControl implementation\r\n onContainerClick(_event: MouseEvent): void {\r\n if (!this.disabled() && !this.readonly()) {\r\n this.toggle();\r\n }\r\n }\r\n\r\n setDescribedByIds(ids: string[]): void {\r\n this._ariaDescribedby = ids.length ? ids.join(' ') : null;\r\n }\r\n\r\n setReadOnly(readOnly: boolean): void {\r\n this._readOnly.set(readOnly);\r\n }\r\n\r\n // Sync options selection state with current value\r\n private _syncOptionsSelection(): void {\r\n const currentValue = this._value();\r\n const opts = this.options();\r\n const isMultiple = this.multiple();\r\n const compareFn = this.compareWith();\r\n\r\n opts.forEach((option) => {\r\n const optValue = option.value();\r\n // Skip options that don't have a value set yet\r\n if (optValue === undefined) {\r\n return;\r\n }\r\n let isSelected = false;\r\n\r\n if (isMultiple && this.isArray(currentValue)) {\r\n isSelected = currentValue.some((v: unknown) => compareFn(v, optValue));\r\n } else if (currentValue !== null && currentValue !== undefined) {\r\n isSelected = compareFn(currentValue, optValue);\r\n }\r\n\r\n if (isSelected) {\r\n option.select();\r\n } else {\r\n option.deselect();\r\n }\r\n });\r\n }\r\n\r\n // Focus/blur event handlers from template\r\n _onFocus(): void {\r\n this._focused.set(true);\r\n this.stateChanges.next();\r\n }\r\n\r\n _onBlur(event?: FocusEvent): void {\r\n if (this.panelOpen()) {\r\n // Check if focus moved to the overlay panel (e.g. clicking an option).\r\n // In that case, don't close — the user is interacting with the dropdown.\r\n const relatedTarget = event?.relatedTarget as HTMLElement | null;\r\n const overlayElement = this._overlayRef?.overlayElement;\r\n if (relatedTarget && overlayElement?.contains(relatedTarget)) {\r\n return;\r\n }\r\n // Focus left the select entirely (e.g. Tab) — close without restoring focus\r\n this.close(false);\r\n }\r\n this._focused.set(false);\r\n this._onTouched();\r\n this.stateChanges.next();\r\n }\r\n\r\n // Public methods\r\n focus(): void {\r\n this.trigger?.nativeElement.focus();\r\n }\r\n\r\n blur(): void {\r\n this.trigger?.nativeElement.blur();\r\n }\r\n\r\n // Toggle panel open/close\r\n toggle(): void {\r\n if (this.disabled()) return;\r\n if (this.panelOpen()) {\r\n this.close();\r\n } else {\r\n this.open();\r\n }\r\n }\r\n\r\n // Open the dropdown panel\r\n open(): void {\r\n if (this.disabled() || this.readonly() || this.panelOpen()) return;\r\n // Ensure DOM focus is on the trigger so blur/Tab work correctly\r\n this.trigger?.nativeElement.focus();\r\n requestAnimationFrame(() => {\r\n this.panelOpen.set(true);\r\n this._focused.set(true);\r\n this.openedChange.emit(true);\r\n\r\n // Set active option to currently selected or first option\r\n this._setInitialActiveOption();\r\n\r\n // Create overlay after the view updates\r\n setTimeout(() => {\r\n this._createOverlay();\r\n this._scrollToActiveOption();\r\n this._listenForOutsideClicks();\r\n });\r\n });\r\n }\r\n\r\n // Close the dropdown panel\r\n close(restoreFocus = true): void {\r\n if (!this.panelOpen()) return;\r\n this._outsideClickSub?.unsubscribe();\r\n\r\n this.panelOpen.set(false);\r\n this._focused.set(false);\r\n this._activeOptionIndex.set(-1);\r\n this._disposeOverlay();\r\n this.openedChange.emit(false);\r\n this._onTouched();\r\n\r\n // Return focus to trigger only when explicitly requested (e.g. Escape, backdrop click).\r\n // When closing via Tab, let the browser move focus naturally.\r\n // Focus synchronously to avoid race conditions with Tab key presses.\r\n if (restoreFocus) {\r\n this.trigger?.nativeElement.focus();\r\n }\r\n }\r\n\r\n // Handle option selection (called by FuiOptionComponent)\r\n _onOptionSelected(option: FuiOptionComponent): void {\r\n const newValue = option.value();\r\n\r\n if (this.multiple()) {\r\n const raw = this._value();\r\n const currentValue = this.isArray(raw) ? [...raw] : [];\r\n const compareFn = this.compareWith();\r\n const index = currentValue.findIndex((v: unknown) => compareFn(v, newValue));\r\n\r\n if (index > -1) {\r\n currentValue.splice(index, 1);\r\n option.deselect();\r\n } else {\r\n currentValue.push(newValue);\r\n option.select();\r\n }\r\n\r\n this._value.set(currentValue);\r\n this._onChange(currentValue);\r\n this.valueChange.emit(currentValue);\r\n this.selectionChange.emit({ source: this, value: currentValue });\r\n\r\n // Announce for screen readers\r\n const label = option.getLabel();\r\n const action = index > -1 ? 'deselected' : 'selected';\r\n this._announce(`${label} ${action}`);\r\n } else {\r\n // Deselect previous option\r\n const opts = this.options();\r\n opts.forEach((opt) => {\r\n if (opt !== option) {\r\n opt.deselect();\r\n }\r\n });\r\n\r\n option.select();\r\n this._value.set(newValue);\r\n this._onChange(newValue);\r\n this.valueChange.emit(newValue);\r\n this.selectionChange.emit({ source: this, value: newValue });\r\n\r\n // Announce for screen readers\r\n this._announce(`${option.getLabel()} selected`);\r\n this.close();\r\n }\r\n\r\n this.stateChanges.next();\r\n }\r\n\r\n // Get display value for trigger\r\n _getDisplayValue(): string {\r\n return this.displayValue();\r\n }\r\n\r\n // Handle keyboard navigation\r\n _handleKeydown(event: KeyboardEvent): void {\r\n if (this.disabled()) return;\r\n\r\n const isOpen = this.panelOpen();\r\n\r\n if (!isOpen) {\r\n this._handleClosedKeydown(event);\r\n } else {\r\n this._handleOpenKeydown(event);\r\n }\r\n }\r\n\r\n // Handle keydown when panel is closed\r\n private _handleClosedKeydown(event: KeyboardEvent): void {\r\n const key = event.key;\r\n\r\n switch (key) {\r\n case 'Enter':\r\n case ' ':\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this.open();\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n this._selectFirstOption();\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n this._selectLastOption();\r\n break;\r\n default:\r\n // Type-ahead when closed\r\n if (key.length === 1 && !event.ctrlKey && !event.metaKey) {\r\n this._handleTypeahead(key);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // Handle keydown when panel is open\r\n private _handleOpenKeydown(event: KeyboardEvent): void {\r\n const key = event.key;\r\n const opts = this._getEnabledOptions();\r\n const activeIndex = this._activeOptionIndex();\r\n\r\n switch (key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n this._setNextActiveOption(1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this._setNextActiveOption(-1);\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n this._setActiveOptionIndex(0);\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n this._setActiveOptionIndex(opts.length - 1);\r\n break;\r\n case 'Enter':\r\n case ' ':\r\n event.preventDefault();\r\n if (activeIndex >= 0 && activeIndex < opts.length) {\r\n this._onOptionSelected(opts[activeIndex]);\r\n }\r\n break;\r\n case 'Escape':\r\n event.preventDefault();\r\n this.close();\r\n break;\r\n case 'Tab':\r\n // Don't preventDefault — let browser handle Tab naturally.\r\n // _onBlur will close the panel when focus leaves the trigger.\r\n break;\r\n default:\r\n // Type-ahead when open\r\n if (key.length === 1 && !event.ctrlKey && !event.metaKey) {\r\n event.preventDefault();\r\n this._handleTypeahead(key);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // Set the next active option based on delta\r\n private _setNextActiveOption(delta: number): void {\r\n const opts = this._getEnabledOptions();\r\n if (opts.length === 0) return;\r\n\r\n const currentIndex = this._activeOptionIndex();\r\n let newIndex = currentIndex + delta;\r\n\r\n // Wrap around\r\n if (newIndex < 0) {\r\n newIndex = opts.length - 1;\r\n } else if (newIndex >= opts.length) {\r\n newIndex = 0;\r\n }\r\n\r\n this._setActiveOptionIndex(newIndex);\r\n }\r\n\r\n // Set the active option index\r\n private _setActiveOptionIndex(index: number): void {\r\n const opts = this._getEnabledOptions();\r\n if (index < 0 || index >= opts.length) return;\r\n\r\n // Update active state on options\r\n const allOpts = this.options();\r\n allOpts.forEach((opt) => {\r\n opt.setInactive();\r\n });\r\n\r\n const activeOption = opts[index];\r\n activeOption.setActive();\r\n this._activeOptionIndex.set(index);\r\n this._scrollToActiveOption();\r\n\r\n // Announce active option for screen readers (when panel is open and using keyboard)\r\n if (this.panelOpen()) {\r\n const label = activeOption.getLabel();\r\n const selectedState = activeOption._selected() ? ', selected' : '';\r\n this._announce(`${label}${selectedState}, ${index + 1} of ${opts.length}`);\r\n }\r\n }\r\n\r\n // Set initial active option when opening\r\n private _setInitialActiveOption(): void {\r\n const opts = this._getEnabledOptions();\r\n if (opts.length === 0) {\r\n this._activeOptionIndex.set(-1);\r\n return;\r\n }\r\n\r\n const currentValue = this._value();\r\n const compareFn = this.compareWith();\r\n\r\n // Find the first selected option\r\n let selectedIndex = -1;\r\n if (!this.multiple() && currentValue !== null && currentValue !== undefined) {\r\n selectedIndex = opts.findIndex((opt) => compareFn(opt.value(), currentValue));\r\n } else if (this.multiple() && this.isArray(currentValue) && currentValue.length > 0) {\r\n selectedIndex = opts.findIndex((opt) => currentValue.some((v: unknown) => compareFn(v, opt.value())));\r\n }\r\n\r\n const initialIndex = selectedIndex >= 0 ? selectedIndex : 0;\r\n this._setActiveOptionIndex(initialIndex);\r\n }\r\n\r\n // Scroll to active option\r\n private _scrollToActiveOption(): void {\r\n const opts = this._getEnabledOptions();\r\n const activeIndex = this._activeOptionIndex();\r\n\r\n if (activeIndex < 0 || activeIndex >= opts.length) return;\r\n\r\n const activeOption = opts[activeIndex];\r\n const element = activeOption._getHostElement();\r\n const panel = this.panel?.nativeElement;\r\n\r\n if (element && panel) {\r\n const optionTop = element.offsetTop;\r\n const optionBottom = optionTop + element.offsetHeight;\r\n const panelTop = panel.scrollTop;\r\n const panelBottom = panelTop + panel.clientHeight;\r\n\r\n if (optionTop < panelTop) {\r\n panel.scrollTop = optionTop;\r\n } else if (optionBottom > panelBottom) {\r\n panel.scrollTop = optionBottom - panel.clientHeight;\r\n }\r\n }\r\n }\r\n\r\n // Handle type-ahead search\r\n private _handleTypeahead(char: string): void {\r\n // Clear timeout and add to buffer\r\n if (this._typeaheadTimeout) {\r\n clearTimeout(this._typeaheadTimeout);\r\n }\r\n this._typeaheadBuffer += char.toLowerCase();\r\n\r\n // Find matching option\r\n const opts = this._getEnabledOptions();\r\n const matchIndex = opts.findIndex((opt) => opt.getLabel().toLowerCase().startsWith(this._typeaheadBuffer));\r\n\r\n if (matchIndex >= 0) {\r\n if (this.panelOpen()) {\r\n this._setActiveOptionIndex(matchIndex);\r\n } else {\r\n // Select the option when closed\r\n this._onOptionSelected(opts[matchIndex]);\r\n }\r\n }\r\n\r\n // Clear buffer after debounce\r\n this._typeaheadTimeout = setTimeout(() => {\r\n this._typeaheadBuffer = '';\r\n }, this.TYPE_AHEAD_DEBOUNCE);\r\n }\r\n\r\n // Select first non-disabled option\r\n private _selectFirstOption(): void {\r\n const opts = this._getEnabledOptions();\r\n if (opts.length > 0) {\r\n this._onOptionSelected(opts[0]);\r\n }\r\n }\r\n\r\n // Select last non-disabled option\r\n private _selectLastOption(): void {\r\n const opts = this._getEnabledOptions();\r\n if (opts.length > 0) {\r\n this._onOptionSelected(opts[opts.length - 1]);\r\n }\r\n }\r\n\r\n // Get all non-disabled options\r\n private _getEnabledOptions(): FuiOptionComponent[] {\r\n return this.options().filter((opt) => !opt.disabled());\r\n }\r\n\r\n // Start listening for outside clicks when panel opens\r\n private _listenForOutsideClicks(): void {\r\n this._outsideClickSub?.unsubscribe();\r\n\r\n // Run outside Angular zone to avoid triggering change detection on every document click\r\n this._ngZone.runOutsideAngular(() => {\r\n // Use setTimeout to skip the current click event that opened the panel\r\n setTimeout(() => {\r\n this._outsideClickSub = fromEvent<MouseEvent>(this._document, 'click')\r\n .pipe(\r\n filter(() => this.panelOpen()),\r\n filter((event) => {\r\n const target = event.target as HTMLElement;\r\n const triggerElement = this.trigger?.nativeElement;\r\n const panelElement = this.panel?.nativeElement;\r\n const overlayElement = this._overlayRef?.overlayElement;\r\n return (\r\n !triggerElement?.contains(target) &&\r\n !panelElement?.contains(target) &&\r\n !overlayElement?.contains(target)\r\n );\r\n }),\r\n )\r\n .subscribe(() => {\r\n this._ngZone.run(() => {\r\n this.close();\r\n });\r\n });\r\n });\r\n });\r\n }\r\n\r\n // Create overlay for panel\r\n private _createOverlay(): void {\r\n if (this._overlayRef || !this.panel || !this.trigger) return;\r\n\r\n const triggerElement = this.trigger.nativeElement;\r\n const triggerWidth = triggerElement.getBoundingClientRect().width;\r\n\r\n const positions: FuiConnectedPosition[] = [\r\n // Primary: open below\r\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },\r\n // Fallback: open above if no space below\r\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },\r\n ];\r\n\r\n const positionStrategy = this._overlayService\r\n .position()\r\n .connectedTo(triggerElement, positions)\r\n .withPush(false)\r\n .withFlexibleDimensions(true)\r\n .withViewportMargin(8);\r\n\r\n this._overlayRef = this._overlayService.create({\r\n positionStrategy,\r\n scrollStrategy: this._overlayService.scrollStrategies.reposition(),\r\n hasBackdrop: true,\r\n backdropClass: 'fui-select-backdrop',\r\n backdropClickBehavior: 'close',\r\n panelClass: ['fui-select-overlay-panel'],\r\n width: triggerWidth,\r\n });\r\n\r\n // Track overlay subscriptions for proper cleanup\r\n this._overlaySubscriptions.unsubscribe();\r\n this._overlaySubscriptions = new Subscription();\r\n\r\n this._overlaySubscriptions.add(\r\n this._overlayRef.backdropClick.subscribe(() => {\r\n this.close();\r\n }),\r\n );\r\n\r\n this._overlaySubscriptions.add(\r\n this._overlayRef.keydownEvents.subscribe((event) => {\r\n if (event.key === 'Escape') {\r\n this.close();\r\n }\r\n }),\r\n );\r\n\r\n // Attach panel to overlay\r\n const panelElement = this.panel.nativeElement;\r\n this._overlayRef.attach(panelElement);\r\n }\r\n\r\n // Dispose overlay\r\n private _disposeOverlay(): void {\r\n this._overlaySubscriptions.unsubscribe();\r\n if (this._overlayRef) {\r\n this._overlayRef.dispose();\r\n this._overlayRef = null;\r\n }\r\n }\r\n\r\n // Get the active option's id for aria-activedescendant\r\n _getActiveDescendant(): string | null {\r\n const opts = this._getEnabledOptions();\r\n const activeIndex = this._activeOptionIndex();\r\n if (activeIndex >= 0 && activeIndex < opts.length) {\r\n return opts[activeIndex].id;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Announces a message to screen readers via the aria-live region.\r\n * Clears the message after a brief delay to allow repeated announcements.\r\n */\r\n private _announce(message: string): void {\r\n // Clear first to ensure repeated identical messages are announced\r\n this._liveAnnouncement.set('');\r\n setTimeout(() => {\r\n this._liveAnnouncement.set(message);\r\n }, 50);\r\n }\r\n\r\n // Mat-select compatibility methods\r\n get selected(): Signal<unknown> {\r\n return this.value;\r\n }\r\n\r\n // Helper method to check if value is array\r\n isArray(value: unknown): value is unknown[] {\r\n return Array.isArray(value);\r\n }\r\n}\r\n","<!-- Select Trigger -->\r\n<div\r\n #trigger\r\n [id]=\"id\"\r\n class=\"fui-select__trigger\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n [attr.role]=\"'combobox'\"\r\n [attr.aria-haspopup]=\"'listbox'\"\r\n [attr.aria-expanded]=\"panelOpen()\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.aria-invalid]=\"errorState()\"\r\n [attr.aria-describedby]=\"_ariaDescribedby\"\r\n [attr.aria-required]=\"required()\"\r\n [attr.aria-label]=\"empty() ? placeholder() : null\"\r\n aria-autocomplete=\"none\"\r\n [attr.aria-activedescendant]=\"panelOpen() ? _getActiveDescendant() : null\"\r\n [attr.aria-controls]=\"panelOpen() ? id + '-panel' : null\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n (focus)=\"_onFocus()\"\r\n (blur)=\"_onBlur($event)\"\r\n>\r\n <span class=\"fui-select__value\">\r\n @if (empty()) {\r\n <span class=\"fui-select__placeholder\">{{ placeholder() }}</span>\r\n } @else {\r\n <span class=\"fui-select__value-text\">{{ _getDisplayValue() }}</span>\r\n }\r\n </span>\r\n</div>\r\n\r\n<!-- Live region for screen reader announcements -->\r\n<span class=\"fui-sr-only\" aria-live=\"assertive\" aria-atomic=\"true\">{{ _liveAnnouncement() }}</span>\r\n\r\n<!-- Dropdown Panel -->\r\n@if (panelOpen()) {\r\n <div\r\n #panel\r\n [id]=\"id + '-panel'\"\r\n class=\"fui-select__panel\"\r\n role=\"listbox\"\r\n [attr.aria-multiselectable]=\"multiple()\"\r\n [attr.aria-label]=\"placeholder()\"\r\n >\r\n <ng-content></ng-content>\r\n </div>\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"raintonic-formaui-components-select.mjs","sources":["../../../lib/components/select/select-tokens.ts","../../../lib/components/select/option.component.ts","../../../lib/components/select/select.component.ts","../../../lib/components/select/select.component.html","../../../lib/components/select/raintonic-formaui-components-select.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\n\r\n/**\r\n * Interface representing the parent select contract that options need.\r\n * Used to break the circular dependency between select and option components.\r\n */\r\nexport interface FuiSelectParent {\r\n multiple(): boolean;\r\n _onOptionSelected(option: any): void;\r\n}\r\n\r\n/**\r\n * Injection token used to provide the parent select to options.\r\n */\r\nexport const FUI_SELECT = new InjectionToken<FuiSelectParent>('FUI_SELECT');\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n InputSignal,\r\n OutputEmitterRef,\r\n ElementRef,\r\n inject,\r\n signal,\r\n WritableSignal,\r\n HostListener,\r\n OnDestroy,\r\n AfterViewInit,\r\n} from '@angular/core';\r\n\r\nimport { Subject } from 'rxjs';\r\nimport { FUI_SELECT } from './select-tokens';\r\n\r\n/**\r\n * # FuiOption Component\r\n *\r\n * Individual option component for use within fui-select.\r\n * Works like Angular Material's mat-option with full accessibility support.\r\n *\r\n * ## Features\r\n * - Disabled state support\r\n * - Selection state management\r\n * - Full accessibility support (ARIA attributes)\r\n * - Keyboard navigation support\r\n * - Custom content projection\r\n * - Smooth hover animations\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Option\r\n * ```html\r\n * <fui-select placeholder=\"Select a status\">\r\n * <fui-option value=\"active\">Active</fui-option>\r\n * <fui-option value=\"inactive\">Inactive</fui-option>\r\n * <fui-option value=\"pending\" [disabled]=\"true\">Pending (Disabled)</fui-option>\r\n * </fui-select>\r\n * ```\r\n *\r\n * ### Option with Custom Content\r\n * ```html\r\n * <fui-select placeholder=\"Select a country\">\r\n * <fui-option value=\"us\">\r\n * <fui-icon name=\"flag-us\"></fui-icon>\r\n * United States\r\n * </fui-option>\r\n * <fui-option value=\"ca\">\r\n * <fui-icon name=\"flag-ca\"></fui-icon>\r\n * Canada\r\n * </fui-option>\r\n * </fui-select>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-option',\r\n standalone: true,\r\n imports: [],\r\n template: `\r\n @if (_showCheckmark()) {\r\n <span class=\"fui-option__checkmark\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\r\n <path d=\"M6.5 11.5L3 8l1-1 2.5 2.5L12 4l1 1z\" />\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"fui-option__content\">\r\n <ng-content></ng-content>\r\n </span>\r\n `,\r\n styleUrls: ['./option.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-option',\r\n '[class.fui-option--selected]': '_selected()',\r\n '[class.fui-option--disabled]': 'disabled()',\r\n '[class.fui-option--active]': '_active()',\r\n role: 'option',\r\n '[attr.id]': 'id',\r\n '[attr.aria-selected]': '_selected()',\r\n '[attr.aria-disabled]': 'disabled()',\r\n '[attr.tabindex]': '-1',\r\n },\r\n})\r\nexport class FuiOptionComponent implements OnDestroy, AfterViewInit {\r\n static nextId = 0;\r\n\r\n /**\r\n * The value of the option\r\n */\r\n readonly value: InputSignal<unknown> = input<unknown>(undefined);\r\n\r\n /**\r\n * Whether the option is disabled\r\n * @default false\r\n */\r\n readonly disabled: InputSignal<boolean> = input(false);\r\n\r\n /**\r\n * Event emitted when the option is selected\r\n */\r\n readonly selectionChange: OutputEmitterRef<{ source: FuiOptionComponent; value: unknown }> = output();\r\n\r\n // Internal state\r\n readonly _selected: WritableSignal<boolean> = signal(false);\r\n readonly _active: WritableSignal<boolean> = signal(false);\r\n readonly stateChanges = new Subject<void>();\r\n\r\n // Element reference\r\n private readonly _element: ElementRef<HTMLElement> = inject(ElementRef);\r\n\r\n // Parent select (optional - may not exist if used standalone)\r\n private readonly _parentSelect = inject(FUI_SELECT, { optional: true });\r\n\r\n // Unique ID\r\n readonly id = `fui-option-${FuiOptionComponent.nextId++}`;\r\n\r\n // Show checkmark only in multiple mode when selected\r\n readonly _showCheckmark = signal(false);\r\n\r\n ngAfterViewInit(): void {\r\n // Update checkmark visibility based on parent select's multiple mode\r\n this._updateCheckmarkVisibility();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stateChanges.complete();\r\n }\r\n\r\n // View value (text content)\r\n get viewValue(): string {\r\n return (this._element.nativeElement.textContent || '').trim();\r\n }\r\n\r\n @HostListener('click', ['$event'])\r\n _handleClick(event: Event): void {\r\n if (!this.disabled()) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n // Notify parent select\r\n if (this._parentSelect) {\r\n this._parentSelect._onOptionSelected(this);\r\n } else {\r\n // Standalone usage - emit event\r\n this._emitSelectionChangeEvent();\r\n }\r\n }\r\n }\r\n\r\n @HostListener('mouseenter')\r\n _handleMouseEnter(): void {\r\n if (!this.disabled()) {\r\n this._active.set(true);\r\n }\r\n }\r\n\r\n @HostListener('mouseleave')\r\n _handleMouseLeave(): void {\r\n this._active.set(false);\r\n }\r\n\r\n /**\r\n * Selects the option\r\n */\r\n select(): void {\r\n if (!this._selected()) {\r\n this._selected.set(true);\r\n this._updateCheckmarkVisibility();\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n /**\r\n * Deselects the option\r\n */\r\n deselect(): void {\r\n if (this._selected()) {\r\n this._selected.set(false);\r\n this._updateCheckmarkVisibility();\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n /**\r\n * Sets the option as active (keyboard navigation)\r\n */\r\n setActive(): void {\r\n if (!this._active()) {\r\n this._active.set(true);\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n /**\r\n * Sets the option as inactive\r\n */\r\n setInactive(): void {\r\n if (this._active()) {\r\n this._active.set(false);\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n /**\r\n * Sets focus onto this option\r\n */\r\n focus(): void {\r\n const element = this._element.nativeElement;\r\n if (typeof element.focus === 'function') {\r\n element.focus();\r\n }\r\n }\r\n\r\n /**\r\n * Gets the label to be used when displaying the option\r\n */\r\n getLabel(): string {\r\n return this.viewValue;\r\n }\r\n\r\n /**\r\n * Gets the host element\r\n */\r\n _getHostElement(): HTMLElement {\r\n return this._element.nativeElement;\r\n }\r\n\r\n /** Update checkmark visibility based on selection and multiple mode */\r\n private _updateCheckmarkVisibility(): void {\r\n const isMultiple = this._parentSelect?.multiple() ?? false;\r\n this._showCheckmark.set(isMultiple && this._selected());\r\n }\r\n\r\n /** Emits the selection change event */\r\n private _emitSelectionChangeEvent(): void {\r\n this.selectionChange.emit({ source: this, value: this.value() });\r\n }\r\n}\r\n","import {\r\n AfterContentInit,\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n contentChildren,\r\n DoCheck,\r\n effect,\r\n ElementRef,\r\n inject,\r\n NgZone,\r\n input,\r\n InputSignal,\r\n OnDestroy,\r\n output,\r\n OutputEmitterRef,\r\n signal,\r\n Signal,\r\n ViewChild,\r\n ViewEncapsulation,\r\n WritableSignal,\r\n} from '@angular/core';\r\n\r\nimport {\r\n ControlValueAccessor,\r\n FormGroupDirective,\r\n NG_VALUE_ACCESSOR,\r\n NgControl,\r\n NgForm,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { fromEvent, Subject, Subscription } from 'rxjs';\r\nimport { filter } from 'rxjs/operators';\r\nimport { injectNgControl, updateErrorState, syncRequiredState, syncNgControlDisabled } from '@raintonic/formaui/cdk/form-field';\r\nimport { FUI_FORM_FIELD_CONTROL, FuiFormFieldControl } from '@raintonic/formaui/core';\r\nimport { DefaultErrorStateMatcher, ErrorStateMatcher } from '@raintonic/formaui/core';\r\nimport { FuiOptionComponent } from './option.component';\r\nimport { FuiConnectedPosition, FuiOverlayRef, FuiOverlayService } from '@raintonic/formaui/cdk/overlay';\r\nimport { FUI_SELECT } from './select-tokens';\r\n\r\n/**\r\n * Available select sizes\r\n */\r\nexport type FuiSelectSize = 'sm' | 'md' | 'lg';\r\n\r\n/**\r\n * Available select variants following Carbon Design System patterns\r\n */\r\nexport type FuiSelectVariant = 'outlined' | 'filled';\r\n\r\n/**\r\n * Selection change event object emitted when the select's selection changes\r\n */\r\nexport interface FuiSelectChange {\r\n source: FuiSelectComponent;\r\n value: unknown;\r\n}\r\n\r\n/**\r\n * # fui-select Component\r\n *\r\n * A select component designed to work seamlessly with fui-form-field.\r\n * Similar to Angular Material's mat-select integration with mat-form-field.\r\n * Provides full Reactive Forms support with validation and error handling.\r\n *\r\n * ## Features\r\n * - Works inside fui-form-field like mat-select\r\n * - Full Reactive Forms integration (ControlValueAccessor)\r\n * - Multiple selection support\r\n * - Options via projected content (fui-option)\r\n * - Disabled and readonly states\r\n * - Full accessibility support\r\n * - Full keyboard navigation (Arrow keys, Enter, Space, Escape, Home, End)\r\n * - Type-ahead search functionality\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Select with Form Field\r\n * ```html\r\n * <fui-form-field>\r\n * <label>Country</label>\r\n * <fui-select placeholder=\"Select a country\">\r\n * <fui-option value=\"us\">United States</fui-option>\r\n * <fui-option value=\"ca\">Canada</fui-option>\r\n * <fui-option value=\"mx\">Mexico</fui-option>\r\n * </fui-select>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### With Reactive Forms and Validation\r\n * ```html\r\n * <form [formGroup]=\"form\">\r\n * <fui-form-field>\r\n * <label>Country</label>\r\n * <fui-select formControlName=\"country\" placeholder=\"Select a country\">\r\n * <fui-option value=\"us\">United States</fui-option>\r\n * <fui-option value=\"ca\">Canada</fui-option>\r\n * </fui-select>\r\n * <fui-error *ngIf=\"form.get('country')?.hasError('required')\">\r\n * Country is required\r\n * </fui-error>\r\n * </fui-form-field>\r\n * </form>\r\n * ```\r\n *\r\n * ### Multiple Selection\r\n * ```html\r\n * <fui-form-field>\r\n * <label>Skills</label>\r\n * <fui-select formControlName=\"skills\" [multiple]=\"true\">\r\n * <fui-option value=\"js\">JavaScript</fui-option>\r\n * <fui-option value=\"ts\">TypeScript</fui-option>\r\n * <fui-option value=\"py\">Python</fui-option>\r\n * </fui-select>\r\n * </fui-form-field>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-select',\r\n standalone: true,\r\n imports: [ReactiveFormsModule],\r\n templateUrl: './select.component.html',\r\n styleUrls: ['./select.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-select',\r\n '[attr.id]': 'id',\r\n '[class.fui-select--open]': 'panelOpen()',\r\n '[class.fui-select--disabled]': 'disabled()',\r\n '[class.fui-select--multiple]': 'multiple()',\r\n '[class.fui-select--readonly]': '_readOnly()',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: FuiSelectComponent,\r\n multi: true,\r\n },\r\n {\r\n provide: FUI_FORM_FIELD_CONTROL,\r\n useExisting: FuiSelectComponent,\r\n },\r\n {\r\n provide: FUI_SELECT,\r\n useExisting: FuiSelectComponent,\r\n },\r\n ],\r\n})\r\nexport class FuiSelectComponent\r\n implements ControlValueAccessor, FuiFormFieldControl, DoCheck, OnDestroy, AfterContentInit\r\n{\r\n // Static properties\r\n static nextId = 0;\r\n readonly controlType = 'fui-select';\r\n\r\n // Inputs using new signal-based API\r\n readonly placeholderInput: InputSignal<string> = input('', { alias: 'placeholder' });\r\n readonly disabledInput: InputSignal<boolean> = input(false, { alias: 'disabled' });\r\n readonly readonly: InputSignal<boolean> = input(false);\r\n readonly multiple: InputSignal<boolean> = input(false);\r\n readonly errorStateMatcher: InputSignal<ErrorStateMatcher | null> = input<ErrorStateMatcher | null>(null);\r\n\r\n /**\r\n * Whether to compare option values using object identity or deep equality\r\n */\r\n readonly compareWith: InputSignal<(o1: unknown, o2: unknown) => boolean> = input<\r\n (o1: unknown, o2: unknown) => boolean\r\n >((o1, o2) => o1 === o2);\r\n\r\n // Outputs\r\n readonly valueChange: OutputEmitterRef<unknown> = output<unknown>();\r\n readonly selectionChange: OutputEmitterRef<FuiSelectChange> = output<FuiSelectChange>();\r\n readonly openedChange: OutputEmitterRef<boolean> = output<boolean>();\r\n\r\n // Internal state signals\r\n private readonly _value: WritableSignal<unknown> = signal(null);\r\n private readonly _focused: WritableSignal<boolean> = signal(false);\r\n private readonly _disabled: WritableSignal<boolean> = signal(false);\r\n readonly _readOnly: WritableSignal<boolean> = signal(false);\r\n\r\n // FuiFormFieldControl implementation\r\n readonly stateChanges = new Subject<void>();\r\n private _uid = `fui-select-${FuiSelectComponent.nextId++}`;\r\n _ariaDescribedby: string | null = null;\r\n\r\n // Error state\r\n private readonly _errorState: WritableSignal<boolean> = signal(false);\r\n readonly errorState = this._errorState;\r\n\r\n // Form control references\r\n private _parentForm = inject(NgForm, { optional: true });\r\n private _parentFormGroup = inject(FormGroupDirective, { optional: true });\r\n private _defaultErrorStateMatcher = inject(DefaultErrorStateMatcher);\r\n private readonly _ngControlRef = injectNgControl();\r\n get ngControl(): NgControl | null {\r\n return this._ngControlRef.ngControl;\r\n }\r\n\r\n // Interface implementation\r\n readonly placeholder = computed(() => this.placeholderInput());\r\n private readonly _required: WritableSignal<boolean> = signal(false);\r\n readonly required = this._required;\r\n\r\n readonly value = this._value;\r\n\r\n readonly focused = this._focused;\r\n\r\n private readonly _ngControlDisabled: WritableSignal<boolean> = signal(false);\r\n readonly disabled = computed(() => this._disabled() || this.disabledInput() || this._ngControlDisabled());\r\n\r\n readonly empty = computed(() => {\r\n const val = this._value();\r\n return val === null || val === undefined || (this.isArray(val) && val.length === 0);\r\n });\r\n\r\n readonly id = this._uid;\r\n\r\n // ViewChild for trigger and panel\r\n @ViewChild('trigger', { static: false }) trigger?: ElementRef<HTMLDivElement>;\r\n @ViewChild('panel', { static: false }) panel?: ElementRef<HTMLDivElement>;\r\n\r\n // ContentChildren for options\r\n readonly options = contentChildren(FuiOptionComponent, { descendants: true });\r\n\r\n // Panel open/close state\r\n readonly panelOpen = signal(false);\r\n\r\n // Active option index for keyboard navigation\r\n private readonly _activeOptionIndex: WritableSignal<number> = signal(-1);\r\n readonly activeOptionIndex = this._activeOptionIndex.asReadonly();\r\n\r\n // Live announcement for screen readers\r\n readonly _liveAnnouncement: WritableSignal<string> = signal('');\r\n\r\n // Overlay reference\r\n private _overlayRef: FuiOverlayRef | null = null;\r\n private _overlaySubscriptions = new Subscription();\r\n\r\n // Services\r\n private readonly _overlayService = inject(FuiOverlayService);\r\n private readonly _elementRef = inject(ElementRef);\r\n private readonly _document = inject(DOCUMENT);\r\n private readonly _ngZone = inject(NgZone);\r\n private _outsideClickSub?: Subscription;\r\n\r\n // Type-ahead search\r\n private _typeaheadBuffer = '';\r\n private _typeaheadTimeout: ReturnType<typeof setTimeout> | null = null;\r\n private readonly TYPE_AHEAD_DEBOUNCE = 200;\r\n\r\n // ControlValueAccessor callbacks\r\n private _onChange: (value: unknown) => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n private _onTouched: () => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n\r\n // Computed properties\r\n readonly displayValue: Signal<string> = computed(() => {\r\n const currentValue = this.value();\r\n const opts = this.options();\r\n\r\n if (currentValue === null || currentValue === undefined) {\r\n return '';\r\n }\r\n\r\n // Filter out options that don't have a value set yet\r\n const validOpts = opts.filter((opt) => opt.value() !== undefined);\r\n\r\n if (this.multiple()) {\r\n if (this.isArray(currentValue)) {\r\n const selectedOptions = validOpts.filter((opt) =>\r\n currentValue.some((v: unknown) => this.compareWith()(v, opt.value())),\r\n );\r\n return selectedOptions.map((opt) => opt.getLabel()).join(', ');\r\n }\r\n return '';\r\n } else {\r\n const selectedOption = validOpts.find((opt) => this.compareWith()(opt.value(), currentValue));\r\n return selectedOption ? selectedOption.getLabel() : String(currentValue);\r\n }\r\n });\r\n\r\n constructor() {\r\n // Set valueAccessor after NgControl is resolved\r\n void Promise.resolve().then(() => {\r\n if (this._ngControlRef.ngControl) {\r\n this._ngControlRef.ngControl.valueAccessor = this;\r\n }\r\n });\r\n\r\n // Effect to emit state changes\r\n effect(() => {\r\n // Track all reactive inputs and internal signals\r\n this.placeholderInput();\r\n this.readonly();\r\n this.disabledInput();\r\n this.multiple();\r\n this.errorStateMatcher();\r\n this._focused();\r\n this._disabled();\r\n this._value();\r\n this._ngControlDisabled();\r\n this._required();\r\n this._errorState();\r\n\r\n // Emit state change\r\n this.stateChanges.next();\r\n });\r\n\r\n // Effect to update options selected state when value or options change\r\n effect(() => {\r\n const currentValue = this._value();\r\n const opts = this.options();\r\n const isMultiple = this.multiple();\r\n const compareFn = this.compareWith();\r\n\r\n opts.forEach((option) => {\r\n const optValue = option.value();\r\n // Skip options that don't have a value set yet\r\n if (optValue === undefined) {\r\n return;\r\n }\r\n let isSelected = false;\r\n\r\n if (isMultiple && this.isArray(currentValue)) {\r\n isSelected = currentValue.some((v: unknown) => compareFn(v, optValue));\r\n } else {\r\n isSelected = compareFn(currentValue, optValue);\r\n }\r\n\r\n if (isSelected) {\r\n option.select();\r\n } else {\r\n option.deselect();\r\n }\r\n });\r\n\r\n // Notify form-field that state may have changed (for display value updates)\r\n this.stateChanges.next();\r\n });\r\n }\r\n\r\n ngDoCheck(): void {\r\n if (this.ngControl) {\r\n updateErrorState(\r\n this.ngControl,\r\n this._errorState,\r\n this.errorStateMatcher(),\r\n this._defaultErrorStateMatcher,\r\n this._parentForm,\r\n this._parentFormGroup,\r\n this.stateChanges,\r\n );\r\n syncRequiredState(this.ngControl, this._required, this.stateChanges);\r\n syncNgControlDisabled(this.ngControl, this._ngControlDisabled, this.stateChanges);\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stateChanges.complete();\r\n this._outsideClickSub?.unsubscribe();\r\n this._disposeOverlay();\r\n if (this._typeaheadTimeout) {\r\n clearTimeout(this._typeaheadTimeout);\r\n }\r\n }\r\n\r\n ngAfterContentInit(): void {\r\n // Set up initial selection based on value\r\n this._syncOptionsSelection();\r\n }\r\n\r\n // ControlValueAccessor implementation\r\n writeValue(value: unknown): void {\r\n this._value.set(value ?? null);\r\n //this._syncOptionsSelection();\r\n this.stateChanges.next();\r\n }\r\n\r\n registerOnChange(fn: (value: unknown) => 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 setDisabledState(isDisabled: boolean): void {\r\n this._disabled.set(isDisabled);\r\n this.stateChanges.next();\r\n }\r\n\r\n // FuiFormFieldControl implementation\r\n onContainerClick(_event: MouseEvent): void {\r\n if (!this.disabled() && !this.readonly()) {\r\n this.toggle();\r\n }\r\n }\r\n\r\n setDescribedByIds(ids: string[]): void {\r\n this._ariaDescribedby = ids.length ? ids.join(' ') : null;\r\n }\r\n\r\n setReadOnly(readOnly: boolean): void {\r\n this._readOnly.set(readOnly);\r\n }\r\n\r\n // Sync options selection state with current value\r\n private _syncOptionsSelection(): void {\r\n const currentValue = this._value();\r\n const opts = this.options();\r\n const isMultiple = this.multiple();\r\n const compareFn = this.compareWith();\r\n\r\n opts.forEach((option) => {\r\n const optValue = option.value();\r\n // Skip options that don't have a value set yet\r\n if (optValue === undefined) {\r\n return;\r\n }\r\n let isSelected = false;\r\n\r\n if (isMultiple && this.isArray(currentValue)) {\r\n isSelected = currentValue.some((v: unknown) => compareFn(v, optValue));\r\n } else if (currentValue !== null && currentValue !== undefined) {\r\n isSelected = compareFn(currentValue, optValue);\r\n }\r\n\r\n if (isSelected) {\r\n option.select();\r\n } else {\r\n option.deselect();\r\n }\r\n });\r\n }\r\n\r\n // Focus/blur event handlers from template\r\n _onFocus(): void {\r\n this._focused.set(true);\r\n this.stateChanges.next();\r\n }\r\n\r\n _onBlur(event?: FocusEvent): void {\r\n if (this.panelOpen()) {\r\n // Check if focus moved to the overlay panel (e.g. clicking an option).\r\n // In that case, don't close — the user is interacting with the dropdown.\r\n const relatedTarget = event?.relatedTarget as HTMLElement | null;\r\n const overlayElement = this._overlayRef?.overlayElement;\r\n if (relatedTarget && overlayElement?.contains(relatedTarget)) {\r\n return;\r\n }\r\n // Focus left the select entirely (e.g. Tab) — close without restoring focus\r\n this.close(false);\r\n }\r\n this._focused.set(false);\r\n this._onTouched();\r\n this.stateChanges.next();\r\n }\r\n\r\n // Public methods\r\n focus(): void {\r\n this.trigger?.nativeElement.focus();\r\n }\r\n\r\n blur(): void {\r\n this.trigger?.nativeElement.blur();\r\n }\r\n\r\n // Toggle panel open/close\r\n toggle(): void {\r\n if (this.disabled()) return;\r\n if (this.panelOpen()) {\r\n this.close();\r\n } else {\r\n this.open();\r\n }\r\n }\r\n\r\n // Open the dropdown panel\r\n open(): void {\r\n if (this.disabled() || this.readonly() || this.panelOpen()) return;\r\n // Ensure DOM focus is on the trigger so blur/Tab work correctly\r\n this.trigger?.nativeElement.focus();\r\n requestAnimationFrame(() => {\r\n this.panelOpen.set(true);\r\n this._focused.set(true);\r\n this.openedChange.emit(true);\r\n\r\n // Set active option to currently selected or first option\r\n this._setInitialActiveOption();\r\n\r\n // Create overlay after the view updates\r\n setTimeout(() => {\r\n this._createOverlay();\r\n this._scrollToActiveOption();\r\n this._listenForOutsideClicks();\r\n });\r\n });\r\n }\r\n\r\n // Close the dropdown panel\r\n close(restoreFocus = true): void {\r\n if (!this.panelOpen()) return;\r\n this._outsideClickSub?.unsubscribe();\r\n\r\n this.panelOpen.set(false);\r\n this._focused.set(false);\r\n this._activeOptionIndex.set(-1);\r\n this._disposeOverlay();\r\n this.openedChange.emit(false);\r\n this._onTouched();\r\n\r\n // Return focus to trigger only when explicitly requested (e.g. Escape, backdrop click).\r\n // When closing via Tab, let the browser move focus naturally.\r\n // Focus synchronously to avoid race conditions with Tab key presses.\r\n if (restoreFocus) {\r\n this.trigger?.nativeElement.focus();\r\n }\r\n }\r\n\r\n // Handle option selection (called by FuiOptionComponent)\r\n _onOptionSelected(option: FuiOptionComponent): void {\r\n const newValue = option.value();\r\n\r\n if (this.multiple()) {\r\n const raw = this._value();\r\n const currentValue = this.isArray(raw) ? [...raw] : [];\r\n const compareFn = this.compareWith();\r\n const index = currentValue.findIndex((v: unknown) => compareFn(v, newValue));\r\n\r\n if (index > -1) {\r\n currentValue.splice(index, 1);\r\n option.deselect();\r\n } else {\r\n currentValue.push(newValue);\r\n option.select();\r\n }\r\n\r\n this._value.set(currentValue);\r\n this._onChange(currentValue);\r\n this.valueChange.emit(currentValue);\r\n this.selectionChange.emit({ source: this, value: currentValue });\r\n\r\n // Announce for screen readers\r\n const label = option.getLabel();\r\n const action = index > -1 ? 'deselected' : 'selected';\r\n this._announce(`${label} ${action}`);\r\n } else {\r\n // Deselect previous option\r\n const opts = this.options();\r\n opts.forEach((opt) => {\r\n if (opt !== option) {\r\n opt.deselect();\r\n }\r\n });\r\n\r\n option.select();\r\n this._value.set(newValue);\r\n this._onChange(newValue);\r\n this.valueChange.emit(newValue);\r\n this.selectionChange.emit({ source: this, value: newValue });\r\n\r\n // Announce for screen readers\r\n this._announce(`${option.getLabel()} selected`);\r\n this.close();\r\n }\r\n\r\n this.stateChanges.next();\r\n }\r\n\r\n // Get display value for trigger\r\n _getDisplayValue(): string {\r\n return this.displayValue();\r\n }\r\n\r\n // Handle keyboard navigation\r\n _handleKeydown(event: KeyboardEvent): void {\r\n if (this.disabled()) return;\r\n\r\n const isOpen = this.panelOpen();\r\n\r\n if (!isOpen) {\r\n this._handleClosedKeydown(event);\r\n } else {\r\n this._handleOpenKeydown(event);\r\n }\r\n }\r\n\r\n // Handle keydown when panel is closed\r\n private _handleClosedKeydown(event: KeyboardEvent): void {\r\n const key = event.key;\r\n\r\n switch (key) {\r\n case 'Enter':\r\n case ' ':\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this.open();\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n this._selectFirstOption();\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n this._selectLastOption();\r\n break;\r\n default:\r\n // Type-ahead when closed\r\n if (key.length === 1 && !event.ctrlKey && !event.metaKey) {\r\n this._handleTypeahead(key);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // Handle keydown when panel is open\r\n private _handleOpenKeydown(event: KeyboardEvent): void {\r\n const PAGE_SIZE = 5;\r\n const key = event.key;\r\n const opts = this._getEnabledOptions();\r\n const activeIndex = this._activeOptionIndex();\r\n\r\n switch (key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n this._setNextActiveOption(1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this._setNextActiveOption(-1);\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n this._setActiveOptionIndex(0);\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n this._setActiveOptionIndex(opts.length - 1);\r\n break;\r\n case 'PageDown':\r\n event.preventDefault();\r\n if (opts.length > 0) {\r\n const newIndex = Math.min(activeIndex + PAGE_SIZE, opts.length - 1);\r\n this._setActiveOptionIndex(newIndex);\r\n }\r\n break;\r\n case 'PageUp':\r\n event.preventDefault();\r\n if (opts.length > 0) {\r\n const newIndex = Math.max(activeIndex - PAGE_SIZE, 0);\r\n this._setActiveOptionIndex(newIndex);\r\n }\r\n break;\r\n case 'Enter':\r\n case ' ':\r\n event.preventDefault();\r\n if (activeIndex >= 0 && activeIndex < opts.length) {\r\n this._onOptionSelected(opts[activeIndex]);\r\n }\r\n break;\r\n case 'Escape':\r\n event.preventDefault();\r\n this.close();\r\n break;\r\n case 'Tab':\r\n // Don't preventDefault — let browser handle Tab naturally.\r\n // _onBlur will close the panel when focus leaves the trigger.\r\n break;\r\n default:\r\n // Type-ahead when open\r\n if (key.length === 1 && !event.ctrlKey && !event.metaKey) {\r\n event.preventDefault();\r\n this._handleTypeahead(key);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // Set the next active option based on delta\r\n private _setNextActiveOption(delta: number): void {\r\n const opts = this._getEnabledOptions();\r\n if (opts.length === 0) return;\r\n\r\n const currentIndex = this._activeOptionIndex();\r\n let newIndex = currentIndex + delta;\r\n\r\n // Wrap around\r\n if (newIndex < 0) {\r\n newIndex = opts.length - 1;\r\n } else if (newIndex >= opts.length) {\r\n newIndex = 0;\r\n }\r\n\r\n this._setActiveOptionIndex(newIndex);\r\n }\r\n\r\n // Set the active option index\r\n private _setActiveOptionIndex(index: number): void {\r\n const opts = this._getEnabledOptions();\r\n if (index < 0 || index >= opts.length) return;\r\n\r\n // Update active state on options\r\n const allOpts = this.options();\r\n allOpts.forEach((opt) => {\r\n opt.setInactive();\r\n });\r\n\r\n const activeOption = opts[index];\r\n activeOption.setActive();\r\n this._activeOptionIndex.set(index);\r\n this._scrollToActiveOption();\r\n\r\n // Announce active option for screen readers (when panel is open and using keyboard)\r\n if (this.panelOpen()) {\r\n const label = activeOption.getLabel();\r\n const selectedState = activeOption._selected() ? ', selected' : '';\r\n this._announce(`${label}${selectedState}, ${index + 1} of ${opts.length}`);\r\n }\r\n }\r\n\r\n // Set initial active option when opening\r\n private _setInitialActiveOption(): void {\r\n const opts = this._getEnabledOptions();\r\n if (opts.length === 0) {\r\n this._activeOptionIndex.set(-1);\r\n return;\r\n }\r\n\r\n const currentValue = this._value();\r\n const compareFn = this.compareWith();\r\n\r\n // Find the first selected option\r\n let selectedIndex = -1;\r\n if (!this.multiple() && currentValue !== null && currentValue !== undefined) {\r\n selectedIndex = opts.findIndex((opt) => compareFn(opt.value(), currentValue));\r\n } else if (this.multiple() && this.isArray(currentValue) && currentValue.length > 0) {\r\n selectedIndex = opts.findIndex((opt) => currentValue.some((v: unknown) => compareFn(v, opt.value())));\r\n }\r\n\r\n const initialIndex = selectedIndex >= 0 ? selectedIndex : 0;\r\n this._setActiveOptionIndex(initialIndex);\r\n }\r\n\r\n // Scroll to active option\r\n private _scrollToActiveOption(): void {\r\n const opts = this._getEnabledOptions();\r\n const activeIndex = this._activeOptionIndex();\r\n\r\n if (activeIndex < 0 || activeIndex >= opts.length) return;\r\n\r\n const activeOption = opts[activeIndex];\r\n const element = activeOption._getHostElement();\r\n const panel = this.panel?.nativeElement;\r\n\r\n if (element && panel) {\r\n const optionTop = element.offsetTop;\r\n const optionBottom = optionTop + element.offsetHeight;\r\n const panelTop = panel.scrollTop;\r\n const panelBottom = panelTop + panel.clientHeight;\r\n\r\n if (optionTop < panelTop) {\r\n panel.scrollTop = optionTop;\r\n } else if (optionBottom > panelBottom) {\r\n panel.scrollTop = optionBottom - panel.clientHeight;\r\n }\r\n }\r\n }\r\n\r\n // Handle type-ahead search\r\n private _handleTypeahead(char: string): void {\r\n // Clear timeout and add to buffer\r\n if (this._typeaheadTimeout) {\r\n clearTimeout(this._typeaheadTimeout);\r\n }\r\n this._typeaheadBuffer += char.toLowerCase();\r\n\r\n // Find matching option\r\n const opts = this._getEnabledOptions();\r\n const matchIndex = opts.findIndex((opt) => opt.getLabel().toLowerCase().startsWith(this._typeaheadBuffer));\r\n\r\n if (matchIndex >= 0) {\r\n if (this.panelOpen()) {\r\n this._setActiveOptionIndex(matchIndex);\r\n } else {\r\n // Select the option when closed\r\n this._onOptionSelected(opts[matchIndex]);\r\n }\r\n }\r\n\r\n // Clear buffer after debounce\r\n this._typeaheadTimeout = setTimeout(() => {\r\n this._typeaheadBuffer = '';\r\n }, this.TYPE_AHEAD_DEBOUNCE);\r\n }\r\n\r\n // Select first non-disabled option\r\n private _selectFirstOption(): void {\r\n const opts = this._getEnabledOptions();\r\n if (opts.length > 0) {\r\n this._onOptionSelected(opts[0]);\r\n }\r\n }\r\n\r\n // Select last non-disabled option\r\n private _selectLastOption(): void {\r\n const opts = this._getEnabledOptions();\r\n if (opts.length > 0) {\r\n this._onOptionSelected(opts[opts.length - 1]);\r\n }\r\n }\r\n\r\n // Get all non-disabled options\r\n private _getEnabledOptions(): FuiOptionComponent[] {\r\n return this.options().filter((opt) => !opt.disabled());\r\n }\r\n\r\n // Start listening for outside clicks when panel opens\r\n private _listenForOutsideClicks(): void {\r\n this._outsideClickSub?.unsubscribe();\r\n\r\n // Run outside Angular zone to avoid triggering change detection on every document click\r\n this._ngZone.runOutsideAngular(() => {\r\n // Use setTimeout to skip the current click event that opened the panel\r\n setTimeout(() => {\r\n this._outsideClickSub = fromEvent<MouseEvent>(this._document, 'click')\r\n .pipe(\r\n filter(() => this.panelOpen()),\r\n filter((event) => {\r\n const target = event.target as HTMLElement;\r\n const triggerElement = this.trigger?.nativeElement;\r\n const panelElement = this.panel?.nativeElement;\r\n const overlayElement = this._overlayRef?.overlayElement;\r\n return (\r\n !triggerElement?.contains(target) &&\r\n !panelElement?.contains(target) &&\r\n !overlayElement?.contains(target)\r\n );\r\n }),\r\n )\r\n .subscribe(() => {\r\n this._ngZone.run(() => {\r\n this.close();\r\n });\r\n });\r\n });\r\n });\r\n }\r\n\r\n // Create overlay for panel\r\n private _createOverlay(): void {\r\n if (this._overlayRef || !this.panel || !this.trigger) return;\r\n\r\n const triggerElement = this.trigger.nativeElement;\r\n const triggerWidth = triggerElement.getBoundingClientRect().width;\r\n\r\n const positions: FuiConnectedPosition[] = [\r\n // Primary: open below\r\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },\r\n // Fallback: open above if no space below\r\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },\r\n ];\r\n\r\n const positionStrategy = this._overlayService\r\n .position()\r\n .connectedTo(triggerElement, positions)\r\n .withPush(false)\r\n .withFlexibleDimensions(true)\r\n .withViewportMargin(8);\r\n\r\n this._overlayRef = this._overlayService.create({\r\n positionStrategy,\r\n scrollStrategy: this._overlayService.scrollStrategies.reposition(),\r\n hasBackdrop: true,\r\n backdropClass: 'fui-select-backdrop',\r\n backdropClickBehavior: 'close',\r\n panelClass: ['fui-select-overlay-panel'],\r\n width: triggerWidth,\r\n });\r\n\r\n // Track overlay subscriptions for proper cleanup\r\n this._overlaySubscriptions.unsubscribe();\r\n this._overlaySubscriptions = new Subscription();\r\n\r\n this._overlaySubscriptions.add(\r\n this._overlayRef.backdropClick.subscribe(() => {\r\n this.close();\r\n }),\r\n );\r\n\r\n this._overlaySubscriptions.add(\r\n this._overlayRef.keydownEvents.subscribe((event) => {\r\n if (event.key === 'Escape') {\r\n this.close();\r\n }\r\n }),\r\n );\r\n\r\n // Attach panel to overlay\r\n const panelElement = this.panel.nativeElement;\r\n this._overlayRef.attach(panelElement);\r\n }\r\n\r\n // Dispose overlay\r\n private _disposeOverlay(): void {\r\n this._overlaySubscriptions.unsubscribe();\r\n if (this._overlayRef) {\r\n this._overlayRef.dispose();\r\n this._overlayRef = null;\r\n }\r\n }\r\n\r\n // Get the active option's id for aria-activedescendant\r\n _getActiveDescendant(): string | null {\r\n const opts = this._getEnabledOptions();\r\n const activeIndex = this._activeOptionIndex();\r\n if (activeIndex >= 0 && activeIndex < opts.length) {\r\n return opts[activeIndex].id;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Announces a message to screen readers via the aria-live region.\r\n * Clears the message after a brief delay to allow repeated announcements.\r\n */\r\n private _announce(message: string): void {\r\n // Clear first to ensure repeated identical messages are announced\r\n this._liveAnnouncement.set('');\r\n setTimeout(() => {\r\n this._liveAnnouncement.set(message);\r\n }, 50);\r\n }\r\n\r\n // Mat-select compatibility methods\r\n get selected(): Signal<unknown> {\r\n return this.value;\r\n }\r\n\r\n // Helper method to check if value is array\r\n isArray(value: unknown): value is unknown[] {\r\n return Array.isArray(value);\r\n }\r\n}\r\n","<!-- Select Trigger -->\r\n<div\r\n #trigger\r\n [id]=\"id\"\r\n class=\"fui-select__trigger\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n [attr.role]=\"'combobox'\"\r\n [attr.aria-haspopup]=\"'listbox'\"\r\n [attr.aria-expanded]=\"panelOpen()\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.aria-invalid]=\"errorState()\"\r\n [attr.aria-describedby]=\"_ariaDescribedby\"\r\n [attr.aria-required]=\"required()\"\r\n [attr.aria-label]=\"empty() ? placeholder() : null\"\r\n aria-autocomplete=\"none\"\r\n [attr.aria-activedescendant]=\"panelOpen() ? _getActiveDescendant() : null\"\r\n [attr.aria-controls]=\"panelOpen() ? id + '-panel' : null\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n (focus)=\"_onFocus()\"\r\n (blur)=\"_onBlur($event)\"\r\n>\r\n <span class=\"fui-select__value\">\r\n @if (empty()) {\r\n <span class=\"fui-select__placeholder\">{{ placeholder() }}</span>\r\n } @else {\r\n <span class=\"fui-select__value-text\">{{ _getDisplayValue() }}</span>\r\n }\r\n </span>\r\n</div>\r\n\r\n<!-- Live region for screen reader announcements -->\r\n<span class=\"fui-sr-only\" aria-live=\"assertive\" aria-atomic=\"true\">{{ _liveAnnouncement() }}</span>\r\n\r\n<!-- Dropdown Panel -->\r\n@if (panelOpen()) {\r\n <div\r\n #panel\r\n [id]=\"id + '-panel'\"\r\n class=\"fui-select__panel\"\r\n role=\"listbox\"\r\n [attr.aria-multiselectable]=\"multiple()\"\r\n [attr.aria-label]=\"placeholder()\"\r\n >\r\n <ng-content></ng-content>\r\n </div>\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, input, output, effect, HostListener, ViewChild, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
2
|
+
import { Injectable, inject, ChangeDetectorRef, input, output, effect, HostListener, ViewChild, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
4
|
import { DOCUMENT } from '@angular/common';
|
|
4
5
|
import { FuiIconComponent } from '@raintonic/formaui/components/icon';
|
|
6
|
+
import { FuiIntlBase } from '@raintonic/formaui/core';
|
|
7
|
+
|
|
8
|
+
class FuiSidePanelIntl extends FuiIntlBase {
|
|
9
|
+
closeAriaLabel = 'Close panel';
|
|
10
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiSidePanelIntl, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
11
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiSidePanelIntl, providedIn: 'root' });
|
|
12
|
+
}
|
|
13
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiSidePanelIntl, decorators: [{
|
|
14
|
+
type: Injectable,
|
|
15
|
+
args: [{ providedIn: 'root' }]
|
|
16
|
+
}] });
|
|
5
17
|
|
|
6
18
|
/**
|
|
7
19
|
* @component FuiSidePanelComponent
|
|
@@ -27,6 +39,8 @@ import { FuiIconComponent } from '@raintonic/formaui/components/icon';
|
|
|
27
39
|
*/
|
|
28
40
|
class FuiSidePanelComponent {
|
|
29
41
|
_document = inject(DOCUMENT);
|
|
42
|
+
intl = inject(FuiSidePanelIntl);
|
|
43
|
+
_cdr = inject(ChangeDetectorRef);
|
|
30
44
|
open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
31
45
|
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
32
46
|
width = input('500px', ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
@@ -50,6 +64,7 @@ class FuiSidePanelComponent {
|
|
|
50
64
|
this._restoreFocus();
|
|
51
65
|
}
|
|
52
66
|
});
|
|
67
|
+
this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });
|
|
53
68
|
}
|
|
54
69
|
onKeydown(event) {
|
|
55
70
|
if (!this.open())
|
|
@@ -124,7 +139,7 @@ class FuiSidePanelComponent {
|
|
|
124
139
|
return Array.from(panel.querySelectorAll(selectors)).filter((el) => el.offsetParent !== null);
|
|
125
140
|
}
|
|
126
141
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiSidePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
127
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiSidePanelComponent, isStandalone: true, selector: "fui-side-panel", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, topOffset: { classPropertyName: "topOffset", publicName: "topOffset", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "ariaLabelledBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class.fui-side-panel--open": "open()", "class.fui-side-panel--no-backdrop": "!hasBackdrop()", "style.--_side-panel-top-offset": "topOffset()" }, classAttribute: "fui-side-panel" }, viewQueries: [{ propertyName: "_panelElement", first: true, predicate: ["panelElement"], descendants: true }], ngImport: i0, template: "@if (open() && hasBackdrop()) {\r\n <div class=\"fui-side-panel__backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\r\n}\r\n<div\r\n #panelElement\r\n class=\"fui-side-panel__panel\"\r\n [style.width]=\"width()\"\r\n role=\"dialog\"\r\n [attr.aria-modal]=\"open() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel() || (!ariaLabelledBy() ? title() : null)\"\r\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\r\n tabindex=\"-1\"\r\n>\r\n <div class=\"fui-side-panel__header\">\r\n <span class=\"fui-side-panel__title\">{{ title() }}</span>\r\n <button type=\"button\" class=\"fui-side-panel__close\" (click)=\"close()\" aria-label=\"
|
|
142
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiSidePanelComponent, isStandalone: true, selector: "fui-side-panel", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, topOffset: { classPropertyName: "topOffset", publicName: "topOffset", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "ariaLabelledBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class.fui-side-panel--open": "open()", "class.fui-side-panel--no-backdrop": "!hasBackdrop()", "style.--_side-panel-top-offset": "topOffset()" }, classAttribute: "fui-side-panel" }, viewQueries: [{ propertyName: "_panelElement", first: true, predicate: ["panelElement"], descendants: true }], ngImport: i0, template: "@if (open() && hasBackdrop()) {\r\n <div class=\"fui-side-panel__backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\r\n}\r\n<div\r\n #panelElement\r\n class=\"fui-side-panel__panel\"\r\n [style.width]=\"width()\"\r\n role=\"dialog\"\r\n [attr.aria-modal]=\"open() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel() || (!ariaLabelledBy() ? title() : null)\"\r\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\r\n tabindex=\"-1\"\r\n>\r\n <div class=\"fui-side-panel__header\">\r\n <span class=\"fui-side-panel__title\">{{ title() }}</span>\r\n <button type=\"button\" class=\"fui-side-panel__close\" (click)=\"close()\" [attr.aria-label]=\"intl.closeAriaLabel\">\r\n <fui-icon name=\"x\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n <div class=\"fui-side-panel__content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"fui-side-panel__footer\">\r\n <ng-content select=\"[sidePanelFooter]\"></ng-content>\r\n </div>\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-side-panel{--fui-side-panel-z-index: 10;--fui-side-panel-bg: var(--fui-surface-00);--fui-side-panel-border-color: var(--fui-border-color);--fui-side-panel-shadow: -4px 0 16px var(--fui-black-10);--fui-side-panel-backdrop-color: var(--fui-black-20);--fui-side-panel-header-padding: var(--fui-spacing-04) var(--fui-spacing-05);--fui-side-panel-content-padding: var(--fui-spacing-03);--fui-side-panel-footer-padding: var(--fui-spacing-04) var(--fui-spacing-05);position:fixed;top:var(--_side-panel-top-offset, 0);right:0;bottom:0;left:0;pointer-events:none;z-index:var(--fui-side-panel-z-index);overflow:hidden}.fui-side-panel--open{pointer-events:auto}.fui-side-panel--no-backdrop.fui-side-panel--open{pointer-events:none}.fui-side-panel__backdrop{position:fixed;top:var(--_side-panel-top-offset, 0);right:0;bottom:0;left:0;background-color:var(--fui-side-panel-backdrop-color);z-index:1;transition:opacity var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}.fui-side-panel__panel{position:fixed;top:var(--_side-panel-top-offset, 0);right:0;bottom:0;display:flex;flex-direction:column;background-color:var(--fui-side-panel-bg);border-left:1px solid var(--fui-side-panel-border-color);box-shadow:var(--fui-side-panel-shadow);z-index:2;transform:translate(100%);transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms}.fui-side-panel--open .fui-side-panel__panel{transform:translate(0)}.fui-side-panel__panel{pointer-events:auto}.fui-side-panel__header{display:flex;align-items:center;justify-content:space-between;padding:var(--fui-side-panel-header-padding);border-bottom:1px solid var(--fui-side-panel-border-color);flex-shrink:0}.fui-side-panel__title{font-size:var(--fui-font-size-03);font-weight:var(--fui-font-weight-semibold);color:var(--fui-text-primary)}.fui-side-panel__close{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:none;background:transparent;border-radius:var(--fui-border-radius-sm);color:var(--fui-text-secondary);cursor:pointer;transition:background-color var(--fui-duration-moderate-01) var(--fui-ease-standard),color var(--fui-duration-moderate-01) var(--fui-ease-standard)}.fui-side-panel__close:hover{background-color:var(--fui-surface-02);color:var(--fui-text-primary)}.fui-side-panel__content{flex:1;overflow-y:auto;background-color:var(--fui-bg);padding:var(--fui-side-panel-content-padding)}.fui-side-panel__footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--fui-spacing-03);padding:var(--fui-side-panel-footer-padding);border-top:1px solid var(--fui-side-panel-border-color);flex-shrink:0}.fui-side-panel__footer:empty{display:none}@media(prefers-reduced-motion:reduce){.fui-side-panel__backdrop,.fui-side-panel__panel,.fui-side-panel__close{transition:none}}\n"], dependencies: [{ kind: "component", type: FuiIconComponent, selector: "fui-icon", inputs: ["name", "size", "weight", "color", "ariaLabel", "spin", "pulse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
128
143
|
}
|
|
129
144
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiSidePanelComponent, decorators: [{
|
|
130
145
|
type: Component,
|
|
@@ -133,7 +148,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
133
148
|
'[class.fui-side-panel--open]': 'open()',
|
|
134
149
|
'[class.fui-side-panel--no-backdrop]': '!hasBackdrop()',
|
|
135
150
|
'[style.--_side-panel-top-offset]': 'topOffset()',
|
|
136
|
-
}, template: "@if (open() && hasBackdrop()) {\r\n <div class=\"fui-side-panel__backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\r\n}\r\n<div\r\n #panelElement\r\n class=\"fui-side-panel__panel\"\r\n [style.width]=\"width()\"\r\n role=\"dialog\"\r\n [attr.aria-modal]=\"open() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel() || (!ariaLabelledBy() ? title() : null)\"\r\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\r\n tabindex=\"-1\"\r\n>\r\n <div class=\"fui-side-panel__header\">\r\n <span class=\"fui-side-panel__title\">{{ title() }}</span>\r\n <button type=\"button\" class=\"fui-side-panel__close\" (click)=\"close()\" aria-label=\"
|
|
151
|
+
}, template: "@if (open() && hasBackdrop()) {\r\n <div class=\"fui-side-panel__backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\r\n}\r\n<div\r\n #panelElement\r\n class=\"fui-side-panel__panel\"\r\n [style.width]=\"width()\"\r\n role=\"dialog\"\r\n [attr.aria-modal]=\"open() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel() || (!ariaLabelledBy() ? title() : null)\"\r\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\r\n tabindex=\"-1\"\r\n>\r\n <div class=\"fui-side-panel__header\">\r\n <span class=\"fui-side-panel__title\">{{ title() }}</span>\r\n <button type=\"button\" class=\"fui-side-panel__close\" (click)=\"close()\" [attr.aria-label]=\"intl.closeAriaLabel\">\r\n <fui-icon name=\"x\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n <div class=\"fui-side-panel__content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"fui-side-panel__footer\">\r\n <ng-content select=\"[sidePanelFooter]\"></ng-content>\r\n </div>\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-side-panel{--fui-side-panel-z-index: 10;--fui-side-panel-bg: var(--fui-surface-00);--fui-side-panel-border-color: var(--fui-border-color);--fui-side-panel-shadow: -4px 0 16px var(--fui-black-10);--fui-side-panel-backdrop-color: var(--fui-black-20);--fui-side-panel-header-padding: var(--fui-spacing-04) var(--fui-spacing-05);--fui-side-panel-content-padding: var(--fui-spacing-03);--fui-side-panel-footer-padding: var(--fui-spacing-04) var(--fui-spacing-05);position:fixed;top:var(--_side-panel-top-offset, 0);right:0;bottom:0;left:0;pointer-events:none;z-index:var(--fui-side-panel-z-index);overflow:hidden}.fui-side-panel--open{pointer-events:auto}.fui-side-panel--no-backdrop.fui-side-panel--open{pointer-events:none}.fui-side-panel__backdrop{position:fixed;top:var(--_side-panel-top-offset, 0);right:0;bottom:0;left:0;background-color:var(--fui-side-panel-backdrop-color);z-index:1;transition:opacity var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}.fui-side-panel__panel{position:fixed;top:var(--_side-panel-top-offset, 0);right:0;bottom:0;display:flex;flex-direction:column;background-color:var(--fui-side-panel-bg);border-left:1px solid var(--fui-side-panel-border-color);box-shadow:var(--fui-side-panel-shadow);z-index:2;transform:translate(100%);transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms}.fui-side-panel--open .fui-side-panel__panel{transform:translate(0)}.fui-side-panel__panel{pointer-events:auto}.fui-side-panel__header{display:flex;align-items:center;justify-content:space-between;padding:var(--fui-side-panel-header-padding);border-bottom:1px solid var(--fui-side-panel-border-color);flex-shrink:0}.fui-side-panel__title{font-size:var(--fui-font-size-03);font-weight:var(--fui-font-weight-semibold);color:var(--fui-text-primary)}.fui-side-panel__close{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:none;background:transparent;border-radius:var(--fui-border-radius-sm);color:var(--fui-text-secondary);cursor:pointer;transition:background-color var(--fui-duration-moderate-01) var(--fui-ease-standard),color var(--fui-duration-moderate-01) var(--fui-ease-standard)}.fui-side-panel__close:hover{background-color:var(--fui-surface-02);color:var(--fui-text-primary)}.fui-side-panel__content{flex:1;overflow-y:auto;background-color:var(--fui-bg);padding:var(--fui-side-panel-content-padding)}.fui-side-panel__footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--fui-spacing-03);padding:var(--fui-side-panel-footer-padding);border-top:1px solid var(--fui-side-panel-border-color);flex-shrink:0}.fui-side-panel__footer:empty{display:none}@media(prefers-reduced-motion:reduce){.fui-side-panel__backdrop,.fui-side-panel__panel,.fui-side-panel__close{transition:none}}\n"] }]
|
|
137
152
|
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], hasBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBackdrop", required: false }] }], topOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "topOffset", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledBy", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], _panelElement: [{
|
|
138
153
|
type: ViewChild,
|
|
139
154
|
args: ['panelElement', { static: false }]
|
|
@@ -146,5 +161,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
146
161
|
* Generated bundle index. Do not edit.
|
|
147
162
|
*/
|
|
148
163
|
|
|
149
|
-
export { FuiSidePanelComponent };
|
|
164
|
+
export { FuiSidePanelComponent, FuiSidePanelIntl };
|
|
150
165
|
//# sourceMappingURL=raintonic-formaui-components-side-panel.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raintonic-formaui-components-side-panel.mjs","sources":["../../../lib/components/side-panel/side-panel.component.ts","../../../lib/components/side-panel/side-panel.component.html","../../../lib/components/side-panel/raintonic-formaui-components-side-panel.ts"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n effect,\r\n ElementRef,\r\n HostListener,\r\n inject,\r\n input,\r\n output,\r\n ViewChild,\r\n ViewEncapsulation,\r\n} from '@angular/core';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\n\r\n/**\r\n * @component FuiSidePanelComponent\r\n * @selector fui-side-panel\r\n * @description A slide-in side panel overlay with optional backdrop, focus trapping, and keyboard dismiss.\r\n * Renders from the right edge of the viewport with configurable width and top offset.\r\n *\r\n * @input open - Whether the side panel is visible. Default false.\r\n * @input title - Title text displayed in the panel header.\r\n * @input width - CSS width of the panel. Default '500px'.\r\n * @input hasBackdrop - Whether to show a backdrop behind the panel. Default true.\r\n * @input topOffset - CSS top offset (e.g. to clear a fixed toolbar). Default '0px'.\r\n * @input ariaLabel - ARIA label for the panel when no visible title is present.\r\n * @input ariaLabelledBy - ID of an element that labels the panel.\r\n * @output closed - Emits when the panel requests closing (close button, Escape, or backdrop click).\r\n *\r\n * @cssvar --_side-panel-top-offset - Internal CSS variable set from the topOffset input.\r\n *\r\n * @example\r\n * <fui-side-panel [open]=\"isPanelOpen\" title=\"Details\" (closed)=\"isPanelOpen = false\">\r\n * <p>Panel content here.</p>\r\n * </fui-side-panel>\r\n */\r\n@Component({\r\n selector: 'fui-side-panel',\r\n standalone: true,\r\n imports: [FuiIconComponent],\r\n templateUrl: './side-panel.component.html',\r\n styleUrl: './side-panel.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-side-panel',\r\n '[class.fui-side-panel--open]': 'open()',\r\n '[class.fui-side-panel--no-backdrop]': '!hasBackdrop()',\r\n '[style.--_side-panel-top-offset]': 'topOffset()',\r\n },\r\n})\r\nexport class FuiSidePanelComponent {\r\n private readonly _document = inject(DOCUMENT);\r\n\r\n readonly open = input(false);\r\n readonly title = input('');\r\n readonly width = input('500px');\r\n readonly hasBackdrop = input(true);\r\n readonly topOffset = input('0px');\r\n\r\n /** ARIA label for the side panel, used when no visible title is present */\r\n readonly ariaLabel = input<string | null>(null);\r\n\r\n /** ID of an element that labels the side panel */\r\n readonly ariaLabelledBy = input<string | null>(null);\r\n\r\n readonly closed = output();\r\n\r\n @ViewChild('panelElement', { static: false })\r\n private _panelElement?: ElementRef<HTMLElement>;\r\n\r\n private _previouslyFocusedElement: HTMLElement | null = null;\r\n\r\n constructor() {\r\n // Watch open state changes for focus management\r\n effect(() => {\r\n const isOpen = this.open();\r\n if (isOpen) {\r\n this._saveFocusAndTrap();\r\n } else {\r\n this._restoreFocus();\r\n }\r\n });\r\n }\r\n\r\n @HostListener('keydown', ['$event'])\r\n onKeydown(event: KeyboardEvent): void {\r\n if (!this.open()) return;\r\n\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n this.close();\r\n return;\r\n }\r\n\r\n // Focus trap cycling\r\n if (event.key === 'Tab') {\r\n const focusableElements = this._getFocusableElements();\r\n if (focusableElements.length === 0) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n const firstFocusable = focusableElements[0];\r\n const lastFocusable = focusableElements[focusableElements.length - 1];\r\n const activeElement = this._document.activeElement;\r\n\r\n if (event.shiftKey) {\r\n if (activeElement === firstFocusable) {\r\n event.preventDefault();\r\n lastFocusable.focus();\r\n }\r\n } else {\r\n if (activeElement === lastFocusable) {\r\n event.preventDefault();\r\n firstFocusable.focus();\r\n }\r\n }\r\n }\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n\r\n private _saveFocusAndTrap(): void {\r\n this._previouslyFocusedElement = this._document.activeElement as HTMLElement;\r\n // Focus the panel after it renders\r\n setTimeout(() => {\r\n this._focusFirstTabbable();\r\n });\r\n }\r\n\r\n private _restoreFocus(): void {\r\n if (this._previouslyFocusedElement) {\r\n this._previouslyFocusedElement.focus();\r\n this._previouslyFocusedElement = null;\r\n }\r\n }\r\n\r\n private _focusFirstTabbable(): void {\r\n const focusableElements = this._getFocusableElements();\r\n if (focusableElements.length > 0) {\r\n focusableElements[0].focus();\r\n } else {\r\n this._panelElement?.nativeElement.focus();\r\n }\r\n }\r\n\r\n private _getFocusableElements(): HTMLElement[] {\r\n const panel = this._panelElement?.nativeElement;\r\n if (!panel) return [];\r\n\r\n const selectors = [\r\n 'a[href]',\r\n 'button:not([disabled])',\r\n 'textarea:not([disabled])',\r\n 'input:not([disabled])',\r\n 'select:not([disabled])',\r\n '[tabindex]:not([tabindex=\"-1\"])',\r\n '[contenteditable=\"true\"]',\r\n ].join(',');\r\n\r\n return Array.from(panel.querySelectorAll<HTMLElement>(selectors)).filter((el) => el.offsetParent !== null);\r\n }\r\n}\r\n","@if (open() && hasBackdrop()) {\r\n <div class=\"fui-side-panel__backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\r\n}\r\n<div\r\n #panelElement\r\n class=\"fui-side-panel__panel\"\r\n [style.width]=\"width()\"\r\n role=\"dialog\"\r\n [attr.aria-modal]=\"open() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel() || (!ariaLabelledBy() ? title() : null)\"\r\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\r\n tabindex=\"-1\"\r\n>\r\n <div class=\"fui-side-panel__header\">\r\n <span class=\"fui-side-panel__title\">{{ title() }}</span>\r\n <button type=\"button\" class=\"fui-side-panel__close\" (click)=\"close()\" aria-label=\"Close panel\">\r\n <fui-icon name=\"x\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n <div class=\"fui-side-panel__content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"fui-side-panel__footer\">\r\n <ng-content select=\"[sidePanelFooter]\"></ng-content>\r\n </div>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"raintonic-formaui-components-side-panel.mjs","sources":["../../../lib/components/side-panel/side-panel.intl.ts","../../../lib/components/side-panel/side-panel.component.ts","../../../lib/components/side-panel/side-panel.component.html","../../../lib/components/side-panel/raintonic-formaui-components-side-panel.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiSidePanelIntl extends FuiIntlBase {\r\n closeAriaLabel = 'Close panel';\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n effect,\r\n ElementRef,\r\n HostListener,\r\n inject,\r\n input,\r\n output,\r\n ViewChild,\r\n ViewEncapsulation,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FuiSidePanelIntl } from './side-panel.intl';\r\n\r\n/**\r\n * @component FuiSidePanelComponent\r\n * @selector fui-side-panel\r\n * @description A slide-in side panel overlay with optional backdrop, focus trapping, and keyboard dismiss.\r\n * Renders from the right edge of the viewport with configurable width and top offset.\r\n *\r\n * @input open - Whether the side panel is visible. Default false.\r\n * @input title - Title text displayed in the panel header.\r\n * @input width - CSS width of the panel. Default '500px'.\r\n * @input hasBackdrop - Whether to show a backdrop behind the panel. Default true.\r\n * @input topOffset - CSS top offset (e.g. to clear a fixed toolbar). Default '0px'.\r\n * @input ariaLabel - ARIA label for the panel when no visible title is present.\r\n * @input ariaLabelledBy - ID of an element that labels the panel.\r\n * @output closed - Emits when the panel requests closing (close button, Escape, or backdrop click).\r\n *\r\n * @cssvar --_side-panel-top-offset - Internal CSS variable set from the topOffset input.\r\n *\r\n * @example\r\n * <fui-side-panel [open]=\"isPanelOpen\" title=\"Details\" (closed)=\"isPanelOpen = false\">\r\n * <p>Panel content here.</p>\r\n * </fui-side-panel>\r\n */\r\n@Component({\r\n selector: 'fui-side-panel',\r\n standalone: true,\r\n imports: [FuiIconComponent],\r\n templateUrl: './side-panel.component.html',\r\n styleUrl: './side-panel.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-side-panel',\r\n '[class.fui-side-panel--open]': 'open()',\r\n '[class.fui-side-panel--no-backdrop]': '!hasBackdrop()',\r\n '[style.--_side-panel-top-offset]': 'topOffset()',\r\n },\r\n})\r\nexport class FuiSidePanelComponent {\r\n private readonly _document = inject(DOCUMENT);\r\n readonly intl = inject(FuiSidePanelIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n readonly open = input(false);\r\n readonly title = input('');\r\n readonly width = input('500px');\r\n readonly hasBackdrop = input(true);\r\n readonly topOffset = input('0px');\r\n\r\n /** ARIA label for the side panel, used when no visible title is present */\r\n readonly ariaLabel = input<string | null>(null);\r\n\r\n /** ID of an element that labels the side panel */\r\n readonly ariaLabelledBy = input<string | null>(null);\r\n\r\n readonly closed = output();\r\n\r\n @ViewChild('panelElement', { static: false })\r\n private _panelElement?: ElementRef<HTMLElement>;\r\n\r\n private _previouslyFocusedElement: HTMLElement | null = null;\r\n\r\n constructor() {\r\n // Watch open state changes for focus management\r\n effect(() => {\r\n const isOpen = this.open();\r\n if (isOpen) {\r\n this._saveFocusAndTrap();\r\n } else {\r\n this._restoreFocus();\r\n }\r\n });\r\n\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });\r\n }\r\n\r\n @HostListener('keydown', ['$event'])\r\n onKeydown(event: KeyboardEvent): void {\r\n if (!this.open()) return;\r\n\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n this.close();\r\n return;\r\n }\r\n\r\n // Focus trap cycling\r\n if (event.key === 'Tab') {\r\n const focusableElements = this._getFocusableElements();\r\n if (focusableElements.length === 0) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n const firstFocusable = focusableElements[0];\r\n const lastFocusable = focusableElements[focusableElements.length - 1];\r\n const activeElement = this._document.activeElement;\r\n\r\n if (event.shiftKey) {\r\n if (activeElement === firstFocusable) {\r\n event.preventDefault();\r\n lastFocusable.focus();\r\n }\r\n } else {\r\n if (activeElement === lastFocusable) {\r\n event.preventDefault();\r\n firstFocusable.focus();\r\n }\r\n }\r\n }\r\n }\r\n\r\n close(): void {\r\n this.closed.emit();\r\n }\r\n\r\n private _saveFocusAndTrap(): void {\r\n this._previouslyFocusedElement = this._document.activeElement as HTMLElement;\r\n // Focus the panel after it renders\r\n setTimeout(() => {\r\n this._focusFirstTabbable();\r\n });\r\n }\r\n\r\n private _restoreFocus(): void {\r\n if (this._previouslyFocusedElement) {\r\n this._previouslyFocusedElement.focus();\r\n this._previouslyFocusedElement = null;\r\n }\r\n }\r\n\r\n private _focusFirstTabbable(): void {\r\n const focusableElements = this._getFocusableElements();\r\n if (focusableElements.length > 0) {\r\n focusableElements[0].focus();\r\n } else {\r\n this._panelElement?.nativeElement.focus();\r\n }\r\n }\r\n\r\n private _getFocusableElements(): HTMLElement[] {\r\n const panel = this._panelElement?.nativeElement;\r\n if (!panel) return [];\r\n\r\n const selectors = [\r\n 'a[href]',\r\n 'button:not([disabled])',\r\n 'textarea:not([disabled])',\r\n 'input:not([disabled])',\r\n 'select:not([disabled])',\r\n '[tabindex]:not([tabindex=\"-1\"])',\r\n '[contenteditable=\"true\"]',\r\n ].join(',');\r\n\r\n return Array.from(panel.querySelectorAll<HTMLElement>(selectors)).filter((el) => el.offsetParent !== null);\r\n }\r\n}\r\n","@if (open() && hasBackdrop()) {\r\n <div class=\"fui-side-panel__backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\r\n}\r\n<div\r\n #panelElement\r\n class=\"fui-side-panel__panel\"\r\n [style.width]=\"width()\"\r\n role=\"dialog\"\r\n [attr.aria-modal]=\"open() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel() || (!ariaLabelledBy() ? title() : null)\"\r\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\r\n tabindex=\"-1\"\r\n>\r\n <div class=\"fui-side-panel__header\">\r\n <span class=\"fui-side-panel__title\">{{ title() }}</span>\r\n <button type=\"button\" class=\"fui-side-panel__close\" (click)=\"close()\" [attr.aria-label]=\"intl.closeAriaLabel\">\r\n <fui-icon name=\"x\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n <div class=\"fui-side-panel__content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"fui-side-panel__footer\">\r\n <ng-content select=\"[sidePanelFooter]\"></ng-content>\r\n </div>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|