@raintonic/formaui 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +145 -0
- package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs +806 -0
- package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-cdk-form-field.mjs +86 -0
- package/fesm2022/raintonic-formaui-cdk-form-field.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-cdk-overlay.mjs +1757 -0
- package/fesm2022/raintonic-formaui-cdk-overlay.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs +287 -0
- package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-accordion.mjs +217 -0
- package/fesm2022/raintonic-formaui-components-accordion.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-alert.mjs +161 -0
- package/fesm2022/raintonic-formaui-components-alert.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs +726 -0
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-avatar.mjs +92 -0
- package/fesm2022/raintonic-formaui-components-avatar.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-badge.mjs +107 -0
- package/fesm2022/raintonic-formaui-components-badge.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-big-menu.mjs +68 -0
- package/fesm2022/raintonic-formaui-components-big-menu.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-breadcrumb.mjs +55 -0
- package/fesm2022/raintonic-formaui-components-breadcrumb.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-button-group.mjs +103 -0
- package/fesm2022/raintonic-formaui-components-button-group.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-button.mjs +241 -0
- package/fesm2022/raintonic-formaui-components-button.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-card.mjs +270 -0
- package/fesm2022/raintonic-formaui-components-card.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-checkbox.mjs +295 -0
- package/fesm2022/raintonic-formaui-components-checkbox.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-data-table.mjs +631 -0
- package/fesm2022/raintonic-formaui-components-data-table.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-date-picker.mjs +1331 -0
- package/fesm2022/raintonic-formaui-components-date-picker.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-divider.mjs +41 -0
- package/fesm2022/raintonic-formaui-components-divider.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-drawer.mjs +190 -0
- package/fesm2022/raintonic-formaui-components-drawer.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-dynamic-form.mjs +266 -0
- package/fesm2022/raintonic-formaui-components-dynamic-form.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-empty-state.mjs +33 -0
- package/fesm2022/raintonic-formaui-components-empty-state.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-file-upload.mjs +246 -0
- package/fesm2022/raintonic-formaui-components-file-upload.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-form-field.mjs +482 -0
- package/fesm2022/raintonic-formaui-components-form-field.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-icon.mjs +117 -0
- package/fesm2022/raintonic-formaui-components-icon.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-input.mjs +327 -0
- package/fesm2022/raintonic-formaui-components-input.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-list.mjs +149 -0
- package/fesm2022/raintonic-formaui-components-list.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-menu.mjs +896 -0
- package/fesm2022/raintonic-formaui-components-menu.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-number-input.mjs +345 -0
- package/fesm2022/raintonic-formaui-components-number-input.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-paginator.mjs +139 -0
- package/fesm2022/raintonic-formaui-components-paginator.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-password-input.mjs +306 -0
- package/fesm2022/raintonic-formaui-components-password-input.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-popover.mjs +451 -0
- package/fesm2022/raintonic-formaui-components-popover.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-progressbar.mjs +148 -0
- package/fesm2022/raintonic-formaui-components-progressbar.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-radio.mjs +260 -0
- package/fesm2022/raintonic-formaui-components-radio.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-select.mjs +1011 -0
- package/fesm2022/raintonic-formaui-components-select.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-side-panel.mjs +150 -0
- package/fesm2022/raintonic-formaui-components-side-panel.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-sidebar.mjs +257 -0
- package/fesm2022/raintonic-formaui-components-sidebar.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-skeleton.mjs +50 -0
- package/fesm2022/raintonic-formaui-components-skeleton.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-slider.mjs +347 -0
- package/fesm2022/raintonic-formaui-components-slider.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-spinner.mjs +63 -0
- package/fesm2022/raintonic-formaui-components-spinner.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-stepper.mjs +317 -0
- package/fesm2022/raintonic-formaui-components-stepper.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tab.mjs +197 -0
- package/fesm2022/raintonic-formaui-components-tab.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tag.mjs +78 -0
- package/fesm2022/raintonic-formaui-components-tag.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-time-picker.mjs +644 -0
- package/fesm2022/raintonic-formaui-components-time-picker.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-toggle.mjs +171 -0
- package/fesm2022/raintonic-formaui-components-toggle.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-toolbar.mjs +140 -0
- package/fesm2022/raintonic-formaui-components-toolbar.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tooltip.mjs +555 -0
- package/fesm2022/raintonic-formaui-components-tooltip.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tree-select.mjs +314 -0
- package/fesm2022/raintonic-formaui-components-tree-select.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tree-table.mjs +103 -0
- package/fesm2022/raintonic-formaui-components-tree-table.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tree.mjs +430 -0
- package/fesm2022/raintonic-formaui-components-tree.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-core.mjs +62 -0
- package/fesm2022/raintonic-formaui-core.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-services-dialog.mjs +798 -0
- package/fesm2022/raintonic-formaui-services-dialog.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-services-notification.mjs +391 -0
- package/fesm2022/raintonic-formaui-services-notification.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-services-theme.mjs +248 -0
- package/fesm2022/raintonic-formaui-services-theme.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-test-utils.mjs +66 -0
- package/fesm2022/raintonic-formaui-test-utils.mjs.map +1 -0
- package/fesm2022/raintonic-formaui.mjs +15 -0
- package/fesm2022/raintonic-formaui.mjs.map +1 -0
- package/llms-full.txt +1627 -0
- package/llms.txt +60 -0
- package/package.json +251 -0
- package/styles/_fonts-entry.scss +3 -0
- package/styles/fonts/dm-mono-400-latin.woff2 +0 -0
- package/styles/fonts/inter-tight-latin-italic.woff2 +0 -0
- package/styles/fonts/inter-tight-latin.woff2 +0 -0
- package/styles/index.scss +127 -0
- package/styles/partials/_constants.scss +29 -0
- package/styles/partials/_fonts.scss +36 -0
- package/styles/partials/_grid.scss +171 -0
- package/styles/partials/_mixins.scss +145 -0
- package/styles/partials/_motion.scss +252 -0
- package/styles/partials/_theme.scss +275 -0
- package/styles/partials/_typography.scss +112 -0
- package/styles/partials/_utilities.scss +480 -0
- package/styles/partials/themes/_dark.scss +254 -0
- package/styles/partials/themes/_light.scss +254 -0
- package/types/raintonic-formaui-cdk-drag-drop.d.ts +196 -0
- package/types/raintonic-formaui-cdk-drag-drop.d.ts.map +1 -0
- package/types/raintonic-formaui-cdk-form-field.d.ts +62 -0
- package/types/raintonic-formaui-cdk-form-field.d.ts.map +1 -0
- package/types/raintonic-formaui-cdk-overlay.d.ts +843 -0
- package/types/raintonic-formaui-cdk-overlay.d.ts.map +1 -0
- package/types/raintonic-formaui-cdk-virtual-scroll.d.ts +112 -0
- package/types/raintonic-formaui-cdk-virtual-scroll.d.ts.map +1 -0
- package/types/raintonic-formaui-components-accordion.d.ts +124 -0
- package/types/raintonic-formaui-components-accordion.d.ts.map +1 -0
- package/types/raintonic-formaui-components-alert.d.ts +143 -0
- package/types/raintonic-formaui-components-alert.d.ts.map +1 -0
- package/types/raintonic-formaui-components-autocomplete.d.ts +193 -0
- package/types/raintonic-formaui-components-autocomplete.d.ts.map +1 -0
- package/types/raintonic-formaui-components-avatar.d.ts +52 -0
- package/types/raintonic-formaui-components-avatar.d.ts.map +1 -0
- package/types/raintonic-formaui-components-badge.d.ts +47 -0
- package/types/raintonic-formaui-components-badge.d.ts.map +1 -0
- package/types/raintonic-formaui-components-big-menu.d.ts +62 -0
- package/types/raintonic-formaui-components-big-menu.d.ts.map +1 -0
- package/types/raintonic-formaui-components-breadcrumb.d.ts +26 -0
- package/types/raintonic-formaui-components-breadcrumb.d.ts.map +1 -0
- package/types/raintonic-formaui-components-button-group.d.ts +61 -0
- package/types/raintonic-formaui-components-button-group.d.ts.map +1 -0
- package/types/raintonic-formaui-components-button.d.ts +116 -0
- package/types/raintonic-formaui-components-button.d.ts.map +1 -0
- package/types/raintonic-formaui-components-card.d.ts +191 -0
- package/types/raintonic-formaui-components-card.d.ts.map +1 -0
- package/types/raintonic-formaui-components-checkbox.d.ts +132 -0
- package/types/raintonic-formaui-components-checkbox.d.ts.map +1 -0
- package/types/raintonic-formaui-components-data-table.d.ts +368 -0
- package/types/raintonic-formaui-components-data-table.d.ts.map +1 -0
- package/types/raintonic-formaui-components-date-picker.d.ts +341 -0
- package/types/raintonic-formaui-components-date-picker.d.ts.map +1 -0
- package/types/raintonic-formaui-components-divider.d.ts +21 -0
- package/types/raintonic-formaui-components-divider.d.ts.map +1 -0
- package/types/raintonic-formaui-components-drawer.d.ts +48 -0
- package/types/raintonic-formaui-components-drawer.d.ts.map +1 -0
- package/types/raintonic-formaui-components-dynamic-form.d.ts +412 -0
- package/types/raintonic-formaui-components-dynamic-form.d.ts.map +1 -0
- package/types/raintonic-formaui-components-empty-state.d.ts +14 -0
- package/types/raintonic-formaui-components-empty-state.d.ts.map +1 -0
- package/types/raintonic-formaui-components-file-upload.d.ts +77 -0
- package/types/raintonic-formaui-components-file-upload.d.ts.map +1 -0
- package/types/raintonic-formaui-components-form-field.d.ts +271 -0
- package/types/raintonic-formaui-components-form-field.d.ts.map +1 -0
- package/types/raintonic-formaui-components-icon.d.ts +61 -0
- package/types/raintonic-formaui-components-icon.d.ts.map +1 -0
- package/types/raintonic-formaui-components-input.d.ts +149 -0
- package/types/raintonic-formaui-components-input.d.ts.map +1 -0
- package/types/raintonic-formaui-components-list.d.ts +48 -0
- package/types/raintonic-formaui-components-list.d.ts.map +1 -0
- package/types/raintonic-formaui-components-menu.d.ts +403 -0
- package/types/raintonic-formaui-components-menu.d.ts.map +1 -0
- package/types/raintonic-formaui-components-number-input.d.ts +127 -0
- package/types/raintonic-formaui-components-number-input.d.ts.map +1 -0
- package/types/raintonic-formaui-components-paginator.d.ts +37 -0
- package/types/raintonic-formaui-components-paginator.d.ts.map +1 -0
- package/types/raintonic-formaui-components-password-input.d.ts +111 -0
- package/types/raintonic-formaui-components-password-input.d.ts.map +1 -0
- package/types/raintonic-formaui-components-popover.d.ts +131 -0
- package/types/raintonic-formaui-components-popover.d.ts.map +1 -0
- package/types/raintonic-formaui-components-progressbar.d.ts +111 -0
- package/types/raintonic-formaui-components-progressbar.d.ts.map +1 -0
- package/types/raintonic-formaui-components-radio.d.ts +95 -0
- package/types/raintonic-formaui-components-radio.d.ts.map +1 -0
- package/types/raintonic-formaui-components-select.d.ts +307 -0
- package/types/raintonic-formaui-components-select.d.ts.map +1 -0
- package/types/raintonic-formaui-components-side-panel.d.ts +51 -0
- package/types/raintonic-formaui-components-side-panel.d.ts.map +1 -0
- package/types/raintonic-formaui-components-sidebar.d.ts +174 -0
- package/types/raintonic-formaui-components-sidebar.d.ts.map +1 -0
- package/types/raintonic-formaui-components-skeleton.d.ts +20 -0
- package/types/raintonic-formaui-components-skeleton.d.ts.map +1 -0
- package/types/raintonic-formaui-components-slider.d.ts +108 -0
- package/types/raintonic-formaui-components-slider.d.ts.map +1 -0
- package/types/raintonic-formaui-components-spinner.d.ts +42 -0
- package/types/raintonic-formaui-components-spinner.d.ts.map +1 -0
- package/types/raintonic-formaui-components-stepper.d.ts +126 -0
- package/types/raintonic-formaui-components-stepper.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tab.d.ts +96 -0
- package/types/raintonic-formaui-components-tab.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tag.d.ts +34 -0
- package/types/raintonic-formaui-components-tag.d.ts.map +1 -0
- package/types/raintonic-formaui-components-time-picker.d.ts +172 -0
- package/types/raintonic-formaui-components-time-picker.d.ts.map +1 -0
- package/types/raintonic-formaui-components-toggle.d.ts +70 -0
- package/types/raintonic-formaui-components-toggle.d.ts.map +1 -0
- package/types/raintonic-formaui-components-toolbar.d.ts +128 -0
- package/types/raintonic-formaui-components-toolbar.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tooltip.d.ts +268 -0
- package/types/raintonic-formaui-components-tooltip.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tree-select.d.ts +80 -0
- package/types/raintonic-formaui-components-tree-select.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tree-table.d.ts +90 -0
- package/types/raintonic-formaui-components-tree-table.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tree.d.ts +104 -0
- package/types/raintonic-formaui-components-tree.d.ts.map +1 -0
- package/types/raintonic-formaui-core.d.ts +115 -0
- package/types/raintonic-formaui-core.d.ts.map +1 -0
- package/types/raintonic-formaui-services-dialog.d.ts +451 -0
- package/types/raintonic-formaui-services-dialog.d.ts.map +1 -0
- package/types/raintonic-formaui-services-notification.d.ts +221 -0
- package/types/raintonic-formaui-services-notification.d.ts.map +1 -0
- package/types/raintonic-formaui-services-theme.d.ts +126 -0
- package/types/raintonic-formaui-services-theme.d.ts.map +1 -0
- package/types/raintonic-formaui-test-utils.d.ts +24 -0
- package/types/raintonic-formaui-test-utils.d.ts.map +1 -0
- package/types/raintonic-formaui.d.ts +4 -0
- package/types/raintonic-formaui.d.ts.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raintonic-formaui-components-tooltip.mjs","sources":["../../../lib/components/tooltip/tooltip.types.ts","../../../lib/components/tooltip/tooltip.component.ts","../../../lib/components/tooltip/tooltip.component.html","../../../lib/components/tooltip/tooltip.directive.ts","../../../lib/components/tooltip/index.ts","../../../lib/components/tooltip/raintonic-formaui-components-tooltip.ts"],"sourcesContent":["/**\n * Available tooltip positions relative to the trigger element\n */\nexport type TooltipPosition =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'right'\n | 'right-start'\n | 'right-end';\n\n/**\n * Available tooltip sizes\n */\nexport type TooltipSize = 'sm' | 'md' | 'lg';\n\n/**\n * Tooltip trigger events\n */\nexport type TooltipTrigger = 'hover' | 'focus' | 'click' | 'manual';\n\n/**\n * Constants for validation\n */\nexport const TOOLTIP_POSITIONS = [\n 'top',\n 'top-start',\n 'top-end',\n 'bottom',\n 'bottom-start',\n 'bottom-end',\n 'left',\n 'left-start',\n 'left-end',\n 'right',\n 'right-start',\n 'right-end',\n] as const;\n\nexport const TOOLTIP_SIZES = ['sm', 'md', 'lg'] as const;\nexport const TOOLTIP_TRIGGERS = ['hover', 'focus', 'click', 'manual'] as const;\n\n/**\n * Tooltip configuration interface\n */\nexport interface TooltipConfig {\n position?: TooltipPosition;\n size?: TooltipSize;\n trigger?: TooltipTrigger;\n showDelay?: number;\n hideDelay?: number;\n disabled?: boolean;\n maxWidth?: string;\n offset?: number;\n arrow?: boolean;\n}\n","import { Component, input, computed, Signal, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';\n\nimport { TooltipPosition, TooltipSize } from './tooltip.types';\n\n/**\n * @component FuiTooltipComponent\n * @selector fui-tooltip\n * @description Internal tooltip component rendered by FuiTooltipDirective via the overlay system.\n * Not intended for direct use; created programmatically by the directive.\n *\n * @input content - (required) Tooltip text content.\n * @input position - (required) Tooltip position relative to the trigger element.\n * @input size - (required) Tooltip size variant.\n * @input maxWidth - (required) Maximum CSS width of the tooltip.\n * @input arrow - (required) Whether to render an arrow indicator.\n * @input tooltipId - (required) Unique ID for ARIA accessibility linking.\n *\n * @example\n * <!-- Used internally by FuiTooltipDirective -->\n * <button fuiTooltip=\"Save your changes\">Save</button>\n *\n * @internal\n */\n@Component({\n selector: 'fui-tooltip',\n standalone: true,\n imports: [],\n templateUrl: './tooltip.component.html',\n styleUrl: './tooltip.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'fui-tooltip',\n '[class]': 'computedClasses()',\n '[id]': 'tooltipId()',\n '[attr.role]': '\"tooltip\"',\n '[style.max-width]': 'maxWidth()',\n },\n})\nexport class FuiTooltipComponent {\n /**\n * Tooltip content text\n */\n readonly content = input.required<string>();\n\n /**\n * Tooltip position\n */\n readonly position = input.required<TooltipPosition>();\n\n /**\n * Tooltip size\n */\n readonly size = input.required<TooltipSize>();\n\n /**\n * Maximum width of the tooltip\n */\n readonly maxWidth = input.required<string>();\n\n /**\n * Whether to show arrow\n */\n readonly arrow = input.required<boolean>();\n\n /**\n * Tooltip ID for accessibility\n */\n readonly tooltipId = input.required<string>();\n\n /**\n * Computed CSS classes for the tooltip\n */\n readonly computedClasses: Signal<string> = computed(() => {\n const classes: string[] = ['fui-tooltip', `fui-tooltip--${this.size()}`, `fui-tooltip--${this.position()}`];\n\n if (this.arrow()) {\n classes.push('fui-tooltip--with-arrow');\n }\n\n return classes.join(' ');\n });\n\n /**\n * Computed arrow classes based on position\n */\n readonly arrowClasses: Signal<string> = computed(() => {\n const position = this.position();\n const baseClass = 'fui-tooltip__arrow';\n\n if (position.startsWith('top')) {\n return `${baseClass} ${baseClass}--bottom`;\n } else if (position.startsWith('bottom')) {\n return `${baseClass} ${baseClass}--top`;\n } else if (position.startsWith('left')) {\n return `${baseClass} ${baseClass}--right`;\n } else if (position.startsWith('right')) {\n return `${baseClass} ${baseClass}--left`;\n }\n\n return baseClass;\n });\n}\n","<div class=\"fui-tooltip__content\">\r\n {{ content() }}\r\n</div>\r\n@if (arrow()) {\r\n <div [class]=\"arrowClasses()\"></div>\r\n}\r\n","import {\n Directive,\n ElementRef,\n input,\n computed,\n effect,\n HostListener,\n inject,\n Signal,\n OnDestroy,\n booleanAttribute,\n numberAttribute,\n ComponentRef,\n createComponent,\n EnvironmentInjector,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport {\n TooltipPosition,\n TooltipSize,\n TooltipTrigger,\n TOOLTIP_POSITIONS,\n TOOLTIP_SIZES,\n TOOLTIP_TRIGGERS,\n} from './tooltip.types';\nimport { FuiTooltipComponent } from './tooltip.component';\nimport { FuiOverlayService, FuiOverlayRef, FuiConnectedPosition } from '@raintonic/formaui/cdk/overlay';\n\n/**\n * # Tooltip Directive\n *\n * A professional tooltip directive that provides contextual information on hover, focus, or click.\n * Follows Material Design patterns with full accessibility support and advanced positioning.\n *\n * ## Features\n * - Multiple positioning options (12 positions)\n * - Configurable trigger events (hover, focus, click, manual)\n * - Multiple variants for different semantic meanings\n * - Flexible sizing options\n * - Smart positioning with collision detection\n * - Customizable delays and animations\n * - Full accessibility support (ARIA attributes, keyboard navigation)\n * - Arrow indicator support\n * - Responsive design with max-width control\n * - Theme support (light/dark)\n *\n * ## Usage\n *\n * ### Basic Tooltip\n * ```html\n * <button fuiTooltip=\"Save your changes\">Save</button>\n * ```\n *\n * ### Advanced Configuration\n * ```html\n * <button fuiTooltip=\"Delete this item permanently\"\n * fuiTooltipPosition=\"top\"\n * fuiTooltipVariant=\"error\"\n * fuiTooltipSize=\"lg\"\n * [fuiTooltipShowDelay]=\"500\">\n * Delete\n * </button>\n * ```\n *\n * ### Click Trigger\n * ```html\n * <span fuiTooltip=\"Click to copy\"\n * fuiTooltipTrigger=\"click\"\n * fuiTooltipPosition=\"bottom\">\n * 📋 Copy to clipboard\n * </span>\n * ```\n *\n * ### Manual Control\n * ```html\n * <div fuiTooltip=\"Manual tooltip\"\n * fuiTooltipTrigger=\"manual\"\n * [fuiTooltipShow]=\"showTooltip\">\n * Hover me\n * </div>\n * ```\n *\n * @example\n * ```typescript\n * import { FuiTooltipDirective } from '@raintonic/formaui/components/tooltip';\n *\n * @Component({\n * standalone: true,\n * imports: [FuiTooltipDirective],\n * template: `\n * <button fuiTooltip=\"This will save your work\"\n * fuiTooltipPosition=\"top\"\n * fuiTooltipVariant=\"info\">\n * Save Document\n * </button>\n * `\n * })\n * export class MyComponent { }\n * ```\n */\n@Directive({\n selector: '[fuiTooltip]',\n standalone: true,\n host: {\n '[attr.aria-describedby]': 'isVisible() ? tooltipId() : null',\n },\n})\nexport class FuiTooltipDirective implements OnDestroy {\n private static _nextId = 0;\n /**\n * Tooltip content text\n */\n readonly fuiTooltip = input.required<string>();\n\n /**\n * Tooltip position relative to the trigger element\n * @default 'top'\n */\n readonly fuiTooltipPosition = input<TooltipPosition, TooltipPosition | string>('top', {\n transform: (v) => ((TOOLTIP_POSITIONS as readonly string[]).includes(v) ? (v as TooltipPosition) : 'top'),\n });\n\n /**\n * Tooltip size\n * @default 'md'\n */\n readonly fuiTooltipSize = input<TooltipSize, TooltipSize | string>('md', {\n transform: (v) => ((TOOLTIP_SIZES as readonly string[]).includes(v) ? (v as TooltipSize) : 'md'),\n });\n\n /**\n * Tooltip trigger event\n * @default 'hover'\n */\n readonly fuiTooltipTrigger = input<TooltipTrigger, TooltipTrigger | string>('hover', {\n transform: (v) => ((TOOLTIP_TRIGGERS as readonly string[]).includes(v) ? (v as TooltipTrigger) : 'hover'),\n });\n\n /**\n * Delay before showing tooltip (in milliseconds)\n * @default 500\n */\n readonly fuiTooltipShowDelay = input<number, unknown>(500, { transform: numberAttribute });\n\n /**\n * Delay before hiding tooltip (in milliseconds)\n * @default 0\n */\n readonly fuiTooltipHideDelay = input<number, unknown>(0, { transform: numberAttribute });\n\n /**\n * Whether the tooltip is disabled\n * @default false\n */\n readonly fuiTooltipDisabled = input<boolean, unknown>(false, { transform: booleanAttribute });\n\n /**\n * Maximum width of the tooltip\n * @default '200px'\n */\n readonly fuiTooltipMaxWidth = input('200px');\n\n /**\n * Offset distance from the trigger element (in pixels)\n * @default 8\n */\n readonly fuiTooltipOffset = input<number, unknown>(8, { transform: numberAttribute });\n\n /**\n * Whether to show an arrow pointing to the trigger element\n * @default true\n */\n readonly fuiTooltipArrow = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n /**\n * Manual control for showing/hiding tooltip (only works with trigger=\"manual\")\n * @default false\n */\n readonly fuiTooltipShow = input<boolean, unknown>(false, { transform: booleanAttribute });\n\n // Internal state\n private readonly _isVisible: WritableSignal<boolean> = signal(false);\n private readonly _tooltipId: WritableSignal<string> = signal('');\n private _overlayRef: FuiOverlayRef | null = null;\n private _tooltipComponent: ComponentRef<FuiTooltipComponent> | null = null;\n private _showTimeout: number | null = null;\n private _hideTimeout: number | null = null;\n private _isHoveringTooltip = false;\n\n // Computed properties\n readonly isVisible: Signal<boolean> = computed(() => this._isVisible());\n readonly tooltipId: Signal<string> = computed(() => this._tooltipId());\n\n // Injected dependencies\n private readonly _elementRef: ElementRef<HTMLElement> = inject(ElementRef);\n private readonly _overlayService: FuiOverlayService = inject(FuiOverlayService);\n private readonly _environmentInjector: EnvironmentInjector = inject(EnvironmentInjector);\n\n constructor() {\n // Generate unique tooltip ID\n this._tooltipId.set(`fui-tooltip-${FuiTooltipDirective._nextId++}`);\n\n // Handle manual control\n effect(() => {\n if (this.fuiTooltipTrigger() === 'manual') {\n if (this.fuiTooltipShow()) {\n this._showTooltip();\n } else {\n this._hideTooltip();\n }\n }\n });\n\n // Handle disabled state\n effect(() => {\n if (this.fuiTooltipDisabled() && this._isVisible()) {\n this._hideTooltip();\n }\n });\n }\n\n ngOnDestroy(): void {\n this._clearTimeouts();\n this._destroyTooltip();\n }\n\n @HostListener('mouseenter')\n onMouseEnter(): void {\n if (this.fuiTooltipTrigger() === 'hover' && !this.fuiTooltipDisabled()) {\n this._scheduleShow();\n }\n }\n\n @HostListener('mouseleave')\n onMouseLeave(): void {\n if (this.fuiTooltipTrigger() === 'hover' && !this.fuiTooltipDisabled()) {\n this._scheduleHide();\n }\n }\n\n @HostListener('focus')\n onFocus(): void {\n if ((this.fuiTooltipTrigger() === 'focus' || this.fuiTooltipTrigger() === 'hover') && !this.fuiTooltipDisabled()) {\n this._scheduleShow();\n }\n }\n\n @HostListener('blur')\n onBlur(): void {\n if ((this.fuiTooltipTrigger() === 'focus' || this.fuiTooltipTrigger() === 'hover') && !this.fuiTooltipDisabled()) {\n this._scheduleHide();\n }\n }\n\n @HostListener('click')\n onClick(): void {\n if (this.fuiTooltipTrigger() === 'click' && !this.fuiTooltipDisabled()) {\n if (this._isVisible()) {\n this._hideTooltip();\n } else {\n this._showTooltip();\n }\n }\n }\n\n @HostListener('keydown', ['$event'])\n onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape' && this._isVisible()) {\n this._hideTooltip();\n event.preventDefault();\n }\n }\n\n /**\n * Programmatically show the tooltip\n */\n show(): void {\n if (!this.fuiTooltipDisabled()) {\n this._showTooltip();\n }\n }\n\n /**\n * Programmatically hide the tooltip\n */\n hide(): void {\n this._hideTooltip();\n }\n\n /**\n * Toggle tooltip visibility\n */\n toggle(): void {\n if (this._isVisible()) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n private _scheduleShow(): void {\n this._clearTimeouts();\n\n if (this.fuiTooltipShowDelay() > 0) {\n this._showTimeout = window.setTimeout(() => {\n this._showTooltip();\n }, this.fuiTooltipShowDelay());\n } else {\n this._showTooltip();\n }\n }\n\n private _scheduleHide(): void {\n this._clearTimeouts();\n\n if (this.fuiTooltipHideDelay() > 0) {\n this._hideTimeout = window.setTimeout(() => {\n if (!this._isHoveringTooltip) {\n this._hideTooltip();\n }\n }, this.fuiTooltipHideDelay());\n } else {\n if (!this._isHoveringTooltip) {\n this._hideTooltip();\n }\n }\n }\n\n private _showTooltip(): void {\n if (this._isVisible() || this.fuiTooltipDisabled() || !this.fuiTooltip().trim()) {\n return;\n }\n\n this._createTooltip();\n this._isVisible.set(true);\n\n // Add click outside listener for click trigger\n if (this.fuiTooltipTrigger() === 'click') {\n setTimeout(() => {\n document.addEventListener('click', this._onDocumentClick, true);\n });\n }\n }\n\n private _hideTooltip(): void {\n if (!this._isVisible()) {\n return;\n }\n\n this._isVisible.set(false);\n this._destroyTooltip();\n document.removeEventListener('click', this._onDocumentClick, true);\n }\n\n private _createTooltip(): void {\n if (this._overlayRef) {\n return;\n }\n\n // Create tooltip component first\n this._tooltipComponent = createComponent(FuiTooltipComponent, {\n environmentInjector: this._environmentInjector,\n });\n\n // Set tooltip properties immediately\n this._tooltipComponent.setInput('content', this.fuiTooltip());\n this._tooltipComponent.setInput('position', this.fuiTooltipPosition());\n this._tooltipComponent.setInput('size', this.fuiTooltipSize());\n this._tooltipComponent.setInput('maxWidth', this.fuiTooltipMaxWidth());\n this._tooltipComponent.setInput('arrow', this.fuiTooltipArrow());\n this._tooltipComponent.setInput('tooltipId', this.tooltipId());\n\n // Trigger change detection to ensure component is rendered with correct props\n this._tooltipComponent.changeDetectorRef.detectChanges();\n\n // Now create overlay with positioning strategy\n const positions = this._getPositionsForTooltipPosition(this.fuiTooltipPosition());\n const positionStrategy = this._overlayService\n .position()\n .connectedTo(this._elementRef, positions)\n .withPush(true)\n .withViewportMargin(8);\n\n // Create overlay\n this._overlayRef = this._overlayService.create({\n positionStrategy,\n scrollStrategy: this._overlayService.scrollStrategies.reposition(20),\n panelClass: 'fui-tooltip-panel',\n });\n\n // Attach component to overlay\n this._overlayRef.attach(this._tooltipComponent);\n\n // Set up hover events for tooltip persistence\n const tooltipElement = this._tooltipComponent.location.nativeElement;\n\n tooltipElement.addEventListener('mouseenter', () => {\n this._isHoveringTooltip = true;\n this._clearTimeouts();\n });\n\n tooltipElement.addEventListener('mouseleave', () => {\n this._isHoveringTooltip = false;\n if (this.fuiTooltipTrigger() === 'hover') {\n this._scheduleHide();\n }\n });\n }\n\n private _getPositionsForTooltipPosition(position: TooltipPosition): FuiConnectedPosition[] {\n const offset = this.fuiTooltipOffset();\n const positionMap: Record<TooltipPosition, FuiConnectedPosition[]> = {\n top: [\n { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -offset },\n { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: offset },\n ],\n 'top-start': [\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -offset },\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: offset },\n ],\n 'top-end': [\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -offset },\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: offset },\n ],\n bottom: [\n { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: offset },\n { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -offset },\n ],\n 'bottom-start': [\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: offset },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -offset },\n ],\n 'bottom-end': [\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: offset },\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -offset },\n ],\n left: [\n { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -offset },\n { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: offset },\n ],\n 'left-start': [\n { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top', offsetX: -offset },\n { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'top', offsetX: offset },\n ],\n 'left-end': [\n { originX: 'start', originY: 'bottom', overlayX: 'end', overlayY: 'bottom', offsetX: -offset },\n { originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'bottom', offsetX: offset },\n ],\n right: [\n { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: offset },\n { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -offset },\n ],\n 'right-start': [\n { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'top', offsetX: offset },\n { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top', offsetX: -offset },\n ],\n 'right-end': [\n { originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'bottom', offsetX: offset },\n { originX: 'start', originY: 'bottom', overlayX: 'end', overlayY: 'bottom', offsetX: -offset },\n ],\n };\n\n return positionMap[position] || positionMap.top;\n }\n\n private _destroyTooltip(): void {\n if (this._overlayRef) {\n this._overlayRef.dispose();\n this._overlayRef = null;\n }\n\n if (this._tooltipComponent) {\n this._tooltipComponent.destroy();\n this._tooltipComponent = null;\n }\n }\n\n private _clearTimeouts(): void {\n if (this._showTimeout) {\n clearTimeout(this._showTimeout);\n this._showTimeout = null;\n }\n if (this._hideTimeout) {\n clearTimeout(this._hideTimeout);\n this._hideTimeout = null;\n }\n }\n\n private readonly _onDocumentClick = (event: Event): void => {\n const target = event.target as HTMLElement;\n const triggerElement = this._elementRef.nativeElement;\n const tooltipElement = this._tooltipComponent?.location.nativeElement;\n\n if (target && !triggerElement.contains(target) && !tooltipElement?.contains(target)) {\n this._hideTooltip();\n }\n };\n}\n","// Public API for tooltip component\nexport * from './tooltip.directive';\nexport * from './tooltip.component';\nexport * from './tooltip.types';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, signal, computed, inject, ElementRef, forwardRef, ViewChild, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
|
+
import { Subject } from 'rxjs';
|
|
5
|
+
import { FUI_FORM_FIELD_CONTROL } from '@raintonic/formaui/core';
|
|
6
|
+
import { injectNgControl } from '@raintonic/formaui/cdk/form-field';
|
|
7
|
+
import { FuiTreeComponent } from '@raintonic/formaui/components/tree';
|
|
8
|
+
import { FuiIconComponent } from '@raintonic/formaui/components/icon';
|
|
9
|
+
import { FuiBadgeComponent } from '@raintonic/formaui/components/badge';
|
|
10
|
+
import { FuiOverlayService } from '@raintonic/formaui/cdk/overlay';
|
|
11
|
+
|
|
12
|
+
let nextId = 0;
|
|
13
|
+
class FuiTreeSelectComponent {
|
|
14
|
+
// Public API
|
|
15
|
+
nodes = input.required(...(ngDevMode ? [{ debugName: "nodes" }] : /* istanbul ignore next */ []));
|
|
16
|
+
selectionMode = input('single', ...(ngDevMode ? [{ debugName: "selectionMode" }] : /* istanbul ignore next */ []));
|
|
17
|
+
placeholderInput = input('', { ...(ngDevMode ? { debugName: "placeholderInput" } : /* istanbul ignore next */ {}), alias: 'placeholder' });
|
|
18
|
+
showSearch = input(false, ...(ngDevMode ? [{ debugName: "showSearch" }] : /* istanbul ignore next */ []));
|
|
19
|
+
loadChildren = input(null, ...(ngDevMode ? [{ debugName: "loadChildren" }] : /* istanbul ignore next */ []));
|
|
20
|
+
nodeTemplate = input(null, ...(ngDevMode ? [{ debugName: "nodeTemplate" }] : /* istanbul ignore next */ []));
|
|
21
|
+
displayField = input(null, ...(ngDevMode ? [{ debugName: "displayField" }] : /* istanbul ignore next */ []));
|
|
22
|
+
disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled' });
|
|
23
|
+
selectionChange = output();
|
|
24
|
+
// FuiFormFieldControl implementation
|
|
25
|
+
stateChanges = new Subject();
|
|
26
|
+
_value = signal(null, ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
27
|
+
value = this._value;
|
|
28
|
+
placeholder = computed(() => this.placeholderInput(), ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
29
|
+
focused = signal(false, ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
|
|
30
|
+
empty = computed(() => {
|
|
31
|
+
const v = this._value();
|
|
32
|
+
return v === null || v === undefined || (Array.isArray(v) && v.length === 0);
|
|
33
|
+
}, ...(ngDevMode ? [{ debugName: "empty" }] : /* istanbul ignore next */ []));
|
|
34
|
+
required = signal(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
35
|
+
_disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
|
|
36
|
+
disabled = computed(() => this._disabled() || this.disabledInput(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
37
|
+
errorState = signal(false, ...(ngDevMode ? [{ debugName: "errorState" }] : /* istanbul ignore next */ []));
|
|
38
|
+
controlType = 'fui-tree-select';
|
|
39
|
+
id = `fui-tree-select-${nextId++}`;
|
|
40
|
+
// Internal
|
|
41
|
+
_panelOpen = signal(false, ...(ngDevMode ? [{ debugName: "_panelOpen" }] : /* istanbul ignore next */ []));
|
|
42
|
+
_treeId = `${this.id}-tree`;
|
|
43
|
+
_searchFilter = signal('', ...(ngDevMode ? [{ debugName: "_searchFilter" }] : /* istanbul ignore next */ []));
|
|
44
|
+
_overlayRef = null;
|
|
45
|
+
_ngControlRef = injectNgControl();
|
|
46
|
+
get ngControl() {
|
|
47
|
+
return this._ngControlRef.ngControl;
|
|
48
|
+
}
|
|
49
|
+
_overlayService = inject(FuiOverlayService);
|
|
50
|
+
_elementRef = inject(ElementRef);
|
|
51
|
+
// Track selected nodes internally
|
|
52
|
+
_selectedNodes = signal([], ...(ngDevMode ? [{ debugName: "_selectedNodes" }] : /* istanbul ignore next */ []));
|
|
53
|
+
trigger;
|
|
54
|
+
panel;
|
|
55
|
+
// CVA callbacks
|
|
56
|
+
_onChange = () => {
|
|
57
|
+
/* noop */
|
|
58
|
+
};
|
|
59
|
+
_onTouched = () => {
|
|
60
|
+
/* noop */
|
|
61
|
+
};
|
|
62
|
+
constructor() {
|
|
63
|
+
void Promise.resolve().then(() => {
|
|
64
|
+
if (this._ngControlRef.ngControl) {
|
|
65
|
+
this._ngControlRef.ngControl.valueAccessor = this;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
// Methods
|
|
70
|
+
toggle() {
|
|
71
|
+
if (this._panelOpen()) {
|
|
72
|
+
this.close();
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.open();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
open() {
|
|
79
|
+
if (this.disabled() || this._panelOpen())
|
|
80
|
+
return;
|
|
81
|
+
requestAnimationFrame(() => {
|
|
82
|
+
this._panelOpen.set(true);
|
|
83
|
+
this.focused.set(true);
|
|
84
|
+
this.stateChanges.next();
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
this._createOverlay();
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
close() {
|
|
91
|
+
if (!this._panelOpen())
|
|
92
|
+
return;
|
|
93
|
+
this._panelOpen.set(false);
|
|
94
|
+
this.focused.set(false);
|
|
95
|
+
this._searchFilter.set('');
|
|
96
|
+
this._disposeOverlay();
|
|
97
|
+
this._onTouched();
|
|
98
|
+
this.stateChanges.next();
|
|
99
|
+
}
|
|
100
|
+
onContainerClick(_event) {
|
|
101
|
+
this.toggle();
|
|
102
|
+
}
|
|
103
|
+
setDescribedByIds(_ids) {
|
|
104
|
+
/* no-op for now */
|
|
105
|
+
}
|
|
106
|
+
// Tree selection handlers
|
|
107
|
+
_onTreeSelect(event) {
|
|
108
|
+
const node = event.node;
|
|
109
|
+
if (this.selectionMode() === 'single') {
|
|
110
|
+
// Deselect all first, then select clicked
|
|
111
|
+
this._deselectAll(this.nodes());
|
|
112
|
+
node.selected = true;
|
|
113
|
+
this._selectedNodes.set([node]);
|
|
114
|
+
this._value.set(node.data);
|
|
115
|
+
this._onChange(node.data);
|
|
116
|
+
this.selectionChange.emit({ value: node, source: this });
|
|
117
|
+
this.stateChanges.next();
|
|
118
|
+
this.close();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
node.selected = !node.selected;
|
|
122
|
+
this._updateMultiSelection();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
_onTreeUnselect(event) {
|
|
126
|
+
event.node.selected = false;
|
|
127
|
+
if (this.selectionMode() === 'single') {
|
|
128
|
+
this._selectedNodes.set([]);
|
|
129
|
+
this._value.set(null);
|
|
130
|
+
this._onChange(null);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
this._updateMultiSelection();
|
|
134
|
+
}
|
|
135
|
+
this.stateChanges.next();
|
|
136
|
+
}
|
|
137
|
+
_getDisplayValue() {
|
|
138
|
+
const nodes = this._selectedNodes();
|
|
139
|
+
if (nodes.length === 0)
|
|
140
|
+
return '';
|
|
141
|
+
return this._getNodeLabel(nodes[0]);
|
|
142
|
+
}
|
|
143
|
+
_getSelectedDisplayValues() {
|
|
144
|
+
return this._selectedNodes().map((n) => this._getNodeLabel(n));
|
|
145
|
+
}
|
|
146
|
+
_onSearchInput(event) {
|
|
147
|
+
const value = event.target.value;
|
|
148
|
+
this._searchFilter.set(value);
|
|
149
|
+
}
|
|
150
|
+
_onKeydown(event) {
|
|
151
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
152
|
+
if (!this._panelOpen()) {
|
|
153
|
+
event.preventDefault();
|
|
154
|
+
this.open();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (event.key === 'Escape') {
|
|
158
|
+
if (this._panelOpen()) {
|
|
159
|
+
event.preventDefault();
|
|
160
|
+
this.close();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
_treeSelectionMode = computed(() => {
|
|
165
|
+
return this.selectionMode();
|
|
166
|
+
}, ...(ngDevMode ? [{ debugName: "_treeSelectionMode" }] : /* istanbul ignore next */ []));
|
|
167
|
+
// CVA
|
|
168
|
+
writeValue(value) {
|
|
169
|
+
this._value.set(value);
|
|
170
|
+
this._syncSelectedFromValue(value);
|
|
171
|
+
this.stateChanges.next();
|
|
172
|
+
}
|
|
173
|
+
registerOnChange(fn) {
|
|
174
|
+
this._onChange = fn;
|
|
175
|
+
}
|
|
176
|
+
registerOnTouched(fn) {
|
|
177
|
+
this._onTouched = fn;
|
|
178
|
+
}
|
|
179
|
+
setDisabledState(disabled) {
|
|
180
|
+
this._disabled.set(disabled);
|
|
181
|
+
this.stateChanges.next();
|
|
182
|
+
}
|
|
183
|
+
ngOnDestroy() {
|
|
184
|
+
this._disposeOverlay();
|
|
185
|
+
this.stateChanges.complete();
|
|
186
|
+
}
|
|
187
|
+
ngDoCheck() {
|
|
188
|
+
if (this.ngControl) {
|
|
189
|
+
const control = this.ngControl.control;
|
|
190
|
+
if (control) {
|
|
191
|
+
const isInvalid = control.invalid && (control.touched || false);
|
|
192
|
+
this.errorState.set(isInvalid);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Private helpers
|
|
197
|
+
_getNodeLabel(node) {
|
|
198
|
+
const displayFn = this.displayField();
|
|
199
|
+
if (typeof displayFn === 'function')
|
|
200
|
+
return displayFn(node);
|
|
201
|
+
if (typeof displayFn === 'string' && node.data && typeof node.data === 'object') {
|
|
202
|
+
return String(node.data[displayFn] ?? '');
|
|
203
|
+
}
|
|
204
|
+
return String(node.data ?? '');
|
|
205
|
+
}
|
|
206
|
+
_deselectAll(nodes) {
|
|
207
|
+
for (const n of nodes) {
|
|
208
|
+
n.selected = false;
|
|
209
|
+
if (Array.isArray(n.children))
|
|
210
|
+
this._deselectAll(n.children);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
_updateMultiSelection() {
|
|
214
|
+
const selected = this._collectSelected(this.nodes());
|
|
215
|
+
this._selectedNodes.set(selected);
|
|
216
|
+
const values = selected.map((n) => n.data);
|
|
217
|
+
this._value.set(values);
|
|
218
|
+
this._onChange(values);
|
|
219
|
+
this.selectionChange.emit({ value: selected, source: this });
|
|
220
|
+
this.stateChanges.next();
|
|
221
|
+
}
|
|
222
|
+
_collectSelected(nodes) {
|
|
223
|
+
const result = [];
|
|
224
|
+
for (const n of nodes) {
|
|
225
|
+
if (n.selected)
|
|
226
|
+
result.push(n);
|
|
227
|
+
if (Array.isArray(n.children))
|
|
228
|
+
result.push(...this._collectSelected(n.children));
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
_syncSelectedFromValue(value) {
|
|
233
|
+
if (value === null || value === undefined) {
|
|
234
|
+
this._deselectAll(this.nodes());
|
|
235
|
+
this._selectedNodes.set([]);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
// For now, leave nodes as-is since the consumer controls node.selected
|
|
239
|
+
}
|
|
240
|
+
_createOverlay() {
|
|
241
|
+
if (this._overlayRef || !this.panel)
|
|
242
|
+
return;
|
|
243
|
+
const triggerElement = this._elementRef.nativeElement;
|
|
244
|
+
const triggerWidth = triggerElement.getBoundingClientRect().width;
|
|
245
|
+
const positions = [
|
|
246
|
+
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
247
|
+
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
248
|
+
];
|
|
249
|
+
const positionStrategy = this._overlayService
|
|
250
|
+
.position()
|
|
251
|
+
.connectedTo(triggerElement, positions)
|
|
252
|
+
.withPush(true)
|
|
253
|
+
.withViewportMargin(8);
|
|
254
|
+
this._overlayRef = this._overlayService.create({
|
|
255
|
+
positionStrategy,
|
|
256
|
+
scrollStrategy: this._overlayService.scrollStrategies.reposition(),
|
|
257
|
+
hasBackdrop: true,
|
|
258
|
+
backdropClass: 'fui-tree-select-backdrop',
|
|
259
|
+
backdropClickBehavior: 'close',
|
|
260
|
+
panelClass: ['fui-tree-select-overlay-panel'],
|
|
261
|
+
minWidth: triggerWidth,
|
|
262
|
+
});
|
|
263
|
+
this._overlayRef.backdropClick.subscribe(() => {
|
|
264
|
+
this.close();
|
|
265
|
+
});
|
|
266
|
+
this._overlayRef.keydownEvents.subscribe((event) => {
|
|
267
|
+
if (event.key === 'Escape')
|
|
268
|
+
this.close();
|
|
269
|
+
});
|
|
270
|
+
this._overlayRef.attach(this.panel.nativeElement);
|
|
271
|
+
}
|
|
272
|
+
_disposeOverlay() {
|
|
273
|
+
if (this._overlayRef) {
|
|
274
|
+
this._overlayRef.dispose();
|
|
275
|
+
this._overlayRef = null;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiTreeSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
279
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiTreeSelectComponent, isStandalone: true, selector: "fui-tree-select", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: true, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, placeholderInput: { classPropertyName: "placeholderInput", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, loadChildren: { classPropertyName: "loadChildren", publicName: "loadChildren", isSignal: true, isRequired: false, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, displayField: { classPropertyName: "displayField", publicName: "displayField", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { attributes: { "role": "combobox", "tabindex": "0" }, listeners: { "click": "toggle()", "keydown": "_onKeydown($event)" }, properties: { "attr.aria-expanded": "_panelOpen()", "attr.aria-haspopup": "\"tree\"", "attr.aria-owns": "_panelOpen() ? _treeId : null", "class.fui-tree-select--open": "_panelOpen()", "class.fui-tree-select--disabled": "disabled()" }, classAttribute: "fui-tree-select" }, providers: [
|
|
280
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FuiTreeSelectComponent), multi: true },
|
|
281
|
+
{ provide: FUI_FORM_FIELD_CONTROL, useExisting: forwardRef(() => FuiTreeSelectComponent) },
|
|
282
|
+
], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true }, { propertyName: "panel", first: true, predicate: ["panel"], descendants: true }], ngImport: i0, template: "<!-- Trigger area -->\n<div class=\"fui-tree-select__trigger\" #trigger>\n @if (empty()) {\n <span class=\"fui-tree-select__placeholder\">{{ placeholder() }}</span>\n } @else if (selectionMode() === 'single') {\n <span class=\"fui-tree-select__value\">{{ _getDisplayValue() }}</span>\n } @else {\n <div class=\"fui-tree-select__tags\">\n @for (tag of _getSelectedDisplayValues(); track tag) {\n <fui-badge [label]=\"tag\" size=\"sm\" variant=\"secondary\"></fui-badge>\n }\n </div>\n }\n <fui-icon class=\"fui-tree-select__arrow\" [name]=\"_panelOpen() ? 'caret-up' : 'caret-down'\" size=\"sm\"></fui-icon>\n</div>\n\n<!-- Panel (rendered always but hidden, moved to overlay when open) -->\n<div class=\"fui-tree-select__panel\" [id]=\"_treeId\" #panel [style.display]=\"_panelOpen() ? '' : 'none'\">\n @if (showSearch()) {\n <div class=\"fui-tree-select__search\">\n <input\n class=\"fui-tree-select__search-input\"\n type=\"text\"\n placeholder=\"Search...\"\n (input)=\"_onSearchInput($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n </div>\n }\n <fui-tree\n [nodes]=\"nodes()\"\n [selectionMode]=\"_treeSelectionMode()\"\n [loadChildren]=\"loadChildren()\"\n [nodeTemplate]=\"nodeTemplate()\"\n [filter]=\"_searchFilter()\"\n (nodeSelect)=\"_onTreeSelect($event)\"\n (nodeUnselect)=\"_onTreeUnselect($event)\"\n >\n </fui-tree>\n</div>\n", styles: [".fui-tree-select{display:inline-flex;align-items:center;width:100%;min-height:40px;padding:8px 12px;border:1px solid var(--fui-border-color);border-radius:var(--fui-border-radius-sm);background:var(--fui-field-background);cursor:pointer;outline:none;font-family:var(--fui-font-family);font-size:var(--fui-font-size-03);transition:border-color var(--fui-duration-moderate-01) var(--fui-ease-standard)}.fui-tree-select:hover{border-color:var(--fui-primary-60)}.fui-tree-select:focus{outline:2px solid var(--fui-primary-60);outline-offset:-2px}.fui-tree-select--disabled{opacity:.5;pointer-events:none}.fui-tree-select--open{border-color:var(--fui-primary-60)}.fui-tree-select__trigger{display:flex;align-items:center;width:100%;gap:8px}.fui-tree-select__placeholder{color:var(--fui-text-disabled);flex:1}.fui-tree-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-tree-select__tags{display:flex;flex-wrap:wrap;gap:4px;flex:1}.fui-tree-select__arrow{flex-shrink:0;color:var(--fui-text-secondary);transition:transform var(--fui-duration-moderate-01) var(--fui-ease-standard)}.fui-tree-select__panel{background:var(--fui-surface-card);border:1px solid var(--fui-border-color);border-radius:var(--fui-border-radius-sm);box-shadow:var(--fui-shadow-04);max-height:300px;overflow:auto}.fui-tree-select__search{padding:8px;border-bottom:1px solid var(--fui-border-color)}.fui-tree-select__search-input{width:100%;padding:4px 8px;border:1px solid var(--fui-border-color);border-radius:var(--fui-border-radius-sm);font-family:var(--fui-font-family);font-size:var(--fui-font-size-02);outline:none;background:var(--fui-field-background)}.fui-tree-select__search-input:focus{border-color:var(--fui-primary-60)}.fui-tree-select-backdrop{background:transparent}\n"], dependencies: [{ kind: "component", type: FuiTreeComponent, selector: "fui-tree", inputs: ["nodes", "selectionMode", "loadChildren", "nodeTemplate", "draggable", "virtualScroll", "virtualItemSize", "filter"], outputs: ["nodeSelect", "nodeUnselect", "nodeExpand", "nodeCollapse", "nodeDrop", "filterChange"] }, { kind: "component", type: FuiIconComponent, selector: "fui-icon", inputs: ["name", "size", "weight", "color", "ariaLabel", "spin", "pulse"] }, { kind: "component", type: FuiBadgeComponent, selector: "fui-badge", inputs: ["label", "icon", "customColor", "size", "variant", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
283
|
+
}
|
|
284
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiTreeSelectComponent, decorators: [{
|
|
285
|
+
type: Component,
|
|
286
|
+
args: [{ selector: 'fui-tree-select', standalone: true, imports: [FuiTreeComponent, FuiIconComponent, FuiBadgeComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
287
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FuiTreeSelectComponent), multi: true },
|
|
288
|
+
{ provide: FUI_FORM_FIELD_CONTROL, useExisting: forwardRef(() => FuiTreeSelectComponent) },
|
|
289
|
+
], host: {
|
|
290
|
+
class: 'fui-tree-select',
|
|
291
|
+
role: 'combobox',
|
|
292
|
+
'[attr.aria-expanded]': '_panelOpen()',
|
|
293
|
+
'[attr.aria-haspopup]': '"tree"',
|
|
294
|
+
'[attr.aria-owns]': '_panelOpen() ? _treeId : null',
|
|
295
|
+
'[class.fui-tree-select--open]': '_panelOpen()',
|
|
296
|
+
'[class.fui-tree-select--disabled]': 'disabled()',
|
|
297
|
+
'(click)': 'toggle()',
|
|
298
|
+
'(keydown)': '_onKeydown($event)',
|
|
299
|
+
tabindex: '0',
|
|
300
|
+
}, template: "<!-- Trigger area -->\n<div class=\"fui-tree-select__trigger\" #trigger>\n @if (empty()) {\n <span class=\"fui-tree-select__placeholder\">{{ placeholder() }}</span>\n } @else if (selectionMode() === 'single') {\n <span class=\"fui-tree-select__value\">{{ _getDisplayValue() }}</span>\n } @else {\n <div class=\"fui-tree-select__tags\">\n @for (tag of _getSelectedDisplayValues(); track tag) {\n <fui-badge [label]=\"tag\" size=\"sm\" variant=\"secondary\"></fui-badge>\n }\n </div>\n }\n <fui-icon class=\"fui-tree-select__arrow\" [name]=\"_panelOpen() ? 'caret-up' : 'caret-down'\" size=\"sm\"></fui-icon>\n</div>\n\n<!-- Panel (rendered always but hidden, moved to overlay when open) -->\n<div class=\"fui-tree-select__panel\" [id]=\"_treeId\" #panel [style.display]=\"_panelOpen() ? '' : 'none'\">\n @if (showSearch()) {\n <div class=\"fui-tree-select__search\">\n <input\n class=\"fui-tree-select__search-input\"\n type=\"text\"\n placeholder=\"Search...\"\n (input)=\"_onSearchInput($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n </div>\n }\n <fui-tree\n [nodes]=\"nodes()\"\n [selectionMode]=\"_treeSelectionMode()\"\n [loadChildren]=\"loadChildren()\"\n [nodeTemplate]=\"nodeTemplate()\"\n [filter]=\"_searchFilter()\"\n (nodeSelect)=\"_onTreeSelect($event)\"\n (nodeUnselect)=\"_onTreeUnselect($event)\"\n >\n </fui-tree>\n</div>\n", styles: [".fui-tree-select{display:inline-flex;align-items:center;width:100%;min-height:40px;padding:8px 12px;border:1px solid var(--fui-border-color);border-radius:var(--fui-border-radius-sm);background:var(--fui-field-background);cursor:pointer;outline:none;font-family:var(--fui-font-family);font-size:var(--fui-font-size-03);transition:border-color var(--fui-duration-moderate-01) var(--fui-ease-standard)}.fui-tree-select:hover{border-color:var(--fui-primary-60)}.fui-tree-select:focus{outline:2px solid var(--fui-primary-60);outline-offset:-2px}.fui-tree-select--disabled{opacity:.5;pointer-events:none}.fui-tree-select--open{border-color:var(--fui-primary-60)}.fui-tree-select__trigger{display:flex;align-items:center;width:100%;gap:8px}.fui-tree-select__placeholder{color:var(--fui-text-disabled);flex:1}.fui-tree-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-tree-select__tags{display:flex;flex-wrap:wrap;gap:4px;flex:1}.fui-tree-select__arrow{flex-shrink:0;color:var(--fui-text-secondary);transition:transform var(--fui-duration-moderate-01) var(--fui-ease-standard)}.fui-tree-select__panel{background:var(--fui-surface-card);border:1px solid var(--fui-border-color);border-radius:var(--fui-border-radius-sm);box-shadow:var(--fui-shadow-04);max-height:300px;overflow:auto}.fui-tree-select__search{padding:8px;border-bottom:1px solid var(--fui-border-color)}.fui-tree-select__search-input{width:100%;padding:4px 8px;border:1px solid var(--fui-border-color);border-radius:var(--fui-border-radius-sm);font-family:var(--fui-font-family);font-size:var(--fui-font-size-02);outline:none;background:var(--fui-field-background)}.fui-tree-select__search-input:focus{border-color:var(--fui-primary-60)}.fui-tree-select-backdrop{background:transparent}\n"] }]
|
|
301
|
+
}], ctorParameters: () => [], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: true }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], placeholderInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], showSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSearch", required: false }] }], loadChildren: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadChildren", required: false }] }], nodeTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeTemplate", required: false }] }], displayField: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayField", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], trigger: [{
|
|
302
|
+
type: ViewChild,
|
|
303
|
+
args: ['trigger', { static: false }]
|
|
304
|
+
}], panel: [{
|
|
305
|
+
type: ViewChild,
|
|
306
|
+
args: ['panel', { static: false }]
|
|
307
|
+
}] } });
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Generated bundle index. Do not edit.
|
|
311
|
+
*/
|
|
312
|
+
|
|
313
|
+
export { FuiTreeSelectComponent };
|
|
314
|
+
//# sourceMappingURL=raintonic-formaui-components-tree-select.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raintonic-formaui-components-tree-select.mjs","sources":["../../../lib/components/tree-select/fui-tree-select.component.ts","../../../lib/components/tree-select/fui-tree-select.component.html","../../../lib/components/tree-select/raintonic-formaui-components-tree-select.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DoCheck,\n ElementRef,\n forwardRef,\n inject,\n input,\n OnDestroy,\n output,\n signal,\n Signal,\n TemplateRef,\n ViewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';\nimport { Observable, Subject } from 'rxjs';\nimport { FUI_FORM_FIELD_CONTROL, FuiFormFieldControl } from '@raintonic/formaui/core';\nimport { injectNgControl } from '@raintonic/formaui/cdk/form-field';\nimport { FuiTreeComponent, FuiTreeNode, FuiTreeNodeEvent, FuiTreeSelectionMode } from '@raintonic/formaui/components/tree';\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\nimport { FuiBadgeComponent } from '@raintonic/formaui/components/badge';\nimport { FuiConnectedPosition, FuiOverlayRef, FuiOverlayService } from '@raintonic/formaui/cdk/overlay';\nimport { FuiTreeSelectChange } from './tree-select.types';\n\nlet nextId = 0;\n\n@Component({\n selector: 'fui-tree-select',\n standalone: true,\n imports: [FuiTreeComponent, FuiIconComponent, FuiBadgeComponent],\n templateUrl: './fui-tree-select.component.html',\n styleUrl: './fui-tree-select.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n providers: [\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FuiTreeSelectComponent), multi: true },\n { provide: FUI_FORM_FIELD_CONTROL, useExisting: forwardRef(() => FuiTreeSelectComponent) },\n ],\n host: {\n class: 'fui-tree-select',\n role: 'combobox',\n '[attr.aria-expanded]': '_panelOpen()',\n '[attr.aria-haspopup]': '\"tree\"',\n '[attr.aria-owns]': '_panelOpen() ? _treeId : null',\n '[class.fui-tree-select--open]': '_panelOpen()',\n '[class.fui-tree-select--disabled]': 'disabled()',\n '(click)': 'toggle()',\n '(keydown)': '_onKeydown($event)',\n tabindex: '0',\n },\n})\nexport class FuiTreeSelectComponent<T = any>\n implements ControlValueAccessor, FuiFormFieldControl<T | T[]>, OnDestroy, DoCheck\n{\n // Public API\n readonly nodes = input.required<FuiTreeNode<T>[]>();\n readonly selectionMode = input<'single' | 'multi' | 'checkbox'>('single');\n readonly placeholderInput = input('', { alias: 'placeholder' });\n readonly showSearch = input(false);\n readonly loadChildren = input<((node: FuiTreeNode<T>) => Observable<FuiTreeNode<T>[]>) | null>(null);\n readonly nodeTemplate = input<TemplateRef<any> | null>(null);\n readonly displayField = input<string | ((node: FuiTreeNode<T>) => string) | null>(null);\n readonly disabledInput = input(false, { alias: 'disabled' });\n\n readonly selectionChange = output<FuiTreeSelectChange<T>>();\n\n // FuiFormFieldControl implementation\n readonly stateChanges = new Subject<void>();\n private readonly _value = signal<T | T[] | null>(null);\n readonly value: Signal<T | T[] | null> = this._value;\n readonly placeholder = computed(() => this.placeholderInput());\n readonly focused = signal(false);\n readonly empty = computed(() => {\n const v = this._value();\n return v === null || v === undefined || (Array.isArray(v) && v.length === 0);\n });\n readonly required = signal(false);\n private readonly _disabled = signal(false);\n readonly disabled = computed(() => this._disabled() || this.disabledInput());\n readonly errorState = signal(false);\n readonly controlType = 'fui-tree-select';\n readonly id = `fui-tree-select-${nextId++}`;\n\n // Internal\n readonly _panelOpen = signal(false);\n readonly _treeId = `${this.id}-tree`;\n readonly _searchFilter = signal('');\n private _overlayRef: FuiOverlayRef | null = null;\n private readonly _ngControlRef = injectNgControl();\n get ngControl(): NgControl | null {\n return this._ngControlRef.ngControl;\n }\n\n private readonly _overlayService = inject(FuiOverlayService);\n private readonly _elementRef = inject(ElementRef);\n\n // Track selected nodes internally\n readonly _selectedNodes = signal<FuiTreeNode<T>[]>([]);\n\n @ViewChild('trigger', { static: false }) trigger?: ElementRef<HTMLDivElement>;\n @ViewChild('panel', { static: false }) panel?: ElementRef<HTMLDivElement>;\n\n // CVA callbacks\n private _onChange: (value: any) => void = () => {\n /* noop */\n };\n private _onTouched: () => void = () => {\n /* noop */\n };\n\n constructor() {\n void Promise.resolve().then(() => {\n if (this._ngControlRef.ngControl) {\n this._ngControlRef.ngControl.valueAccessor = this;\n }\n });\n }\n\n // Methods\n toggle(): void {\n if (this._panelOpen()) {\n this.close();\n } else {\n this.open();\n }\n }\n\n open(): void {\n if (this.disabled() || this._panelOpen()) return;\n requestAnimationFrame(() => {\n this._panelOpen.set(true);\n this.focused.set(true);\n this.stateChanges.next();\n setTimeout(() => {\n this._createOverlay();\n });\n });\n }\n\n close(): void {\n if (!this._panelOpen()) return;\n this._panelOpen.set(false);\n this.focused.set(false);\n this._searchFilter.set('');\n this._disposeOverlay();\n this._onTouched();\n this.stateChanges.next();\n }\n\n onContainerClick(_event: MouseEvent): void {\n this.toggle();\n }\n\n setDescribedByIds(_ids: string[]): void {\n /* no-op for now */\n }\n\n // Tree selection handlers\n _onTreeSelect(event: FuiTreeNodeEvent<T>): void {\n const node = event.node;\n if (this.selectionMode() === 'single') {\n // Deselect all first, then select clicked\n this._deselectAll(this.nodes());\n node.selected = true;\n this._selectedNodes.set([node]);\n this._value.set(node.data);\n this._onChange(node.data);\n this.selectionChange.emit({ value: node, source: this });\n this.stateChanges.next();\n this.close();\n } else {\n node.selected = !node.selected;\n this._updateMultiSelection();\n }\n }\n\n _onTreeUnselect(event: FuiTreeNodeEvent<T>): void {\n event.node.selected = false;\n if (this.selectionMode() === 'single') {\n this._selectedNodes.set([]);\n this._value.set(null);\n this._onChange(null);\n } else {\n this._updateMultiSelection();\n }\n this.stateChanges.next();\n }\n\n _getDisplayValue(): string {\n const nodes = this._selectedNodes();\n if (nodes.length === 0) return '';\n return this._getNodeLabel(nodes[0]);\n }\n\n _getSelectedDisplayValues(): string[] {\n return this._selectedNodes().map((n) => this._getNodeLabel(n));\n }\n\n _onSearchInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this._searchFilter.set(value);\n }\n\n _onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter' || event.key === ' ') {\n if (!this._panelOpen()) {\n event.preventDefault();\n this.open();\n }\n } else if (event.key === 'Escape') {\n if (this._panelOpen()) {\n event.preventDefault();\n this.close();\n }\n }\n }\n\n readonly _treeSelectionMode = computed((): FuiTreeSelectionMode => {\n return this.selectionMode() as FuiTreeSelectionMode;\n });\n\n // CVA\n writeValue(value: any): void {\n this._value.set(value);\n this._syncSelectedFromValue(value);\n this.stateChanges.next();\n }\n\n registerOnChange(fn: any): void {\n this._onChange = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this._disabled.set(disabled);\n this.stateChanges.next();\n }\n\n ngOnDestroy(): void {\n this._disposeOverlay();\n this.stateChanges.complete();\n }\n\n ngDoCheck(): void {\n if (this.ngControl) {\n const control = this.ngControl.control;\n if (control) {\n const isInvalid = control.invalid && (control.touched || false);\n this.errorState.set(isInvalid);\n }\n }\n }\n\n // Private helpers\n private _getNodeLabel(node: FuiTreeNode<T>): string {\n const displayFn = this.displayField();\n if (typeof displayFn === 'function') return displayFn(node);\n if (typeof displayFn === 'string' && node.data && typeof node.data === 'object') {\n return String((node.data as any)[displayFn] ?? '');\n }\n return String(node.data ?? '');\n }\n\n private _deselectAll(nodes: FuiTreeNode<T>[]): void {\n for (const n of nodes) {\n n.selected = false;\n if (Array.isArray(n.children)) this._deselectAll(n.children);\n }\n }\n\n private _updateMultiSelection(): void {\n const selected = this._collectSelected(this.nodes());\n this._selectedNodes.set(selected);\n const values = selected.map((n) => n.data);\n this._value.set(values as any);\n this._onChange(values);\n this.selectionChange.emit({ value: selected, source: this });\n this.stateChanges.next();\n }\n\n private _collectSelected(nodes: FuiTreeNode<T>[]): FuiTreeNode<T>[] {\n const result: FuiTreeNode<T>[] = [];\n for (const n of nodes) {\n if (n.selected) result.push(n);\n if (Array.isArray(n.children)) result.push(...this._collectSelected(n.children));\n }\n return result;\n }\n\n private _syncSelectedFromValue(value: any): void {\n if (value === null || value === undefined) {\n this._deselectAll(this.nodes());\n this._selectedNodes.set([]);\n return;\n }\n // For now, leave nodes as-is since the consumer controls node.selected\n }\n\n private _createOverlay(): void {\n if (this._overlayRef || !this.panel) return;\n const triggerElement = this._elementRef.nativeElement;\n const triggerWidth = triggerElement.getBoundingClientRect().width;\n const positions: FuiConnectedPosition[] = [\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },\n ];\n const positionStrategy = this._overlayService\n .position()\n .connectedTo(triggerElement, positions)\n .withPush(true)\n .withViewportMargin(8);\n this._overlayRef = this._overlayService.create({\n positionStrategy,\n scrollStrategy: this._overlayService.scrollStrategies.reposition(),\n hasBackdrop: true,\n backdropClass: 'fui-tree-select-backdrop',\n backdropClickBehavior: 'close',\n panelClass: ['fui-tree-select-overlay-panel'],\n minWidth: triggerWidth,\n });\n this._overlayRef.backdropClick.subscribe(() => {\n this.close();\n });\n this._overlayRef.keydownEvents.subscribe((event) => {\n if (event.key === 'Escape') this.close();\n });\n this._overlayRef.attach(this.panel.nativeElement);\n }\n\n private _disposeOverlay(): void {\n if (this._overlayRef) {\n this._overlayRef.dispose();\n this._overlayRef = null;\n }\n }\n}\n","<!-- Trigger area -->\n<div class=\"fui-tree-select__trigger\" #trigger>\n @if (empty()) {\n <span class=\"fui-tree-select__placeholder\">{{ placeholder() }}</span>\n } @else if (selectionMode() === 'single') {\n <span class=\"fui-tree-select__value\">{{ _getDisplayValue() }}</span>\n } @else {\n <div class=\"fui-tree-select__tags\">\n @for (tag of _getSelectedDisplayValues(); track tag) {\n <fui-badge [label]=\"tag\" size=\"sm\" variant=\"secondary\"></fui-badge>\n }\n </div>\n }\n <fui-icon class=\"fui-tree-select__arrow\" [name]=\"_panelOpen() ? 'caret-up' : 'caret-down'\" size=\"sm\"></fui-icon>\n</div>\n\n<!-- Panel (rendered always but hidden, moved to overlay when open) -->\n<div class=\"fui-tree-select__panel\" [id]=\"_treeId\" #panel [style.display]=\"_panelOpen() ? '' : 'none'\">\n @if (showSearch()) {\n <div class=\"fui-tree-select__search\">\n <input\n class=\"fui-tree-select__search-input\"\n type=\"text\"\n placeholder=\"Search...\"\n (input)=\"_onSearchInput($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n </div>\n }\n <fui-tree\n [nodes]=\"nodes()\"\n [selectionMode]=\"_treeSelectionMode()\"\n [loadChildren]=\"loadChildren()\"\n [nodeTemplate]=\"nodeTemplate()\"\n [filter]=\"_searchFilter()\"\n (nodeSelect)=\"_onTreeSelect($event)\"\n (nodeUnselect)=\"_onTreeUnselect($event)\"\n >\n </fui-tree>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, signal, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { FuiIconComponent } from '@raintonic/formaui/components/icon';
|
|
4
|
+
|
|
5
|
+
class FuiTreeTableComponent {
|
|
6
|
+
// Config & headers
|
|
7
|
+
config = input.required(...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
8
|
+
sort = input(null, ...(ngDevMode ? [{ debugName: "sort" }] : /* istanbul ignore next */ []));
|
|
9
|
+
filters = input([], ...(ngDevMode ? [{ debugName: "filters" }] : /* istanbul ignore next */ []));
|
|
10
|
+
enableRowHighlight = input(false, ...(ngDevMode ? [{ debugName: "enableRowHighlight" }] : /* istanbul ignore next */ []));
|
|
11
|
+
emptyMessage = input('Nessun dato disponibile', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
|
|
12
|
+
// Tree-specific inputs
|
|
13
|
+
nodes = input.required(...(ngDevMode ? [{ debugName: "nodes" }] : /* istanbul ignore next */ []));
|
|
14
|
+
loadChildren = input(null, ...(ngDevMode ? [{ debugName: "loadChildren" }] : /* istanbul ignore next */ []));
|
|
15
|
+
// Outputs
|
|
16
|
+
sortChange = output();
|
|
17
|
+
filtersChange = output();
|
|
18
|
+
rowDblClick = output();
|
|
19
|
+
rowExpand = output();
|
|
20
|
+
rowCollapse = output();
|
|
21
|
+
// Internal
|
|
22
|
+
_refreshCounter = signal(0, ...(ngDevMode ? [{ debugName: "_refreshCounter" }] : /* istanbul ignore next */ []));
|
|
23
|
+
flatRows = computed(() => {
|
|
24
|
+
this._refreshCounter();
|
|
25
|
+
return this._flattenNodes(this.nodes());
|
|
26
|
+
}, ...(ngDevMode ? [{ debugName: "flatRows" }] : /* istanbul ignore next */ []));
|
|
27
|
+
treeColumnField = computed(() => {
|
|
28
|
+
const cfg = this.config();
|
|
29
|
+
return cfg.treeColumn ?? cfg.headers[0]?.field ?? '';
|
|
30
|
+
}, ...(ngDevMode ? [{ debugName: "treeColumnField" }] : /* istanbul ignore next */ []));
|
|
31
|
+
indentPx = computed(() => this.config().indentPx ?? 24, ...(ngDevMode ? [{ debugName: "indentPx" }] : /* istanbul ignore next */ []));
|
|
32
|
+
// Methods
|
|
33
|
+
_flattenNodes(nodes) {
|
|
34
|
+
const result = [];
|
|
35
|
+
let flatIndex = 0;
|
|
36
|
+
const recurse = (nodeList, level) => {
|
|
37
|
+
for (const node of nodeList) {
|
|
38
|
+
const expandable = !node.leaf && (Array.isArray(node.children) ? node.children.length > 0 : node.children != null);
|
|
39
|
+
result.push({
|
|
40
|
+
data: node.data,
|
|
41
|
+
origin: node,
|
|
42
|
+
level,
|
|
43
|
+
expandable,
|
|
44
|
+
expanded: node.expanded ?? false,
|
|
45
|
+
selected: node.selected ?? false,
|
|
46
|
+
disabled: node.disabled ?? false,
|
|
47
|
+
loading: false,
|
|
48
|
+
_flatIndex: flatIndex++,
|
|
49
|
+
});
|
|
50
|
+
if (node.expanded && Array.isArray(node.children)) {
|
|
51
|
+
recurse(node.children, level + 1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
recurse(nodes, 0);
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
onToggleRow(flatRow) {
|
|
59
|
+
const node = flatRow.origin;
|
|
60
|
+
if (flatRow.expanded) {
|
|
61
|
+
node.expanded = false;
|
|
62
|
+
this.rowCollapse.emit({ row: node, flatRow });
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
node.expanded = true;
|
|
66
|
+
this.rowExpand.emit({ row: node, flatRow });
|
|
67
|
+
}
|
|
68
|
+
this._refreshCounter.update((c) => c + 1);
|
|
69
|
+
}
|
|
70
|
+
onSortColumn(field) {
|
|
71
|
+
const current = this.sort();
|
|
72
|
+
if (current?.field === field) {
|
|
73
|
+
if (current.direction === 'ASC') {
|
|
74
|
+
this.sortChange.emit({ field, direction: 'DESC' });
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.sortChange.emit(null);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.sortChange.emit({ field, direction: 'ASC' });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
getCellValue(row, field) {
|
|
85
|
+
// Support dot-notation fields like 'address.city'
|
|
86
|
+
return field.split('.').reduce((obj, key) => obj?.[key], row);
|
|
87
|
+
}
|
|
88
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiTreeTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
89
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiTreeTableComponent, isStandalone: true, selector: "fui-tree-table", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, enableRowHighlight: { classPropertyName: "enableRowHighlight", publicName: "enableRowHighlight", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: true, transformFunction: null }, loadChildren: { classPropertyName: "loadChildren", publicName: "loadChildren", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortChange: "sortChange", filtersChange: "filtersChange", rowDblClick: "rowDblClick", rowExpand: "rowExpand", rowCollapse: "rowCollapse" }, host: { classAttribute: "fui-tree-table" }, ngImport: i0, template: "<div class=\"fui-tree-table__wrapper\">\n <table class=\"fui-tree-table__table\">\n <thead class=\"fui-tree-table__head\" [class.fui-tree-table__head--sticky]=\"config().headerSticky\">\n <tr class=\"fui-tree-table__header-row\">\n @for (header of config().headers; track header.field) {\n <th\n class=\"fui-tree-table__header-cell\"\n [class.fui-tree-table__header-cell--sortable]=\"header.hasSort\"\n (click)=\"header.hasSort ? onSortColumn(header.field) : null\"\n >\n <div class=\"fui-tree-table__header-content\">\n <span>{{ header.label }}</span>\n @if (header.hasSort) {\n @if (sort()?.field === header.field) {\n <fui-icon [name]=\"sort()?.direction === 'ASC' ? 'caret-up' : 'caret-down'\" size=\"sm\"></fui-icon>\n }\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"fui-tree-table__body\">\n @if (flatRows().length === 0) {\n <tr class=\"fui-tree-table__empty-row\">\n <td [attr.colspan]=\"config().headers.length\" class=\"fui-tree-table__empty-cell\">\n {{ emptyMessage() }}\n </td>\n </tr>\n }\n @for (flatRow of flatRows(); track flatRow._flatIndex) {\n <tr\n class=\"fui-tree-table__row\"\n [class.fui-tree-table__row--selected]=\"flatRow.selected\"\n [class.fui-tree-table__row--disabled]=\"flatRow.disabled\"\n [class.fui-tree-table__row--highlight]=\"enableRowHighlight()\"\n [attr.aria-level]=\"flatRow.level + 1\"\n [attr.aria-expanded]=\"flatRow.expandable ? flatRow.expanded : null\"\n (dblclick)=\"rowDblClick.emit(flatRow.data)\"\n >\n @for (header of config().headers; track header.field) {\n <td class=\"fui-tree-table__cell\">\n @if (header.field === treeColumnField()) {\n <div class=\"fui-tree-table__tree-cell\" [style.padding-left.px]=\"flatRow.level * indentPx()\">\n <button\n class=\"fui-tree-table__expand-toggle\"\n [class.fui-tree-table__expand-toggle--hidden]=\"!flatRow.expandable\"\n (click)=\"onToggleRow(flatRow); $event.stopPropagation()\"\n type=\"button\"\n tabindex=\"-1\"\n >\n @if (flatRow.loading) {\n <fui-icon name=\"spinner\" [spin]=\"true\" size=\"sm\"></fui-icon>\n } @else {\n <fui-icon [name]=\"flatRow.expanded ? 'caret-down' : 'caret-right'\" size=\"sm\"></fui-icon>\n }\n </button>\n <span class=\"fui-tree-table__cell-text\">{{ getCellValue(flatRow.data, header.field) }}</span>\n </div>\n } @else {\n {{ getCellValue(flatRow.data, header.field) }}\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n</div>\n", styles: [".fui-tree-table{display:block;width:100%;font-family:var(--fui-font-family);font-size:var(--fui-font-size-03);color:var(--fui-text-primary)}.fui-tree-table__wrapper{overflow:auto;border:1px solid var(--fui-border-color);border-radius:var(--fui-border-radius-sm)}.fui-tree-table__table{width:100%;border-collapse:collapse}.fui-tree-table__head--sticky{position:sticky;top:0;z-index:1}.fui-tree-table__header-row{background-color:var(--fui-surface-card)}.fui-tree-table__header-cell{padding:12px 16px;text-align:left;font-weight:600;font-size:var(--fui-font-size-02);color:var(--fui-text-secondary);border-bottom:1px solid var(--fui-border-color);white-space:nowrap}.fui-tree-table__header-cell--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.fui-tree-table__header-cell--sortable:hover{background-color:var(--fui-surface-hover, var(--fui-black-5))}.fui-tree-table__header-content{display:flex;align-items:center;gap:4px}.fui-tree-table__row{border-bottom:1px solid var(--fui-border-color);transition:background-color var(--fui-duration-moderate-01) var(--fui-ease-standard)}.fui-tree-table__row--highlight:hover{background-color:var(--fui-surface-hover, var(--fui-black-5))}.fui-tree-table__row--selected{background-color:var(--fui-primary-10)}.fui-tree-table__row--disabled{opacity:.5;pointer-events:none}.fui-tree-table__cell{padding:8px 16px;vertical-align:middle}.fui-tree-table__tree-cell{display:flex;align-items:center;gap:4px}.fui-tree-table__expand-toggle{all:unset;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;flex-shrink:0;border-radius:var(--fui-border-radius-sm);cursor:pointer}.fui-tree-table__expand-toggle--hidden{visibility:hidden}.fui-tree-table__expand-toggle:hover{background-color:var(--fui-surface-hover, var(--fui-black-10))}.fui-tree-table__cell-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-tree-table__empty-cell{padding:32px 16px;text-align:center;color:var(--fui-text-disabled)}\n"], dependencies: [{ kind: "component", type: FuiIconComponent, selector: "fui-icon", inputs: ["name", "size", "weight", "color", "ariaLabel", "spin", "pulse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
90
|
+
}
|
|
91
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiTreeTableComponent, decorators: [{
|
|
92
|
+
type: Component,
|
|
93
|
+
args: [{ selector: 'fui-tree-table', standalone: true, imports: [FuiIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
94
|
+
class: 'fui-tree-table',
|
|
95
|
+
}, template: "<div class=\"fui-tree-table__wrapper\">\n <table class=\"fui-tree-table__table\">\n <thead class=\"fui-tree-table__head\" [class.fui-tree-table__head--sticky]=\"config().headerSticky\">\n <tr class=\"fui-tree-table__header-row\">\n @for (header of config().headers; track header.field) {\n <th\n class=\"fui-tree-table__header-cell\"\n [class.fui-tree-table__header-cell--sortable]=\"header.hasSort\"\n (click)=\"header.hasSort ? onSortColumn(header.field) : null\"\n >\n <div class=\"fui-tree-table__header-content\">\n <span>{{ header.label }}</span>\n @if (header.hasSort) {\n @if (sort()?.field === header.field) {\n <fui-icon [name]=\"sort()?.direction === 'ASC' ? 'caret-up' : 'caret-down'\" size=\"sm\"></fui-icon>\n }\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"fui-tree-table__body\">\n @if (flatRows().length === 0) {\n <tr class=\"fui-tree-table__empty-row\">\n <td [attr.colspan]=\"config().headers.length\" class=\"fui-tree-table__empty-cell\">\n {{ emptyMessage() }}\n </td>\n </tr>\n }\n @for (flatRow of flatRows(); track flatRow._flatIndex) {\n <tr\n class=\"fui-tree-table__row\"\n [class.fui-tree-table__row--selected]=\"flatRow.selected\"\n [class.fui-tree-table__row--disabled]=\"flatRow.disabled\"\n [class.fui-tree-table__row--highlight]=\"enableRowHighlight()\"\n [attr.aria-level]=\"flatRow.level + 1\"\n [attr.aria-expanded]=\"flatRow.expandable ? flatRow.expanded : null\"\n (dblclick)=\"rowDblClick.emit(flatRow.data)\"\n >\n @for (header of config().headers; track header.field) {\n <td class=\"fui-tree-table__cell\">\n @if (header.field === treeColumnField()) {\n <div class=\"fui-tree-table__tree-cell\" [style.padding-left.px]=\"flatRow.level * indentPx()\">\n <button\n class=\"fui-tree-table__expand-toggle\"\n [class.fui-tree-table__expand-toggle--hidden]=\"!flatRow.expandable\"\n (click)=\"onToggleRow(flatRow); $event.stopPropagation()\"\n type=\"button\"\n tabindex=\"-1\"\n >\n @if (flatRow.loading) {\n <fui-icon name=\"spinner\" [spin]=\"true\" size=\"sm\"></fui-icon>\n } @else {\n <fui-icon [name]=\"flatRow.expanded ? 'caret-down' : 'caret-right'\" size=\"sm\"></fui-icon>\n }\n </button>\n <span class=\"fui-tree-table__cell-text\">{{ getCellValue(flatRow.data, header.field) }}</span>\n </div>\n } @else {\n {{ getCellValue(flatRow.data, header.field) }}\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n</div>\n", styles: [".fui-tree-table{display:block;width:100%;font-family:var(--fui-font-family);font-size:var(--fui-font-size-03);color:var(--fui-text-primary)}.fui-tree-table__wrapper{overflow:auto;border:1px solid var(--fui-border-color);border-radius:var(--fui-border-radius-sm)}.fui-tree-table__table{width:100%;border-collapse:collapse}.fui-tree-table__head--sticky{position:sticky;top:0;z-index:1}.fui-tree-table__header-row{background-color:var(--fui-surface-card)}.fui-tree-table__header-cell{padding:12px 16px;text-align:left;font-weight:600;font-size:var(--fui-font-size-02);color:var(--fui-text-secondary);border-bottom:1px solid var(--fui-border-color);white-space:nowrap}.fui-tree-table__header-cell--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.fui-tree-table__header-cell--sortable:hover{background-color:var(--fui-surface-hover, var(--fui-black-5))}.fui-tree-table__header-content{display:flex;align-items:center;gap:4px}.fui-tree-table__row{border-bottom:1px solid var(--fui-border-color);transition:background-color var(--fui-duration-moderate-01) var(--fui-ease-standard)}.fui-tree-table__row--highlight:hover{background-color:var(--fui-surface-hover, var(--fui-black-5))}.fui-tree-table__row--selected{background-color:var(--fui-primary-10)}.fui-tree-table__row--disabled{opacity:.5;pointer-events:none}.fui-tree-table__cell{padding:8px 16px;vertical-align:middle}.fui-tree-table__tree-cell{display:flex;align-items:center;gap:4px}.fui-tree-table__expand-toggle{all:unset;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;flex-shrink:0;border-radius:var(--fui-border-radius-sm);cursor:pointer}.fui-tree-table__expand-toggle--hidden{visibility:hidden}.fui-tree-table__expand-toggle:hover{background-color:var(--fui-surface-hover, var(--fui-black-10))}.fui-tree-table__cell-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-tree-table__empty-cell{padding:32px 16px;text-align:center;color:var(--fui-text-disabled)}\n"] }]
|
|
96
|
+
}], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }], filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }], enableRowHighlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableRowHighlight", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: true }] }], loadChildren: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadChildren", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filtersChange: [{ type: i0.Output, args: ["filtersChange"] }], rowDblClick: [{ type: i0.Output, args: ["rowDblClick"] }], rowExpand: [{ type: i0.Output, args: ["rowExpand"] }], rowCollapse: [{ type: i0.Output, args: ["rowCollapse"] }] } });
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Generated bundle index. Do not edit.
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
export { FuiTreeTableComponent };
|
|
103
|
+
//# sourceMappingURL=raintonic-formaui-components-tree-table.mjs.map
|