@raintonic/formaui 0.4.0 → 0.9.2
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 +80 -35
- package/README.md +22 -26
- package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs +39 -41
- package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-cdk-form-field.mjs +207 -3
- package/fesm2022/raintonic-formaui-cdk-form-field.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-cdk-overlay.mjs +19 -1
- package/fesm2022/raintonic-formaui-cdk-overlay.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs +5 -12
- package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-accordion.mjs +8 -5
- package/fesm2022/raintonic-formaui-components-accordion.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-alert.mjs +16 -2
- package/fesm2022/raintonic-formaui-components-alert.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs +255 -462
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-avatar.mjs +34 -59
- package/fesm2022/raintonic-formaui-components-avatar.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-badge.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-badge.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-breadcrumb.mjs +4 -4
- package/fesm2022/raintonic-formaui-components-breadcrumb.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-button-group.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-button-group.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-button.mjs +15 -20
- package/fesm2022/raintonic-formaui-components-button.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-card.mjs +2 -2
- 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-chip.mjs +97 -0
- package/fesm2022/raintonic-formaui-components-chip.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-data-table.mjs +69 -29
- package/fesm2022/raintonic-formaui-components-data-table.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-date-picker.mjs +223 -144
- package/fesm2022/raintonic-formaui-components-date-picker.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-divider.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-divider.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-drawer.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-drawer.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-dropdown-menu.mjs +888 -0
- package/fesm2022/raintonic-formaui-components-dropdown-menu.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-dual-tier-navigation.mjs +774 -0
- package/fesm2022/raintonic-formaui-components-dual-tier-navigation.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-empty-state.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-empty-state.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-file-upload.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-file-upload.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-form-field.mjs +81 -50
- 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 +47 -12
- 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-number-input.mjs +20 -12
- package/fesm2022/raintonic-formaui-components-number-input.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-paginator.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-paginator.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-password-input.mjs +35 -110
- package/fesm2022/raintonic-formaui-components-password-input.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-popover.mjs +3 -2
- package/fesm2022/raintonic-formaui-components-popover.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-progressbar.mjs +3 -2
- package/fesm2022/raintonic-formaui-components-progressbar.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-radio.mjs +5 -6
- package/fesm2022/raintonic-formaui-components-radio.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-select.mjs +257 -412
- package/fesm2022/raintonic-formaui-components-select.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-side-panel.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-side-panel.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-sidebar-nav-menu.mjs +525 -0
- package/fesm2022/raintonic-formaui-components-sidebar-nav-menu.mjs.map +1 -0
- 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 +2 -2
- package/fesm2022/raintonic-formaui-components-slider.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-spinner.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-spinner.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-stepper.mjs +50 -45
- package/fesm2022/raintonic-formaui-components-stepper.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-strength-meter.mjs +149 -0
- package/fesm2022/raintonic-formaui-components-strength-meter.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tab.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-tab.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-time-picker.mjs +194 -154
- package/fesm2022/raintonic-formaui-components-time-picker.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-toggle-group.mjs +302 -0
- package/fesm2022/raintonic-formaui-components-toggle-group.mjs.map +1 -0
- 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 +2 -2
- package/fesm2022/raintonic-formaui-components-toolbar.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tooltip.mjs +10 -4
- package/fesm2022/raintonic-formaui-components-tooltip.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-topbar.mjs +60 -0
- package/fesm2022/raintonic-formaui-components-topbar.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tree-select.mjs +59 -69
- package/fesm2022/raintonic-formaui-components-tree-select.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tree-table.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-tree-table.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tree.mjs +31 -5
- package/fesm2022/raintonic-formaui-components-tree.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-core.mjs +279 -1
- package/fesm2022/raintonic-formaui-core.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-services-breakpoint.mjs +93 -0
- package/fesm2022/raintonic-formaui-services-breakpoint.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-services-dialog.mjs +314 -16
- package/fesm2022/raintonic-formaui-services-dialog.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-services-notification.mjs +93 -29
- package/fesm2022/raintonic-formaui-services-notification.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-services-theme.mjs +46 -196
- package/fesm2022/raintonic-formaui-services-theme.mjs.map +1 -1
- package/fesm2022/raintonic-formaui.mjs +1 -1
- package/fesm2022/raintonic-formaui.mjs.map +1 -1
- package/llms-full.txt +2329 -450
- package/llms.txt +36 -33
- package/package.json +42 -19
- package/styles/fonts/Geist-Bold.woff2 +0 -0
- package/styles/fonts/Geist-Italic.woff2 +0 -0
- package/styles/fonts/Geist-Light.woff2 +0 -0
- package/styles/fonts/Geist-Medium.woff2 +0 -0
- package/styles/fonts/Geist-Regular.woff2 +0 -0
- package/styles/fonts/Geist-SemiBold.woff2 +0 -0
- package/styles/fonts/GeistMono-Regular.woff2 +0 -0
- package/styles/generated/_tokens.scss +906 -0
- package/styles/index.scss +11 -10
- package/styles/partials/_brand.scss +46 -0
- package/styles/partials/_constants.scss +22 -20
- package/styles/partials/_fonts.scss +54 -10
- package/styles/partials/_grid.scss +29 -18
- package/styles/partials/_mixins.scss +69 -27
- package/styles/partials/_motion.scss +28 -33
- package/styles/partials/_theme.scss +28 -255
- package/styles/partials/_type.scss +117 -0
- package/styles/partials/_typography.scss +45 -45
- package/styles/partials/_utilities.scss +198 -98
- package/styles/partials/components/_button.scss +144 -75
- package/styles/partials/components/_dialog.scss +181 -180
- package/styles/partials/components/_overlay.scss +87 -87
- package/styles/partials/themes/_dark.scss +3 -268
- package/styles/partials/themes/_light.scss +4 -268
- package/styles/styles.css +7744 -0
- package/styles/styles.entry.scss +3 -0
- package/styles/utilities.css +4802 -0
- package/styles/utilities.entry.scss +3 -0
- package/types/raintonic-formaui-cdk-drag-drop.d.ts +0 -1
- package/types/raintonic-formaui-cdk-drag-drop.d.ts.map +1 -1
- package/types/raintonic-formaui-cdk-form-field.d.ts +118 -2
- package/types/raintonic-formaui-cdk-form-field.d.ts.map +1 -1
- package/types/raintonic-formaui-cdk-overlay.d.ts +2 -0
- package/types/raintonic-formaui-cdk-overlay.d.ts.map +1 -1
- package/types/raintonic-formaui-cdk-virtual-scroll.d.ts +0 -1
- package/types/raintonic-formaui-cdk-virtual-scroll.d.ts.map +1 -1
- package/types/raintonic-formaui-components-accordion.d.ts +1 -1
- package/types/raintonic-formaui-components-accordion.d.ts.map +1 -1
- package/types/raintonic-formaui-components-alert.d.ts +6 -1
- package/types/raintonic-formaui-components-alert.d.ts.map +1 -1
- package/types/raintonic-formaui-components-autocomplete.d.ts +73 -116
- package/types/raintonic-formaui-components-autocomplete.d.ts.map +1 -1
- package/types/raintonic-formaui-components-avatar.d.ts +13 -31
- package/types/raintonic-formaui-components-avatar.d.ts.map +1 -1
- package/types/raintonic-formaui-components-button.d.ts +4 -10
- package/types/raintonic-formaui-components-button.d.ts.map +1 -1
- package/types/raintonic-formaui-components-chip.d.ts +43 -0
- package/types/raintonic-formaui-components-chip.d.ts.map +1 -0
- package/types/raintonic-formaui-components-data-table.d.ts +48 -11
- package/types/raintonic-formaui-components-data-table.d.ts.map +1 -1
- package/types/raintonic-formaui-components-date-picker.d.ts +59 -23
- package/types/raintonic-formaui-components-date-picker.d.ts.map +1 -1
- package/types/raintonic-formaui-components-dropdown-menu.d.ts +394 -0
- package/types/raintonic-formaui-components-dropdown-menu.d.ts.map +1 -0
- package/types/raintonic-formaui-components-dual-tier-navigation.d.ts +87 -0
- package/types/raintonic-formaui-components-dual-tier-navigation.d.ts.map +1 -0
- package/types/raintonic-formaui-components-form-field.d.ts +51 -21
- package/types/raintonic-formaui-components-form-field.d.ts.map +1 -1
- package/types/raintonic-formaui-components-input.d.ts +20 -11
- package/types/raintonic-formaui-components-input.d.ts.map +1 -1
- package/types/raintonic-formaui-components-number-input.d.ts +5 -3
- package/types/raintonic-formaui-components-number-input.d.ts.map +1 -1
- package/types/raintonic-formaui-components-password-input.d.ts +18 -32
- package/types/raintonic-formaui-components-password-input.d.ts.map +1 -1
- package/types/raintonic-formaui-components-popover.d.ts.map +1 -1
- package/types/raintonic-formaui-components-progressbar.d.ts +1 -1
- package/types/raintonic-formaui-components-progressbar.d.ts.map +1 -1
- package/types/raintonic-formaui-components-radio.d.ts +1 -2
- package/types/raintonic-formaui-components-radio.d.ts.map +1 -1
- package/types/raintonic-formaui-components-select.d.ts +107 -76
- package/types/raintonic-formaui-components-select.d.ts.map +1 -1
- package/types/raintonic-formaui-components-sidebar-nav-menu.d.ts +223 -0
- package/types/raintonic-formaui-components-sidebar-nav-menu.d.ts.map +1 -0
- package/types/raintonic-formaui-components-stepper.d.ts +4 -2
- package/types/raintonic-formaui-components-stepper.d.ts.map +1 -1
- package/types/raintonic-formaui-components-strength-meter.d.ts +78 -0
- package/types/raintonic-formaui-components-strength-meter.d.ts.map +1 -0
- package/types/raintonic-formaui-components-time-picker.d.ts +44 -24
- package/types/raintonic-formaui-components-time-picker.d.ts.map +1 -1
- package/types/raintonic-formaui-components-toggle-group.d.ts +100 -0
- package/types/raintonic-formaui-components-toggle-group.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tooltip.d.ts +2 -1
- package/types/raintonic-formaui-components-tooltip.d.ts.map +1 -1
- package/types/raintonic-formaui-components-topbar.d.ts +48 -0
- package/types/raintonic-formaui-components-topbar.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tree-select.d.ts +25 -9
- package/types/raintonic-formaui-components-tree-select.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 +243 -5
- package/types/raintonic-formaui-core.d.ts.map +1 -1
- package/types/raintonic-formaui-services-breakpoint.d.ts +44 -0
- package/types/raintonic-formaui-services-breakpoint.d.ts.map +1 -0
- package/types/raintonic-formaui-services-dialog.d.ts +141 -2
- package/types/raintonic-formaui-services-dialog.d.ts.map +1 -1
- package/types/raintonic-formaui-services-notification.d.ts +24 -2
- package/types/raintonic-formaui-services-notification.d.ts.map +1 -1
- package/types/raintonic-formaui-services-theme.d.ts +13 -103
- package/types/raintonic-formaui-services-theme.d.ts.map +1 -1
- package/types/raintonic-formaui.d.ts +1 -1
- package/fesm2022/raintonic-formaui-components-big-menu.mjs +0 -86
- package/fesm2022/raintonic-formaui-components-big-menu.mjs.map +0 -1
- package/fesm2022/raintonic-formaui-components-menu.mjs +0 -896
- package/fesm2022/raintonic-formaui-components-menu.mjs.map +0 -1
- package/fesm2022/raintonic-formaui-components-sidebar.mjs +0 -275
- package/fesm2022/raintonic-formaui-components-sidebar.mjs.map +0 -1
- package/fesm2022/raintonic-formaui-components-tag.mjs +0 -95
- package/fesm2022/raintonic-formaui-components-tag.mjs.map +0 -1
- package/styles/_fonts-entry.scss +0 -3
- package/styles/fonts/inter-tight-latin-italic.woff2 +0 -0
- package/styles/fonts/inter-tight-latin.woff2 +0 -0
- package/types/raintonic-formaui-components-big-menu.d.ts +0 -73
- package/types/raintonic-formaui-components-big-menu.d.ts.map +0 -1
- package/types/raintonic-formaui-components-menu.d.ts +0 -403
- package/types/raintonic-formaui-components-menu.d.ts.map +0 -1
- package/types/raintonic-formaui-components-sidebar.d.ts +0 -185
- package/types/raintonic-formaui-components-sidebar.d.ts.map +0 -1
- package/types/raintonic-formaui-components-tag.d.ts +0 -43
- package/types/raintonic-formaui-components-tag.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raintonic-formaui-components-tree.mjs","sources":["../../../lib/components/tree/tree.intl.ts","../../../lib/components/tree/fui-tree-node.component.ts","../../../lib/components/tree/fui-tree-node.component.html","../../../lib/components/tree/tree-flattener.ts","../../../lib/components/tree/fui-tree.component.ts","../../../lib/components/tree/fui-tree.component.html","../../../lib/components/tree/raintonic-formaui-components-tree.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiTreeIntl extends FuiIntlBase {\r\n collapseAriaLabel = 'Collapse';\r\n expandAriaLabel = 'Expand';\r\n}\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n ViewEncapsulation,\r\n inject,\r\n input,\r\n output,\r\n TemplateRef,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { NgTemplateOutlet } from '@angular/common';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FuiCheckboxComponent } from '@raintonic/formaui/components/checkbox';\r\nimport { FuiFlatTreeNode, FuiTreeSelectionMode } from './tree.types';\r\nimport { FuiTreeIntl } from './tree.intl';\r\n\r\n@Component({\r\n selector: 'fui-tree-node',\r\n standalone: true,\r\n imports: [NgTemplateOutlet, FuiIconComponent, FuiCheckboxComponent],\r\n templateUrl: './fui-tree-node.component.html',\r\n styleUrl: './fui-tree-node.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-tree-node',\r\n role: 'treeitem',\r\n '[attr.aria-level]': 'flatNode().level + 1',\r\n '[attr.aria-expanded]': 'flatNode().expandable ? flatNode().expanded : null',\r\n '[attr.aria-selected]': 'flatNode().selected',\r\n '[class.fui-tree-node--focused]': 'focused()',\r\n '[class.fui-tree-node--selected]': 'flatNode().selected',\r\n '[class.fui-tree-node--disabled]': 'flatNode().disabled',\r\n '[style.padding-left.px]': 'flatNode().level * indentPx',\r\n },\r\n})\r\nexport class FuiTreeNodeComponent {\r\n readonly intl = inject(FuiTreeIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n constructor() {\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });\r\n }\r\n\r\n readonly flatNode = input.required<FuiFlatTreeNode>();\r\n readonly selectionMode = input<FuiTreeSelectionMode>('none');\r\n readonly nodeTemplate = input<TemplateRef<any> | null>(null);\r\n readonly checkboxState = input<'checked' | 'unchecked' | 'indeterminate'>('unchecked');\r\n readonly focused = input(false);\r\n\r\n readonly toggle = output();\r\n readonly select = output();\r\n readonly checkboxChange = output();\r\n\r\n readonly indentPx = 24;\r\n}\r\n","<div class=\"fui-tree-node__content\">\r\n <!-- Expand/collapse toggle -->\r\n <button\r\n class=\"fui-tree-node__toggle\"\r\n [class.fui-tree-node__toggle--hidden]=\"!flatNode().expandable\"\r\n (click)=\"toggle.emit(); $event.stopPropagation()\"\r\n [attr.aria-label]=\"flatNode().expanded ? intl.collapseAriaLabel : intl.expandAriaLabel\"\r\n tabindex=\"-1\"\r\n type=\"button\"\r\n >\r\n @if (flatNode().loading) {\r\n <fui-icon name=\"spinner\" [spin]=\"true\" size=\"sm\"></fui-icon>\r\n } @else {\r\n <fui-icon [name]=\"flatNode().expanded ? 'caret-down' : 'caret-right'\" size=\"sm\"></fui-icon>\r\n }\r\n </button>\r\n\r\n <!-- Checkbox (only in checkbox mode) -->\r\n @if (selectionMode() === 'checkbox') {\r\n <fui-checkbox\r\n [checked]=\"checkboxState() === 'checked'\"\r\n [indeterminate]=\"checkboxState() === 'indeterminate'\"\r\n [disabled]=\"flatNode().disabled\"\r\n (change)=\"checkboxChange.emit()\"\r\n >\r\n </fui-checkbox>\r\n }\r\n\r\n <!-- Node content -->\r\n <div class=\"fui-tree-node__label\" (click)=\"select.emit()\" (dblclick)=\"toggle.emit()\">\r\n @if (nodeTemplate()) {\r\n <ng-container *ngTemplateOutlet=\"nodeTemplate()!; context: { $implicit: flatNode().origin, node: flatNode() }\">\r\n </ng-container>\r\n } @else {\r\n {{ flatNode().origin.data }}\r\n }\r\n </div>\r\n</div>\r\n","import { FuiFlatTreeNode, FuiTreeNode } from './tree.types';\r\n\r\nexport class FuiTreeFlattener<T = any> {\r\n flatten(nodes: FuiTreeNode<T>[], hasLoadChildren = false): FuiFlatTreeNode<T>[] {\r\n const result: FuiFlatTreeNode<T>[] = [];\r\n let flatIndex = 0;\r\n\r\n const recurse = (nodeList: FuiTreeNode<T>[], level: number, parentVisible: boolean): void => {\r\n for (const node of nodeList) {\r\n const visible = parentVisible;\r\n const hasChildren = node.children != null && node.children.length > 0;\r\n const expandable = !node.leaf && (hasChildren || (hasLoadChildren && node.children == null));\r\n\r\n result.push({\r\n origin: node,\r\n level,\r\n expandable,\r\n expanded: node.expanded ?? false,\r\n selected: node.selected ?? false,\r\n disabled: node.disabled ?? false,\r\n visible,\r\n loading: false,\r\n _flatIndex: flatIndex++,\r\n });\r\n\r\n if (node.expanded && node.children != null) {\r\n recurse(node.children, level + 1, visible);\r\n }\r\n }\r\n };\r\n\r\n recurse(nodes, 0, true);\r\n return result;\r\n }\r\n\r\n calculateCheckboxStates(nodes: FuiTreeNode<T>[]): Map<FuiTreeNode<T>, 'checked' | 'unchecked' | 'indeterminate'> {\r\n const states = new Map<FuiTreeNode<T>, 'checked' | 'unchecked' | 'indeterminate'>();\r\n\r\n const recurse = (nodeList: FuiTreeNode<T>[]): { total: number; checked: number } => {\r\n let total = 0;\r\n let checked = 0;\r\n\r\n for (const node of nodeList) {\r\n if (node.children != null && node.children.length > 0) {\r\n const childResult = recurse(node.children);\r\n total += childResult.total;\r\n checked += childResult.checked;\r\n\r\n if (childResult.checked === 0) {\r\n states.set(node, node.selected ? 'checked' : 'unchecked');\r\n } else if (childResult.checked === childResult.total) {\r\n states.set(node, 'checked');\r\n } else {\r\n states.set(node, 'indeterminate');\r\n }\r\n } else {\r\n total++;\r\n if (node.selected) checked++;\r\n states.set(node, node.selected ? 'checked' : 'unchecked');\r\n }\r\n }\r\n\r\n return { total, checked };\r\n };\r\n\r\n recurse(nodes);\r\n return states;\r\n }\r\n}\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n signal,\r\n computed,\r\n OnDestroy,\r\n TemplateRef,\r\n} from '@angular/core';\r\nimport { Observable, Subscription, take } from 'rxjs';\r\nimport { FuiTreeNodeComponent } from './fui-tree-node.component';\r\nimport { FuiVirtualScrollViewportComponent, FuiVirtualForDirective } from '@raintonic/formaui/cdk/virtual-scroll';\r\nimport { FuiTreeFlattener } from './tree-flattener';\r\nimport {\r\n FuiTreeNode,\r\n FuiFlatTreeNode,\r\n FuiTreeSelectionMode,\r\n FuiTreeNodeEvent,\r\n FuiTreeDragDropEvent,\r\n} from './tree.types';\r\n\r\n@Component({\r\n selector: 'fui-tree',\r\n standalone: true,\r\n imports: [FuiTreeNodeComponent, FuiVirtualScrollViewportComponent, FuiVirtualForDirective],\r\n templateUrl: './fui-tree.component.html',\r\n styleUrl: './fui-tree.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-tree',\r\n role: 'tree',\r\n '[attr.tabindex]': '0',\r\n '(keydown)': '_onKeydown($event)',\r\n },\r\n})\r\nexport class FuiTreeComponent<T = any> implements OnDestroy {\r\n readonly nodes = input.required<FuiTreeNode<T>[]>();\r\n readonly selectionMode = input<FuiTreeSelectionMode>('none');\r\n readonly loadChildren = input<((node: FuiTreeNode<T>) => Observable<FuiTreeNode<T>[]>) | null>(null);\r\n readonly nodeTemplate = input<TemplateRef<any> | null>(null);\r\n readonly draggable = input(false);\r\n readonly virtualScroll = input(false);\r\n readonly virtualItemSize = input(32);\r\n readonly filter = input('');\r\n\r\n readonly nodeSelect = output<FuiTreeNodeEvent<T>>();\r\n readonly nodeUnselect = output<FuiTreeNodeEvent<T>>();\r\n readonly nodeExpand = output<FuiTreeNodeEvent<T>>();\r\n readonly nodeCollapse = output<FuiTreeNodeEvent<T>>();\r\n readonly nodeDrop = output<FuiTreeDragDropEvent<T>>();\r\n readonly filterChange = output<string>();\r\n\r\n private readonly _flattener = new FuiTreeFlattener<T>();\r\n private readonly _subscriptions: Subscription[] = [];\r\n\r\n /** Refresh counter to trigger re-flatten after mutations */\r\n private readonly _refreshCounter = signal(0);\r\n\r\n readonly flatNodes = computed(() => {\r\n this._refreshCounter();\r\n const nodes = this.nodes();\r\n const filterStr = this.filter();\r\n let processedNodes = nodes;\r\n if (filterStr) {\r\n processedNodes = this._filterNodes(nodes, filterStr);\r\n }\r\n return this._flattener.flatten(processedNodes, this.loadChildren() != null);\r\n });\r\n\r\n readonly checkboxStates = computed(() => {\r\n this._refreshCounter();\r\n if (this.selectionMode() !== 'checkbox') {\r\n return new Map<FuiTreeNode<T>, 'checked' | 'unchecked' | 'indeterminate'>();\r\n }\r\n return this._flattener.calculateCheckboxStates(this.nodes());\r\n });\r\n\r\n readonly focusedIndex = signal(0);\r\n\r\n ngOnDestroy(): void {\r\n for (const sub of this._subscriptions) {\r\n sub.unsubscribe();\r\n }\r\n }\r\n\r\n // --- Public API ---\r\n\r\n expandAll(): void {\r\n this._setExpandedRecursive(this.nodes(), true);\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n collapseAll(): void {\r\n this._setExpandedRecursive(this.nodes(), false);\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n selectNode(node: FuiTreeNode<T>): void {\r\n const mode = this.selectionMode();\r\n if (mode === 'none') return;\r\n\r\n if (mode === 'single') {\r\n this._clearSelectionRecursive(this.nodes());\r\n node.selected = true;\r\n } else if (mode === 'multi' || mode === 'checkbox') {\r\n node.selected = true;\r\n }\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n getSelectedNodes(): FuiTreeNode<T>[] {\r\n const selected: FuiTreeNode<T>[] = [];\r\n this._collectSelectedRecursive(this.nodes(), selected);\r\n return selected;\r\n }\r\n\r\n // --- Event handlers ---\r\n\r\n onNodeToggle(flatNode: FuiFlatTreeNode<T>): void {\r\n const node = flatNode.origin;\r\n\r\n if (flatNode.expanded) {\r\n node.expanded = false;\r\n this.nodeCollapse.emit({ node, flatNode });\r\n } else {\r\n const loadChildrenFn = this.loadChildren();\r\n if (loadChildrenFn && node.children == null) {\r\n // Lazy load children\r\n this._refreshCounter.update((c) => c + 1);\r\n\r\n const sub = loadChildrenFn(node)\r\n .pipe(take(1))\r\n .subscribe({\r\n next: (children) => {\r\n node.children = children;\r\n node.expanded = true;\r\n this._refreshCounter.update((c) => c + 1);\r\n this.nodeExpand.emit({ node, flatNode });\r\n },\r\n error: () => {\r\n this._refreshCounter.update((c) => c + 1);\r\n },\r\n });\r\n this._subscriptions.push(sub);\r\n return;\r\n } else {\r\n node.expanded = true;\r\n this.nodeExpand.emit({ node, flatNode });\r\n }\r\n }\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n onNodeSelect(flatNode: FuiFlatTreeNode<T>): void {\r\n const node = flatNode.origin;\r\n const mode = this.selectionMode();\r\n\r\n if (mode === 'none' || flatNode.disabled) return;\r\n\r\n if (mode === 'single') {\r\n const wasSelected = node.selected;\r\n this._clearSelectionRecursive(this.nodes());\r\n if (!wasSelected) {\r\n node.selected = true;\r\n this.nodeSelect.emit({ node, flatNode });\r\n } else {\r\n this.nodeUnselect.emit({ node, flatNode });\r\n }\r\n } else if (mode === 'multi') {\r\n node.selected = !node.selected;\r\n if (node.selected) {\r\n this.nodeSelect.emit({ node, flatNode });\r\n } else {\r\n this.nodeUnselect.emit({ node, flatNode });\r\n }\r\n }\r\n\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n onCheckboxChange(flatNode: FuiFlatTreeNode<T>): void {\r\n const node = flatNode.origin;\r\n if (flatNode.disabled) return;\r\n\r\n node.selected = !node.selected;\r\n\r\n // Propagate to children\r\n if (node.children != null) {\r\n this._setSelectedRecursive(node.children, node.selected);\r\n }\r\n\r\n if (node.selected) {\r\n this.nodeSelect.emit({ node, flatNode });\r\n } else {\r\n this.nodeUnselect.emit({ node, flatNode });\r\n }\r\n\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n // --- Keyboard navigation ---\r\n\r\n _onKeydown(event: KeyboardEvent): void {\r\n const visibleNodes = this.flatNodes().filter((n) => n.visible);\r\n if (visibleNodes.length === 0) return;\r\n\r\n const currentIndex = this.focusedIndex();\r\n const currentNode = visibleNodes.find((n) => n._flatIndex === currentIndex);\r\n\r\n switch (event.key) {\r\n case 'ArrowDown': {\r\n event.preventDefault();\r\n const currentVisIdx = visibleNodes.findIndex((n) => n._flatIndex === currentIndex);\r\n if (currentVisIdx < visibleNodes.length - 1) {\r\n this.focusedIndex.set(visibleNodes[currentVisIdx + 1]._flatIndex);\r\n }\r\n break;\r\n }\r\n\r\n case 'ArrowUp': {\r\n event.preventDefault();\r\n const currentVisIdx = visibleNodes.findIndex((n) => n._flatIndex === currentIndex);\r\n if (currentVisIdx > 0) {\r\n this.focusedIndex.set(visibleNodes[currentVisIdx - 1]._flatIndex);\r\n }\r\n break;\r\n }\r\n\r\n case 'ArrowRight': {\r\n event.preventDefault();\r\n if (currentNode?.expandable) {\r\n if (!currentNode.expanded) {\r\n this.onNodeToggle(currentNode);\r\n } else {\r\n // Move to first child\r\n const currentVisIdx = visibleNodes.findIndex((n) => n._flatIndex === currentIndex);\r\n if (currentVisIdx < visibleNodes.length - 1) {\r\n this.focusedIndex.set(visibleNodes[currentVisIdx + 1]._flatIndex);\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'ArrowLeft': {\r\n event.preventDefault();\r\n if (currentNode && currentNode.expanded && currentNode.expandable) {\r\n this.onNodeToggle(currentNode);\r\n } else if (currentNode && currentNode.level > 0) {\r\n // Move to parent - search backwards for closest node at parent level\r\n for (let i = visibleNodes.length - 1; i >= 0; i--) {\r\n if (visibleNodes[i]._flatIndex < currentIndex && visibleNodes[i].level === currentNode.level - 1) {\r\n this.focusedIndex.set(visibleNodes[i]._flatIndex);\r\n break;\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'Home': {\r\n event.preventDefault();\r\n if (visibleNodes.length > 0) {\r\n this.focusedIndex.set(visibleNodes[0]._flatIndex);\r\n }\r\n break;\r\n }\r\n\r\n case 'End': {\r\n event.preventDefault();\r\n if (visibleNodes.length > 0) {\r\n this.focusedIndex.set(visibleNodes[visibleNodes.length - 1]._flatIndex);\r\n }\r\n break;\r\n }\r\n\r\n case 'Enter':\r\n case ' ': {\r\n event.preventDefault();\r\n if (currentNode) {\r\n if (this.selectionMode() === 'checkbox') {\r\n this.onCheckboxChange(currentNode);\r\n } else {\r\n this.onNodeSelect(currentNode);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case '*': {\r\n event.preventDefault();\r\n // Expand all siblings at the same level\r\n if (currentNode) {\r\n for (const node of visibleNodes) {\r\n if (node.level === currentNode.level && node.expandable && !node.expanded) {\r\n node.origin.expanded = true;\r\n }\r\n }\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // --- Private helpers ---\r\n\r\n private _filterNodes(nodes: FuiTreeNode<T>[], filterStr: string): FuiTreeNode<T>[] {\r\n const lowerFilter = filterStr.toLowerCase();\r\n const result: FuiTreeNode<T>[] = [];\r\n\r\n for (const node of nodes) {\r\n const matches = this._nodeMatchesFilter(node, lowerFilter);\r\n const filteredChildren = node.children != null ? this._filterNodes(node.children, filterStr) : [];\r\n\r\n if (matches || filteredChildren.length > 0) {\r\n const cloned: FuiTreeNode<T> = {\r\n ...node,\r\n children: filteredChildren.length > 0 ? filteredChildren : node.children,\r\n expanded: filteredChildren.length > 0 ? true : node.expanded,\r\n };\r\n result.push(cloned);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private _nodeMatchesFilter(node: FuiTreeNode<T>, lowerFilter: string): boolean {\r\n const data = node.data as any;\r\n if (typeof data === 'string') {\r\n return data.toLowerCase().includes(lowerFilter);\r\n }\r\n if (data != null && typeof data === 'object') {\r\n if ('name' in data && typeof data.name === 'string') {\r\n return data.name.toLowerCase().includes(lowerFilter);\r\n }\r\n if ('label' in data && typeof data.label === 'string') {\r\n return data.label.toLowerCase().includes(lowerFilter);\r\n }\r\n }\r\n return String(data).toLowerCase().includes(lowerFilter);\r\n }\r\n\r\n private _setExpandedRecursive(nodes: FuiTreeNode<T>[], expanded: boolean): void {\r\n for (const node of nodes) {\r\n node.expanded = expanded;\r\n if (node.children != null) {\r\n this._setExpandedRecursive(node.children, expanded);\r\n }\r\n }\r\n }\r\n\r\n private _clearSelectionRecursive(nodes: FuiTreeNode<T>[]): void {\r\n for (const node of nodes) {\r\n node.selected = false;\r\n if (node.children != null) {\r\n this._clearSelectionRecursive(node.children);\r\n }\r\n }\r\n }\r\n\r\n private _setSelectedRecursive(nodes: FuiTreeNode<T>[], selected: boolean): void {\r\n for (const node of nodes) {\r\n node.selected = selected;\r\n if (node.children != null) {\r\n this._setSelectedRecursive(node.children, selected);\r\n }\r\n }\r\n }\r\n\r\n private _collectSelectedRecursive(nodes: FuiTreeNode<T>[], result: FuiTreeNode<T>[]): void {\r\n for (const node of nodes) {\r\n if (node.selected) {\r\n result.push(node);\r\n }\r\n if (node.children != null) {\r\n this._collectSelectedRecursive(node.children, result);\r\n }\r\n }\r\n }\r\n}\r\n","@if (!virtualScroll()) {\r\n @for (flatNode of flatNodes(); track flatNode._flatIndex) {\r\n <fui-tree-node\r\n [flatNode]=\"flatNode\"\r\n [selectionMode]=\"selectionMode()\"\r\n [nodeTemplate]=\"nodeTemplate()\"\r\n [checkboxState]=\"checkboxStates().get(flatNode.origin) ?? 'unchecked'\"\r\n [focused]=\"focusedIndex() === flatNode._flatIndex\"\r\n (toggle)=\"onNodeToggle(flatNode)\"\r\n (select)=\"onNodeSelect(flatNode)\"\r\n (checkboxChange)=\"onCheckboxChange(flatNode)\"\r\n >\r\n </fui-tree-node>\r\n }\r\n}\r\n\r\n@if (virtualScroll()) {\r\n <fui-virtual-scroll-viewport [itemSize]=\"virtualItemSize()\" style=\"height: 100%\">\r\n <fui-tree-node\r\n *fuiVirtualFor=\"let flatNode of flatNodes()\"\r\n [flatNode]=\"flatNode\"\r\n [selectionMode]=\"selectionMode()\"\r\n [nodeTemplate]=\"nodeTemplate()\"\r\n [checkboxState]=\"checkboxStates().get(flatNode.origin) ?? 'unchecked'\"\r\n [focused]=\"focusedIndex() === flatNode._flatIndex\"\r\n (toggle)=\"onNodeToggle(flatNode)\"\r\n (select)=\"onNodeSelect(flatNode)\"\r\n (checkboxChange)=\"onCheckboxChange(flatNode)\"\r\n >\r\n </fui-tree-node>\r\n </fui-virtual-scroll-viewport>\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-tree.mjs","sources":["../../../lib/components/tree/tree.intl.ts","../../../lib/components/tree/fui-tree-node.component.ts","../../../lib/components/tree/fui-tree-node.component.html","../../../lib/components/tree/tree-flattener.ts","../../../lib/components/tree/fui-tree.component.ts","../../../lib/components/tree/fui-tree.component.html","../../../lib/components/tree/raintonic-formaui-components-tree.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiTreeIntl extends FuiIntlBase {\r\n collapseAriaLabel = 'Collapse';\r\n expandAriaLabel = 'Expand';\r\n}\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n ViewEncapsulation,\r\n inject,\r\n input,\r\n output,\r\n TemplateRef,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { NgTemplateOutlet } from '@angular/common';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FuiCheckboxComponent } from '@raintonic/formaui/components/checkbox';\r\nimport { FuiFlatTreeNode, FuiTreeSelectionMode } from './tree.types';\r\nimport { FuiTreeIntl } from './tree.intl';\r\n\r\n@Component({\r\n selector: 'fui-tree-node',\r\n standalone: true,\r\n imports: [NgTemplateOutlet, FuiIconComponent, FuiCheckboxComponent],\r\n templateUrl: './fui-tree-node.component.html',\r\n styleUrl: './fui-tree-node.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-tree-node',\r\n role: 'treeitem',\r\n '[attr.aria-level]': 'flatNode().level + 1',\r\n '[attr.aria-expanded]': 'flatNode().expandable ? flatNode().expanded : null',\r\n '[attr.aria-selected]': 'flatNode().selected',\r\n '[class.fui-tree-node--focused]': 'focused()',\r\n '[class.fui-tree-node--selected]': 'flatNode().selected',\r\n '[class.fui-tree-node--disabled]': 'flatNode().disabled',\r\n '[style.padding-left.px]': 'flatNode().level * indentPx',\r\n },\r\n})\r\nexport class FuiTreeNodeComponent {\r\n readonly intl = inject(FuiTreeIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n constructor() {\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });\r\n }\r\n\r\n readonly flatNode = input.required<FuiFlatTreeNode>();\r\n readonly selectionMode = input<FuiTreeSelectionMode>('none');\r\n readonly nodeTemplate = input<TemplateRef<any> | null>(null);\r\n readonly checkboxState = input<'checked' | 'unchecked' | 'indeterminate'>('unchecked');\r\n readonly focused = input(false);\r\n\r\n readonly toggle = output();\r\n readonly select = output();\r\n readonly checkboxChange = output();\r\n\r\n readonly indentPx = 24;\r\n}\r\n","<div class=\"fui-tree-node__content\">\r\n <!-- Expand/collapse toggle -->\r\n <button\r\n class=\"fui-tree-node__toggle\"\r\n [class.fui-tree-node__toggle--hidden]=\"!flatNode().expandable\"\r\n (click)=\"toggle.emit(); $event.stopPropagation()\"\r\n [attr.aria-label]=\"flatNode().expanded ? intl.collapseAriaLabel : intl.expandAriaLabel\"\r\n tabindex=\"-1\"\r\n type=\"button\"\r\n >\r\n @if (flatNode().loading) {\r\n <fui-icon name=\"spinner\" [spin]=\"true\" size=\"sm\"></fui-icon>\r\n } @else {\r\n <fui-icon [name]=\"flatNode().expanded ? 'caret-down' : 'caret-right'\" size=\"sm\"></fui-icon>\r\n }\r\n </button>\r\n\r\n <!-- Checkbox (only in checkbox mode) -->\r\n @if (selectionMode() === 'checkbox') {\r\n <fui-checkbox\r\n [checked]=\"checkboxState() === 'checked'\"\r\n [indeterminate]=\"checkboxState() === 'indeterminate'\"\r\n [disabled]=\"flatNode().disabled\"\r\n (change)=\"checkboxChange.emit()\"\r\n >\r\n </fui-checkbox>\r\n }\r\n\r\n <!-- Node content -->\r\n <div class=\"fui-tree-node__label\" (click)=\"select.emit()\" (dblclick)=\"toggle.emit()\">\r\n @if (nodeTemplate()) {\r\n <ng-container *ngTemplateOutlet=\"nodeTemplate()!; context: { $implicit: flatNode().origin, node: flatNode() }\">\r\n </ng-container>\r\n } @else {\r\n {{ flatNode().origin.data }}\r\n }\r\n </div>\r\n</div>\r\n","import { FuiFlatTreeNode, FuiTreeNode } from './tree.types';\r\n\r\nexport class FuiTreeFlattener<T = any> {\r\n flatten(nodes: FuiTreeNode<T>[], hasLoadChildren = false): FuiFlatTreeNode<T>[] {\r\n const result: FuiFlatTreeNode<T>[] = [];\r\n let flatIndex = 0;\r\n\r\n const recurse = (nodeList: FuiTreeNode<T>[], level: number, parentVisible: boolean): void => {\r\n for (const node of nodeList) {\r\n const visible = parentVisible;\r\n const hasChildren = node.children != null && node.children.length > 0;\r\n const expandable = !node.leaf && (hasChildren || (hasLoadChildren && node.children == null));\r\n\r\n result.push({\r\n origin: node,\r\n level,\r\n expandable,\r\n expanded: node.expanded ?? false,\r\n selected: node.selected ?? false,\r\n disabled: node.disabled ?? false,\r\n visible,\r\n loading: false,\r\n _flatIndex: flatIndex++,\r\n });\r\n\r\n if (node.expanded && node.children != null) {\r\n recurse(node.children, level + 1, visible);\r\n }\r\n }\r\n };\r\n\r\n recurse(nodes, 0, true);\r\n return result;\r\n }\r\n\r\n calculateCheckboxStates(nodes: FuiTreeNode<T>[]): Map<FuiTreeNode<T>, 'checked' | 'unchecked' | 'indeterminate'> {\r\n const states = new Map<FuiTreeNode<T>, 'checked' | 'unchecked' | 'indeterminate'>();\r\n\r\n const recurse = (nodeList: FuiTreeNode<T>[]): { total: number; checked: number } => {\r\n let total = 0;\r\n let checked = 0;\r\n\r\n for (const node of nodeList) {\r\n if (node.children != null && node.children.length > 0) {\r\n const childResult = recurse(node.children);\r\n total += childResult.total;\r\n checked += childResult.checked;\r\n\r\n if (childResult.checked === 0) {\r\n states.set(node, node.selected ? 'checked' : 'unchecked');\r\n } else if (childResult.checked === childResult.total) {\r\n states.set(node, 'checked');\r\n } else {\r\n states.set(node, 'indeterminate');\r\n }\r\n } else {\r\n total++;\r\n if (node.selected) checked++;\r\n states.set(node, node.selected ? 'checked' : 'unchecked');\r\n }\r\n }\r\n\r\n return { total, checked };\r\n };\r\n\r\n recurse(nodes);\r\n return states;\r\n }\r\n}\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n signal,\r\n computed,\r\n OnDestroy,\r\n TemplateRef,\r\n} from '@angular/core';\r\nimport { Observable, Subscription, take } from 'rxjs';\r\nimport { FuiTreeNodeComponent } from './fui-tree-node.component';\r\nimport { FuiVirtualScrollViewportComponent, FuiVirtualForDirective } from '@raintonic/formaui/cdk/virtual-scroll';\r\nimport { FuiTreeFlattener } from './tree-flattener';\r\nimport {\r\n FuiTreeNode,\r\n FuiFlatTreeNode,\r\n FuiTreeSelectionMode,\r\n FuiTreeNodeEvent,\r\n FuiTreeDragDropEvent,\r\n} from './tree.types';\r\n\r\n@Component({\r\n selector: 'fui-tree',\r\n standalone: true,\r\n imports: [FuiTreeNodeComponent, FuiVirtualScrollViewportComponent, FuiVirtualForDirective],\r\n templateUrl: './fui-tree.component.html',\r\n styleUrl: './fui-tree.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-tree',\r\n role: 'tree',\r\n '[attr.tabindex]': '0',\r\n '(keydown)': '_onKeydown($event)',\r\n },\r\n})\r\nexport class FuiTreeComponent<T = any> implements OnDestroy {\r\n readonly nodes = input.required<FuiTreeNode<T>[]>();\r\n readonly selectionMode = input<FuiTreeSelectionMode>('none');\r\n readonly loadChildren = input<((node: FuiTreeNode<T>) => Observable<FuiTreeNode<T>[]>) | null>(null);\r\n readonly nodeTemplate = input<TemplateRef<any> | null>(null);\r\n readonly draggable = input(false);\r\n readonly virtualScroll = input(false);\r\n readonly virtualItemSize = input(32);\r\n readonly filter = input('');\r\n /**\r\n * Optional prefix used to build stable DOM ids for each rendered tree-node element.\r\n * When provided, each node element receives `id=\"${nodeIdPrefix}-${flatIndex}\"`.\r\n * Used by parent combobox components (e.g. tree-select) to resolve `aria-activedescendant`.\r\n */\r\n readonly nodeIdPrefix = input<string | null>(null);\r\n\r\n readonly nodeSelect = output<FuiTreeNodeEvent<T>>();\r\n readonly nodeUnselect = output<FuiTreeNodeEvent<T>>();\r\n readonly nodeExpand = output<FuiTreeNodeEvent<T>>();\r\n readonly nodeCollapse = output<FuiTreeNodeEvent<T>>();\r\n readonly nodeDrop = output<FuiTreeDragDropEvent<T>>();\r\n readonly filterChange = output<string>();\r\n /** Emits the DOM id of the tree-node element that gains keyboard focus. Used by parent\r\n * combobox components to update `aria-activedescendant`. */\r\n readonly focusChange = output<string | null>();\r\n\r\n private readonly _flattener = new FuiTreeFlattener<T>();\r\n private readonly _subscriptions: Subscription[] = [];\r\n\r\n /** Refresh counter to trigger re-flatten after mutations */\r\n private readonly _refreshCounter = signal(0);\r\n\r\n readonly flatNodes = computed(() => {\r\n this._refreshCounter();\r\n const nodes = this.nodes();\r\n const filterStr = this.filter();\r\n let processedNodes = nodes;\r\n if (filterStr) {\r\n processedNodes = this._filterNodes(nodes, filterStr);\r\n }\r\n return this._flattener.flatten(processedNodes, this.loadChildren() != null);\r\n });\r\n\r\n readonly checkboxStates = computed(() => {\r\n this._refreshCounter();\r\n if (this.selectionMode() !== 'checkbox') {\r\n return new Map<FuiTreeNode<T>, 'checked' | 'unchecked' | 'indeterminate'>();\r\n }\r\n return this._flattener.calculateCheckboxStates(this.nodes());\r\n });\r\n\r\n readonly focusedIndex = signal(0);\r\n\r\n /** Builds the DOM element id for a flat-node at the given index. Returns null when no prefix is set. */\r\n nodeElementId(flatIndex: number): string | null {\r\n const prefix = this.nodeIdPrefix();\r\n return prefix != null ? `${prefix}-node-${String(flatIndex)}` : null;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n for (const sub of this._subscriptions) {\r\n sub.unsubscribe();\r\n }\r\n }\r\n\r\n // --- Public API ---\r\n\r\n expandAll(): void {\r\n this._setExpandedRecursive(this.nodes(), true);\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n collapseAll(): void {\r\n this._setExpandedRecursive(this.nodes(), false);\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n selectNode(node: FuiTreeNode<T>): void {\r\n const mode = this.selectionMode();\r\n if (mode === 'none') return;\r\n\r\n if (mode === 'single') {\r\n this._clearSelectionRecursive(this.nodes());\r\n node.selected = true;\r\n } else if (mode === 'multi' || mode === 'checkbox') {\r\n node.selected = true;\r\n }\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n getSelectedNodes(): FuiTreeNode<T>[] {\r\n const selected: FuiTreeNode<T>[] = [];\r\n this._collectSelectedRecursive(this.nodes(), selected);\r\n return selected;\r\n }\r\n\r\n // --- Event handlers ---\r\n\r\n onNodeToggle(flatNode: FuiFlatTreeNode<T>): void {\r\n const node = flatNode.origin;\r\n\r\n if (flatNode.expanded) {\r\n node.expanded = false;\r\n this.nodeCollapse.emit({ node, flatNode });\r\n } else {\r\n const loadChildrenFn = this.loadChildren();\r\n if (loadChildrenFn && node.children == null) {\r\n // Lazy load children\r\n this._refreshCounter.update((c) => c + 1);\r\n\r\n const sub = loadChildrenFn(node)\r\n .pipe(take(1))\r\n .subscribe({\r\n next: (children) => {\r\n node.children = children;\r\n node.expanded = true;\r\n this._refreshCounter.update((c) => c + 1);\r\n this.nodeExpand.emit({ node, flatNode });\r\n },\r\n error: () => {\r\n this._refreshCounter.update((c) => c + 1);\r\n },\r\n });\r\n this._subscriptions.push(sub);\r\n return;\r\n } else {\r\n node.expanded = true;\r\n this.nodeExpand.emit({ node, flatNode });\r\n }\r\n }\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n onNodeSelect(flatNode: FuiFlatTreeNode<T>): void {\r\n const node = flatNode.origin;\r\n const mode = this.selectionMode();\r\n\r\n if (mode === 'none' || flatNode.disabled) return;\r\n\r\n if (mode === 'single') {\r\n const wasSelected = node.selected;\r\n this._clearSelectionRecursive(this.nodes());\r\n if (!wasSelected) {\r\n node.selected = true;\r\n this.nodeSelect.emit({ node, flatNode });\r\n } else {\r\n this.nodeUnselect.emit({ node, flatNode });\r\n }\r\n } else if (mode === 'multi') {\r\n node.selected = !node.selected;\r\n if (node.selected) {\r\n this.nodeSelect.emit({ node, flatNode });\r\n } else {\r\n this.nodeUnselect.emit({ node, flatNode });\r\n }\r\n }\r\n\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n onCheckboxChange(flatNode: FuiFlatTreeNode<T>): void {\r\n const node = flatNode.origin;\r\n if (flatNode.disabled) return;\r\n\r\n node.selected = !node.selected;\r\n\r\n // Propagate to children\r\n if (node.children != null) {\r\n this._setSelectedRecursive(node.children, node.selected);\r\n }\r\n\r\n if (node.selected) {\r\n this.nodeSelect.emit({ node, flatNode });\r\n } else {\r\n this.nodeUnselect.emit({ node, flatNode });\r\n }\r\n\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n\r\n // --- Keyboard navigation ---\r\n\r\n _onKeydown(event: KeyboardEvent): void {\r\n const visibleNodes = this.flatNodes().filter((n) => n.visible);\r\n if (visibleNodes.length === 0) return;\r\n\r\n const currentIndex = this.focusedIndex();\r\n const currentNode = visibleNodes.find((n) => n._flatIndex === currentIndex);\r\n const prevFocusedIndex = currentIndex;\r\n const prevRefreshCounter = this._refreshCounter();\r\n\r\n switch (event.key) {\r\n case 'ArrowDown': {\r\n event.preventDefault();\r\n const currentVisIdx = visibleNodes.findIndex((n) => n._flatIndex === currentIndex);\r\n if (currentVisIdx < visibleNodes.length - 1) {\r\n this.focusedIndex.set(visibleNodes[currentVisIdx + 1]._flatIndex);\r\n }\r\n break;\r\n }\r\n\r\n case 'ArrowUp': {\r\n event.preventDefault();\r\n const currentVisIdx = visibleNodes.findIndex((n) => n._flatIndex === currentIndex);\r\n if (currentVisIdx > 0) {\r\n this.focusedIndex.set(visibleNodes[currentVisIdx - 1]._flatIndex);\r\n }\r\n break;\r\n }\r\n\r\n case 'ArrowRight': {\r\n event.preventDefault();\r\n if (currentNode?.expandable) {\r\n if (!currentNode.expanded) {\r\n this.onNodeToggle(currentNode);\r\n } else {\r\n // Move to first child\r\n const currentVisIdx = visibleNodes.findIndex((n) => n._flatIndex === currentIndex);\r\n if (currentVisIdx < visibleNodes.length - 1) {\r\n this.focusedIndex.set(visibleNodes[currentVisIdx + 1]._flatIndex);\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'ArrowLeft': {\r\n event.preventDefault();\r\n if (currentNode && currentNode.expanded && currentNode.expandable) {\r\n this.onNodeToggle(currentNode);\r\n } else if (currentNode && currentNode.level > 0) {\r\n // Move to parent - search backwards for closest node at parent level\r\n for (let i = visibleNodes.length - 1; i >= 0; i--) {\r\n if (visibleNodes[i]._flatIndex < currentIndex && visibleNodes[i].level === currentNode.level - 1) {\r\n this.focusedIndex.set(visibleNodes[i]._flatIndex);\r\n break;\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'Home': {\r\n event.preventDefault();\r\n if (visibleNodes.length > 0) {\r\n this.focusedIndex.set(visibleNodes[0]._flatIndex);\r\n }\r\n break;\r\n }\r\n\r\n case 'End': {\r\n event.preventDefault();\r\n if (visibleNodes.length > 0) {\r\n this.focusedIndex.set(visibleNodes[visibleNodes.length - 1]._flatIndex);\r\n }\r\n break;\r\n }\r\n\r\n case 'Enter':\r\n case ' ': {\r\n event.preventDefault();\r\n if (currentNode) {\r\n if (this.selectionMode() === 'checkbox') {\r\n this.onCheckboxChange(currentNode);\r\n } else {\r\n this.onNodeSelect(currentNode);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case '*': {\r\n event.preventDefault();\r\n // Expand all siblings at the same level\r\n if (currentNode) {\r\n for (const node of visibleNodes) {\r\n if (node.level === currentNode.level && node.expandable && !node.expanded) {\r\n node.origin.expanded = true;\r\n }\r\n }\r\n this._refreshCounter.update((c) => c + 1);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // Emit focusChange when either the focused index changed OR a structural refresh\r\n // happened (expand/collapse). The latter is required because flatIndex values shift\r\n // after a refresh, which changes the DOM ids of nodes — so any cached\r\n // aria-activedescendant id in a parent component must be re-synced even if the\r\n // logically-focused node is unchanged.\r\n const newFocusedIndex = this.focusedIndex();\r\n const didRefresh = this._refreshCounter() !== prevRefreshCounter;\r\n if (newFocusedIndex !== prevFocusedIndex || didRefresh) {\r\n this.focusChange.emit(this.nodeElementId(newFocusedIndex));\r\n }\r\n }\r\n\r\n // --- Private helpers ---\r\n\r\n private _filterNodes(nodes: FuiTreeNode<T>[], filterStr: string): FuiTreeNode<T>[] {\r\n const lowerFilter = filterStr.toLowerCase();\r\n const result: FuiTreeNode<T>[] = [];\r\n\r\n for (const node of nodes) {\r\n const matches = this._nodeMatchesFilter(node, lowerFilter);\r\n const filteredChildren = node.children != null ? this._filterNodes(node.children, filterStr) : [];\r\n\r\n if (matches || filteredChildren.length > 0) {\r\n const cloned: FuiTreeNode<T> = {\r\n ...node,\r\n children: filteredChildren.length > 0 ? filteredChildren : node.children,\r\n expanded: filteredChildren.length > 0 ? true : node.expanded,\r\n };\r\n result.push(cloned);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private _nodeMatchesFilter(node: FuiTreeNode<T>, lowerFilter: string): boolean {\r\n const data = node.data as any;\r\n if (typeof data === 'string') {\r\n return data.toLowerCase().includes(lowerFilter);\r\n }\r\n if (data != null && typeof data === 'object') {\r\n if ('name' in data && typeof data.name === 'string') {\r\n return data.name.toLowerCase().includes(lowerFilter);\r\n }\r\n if ('label' in data && typeof data.label === 'string') {\r\n return data.label.toLowerCase().includes(lowerFilter);\r\n }\r\n }\r\n return String(data).toLowerCase().includes(lowerFilter);\r\n }\r\n\r\n private _setExpandedRecursive(nodes: FuiTreeNode<T>[], expanded: boolean): void {\r\n for (const node of nodes) {\r\n node.expanded = expanded;\r\n if (node.children != null) {\r\n this._setExpandedRecursive(node.children, expanded);\r\n }\r\n }\r\n }\r\n\r\n private _clearSelectionRecursive(nodes: FuiTreeNode<T>[]): void {\r\n for (const node of nodes) {\r\n node.selected = false;\r\n if (node.children != null) {\r\n this._clearSelectionRecursive(node.children);\r\n }\r\n }\r\n }\r\n\r\n private _setSelectedRecursive(nodes: FuiTreeNode<T>[], selected: boolean): void {\r\n for (const node of nodes) {\r\n node.selected = selected;\r\n if (node.children != null) {\r\n this._setSelectedRecursive(node.children, selected);\r\n }\r\n }\r\n }\r\n\r\n private _collectSelectedRecursive(nodes: FuiTreeNode<T>[], result: FuiTreeNode<T>[]): void {\r\n for (const node of nodes) {\r\n if (node.selected) {\r\n result.push(node);\r\n }\r\n if (node.children != null) {\r\n this._collectSelectedRecursive(node.children, result);\r\n }\r\n }\r\n }\r\n}\r\n","@if (!virtualScroll()) {\r\n @for (flatNode of flatNodes(); track flatNode._flatIndex) {\r\n <fui-tree-node\r\n [attr.id]=\"nodeElementId(flatNode._flatIndex)\"\r\n [flatNode]=\"flatNode\"\r\n [selectionMode]=\"selectionMode()\"\r\n [nodeTemplate]=\"nodeTemplate()\"\r\n [checkboxState]=\"checkboxStates().get(flatNode.origin) ?? 'unchecked'\"\r\n [focused]=\"focusedIndex() === flatNode._flatIndex\"\r\n (toggle)=\"onNodeToggle(flatNode)\"\r\n (select)=\"onNodeSelect(flatNode)\"\r\n (checkboxChange)=\"onCheckboxChange(flatNode)\"\r\n >\r\n </fui-tree-node>\r\n }\r\n}\r\n\r\n@if (virtualScroll()) {\r\n <fui-virtual-scroll-viewport [itemSize]=\"virtualItemSize()\" style=\"height: 100%\">\r\n <fui-tree-node\r\n *fuiVirtualFor=\"let flatNode of flatNodes()\"\r\n [attr.id]=\"nodeElementId(flatNode._flatIndex)\"\r\n [flatNode]=\"flatNode\"\r\n [selectionMode]=\"selectionMode()\"\r\n [nodeTemplate]=\"nodeTemplate()\"\r\n [checkboxState]=\"checkboxStates().get(flatNode.origin) ?? 'unchecked'\"\r\n [focused]=\"focusedIndex() === flatNode._flatIndex\"\r\n (toggle)=\"onNodeToggle(flatNode)\"\r\n (select)=\"onNodeSelect(flatNode)\"\r\n (checkboxChange)=\"onCheckboxChange(flatNode)\"\r\n >\r\n </fui-tree-node>\r\n </fui-virtual-scroll-viewport>\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -78,9 +78,287 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
78
78
|
type: Injectable
|
|
79
79
|
}] });
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Injection token used to look up a strength meter component projected
|
|
83
|
+
* inside a form field without creating a hard secondary-entry-point
|
|
84
|
+
* dependency.
|
|
85
|
+
*/
|
|
86
|
+
const FUI_STRENGTH_METER = new InjectionToken('FuiStrengthMeter');
|
|
87
|
+
|
|
88
|
+
/* keep for lint rules errors. must use any[] */
|
|
89
|
+
const noop = (..._args) => {
|
|
90
|
+
/* noop */
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Number of options to skip when handling PageUp/PageDown in both select and autocomplete.
|
|
95
|
+
* Effective page size is `Math.min(KEYBOARD_PAGE_SIZE, optionCount)`.
|
|
96
|
+
*/
|
|
97
|
+
const KEYBOARD_PAGE_SIZE = 10;
|
|
98
|
+
/**
|
|
99
|
+
* Computes the display string shown in the trigger.
|
|
100
|
+
*
|
|
101
|
+
* - Single mode: returns the label of the matching option (or stringified value).
|
|
102
|
+
* - Multiple mode: joins selected option labels with `', '`.
|
|
103
|
+
* - Null/undefined/empty-array: returns `''`.
|
|
104
|
+
* - If no option matches the value, returns `String(value)` (single) or `''` (multiple).
|
|
105
|
+
*/
|
|
106
|
+
function computeMultiDisplayValue(host) {
|
|
107
|
+
const val = host.value();
|
|
108
|
+
const opts = host.options();
|
|
109
|
+
const compareFn = host.compareWith();
|
|
110
|
+
if (val === null || val === undefined) {
|
|
111
|
+
return '';
|
|
112
|
+
}
|
|
113
|
+
// Filter out options that don't have a value set yet
|
|
114
|
+
const validOpts = opts.filter((o) => o.value() !== undefined);
|
|
115
|
+
if (host.multiple()) {
|
|
116
|
+
if (!Array.isArray(val)) {
|
|
117
|
+
return '';
|
|
118
|
+
}
|
|
119
|
+
const selectedOptions = validOpts.filter((o) => val.some((v) => compareFn(v, o.value())));
|
|
120
|
+
return selectedOptions.map((o) => o.getLabel()).join(', ');
|
|
121
|
+
}
|
|
122
|
+
const selectedOption = validOpts.find((o) => compareFn(o.value(), val));
|
|
123
|
+
return selectedOption ? selectedOption.getLabel() : String(val);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Iterates all options and calls `select()` / `deselect()` based on whether
|
|
127
|
+
* the option's value matches the current model value (by identity).
|
|
128
|
+
*
|
|
129
|
+
* - Single mode: compares the scalar value directly.
|
|
130
|
+
* - Multiple mode: checks each array element.
|
|
131
|
+
* - Options with `undefined` value are skipped.
|
|
132
|
+
*/
|
|
133
|
+
function syncMultiOptions(host) {
|
|
134
|
+
const currentValue = host.value();
|
|
135
|
+
const opts = host.options();
|
|
136
|
+
const isMultiple = host.multiple();
|
|
137
|
+
const compareFn = host.compareWith();
|
|
138
|
+
opts.forEach((option) => {
|
|
139
|
+
const optValue = option.value();
|
|
140
|
+
// Skip options that don't have a value set yet
|
|
141
|
+
if (optValue === undefined) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
let isSelected = false;
|
|
145
|
+
if (isMultiple && Array.isArray(currentValue)) {
|
|
146
|
+
isSelected = currentValue.some((v) => compareFn(v, optValue));
|
|
147
|
+
}
|
|
148
|
+
else if (currentValue !== null && currentValue !== undefined) {
|
|
149
|
+
isSelected = compareFn(currentValue, optValue);
|
|
150
|
+
}
|
|
151
|
+
if (isSelected) {
|
|
152
|
+
option.select();
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
option.deselect();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Toggles an option value in/out of an array-based multi-value.
|
|
161
|
+
*
|
|
162
|
+
* - If the value is already present, it is removed (deselect).
|
|
163
|
+
* - If absent, it is appended (select).
|
|
164
|
+
* - If `current` is not an array, starts fresh with `[]`.
|
|
165
|
+
*
|
|
166
|
+
* Returns a **new array** (shallow copy) so callers can set it as the new model value.
|
|
167
|
+
*/
|
|
168
|
+
function toggleMultiValue(current, optionValue, compareFn) {
|
|
169
|
+
const arr = Array.isArray(current) ? [...current] : [];
|
|
170
|
+
const idx = arr.findIndex((v) => compareFn(v, optionValue));
|
|
171
|
+
if (idx > -1) {
|
|
172
|
+
arr.splice(idx, 1);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
arr.push(optionValue);
|
|
176
|
+
}
|
|
177
|
+
return arr;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Checks whether a value represents the "empty" state.
|
|
181
|
+
*
|
|
182
|
+
* - `null` or `undefined` → empty
|
|
183
|
+
* - Empty array `[]` → empty (so multiple-mode starts with no selection)
|
|
184
|
+
* - Everything else → not empty
|
|
185
|
+
*/
|
|
186
|
+
function isEmpty(value) {
|
|
187
|
+
if (value === null || value === undefined) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
if (Array.isArray(value)) {
|
|
191
|
+
return value.length === 0;
|
|
192
|
+
}
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Finds the index of the first enabled option whose value matches the current
|
|
197
|
+
* model value. Used to set the initial keyboard-navigation active option when
|
|
198
|
+
* opening the panel.
|
|
199
|
+
*
|
|
200
|
+
* - Single mode: finds the option whose value equals the scalar value.
|
|
201
|
+
* - Multiple mode: finds the first option whose value appears in the array.
|
|
202
|
+
* - Returns `0` when no match is found (default to first option).
|
|
203
|
+
* - Returns `-1` when there are no enabled options.
|
|
204
|
+
*/
|
|
205
|
+
function findInitialActiveOptionIndex(opts, value, multiple, compareFn) {
|
|
206
|
+
const enabled = opts.filter((o) => !o.disabled());
|
|
207
|
+
if (enabled.length === 0) {
|
|
208
|
+
return -1;
|
|
209
|
+
}
|
|
210
|
+
if (multiple && Array.isArray(value) && value.length > 0) {
|
|
211
|
+
const idx = enabled.findIndex((o) => value.some((v) => compareFn(v, o.value())));
|
|
212
|
+
return idx >= 0 ? idx : 0;
|
|
213
|
+
}
|
|
214
|
+
if (value !== null && value !== undefined) {
|
|
215
|
+
const idx = enabled.findIndex((o) => compareFn(o.value(), value));
|
|
216
|
+
return idx >= 0 ? idx : 0;
|
|
217
|
+
}
|
|
218
|
+
return 0;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Returns the next index to navigate to with wrap-around.
|
|
222
|
+
*
|
|
223
|
+
* If the option count is 0, returns -1 (no valid target).
|
|
224
|
+
* If the current index is negative, starts from the beginning (delta > 0) or end (delta < 0).
|
|
225
|
+
*/
|
|
226
|
+
function computeNextActiveOptionIndex(optCount, currentIndex, delta) {
|
|
227
|
+
if (optCount === 0)
|
|
228
|
+
return -1;
|
|
229
|
+
let idx = currentIndex < 0 ? (delta > 0 ? -1 : optCount) : currentIndex;
|
|
230
|
+
idx += delta;
|
|
231
|
+
// Wrap around
|
|
232
|
+
if (idx < 0)
|
|
233
|
+
return optCount - 1;
|
|
234
|
+
if (idx >= optCount)
|
|
235
|
+
return 0;
|
|
236
|
+
return idx;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Computes a new active index constrained within [0, optCount - 1], applying
|
|
240
|
+
* a page-sized step (clamped to optCount). Used for PageUp/PageDown navigation.
|
|
241
|
+
*/
|
|
242
|
+
function computePagedActiveOptionIndex(optCount, currentIndex, direction) {
|
|
243
|
+
if (optCount === 0)
|
|
244
|
+
return -1;
|
|
245
|
+
const pageSize = Math.min(KEYBOARD_PAGE_SIZE, optCount);
|
|
246
|
+
const idx = currentIndex + direction * pageSize;
|
|
247
|
+
return Math.max(0, Math.min(idx, optCount - 1));
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Scrolls the given container element so the option at `element` is visible.
|
|
251
|
+
*
|
|
252
|
+
* Handles two panel layouts:
|
|
253
|
+
* - **Direct**: the container itself is the scrollable panel (`container` === `scrollContainer`).
|
|
254
|
+
* - **Nested**: options sit inside a scrollable sub-element within the main panel
|
|
255
|
+
* (`container` is the nested element, e.g. `.fui-autocomplete__options`).
|
|
256
|
+
*
|
|
257
|
+
* Pass `select`-style (direct) or `autocomplete`-style (nested) via a selector.
|
|
258
|
+
*/
|
|
259
|
+
function scrollOptionIntoView(element, container, nestedSelector) {
|
|
260
|
+
if (!element || !container)
|
|
261
|
+
return;
|
|
262
|
+
const scrollEl = nestedSelector ? container.querySelector(nestedSelector) : container;
|
|
263
|
+
if (!scrollEl)
|
|
264
|
+
return;
|
|
265
|
+
// In nested layout, the option's offsetParent is the container not the scrollEl,
|
|
266
|
+
// so we need to account for the offset difference.
|
|
267
|
+
const optionTop = nestedSelector ? element.offsetTop - scrollEl.offsetTop : element.offsetTop;
|
|
268
|
+
const optionBottom = optionTop + element.offsetHeight;
|
|
269
|
+
const scrollTop = scrollEl.scrollTop;
|
|
270
|
+
const scrollBottom = scrollTop + scrollEl.clientHeight;
|
|
271
|
+
if (optionTop < scrollTop) {
|
|
272
|
+
scrollEl.scrollTop = optionTop;
|
|
273
|
+
}
|
|
274
|
+
else if (optionBottom > scrollBottom) {
|
|
275
|
+
scrollEl.scrollTop = optionBottom - scrollEl.clientHeight;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Screen reader announcement.
|
|
280
|
+
* Clears the message first so repeated identical messages are re-announced.
|
|
281
|
+
*/
|
|
282
|
+
function announceMessage(liveSignal, message) {
|
|
283
|
+
liveSignal.set('');
|
|
284
|
+
setTimeout(() => {
|
|
285
|
+
liveSignal.set(message);
|
|
286
|
+
}, 50);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Computes the active descendant id for aria-activedescendant.
|
|
290
|
+
*/
|
|
291
|
+
function computeActiveDescendant(opts, activeIndex) {
|
|
292
|
+
if (activeIndex >= 0 && activeIndex < opts.length) {
|
|
293
|
+
return opts[activeIndex].id;
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Returns all non-disabled options from the given list.
|
|
299
|
+
*/
|
|
300
|
+
function getEnabledOptions(opts) {
|
|
301
|
+
return opts.filter((o) => !o.disabled());
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Determines whether a single option should be considered selected based on
|
|
305
|
+
* the current model value.
|
|
306
|
+
*
|
|
307
|
+
* Labels are unique identifiers, so comparison uses value identity (`===`).
|
|
308
|
+
* No custom `compareWith` is needed.
|
|
309
|
+
*/
|
|
310
|
+
function isOptionSelected(optValue, currentValue, isMultiple, compareFn) {
|
|
311
|
+
if (optValue === undefined)
|
|
312
|
+
return false;
|
|
313
|
+
if (isMultiple && Array.isArray(currentValue)) {
|
|
314
|
+
return currentValue.some((v) => compareFn(v, optValue));
|
|
315
|
+
}
|
|
316
|
+
if (currentValue !== null && currentValue !== undefined) {
|
|
317
|
+
return compareFn(currentValue, optValue);
|
|
318
|
+
}
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Applied option selection for both single and multiple mode.
|
|
323
|
+
*
|
|
324
|
+
* This is the shared core of `_onOptionSelected` in both `FuiSelectComponent`
|
|
325
|
+
* and `FuiAutocompleteComponent`. It mutates option state (`select()`/`deselect()`)
|
|
326
|
+
* and returns the new value, but does NOT touch component signals or emit outputs
|
|
327
|
+
* — that stays in the calling component.
|
|
328
|
+
*
|
|
329
|
+
* @param host The host component (provides `value`, `options`, `multiple`).
|
|
330
|
+
* @param option The option being selected/deselected.
|
|
331
|
+
* @returns `{ newValue, wasSelected }`.
|
|
332
|
+
*/
|
|
333
|
+
function applyOptionSelection(host, option) {
|
|
334
|
+
const newValue = option.value();
|
|
335
|
+
const compareFn = host.compareWith();
|
|
336
|
+
if (host.multiple()) {
|
|
337
|
+
// Check if the option was already selected before toggling
|
|
338
|
+
const current = host.value();
|
|
339
|
+
const wasSelected = Array.isArray(current) && current.some((v) => compareFn(v, newValue));
|
|
340
|
+
const arr = toggleMultiValue(current, newValue, compareFn);
|
|
341
|
+
if (wasSelected) {
|
|
342
|
+
option.deselect();
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
option.select();
|
|
346
|
+
}
|
|
347
|
+
return { newValue: arr, wasSelected };
|
|
348
|
+
}
|
|
349
|
+
// Single mode
|
|
350
|
+
host.options().forEach((opt) => {
|
|
351
|
+
if (opt !== option) {
|
|
352
|
+
opt.deselect();
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
option.select();
|
|
356
|
+
return { newValue, wasSelected: false };
|
|
357
|
+
}
|
|
358
|
+
|
|
81
359
|
/**
|
|
82
360
|
* Generated bundle index. Do not edit.
|
|
83
361
|
*/
|
|
84
362
|
|
|
85
|
-
export { DefaultErrorStateMatcher, FUI_FORM_FIELD_CONTROL, FuiIntlBase, mixinErrorState };
|
|
363
|
+
export { DefaultErrorStateMatcher, FUI_FORM_FIELD_CONTROL, FUI_STRENGTH_METER, FuiIntlBase, KEYBOARD_PAGE_SIZE, announceMessage, applyOptionSelection, computeActiveDescendant, computeMultiDisplayValue, computeNextActiveOptionIndex, computePagedActiveOptionIndex, findInitialActiveOptionIndex, getEnabledOptions, isEmpty, isOptionSelected, mixinErrorState, noop, scrollOptionIntoView, syncMultiOptions, toggleMultiValue };
|
|
86
364
|
//# sourceMappingURL=raintonic-formaui-core.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raintonic-formaui-core.mjs","sources":["../../../lib/core/form-field-control.ts","../../../lib/core/error-state.ts","../../../lib/core/intl/fui-intl-base.ts","../../../lib/core/raintonic-formaui-core.ts"],"sourcesContent":["import { Observable } from 'rxjs';\r\nimport { NgControl } from '@angular/forms';\r\nimport { InjectionToken, Signal } from '@angular/core';\r\n\r\n/**\r\n * Interface for form field controls following Angular Material patterns\r\n * This interface should be implemented by any component that can be used inside fui-form-field\r\n */\r\nexport interface FuiFormFieldControl<T = unknown> {\r\n /**\r\n * Stream that emits whenever the state of the control changes\r\n */\r\n readonly stateChanges: Observable<void>;\r\n\r\n /**\r\n * The value of the control\r\n */\r\n readonly value: Signal<T | null>;\r\n\r\n /**\r\n * The placeholder for this control\r\n */\r\n readonly placeholder: Signal<string>;\r\n\r\n /**\r\n * The NgControl for this control (non-reactive)\r\n */\r\n readonly ngControl: NgControl | null;\r\n\r\n /**\r\n * Whether the control is focused\r\n */\r\n readonly focused: Signal<boolean>;\r\n\r\n /**\r\n * Whether the control is empty\r\n */\r\n readonly empty: Signal<boolean>;\r\n\r\n /**\r\n * Whether the control is required\r\n */\r\n readonly required: Signal<boolean>;\r\n\r\n /**\r\n * Whether the control is disabled\r\n */\r\n readonly disabled: Signal<boolean>;\r\n\r\n /**\r\n * Whether the control is in an error state\r\n */\r\n readonly errorState: Signal<boolean>;\r\n\r\n /**\r\n * The aria-describedby attribute on the control\r\n */\r\n readonly controlType?: string;\r\n\r\n /**\r\n * The element ID for the control\r\n */\r\n readonly id: string;\r\n\r\n /**\r\n * Handles a click on the control's container\r\n */\r\n onContainerClick(event: MouseEvent): void;\r\n\r\n /**\r\n * Sets the list of element IDs that describe the control\r\n */\r\n setDescribedByIds(ids: string[]): void;\r\n\r\n /**\r\n * Sets the read-only state of the control (propagated from form-field)\r\n */\r\n setReadOnly?(readOnly: boolean): void;\r\n}\r\n\r\n/**\r\n * Injection token used to provide the form field control to the form field\r\n */\r\nexport const FUI_FORM_FIELD_CONTROL = new InjectionToken<FuiFormFieldControl>('FuiFormFieldControl');\r\n","import { Injectable } from '@angular/core';\r\nimport { FormControl, FormGroupDirective, NgControl, NgForm } from '@angular/forms';\r\nimport { Subject } from 'rxjs';\r\n\r\n/**\r\n * Error state matcher that follows Angular Material patterns\r\n * Determines when to show error messages\r\n */\r\nexport interface ErrorStateMatcher {\r\n isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean;\r\n}\r\n\r\n/**\r\n * Default error state matcher implementation\r\n * Shows errors when control is invalid and either touched or form is submitted\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class DefaultErrorStateMatcher implements ErrorStateMatcher {\r\n isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {\r\n const isSubmitted = form?.submitted;\r\n return !!(control && control.invalid && (control.touched || isSubmitted));\r\n }\r\n}\r\n\r\n/**\r\n * Interface for components that can display error state\r\n */\r\nexport interface CanUpdateErrorState {\r\n readonly stateChanges: Subject<void>;\r\n errorState: boolean;\r\n errorStateMatcher: ErrorStateMatcher | null;\r\n updateErrorState(): void;\r\n}\r\n\r\n/**\r\n * Mixin to add error state handling to a component\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Mixin pattern requires any[] for constructor spread\r\nexport type Constructor<T = object> = new (...args: any[]) => T;\r\n\r\nexport interface HasErrorState {\r\n _defaultErrorStateMatcher: ErrorStateMatcher;\r\n _parentForm: NgForm | FormGroupDirective | null;\r\n _parentFormGroup: FormGroupDirective | null;\r\n ngControl: NgControl | null;\r\n}\r\n\r\n/**\r\n * Mixin that adds error state handling\r\n */\r\nexport function mixinErrorState<T extends Constructor<HasErrorState>>(base: T): Constructor<CanUpdateErrorState> & T {\r\n return class extends base implements CanUpdateErrorState {\r\n errorState = false;\r\n isErrorState = false;\r\n errorStateMatcher: ErrorStateMatcher | null = null;\r\n readonly stateChanges = new Subject<void>();\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor, @typescript-eslint/no-explicit-any -- Mixin pattern requires any[] for constructor spread\r\n constructor(...args: any[]) {\r\n super(...args);\r\n }\r\n\r\n updateErrorState(): void {\r\n this._updateErrorState();\r\n }\r\n\r\n _updateErrorState(): void {\r\n const isOldState = this.isErrorState;\r\n const parent = this._parentFormGroup ?? this._parentForm;\r\n const matcher = this.errorStateMatcher ?? this._defaultErrorStateMatcher;\r\n const control = this.ngControl ? (this.ngControl.control as FormControl) : null;\r\n const isNewState = matcher.isErrorState(control, parent);\r\n\r\n if (isNewState !== isOldState) {\r\n this.isErrorState = isNewState;\r\n this.errorState = isNewState;\r\n this.stateChanges.next();\r\n }\r\n }\r\n };\r\n}\r\n","import { Injectable, OnDestroy } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\n\r\n/**\r\n * Base class for every FormaUI component Intl service.\r\n * Exposes a `changes` Subject so consumers that mutate strings at runtime\r\n * can trigger a re-render in all components that subscribe.\r\n *\r\n * Consumers extend and override properties, OR provide a replacement class via DI.\r\n */\r\n@Injectable()\r\nexport abstract class FuiIntlBase implements OnDestroy {\r\n /** Emits whenever the labels change. Components subscribe and mark for check. */\r\n readonly changes = new Subject<void>();\r\n\r\n /** Call after mutating properties to notify subscribers. */\r\n notifyChanges(): void {\r\n this.changes.next();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.changes.complete();\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAgFA;;AAEG;MACU,sBAAsB,GAAG,IAAI,cAAc,CAAsB,qBAAqB;;ACvEnG;;;AAGG;MAEU,wBAAwB,CAAA;IACnC,YAAY,CAAC,OAA2B,EAAE,IAAwC,EAAA;AAChF,QAAA,MAAM,WAAW,GAAG,IAAI,EAAE,SAAS;AACnC,QAAA,OAAO,CAAC,EAAE,OAAO,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,CAAC;IAC3E;uGAJW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAxB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,wBAAwB,cADX,MAAM,EAAA,CAAA;;2FACnB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBADpC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AA+BlC;;AAEG;AACG,SAAU,eAAe,CAAuC,IAAO,EAAA;IAC3E,OAAO,cAAc,IAAI,CAAA;QACvB,UAAU,GAAG,KAAK;QAClB,YAAY,GAAG,KAAK;QACpB,iBAAiB,GAA6B,IAAI;AACzC,QAAA,YAAY,GAAG,IAAI,OAAO,EAAQ;;AAG3C,QAAA,WAAA,CAAY,GAAG,IAAW,EAAA;AACxB,YAAA,KAAK,CAAC,GAAG,IAAI,CAAC;QAChB;QAEA,gBAAgB,GAAA;YACd,IAAI,CAAC,iBAAiB,EAAE;QAC1B;QAEA,iBAAiB,GAAA;AACf,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,WAAW;YACxD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,yBAAyB;AACxE,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,GAAI,IAAI,CAAC,SAAS,CAAC,OAAuB,GAAG,IAAI;YAC/E,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC;AAExD,YAAA,IAAI,UAAU,KAAK,UAAU,EAAE;AAC7B,gBAAA,IAAI,CAAC,YAAY,GAAG,UAAU;AAC9B,gBAAA,IAAI,CAAC,UAAU,GAAG,UAAU;AAC5B,gBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;YAC1B;QACF;KACD;AACH;;AC7EA;;;;;;AAMG;MAEmB,WAAW,CAAA;;AAEtB,IAAA,OAAO,GAAG,IAAI,OAAO,EAAQ;;IAGtC,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;IACrB;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;IACzB;uGAXoB,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;2GAAX,WAAW,EAAA,CAAA;;2FAAX,WAAW,EAAA,UAAA,EAAA,CAAA;kBADhC;;;ACVD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"raintonic-formaui-core.mjs","sources":["../../../lib/core/form-field-control.ts","../../../lib/core/error-state.ts","../../../lib/core/intl/fui-intl-base.ts","../../../lib/core/strength-meter.ts","../../../lib/core/utils/index.ts","../../../lib/core/multi-select/multi-select.ts","../../../lib/core/raintonic-formaui-core.ts"],"sourcesContent":["import { Observable } from 'rxjs';\r\nimport { NgControl } from '@angular/forms';\r\nimport { InjectionToken, Signal } from '@angular/core';\r\n\r\n/**\r\n * Interface for form field controls following Angular Material patterns\r\n * This interface should be implemented by any component that can be used inside fui-form-field\r\n */\r\nexport interface FuiFormFieldControl<T = unknown> {\r\n /**\r\n * Stream that emits whenever the state of the control changes\r\n */\r\n readonly stateChanges: Observable<void>;\r\n\r\n /**\r\n * The value of the control\r\n */\r\n readonly value: Signal<T | null>;\r\n\r\n /**\r\n * The placeholder for this control\r\n */\r\n readonly placeholder: Signal<string>;\r\n\r\n /**\r\n * The NgControl for this control (non-reactive)\r\n */\r\n readonly ngControl: NgControl | null;\r\n\r\n /**\r\n * Whether the control is focused\r\n */\r\n readonly focused: Signal<boolean>;\r\n\r\n /**\r\n * Whether the control is empty\r\n */\r\n readonly empty: Signal<boolean>;\r\n\r\n /**\r\n * Whether the control is required\r\n */\r\n readonly required: Signal<boolean>;\r\n\r\n /**\r\n * Whether the control is disabled\r\n */\r\n readonly disabled: Signal<boolean>;\r\n\r\n /**\r\n * Whether the control is in read-only mode\r\n */\r\n readonly readonly: Signal<boolean>;\r\n\r\n /**\r\n * Whether the control is in an error state\r\n */\r\n readonly errorState: Signal<boolean>;\r\n\r\n /**\r\n * The aria-describedby attribute on the control\r\n */\r\n readonly controlType?: string;\r\n\r\n /**\r\n * The element ID for the control\r\n */\r\n readonly id: string;\r\n\r\n /**\r\n * Handles a click on the control's container\r\n */\r\n onContainerClick(event: MouseEvent): void;\r\n\r\n /**\r\n * Sets the list of element IDs that describe the control\r\n */\r\n setDescribedByIds(ids: string[]): void;\r\n\r\n /**\r\n * Whether the form-field should show a copy-to-clipboard button when\r\n * the control is in read-only mode. Only plain input controls (e.g.\r\n * `fuiInput`) return `true` — wrapper controls with their own interactive\r\n * elements should not implement this (defaults to `false`).\r\n */\r\n readonlyCopyEnabled?(): boolean;\r\n}\r\n\r\n/**\r\n * Injection token used to provide the form field control to the form field\r\n */\r\nexport const FUI_FORM_FIELD_CONTROL = new InjectionToken<FuiFormFieldControl>('FuiFormFieldControl');\r\n","import { Injectable } from '@angular/core';\r\nimport { FormControl, FormGroupDirective, NgControl, NgForm } from '@angular/forms';\r\nimport { Subject } from 'rxjs';\r\n\r\n/**\r\n * Error state matcher that follows Angular Material patterns\r\n * Determines when to show error messages\r\n */\r\nexport interface ErrorStateMatcher {\r\n isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean;\r\n}\r\n\r\n/**\r\n * Default error state matcher implementation\r\n * Shows errors when control is invalid and either touched or form is submitted\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class DefaultErrorStateMatcher implements ErrorStateMatcher {\r\n isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {\r\n const isSubmitted = form?.submitted;\r\n return !!(control && control.invalid && (control.touched || isSubmitted));\r\n }\r\n}\r\n\r\n/**\r\n * Interface for components that can display error state\r\n */\r\nexport interface CanUpdateErrorState {\r\n readonly stateChanges: Subject<void>;\r\n errorState: boolean;\r\n errorStateMatcher: ErrorStateMatcher | null;\r\n updateErrorState(): void;\r\n}\r\n\r\n/**\r\n * Mixin to add error state handling to a component\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Mixin pattern requires any[] for constructor spread\r\nexport type Constructor<T = object> = new (...args: any[]) => T;\r\n\r\nexport interface HasErrorState {\r\n _defaultErrorStateMatcher: ErrorStateMatcher;\r\n _parentForm: NgForm | FormGroupDirective | null;\r\n _parentFormGroup: FormGroupDirective | null;\r\n ngControl: NgControl | null;\r\n}\r\n\r\n/**\r\n * Mixin that adds error state handling\r\n */\r\nexport function mixinErrorState<T extends Constructor<HasErrorState>>(base: T): Constructor<CanUpdateErrorState> & T {\r\n return class extends base implements CanUpdateErrorState {\r\n errorState = false;\r\n isErrorState = false;\r\n errorStateMatcher: ErrorStateMatcher | null = null;\r\n readonly stateChanges = new Subject<void>();\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor, @typescript-eslint/no-explicit-any -- Mixin pattern requires any[] for constructor spread\r\n constructor(...args: any[]) {\r\n super(...args);\r\n }\r\n\r\n updateErrorState(): void {\r\n this._updateErrorState();\r\n }\r\n\r\n _updateErrorState(): void {\r\n const isOldState = this.isErrorState;\r\n const parent = this._parentFormGroup ?? this._parentForm;\r\n const matcher = this.errorStateMatcher ?? this._defaultErrorStateMatcher;\r\n const control = this.ngControl ? (this.ngControl.control as FormControl) : null;\r\n const isNewState = matcher.isErrorState(control, parent);\r\n\r\n if (isNewState !== isOldState) {\r\n this.isErrorState = isNewState;\r\n this.errorState = isNewState;\r\n this.stateChanges.next();\r\n }\r\n }\r\n };\r\n}\r\n","import { Injectable, OnDestroy } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\n\r\n/**\r\n * Base class for every FormaUI component Intl service.\r\n * Exposes a `changes` Subject so consumers that mutate strings at runtime\r\n * can trigger a re-render in all components that subscribe.\r\n *\r\n * Consumers extend and override properties, OR provide a replacement class via DI.\r\n */\r\n@Injectable()\r\nexport abstract class FuiIntlBase implements OnDestroy {\r\n /** Emits whenever the labels change. Components subscribe and mark for check. */\r\n readonly changes = new Subject<void>();\r\n\r\n /** Call after mutating properties to notify subscribers. */\r\n notifyChanges(): void {\r\n this.changes.next();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.changes.complete();\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\n/**\r\n * Interface for components that act as a strength meter within a form field.\r\n * Currently used as a presence-only token — the form-field only queries\r\n * whether a strength meter component is projected as a content child.\r\n */\r\nexport interface FuiStrengthMeter {\r\n /** Placeholder for future shared interface needs. */\r\n __brand: '';\r\n}\r\n\r\n/**\r\n * Injection token used to look up a strength meter component projected\r\n * inside a form field without creating a hard secondary-entry-point\r\n * dependency.\r\n */\r\nexport const FUI_STRENGTH_METER = new InjectionToken<FuiStrengthMeter>('FuiStrengthMeter');\r\n","/* keep for lint rules errors. must use any[] */\r\nexport const noop = (..._args: any[]) => {\r\n /* noop */\r\n};\r\n","import { type Signal, type WritableSignal } from '@angular/core';\r\n\r\n/**\r\n * Contract that a parent component (select or autocomplete) must satisfy\r\n * for the multi-select helpers. Both FuiSelectComponent and FuiAutocompleteComponent\r\n * implement this implicitly by exposing the same signal/input shape.\r\n */\r\nexport interface MultiSelectHost {\r\n readonly value: Signal<unknown>;\r\n readonly options: Signal<readonly OptionLike[]>;\r\n readonly multiple: () => boolean;\r\n readonly compareWith: () => (a: unknown, b: unknown) => boolean;\r\n}\r\n\r\n/** Minimal shape of an option that the helpers need. */\r\nexport interface OptionLike {\r\n readonly value: () => unknown;\r\n readonly disabled: () => boolean;\r\n getLabel(): string;\r\n select(): void;\r\n deselect(): void;\r\n}\r\n\r\n/**\r\n * Number of options to skip when handling PageUp/PageDown in both select and autocomplete.\r\n * Effective page size is `Math.min(KEYBOARD_PAGE_SIZE, optionCount)`.\r\n */\r\nexport const KEYBOARD_PAGE_SIZE = 10;\r\n\r\n/**\r\n * Interface extending OptionLike with methods needed for keyboard navigation.\r\n * Components that use keyboard navigation helpers must provide options that\r\n * implement this contract.\r\n */\r\nexport interface NavigableOption extends OptionLike {\r\n readonly _selected?: () => boolean;\r\n setActive(): void;\r\n setInactive(): void;\r\n _getHostElement(): HTMLElement;\r\n readonly id: string;\r\n}\r\n\r\n/**\r\n * Computes the display string shown in the trigger.\r\n *\r\n * - Single mode: returns the label of the matching option (or stringified value).\r\n * - Multiple mode: joins selected option labels with `', '`.\r\n * - Null/undefined/empty-array: returns `''`.\r\n * - If no option matches the value, returns `String(value)` (single) or `''` (multiple).\r\n */\r\nexport function computeMultiDisplayValue(host: MultiSelectHost): string {\r\n const val = host.value();\r\n const opts = host.options();\r\n const compareFn = host.compareWith();\r\n\r\n if (val === null || val === 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((o) => o.value() !== undefined);\r\n\r\n if (host.multiple()) {\r\n if (!Array.isArray(val)) {\r\n return '';\r\n }\r\n const selectedOptions = validOpts.filter((o) => (val as unknown[]).some((v: unknown) => compareFn(v, o.value())));\r\n return selectedOptions.map((o) => o.getLabel()).join(', ');\r\n }\r\n\r\n const selectedOption = validOpts.find((o) => compareFn(o.value(), val));\r\n return selectedOption ? selectedOption.getLabel() : String(val);\r\n}\r\n\r\n/**\r\n * Iterates all options and calls `select()` / `deselect()` based on whether\r\n * the option's value matches the current model value (by identity).\r\n *\r\n * - Single mode: compares the scalar value directly.\r\n * - Multiple mode: checks each array element.\r\n * - Options with `undefined` value are skipped.\r\n */\r\nexport function syncMultiOptions(host: MultiSelectHost): void {\r\n const currentValue = host.value();\r\n const opts = host.options();\r\n const isMultiple = host.multiple();\r\n const compareFn = host.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\r\n let isSelected = false;\r\n\r\n if (isMultiple && Array.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/**\r\n * Toggles an option value in/out of an array-based multi-value.\r\n *\r\n * - If the value is already present, it is removed (deselect).\r\n * - If absent, it is appended (select).\r\n * - If `current` is not an array, starts fresh with `[]`.\r\n *\r\n * Returns a **new array** (shallow copy) so callers can set it as the new model value.\r\n */\r\nexport function toggleMultiValue(\r\n current: unknown,\r\n optionValue: unknown,\r\n compareFn: (a: unknown, b: unknown) => boolean,\r\n): unknown[] {\r\n const arr = Array.isArray(current) ? [...current] : [];\r\n const idx = arr.findIndex((v: unknown) => compareFn(v, optionValue));\r\n\r\n if (idx > -1) {\r\n arr.splice(idx, 1);\r\n } else {\r\n arr.push(optionValue);\r\n }\r\n return arr;\r\n}\r\n\r\n/**\r\n * Checks whether a value represents the \"empty\" state.\r\n *\r\n * - `null` or `undefined` → empty\r\n * - Empty array `[]` → empty (so multiple-mode starts with no selection)\r\n * - Everything else → not empty\r\n */\r\nexport function isEmpty(value: unknown): boolean {\r\n if (value === null || value === undefined) {\r\n return true;\r\n }\r\n if (Array.isArray(value)) {\r\n return value.length === 0;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Finds the index of the first enabled option whose value matches the current\r\n * model value. Used to set the initial keyboard-navigation active option when\r\n * opening the panel.\r\n *\r\n * - Single mode: finds the option whose value equals the scalar value.\r\n * - Multiple mode: finds the first option whose value appears in the array.\r\n * - Returns `0` when no match is found (default to first option).\r\n * - Returns `-1` when there are no enabled options.\r\n */\r\nexport function findInitialActiveOptionIndex(\r\n opts: readonly OptionLike[],\r\n value: unknown,\r\n multiple: boolean,\r\n compareFn: (a: unknown, b: unknown) => boolean,\r\n): number {\r\n const enabled = opts.filter((o) => !o.disabled());\r\n if (enabled.length === 0) {\r\n return -1;\r\n }\r\n\r\n if (multiple && Array.isArray(value) && value.length > 0) {\r\n const idx = enabled.findIndex((o) => (value as unknown[]).some((v: unknown) => compareFn(v, o.value())));\r\n return idx >= 0 ? idx : 0;\r\n }\r\n\r\n if (value !== null && value !== undefined) {\r\n const idx = enabled.findIndex((o) => compareFn(o.value(), value));\r\n return idx >= 0 ? idx : 0;\r\n }\r\n\r\n return 0;\r\n}\r\n\r\n/**\r\n * Returns the next index to navigate to with wrap-around.\r\n *\r\n * If the option count is 0, returns -1 (no valid target).\r\n * If the current index is negative, starts from the beginning (delta > 0) or end (delta < 0).\r\n */\r\nexport function computeNextActiveOptionIndex(optCount: number, currentIndex: number, delta: number): number {\r\n if (optCount === 0) return -1;\r\n\r\n let idx = currentIndex < 0 ? (delta > 0 ? -1 : optCount) : currentIndex;\r\n idx += delta;\r\n\r\n // Wrap around\r\n if (idx < 0) return optCount - 1;\r\n if (idx >= optCount) return 0;\r\n return idx;\r\n}\r\n\r\n/**\r\n * Computes a new active index constrained within [0, optCount - 1], applying\r\n * a page-sized step (clamped to optCount). Used for PageUp/PageDown navigation.\r\n */\r\nexport function computePagedActiveOptionIndex(optCount: number, currentIndex: number, direction: -1 | 1): number {\r\n if (optCount === 0) return -1;\r\n const pageSize = Math.min(KEYBOARD_PAGE_SIZE, optCount);\r\n const idx = currentIndex + direction * pageSize;\r\n return Math.max(0, Math.min(idx, optCount - 1));\r\n}\r\n\r\n/**\r\n * Scrolls the given container element so the option at `element` is visible.\r\n *\r\n * Handles two panel layouts:\r\n * - **Direct**: the container itself is the scrollable panel (`container` === `scrollContainer`).\r\n * - **Nested**: options sit inside a scrollable sub-element within the main panel\r\n * (`container` is the nested element, e.g. `.fui-autocomplete__options`).\r\n *\r\n * Pass `select`-style (direct) or `autocomplete`-style (nested) via a selector.\r\n */\r\nexport function scrollOptionIntoView(\r\n element: HTMLElement | null | undefined,\r\n container: HTMLElement | null | undefined,\r\n nestedSelector?: string,\r\n): void {\r\n if (!element || !container) return;\r\n\r\n const scrollEl: HTMLElement | null = nestedSelector ? container.querySelector(nestedSelector) : container;\r\n if (!scrollEl) return;\r\n\r\n // In nested layout, the option's offsetParent is the container not the scrollEl,\r\n // so we need to account for the offset difference.\r\n const optionTop = nestedSelector ? element.offsetTop - scrollEl.offsetTop : element.offsetTop;\r\n const optionBottom = optionTop + element.offsetHeight;\r\n const scrollTop = scrollEl.scrollTop;\r\n const scrollBottom = scrollTop + scrollEl.clientHeight;\r\n\r\n if (optionTop < scrollTop) {\r\n scrollEl.scrollTop = optionTop;\r\n } else if (optionBottom > scrollBottom) {\r\n scrollEl.scrollTop = optionBottom - scrollEl.clientHeight;\r\n }\r\n}\r\n\r\n/**\r\n * Screen reader announcement.\r\n * Clears the message first so repeated identical messages are re-announced.\r\n */\r\nexport function announceMessage(liveSignal: WritableSignal<string>, message: string): void {\r\n liveSignal.set('');\r\n setTimeout(() => {\r\n liveSignal.set(message);\r\n }, 50);\r\n}\r\n\r\n/**\r\n * Computes the active descendant id for aria-activedescendant.\r\n */\r\nexport function computeActiveDescendant(\r\n opts: readonly { id: string; disabled(): boolean }[],\r\n activeIndex: number,\r\n): string | null {\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 * Returns all non-disabled options from the given list.\r\n */\r\nexport function getEnabledOptions<T extends { disabled(): boolean }>(opts: readonly T[]): T[] {\r\n return opts.filter((o) => !o.disabled());\r\n}\r\n\r\n/**\r\n * Determines whether a single option should be considered selected based on\r\n * the current model value.\r\n *\r\n * Labels are unique identifiers, so comparison uses value identity (`===`).\r\n * No custom `compareWith` is needed.\r\n */\r\nexport function isOptionSelected(\r\n optValue: unknown,\r\n currentValue: unknown,\r\n isMultiple: boolean,\r\n compareFn: (a: unknown, b: unknown) => boolean,\r\n): boolean {\r\n if (optValue === undefined) return false;\r\n\r\n if (isMultiple && Array.isArray(currentValue)) {\r\n return currentValue.some((v: unknown) => compareFn(v, optValue));\r\n }\r\n\r\n if (currentValue !== null && currentValue !== undefined) {\r\n return compareFn(currentValue, optValue);\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Result of `applyOptionSelection`, returned so the calling component can\r\n * update its signals and emit outputs.\r\n */\r\nexport interface SelectionResult {\r\n /** New value for the model (already toggled/selected). */\r\n newValue: unknown;\r\n /** Whether the option was already selected before this call (multi-mode only; `false` for single). */\r\n wasSelected: boolean;\r\n}\r\n\r\n/**\r\n * Applied option selection for both single and multiple mode.\r\n *\r\n * This is the shared core of `_onOptionSelected` in both `FuiSelectComponent`\r\n * and `FuiAutocompleteComponent`. It mutates option state (`select()`/`deselect()`)\r\n * and returns the new value, but does NOT touch component signals or emit outputs\r\n * — that stays in the calling component.\r\n *\r\n * @param host The host component (provides `value`, `options`, `multiple`).\r\n * @param option The option being selected/deselected.\r\n * @returns `{ newValue, wasSelected }`.\r\n */\r\nexport function applyOptionSelection(host: MultiSelectHost, option: OptionLike): SelectionResult {\r\n const newValue = option.value();\r\n const compareFn = host.compareWith();\r\n\r\n if (host.multiple()) {\r\n // Check if the option was already selected before toggling\r\n const current = host.value();\r\n const wasSelected = Array.isArray(current) && current.some((v: unknown) => compareFn(v, newValue));\r\n\r\n const arr = toggleMultiValue(current, newValue, compareFn);\r\n\r\n if (wasSelected) {\r\n option.deselect();\r\n } else {\r\n option.select();\r\n }\r\n\r\n return { newValue: arr, wasSelected };\r\n }\r\n\r\n // Single mode\r\n host.options().forEach((opt) => {\r\n if (opt !== option) {\r\n opt.deselect();\r\n }\r\n });\r\n\r\n option.select();\r\n return { newValue, wasSelected: false };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|