@raintonic/formaui 0.9.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/fesm2022/raintonic-formaui-components-accordion.mjs +4 -4
- package/fesm2022/raintonic-formaui-components-accordion.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-alert.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-alert.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-avatar.mjs +2 -2
- 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-button-group.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-button-group.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 +2 -2
- package/fesm2022/raintonic-formaui-components-chip.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-data-table.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-data-table.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-date-picker.mjs +4 -4
- 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 +2 -2
- package/fesm2022/raintonic-formaui-components-dropdown-menu.mjs.map +1 -1
- 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 +2 -2
- package/fesm2022/raintonic-formaui-components-form-field.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 +2 -2
- 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 +2 -2
- package/fesm2022/raintonic-formaui-components-password-input.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-popover.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-popover.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-progressbar.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-progressbar.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-radio.mjs +4 -4
- package/fesm2022/raintonic-formaui-components-radio.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-select.mjs +4 -4
- 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 +4 -4
- package/fesm2022/raintonic-formaui-components-sidebar-nav-menu.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 +2 -2
- package/fesm2022/raintonic-formaui-components-stepper.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tab.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-tab.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-time-picker.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-time-picker.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-toggle-group.mjs +4 -4
- package/fesm2022/raintonic-formaui-components-toggle-group.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-topbar.mjs +2 -2
- package/fesm2022/raintonic-formaui-components-topbar.mjs.map +1 -1
- package/fesm2022/raintonic-formaui-components-tree-select.mjs +2 -2
- 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 +4 -4
- package/fesm2022/raintonic-formaui-components-tree.mjs.map +1 -1
- package/fesm2022/raintonic-formaui.mjs +1 -1
- package/fesm2022/raintonic-formaui.mjs.map +1 -1
- package/llms-full.txt +8 -8
- package/package.json +1 -1
- package/styles/generated/_tokens.scss +8 -8
- package/styles/styles.css +8 -8
- package/types/raintonic-formaui.d.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raintonic-formaui-components-sidebar-nav-menu.mjs","sources":["../../../lib/components/sidebar-nav-menu/sidebar-nav-submenu.component.ts","../../../lib/components/sidebar-nav-menu/sidebar-nav-submenu.component.html","../../../lib/components/sidebar-nav-menu/sidebar-nav-search.intl.ts","../../../lib/components/sidebar-nav-menu/sidebar-nav-search.component.ts","../../../lib/components/sidebar-nav-menu/sidebar-nav-menu.component.ts","../../../lib/components/sidebar-nav-menu/sidebar-nav-menu.component.html","../../../lib/components/sidebar-nav-menu/expand-menu-items.ts","../../../lib/components/sidebar-nav-menu/raintonic-formaui-components-sidebar-nav-menu.ts"],"sourcesContent":["import { Component, effect, input, output, signal } from '@angular/core';\r\nimport { RouterLink, RouterLinkActive } from '@angular/router';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { MenuItem } from '@raintonic/formaui/core';\r\n\r\n/**\r\n * Recursive submenu component for rendering nested menu items.\r\n *\r\n * Used internally by FuiSidebarNavMenuComponent. Renders a flat list\r\n * of items and recurses via <sidebar-nav-submenu> in the template\r\n * when an item has children.\r\n *\r\n * Keyboard navigation follows WAI-ARIA menu patterns:\r\n * - ArrowDown / ArrowUp: navigate between siblings\r\n * - ArrowRight: expand submenu\r\n * - ArrowLeft: collapse submenu / move focus to parent\r\n * - Enter / Space: activate item\r\n * - Home / End: first / last item\r\n */\r\n@Component({\r\n selector: 'fui-sidebar-nav-submenu',\r\n standalone: true,\r\n imports: [RouterLink, RouterLinkActive, FuiIconComponent],\r\n templateUrl: './sidebar-nav-submenu.component.html',\r\n styleUrl: './sidebar-nav-menu.component.scss',\r\n})\r\nexport class SidebarNavSubmenuComponent {\r\n /** Menu items to render (IDs already assigned by parent) */\r\n readonly items = input([] as MenuItem[]);\r\n\r\n /** Accessible label for this submenu group */\r\n readonly submenuLabel = input('');\r\n\r\n /** Whether this is the root level (applies root-level styles) */\r\n readonly isRoot = input(false);\r\n\r\n /** Nesting depth (0 = root). Used to compute aria-level on section headers. */\r\n readonly depth = input(0);\r\n\r\n /** Emitted when any clickable item is activated */\r\n readonly itemClick = output<MenuItem>();\r\n\r\n // Track expanded state per item id (Set of string IDs)\r\n readonly _expanded = signal(new Set<string>());\r\n\r\n constructor() {\r\n // Initialize expanded states from item data.\r\n // When the items input changes (new reference), manual user toggle state is\r\n // intentionally reset — auto-expansion from item.expanded takes priority.\r\n // Every `expanded: true` in the data is honoured (filtering and URL-based\r\n // auto-expansion may mark several branches at once); the accordion rule\r\n // only applies to user interaction (see toggleExpand / ArrowRight).\r\n effect(() => {\r\n const expanded = new Set<string>();\r\n\r\n const walk = (list: MenuItem[]) => {\r\n for (const it of list) {\r\n if (it.expanded && it.items?.length) {\r\n expanded.add(it.id!);\r\n }\r\n if (it.items) walk(it.items);\r\n }\r\n };\r\n walk(this.items());\r\n this._expanded.set(expanded);\r\n });\r\n }\r\n\r\n // ─── Public helpers (used in template) ───────────────────\r\n\r\n /** @internal Whether the item has child submenu items */\r\n hasChildren(item: MenuItem): boolean {\r\n return !!(item.items && item.items.length > 0);\r\n }\r\n\r\n /** @internal Whether the item's submenu is currently expanded */\r\n isExpanded(item: MenuItem): boolean {\r\n if (!this.hasChildren(item)) return false;\r\n return this._expanded().has(item.id!);\r\n }\r\n\r\n /** @internal Toggle submenu open/closed */\r\n toggleExpand(event: Event, item: MenuItem): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (item.disabled) return;\r\n\r\n const wasExpanded = this._expanded().has(item.id!);\r\n\r\n this._expanded.update((s) => {\r\n const next = new Set(s);\r\n const id = item.id!;\r\n\r\n if (wasExpanded) {\r\n // Collapse this item\r\n next.delete(id);\r\n } else {\r\n // Expand this item\r\n if (this.isRoot()) {\r\n // Accordion: close any other root items first\r\n next.clear();\r\n }\r\n next.add(id);\r\n }\r\n\r\n return next;\r\n });\r\n\r\n if (item.command) {\r\n item.command(event);\r\n }\r\n this.itemClick.emit(item);\r\n }\r\n\r\n /** @internal Handle click on a leaf (non-parent) item */\r\n onLeafClick(event: Event, item: MenuItem): void {\r\n if (item.disabled) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (item.command) {\r\n item.command(event);\r\n }\r\n\r\n this.itemClick.emit(item);\r\n }\r\n\r\n /** @internal Keyboard event handler */\r\n onKeydown(event: KeyboardEvent, item: MenuItem): void {\r\n if (item.disabled) return;\r\n\r\n const itemEl = event.currentTarget as HTMLElement | null;\r\n if (!itemEl) return;\r\n\r\n const listEl = itemEl.closest('ul') as HTMLElement | null;\r\n if (!listEl) return;\r\n\r\n // Collect all enabled items at this level\r\n const items = Array.from(listEl.querySelectorAll<HTMLElement>(':scope > li > .sidebar-nav-menu__item'));\r\n const currentIndex = items.indexOf(itemEl);\r\n\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n this._focusItemAt(items, currentIndex + 1, 1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this._focusItemAt(items, currentIndex - 1, -1);\r\n break;\r\n case 'ArrowRight':\r\n event.preventDefault();\r\n if (this.hasChildren(item) && !this.isExpanded(item)) {\r\n this._expanded.update((s) => {\r\n const next = new Set(s);\r\n if (this.isRoot()) {\r\n // Accordion: close any other root items\r\n next.clear();\r\n }\r\n next.add(item.id!);\r\n return next;\r\n });\r\n }\r\n break;\r\n case 'ArrowLeft':\r\n if (this.hasChildren(item) && this.isExpanded(item)) {\r\n event.preventDefault();\r\n this._expanded.update((s) => {\r\n const next = new Set(s);\r\n next.delete(item.id!);\r\n return next;\r\n });\r\n }\r\n if (this._hasParentSubmenu(itemEl)) {\r\n event.preventDefault();\r\n this._focusParent(itemEl);\r\n }\r\n break;\r\n case 'Enter':\r\n case ' ':\r\n event.preventDefault();\r\n if (this.hasChildren(item)) {\r\n this.toggleExpand(event, item);\r\n } else {\r\n itemEl.click();\r\n }\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n this._focusItemAt(items, 0, 1);\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n this._focusItemAt(items, items.length - 1, -1);\r\n break;\r\n }\r\n }\r\n\r\n // ─── Private helpers ─────────────────────────────────────\r\n\r\n private _focusItemAt(items: HTMLElement[], start: number, step: 1 | -1): void {\r\n let i = start;\r\n while (i >= 0 && i < items.length) {\r\n if (!items[i].classList.contains('sidebar-nav-menu__item--disabled')) {\r\n items[i].focus();\r\n return;\r\n }\r\n i += step;\r\n }\r\n }\r\n\r\n private _hasParentSubmenu(itemEl: HTMLElement): boolean {\r\n return !!itemEl.closest('fui-sidebar-nav-submenu')?.parentElement?.closest('li');\r\n }\r\n\r\n private _focusParent(itemEl: HTMLElement): void {\r\n const parentSubmenu = itemEl.closest('fui-sidebar-nav-submenu')?.parentElement?.closest('li');\r\n\r\n if (parentSubmenu) {\r\n const parentTrigger = parentSubmenu.querySelector<HTMLElement>('.sidebar-nav-menu__item--parent');\r\n parentTrigger?.focus();\r\n }\r\n }\r\n}\r\n","<ul\r\n class=\"sidebar-nav-submenu\"\r\n role=\"group\"\r\n [class.sidebar-nav-submenu--root]=\"isRoot()\"\r\n [attr.aria-label]=\"submenuLabel()\"\r\n>\r\n @for (item of items(); track item.id; let idx = $index) {\r\n @if (item.visible !== false) {\r\n @if (item.separator) {\r\n <li class=\"sidebar-nav-menu__separator\" role=\"separator\"></li>\r\n } @else if (item.sectionHeader) {\r\n <li class=\"sidebar-nav-menu__section-header\" role=\"heading\" [attr.aria-level]=\"depth() + 2\">\r\n <span class=\"sidebar-nav-menu__section-header-label\">{{ item.label }}</span>\r\n </li>\r\n } @else {\r\n <li\r\n class=\"sidebar-nav-menu__item-wrapper\"\r\n role=\"none\"\r\n [class.sidebar-nav-menu__item-wrapper--root]=\"isRoot()\"\r\n [class.sidebar-nav-menu__item-wrapper--expanded]=\"hasChildren(item) && isExpanded(item)\"\r\n >\r\n @if (hasChildren(item)) {\r\n <!-- Parent item with submenu -->\r\n <button\r\n class=\"sidebar-nav-menu__item sidebar-nav-menu__item--parent\"\r\n type=\"button\"\r\n [class.sidebar-nav-menu__item--disabled]=\"item.disabled\"\r\n [class.sidebar-nav-menu__item--expanded]=\"isExpanded(item)\"\r\n [id]=\"item.id + '_trigger'\"\r\n [attr.aria-haspopup]=\"true\"\r\n [attr.aria-expanded]=\"isExpanded(item)\"\r\n [disabled]=\"item.disabled\"\r\n (click)=\"toggleExpand($event, item)\"\r\n (keydown)=\"onKeydown($event, item)\"\r\n >\r\n <span class=\"sidebar-nav-menu__item-content\">\r\n @if (item.icon) {\r\n <fui-icon\r\n class=\"sidebar-nav-menu__item-icon\"\r\n [name]=\"item.icon\"\r\n size=\"md\"\r\n aria-hidden=\"true\"\r\n ></fui-icon>\r\n }\r\n <span class=\"sidebar-nav-menu__item-label\">{{ item.label }}</span>\r\n </span>\r\n <fui-icon\r\n class=\"sidebar-nav-menu__item-chevron\"\r\n name=\"caret-right\"\r\n [class.sidebar-nav-menu__item-chevron--expanded]=\"isExpanded(item)\"\r\n size=\"sm\"\r\n aria-hidden=\"true\"\r\n ></fui-icon>\r\n </button>\r\n\r\n <!-- Submenu content with left border -->\r\n @if (isExpanded(item)) {\r\n <div\r\n class=\"sidebar-nav-submenu__inline\"\r\n animate.enter=\"sidebar-nav-submenu__inline--enter\"\r\n animate.leave=\"sidebar-nav-submenu__inline--leave\"\r\n >\r\n <div class=\"sidebar-nav-submenu__border\"></div>\r\n <fui-sidebar-nav-submenu\r\n [items]=\"item.items!\"\r\n [submenuLabel]=\"item.label || ''\"\r\n [isRoot]=\"false\"\r\n [depth]=\"depth() + 1\"\r\n (itemClick)=\"itemClick.emit($event)\"\r\n />\r\n </div>\r\n }\r\n } @else {\r\n <!-- Leaf item -->\r\n @if (item.routerLink) {\r\n <a\r\n class=\"sidebar-nav-menu__item\"\r\n routerLinkActive=\"sidebar-nav-menu__item--active\"\r\n [class.sidebar-nav-menu__item--disabled]=\"item.disabled\"\r\n [attr.tabindex]=\"item.disabled ? '-1' : '0'\"\r\n [attr.aria-disabled]=\"item.disabled ? 'true' : null\"\r\n [routerLink]=\"item.routerLink\"\r\n [queryParams]=\"item.queryParams || undefined\"\r\n [fragment]=\"item.fragment || undefined\"\r\n [target]=\"item.target\"\r\n [title]=\"item.title\"\r\n (click)=\"onLeafClick($event, item)\"\r\n (keydown)=\"onKeydown($event, item)\"\r\n >\r\n <span class=\"sidebar-nav-menu__item-content\">\r\n @if (item.icon) {\r\n <fui-icon\r\n class=\"sidebar-nav-menu__item-icon\"\r\n [name]=\"item.icon\"\r\n size=\"md\"\r\n aria-hidden=\"true\"\r\n ></fui-icon>\r\n }\r\n <span class=\"sidebar-nav-menu__item-label\">{{ item.label }}</span>\r\n </span>\r\n </a>\r\n } @else {\r\n <button\r\n class=\"sidebar-nav-menu__item\"\r\n type=\"button\"\r\n [class.sidebar-nav-menu__item--disabled]=\"item.disabled\"\r\n [attr.tabindex]=\"item.disabled ? '-1' : '0'\"\r\n [attr.aria-disabled]=\"item.disabled ? 'true' : null\"\r\n [title]=\"item.title\"\r\n [disabled]=\"item.disabled\"\r\n (click)=\"onLeafClick($event, item)\"\r\n (keydown)=\"onKeydown($event, item)\"\r\n >\r\n <span class=\"sidebar-nav-menu__item-content\">\r\n @if (item.icon) {\r\n <fui-icon\r\n class=\"sidebar-nav-menu__item-icon\"\r\n [name]=\"item.icon\"\r\n size=\"md\"\r\n aria-hidden=\"true\"\r\n ></fui-icon>\r\n }\r\n <span class=\"sidebar-nav-menu__item-label\">{{ item.label }}</span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </li>\r\n }\r\n }\r\n }\r\n</ul>\r\n","import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiSidebarNavSearchIntl extends FuiIntlBase {\r\n /** Placeholder text for the search input. */\r\n searchPlaceholder = 'Cerca';\r\n /** aria-label for the search input. */\r\n searchInputAriaLabel = 'Filtra';\r\n /** aria-label for the clear-search button. */\r\n clearSearchAriaLabel = 'Pulisci';\r\n}\r\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, inject, input, model } from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FuiSidebarNavSearchIntl } from './sidebar-nav-search.intl';\r\nimport { FuiInputDirective } from '@raintonic/formaui/components/input';\r\nimport { FuiFormFieldComponent, FuiPrefixDirective } from '@raintonic/formaui/components/form-field';\r\n\r\n/**\r\n * # FuiSidebarNavSearchComponent\r\n *\r\n * A standalone search input component designed to be placed inside the sidebar\r\n * navigation menu. Emits the current filter string so the parent component can\r\n * reactively filter menu items.\r\n *\r\n * ## Features\r\n * - Search input with magnifying-glass icon\r\n * - Clear button that appears when a query is entered\r\n * - Configurable placeholder text (falls back to `FuiSidebarNavSearchIntl` default)\r\n * - Two-way binding via `filterString` model\r\n * - Aria labels via `FuiSidebarNavSearchIntl` (overridable via DI)\r\n *\r\n * ## Usage\r\n *\r\n * ```html\r\n * <fui-sidebar-nav-search\r\n * [(filterString)]=\"myFilter\"\r\n * placeholder=\"Search…\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-sidebar-nav-search',\r\n standalone: true,\r\n imports: [FuiIconComponent, FuiInputDirective, FuiFormFieldComponent, FuiPrefixDirective],\r\n template: `\r\n <fui-form-field>\r\n <fui-icon fuiPrefix name=\"magnifying-glass\" color=\"var(--fui-text-disabled)\" size=\"sm\"></fui-icon>\r\n <input\r\n fuiInput\r\n #searchInput\r\n class=\"fui-sidebar-nav-search__input\"\r\n type=\"search\"\r\n [placeholder]=\"resolvedPlaceholder()\"\r\n [value]=\"filterString()\"\r\n (input)=\"filterString.set(searchInput.value)\"\r\n [attr.aria-label]=\"resolvedSearchInputAriaLabel()\"\r\n />\r\n </fui-form-field>\r\n `,\r\n styles: `\r\n :host {\r\n display: block;\r\n flex-shrink: 0;\r\n padding: var(--fui-spacing-4) var(--fui-spacing-6);\r\n padding-bottom: 0px;\r\n --fui-bg-subtle: var(--fui-bg-default);\r\n }\r\n `,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class FuiSidebarNavSearchComponent {\r\n readonly intl = inject(FuiSidebarNavSearchIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n constructor() {\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => {\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n /**\r\n * The current filter string. Two-way bindable.\r\n */\r\n readonly filterString = model('');\r\n\r\n /**\r\n * Placeholder text for the search input.\r\n * Falls back to the Intl default when not set.\r\n */\r\n readonly placeholder = input<string | undefined>();\r\n\r\n /** Resolved placeholder: input override -> Intl default. */\r\n readonly resolvedPlaceholder = computed(() => this.placeholder() ?? this.intl.searchPlaceholder);\r\n\r\n /** Resolved search-input aria-label: Intl default. */\r\n readonly resolvedSearchInputAriaLabel = computed(() => this.intl.searchInputAriaLabel);\r\n\r\n /** Resolved clear-button aria-label: Intl default. */\r\n readonly resolvedClearSearchAriaLabel = computed(() => this.intl.clearSearchAriaLabel);\r\n}\r\n","import { ChangeDetectionStrategy, Component, computed, input, model, output } from '@angular/core';\r\nimport { MenuItem } from '@raintonic/formaui/core';\r\nimport { SidebarNavSubmenuComponent } from './sidebar-nav-submenu.component';\r\nimport { FuiSidebarNavSearchComponent } from './sidebar-nav-search.component';\r\n\r\n/**\r\n * # FuiSidebarNavMenuComponent\r\n *\r\n * A standalone sidebar navigation menu component with recursive,\r\n * multi-level submenus. Inspired by PrimeNG's TieredMenu model\r\n * with a minimal, structural approach.\r\n *\r\n * ## Features\r\n * - Unlimited nesting depth via recursive submenu template\r\n * - Inline expand/collapse submenus\r\n * - Built-in search input with clear button\r\n * - Routing integration via `routerLink` with automatic active detection\r\n * - Keyboard navigation (Arrow keys, Enter/Space, Home/End)\r\n * - Full ARIA support (`role=\"navigation\"`, `aria-expanded`, `aria-haspopup`)\r\n *\r\n * ## Usage\r\n *\r\n * ```html\r\n * <fui-sidebar-nav-menu\r\n * [items]=\"menuItems\"\r\n * [(filterString)]=\"myFilter\"\r\n * (itemClick)=\"onMenuItemClick($event)\"\r\n * />\r\n * ```\r\n *\r\n * ```typescript\r\n * import { FuiSidebarNavMenuComponent, MenuItem } from '@raintonic/formaui/components/sidebar-nav-menu';\r\n *\r\n * @Component({\r\n * standalone: true,\r\n * imports: [FuiSidebarNavMenuComponent],\r\n * template: `...`,\r\n * })\r\n * export class MyLayout {\r\n * menuItems: MenuItem[] = [\r\n * { label: 'Dashboard', icon: 'house', routerLink: '/dashboard' },\r\n * {\r\n * label: 'Products',\r\n * icon: 'package',\r\n * items: [\r\n * { label: 'List', routerLink: '/products' },\r\n * { label: 'Categories', routerLink: '/categories' },\r\n * ],\r\n * },\r\n * { separator: true },\r\n * { label: 'Logout', command: () => this.logout() },\r\n * ];\r\n *\r\n * onMenuItemClick(item: MenuItem): void {\r\n * console.log('Menu item:', item.label);\r\n * }\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-sidebar-nav-menu',\r\n standalone: true,\r\n imports: [SidebarNavSubmenuComponent, FuiSidebarNavSearchComponent],\r\n templateUrl: './sidebar-nav-menu.component.html',\r\n styleUrl: './sidebar-nav-menu.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n role: 'navigation',\r\n '[attr.aria-label]': 'ariaLabel()',\r\n class: 'fui-sidebar-nav-menu',\r\n },\r\n})\r\nexport class FuiSidebarNavMenuComponent {\r\n /**\r\n * Array of menu items to render.\r\n */\r\n readonly items = input<MenuItem[]>([]);\r\n\r\n /**\r\n * Accessible label for the navigation region.\r\n * @default 'Sidebar menu'\r\n */\r\n readonly ariaLabel = input('Sidebar menu');\r\n\r\n /**\r\n * Optional filter string. When set, the menu displays only items whose label\r\n * contains the filter text (case-insensitive, substring match). Parent items\r\n * with matching descendants remain visible so the filtered child can be reached.\r\n * Separators and section headers are hidden during filtering.\r\n *\r\n * This is a two-way bindable model signal — set it programmatically or wire it\r\n * to the built-in search component.\r\n */\r\n readonly filterString = model('');\r\n\r\n /**\r\n * Emitted when any clickable menu item is activated.\r\n */\r\n readonly itemClick = output<MenuItem>();\r\n\r\n /**\r\n * Pure derivation that assigns unique IDs without mutating consumer data.\r\n * Each item is shallow-copied; the tree is walked recursively.\r\n */\r\n readonly _readyItems = computed(() => {\r\n let counter = 0;\r\n const assignIds = (list: readonly MenuItem[]): MenuItem[] =>\r\n list.map((it) => {\r\n const copy = { ...it, id: it.id ?? `fui-mi-${++counter}` };\r\n if (copy.items) copy.items = assignIds(copy.items);\r\n return copy;\r\n });\r\n return assignIds(this.items());\r\n });\r\n\r\n /**\r\n * Filtered items based on `filterString`. When the filter is non-empty,\r\n * items are kept if their label matches (case-insensitive substring) or\r\n * if any descendant matches. Separators and section headers are hidden\r\n * during filtering.\r\n */\r\n readonly _filteredItems = computed(() => {\r\n const filter = this.filterString().trim().toLowerCase();\r\n const items = this._readyItems();\r\n\r\n if (!filter) return items;\r\n\r\n const filterTree = (list: MenuItem[]): MenuItem[] =>\r\n list\r\n .filter((it) => !it.separator && !it.sectionHeader)\r\n .filter((item) => {\r\n const childrenMatch = item.items?.length ? filterTree(item.items).length > 0 : false;\r\n return !!item.label?.toLowerCase().includes(filter) || childrenMatch;\r\n })\r\n .map((item) => {\r\n const filteredChildren = item.items?.length ? filterTree(item.items) : undefined;\r\n return filteredChildren?.length ? { ...item, expanded: true, items: filteredChildren } : item;\r\n });\r\n\r\n return filterTree(items);\r\n });\r\n\r\n /** @internal Pass-through handler from submenu */\r\n _onItemClick(item: MenuItem): void {\r\n this.itemClick.emit(item);\r\n }\r\n}\r\n","<div class=\"fui-sidebar-nav-menu__header\">\r\n <ng-content select=\"[fuiSidebarNavHeader]\"></ng-content>\r\n</div>\r\n\r\n<fui-sidebar-nav-search [(filterString)]=\"filterString\" />\r\n\r\n<div class=\"fui-sidebar-nav-menu__body\">\r\n <fui-sidebar-nav-submenu\r\n [items]=\"_filteredItems()\"\r\n [submenuLabel]=\"ariaLabel()\"\r\n [isRoot]=\"true\"\r\n (itemClick)=\"_onItemClick($event)\"\r\n />\r\n</div>\r\n\r\n<div class=\"fui-sidebar-nav-menu__footer\">\r\n <ng-content select=\"[fuiSidebarNavFooter]\"></ng-content>\r\n</div>\r\n","import { MenuItem } from '@raintonic/formaui/core';\r\n\r\n/**\r\n * Walk a menu item tree and set `expanded: true` on every parent whose\r\n * descendant chain contains a `routerLink` that matches the current URL.\r\n *\r\n * The function is **immutable** — it clones items only when it needs to mutate\r\n * them, returning the same reference for untouched subtrees.\r\n *\r\n * ## Usage\r\n *\r\n * ```typescript\r\n * import { expandMenuItems } from '@raintonic/formaui/components/sidebar-nav-menu';\r\n *\r\n * const items = expandMenuItems(myMenuItems, '/products/categories');\r\n * ```\r\n *\r\n * @param items - Menu item tree\r\n * @param currentUrl - The current URL path (e.g. `'/products/categories'`)\r\n * @returns A new tree with `expanded` set on matching parent items\r\n */\r\nexport function expandMenuItems(items: readonly MenuItem[], currentUrl: string): MenuItem[] {\r\n const result: MenuItem[] = [];\r\n\r\n for (const item of items) {\r\n // Separators and section headers are never expandable — pass through unchanged\r\n if (item.separator || item.sectionHeader) {\r\n result.push(item);\r\n continue;\r\n }\r\n\r\n const hasChildMatch = item.items && containsActiveDescendant(item.items, currentUrl);\r\n\r\n if (hasChildMatch) {\r\n // Clone the item, set expanded, and recurse into children\r\n result.push({\r\n ...item,\r\n expanded: true,\r\n items: expandMenuItems(item.items!, currentUrl),\r\n });\r\n } else if (item.expanded) {\r\n // No descendants match — reset expanded to false so the consumer's initial\r\n // state doesn't leak through\r\n result.push({ ...item, expanded: false });\r\n } else {\r\n result.push(item);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Returns `true` if any item in the list has a `routerLink` matching\r\n * `currentUrl`, or if any descendant of an item matches (recursive).\r\n */\r\nfunction containsActiveDescendant(items: readonly MenuItem[], currentUrl: string): boolean {\r\n return items.some((item) => {\r\n if (matchesUrl(item.routerLink, currentUrl)) return true;\r\n if (item.items && containsActiveDescendant(item.items, currentUrl)) return true;\r\n return false;\r\n });\r\n}\r\n\r\n/**\r\n * Normalise and compare a `routerLink` value against the current URL string.\r\n */\r\nfunction matchesUrl(routerLink: string | any[] | undefined, currentUrl: string): boolean {\r\n if (!routerLink) return false;\r\n if (typeof routerLink === 'string') {\r\n return normalise(routerLink) === normalise(currentUrl);\r\n }\r\n // routerLink as array — join segments to form the path\r\n const segments = routerLink.map(String).filter(Boolean);\r\n return segments.length > 0 && normalise(segments.join('/')) === normalise(currentUrl);\r\n}\r\n\r\n/**\r\n * Strip query string, fragment, and leading/trailing slashes for comparison.\r\n * `Router.url` includes query params and fragment (e.g. `/products?page=2#top`),\r\n * which must not prevent the path from matching a plain `routerLink`.\r\n */\r\nfunction normalise(p: string): string {\r\n const pathOnly = p.split(/[?#]/)[0];\r\n return pathOnly.replace(/^\\/+|\\/+$/g, '');\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-sidebar-nav-menu.mjs","sources":["../../../lib/components/sidebar-nav-menu/sidebar-nav-submenu.component.ts","../../../lib/components/sidebar-nav-menu/sidebar-nav-submenu.component.html","../../../lib/components/sidebar-nav-menu/sidebar-nav-search.intl.ts","../../../lib/components/sidebar-nav-menu/sidebar-nav-search.component.ts","../../../lib/components/sidebar-nav-menu/sidebar-nav-menu.component.ts","../../../lib/components/sidebar-nav-menu/sidebar-nav-menu.component.html","../../../lib/components/sidebar-nav-menu/expand-menu-items.ts","../../../lib/components/sidebar-nav-menu/raintonic-formaui-components-sidebar-nav-menu.ts"],"sourcesContent":["import { Component, effect, input, output, signal } from '@angular/core';\r\nimport { RouterLink, RouterLinkActive } from '@angular/router';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { MenuItem } from '@raintonic/formaui/core';\r\n\r\n/**\r\n * Recursive submenu component for rendering nested menu items.\r\n *\r\n * Used internally by FuiSidebarNavMenuComponent. Renders a flat list\r\n * of items and recurses via <sidebar-nav-submenu> in the template\r\n * when an item has children.\r\n *\r\n * Keyboard navigation follows WAI-ARIA menu patterns:\r\n * - ArrowDown / ArrowUp: navigate between siblings\r\n * - ArrowRight: expand submenu\r\n * - ArrowLeft: collapse submenu / move focus to parent\r\n * - Enter / Space: activate item\r\n * - Home / End: first / last item\r\n */\r\n@Component({\r\n selector: 'fui-sidebar-nav-submenu',\r\n standalone: true,\r\n imports: [RouterLink, RouterLinkActive, FuiIconComponent],\r\n templateUrl: './sidebar-nav-submenu.component.html',\r\n styleUrl: './sidebar-nav-menu.component.scss',\r\n})\r\nexport class SidebarNavSubmenuComponent {\r\n /** Menu items to render (IDs already assigned by parent) */\r\n readonly items = input([] as MenuItem[]);\r\n\r\n /** Accessible label for this submenu group */\r\n readonly submenuLabel = input('');\r\n\r\n /** Whether this is the root level (applies root-level styles) */\r\n readonly isRoot = input(false);\r\n\r\n /** Nesting depth (0 = root). Used to compute aria-level on section headers. */\r\n readonly depth = input(0);\r\n\r\n /** Emitted when any clickable item is activated */\r\n readonly itemClick = output<MenuItem>();\r\n\r\n // Track expanded state per item id (Set of string IDs)\r\n readonly _expanded = signal(new Set<string>());\r\n\r\n constructor() {\r\n // Initialize expanded states from item data.\r\n // When the items input changes (new reference), manual user toggle state is\r\n // intentionally reset — auto-expansion from item.expanded takes priority.\r\n // Every `expanded: true` in the data is honoured (filtering and URL-based\r\n // auto-expansion may mark several branches at once); the accordion rule\r\n // only applies to user interaction (see toggleExpand / ArrowRight).\r\n effect(() => {\r\n const expanded = new Set<string>();\r\n\r\n const walk = (list: MenuItem[]) => {\r\n for (const it of list) {\r\n if (it.expanded && it.items?.length) {\r\n expanded.add(it.id!);\r\n }\r\n if (it.items) walk(it.items);\r\n }\r\n };\r\n walk(this.items());\r\n this._expanded.set(expanded);\r\n });\r\n }\r\n\r\n // ─── Public helpers (used in template) ───────────────────\r\n\r\n /** @internal Whether the item has child submenu items */\r\n hasChildren(item: MenuItem): boolean {\r\n return !!(item.items && item.items.length > 0);\r\n }\r\n\r\n /** @internal Whether the item's submenu is currently expanded */\r\n isExpanded(item: MenuItem): boolean {\r\n if (!this.hasChildren(item)) return false;\r\n return this._expanded().has(item.id!);\r\n }\r\n\r\n /** @internal Toggle submenu open/closed */\r\n toggleExpand(event: Event, item: MenuItem): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (item.disabled) return;\r\n\r\n const wasExpanded = this._expanded().has(item.id!);\r\n\r\n this._expanded.update((s) => {\r\n const next = new Set(s);\r\n const id = item.id!;\r\n\r\n if (wasExpanded) {\r\n // Collapse this item\r\n next.delete(id);\r\n } else {\r\n // Expand this item\r\n if (this.isRoot()) {\r\n // Accordion: close any other root items first\r\n next.clear();\r\n }\r\n next.add(id);\r\n }\r\n\r\n return next;\r\n });\r\n\r\n if (item.command) {\r\n item.command(event);\r\n }\r\n this.itemClick.emit(item);\r\n }\r\n\r\n /** @internal Handle click on a leaf (non-parent) item */\r\n onLeafClick(event: Event, item: MenuItem): void {\r\n if (item.disabled) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (item.command) {\r\n item.command(event);\r\n }\r\n\r\n this.itemClick.emit(item);\r\n }\r\n\r\n /** @internal Keyboard event handler */\r\n onKeydown(event: KeyboardEvent, item: MenuItem): void {\r\n if (item.disabled) return;\r\n\r\n const itemEl = event.currentTarget as HTMLElement | null;\r\n if (!itemEl) return;\r\n\r\n const listEl = itemEl.closest('ul') as HTMLElement | null;\r\n if (!listEl) return;\r\n\r\n // Collect all enabled items at this level\r\n const items = Array.from(listEl.querySelectorAll<HTMLElement>(':scope > li > .sidebar-nav-menu__item'));\r\n const currentIndex = items.indexOf(itemEl);\r\n\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n this._focusItemAt(items, currentIndex + 1, 1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this._focusItemAt(items, currentIndex - 1, -1);\r\n break;\r\n case 'ArrowRight':\r\n event.preventDefault();\r\n if (this.hasChildren(item) && !this.isExpanded(item)) {\r\n this._expanded.update((s) => {\r\n const next = new Set(s);\r\n if (this.isRoot()) {\r\n // Accordion: close any other root items\r\n next.clear();\r\n }\r\n next.add(item.id!);\r\n return next;\r\n });\r\n }\r\n break;\r\n case 'ArrowLeft':\r\n if (this.hasChildren(item) && this.isExpanded(item)) {\r\n event.preventDefault();\r\n this._expanded.update((s) => {\r\n const next = new Set(s);\r\n next.delete(item.id!);\r\n return next;\r\n });\r\n }\r\n if (this._hasParentSubmenu(itemEl)) {\r\n event.preventDefault();\r\n this._focusParent(itemEl);\r\n }\r\n break;\r\n case 'Enter':\r\n case ' ':\r\n event.preventDefault();\r\n if (this.hasChildren(item)) {\r\n this.toggleExpand(event, item);\r\n } else {\r\n itemEl.click();\r\n }\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n this._focusItemAt(items, 0, 1);\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n this._focusItemAt(items, items.length - 1, -1);\r\n break;\r\n }\r\n }\r\n\r\n // ─── Private helpers ─────────────────────────────────────\r\n\r\n private _focusItemAt(items: HTMLElement[], start: number, step: 1 | -1): void {\r\n let i = start;\r\n while (i >= 0 && i < items.length) {\r\n if (!items[i].classList.contains('sidebar-nav-menu__item--disabled')) {\r\n items[i].focus();\r\n return;\r\n }\r\n i += step;\r\n }\r\n }\r\n\r\n private _hasParentSubmenu(itemEl: HTMLElement): boolean {\r\n return !!itemEl.closest('fui-sidebar-nav-submenu')?.parentElement?.closest('li');\r\n }\r\n\r\n private _focusParent(itemEl: HTMLElement): void {\r\n const parentSubmenu = itemEl.closest('fui-sidebar-nav-submenu')?.parentElement?.closest('li');\r\n\r\n if (parentSubmenu) {\r\n const parentTrigger = parentSubmenu.querySelector<HTMLElement>('.sidebar-nav-menu__item--parent');\r\n parentTrigger?.focus();\r\n }\r\n }\r\n}\r\n","<ul\r\n class=\"sidebar-nav-submenu\"\r\n role=\"group\"\r\n [class.sidebar-nav-submenu--root]=\"isRoot()\"\r\n [attr.aria-label]=\"submenuLabel()\"\r\n>\r\n @for (item of items(); track item.id; let idx = $index) {\r\n @if (item.visible !== false) {\r\n @if (item.separator) {\r\n <li class=\"sidebar-nav-menu__separator\" role=\"separator\"></li>\r\n } @else if (item.sectionHeader) {\r\n <li class=\"sidebar-nav-menu__section-header\" role=\"heading\" [attr.aria-level]=\"depth() + 2\">\r\n <span class=\"sidebar-nav-menu__section-header-label\">{{ item.label }}</span>\r\n </li>\r\n } @else {\r\n <li\r\n class=\"sidebar-nav-menu__item-wrapper\"\r\n role=\"none\"\r\n [class.sidebar-nav-menu__item-wrapper--root]=\"isRoot()\"\r\n [class.sidebar-nav-menu__item-wrapper--expanded]=\"hasChildren(item) && isExpanded(item)\"\r\n >\r\n @if (hasChildren(item)) {\r\n <!-- Parent item with submenu -->\r\n <button\r\n class=\"sidebar-nav-menu__item sidebar-nav-menu__item--parent\"\r\n type=\"button\"\r\n [class.sidebar-nav-menu__item--disabled]=\"item.disabled\"\r\n [class.sidebar-nav-menu__item--expanded]=\"isExpanded(item)\"\r\n [id]=\"item.id + '_trigger'\"\r\n [attr.aria-haspopup]=\"true\"\r\n [attr.aria-expanded]=\"isExpanded(item)\"\r\n [disabled]=\"item.disabled\"\r\n (click)=\"toggleExpand($event, item)\"\r\n (keydown)=\"onKeydown($event, item)\"\r\n >\r\n <span class=\"sidebar-nav-menu__item-content\">\r\n @if (item.icon) {\r\n <fui-icon\r\n class=\"sidebar-nav-menu__item-icon\"\r\n [name]=\"item.icon\"\r\n size=\"md\"\r\n aria-hidden=\"true\"\r\n ></fui-icon>\r\n }\r\n <span class=\"sidebar-nav-menu__item-label\">{{ item.label }}</span>\r\n </span>\r\n <fui-icon\r\n class=\"sidebar-nav-menu__item-chevron\"\r\n name=\"caret-right\"\r\n [class.sidebar-nav-menu__item-chevron--expanded]=\"isExpanded(item)\"\r\n size=\"sm\"\r\n aria-hidden=\"true\"\r\n ></fui-icon>\r\n </button>\r\n\r\n <!-- Submenu content with left border -->\r\n @if (isExpanded(item)) {\r\n <div\r\n class=\"sidebar-nav-submenu__inline\"\r\n animate.enter=\"sidebar-nav-submenu__inline--enter\"\r\n animate.leave=\"sidebar-nav-submenu__inline--leave\"\r\n >\r\n <div class=\"sidebar-nav-submenu__border\"></div>\r\n <fui-sidebar-nav-submenu\r\n [items]=\"item.items!\"\r\n [submenuLabel]=\"item.label || ''\"\r\n [isRoot]=\"false\"\r\n [depth]=\"depth() + 1\"\r\n (itemClick)=\"itemClick.emit($event)\"\r\n />\r\n </div>\r\n }\r\n } @else {\r\n <!-- Leaf item -->\r\n @if (item.routerLink) {\r\n <a\r\n class=\"sidebar-nav-menu__item\"\r\n routerLinkActive=\"sidebar-nav-menu__item--active\"\r\n [class.sidebar-nav-menu__item--disabled]=\"item.disabled\"\r\n [attr.tabindex]=\"item.disabled ? '-1' : '0'\"\r\n [attr.aria-disabled]=\"item.disabled ? 'true' : null\"\r\n [routerLink]=\"item.routerLink\"\r\n [queryParams]=\"item.queryParams || undefined\"\r\n [fragment]=\"item.fragment || undefined\"\r\n [target]=\"item.target\"\r\n [title]=\"item.title\"\r\n (click)=\"onLeafClick($event, item)\"\r\n (keydown)=\"onKeydown($event, item)\"\r\n >\r\n <span class=\"sidebar-nav-menu__item-content\">\r\n @if (item.icon) {\r\n <fui-icon\r\n class=\"sidebar-nav-menu__item-icon\"\r\n [name]=\"item.icon\"\r\n size=\"md\"\r\n aria-hidden=\"true\"\r\n ></fui-icon>\r\n }\r\n <span class=\"sidebar-nav-menu__item-label\">{{ item.label }}</span>\r\n </span>\r\n </a>\r\n } @else {\r\n <button\r\n class=\"sidebar-nav-menu__item\"\r\n type=\"button\"\r\n [class.sidebar-nav-menu__item--disabled]=\"item.disabled\"\r\n [attr.tabindex]=\"item.disabled ? '-1' : '0'\"\r\n [attr.aria-disabled]=\"item.disabled ? 'true' : null\"\r\n [title]=\"item.title\"\r\n [disabled]=\"item.disabled\"\r\n (click)=\"onLeafClick($event, item)\"\r\n (keydown)=\"onKeydown($event, item)\"\r\n >\r\n <span class=\"sidebar-nav-menu__item-content\">\r\n @if (item.icon) {\r\n <fui-icon\r\n class=\"sidebar-nav-menu__item-icon\"\r\n [name]=\"item.icon\"\r\n size=\"md\"\r\n aria-hidden=\"true\"\r\n ></fui-icon>\r\n }\r\n <span class=\"sidebar-nav-menu__item-label\">{{ item.label }}</span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </li>\r\n }\r\n }\r\n }\r\n</ul>\r\n","import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiSidebarNavSearchIntl extends FuiIntlBase {\r\n /** Placeholder text for the search input. */\r\n searchPlaceholder = 'Cerca';\r\n /** aria-label for the search input. */\r\n searchInputAriaLabel = 'Filtra';\r\n /** aria-label for the clear-search button. */\r\n clearSearchAriaLabel = 'Pulisci';\r\n}\r\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, inject, input, model } from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FuiSidebarNavSearchIntl } from './sidebar-nav-search.intl';\r\nimport { FuiInputDirective } from '@raintonic/formaui/components/input';\r\nimport { FuiFormFieldComponent, FuiPrefixDirective } from '@raintonic/formaui/components/form-field';\r\n\r\n/**\r\n * # FuiSidebarNavSearchComponent\r\n *\r\n * A standalone search input component designed to be placed inside the sidebar\r\n * navigation menu. Emits the current filter string so the parent component can\r\n * reactively filter menu items.\r\n *\r\n * ## Features\r\n * - Search input with magnifying-glass icon\r\n * - Clear button that appears when a query is entered\r\n * - Configurable placeholder text (falls back to `FuiSidebarNavSearchIntl` default)\r\n * - Two-way binding via `filterString` model\r\n * - Aria labels via `FuiSidebarNavSearchIntl` (overridable via DI)\r\n *\r\n * ## Usage\r\n *\r\n * ```html\r\n * <fui-sidebar-nav-search\r\n * [(filterString)]=\"myFilter\"\r\n * placeholder=\"Search…\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-sidebar-nav-search',\r\n standalone: true,\r\n imports: [FuiIconComponent, FuiInputDirective, FuiFormFieldComponent, FuiPrefixDirective],\r\n template: `\r\n <fui-form-field>\r\n <fui-icon fuiPrefix name=\"magnifying-glass\" color=\"var(--fui-text-disabled)\" size=\"sm\"></fui-icon>\r\n <input\r\n fuiInput\r\n #searchInput\r\n class=\"fui-sidebar-nav-search__input\"\r\n type=\"search\"\r\n [placeholder]=\"resolvedPlaceholder()\"\r\n [value]=\"filterString()\"\r\n (input)=\"filterString.set(searchInput.value)\"\r\n [attr.aria-label]=\"resolvedSearchInputAriaLabel()\"\r\n />\r\n </fui-form-field>\r\n `,\r\n styles: `\r\n :host {\r\n display: block;\r\n flex-shrink: 0;\r\n padding: var(--fui-spacing-4) var(--fui-spacing-6);\r\n padding-bottom: 0px;\r\n --fui-bg-subtle: var(--fui-bg-default);\r\n }\r\n `,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class FuiSidebarNavSearchComponent {\r\n readonly intl = inject(FuiSidebarNavSearchIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n constructor() {\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => {\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n /**\r\n * The current filter string. Two-way bindable.\r\n */\r\n readonly filterString = model('');\r\n\r\n /**\r\n * Placeholder text for the search input.\r\n * Falls back to the Intl default when not set.\r\n */\r\n readonly placeholder = input<string | undefined>();\r\n\r\n /** Resolved placeholder: input override -> Intl default. */\r\n readonly resolvedPlaceholder = computed(() => this.placeholder() ?? this.intl.searchPlaceholder);\r\n\r\n /** Resolved search-input aria-label: Intl default. */\r\n readonly resolvedSearchInputAriaLabel = computed(() => this.intl.searchInputAriaLabel);\r\n\r\n /** Resolved clear-button aria-label: Intl default. */\r\n readonly resolvedClearSearchAriaLabel = computed(() => this.intl.clearSearchAriaLabel);\r\n}\r\n","import { ChangeDetectionStrategy, Component, computed, input, model, output } from '@angular/core';\r\nimport { MenuItem } from '@raintonic/formaui/core';\r\nimport { SidebarNavSubmenuComponent } from './sidebar-nav-submenu.component';\r\nimport { FuiSidebarNavSearchComponent } from './sidebar-nav-search.component';\r\n\r\n/**\r\n * # FuiSidebarNavMenuComponent\r\n *\r\n * A standalone sidebar navigation menu component with recursive,\r\n * multi-level submenus. Inspired by PrimeNG's TieredMenu model\r\n * with a minimal, structural approach.\r\n *\r\n * ## Features\r\n * - Unlimited nesting depth via recursive submenu template\r\n * - Inline expand/collapse submenus\r\n * - Built-in search input with clear button\r\n * - Routing integration via `routerLink` with automatic active detection\r\n * - Keyboard navigation (Arrow keys, Enter/Space, Home/End)\r\n * - Full ARIA support (`role=\"navigation\"`, `aria-expanded`, `aria-haspopup`)\r\n *\r\n * ## Usage\r\n *\r\n * ```html\r\n * <fui-sidebar-nav-menu\r\n * [items]=\"menuItems\"\r\n * [(filterString)]=\"myFilter\"\r\n * (itemClick)=\"onMenuItemClick($event)\"\r\n * />\r\n * ```\r\n *\r\n * ```typescript\r\n * import { FuiSidebarNavMenuComponent, MenuItem } from '@raintonic/formaui/components/sidebar-nav-menu';\r\n *\r\n * @Component({\r\n * standalone: true,\r\n * imports: [FuiSidebarNavMenuComponent],\r\n * template: `...`,\r\n * })\r\n * export class MyLayout {\r\n * menuItems: MenuItem[] = [\r\n * { label: 'Dashboard', icon: 'house', routerLink: '/dashboard' },\r\n * {\r\n * label: 'Products',\r\n * icon: 'package',\r\n * items: [\r\n * { label: 'List', routerLink: '/products' },\r\n * { label: 'Categories', routerLink: '/categories' },\r\n * ],\r\n * },\r\n * { separator: true },\r\n * { label: 'Logout', command: () => this.logout() },\r\n * ];\r\n *\r\n * onMenuItemClick(item: MenuItem): void {\r\n * console.log('Menu item:', item.label);\r\n * }\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-sidebar-nav-menu',\r\n standalone: true,\r\n imports: [SidebarNavSubmenuComponent, FuiSidebarNavSearchComponent],\r\n templateUrl: './sidebar-nav-menu.component.html',\r\n styleUrl: './sidebar-nav-menu.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n role: 'navigation',\r\n '[attr.aria-label]': 'ariaLabel()',\r\n class: 'fui-sidebar-nav-menu',\r\n },\r\n})\r\nexport class FuiSidebarNavMenuComponent {\r\n /**\r\n * Array of menu items to render.\r\n */\r\n readonly items = input<MenuItem[]>([]);\r\n\r\n /**\r\n * Accessible label for the navigation region.\r\n * @default 'Sidebar menu'\r\n */\r\n readonly ariaLabel = input('Sidebar menu');\r\n\r\n /**\r\n * Optional filter string. When set, the menu displays only items whose label\r\n * contains the filter text (case-insensitive, substring match). Parent items\r\n * with matching descendants remain visible so the filtered child can be reached.\r\n * Separators and section headers are hidden during filtering.\r\n *\r\n * This is a two-way bindable model signal — set it programmatically or wire it\r\n * to the built-in search component.\r\n */\r\n readonly filterString = model('');\r\n\r\n /**\r\n * Emitted when any clickable menu item is activated.\r\n */\r\n readonly itemClick = output<MenuItem>();\r\n\r\n /**\r\n * Pure derivation that assigns unique IDs without mutating consumer data.\r\n * Each item is shallow-copied; the tree is walked recursively.\r\n */\r\n readonly _readyItems = computed(() => {\r\n let counter = 0;\r\n const assignIds = (list: readonly MenuItem[]): MenuItem[] =>\r\n list.map((it) => {\r\n const copy = { ...it, id: it.id ?? `fui-mi-${++counter}` };\r\n if (copy.items) copy.items = assignIds(copy.items);\r\n return copy;\r\n });\r\n return assignIds(this.items());\r\n });\r\n\r\n /**\r\n * Filtered items based on `filterString`. When the filter is non-empty,\r\n * items are kept if their label matches (case-insensitive substring) or\r\n * if any descendant matches. Separators and section headers are hidden\r\n * during filtering.\r\n */\r\n readonly _filteredItems = computed(() => {\r\n const filter = this.filterString().trim().toLowerCase();\r\n const items = this._readyItems();\r\n\r\n if (!filter) return items;\r\n\r\n const filterTree = (list: MenuItem[]): MenuItem[] =>\r\n list\r\n .filter((it) => !it.separator && !it.sectionHeader)\r\n .filter((item) => {\r\n const childrenMatch = item.items?.length ? filterTree(item.items).length > 0 : false;\r\n return !!item.label?.toLowerCase().includes(filter) || childrenMatch;\r\n })\r\n .map((item) => {\r\n const filteredChildren = item.items?.length ? filterTree(item.items) : undefined;\r\n return filteredChildren?.length ? { ...item, expanded: true, items: filteredChildren } : item;\r\n });\r\n\r\n return filterTree(items);\r\n });\r\n\r\n /** @internal Pass-through handler from submenu */\r\n _onItemClick(item: MenuItem): void {\r\n this.itemClick.emit(item);\r\n }\r\n}\r\n","<div class=\"fui-sidebar-nav-menu__header\">\r\n <ng-content select=\"[fuiSidebarNavHeader]\"></ng-content>\r\n</div>\r\n\r\n<fui-sidebar-nav-search [(filterString)]=\"filterString\" />\r\n\r\n<div class=\"fui-sidebar-nav-menu__body\">\r\n <fui-sidebar-nav-submenu\r\n [items]=\"_filteredItems()\"\r\n [submenuLabel]=\"ariaLabel()\"\r\n [isRoot]=\"true\"\r\n (itemClick)=\"_onItemClick($event)\"\r\n />\r\n</div>\r\n\r\n<div class=\"fui-sidebar-nav-menu__footer\">\r\n <ng-content select=\"[fuiSidebarNavFooter]\"></ng-content>\r\n</div>\r\n","import { MenuItem } from '@raintonic/formaui/core';\r\n\r\n/**\r\n * Walk a menu item tree and set `expanded: true` on every parent whose\r\n * descendant chain contains a `routerLink` that matches the current URL.\r\n *\r\n * The function is **immutable** — it clones items only when it needs to mutate\r\n * them, returning the same reference for untouched subtrees.\r\n *\r\n * ## Usage\r\n *\r\n * ```typescript\r\n * import { expandMenuItems } from '@raintonic/formaui/components/sidebar-nav-menu';\r\n *\r\n * const items = expandMenuItems(myMenuItems, '/products/categories');\r\n * ```\r\n *\r\n * @param items - Menu item tree\r\n * @param currentUrl - The current URL path (e.g. `'/products/categories'`)\r\n * @returns A new tree with `expanded` set on matching parent items\r\n */\r\nexport function expandMenuItems(items: readonly MenuItem[], currentUrl: string): MenuItem[] {\r\n const result: MenuItem[] = [];\r\n\r\n for (const item of items) {\r\n // Separators and section headers are never expandable — pass through unchanged\r\n if (item.separator || item.sectionHeader) {\r\n result.push(item);\r\n continue;\r\n }\r\n\r\n const hasChildMatch = item.items && containsActiveDescendant(item.items, currentUrl);\r\n\r\n if (hasChildMatch) {\r\n // Clone the item, set expanded, and recurse into children\r\n result.push({\r\n ...item,\r\n expanded: true,\r\n items: expandMenuItems(item.items!, currentUrl),\r\n });\r\n } else if (item.expanded) {\r\n // No descendants match — reset expanded to false so the consumer's initial\r\n // state doesn't leak through\r\n result.push({ ...item, expanded: false });\r\n } else {\r\n result.push(item);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Returns `true` if any item in the list has a `routerLink` matching\r\n * `currentUrl`, or if any descendant of an item matches (recursive).\r\n */\r\nfunction containsActiveDescendant(items: readonly MenuItem[], currentUrl: string): boolean {\r\n return items.some((item) => {\r\n if (matchesUrl(item.routerLink, currentUrl)) return true;\r\n if (item.items && containsActiveDescendant(item.items, currentUrl)) return true;\r\n return false;\r\n });\r\n}\r\n\r\n/**\r\n * Normalise and compare a `routerLink` value against the current URL string.\r\n */\r\nfunction matchesUrl(routerLink: string | any[] | undefined, currentUrl: string): boolean {\r\n if (!routerLink) return false;\r\n if (typeof routerLink === 'string') {\r\n return normalise(routerLink) === normalise(currentUrl);\r\n }\r\n // routerLink as array — join segments to form the path\r\n const segments = routerLink.map(String).filter(Boolean);\r\n return segments.length > 0 && normalise(segments.join('/')) === normalise(currentUrl);\r\n}\r\n\r\n/**\r\n * Strip query string, fragment, and leading/trailing slashes for comparison.\r\n * `Router.url` includes query params and fragment (e.g. `/products?page=2#top`),\r\n * which must not prevent the path from matching a plain `routerLink`.\r\n */\r\nfunction normalise(p: string): string {\r\n const pathOnly = p.split(/[?#]/)[0];\r\n return pathOnly.replace(/^\\/+|\\/+$/g, '');\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;AAKA;;;;;;;;;;;;;AAaG;MAQU,0BAA0B,CAAA;;AAE5B,IAAA,KAAK,GAAG,KAAK,CAAC,EAAgB,4EAAC;;AAG/B,IAAA,YAAY,GAAG,KAAK,CAAC,EAAE,mFAAC;;AAGxB,IAAA,MAAM,GAAG,KAAK,CAAC,KAAK,6EAAC;;AAGrB,IAAA,KAAK,GAAG,KAAK,CAAC,CAAC,4EAAC;;IAGhB,SAAS,GAAG,MAAM,EAAY;;AAG9B,IAAA,SAAS,GAAG,MAAM,CAAC,IAAI,GAAG,EAAU,gFAAC;AAE9C,IAAA,WAAA,GAAA;;;;;;;QAOE,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU;AAElC,YAAA,MAAM,IAAI,GAAG,CAAC,IAAgB,KAAI;AAChC,gBAAA,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE;oBACrB,IAAI,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE;AACnC,wBAAA,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAG,CAAC;oBACtB;oBACA,IAAI,EAAE,CAAC,KAAK;AAAE,wBAAA,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC;gBAC9B;AACF,YAAA,CAAC;AACD,YAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;AAClB,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC9B,QAAA,CAAC,CAAC;IACJ;;;AAKA,IAAA,WAAW,CAAC,IAAc,EAAA;AACxB,QAAA,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAChD;;AAGA,IAAA,UAAU,CAAC,IAAc,EAAA;AACvB,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AAAE,YAAA,OAAO,KAAK;QACzC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAG,CAAC;IACvC;;IAGA,YAAY,CAAC,KAAY,EAAE,IAAc,EAAA;QACvC,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;QACvB,IAAI,IAAI,CAAC,QAAQ;YAAE;AAEnB,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAG,CAAC;QAElD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAI;AAC1B,YAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AACvB,YAAA,MAAM,EAAE,GAAG,IAAI,CAAC,EAAG;YAEnB,IAAI,WAAW,EAAE;;AAEf,gBAAA,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACjB;iBAAO;;AAEL,gBAAA,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE;;oBAEjB,IAAI,CAAC,KAAK,EAAE;gBACd;AACA,gBAAA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACd;AAEA,YAAA,OAAO,IAAI;AACb,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,YAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB;AACA,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B;;IAGA,WAAW,CAAC,KAAY,EAAE,IAAc,EAAA;AACtC,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,KAAK,CAAC,cAAc,EAAE;YACtB;QACF;AAEA,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,YAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB;AAEA,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B;;IAGA,SAAS,CAAC,KAAoB,EAAE,IAAc,EAAA;QAC5C,IAAI,IAAI,CAAC,QAAQ;YAAE;AAEnB,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,aAAmC;AACxD,QAAA,IAAI,CAAC,MAAM;YAAE;QAEb,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAuB;AACzD,QAAA,IAAI,CAAC,MAAM;YAAE;;AAGb,QAAA,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAc,uCAAuC,CAAC,CAAC;QACvG,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAE1C,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,WAAW;gBACd,KAAK,CAAC,cAAc,EAAE;gBACtB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC7C;AACF,YAAA,KAAK,SAAS;gBACZ,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC9C;AACF,YAAA,KAAK,YAAY;gBACf,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;oBACpD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAI;AAC1B,wBAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AACvB,wBAAA,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE;;4BAEjB,IAAI,CAAC,KAAK,EAAE;wBACd;AACA,wBAAA,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAG,CAAC;AAClB,wBAAA,OAAO,IAAI;AACb,oBAAA,CAAC,CAAC;gBACJ;gBACA;AACF,YAAA,KAAK,WAAW;AACd,gBAAA,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;oBACnD,KAAK,CAAC,cAAc,EAAE;oBACtB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAI;AAC1B,wBAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AACvB,wBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAG,CAAC;AACrB,wBAAA,OAAO,IAAI;AACb,oBAAA,CAAC,CAAC;gBACJ;AACA,gBAAA,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE;oBAClC,KAAK,CAAC,cAAc,EAAE;AACtB,oBAAA,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;gBAC3B;gBACA;AACF,YAAA,KAAK,OAAO;AACZ,YAAA,KAAK,GAAG;gBACN,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;AAC1B,oBAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC;gBAChC;qBAAO;oBACL,MAAM,CAAC,KAAK,EAAE;gBAChB;gBACA;AACF,YAAA,KAAK,MAAM;gBACT,KAAK,CAAC,cAAc,EAAE;gBACtB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC9B;AACF,YAAA,KAAK,KAAK;gBACR,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC9C;;IAEN;;AAIQ,IAAA,YAAY,CAAC,KAAoB,EAAE,KAAa,EAAE,IAAY,EAAA;QACpE,IAAI,CAAC,GAAG,KAAK;QACb,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE;AACjC,YAAA,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,kCAAkC,CAAC,EAAE;AACpE,gBAAA,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;gBAChB;YACF;YACA,CAAC,IAAI,IAAI;QACX;IACF;AAEQ,IAAA,iBAAiB,CAAC,MAAmB,EAAA;AAC3C,QAAA,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC;IAClF;AAEQ,IAAA,YAAY,CAAC,MAAmB,EAAA;AACtC,QAAA,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC;QAE7F,IAAI,aAAa,EAAE;YACjB,MAAM,aAAa,GAAG,aAAa,CAAC,aAAa,CAAc,iCAAiC,CAAC;YACjG,aAAa,EAAE,KAAK,EAAE;QACxB;IACF;uGArMW,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAA1B,0BAA0B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC1BvC,6rLAoIA,EAAA,MAAA,EAAA,CAAA,ojQAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED1Ga,0BAA0B,kJAJ3B,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,uBAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,QAAA,EAAA,OAAA,EAAA,WAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAI7C,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBAPtC,SAAS;+BACE,yBAAyB,EAAA,UAAA,EACvB,IAAI,EAAA,OAAA,EACP,CAAC,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,EAAA,QAAA,EAAA,6rLAAA,EAAA,MAAA,EAAA,CAAA,ojQAAA,CAAA,EAAA;;;AElBrD,MAAO,uBAAwB,SAAQ,WAAW,CAAA;;IAEtD,iBAAiB,GAAG,OAAO;;IAE3B,oBAAoB,GAAG,QAAQ;;IAE/B,oBAAoB,GAAG,SAAS;uGANrB,uBAAuB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAvB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,uBAAuB,cADV,MAAM,EAAA,CAAA;;2FACnB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBADnC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACIlC;;;;;;;;;;;;;;;;;;;;;;AAsBG;MA+BU,4BAA4B,CAAA;AAC9B,IAAA,IAAI,GAAG,MAAM,CAAC,uBAAuB,CAAC;AAC9B,IAAA,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAEjD,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS,CAAC,MAAK;AAC1D,YAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;AAC1B,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;AACM,IAAA,YAAY,GAAG,KAAK,CAAC,EAAE,mFAAC;AAEjC;;;AAGG;IACM,WAAW,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAsB;;AAGzC,IAAA,mBAAmB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,iBAAiB,0FAAC;;AAGvF,IAAA,4BAA4B,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,8BAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;;AAG7E,IAAA,4BAA4B,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,8BAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;uGA5B3E,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAA5B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,4BAA4B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,YAAA,EAAA,oBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA1B7B,CAAA;;;;;;;;;;;;;;AAcT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,gJAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAfS,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,QAAA,EAAA,OAAA,EAAA,WAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,iBAAiB,EAAA,QAAA,EAAA,uDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,aAAA,EAAA,UAAA,EAAA,WAAA,EAAA,WAAA,EAAA,SAAA,EAAA,mBAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,qBAAqB,0HAAE,kBAAkB,EAAA,QAAA,EAAA,aAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FA2B7E,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBA9BxC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wBAAwB,EAAA,UAAA,EACtB,IAAI,EAAA,OAAA,EACP,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,kBAAkB,CAAC,EAAA,QAAA,EAC/E,CAAA;;;;;;;;;;;;;;GAcT,EAAA,eAAA,EAUgB,uBAAuB,CAAC,MAAM,EAAA,MAAA,EAAA,CAAA,gJAAA,CAAA,EAAA;;;ACrDjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDG;MAcU,0BAA0B,CAAA;AACrC;;AAEG;AACM,IAAA,KAAK,GAAG,KAAK,CAAa,EAAE,4EAAC;AAEtC;;;AAGG;AACM,IAAA,SAAS,GAAG,KAAK,CAAC,cAAc,gFAAC;AAE1C;;;;;;;;AAQG;AACM,IAAA,YAAY,GAAG,KAAK,CAAC,EAAE,mFAAC;AAEjC;;AAEG;IACM,SAAS,GAAG,MAAM,EAAY;AAEvC;;;AAGG;AACM,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;QACnC,IAAI,OAAO,GAAG,CAAC;AACf,QAAA,MAAM,SAAS,GAAG,CAAC,IAAyB,KAC1C,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAI;AACd,YAAA,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAA,OAAA,EAAU,EAAE,OAAO,CAAA,CAAE,EAAE;YAC1D,IAAI,IAAI,CAAC,KAAK;gBAAE,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;AAClD,YAAA,OAAO,IAAI;AACb,QAAA,CAAC,CAAC;AACJ,QAAA,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;AAChC,IAAA,CAAC,kFAAC;AAEF;;;;;AAKG;AACM,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAK;AACtC,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;AACvD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE;AAEhC,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,KAAK;AAEzB,QAAA,MAAM,UAAU,GAAG,CAAC,IAAgB,KAClC;AACG,aAAA,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC,aAAa;AACjD,aAAA,MAAM,CAAC,CAAC,IAAI,KAAI;YACf,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK;AACpF,YAAA,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,aAAa;AACtE,QAAA,CAAC;AACA,aAAA,GAAG,CAAC,CAAC,IAAI,KAAI;YACZ,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS;YAChF,OAAO,gBAAgB,EAAE,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,IAAI;AAC/F,QAAA,CAAC,CAAC;AAEN,QAAA,OAAO,UAAU,CAAC,KAAK,CAAC;AAC1B,IAAA,CAAC,qFAAC;;AAGF,IAAA,YAAY,CAAC,IAAc,EAAA;AACzB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B;uGAzEW,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAA1B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,0BAA0B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,YAAA,EAAA,oBAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,MAAA,EAAA,YAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,EAAA,cAAA,EAAA,sBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECxEvC,+iBAkBA,EAAA,MAAA,EAAA,CAAA,ojQAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED4CY,0BAA0B,kJAAE,4BAA4B,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,CAAA,cAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAUvD,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBAbtC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,sBAAsB,EAAA,UAAA,EACpB,IAAI,EAAA,OAAA,EACP,CAAC,0BAA0B,EAAE,4BAA4B,CAAC,EAAA,eAAA,EAGlD,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC;AACJ,wBAAA,IAAI,EAAE,YAAY;AAClB,wBAAA,mBAAmB,EAAE,aAAa;AAClC,wBAAA,KAAK,EAAE,sBAAsB;AAC9B,qBAAA,EAAA,QAAA,EAAA,+iBAAA,EAAA,MAAA,EAAA,CAAA,ojQAAA,CAAA,EAAA;;;AEpEH;;;;;;;;;;;;;;;;;;AAkBG;AACG,SAAU,eAAe,CAAC,KAA0B,EAAE,UAAkB,EAAA;IAC5E,MAAM,MAAM,GAAe,EAAE;AAE7B,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;;QAExB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,EAAE;AACxC,YAAA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YACjB;QACF;AAEA,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,IAAI,wBAAwB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC;QAEpF,IAAI,aAAa,EAAE;;YAEjB,MAAM,CAAC,IAAI,CAAC;AACV,gBAAA,GAAG,IAAI;AACP,gBAAA,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,KAAM,EAAE,UAAU,CAAC;AAChD,aAAA,CAAC;QACJ;AAAO,aAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;;;AAGxB,YAAA,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC3C;aAAO;AACL,YAAA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACnB;IACF;AAEA,IAAA,OAAO,MAAM;AACf;AAEA;;;AAGG;AACH,SAAS,wBAAwB,CAAC,KAA0B,EAAE,UAAkB,EAAA;AAC9E,IAAA,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAI;AACzB,QAAA,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC;AAAE,YAAA,OAAO,IAAI;QACxD,IAAI,IAAI,CAAC,KAAK,IAAI,wBAAwB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC;AAAE,YAAA,OAAO,IAAI;AAC/E,QAAA,OAAO,KAAK;AACd,IAAA,CAAC,CAAC;AACJ;AAEA;;AAEG;AACH,SAAS,UAAU,CAAC,UAAsC,EAAE,UAAkB,EAAA;AAC5E,IAAA,IAAI,CAAC,UAAU;AAAE,QAAA,OAAO,KAAK;AAC7B,IAAA,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;QAClC,OAAO,SAAS,CAAC,UAAU,CAAC,KAAK,SAAS,CAAC,UAAU,CAAC;IACxD;;AAEA,IAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IACvD,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,SAAS,CAAC,UAAU,CAAC;AACvF;AAEA;;;;AAIG;AACH,SAAS,SAAS,CAAC,CAAS,EAAA;IAC1B,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;AAC3C;;ACrFA;;AAEG;;;;"}
|
|
@@ -339,7 +339,7 @@ class FuiSliderComponent {
|
|
|
339
339
|
useExisting: FuiSliderComponent,
|
|
340
340
|
multi: true,
|
|
341
341
|
},
|
|
342
|
-
], viewQueries: [{ propertyName: "_sliderContainer", first: true, predicate: ["sliderContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"fui-slider__container\" (click)=\"_onTrackClick($event)\" #sliderContainer>\r\n <div class=\"fui-slider__track\">\r\n <div\r\n class=\"fui-slider__track-fill\"\r\n [style.left.%]=\"range() ? _percentageLow() : 0\"\r\n [style.width.%]=\"range() ? _percentageHigh() - _percentageLow() : _percentage()\"\r\n ></div>\r\n </div>\r\n\r\n @if (showTicks()) {\r\n <div class=\"fui-slider__ticks\">\r\n @for (tick of _tickValues(); track tick) {\r\n <div\r\n class=\"fui-slider__tick\"\r\n [style.left.%]=\"_valueToPercent(tick)\"\r\n [class.fui-slider__tick--active]=\"_isTickActive(tick)\"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--low\"\r\n [style.left.%]=\"range() ? _percentageLow() : _percentage()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"range() ? _valueLow() : _value()\"\r\n [attr.aria-valuemin]=\"min()\"\r\n [attr.aria-valuemax]=\"range() ? _valueHigh() : max()\"\r\n [attr.aria-label]=\"range() ? (ariaLabelLow() || intl.minValueAriaLabel) : (ariaLabel() || null)\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'low')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'low')\"\r\n (keydown)=\"_onThumbKeydown($event, 'low')\"\r\n (focus)=\"_hovered.set('low')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'low' || _hovered() === 'low')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(range() ? _valueLow() : _value()) }}</div>\r\n }\r\n </div>\r\n\r\n @if (range()) {\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--high\"\r\n [style.left.%]=\"_percentageHigh()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"_valueHigh()\"\r\n [attr.aria-valuemin]=\"_valueLow()\"\r\n [attr.aria-valuemax]=\"max()\"\r\n [attr.aria-label]=\"ariaLabelHigh() || intl.maxValueAriaLabel\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'high')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'high')\"\r\n (keydown)=\"_onThumbKeydown($event, 'high')\"\r\n (focus)=\"_hovered.set('high')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'high' || _hovered() === 'high')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(_valueHigh()) }}</div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-slider{display:block;position:relative;width:100%;padding:10px 0;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fui-slider__container{position:relative;width:100%;height:20px;display:flex;align-items:center}.fui-slider__track{position:absolute;left:0;right:0;height:8px;border-radius:var(--fui-radius-pill, 999px);background-color:var(--fui-neutral-30, #e2e8f0);overflow:hidden}.fui-slider__track-fill{position:absolute;top:0;bottom:0;background-color:var(--fui-accent-bg);border-radius:var(--fui-radius-pill, 999px);transition-property:left,width;transition-duration:var(--fui-duration-fast, 70ms);transition-timing-function:var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-delay:0ms}.fui-slider__ticks{position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);pointer-events:none}.fui-slider__tick{position:absolute;width:8px;height:8px;border-radius:50%;background-color:var(--fui-neutral-50, #94a3b8);transform:translate(-50%,-50%);top:50%;transition-property:background-color;transition-duration:var(--fui-duration-fast, .15s);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-slider__tick--active{background-color:var(--fui-bg-subtle)}.fui-slider__thumb{position:absolute;width:20px;height:20px;border-radius:50%;background-color:var(--fui-bg-subtle);border:
|
|
342
|
+
], viewQueries: [{ propertyName: "_sliderContainer", first: true, predicate: ["sliderContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"fui-slider__container\" (click)=\"_onTrackClick($event)\" #sliderContainer>\r\n <div class=\"fui-slider__track\">\r\n <div\r\n class=\"fui-slider__track-fill\"\r\n [style.left.%]=\"range() ? _percentageLow() : 0\"\r\n [style.width.%]=\"range() ? _percentageHigh() - _percentageLow() : _percentage()\"\r\n ></div>\r\n </div>\r\n\r\n @if (showTicks()) {\r\n <div class=\"fui-slider__ticks\">\r\n @for (tick of _tickValues(); track tick) {\r\n <div\r\n class=\"fui-slider__tick\"\r\n [style.left.%]=\"_valueToPercent(tick)\"\r\n [class.fui-slider__tick--active]=\"_isTickActive(tick)\"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--low\"\r\n [style.left.%]=\"range() ? _percentageLow() : _percentage()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"range() ? _valueLow() : _value()\"\r\n [attr.aria-valuemin]=\"min()\"\r\n [attr.aria-valuemax]=\"range() ? _valueHigh() : max()\"\r\n [attr.aria-label]=\"range() ? (ariaLabelLow() || intl.minValueAriaLabel) : (ariaLabel() || null)\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'low')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'low')\"\r\n (keydown)=\"_onThumbKeydown($event, 'low')\"\r\n (focus)=\"_hovered.set('low')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'low' || _hovered() === 'low')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(range() ? _valueLow() : _value()) }}</div>\r\n }\r\n </div>\r\n\r\n @if (range()) {\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--high\"\r\n [style.left.%]=\"_percentageHigh()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"_valueHigh()\"\r\n [attr.aria-valuemin]=\"_valueLow()\"\r\n [attr.aria-valuemax]=\"max()\"\r\n [attr.aria-label]=\"ariaLabelHigh() || intl.maxValueAriaLabel\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'high')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'high')\"\r\n (keydown)=\"_onThumbKeydown($event, 'high')\"\r\n (focus)=\"_hovered.set('high')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'high' || _hovered() === 'high')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(_valueHigh()) }}</div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-slider{display:block;position:relative;width:100%;padding:10px 0;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fui-slider__container{position:relative;width:100%;height:20px;display:flex;align-items:center}.fui-slider__track{position:absolute;left:0;right:0;height:8px;border-radius:var(--fui-radius-pill, 999px);background-color:var(--fui-neutral-30, #e2e8f0);overflow:hidden}.fui-slider__track-fill{position:absolute;top:0;bottom:0;background-color:var(--fui-accent-bg);border-radius:var(--fui-radius-pill, 999px);transition-property:left,width;transition-duration:var(--fui-duration-fast, 70ms);transition-timing-function:var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-delay:0ms}.fui-slider__ticks{position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);pointer-events:none}.fui-slider__tick{position:absolute;width:8px;height:8px;border-radius:50%;background-color:var(--fui-neutral-50, #94a3b8);transform:translate(-50%,-50%);top:50%;transition-property:background-color;transition-duration:var(--fui-duration-fast, .15s);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-slider__tick--active{background-color:var(--fui-bg-subtle)}.fui-slider__thumb{position:absolute;width:20px;height:20px;border-radius:50%;background-color:var(--fui-bg-subtle);border:var(--fui-border-width-sm) solid var(--fui-accent-bg);transform:translate(-50%);cursor:grab;z-index:2;outline:none;transition-property:left,transform,box-shadow;transition-duration:var(--fui-duration-fast, 70ms);transition-timing-function:var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-delay:0ms}.fui-slider__thumb:hover{box-shadow:0 0 0 6px color-mix(in srgb,var(--fui-primary-50) 15%,transparent)}.fui-slider__thumb:focus-visible{outline:2px solid var(--fui-primary-10)}.fui-slider__tooltip{position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);padding:4px 8px;background-color:var(--fui-bg-inverse, #1e293b);color:var(--fui-text-inverse, #fff);font-family:var(--fui-font-sans);font-size:var(--fui-text-sm, .75rem);font-weight:var(--fui-weight-medium, 500);line-height:var(--fui-leading-tight);white-space:nowrap;border-radius:var(--fui-radius-sm, 4px);pointer-events:none;transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-slider__tooltip:after{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-top-color:var(--fui-bg-inverse, #1e293b)}.fui-slider--dragging .fui-slider__thumb{cursor:grabbing;transform:translate(-50%) scale(1.15);box-shadow:0 0 0 8px color-mix(in srgb,var(--fui-primary-50) 20%,transparent)}.fui-slider--dragging .fui-slider__track-fill{transition:none}.fui-slider--disabled{cursor:not-allowed;opacity:var(--fui-state-disabled-opacity, .38);pointer-events:none}.fui-slider--disabled .fui-slider__thumb{cursor:not-allowed}.fui-slider--range .fui-slider__thumb--high{z-index:3}@media(prefers-contrast:high){.fui-slider__thumb{border:2px solid CanvasText}.fui-slider__track{border:1px solid CanvasText}}@media(prefers-reduced-motion:reduce){.fui-slider__thumb,.fui-slider__track-fill,.fui-slider__tooltip,.fui-slider__tick{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
343
343
|
}
|
|
344
344
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiSliderComponent, decorators: [{
|
|
345
345
|
type: Component,
|
|
@@ -354,7 +354,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
354
354
|
useExisting: FuiSliderComponent,
|
|
355
355
|
multi: true,
|
|
356
356
|
},
|
|
357
|
-
], template: "<div class=\"fui-slider__container\" (click)=\"_onTrackClick($event)\" #sliderContainer>\r\n <div class=\"fui-slider__track\">\r\n <div\r\n class=\"fui-slider__track-fill\"\r\n [style.left.%]=\"range() ? _percentageLow() : 0\"\r\n [style.width.%]=\"range() ? _percentageHigh() - _percentageLow() : _percentage()\"\r\n ></div>\r\n </div>\r\n\r\n @if (showTicks()) {\r\n <div class=\"fui-slider__ticks\">\r\n @for (tick of _tickValues(); track tick) {\r\n <div\r\n class=\"fui-slider__tick\"\r\n [style.left.%]=\"_valueToPercent(tick)\"\r\n [class.fui-slider__tick--active]=\"_isTickActive(tick)\"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--low\"\r\n [style.left.%]=\"range() ? _percentageLow() : _percentage()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"range() ? _valueLow() : _value()\"\r\n [attr.aria-valuemin]=\"min()\"\r\n [attr.aria-valuemax]=\"range() ? _valueHigh() : max()\"\r\n [attr.aria-label]=\"range() ? (ariaLabelLow() || intl.minValueAriaLabel) : (ariaLabel() || null)\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'low')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'low')\"\r\n (keydown)=\"_onThumbKeydown($event, 'low')\"\r\n (focus)=\"_hovered.set('low')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'low' || _hovered() === 'low')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(range() ? _valueLow() : _value()) }}</div>\r\n }\r\n </div>\r\n\r\n @if (range()) {\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--high\"\r\n [style.left.%]=\"_percentageHigh()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"_valueHigh()\"\r\n [attr.aria-valuemin]=\"_valueLow()\"\r\n [attr.aria-valuemax]=\"max()\"\r\n [attr.aria-label]=\"ariaLabelHigh() || intl.maxValueAriaLabel\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'high')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'high')\"\r\n (keydown)=\"_onThumbKeydown($event, 'high')\"\r\n (focus)=\"_hovered.set('high')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'high' || _hovered() === 'high')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(_valueHigh()) }}</div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-slider{display:block;position:relative;width:100%;padding:10px 0;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fui-slider__container{position:relative;width:100%;height:20px;display:flex;align-items:center}.fui-slider__track{position:absolute;left:0;right:0;height:8px;border-radius:var(--fui-radius-pill, 999px);background-color:var(--fui-neutral-30, #e2e8f0);overflow:hidden}.fui-slider__track-fill{position:absolute;top:0;bottom:0;background-color:var(--fui-accent-bg);border-radius:var(--fui-radius-pill, 999px);transition-property:left,width;transition-duration:var(--fui-duration-fast, 70ms);transition-timing-function:var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-delay:0ms}.fui-slider__ticks{position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);pointer-events:none}.fui-slider__tick{position:absolute;width:8px;height:8px;border-radius:50%;background-color:var(--fui-neutral-50, #94a3b8);transform:translate(-50%,-50%);top:50%;transition-property:background-color;transition-duration:var(--fui-duration-fast, .15s);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-slider__tick--active{background-color:var(--fui-bg-subtle)}.fui-slider__thumb{position:absolute;width:20px;height:20px;border-radius:50%;background-color:var(--fui-bg-subtle);border:
|
|
357
|
+
], template: "<div class=\"fui-slider__container\" (click)=\"_onTrackClick($event)\" #sliderContainer>\r\n <div class=\"fui-slider__track\">\r\n <div\r\n class=\"fui-slider__track-fill\"\r\n [style.left.%]=\"range() ? _percentageLow() : 0\"\r\n [style.width.%]=\"range() ? _percentageHigh() - _percentageLow() : _percentage()\"\r\n ></div>\r\n </div>\r\n\r\n @if (showTicks()) {\r\n <div class=\"fui-slider__ticks\">\r\n @for (tick of _tickValues(); track tick) {\r\n <div\r\n class=\"fui-slider__tick\"\r\n [style.left.%]=\"_valueToPercent(tick)\"\r\n [class.fui-slider__tick--active]=\"_isTickActive(tick)\"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--low\"\r\n [style.left.%]=\"range() ? _percentageLow() : _percentage()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"range() ? _valueLow() : _value()\"\r\n [attr.aria-valuemin]=\"min()\"\r\n [attr.aria-valuemax]=\"range() ? _valueHigh() : max()\"\r\n [attr.aria-label]=\"range() ? (ariaLabelLow() || intl.minValueAriaLabel) : (ariaLabel() || null)\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'low')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'low')\"\r\n (keydown)=\"_onThumbKeydown($event, 'low')\"\r\n (focus)=\"_hovered.set('low')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'low' || _hovered() === 'low')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(range() ? _valueLow() : _value()) }}</div>\r\n }\r\n </div>\r\n\r\n @if (range()) {\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--high\"\r\n [style.left.%]=\"_percentageHigh()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"_valueHigh()\"\r\n [attr.aria-valuemin]=\"_valueLow()\"\r\n [attr.aria-valuemax]=\"max()\"\r\n [attr.aria-label]=\"ariaLabelHigh() || intl.maxValueAriaLabel\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'high')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'high')\"\r\n (keydown)=\"_onThumbKeydown($event, 'high')\"\r\n (focus)=\"_hovered.set('high')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'high' || _hovered() === 'high')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(_valueHigh()) }}</div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-slider{display:block;position:relative;width:100%;padding:10px 0;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fui-slider__container{position:relative;width:100%;height:20px;display:flex;align-items:center}.fui-slider__track{position:absolute;left:0;right:0;height:8px;border-radius:var(--fui-radius-pill, 999px);background-color:var(--fui-neutral-30, #e2e8f0);overflow:hidden}.fui-slider__track-fill{position:absolute;top:0;bottom:0;background-color:var(--fui-accent-bg);border-radius:var(--fui-radius-pill, 999px);transition-property:left,width;transition-duration:var(--fui-duration-fast, 70ms);transition-timing-function:var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-delay:0ms}.fui-slider__ticks{position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);pointer-events:none}.fui-slider__tick{position:absolute;width:8px;height:8px;border-radius:50%;background-color:var(--fui-neutral-50, #94a3b8);transform:translate(-50%,-50%);top:50%;transition-property:background-color;transition-duration:var(--fui-duration-fast, .15s);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-slider__tick--active{background-color:var(--fui-bg-subtle)}.fui-slider__thumb{position:absolute;width:20px;height:20px;border-radius:50%;background-color:var(--fui-bg-subtle);border:var(--fui-border-width-sm) solid var(--fui-accent-bg);transform:translate(-50%);cursor:grab;z-index:2;outline:none;transition-property:left,transform,box-shadow;transition-duration:var(--fui-duration-fast, 70ms);transition-timing-function:var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-delay:0ms}.fui-slider__thumb:hover{box-shadow:0 0 0 6px color-mix(in srgb,var(--fui-primary-50) 15%,transparent)}.fui-slider__thumb:focus-visible{outline:2px solid var(--fui-primary-10)}.fui-slider__tooltip{position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);padding:4px 8px;background-color:var(--fui-bg-inverse, #1e293b);color:var(--fui-text-inverse, #fff);font-family:var(--fui-font-sans);font-size:var(--fui-text-sm, .75rem);font-weight:var(--fui-weight-medium, 500);line-height:var(--fui-leading-tight);white-space:nowrap;border-radius:var(--fui-radius-sm, 4px);pointer-events:none;transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-slider__tooltip:after{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-top-color:var(--fui-bg-inverse, #1e293b)}.fui-slider--dragging .fui-slider__thumb{cursor:grabbing;transform:translate(-50%) scale(1.15);box-shadow:0 0 0 8px color-mix(in srgb,var(--fui-primary-50) 20%,transparent)}.fui-slider--dragging .fui-slider__track-fill{transition:none}.fui-slider--disabled{cursor:not-allowed;opacity:var(--fui-state-disabled-opacity, .38);pointer-events:none}.fui-slider--disabled .fui-slider__thumb{cursor:not-allowed}.fui-slider--range .fui-slider__thumb--high{z-index:3}@media(prefers-contrast:high){.fui-slider__thumb{border:2px solid CanvasText}.fui-slider__track{border:1px solid CanvasText}}@media(prefers-reduced-motion:reduce){.fui-slider__thumb,.fui-slider__track-fill,.fui-slider__tooltip,.fui-slider__tick{transition:none}}\n"] }]
|
|
358
358
|
}], ctorParameters: () => [], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], range: [{ type: i0.Input, args: [{ isSignal: true, alias: "range", required: false }] }], showTicks: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTicks", required: false }] }], showTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTooltip", required: false }] }], formatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelLow: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelLow", required: false }] }], ariaLabelHigh: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelHigh", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], dragStart: [{ type: i0.Output, args: ["dragStart"] }], dragEnd: [{ type: i0.Output, args: ["dragEnd"] }], _sliderContainer: [{ type: i0.ViewChild, args: ['sliderContainer', { isSignal: true }] }] } });
|
|
359
359
|
|
|
360
360
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raintonic-formaui-components-slider.mjs","sources":["../../../lib/components/slider/slider.intl.ts","../../../lib/components/slider/slider.component.ts","../../../lib/components/slider/slider.component.html","../../../lib/components/slider/raintonic-formaui-components-slider.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiSliderIntl extends FuiIntlBase {\r\n minValueAriaLabel = 'Minimum value';\r\n maxValueAriaLabel = 'Maximum value';\r\n}\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n computed,\r\n signal,\r\n viewChild,\r\n ElementRef,\r\n Signal,\r\n WritableSignal,\r\n OnDestroy,\r\n booleanAttribute,\r\n DOCUMENT,\r\n inject,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { SliderValue, SliderFormatLabelFn } from './slider.types';\r\nimport { FuiSliderIntl } from './slider.intl';\r\n\r\n/**\r\n * # FuiSliderComponent\r\n *\r\n * A slider (range input) component with single and dual-thumb (range) support.\r\n * Integrates with Angular Reactive Forms via ControlValueAccessor.\r\n *\r\n * ## Features\r\n * - Single value and range (dual-thumb) modes\r\n * - Configurable min/max/step\r\n * - Optional tick marks and tooltips\r\n * - Custom label formatting\r\n * - Keyboard navigation (Arrow keys, Home, End, PageUp/Down)\r\n * - Drag and click-to-move interaction\r\n * - Full accessibility (ARIA slider role)\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Slider\r\n * ```html\r\n * <fui-slider [formControl]=\"volumeControl\"></fui-slider>\r\n * ```\r\n *\r\n * ### Range Slider\r\n * ```html\r\n * <fui-slider [range]=\"true\" [formControl]=\"priceRange\"></fui-slider>\r\n * ```\r\n *\r\n * ### With Ticks and Custom Label\r\n * ```html\r\n * <fui-slider [showTicks]=\"true\" [formatLabel]=\"formatCurrency\" [min]=\"0\" [max]=\"1000\" [step]=\"100\"></fui-slider>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-slider',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './slider.component.html',\r\n styleUrls: ['./slider.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-slider',\r\n '[class.fui-slider--disabled]': 'disabled()',\r\n '[class.fui-slider--range]': 'range()',\r\n '[class.fui-slider--dragging]': '_dragging() !== null',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: FuiSliderComponent,\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class FuiSliderComponent implements ControlValueAccessor, OnDestroy {\r\n private readonly _document = inject(DOCUMENT);\r\n readonly intl = inject(FuiSliderIntl);\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 // Inputs\r\n readonly min = input(0);\r\n readonly max = input(100);\r\n readonly step = input(1);\r\n readonly range = input<boolean, unknown>(false, { transform: booleanAttribute });\r\n readonly showTicks = input<boolean, unknown>(false, { transform: booleanAttribute });\r\n readonly showTooltip = input<boolean, unknown>(true, { transform: booleanAttribute });\r\n readonly formatLabel = input<SliderFormatLabelFn>((v: number) => String(v));\r\n readonly disabled = input<boolean, unknown>(false, { transform: booleanAttribute });\r\n readonly ariaLabel = input<string | null>(null, { alias: 'aria-label' });\r\n readonly ariaLabelLow = input<string | null>(null);\r\n readonly ariaLabelHigh = input<string | null>(null);\r\n\r\n // Outputs\r\n readonly valueChange = output<SliderValue>();\r\n readonly dragStart = output();\r\n readonly dragEnd = output();\r\n\r\n // Internal state\r\n readonly _value: WritableSignal<number> = signal(0);\r\n readonly _valueLow: WritableSignal<number> = signal(0);\r\n readonly _valueHigh: WritableSignal<number> = signal(100);\r\n readonly _dragging: WritableSignal<'low' | 'high' | null> = signal(null);\r\n readonly _hovered: WritableSignal<'low' | 'high' | null> = signal(null);\r\n\r\n // ViewChild\r\n readonly _sliderContainer: Signal<ElementRef<HTMLElement> | undefined> =\r\n viewChild<ElementRef<HTMLElement>>('sliderContainer');\r\n\r\n // Computed: percentages\r\n readonly _percentage: Signal<number> = computed(() => this._valueToPercent(this._value()));\r\n\r\n readonly _percentageLow: Signal<number> = computed(() => this._valueToPercent(this._valueLow()));\r\n\r\n readonly _percentageHigh: Signal<number> = computed(() => this._valueToPercent(this._valueHigh()));\r\n\r\n // Computed: tick values\r\n readonly _tickValues: Signal<number[]> = computed(() => {\r\n const minVal = this.min();\r\n const maxVal = this.max();\r\n const stepVal = this.step();\r\n const ticks: number[] = [];\r\n for (let v = minVal; v <= maxVal; v += stepVal) {\r\n ticks.push(v);\r\n }\r\n // Ensure max is included\r\n if (ticks[ticks.length - 1] !== maxVal) {\r\n ticks.push(maxVal);\r\n }\r\n return ticks;\r\n });\r\n\r\n // CVA callbacks\r\n private _onChange: (value: SliderValue) => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n private _onTouched: () => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n\r\n // Bound event handlers for cleanup\r\n private _boundOnMouseMove = this._onMouseMove.bind(this);\r\n private _boundOnMouseUp = this._onMouseUp.bind(this);\r\n private _boundOnTouchMove = this._onTouchMove.bind(this);\r\n private _boundOnTouchEnd = this._onTouchEnd.bind(this);\r\n\r\n // ControlValueAccessor\r\n writeValue(value: SliderValue): void {\r\n if (value == null) return;\r\n\r\n if (Array.isArray(value)) {\r\n this._valueLow.set(this._clamp(value[0], this.min(), this.max()));\r\n this._valueHigh.set(this._clamp(value[1], this.min(), this.max()));\r\n } else {\r\n this._value.set(this._clamp(value, this.min(), this.max()));\r\n }\r\n }\r\n\r\n registerOnChange(fn: (value: SliderValue) => void): void {\r\n this._onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this._onTouched = fn;\r\n }\r\n\r\n setDisabledState(_isDisabled: boolean): void {\r\n // disabled is handled by input signal\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._removeDocumentListeners();\r\n }\r\n\r\n // === Public helpers (used in template) ===\r\n\r\n _valueToPercent(value: number): number {\r\n const minVal = this.min();\r\n const maxVal = this.max();\r\n if (maxVal === minVal) return 0;\r\n return ((value - minVal) / (maxVal - minVal)) * 100;\r\n }\r\n\r\n _isTickActive(tick: number): boolean {\r\n if (this.range()) {\r\n return tick >= this._valueLow() && tick <= this._valueHigh();\r\n }\r\n return tick <= this._value();\r\n }\r\n\r\n _snapToStep(value: number): number {\r\n const stepVal = this.step();\r\n const minVal = this.min();\r\n const snapped = Math.round((value - minVal) / stepVal) * stepVal + minVal;\r\n // Clamp to min/max and round to avoid floating point issues\r\n return this._clamp(parseFloat(snapped.toFixed(10)), this.min(), this.max());\r\n }\r\n\r\n _clamp(value: number, min: number, max: number): number {\r\n return Math.min(Math.max(value, min), max);\r\n }\r\n\r\n // === Event handlers ===\r\n\r\n _onTrackClick(event: MouseEvent): void {\r\n if (this.disabled()) return;\r\n // Ignore clicks on thumb elements\r\n const target = event.target as HTMLElement;\r\n if (target.classList.contains('fui-slider__thumb')) return;\r\n\r\n const value = this._getValueFromEvent(event);\r\n if (value === null) return;\r\n\r\n this._setNearestThumb(value);\r\n this._emitChange();\r\n this._onTouched();\r\n }\r\n\r\n _onThumbMouseDown(event: MouseEvent, thumb: 'low' | 'high'): void {\r\n if (this.disabled()) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n this._dragging.set(thumb);\r\n this.dragStart.emit();\r\n\r\n this._document.addEventListener('mousemove', this._boundOnMouseMove);\r\n this._document.addEventListener('mouseup', this._boundOnMouseUp);\r\n }\r\n\r\n _onThumbTouchStart(event: TouchEvent, thumb: 'low' | 'high'): void {\r\n if (this.disabled()) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n this._dragging.set(thumb);\r\n this.dragStart.emit();\r\n\r\n this._document.addEventListener('touchmove', this._boundOnTouchMove, { passive: false });\r\n this._document.addEventListener('touchend', this._boundOnTouchEnd);\r\n }\r\n\r\n _onThumbKeydown(event: KeyboardEvent, thumb: 'low' | 'high'): void {\r\n if (this.disabled()) return;\r\n\r\n const stepVal = this.step();\r\n let delta = 0;\r\n\r\n switch (event.key) {\r\n case 'ArrowRight':\r\n case 'ArrowUp':\r\n delta = stepVal;\r\n break;\r\n case 'ArrowLeft':\r\n case 'ArrowDown':\r\n delta = -stepVal;\r\n break;\r\n case 'PageUp':\r\n delta = stepVal * 10;\r\n break;\r\n case 'PageDown':\r\n delta = -stepVal * 10;\r\n break;\r\n case 'Home':\r\n this._setThumbValue(thumb, this.min());\r\n this._emitChange();\r\n event.preventDefault();\r\n return;\r\n case 'End':\r\n this._setThumbValue(thumb, this.max());\r\n this._emitChange();\r\n event.preventDefault();\r\n return;\r\n default:\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n const currentValue = this._getThumbValue(thumb);\r\n const newValue = this._snapToStep(this._clamp(currentValue + delta, this.min(), this.max()));\r\n this._setThumbValue(thumb, newValue);\r\n this._emitChange();\r\n this._onTouched();\r\n }\r\n\r\n // === Private methods ===\r\n\r\n private _onMouseMove(event: MouseEvent): void {\r\n const value = this._getValueFromEvent(event);\r\n if (value === null) return;\r\n this._updateDraggingThumb(value);\r\n }\r\n\r\n private _onMouseUp(): void {\r\n this._endDrag();\r\n this._document.removeEventListener('mousemove', this._boundOnMouseMove);\r\n this._document.removeEventListener('mouseup', this._boundOnMouseUp);\r\n }\r\n\r\n private _onTouchMove(event: TouchEvent): void {\r\n event.preventDefault();\r\n if (event.touches.length === 0) return;\r\n const touch = event.touches[0];\r\n const value = this._getValueFromClientX(touch.clientX);\r\n if (value === null) return;\r\n this._updateDraggingThumb(value);\r\n }\r\n\r\n private _onTouchEnd(): void {\r\n this._endDrag();\r\n this._document.removeEventListener('touchmove', this._boundOnTouchMove);\r\n this._document.removeEventListener('touchend', this._boundOnTouchEnd);\r\n }\r\n\r\n private _endDrag(): void {\r\n if (this._dragging() !== null) {\r\n this._dragging.set(null);\r\n this.dragEnd.emit();\r\n this._onTouched();\r\n }\r\n }\r\n\r\n private _removeDocumentListeners(): void {\r\n this._document.removeEventListener('mousemove', this._boundOnMouseMove);\r\n this._document.removeEventListener('mouseup', this._boundOnMouseUp);\r\n this._document.removeEventListener('touchmove', this._boundOnTouchMove);\r\n this._document.removeEventListener('touchend', this._boundOnTouchEnd);\r\n }\r\n\r\n private _getValueFromEvent(event: MouseEvent): number | null {\r\n return this._getValueFromClientX(event.clientX);\r\n }\r\n\r\n private _getValueFromClientX(clientX: number): number | null {\r\n const container = this._sliderContainer();\r\n if (!container) return null;\r\n\r\n const rect = container.nativeElement.getBoundingClientRect();\r\n const percent = this._clamp((clientX - rect.left) / rect.width, 0, 1);\r\n const rawValue = this.min() + percent * (this.max() - this.min());\r\n return this._snapToStep(rawValue);\r\n }\r\n\r\n private _updateDraggingThumb(value: number): void {\r\n const thumb = this._dragging();\r\n if (thumb === null) return;\r\n this._setThumbValue(thumb, value);\r\n this._emitChange();\r\n }\r\n\r\n private _getThumbValue(thumb: 'low' | 'high'): number {\r\n if (this.range()) {\r\n return thumb === 'low' ? this._valueLow() : this._valueHigh();\r\n }\r\n return this._value();\r\n }\r\n\r\n private _setThumbValue(thumb: 'low' | 'high', value: number): void {\r\n if (this.range()) {\r\n if (thumb === 'low') {\r\n // Prevent low from exceeding high\r\n this._valueLow.set(this._clamp(value, this.min(), this._valueHigh()));\r\n } else {\r\n // Prevent high from going below low\r\n this._valueHigh.set(this._clamp(value, this._valueLow(), this.max()));\r\n }\r\n } else {\r\n this._value.set(value);\r\n }\r\n }\r\n\r\n private _setNearestThumb(value: number): void {\r\n if (this.range()) {\r\n const distLow = Math.abs(value - this._valueLow());\r\n const distHigh = Math.abs(value - this._valueHigh());\r\n if (distLow <= distHigh) {\r\n this._setThumbValue('low', value);\r\n } else {\r\n this._setThumbValue('high', value);\r\n }\r\n } else {\r\n this._value.set(value);\r\n }\r\n }\r\n\r\n private _emitChange(): void {\r\n const val = this.range() ? ([this._valueLow(), this._valueHigh()] as [number, number]) : this._value();\r\n this._onChange(val);\r\n this.valueChange.emit(val);\r\n }\r\n}\r\n","<div class=\"fui-slider__container\" (click)=\"_onTrackClick($event)\" #sliderContainer>\r\n <div class=\"fui-slider__track\">\r\n <div\r\n class=\"fui-slider__track-fill\"\r\n [style.left.%]=\"range() ? _percentageLow() : 0\"\r\n [style.width.%]=\"range() ? _percentageHigh() - _percentageLow() : _percentage()\"\r\n ></div>\r\n </div>\r\n\r\n @if (showTicks()) {\r\n <div class=\"fui-slider__ticks\">\r\n @for (tick of _tickValues(); track tick) {\r\n <div\r\n class=\"fui-slider__tick\"\r\n [style.left.%]=\"_valueToPercent(tick)\"\r\n [class.fui-slider__tick--active]=\"_isTickActive(tick)\"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--low\"\r\n [style.left.%]=\"range() ? _percentageLow() : _percentage()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"range() ? _valueLow() : _value()\"\r\n [attr.aria-valuemin]=\"min()\"\r\n [attr.aria-valuemax]=\"range() ? _valueHigh() : max()\"\r\n [attr.aria-label]=\"range() ? (ariaLabelLow() || intl.minValueAriaLabel) : (ariaLabel() || null)\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'low')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'low')\"\r\n (keydown)=\"_onThumbKeydown($event, 'low')\"\r\n (focus)=\"_hovered.set('low')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'low' || _hovered() === 'low')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(range() ? _valueLow() : _value()) }}</div>\r\n }\r\n </div>\r\n\r\n @if (range()) {\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--high\"\r\n [style.left.%]=\"_percentageHigh()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"_valueHigh()\"\r\n [attr.aria-valuemin]=\"_valueLow()\"\r\n [attr.aria-valuemax]=\"max()\"\r\n [attr.aria-label]=\"ariaLabelHigh() || intl.maxValueAriaLabel\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'high')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'high')\"\r\n (keydown)=\"_onThumbKeydown($event, 'high')\"\r\n (focus)=\"_hovered.set('high')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'high' || _hovered() === 'high')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(_valueHigh()) }}</div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAIM,MAAO,aAAc,SAAQ,WAAW,CAAA;IAC5C,iBAAiB,GAAG,eAAe;IACnC,iBAAiB,GAAG,eAAe;uGAFxB,aAAa,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAb,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,aAAa,cADA,MAAM,EAAA,CAAA;;2FACnB,aAAa,EAAA,UAAA,EAAA,CAAA;kBADzB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACoBlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BG;MAuBU,kBAAkB,CAAA;AACZ,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC;AACpC,IAAA,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC;AACpB,IAAA,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAEjD,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS,CAAC,MAAK,EAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7F;;AAGS,IAAA,GAAG,GAAG,KAAK,CAAC,CAAC,0EAAC;AACd,IAAA,GAAG,GAAG,KAAK,CAAC,GAAG,0EAAC;AAChB,IAAA,IAAI,GAAG,KAAK,CAAC,CAAC,2EAAC;IACf,KAAK,GAAG,KAAK,CAAmB,KAAK,6EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IACvE,SAAS,GAAG,KAAK,CAAmB,KAAK,iFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IAC3E,WAAW,GAAG,KAAK,CAAmB,IAAI,mFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;AAC5E,IAAA,WAAW,GAAG,KAAK,CAAsB,CAAC,CAAS,KAAK,MAAM,CAAC,CAAC,CAAC,kFAAC;IAClE,QAAQ,GAAG,KAAK,CAAmB,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IAC1E,SAAS,GAAG,KAAK,CAAgB,IAAI,iFAAI,KAAK,EAAE,YAAY,EAAA,CAAG;AAC/D,IAAA,YAAY,GAAG,KAAK,CAAgB,IAAI,mFAAC;AACzC,IAAA,aAAa,GAAG,KAAK,CAAgB,IAAI,oFAAC;;IAG1C,WAAW,GAAG,MAAM,EAAe;IACnC,SAAS,GAAG,MAAM,EAAE;IACpB,OAAO,GAAG,MAAM,EAAE;;AAGlB,IAAA,MAAM,GAA2B,MAAM,CAAC,CAAC,6EAAC;AAC1C,IAAA,SAAS,GAA2B,MAAM,CAAC,CAAC,gFAAC;AAC7C,IAAA,UAAU,GAA2B,MAAM,CAAC,GAAG,iFAAC;AAChD,IAAA,SAAS,GAA0C,MAAM,CAAC,IAAI,gFAAC;AAC/D,IAAA,QAAQ,GAA0C,MAAM,CAAC,IAAI,+EAAC;;AAG9D,IAAA,gBAAgB,GACvB,SAAS,CAA0B,iBAAiB,uFAAC;;AAG9C,IAAA,WAAW,GAAmB,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,kFAAC;AAEjF,IAAA,cAAc,GAAmB,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,qFAAC;AAEvF,IAAA,eAAe,GAAmB,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,sFAAC;;AAGzF,IAAA,WAAW,GAAqB,QAAQ,CAAC,MAAK;AACrD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AACzB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AACzB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE;QAC3B,MAAM,KAAK,GAAa,EAAE;AAC1B,QAAA,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,IAAI,OAAO,EAAE;AAC9C,YAAA,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACf;;QAEA,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE;AACtC,YAAA,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;QACpB;AACA,QAAA,OAAO,KAAK;AACd,IAAA,CAAC,kFAAC;;IAGM,SAAS,GAAiC,MAAK;;AAEvD,IAAA,CAAC;IACO,UAAU,GAAe,MAAK;;AAEtC,IAAA,CAAC;;IAGO,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;IAChD,eAAe,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5C,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;IAChD,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;;AAGtD,IAAA,UAAU,CAAC,KAAkB,EAAA;QAC3B,IAAI,KAAK,IAAI,IAAI;YAAE;AAEnB,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACxB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACpE;aAAO;YACL,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7D;IACF;AAEA,IAAA,gBAAgB,CAAC,EAAgC,EAAA;AAC/C,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;IACrB;AAEA,IAAA,iBAAiB,CAAC,EAAc,EAAA;AAC9B,QAAA,IAAI,CAAC,UAAU,GAAG,EAAE;IACtB;AAEA,IAAA,gBAAgB,CAAC,WAAoB,EAAA;;IAErC;IAEA,WAAW,GAAA;QACT,IAAI,CAAC,wBAAwB,EAAE;IACjC;;AAIA,IAAA,eAAe,CAAC,KAAa,EAAA;AAC3B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AACzB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;QACzB,IAAI,MAAM,KAAK,MAAM;AAAE,YAAA,OAAO,CAAC;AAC/B,QAAA,OAAO,CAAC,CAAC,KAAK,GAAG,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC,IAAI,GAAG;IACrD;AAEA,IAAA,aAAa,CAAC,IAAY,EAAA;AACxB,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;AAChB,YAAA,OAAO,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;QAC9D;AACA,QAAA,OAAO,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;IAC9B;AAEA,IAAA,WAAW,CAAC,KAAa,EAAA;AACvB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE;AAC3B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AACzB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,OAAO,GAAG,MAAM;;QAEzE,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7E;AAEA,IAAA,MAAM,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW,EAAA;AAC5C,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC;IAC5C;;AAIA,IAAA,aAAa,CAAC,KAAiB,EAAA;QAC7B,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;;AAErB,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB;AAC1C,QAAA,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YAAE;QAEpD,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC;QAC5C,IAAI,KAAK,KAAK,IAAI;YAAE;AAEpB,QAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,WAAW,EAAE;QAClB,IAAI,CAAC,UAAU,EAAE;IACnB;IAEA,iBAAiB,CAAC,KAAiB,EAAE,KAAqB,EAAA;QACxD,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;QACrB,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;AAEvB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACzB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;QAErB,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC;QACpE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC;IAClE;IAEA,kBAAkB,CAAC,KAAiB,EAAE,KAAqB,EAAA;QACzD,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;QACrB,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;AAEvB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACzB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;AAErB,QAAA,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACxF,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC;IACpE;IAEA,eAAe,CAAC,KAAoB,EAAE,KAAqB,EAAA;QACzD,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;AAErB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE;QAC3B,IAAI,KAAK,GAAG,CAAC;AAEb,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,YAAY;AACjB,YAAA,KAAK,SAAS;gBACZ,KAAK,GAAG,OAAO;gBACf;AACF,YAAA,KAAK,WAAW;AAChB,YAAA,KAAK,WAAW;gBACd,KAAK,GAAG,CAAC,OAAO;gBAChB;AACF,YAAA,KAAK,QAAQ;AACX,gBAAA,KAAK,GAAG,OAAO,GAAG,EAAE;gBACpB;AACF,YAAA,KAAK,UAAU;AACb,gBAAA,KAAK,GAAG,CAAC,OAAO,GAAG,EAAE;gBACrB;AACF,YAAA,KAAK,MAAM;gBACT,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACtC,IAAI,CAAC,WAAW,EAAE;gBAClB,KAAK,CAAC,cAAc,EAAE;gBACtB;AACF,YAAA,KAAK,KAAK;gBACR,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACtC,IAAI,CAAC,WAAW,EAAE;gBAClB,KAAK,CAAC,cAAc,EAAE;gBACtB;AACF,YAAA;gBACE;;QAGJ,KAAK,CAAC,cAAc,EAAE;QACtB,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;AAC5F,QAAA,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC;QACpC,IAAI,CAAC,WAAW,EAAE;QAClB,IAAI,CAAC,UAAU,EAAE;IACnB;;AAIQ,IAAA,YAAY,CAAC,KAAiB,EAAA;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC;QAC5C,IAAI,KAAK,KAAK,IAAI;YAAE;AACpB,QAAA,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;IAClC;IAEQ,UAAU,GAAA;QAChB,IAAI,CAAC,QAAQ,EAAE;QACf,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC;QACvE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC;IACrE;AAEQ,IAAA,YAAY,CAAC,KAAiB,EAAA;QACpC,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE;QAChC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC;QACtD,IAAI,KAAK,KAAK,IAAI;YAAE;AACpB,QAAA,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;IAClC;IAEQ,WAAW,GAAA;QACjB,IAAI,CAAC,QAAQ,EAAE;QACf,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC;QACvE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC;IACvE;IAEQ,QAAQ,GAAA;AACd,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;AAC7B,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACxB,YAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YACnB,IAAI,CAAC,UAAU,EAAE;QACnB;IACF;IAEQ,wBAAwB,GAAA;QAC9B,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC;QACvE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC;QACnE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC;QACvE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC;IACvE;AAEQ,IAAA,kBAAkB,CAAC,KAAiB,EAAA;QAC1C,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC;IACjD;AAEQ,IAAA,oBAAoB,CAAC,OAAe,EAAA;AAC1C,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACzC,QAAA,IAAI,CAAC,SAAS;AAAE,YAAA,OAAO,IAAI;QAE3B,MAAM,IAAI,GAAG,SAAS,CAAC,aAAa,CAAC,qBAAqB,EAAE;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACjE,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;IACnC;AAEQ,IAAA,oBAAoB,CAAC,KAAa,EAAA;AACxC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE;QAC9B,IAAI,KAAK,KAAK,IAAI;YAAE;AACpB,QAAA,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC;QACjC,IAAI,CAAC,WAAW,EAAE;IACpB;AAEQ,IAAA,cAAc,CAAC,KAAqB,EAAA;AAC1C,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;AAChB,YAAA,OAAO,KAAK,KAAK,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE;QAC/D;AACA,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE;IACtB;IAEQ,cAAc,CAAC,KAAqB,EAAE,KAAa,EAAA;AACzD,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;AAChB,YAAA,IAAI,KAAK,KAAK,KAAK,EAAE;;gBAEnB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YACvE;iBAAO;;gBAEL,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACvE;QACF;aAAO;AACL,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QACxB;IACF;AAEQ,IAAA,gBAAgB,CAAC,KAAa,EAAA;AACpC,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;AAChB,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;AAClD,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;AACpD,YAAA,IAAI,OAAO,IAAI,QAAQ,EAAE;AACvB,gBAAA,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC;YACnC;iBAAO;AACL,gBAAA,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC;YACpC;QACF;aAAO;AACL,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QACxB;IACF;IAEQ,WAAW,GAAA;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,GAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAsB,GAAG,IAAI,CAAC,MAAM,EAAE;AACtG,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;AACnB,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;IAC5B;uGA9TW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,SAAA,EAAA,WAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,4BAAA,EAAA,YAAA,EAAA,yBAAA,EAAA,SAAA,EAAA,4BAAA,EAAA,sBAAA,EAAA,EAAA,cAAA,EAAA,YAAA,EAAA,EAAA,SAAA,EARlB;AACT,YAAA;AACE,gBAAA,OAAO,EAAE,iBAAiB;AAC1B,gBAAA,WAAW,EAAE,kBAAkB;AAC/B,gBAAA,KAAK,EAAE,IAAI;AACZ,aAAA;AACF,SAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC3EH,oqFAmEA,EAAA,MAAA,EAAA,CAAA,mrKAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDUa,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAtB9B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,YAAY,EAAA,UAAA,EACV,IAAI,EAAA,OAAA,EACP,EAAE,EAAA,eAAA,EAGM,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B;AACJ,wBAAA,KAAK,EAAE,YAAY;AACnB,wBAAA,8BAA8B,EAAE,YAAY;AAC5C,wBAAA,2BAA2B,EAAE,SAAS;AACtC,wBAAA,8BAA8B,EAAE,sBAAsB;qBACvD,EAAA,SAAA,EACU;AACT,wBAAA;AACE,4BAAA,OAAO,EAAE,iBAAiB;AAC1B,4BAAA,WAAW,EAAA,kBAAoB;AAC/B,4BAAA,KAAK,EAAE,IAAI;AACZ,yBAAA;AACF,qBAAA,EAAA,QAAA,EAAA,oqFAAA,EAAA,MAAA,EAAA,CAAA,mrKAAA,CAAA,EAAA;8yCAsCoC,iBAAiB,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AEjHxD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"raintonic-formaui-components-slider.mjs","sources":["../../../lib/components/slider/slider.intl.ts","../../../lib/components/slider/slider.component.ts","../../../lib/components/slider/slider.component.html","../../../lib/components/slider/raintonic-formaui-components-slider.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiSliderIntl extends FuiIntlBase {\r\n minValueAriaLabel = 'Minimum value';\r\n maxValueAriaLabel = 'Maximum value';\r\n}\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n computed,\r\n signal,\r\n viewChild,\r\n ElementRef,\r\n Signal,\r\n WritableSignal,\r\n OnDestroy,\r\n booleanAttribute,\r\n DOCUMENT,\r\n inject,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { SliderValue, SliderFormatLabelFn } from './slider.types';\r\nimport { FuiSliderIntl } from './slider.intl';\r\n\r\n/**\r\n * # FuiSliderComponent\r\n *\r\n * A slider (range input) component with single and dual-thumb (range) support.\r\n * Integrates with Angular Reactive Forms via ControlValueAccessor.\r\n *\r\n * ## Features\r\n * - Single value and range (dual-thumb) modes\r\n * - Configurable min/max/step\r\n * - Optional tick marks and tooltips\r\n * - Custom label formatting\r\n * - Keyboard navigation (Arrow keys, Home, End, PageUp/Down)\r\n * - Drag and click-to-move interaction\r\n * - Full accessibility (ARIA slider role)\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Slider\r\n * ```html\r\n * <fui-slider [formControl]=\"volumeControl\"></fui-slider>\r\n * ```\r\n *\r\n * ### Range Slider\r\n * ```html\r\n * <fui-slider [range]=\"true\" [formControl]=\"priceRange\"></fui-slider>\r\n * ```\r\n *\r\n * ### With Ticks and Custom Label\r\n * ```html\r\n * <fui-slider [showTicks]=\"true\" [formatLabel]=\"formatCurrency\" [min]=\"0\" [max]=\"1000\" [step]=\"100\"></fui-slider>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-slider',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './slider.component.html',\r\n styleUrls: ['./slider.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-slider',\r\n '[class.fui-slider--disabled]': 'disabled()',\r\n '[class.fui-slider--range]': 'range()',\r\n '[class.fui-slider--dragging]': '_dragging() !== null',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: FuiSliderComponent,\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class FuiSliderComponent implements ControlValueAccessor, OnDestroy {\r\n private readonly _document = inject(DOCUMENT);\r\n readonly intl = inject(FuiSliderIntl);\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 // Inputs\r\n readonly min = input(0);\r\n readonly max = input(100);\r\n readonly step = input(1);\r\n readonly range = input<boolean, unknown>(false, { transform: booleanAttribute });\r\n readonly showTicks = input<boolean, unknown>(false, { transform: booleanAttribute });\r\n readonly showTooltip = input<boolean, unknown>(true, { transform: booleanAttribute });\r\n readonly formatLabel = input<SliderFormatLabelFn>((v: number) => String(v));\r\n readonly disabled = input<boolean, unknown>(false, { transform: booleanAttribute });\r\n readonly ariaLabel = input<string | null>(null, { alias: 'aria-label' });\r\n readonly ariaLabelLow = input<string | null>(null);\r\n readonly ariaLabelHigh = input<string | null>(null);\r\n\r\n // Outputs\r\n readonly valueChange = output<SliderValue>();\r\n readonly dragStart = output();\r\n readonly dragEnd = output();\r\n\r\n // Internal state\r\n readonly _value: WritableSignal<number> = signal(0);\r\n readonly _valueLow: WritableSignal<number> = signal(0);\r\n readonly _valueHigh: WritableSignal<number> = signal(100);\r\n readonly _dragging: WritableSignal<'low' | 'high' | null> = signal(null);\r\n readonly _hovered: WritableSignal<'low' | 'high' | null> = signal(null);\r\n\r\n // ViewChild\r\n readonly _sliderContainer: Signal<ElementRef<HTMLElement> | undefined> =\r\n viewChild<ElementRef<HTMLElement>>('sliderContainer');\r\n\r\n // Computed: percentages\r\n readonly _percentage: Signal<number> = computed(() => this._valueToPercent(this._value()));\r\n\r\n readonly _percentageLow: Signal<number> = computed(() => this._valueToPercent(this._valueLow()));\r\n\r\n readonly _percentageHigh: Signal<number> = computed(() => this._valueToPercent(this._valueHigh()));\r\n\r\n // Computed: tick values\r\n readonly _tickValues: Signal<number[]> = computed(() => {\r\n const minVal = this.min();\r\n const maxVal = this.max();\r\n const stepVal = this.step();\r\n const ticks: number[] = [];\r\n for (let v = minVal; v <= maxVal; v += stepVal) {\r\n ticks.push(v);\r\n }\r\n // Ensure max is included\r\n if (ticks[ticks.length - 1] !== maxVal) {\r\n ticks.push(maxVal);\r\n }\r\n return ticks;\r\n });\r\n\r\n // CVA callbacks\r\n private _onChange: (value: SliderValue) => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n private _onTouched: () => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n\r\n // Bound event handlers for cleanup\r\n private _boundOnMouseMove = this._onMouseMove.bind(this);\r\n private _boundOnMouseUp = this._onMouseUp.bind(this);\r\n private _boundOnTouchMove = this._onTouchMove.bind(this);\r\n private _boundOnTouchEnd = this._onTouchEnd.bind(this);\r\n\r\n // ControlValueAccessor\r\n writeValue(value: SliderValue): void {\r\n if (value == null) return;\r\n\r\n if (Array.isArray(value)) {\r\n this._valueLow.set(this._clamp(value[0], this.min(), this.max()));\r\n this._valueHigh.set(this._clamp(value[1], this.min(), this.max()));\r\n } else {\r\n this._value.set(this._clamp(value, this.min(), this.max()));\r\n }\r\n }\r\n\r\n registerOnChange(fn: (value: SliderValue) => void): void {\r\n this._onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this._onTouched = fn;\r\n }\r\n\r\n setDisabledState(_isDisabled: boolean): void {\r\n // disabled is handled by input signal\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._removeDocumentListeners();\r\n }\r\n\r\n // === Public helpers (used in template) ===\r\n\r\n _valueToPercent(value: number): number {\r\n const minVal = this.min();\r\n const maxVal = this.max();\r\n if (maxVal === minVal) return 0;\r\n return ((value - minVal) / (maxVal - minVal)) * 100;\r\n }\r\n\r\n _isTickActive(tick: number): boolean {\r\n if (this.range()) {\r\n return tick >= this._valueLow() && tick <= this._valueHigh();\r\n }\r\n return tick <= this._value();\r\n }\r\n\r\n _snapToStep(value: number): number {\r\n const stepVal = this.step();\r\n const minVal = this.min();\r\n const snapped = Math.round((value - minVal) / stepVal) * stepVal + minVal;\r\n // Clamp to min/max and round to avoid floating point issues\r\n return this._clamp(parseFloat(snapped.toFixed(10)), this.min(), this.max());\r\n }\r\n\r\n _clamp(value: number, min: number, max: number): number {\r\n return Math.min(Math.max(value, min), max);\r\n }\r\n\r\n // === Event handlers ===\r\n\r\n _onTrackClick(event: MouseEvent): void {\r\n if (this.disabled()) return;\r\n // Ignore clicks on thumb elements\r\n const target = event.target as HTMLElement;\r\n if (target.classList.contains('fui-slider__thumb')) return;\r\n\r\n const value = this._getValueFromEvent(event);\r\n if (value === null) return;\r\n\r\n this._setNearestThumb(value);\r\n this._emitChange();\r\n this._onTouched();\r\n }\r\n\r\n _onThumbMouseDown(event: MouseEvent, thumb: 'low' | 'high'): void {\r\n if (this.disabled()) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n this._dragging.set(thumb);\r\n this.dragStart.emit();\r\n\r\n this._document.addEventListener('mousemove', this._boundOnMouseMove);\r\n this._document.addEventListener('mouseup', this._boundOnMouseUp);\r\n }\r\n\r\n _onThumbTouchStart(event: TouchEvent, thumb: 'low' | 'high'): void {\r\n if (this.disabled()) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n this._dragging.set(thumb);\r\n this.dragStart.emit();\r\n\r\n this._document.addEventListener('touchmove', this._boundOnTouchMove, { passive: false });\r\n this._document.addEventListener('touchend', this._boundOnTouchEnd);\r\n }\r\n\r\n _onThumbKeydown(event: KeyboardEvent, thumb: 'low' | 'high'): void {\r\n if (this.disabled()) return;\r\n\r\n const stepVal = this.step();\r\n let delta = 0;\r\n\r\n switch (event.key) {\r\n case 'ArrowRight':\r\n case 'ArrowUp':\r\n delta = stepVal;\r\n break;\r\n case 'ArrowLeft':\r\n case 'ArrowDown':\r\n delta = -stepVal;\r\n break;\r\n case 'PageUp':\r\n delta = stepVal * 10;\r\n break;\r\n case 'PageDown':\r\n delta = -stepVal * 10;\r\n break;\r\n case 'Home':\r\n this._setThumbValue(thumb, this.min());\r\n this._emitChange();\r\n event.preventDefault();\r\n return;\r\n case 'End':\r\n this._setThumbValue(thumb, this.max());\r\n this._emitChange();\r\n event.preventDefault();\r\n return;\r\n default:\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n const currentValue = this._getThumbValue(thumb);\r\n const newValue = this._snapToStep(this._clamp(currentValue + delta, this.min(), this.max()));\r\n this._setThumbValue(thumb, newValue);\r\n this._emitChange();\r\n this._onTouched();\r\n }\r\n\r\n // === Private methods ===\r\n\r\n private _onMouseMove(event: MouseEvent): void {\r\n const value = this._getValueFromEvent(event);\r\n if (value === null) return;\r\n this._updateDraggingThumb(value);\r\n }\r\n\r\n private _onMouseUp(): void {\r\n this._endDrag();\r\n this._document.removeEventListener('mousemove', this._boundOnMouseMove);\r\n this._document.removeEventListener('mouseup', this._boundOnMouseUp);\r\n }\r\n\r\n private _onTouchMove(event: TouchEvent): void {\r\n event.preventDefault();\r\n if (event.touches.length === 0) return;\r\n const touch = event.touches[0];\r\n const value = this._getValueFromClientX(touch.clientX);\r\n if (value === null) return;\r\n this._updateDraggingThumb(value);\r\n }\r\n\r\n private _onTouchEnd(): void {\r\n this._endDrag();\r\n this._document.removeEventListener('touchmove', this._boundOnTouchMove);\r\n this._document.removeEventListener('touchend', this._boundOnTouchEnd);\r\n }\r\n\r\n private _endDrag(): void {\r\n if (this._dragging() !== null) {\r\n this._dragging.set(null);\r\n this.dragEnd.emit();\r\n this._onTouched();\r\n }\r\n }\r\n\r\n private _removeDocumentListeners(): void {\r\n this._document.removeEventListener('mousemove', this._boundOnMouseMove);\r\n this._document.removeEventListener('mouseup', this._boundOnMouseUp);\r\n this._document.removeEventListener('touchmove', this._boundOnTouchMove);\r\n this._document.removeEventListener('touchend', this._boundOnTouchEnd);\r\n }\r\n\r\n private _getValueFromEvent(event: MouseEvent): number | null {\r\n return this._getValueFromClientX(event.clientX);\r\n }\r\n\r\n private _getValueFromClientX(clientX: number): number | null {\r\n const container = this._sliderContainer();\r\n if (!container) return null;\r\n\r\n const rect = container.nativeElement.getBoundingClientRect();\r\n const percent = this._clamp((clientX - rect.left) / rect.width, 0, 1);\r\n const rawValue = this.min() + percent * (this.max() - this.min());\r\n return this._snapToStep(rawValue);\r\n }\r\n\r\n private _updateDraggingThumb(value: number): void {\r\n const thumb = this._dragging();\r\n if (thumb === null) return;\r\n this._setThumbValue(thumb, value);\r\n this._emitChange();\r\n }\r\n\r\n private _getThumbValue(thumb: 'low' | 'high'): number {\r\n if (this.range()) {\r\n return thumb === 'low' ? this._valueLow() : this._valueHigh();\r\n }\r\n return this._value();\r\n }\r\n\r\n private _setThumbValue(thumb: 'low' | 'high', value: number): void {\r\n if (this.range()) {\r\n if (thumb === 'low') {\r\n // Prevent low from exceeding high\r\n this._valueLow.set(this._clamp(value, this.min(), this._valueHigh()));\r\n } else {\r\n // Prevent high from going below low\r\n this._valueHigh.set(this._clamp(value, this._valueLow(), this.max()));\r\n }\r\n } else {\r\n this._value.set(value);\r\n }\r\n }\r\n\r\n private _setNearestThumb(value: number): void {\r\n if (this.range()) {\r\n const distLow = Math.abs(value - this._valueLow());\r\n const distHigh = Math.abs(value - this._valueHigh());\r\n if (distLow <= distHigh) {\r\n this._setThumbValue('low', value);\r\n } else {\r\n this._setThumbValue('high', value);\r\n }\r\n } else {\r\n this._value.set(value);\r\n }\r\n }\r\n\r\n private _emitChange(): void {\r\n const val = this.range() ? ([this._valueLow(), this._valueHigh()] as [number, number]) : this._value();\r\n this._onChange(val);\r\n this.valueChange.emit(val);\r\n }\r\n}\r\n","<div class=\"fui-slider__container\" (click)=\"_onTrackClick($event)\" #sliderContainer>\r\n <div class=\"fui-slider__track\">\r\n <div\r\n class=\"fui-slider__track-fill\"\r\n [style.left.%]=\"range() ? _percentageLow() : 0\"\r\n [style.width.%]=\"range() ? _percentageHigh() - _percentageLow() : _percentage()\"\r\n ></div>\r\n </div>\r\n\r\n @if (showTicks()) {\r\n <div class=\"fui-slider__ticks\">\r\n @for (tick of _tickValues(); track tick) {\r\n <div\r\n class=\"fui-slider__tick\"\r\n [style.left.%]=\"_valueToPercent(tick)\"\r\n [class.fui-slider__tick--active]=\"_isTickActive(tick)\"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--low\"\r\n [style.left.%]=\"range() ? _percentageLow() : _percentage()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"range() ? _valueLow() : _value()\"\r\n [attr.aria-valuemin]=\"min()\"\r\n [attr.aria-valuemax]=\"range() ? _valueHigh() : max()\"\r\n [attr.aria-label]=\"range() ? (ariaLabelLow() || intl.minValueAriaLabel) : (ariaLabel() || null)\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'low')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'low')\"\r\n (keydown)=\"_onThumbKeydown($event, 'low')\"\r\n (focus)=\"_hovered.set('low')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'low' || _hovered() === 'low')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(range() ? _valueLow() : _value()) }}</div>\r\n }\r\n </div>\r\n\r\n @if (range()) {\r\n <div\r\n class=\"fui-slider__thumb fui-slider__thumb--high\"\r\n [style.left.%]=\"_percentageHigh()\"\r\n role=\"slider\"\r\n [attr.aria-valuenow]=\"_valueHigh()\"\r\n [attr.aria-valuemin]=\"_valueLow()\"\r\n [attr.aria-valuemax]=\"max()\"\r\n [attr.aria-label]=\"ariaLabelHigh() || intl.maxValueAriaLabel\"\r\n aria-orientation=\"horizontal\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n (mousedown)=\"_onThumbMouseDown($event, 'high')\"\r\n (touchstart)=\"_onThumbTouchStart($event, 'high')\"\r\n (keydown)=\"_onThumbKeydown($event, 'high')\"\r\n (focus)=\"_hovered.set('high')\"\r\n (blur)=\"_hovered.set(null)\"\r\n >\r\n @if (showTooltip() && (_dragging() === 'high' || _hovered() === 'high')) {\r\n <div class=\"fui-slider__tooltip\">{{ formatLabel()(_valueHigh()) }}</div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -51,7 +51,7 @@ class FuiSpinnerComponent {
|
|
|
51
51
|
return this.circumference - (this.clampedValue() / 100) * this.circumference;
|
|
52
52
|
}, ...(ngDevMode ? [{ debugName: "strokeDashoffset" }] : /* istanbul ignore next */ []));
|
|
53
53
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
54
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiSpinnerComponent, isStandalone: true, selector: "fui-spinner", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, overlay: { classPropertyName: "overlay", publicName: "overlay", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status", "aria-live": "polite" }, properties: { "class.fui-spinner--sm": "size() === \"sm\"", "class.fui-spinner--md": "size() === \"md\"", "class.fui-spinner--lg": "size() === \"lg\"", "class.fui-spinner--overlay": "overlay()", "class.fui-spinner--determinate": "mode() === \"determinate\"", "class.fui-spinner--indeterminate": "mode() === \"indeterminate\"", "attr.aria-valuenow": "mode() === \"determinate\" ? clampedValue() : null", "attr.aria-valuemin": "mode() === \"determinate\" ? 0 : null", "attr.aria-valuemax": "mode() === \"determinate\" ? 100 : null", "attr.aria-label": "ariaLabel() ?? intl.loadingAriaLabel" }, classAttribute: "fui-spinner" }, ngImport: i0, template: "@if (overlay()) {\r\n <div class=\"fui-spinner__overlay\">\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n} @else {\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n}\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-spinner{display:inline-flex;align-items:center;justify-content:center;--fui-spinner-color: var(--fui-primary-bg)}.fui-spinner--sm{width:1rem;height:1rem}.fui-spinner--md{width:2.5rem;height:2.5rem}.fui-spinner--lg{width:4rem;height:4rem}.fui-spinner__svg{width:100%;height:100%}.fui-spinner__track{stroke:var(--fui-bg-muted, #e2e8f0)}.fui-spinner__circle{stroke:var(--fui-spinner-color);transform-origin:center}.fui-spinner--indeterminate .fui-spinner__svg{animation:fui-spin var(--fui-duration-deliberate, .7s) linear infinite}.fui-spinner--indeterminate .fui-spinner__circle{stroke-dasharray:80,200;stroke-dashoffset:0;animation:fui-spinner-dash 1.5s ease-in-out infinite}.fui-spinner--determinate .fui-spinner__circle{transition:stroke-dashoffset var(--fui-duration-base, .3s) var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transform:rotate(-90deg);transform-origin:center}.fui-spinner--overlay{position:static}.fui-spinner__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background-color:#ffffffb3;z-index:var(--fui-
|
|
54
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiSpinnerComponent, isStandalone: true, selector: "fui-spinner", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, overlay: { classPropertyName: "overlay", publicName: "overlay", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status", "aria-live": "polite" }, properties: { "class.fui-spinner--sm": "size() === \"sm\"", "class.fui-spinner--md": "size() === \"md\"", "class.fui-spinner--lg": "size() === \"lg\"", "class.fui-spinner--overlay": "overlay()", "class.fui-spinner--determinate": "mode() === \"determinate\"", "class.fui-spinner--indeterminate": "mode() === \"indeterminate\"", "attr.aria-valuenow": "mode() === \"determinate\" ? clampedValue() : null", "attr.aria-valuemin": "mode() === \"determinate\" ? 0 : null", "attr.aria-valuemax": "mode() === \"determinate\" ? 100 : null", "attr.aria-label": "ariaLabel() ?? intl.loadingAriaLabel" }, classAttribute: "fui-spinner" }, ngImport: i0, template: "@if (overlay()) {\r\n <div class=\"fui-spinner__overlay\">\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n} @else {\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n}\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-spinner{display:inline-flex;align-items:center;justify-content:center;--fui-spinner-color: var(--fui-primary-bg);--fui-spinner-overlay-z: 10}.fui-spinner--sm{width:1rem;height:1rem}.fui-spinner--md{width:2.5rem;height:2.5rem}.fui-spinner--lg{width:4rem;height:4rem}.fui-spinner__svg{width:100%;height:100%}.fui-spinner__track{stroke:var(--fui-bg-muted, #e2e8f0)}.fui-spinner__circle{stroke:var(--fui-spinner-color);transform-origin:center}.fui-spinner--indeterminate .fui-spinner__svg{animation:fui-spin var(--fui-duration-deliberate, .7s) linear infinite}.fui-spinner--indeterminate .fui-spinner__circle{stroke-dasharray:80,200;stroke-dashoffset:0;animation:fui-spinner-dash 1.5s ease-in-out infinite}.fui-spinner--determinate .fui-spinner__circle{transition:stroke-dashoffset var(--fui-duration-base, .3s) var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transform:rotate(-90deg);transform-origin:center}.fui-spinner--overlay{position:static}.fui-spinner__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background-color:#ffffffb3;z-index:var(--fui-spinner-overlay-z);border-radius:inherit}[data-theme=dark] .fui-spinner__overlay{background-color:#00000080}@keyframes fui-spinner-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:89,200;stroke-dashoffset:-35px}to{stroke-dasharray:89,200;stroke-dashoffset:-124px}}@media(prefers-reduced-motion:reduce){.fui-spinner__svg,.fui-spinner__circle{animation:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
55
55
|
}
|
|
56
56
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiSpinnerComponent, decorators: [{
|
|
57
57
|
type: Component,
|
|
@@ -69,7 +69,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
69
69
|
'[attr.aria-valuemin]': 'mode() === "determinate" ? 0 : null',
|
|
70
70
|
'[attr.aria-valuemax]': 'mode() === "determinate" ? 100 : null',
|
|
71
71
|
'[attr.aria-label]': 'ariaLabel() ?? intl.loadingAriaLabel',
|
|
72
|
-
}, template: "@if (overlay()) {\r\n <div class=\"fui-spinner__overlay\">\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n} @else {\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n}\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-spinner{display:inline-flex;align-items:center;justify-content:center;--fui-spinner-color: var(--fui-primary-bg)}.fui-spinner--sm{width:1rem;height:1rem}.fui-spinner--md{width:2.5rem;height:2.5rem}.fui-spinner--lg{width:4rem;height:4rem}.fui-spinner__svg{width:100%;height:100%}.fui-spinner__track{stroke:var(--fui-bg-muted, #e2e8f0)}.fui-spinner__circle{stroke:var(--fui-spinner-color);transform-origin:center}.fui-spinner--indeterminate .fui-spinner__svg{animation:fui-spin var(--fui-duration-deliberate, .7s) linear infinite}.fui-spinner--indeterminate .fui-spinner__circle{stroke-dasharray:80,200;stroke-dashoffset:0;animation:fui-spinner-dash 1.5s ease-in-out infinite}.fui-spinner--determinate .fui-spinner__circle{transition:stroke-dashoffset var(--fui-duration-base, .3s) var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transform:rotate(-90deg);transform-origin:center}.fui-spinner--overlay{position:static}.fui-spinner__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background-color:#ffffffb3;z-index:var(--fui-
|
|
72
|
+
}, template: "@if (overlay()) {\r\n <div class=\"fui-spinner__overlay\">\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n} @else {\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n}\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-spinner{display:inline-flex;align-items:center;justify-content:center;--fui-spinner-color: var(--fui-primary-bg);--fui-spinner-overlay-z: 10}.fui-spinner--sm{width:1rem;height:1rem}.fui-spinner--md{width:2.5rem;height:2.5rem}.fui-spinner--lg{width:4rem;height:4rem}.fui-spinner__svg{width:100%;height:100%}.fui-spinner__track{stroke:var(--fui-bg-muted, #e2e8f0)}.fui-spinner__circle{stroke:var(--fui-spinner-color);transform-origin:center}.fui-spinner--indeterminate .fui-spinner__svg{animation:fui-spin var(--fui-duration-deliberate, .7s) linear infinite}.fui-spinner--indeterminate .fui-spinner__circle{stroke-dasharray:80,200;stroke-dashoffset:0;animation:fui-spinner-dash 1.5s ease-in-out infinite}.fui-spinner--determinate .fui-spinner__circle{transition:stroke-dashoffset var(--fui-duration-base, .3s) var(--fui-ease-in-out, cubic-bezier(.4, 0, .2, 1));transform:rotate(-90deg);transform-origin:center}.fui-spinner--overlay{position:static}.fui-spinner__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background-color:#ffffffb3;z-index:var(--fui-spinner-overlay-z);border-radius:inherit}[data-theme=dark] .fui-spinner__overlay{background-color:#00000080}@keyframes fui-spinner-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:89,200;stroke-dashoffset:-35px}to{stroke-dasharray:89,200;stroke-dashoffset:-124px}}@media(prefers-reduced-motion:reduce){.fui-spinner__svg,.fui-spinner__circle{animation:none}}\n"] }]
|
|
73
73
|
}], ctorParameters: () => [], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], overlay: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlay", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }] } });
|
|
74
74
|
|
|
75
75
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raintonic-formaui-components-spinner.mjs","sources":["../../../lib/components/spinner/spinner.intl.ts","../../../lib/components/spinner/spinner.component.ts","../../../lib/components/spinner/spinner.component.html","../../../lib/components/spinner/raintonic-formaui-components-spinner.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiSpinnerIntl extends FuiIntlBase {\r\n loadingAriaLabel = 'Loading';\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n ViewEncapsulation,\r\n computed,\r\n inject,\r\n input,\r\n numberAttribute,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { FuiSpinnerMode, FuiSpinnerSize } from './spinner.types';\r\nimport { FuiSpinnerIntl } from './spinner.intl';\r\n\r\n/**\r\n * @component FuiSpinnerComponent\r\n * @selector fui-spinner\r\n * @description A circular loading spinner with determinate and indeterminate modes.\r\n * Supports an overlay mode that covers its parent container.\r\n *\r\n * @input mode - Spinner mode: 'determinate' | 'indeterminate'. Default 'indeterminate'.\r\n * @input value - Progress value (0-100) for determinate mode. Default 0.\r\n * @input size - Spinner size: 'sm' | 'md' | 'lg'. Default 'md'.\r\n * @input color - Optional custom CSS color for the spinner stroke.\r\n * @input overlay - Whether to render as a full-area overlay. Default false.\r\n * @input ariaLabel - Accessible label. Default 'Loading'.\r\n *\r\n * @example\r\n * <fui-spinner></fui-spinner>\r\n *\r\n * @example\r\n * <fui-spinner mode=\"determinate\" [value]=\"progress\" size=\"lg\"></fui-spinner>\r\n */\r\n@Component({\r\n selector: 'fui-spinner',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './spinner.component.html',\r\n styleUrls: ['./spinner.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-spinner',\r\n '[class.fui-spinner--sm]': 'size() === \"sm\"',\r\n '[class.fui-spinner--md]': 'size() === \"md\"',\r\n '[class.fui-spinner--lg]': 'size() === \"lg\"',\r\n '[class.fui-spinner--overlay]': 'overlay()',\r\n '[class.fui-spinner--determinate]': 'mode() === \"determinate\"',\r\n '[class.fui-spinner--indeterminate]': 'mode() === \"indeterminate\"',\r\n role: 'status',\r\n 'aria-live': 'polite',\r\n '[attr.aria-valuenow]': 'mode() === \"determinate\" ? clampedValue() : null',\r\n '[attr.aria-valuemin]': 'mode() === \"determinate\" ? 0 : null',\r\n '[attr.aria-valuemax]': 'mode() === \"determinate\" ? 100 : null',\r\n '[attr.aria-label]': 'ariaLabel() ?? intl.loadingAriaLabel',\r\n },\r\n})\r\nexport class FuiSpinnerComponent {\r\n readonly intl = inject(FuiSpinnerIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n readonly mode = input<FuiSpinnerMode>('indeterminate');\r\n readonly value = input<number, unknown>(0, { transform: numberAttribute });\r\n readonly size = input<FuiSpinnerSize>('md');\r\n readonly color = input<string | null>(null);\r\n readonly overlay = input(false);\r\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\r\n\r\n constructor() {\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });\r\n }\r\n\r\n private readonly RADIUS = 20;\r\n readonly circumference = 2 * Math.PI * this.RADIUS;\r\n\r\n readonly clampedValue = computed(() => Math.max(0, Math.min(100, this.value() || 0)));\r\n readonly strokeDashoffset = computed(() => {\r\n return this.circumference - (this.clampedValue() / 100) * this.circumference;\r\n });\r\n}\r\n","@if (overlay()) {\r\n <div class=\"fui-spinner__overlay\">\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n} @else {\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAIM,MAAO,cAAe,SAAQ,WAAW,CAAA;IAC7C,gBAAgB,GAAG,SAAS;uGADjB,cAAc,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAd,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,cAAc,cADD,MAAM,EAAA,CAAA;;2FACnB,cAAc,EAAA,UAAA,EAAA,CAAA;kBAD1B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACWlC;;;;;;;;;;;;;;;;;;AAkBG;MAyBU,mBAAmB,CAAA;AACrB,IAAA,IAAI,GAAG,MAAM,CAAC,cAAc,CAAC;AACrB,IAAA,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAExC,IAAA,IAAI,GAAG,KAAK,CAAiB,eAAe,2EAAC;IAC7C,KAAK,GAAG,KAAK,CAAkB,CAAC,6EAAI,SAAS,EAAE,eAAe,EAAA,CAAG;AACjE,IAAA,IAAI,GAAG,KAAK,CAAiB,IAAI,2EAAC;AAClC,IAAA,KAAK,GAAG,KAAK,CAAgB,IAAI,4EAAC;AAClC,IAAA,OAAO,GAAG,KAAK,CAAC,KAAK,8EAAC;IACtB,SAAS,GAAG,KAAK,CAAqB,SAAS,iFAAI,KAAK,EAAE,YAAY,EAAA,CAAG;AAElF,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS,CAAC,MAAK,EAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7F;IAEiB,MAAM,GAAG,EAAE;IACnB,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM;IAEzC,YAAY,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,cAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;AAC5E,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;AACxC,QAAA,OAAO,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,GAAG,IAAI,IAAI,CAAC,aAAa;AAC9E,IAAA,CAAC,uFAAC;uGArBS,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,mBAAmB,k+CCzDhC,y5CAqCA,EAAA,MAAA,EAAA,CAAA,
|
|
1
|
+
{"version":3,"file":"raintonic-formaui-components-spinner.mjs","sources":["../../../lib/components/spinner/spinner.intl.ts","../../../lib/components/spinner/spinner.component.ts","../../../lib/components/spinner/spinner.component.html","../../../lib/components/spinner/raintonic-formaui-components-spinner.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiSpinnerIntl extends FuiIntlBase {\r\n loadingAriaLabel = 'Loading';\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n ViewEncapsulation,\r\n computed,\r\n inject,\r\n input,\r\n numberAttribute,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { FuiSpinnerMode, FuiSpinnerSize } from './spinner.types';\r\nimport { FuiSpinnerIntl } from './spinner.intl';\r\n\r\n/**\r\n * @component FuiSpinnerComponent\r\n * @selector fui-spinner\r\n * @description A circular loading spinner with determinate and indeterminate modes.\r\n * Supports an overlay mode that covers its parent container.\r\n *\r\n * @input mode - Spinner mode: 'determinate' | 'indeterminate'. Default 'indeterminate'.\r\n * @input value - Progress value (0-100) for determinate mode. Default 0.\r\n * @input size - Spinner size: 'sm' | 'md' | 'lg'. Default 'md'.\r\n * @input color - Optional custom CSS color for the spinner stroke.\r\n * @input overlay - Whether to render as a full-area overlay. Default false.\r\n * @input ariaLabel - Accessible label. Default 'Loading'.\r\n *\r\n * @example\r\n * <fui-spinner></fui-spinner>\r\n *\r\n * @example\r\n * <fui-spinner mode=\"determinate\" [value]=\"progress\" size=\"lg\"></fui-spinner>\r\n */\r\n@Component({\r\n selector: 'fui-spinner',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './spinner.component.html',\r\n styleUrls: ['./spinner.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-spinner',\r\n '[class.fui-spinner--sm]': 'size() === \"sm\"',\r\n '[class.fui-spinner--md]': 'size() === \"md\"',\r\n '[class.fui-spinner--lg]': 'size() === \"lg\"',\r\n '[class.fui-spinner--overlay]': 'overlay()',\r\n '[class.fui-spinner--determinate]': 'mode() === \"determinate\"',\r\n '[class.fui-spinner--indeterminate]': 'mode() === \"indeterminate\"',\r\n role: 'status',\r\n 'aria-live': 'polite',\r\n '[attr.aria-valuenow]': 'mode() === \"determinate\" ? clampedValue() : null',\r\n '[attr.aria-valuemin]': 'mode() === \"determinate\" ? 0 : null',\r\n '[attr.aria-valuemax]': 'mode() === \"determinate\" ? 100 : null',\r\n '[attr.aria-label]': 'ariaLabel() ?? intl.loadingAriaLabel',\r\n },\r\n})\r\nexport class FuiSpinnerComponent {\r\n readonly intl = inject(FuiSpinnerIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n readonly mode = input<FuiSpinnerMode>('indeterminate');\r\n readonly value = input<number, unknown>(0, { transform: numberAttribute });\r\n readonly size = input<FuiSpinnerSize>('md');\r\n readonly color = input<string | null>(null);\r\n readonly overlay = input(false);\r\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\r\n\r\n constructor() {\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });\r\n }\r\n\r\n private readonly RADIUS = 20;\r\n readonly circumference = 2 * Math.PI * this.RADIUS;\r\n\r\n readonly clampedValue = computed(() => Math.max(0, Math.min(100, this.value() || 0)));\r\n readonly strokeDashoffset = computed(() => {\r\n return this.circumference - (this.clampedValue() / 100) * this.circumference;\r\n });\r\n}\r\n","@if (overlay()) {\r\n <div class=\"fui-spinner__overlay\">\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n} @else {\r\n <svg class=\"fui-spinner__svg\" viewBox=\"0 0 48 48\" [style.--fui-spinner-color]=\"color()\">\r\n @if (mode() === 'determinate') {\r\n <circle class=\"fui-spinner__track\" cx=\"24\" cy=\"24\" r=\"20\" fill=\"none\" stroke-width=\"4\" />\r\n }\r\n <circle\r\n class=\"fui-spinner__circle\"\r\n cx=\"24\"\r\n cy=\"24\"\r\n r=\"20\"\r\n fill=\"none\"\r\n stroke-width=\"4\"\r\n [attr.stroke-dasharray]=\"mode() === 'determinate' ? circumference : null\"\r\n [attr.stroke-dashoffset]=\"mode() === 'determinate' ? strokeDashoffset() : null\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|