@frame-kit/ui-ng 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +683 -0
- package/DEVELOPMENT_GUIDE.md +1102 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/THEMING.md +130 -0
- package/core/headline/README.md +121 -0
- package/core/icon/README.md +173 -0
- package/core/image/README.md +210 -0
- package/core/link/README.md +297 -0
- package/core/separator/README.md +145 -0
- package/core/text/README.md +240 -0
- package/directives/infinite-scroll/README.md +102 -0
- package/directives/spotlight/README.md +154 -0
- package/directives/tooltip/README.md +147 -0
- package/docs/endpoint-link/README.md +142 -0
- package/docs/method-badge/README.md +154 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs +122 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs +189 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs +123 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs +369 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs +59 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs +204 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs +74 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs +425 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs +63 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs +43 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs +3632 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs +239 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs +132 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs +133 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs +60 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs +166 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs +214 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs +82 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs +68 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs +108 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs +70 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs +1288 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +456 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs +125 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs +111 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs +103 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs +135 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs +79 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs +40 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs +91 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs +86 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs +443 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs +56 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs +105 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs +129 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs +42 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs +894 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs +179 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs +143 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs +191 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng.mjs.map +1 -0
- package/layouts/app-shell/README.md +357 -0
- package/layouts/content-split/README.md +180 -0
- package/package.json +253 -0
- package/services/overlay-orchestrator/README.md +184 -0
- package/services/spotlight/README.md +61 -0
- package/services/toast/README.md +118 -0
- package/types/frame-kit-ui-ng-core-headline.d.ts +38 -0
- package/types/frame-kit-ui-ng-core-icon.d.ts +74 -0
- package/types/frame-kit-ui-ng-core-image.d.ts +93 -0
- package/types/frame-kit-ui-ng-core-link.d.ts +251 -0
- package/types/frame-kit-ui-ng-core-separator.d.ts +28 -0
- package/types/frame-kit-ui-ng-core-text.d.ts +186 -0
- package/types/frame-kit-ui-ng-directives-infinite-scroll.d.ts +42 -0
- package/types/frame-kit-ui-ng-directives-spotlight.d.ts +51 -0
- package/types/frame-kit-ui-ng-directives-tooltip.d.ts +70 -0
- package/types/frame-kit-ui-ng-docs-endpoint-link.d.ts +43 -0
- package/types/frame-kit-ui-ng-docs-method-badge.d.ts +30 -0
- package/types/frame-kit-ui-ng-forms.d.ts +1674 -0
- package/types/frame-kit-ui-ng-layouts-app-shell.d.ts +75 -0
- package/types/frame-kit-ui-ng-layouts-content-split.d.ts +43 -0
- package/types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts +96 -0
- package/types/frame-kit-ui-ng-services-spotlight.d.ts +32 -0
- package/types/frame-kit-ui-ng-services-toast.d.ts +100 -0
- package/types/frame-kit-ui-ng-ui-accordion.d.ts +86 -0
- package/types/frame-kit-ui-ng-ui-alert.d.ts +34 -0
- package/types/frame-kit-ui-ng-ui-avatar-stack.d.ts +38 -0
- package/types/frame-kit-ui-ng-ui-avatar.d.ts +36 -0
- package/types/frame-kit-ui-ng-ui-badge.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-breadcrumb.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-button.d.ts +48 -0
- package/types/frame-kit-ui-ng-ui-callout.d.ts +26 -0
- package/types/frame-kit-ui-ng-ui-card.d.ts +30 -0
- package/types/frame-kit-ui-ng-ui-copyable-field.d.ts +62 -0
- package/types/frame-kit-ui-ng-ui-data-table.d.ts +482 -0
- package/types/frame-kit-ui-ng-ui-dialog.d.ts +166 -0
- package/types/frame-kit-ui-ng-ui-drawer.d.ts +130 -0
- package/types/frame-kit-ui-ng-ui-dropdown-menu.d.ts +77 -0
- package/types/frame-kit-ui-ng-ui-editable-field.d.ts +65 -0
- package/types/frame-kit-ui-ng-ui-icon-badge.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-icon-list.d.ts +67 -0
- package/types/frame-kit-ui-ng-ui-inline-edit.d.ts +44 -0
- package/types/frame-kit-ui-ng-ui-list-editor.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-loader.d.ts +32 -0
- package/types/frame-kit-ui-ng-ui-menu-item.d.ts +27 -0
- package/types/frame-kit-ui-ng-ui-nav-brand.d.ts +25 -0
- package/types/frame-kit-ui-ng-ui-nav-group.d.ts +60 -0
- package/types/frame-kit-ui-ng-ui-nav-separator.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-node-tree-breadcrumb.d.ts +35 -0
- package/types/frame-kit-ui-ng-ui-node-tree.d.ts +135 -0
- package/types/frame-kit-ui-ng-ui-note.d.ts +22 -0
- package/types/frame-kit-ui-ng-ui-numbered-list.d.ts +52 -0
- package/types/frame-kit-ui-ng-ui-pagination.d.ts +49 -0
- package/types/frame-kit-ui-ng-ui-progress-bar.d.ts +50 -0
- package/types/frame-kit-ui-ng-ui-sidenav-link.d.ts +24 -0
- package/types/frame-kit-ui-ng-ui-tabs.d.ts +266 -0
- package/types/frame-kit-ui-ng-ui-timeline.d.ts +42 -0
- package/types/frame-kit-ui-ng-ui-toast.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-user-menu.d.ts +87 -0
- package/types/frame-kit-ui-ng-ui-wizard-dialog.d.ts +116 -0
- package/types/frame-kit-ui-ng.d.ts +53 -0
- package/ui/accordion/README.md +261 -0
- package/ui/alert/README.md +211 -0
- package/ui/avatar/README.md +167 -0
- package/ui/avatar-stack/README.md +164 -0
- package/ui/badge/README.md +162 -0
- package/ui/breadcrumb/README.md +240 -0
- package/ui/button/README.md +184 -0
- package/ui/callout/README.md +159 -0
- package/ui/card/README.md +174 -0
- package/ui/copyable-field/README.md +235 -0
- package/ui/data-table/README.md +408 -0
- package/ui/dialog/README.md +222 -0
- package/ui/drawer/README.md +274 -0
- package/ui/dropdown-menu/README.md +336 -0
- package/ui/editable-field/README.md +171 -0
- package/ui/icon-badge/README.md +131 -0
- package/ui/icon-list/README.md +205 -0
- package/ui/inline-edit/README.md +135 -0
- package/ui/list-editor/README.md +162 -0
- package/ui/loader/README.md +160 -0
- package/ui/menu-item/README.md +204 -0
- package/ui/nav-brand/README.md +111 -0
- package/ui/nav-group/README.md +145 -0
- package/ui/nav-separator/README.md +44 -0
- package/ui/node-tree/README.md +278 -0
- package/ui/node-tree-breadcrumb/README.md +164 -0
- package/ui/note/README.md +146 -0
- package/ui/numbered-list/README.md +187 -0
- package/ui/pagination/README.md +174 -0
- package/ui/progress-bar/README.md +223 -0
- package/ui/sidenav-link/README.md +214 -0
- package/ui/tabs/README.md +204 -0
- package/ui/timeline/README.md +285 -0
- package/ui/toast/README.md +243 -0
- package/ui/user-menu/README.md +260 -0
- package/ui/wizard-dialog/README.md +283 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-services-overlay-orchestrator.mjs","sources":["../../../../packages/ui-ng/services/overlay-orchestrator/overlay-orchestrator.service.ts","../../../../packages/ui-ng/services/overlay-orchestrator/overlay-orchestrator.types.ts","../../../../packages/ui-ng/services/overlay-orchestrator/frame-kit-ui-ng-services-overlay-orchestrator.ts"],"sourcesContent":["import { computed, Injectable, signal } from '@angular/core';\n\nimport type { OverlayEntry } from './overlay-orchestrator.types';\n\nlet nextOverlayId = 0;\n\n/**\n * Centralized overlay orchestrator.\n *\n * Tracks all open overlays (dialogs, drawers, popovers, navigation, tooltips)\n * in a priority-based stack. When a new overlay opens:\n *\n * - All overlays with LOWER priority are closed automatically.\n * - Overlays with EQUAL or HIGHER priority are left open.\n *\n * This prevents UI conflicts like drawers staying open behind dialogs,\n * or kebab menus persisting when a modal pops up.\n *\n * @example\n * ```ts\n * const id = orchestrator.register({\n * priority: OVERLAY_PRIORITY.DRAWER,\n * type: 'drawer',\n * close: () => drawerRef.close(),\n * });\n *\n * // Later, when the overlay closes:\n * orchestrator.unregister(id);\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class OverlayOrchestrator {\n private readonly entries = signal<OverlayEntry[]>([]);\n\n /** Whether any overlay is currently open. */\n readonly hasActiveOverlay = computed(() => this.entries().length > 0);\n\n /** The topmost (highest priority) overlay. */\n readonly topOverlay = computed<OverlayEntry | null>(() => {\n const all = this.entries();\n\n if (all.length === 0) {\n return null;\n }\n\n return all.reduce((top, entry) =>\n entry.priority >= top.priority ? entry : top,\n );\n });\n\n /** Current number of active overlays. */\n readonly count = computed(() => this.entries().length);\n\n /**\n * Register an overlay and close all overlays with lower priority.\n *\n * @returns The unique overlay ID — pass this to `unregister()` when closing.\n */\n register(entry: Omit<OverlayEntry, 'id'>): string {\n const id = `overlay-${nextOverlayId++}`;\n\n // Close all overlays with strictly lower priority\n const current = this.entries();\n const toClose = current.filter((e) => e.priority < entry.priority);\n\n for (const overlay of toClose) {\n overlay.close();\n }\n\n // Remove closed overlays and add the new one\n const remaining = current.filter((e) => e.priority >= entry.priority);\n\n this.entries.set([...remaining, { ...entry, id }]);\n\n return id;\n }\n\n /**\n * Unregister an overlay by ID. Call this when the overlay closes.\n */\n unregister(id: string): void {\n this.entries.update((entries) => entries.filter((e) => e.id !== id));\n }\n\n /**\n * Check if an overlay with the given priority or higher is currently open.\n * Useful for guards that want to prevent opening lower-priority overlays.\n */\n hasOverlayAtOrAbove(priority: number): boolean {\n return this.entries().some((e) => e.priority >= priority);\n }\n\n /**\n * Check if any overlay of a specific type is open.\n */\n hasOverlayOfType(type: string): boolean {\n return this.entries().some((e) => e.type === type);\n }\n\n /**\n * Close all overlays. Closes from lowest to highest priority.\n */\n closeAll(): void {\n const sorted = [...this.entries()].sort((a, b) => a.priority - b.priority);\n\n for (const entry of sorted) {\n entry.close();\n }\n\n this.entries.set([]);\n }\n\n /**\n * Close all overlays at or below the given priority.\n */\n closeAtOrBelow(priority: number): void {\n const current = this.entries();\n const toClose = current.filter((e) => e.priority <= priority);\n\n for (const overlay of toClose) {\n overlay.close();\n }\n\n this.entries.update((entries) =>\n entries.filter((e) => e.priority > priority),\n );\n }\n}\n","/**\n * Default priority levels for common overlay types.\n * Higher number = higher priority = stays open when lower-priority overlays open.\n *\n * Consumers can use any number — these are conventions, not constraints.\n */\nexport const OVERLAY_PRIORITY = {\n /** Tooltips, inline popovers */\n TOOLTIP: 0,\n\n /** Dropdown menus, kebab menus, popovers */\n POPOVER: 10,\n\n /** Side panels, detail drawers */\n DRAWER: 20,\n\n /** Modal dialogs, confirmations */\n DIALOG: 30,\n\n /** App-level navigation (sidebar, mobile nav) */\n NAVIGATION: 40,\n} as const;\n\nexport interface OverlayEntry {\n /** Unique identifier for this overlay instance */\n id: string;\n\n /** Priority level — higher stays open, lower gets closed */\n priority: number;\n\n /** Overlay type label (for debugging/logging) */\n type: string;\n\n /** Called by the orchestrator to close this overlay */\n close: () => void;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { signal, Injectable } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Coordinates "spotlight" pulses across unrelated DOM trees.
|
|
6
|
+
*
|
|
7
|
+
* A holder calls `activate(key)`; every element registered as a target of
|
|
8
|
+
* the same key picks up the spotlight animation in sync. `deactivate`
|
|
9
|
+
* releases that holder. Holders are reference-counted — multiple callers
|
|
10
|
+
* (a hover trigger and a programmatic one-shot, say) can hold the same
|
|
11
|
+
* key concurrently, and the key only clears once every holder has
|
|
12
|
+
* released. This lets a programmatic "auto-spotlight on docs-panel open"
|
|
13
|
+
* coexist with the hover-driven trigger without one cancelling the
|
|
14
|
+
* other prematurely.
|
|
15
|
+
*
|
|
16
|
+
* The model is still a single global active key — last activation wins
|
|
17
|
+
* if a different key arrives while one is held; the primary use case
|
|
18
|
+
* (onboarding "find this button" cues) is mutually exclusive by nature.
|
|
19
|
+
*/
|
|
20
|
+
class SpotlightService {
|
|
21
|
+
_activeKey = signal(null, ...(ngDevMode ? [{ debugName: "_activeKey" }] : /* istanbul ignore next */ []));
|
|
22
|
+
holders = new Map();
|
|
23
|
+
/** Read-only signal exposing the currently active spotlight key, or `null` when none is active. */
|
|
24
|
+
activeKey = this._activeKey.asReadonly();
|
|
25
|
+
/** Activate the spotlight for the given key, incrementing its holder count. */
|
|
26
|
+
activate(key) {
|
|
27
|
+
const current = this.holders.get(key) ?? 0;
|
|
28
|
+
this.holders.set(key, current + 1);
|
|
29
|
+
this._activeKey.set(key);
|
|
30
|
+
}
|
|
31
|
+
/** Release one holder of the given key; clears the active key when the last holder deactivates. */
|
|
32
|
+
deactivate(key) {
|
|
33
|
+
const current = this.holders.get(key) ?? 0;
|
|
34
|
+
if (current <= 0) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const next = current - 1;
|
|
38
|
+
if (next === 0) {
|
|
39
|
+
this.holders.delete(key);
|
|
40
|
+
if (this._activeKey() === key) {
|
|
41
|
+
this._activeKey.set(null);
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.holders.set(key, next);
|
|
46
|
+
}
|
|
47
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SpotlightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
48
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SpotlightService, providedIn: 'root' });
|
|
49
|
+
}
|
|
50
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SpotlightService, decorators: [{
|
|
51
|
+
type: Injectable,
|
|
52
|
+
args: [{ providedIn: 'root' }]
|
|
53
|
+
}] });
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Generated bundle index. Do not edit.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
export { SpotlightService };
|
|
60
|
+
//# sourceMappingURL=frame-kit-ui-ng-services-spotlight.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-services-spotlight.mjs","sources":["../../../../packages/ui-ng/services/spotlight/spotlight.service.ts","../../../../packages/ui-ng/services/spotlight/frame-kit-ui-ng-services-spotlight.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\n\n/**\n * Coordinates \"spotlight\" pulses across unrelated DOM trees.\n *\n * A holder calls `activate(key)`; every element registered as a target of\n * the same key picks up the spotlight animation in sync. `deactivate`\n * releases that holder. Holders are reference-counted — multiple callers\n * (a hover trigger and a programmatic one-shot, say) can hold the same\n * key concurrently, and the key only clears once every holder has\n * released. This lets a programmatic \"auto-spotlight on docs-panel open\"\n * coexist with the hover-driven trigger without one cancelling the\n * other prematurely.\n *\n * The model is still a single global active key — last activation wins\n * if a different key arrives while one is held; the primary use case\n * (onboarding \"find this button\" cues) is mutually exclusive by nature.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpotlightService {\n private readonly _activeKey = signal<string | null>(null);\n private readonly holders = new Map<string, number>();\n\n /** Read-only signal exposing the currently active spotlight key, or `null` when none is active. */\n readonly activeKey = this._activeKey.asReadonly();\n\n /** Activate the spotlight for the given key, incrementing its holder count. */\n activate(key: string): void {\n const current = this.holders.get(key) ?? 0;\n\n this.holders.set(key, current + 1);\n this._activeKey.set(key);\n }\n\n /** Release one holder of the given key; clears the active key when the last holder deactivates. */\n deactivate(key: string): void {\n const current = this.holders.get(key) ?? 0;\n\n if (current <= 0) {\n return;\n }\n\n const next = current - 1;\n\n if (next === 0) {\n this.holders.delete(key);\n\n if (this._activeKey() === key) {\n this._activeKey.set(null);\n }\n\n return;\n }\n\n this.holders.set(key, next);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;AAeG;MAEU,gBAAgB,CAAA;AACV,IAAA,UAAU,GAAG,MAAM,CAAgB,IAAI,iFAAC;AACxC,IAAA,OAAO,GAAG,IAAI,GAAG,EAAkB;;AAG3C,IAAA,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE;;AAGjD,IAAA,QAAQ,CAAC,GAAW,EAAA;AAClB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;QAE1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,CAAC,CAAC;AAClC,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;IAC1B;;AAGA,IAAA,UAAU,CAAC,GAAW,EAAA;AACpB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;AAE1C,QAAA,IAAI,OAAO,IAAI,CAAC,EAAE;YAChB;QACF;AAEA,QAAA,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC;AAExB,QAAA,IAAI,IAAI,KAAK,CAAC,EAAE;AACd,YAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;AAExB,YAAA,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,EAAE;AAC7B,gBAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;YAC3B;YAEA;QACF;QAEA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC;IAC7B;uGApCW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cADH,MAAM,EAAA,CAAA;;2FACnB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;AClBlC;;AAEG;;;;"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, signal, Injectable } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_TOAST_CONFIG = {
|
|
5
|
+
defaultDuration: 5000,
|
|
6
|
+
errorDuration: 8000,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const TOAST_DATA = new InjectionToken('TOAST_DATA');
|
|
10
|
+
const TOAST_REF = new InjectionToken('TOAST_REF');
|
|
11
|
+
/**
|
|
12
|
+
* Reference to an active toast. Injected into custom toast components
|
|
13
|
+
* so they can dismiss themselves.
|
|
14
|
+
*/
|
|
15
|
+
class ToastRef {
|
|
16
|
+
id;
|
|
17
|
+
dismissFn;
|
|
18
|
+
constructor(id, dismissFn) {
|
|
19
|
+
this.id = id;
|
|
20
|
+
this.dismissFn = dismissFn;
|
|
21
|
+
}
|
|
22
|
+
dismiss() {
|
|
23
|
+
this.dismissFn(this.id);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const TOAST_CONFIG = new InjectionToken('TOAST_CONFIG');
|
|
28
|
+
let nextToastId = 0;
|
|
29
|
+
/**
|
|
30
|
+
* Global toast notification service.
|
|
31
|
+
*
|
|
32
|
+
* Default toasts:
|
|
33
|
+
* ```ts
|
|
34
|
+
* this.toast.success("Saved successfully");
|
|
35
|
+
* this.toast.error("Something went wrong", "Please try again.");
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* Custom component toasts:
|
|
39
|
+
* ```ts
|
|
40
|
+
* this.toast.open(RetryToastComponent, {
|
|
41
|
+
* severity: "error",
|
|
42
|
+
* data: { message: "Failed to save", retryFn: () => this.save() },
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
class ToastService {
|
|
47
|
+
config = inject(TOAST_CONFIG, { optional: true });
|
|
48
|
+
timers = new Map();
|
|
49
|
+
_toasts = signal([], ...(ngDevMode ? [{ debugName: "_toasts" }] : /* istanbul ignore next */ []));
|
|
50
|
+
/** Current toast stack (read-only). */
|
|
51
|
+
toasts = this._toasts.asReadonly();
|
|
52
|
+
/** Resolved config with defaults. */
|
|
53
|
+
resolvedConfig = {
|
|
54
|
+
...DEFAULT_TOAST_CONFIG,
|
|
55
|
+
...this.config,
|
|
56
|
+
defaultDuration: this.config?.defaultDuration ??
|
|
57
|
+
DEFAULT_TOAST_CONFIG.defaultDuration ??
|
|
58
|
+
5000,
|
|
59
|
+
errorDuration: this.config?.errorDuration ?? DEFAULT_TOAST_CONFIG.errorDuration ?? 8000,
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Show a default toast. Returns the toast ID for manual dismissal.
|
|
63
|
+
*/
|
|
64
|
+
show(options) {
|
|
65
|
+
const id = `fk-toast-${nextToastId++}`;
|
|
66
|
+
const duration = options.duration ??
|
|
67
|
+
(options.severity === 'error'
|
|
68
|
+
? this.resolvedConfig.errorDuration
|
|
69
|
+
: this.resolvedConfig.defaultDuration);
|
|
70
|
+
const toast = {
|
|
71
|
+
id,
|
|
72
|
+
severity: options.severity,
|
|
73
|
+
summary: options.summary,
|
|
74
|
+
detail: options.detail,
|
|
75
|
+
duration,
|
|
76
|
+
};
|
|
77
|
+
this._toasts.update((list) => [...list, toast]);
|
|
78
|
+
this.scheduleAutoDismiss(id, duration);
|
|
79
|
+
return id;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Show a custom component toast. The component receives TOAST_DATA
|
|
83
|
+
* and TOAST_REF via injection. Returns a ToastRef for external dismissal.
|
|
84
|
+
*/
|
|
85
|
+
open(component, options = {}) {
|
|
86
|
+
const id = `fk-toast-${nextToastId++}`;
|
|
87
|
+
const severity = options.severity ?? 'info';
|
|
88
|
+
const duration = options.duration ??
|
|
89
|
+
(severity === 'error'
|
|
90
|
+
? this.resolvedConfig.errorDuration
|
|
91
|
+
: this.resolvedConfig.defaultDuration);
|
|
92
|
+
const toast = {
|
|
93
|
+
id,
|
|
94
|
+
severity,
|
|
95
|
+
summary: '',
|
|
96
|
+
duration,
|
|
97
|
+
component,
|
|
98
|
+
data: options.data,
|
|
99
|
+
};
|
|
100
|
+
this._toasts.update((list) => [...list, toast]);
|
|
101
|
+
this.scheduleAutoDismiss(id, duration);
|
|
102
|
+
return new ToastRef(id, (toastId) => this.dismiss(toastId));
|
|
103
|
+
}
|
|
104
|
+
/** Dismiss a specific toast by ID. */
|
|
105
|
+
dismiss(id) {
|
|
106
|
+
const timer = this.timers.get(id);
|
|
107
|
+
if (timer) {
|
|
108
|
+
clearTimeout(timer);
|
|
109
|
+
this.timers.delete(id);
|
|
110
|
+
}
|
|
111
|
+
this._toasts.update((list) => list.filter((t) => t.id !== id));
|
|
112
|
+
}
|
|
113
|
+
/** Clear all toasts. */
|
|
114
|
+
clear() {
|
|
115
|
+
for (const timer of this.timers.values()) {
|
|
116
|
+
clearTimeout(timer);
|
|
117
|
+
}
|
|
118
|
+
this.timers.clear();
|
|
119
|
+
this._toasts.set([]);
|
|
120
|
+
}
|
|
121
|
+
// ===== CONVENIENCE METHODS =====
|
|
122
|
+
/** Show a success toast and return its ID. */
|
|
123
|
+
success(summary, detail) {
|
|
124
|
+
return this.show({ severity: 'success', summary, detail });
|
|
125
|
+
}
|
|
126
|
+
/** Show an error toast and return its ID. */
|
|
127
|
+
error(summary, detail) {
|
|
128
|
+
return this.show({ severity: 'error', summary, detail });
|
|
129
|
+
}
|
|
130
|
+
/** Show a warning toast and return its ID. */
|
|
131
|
+
warning(summary, detail) {
|
|
132
|
+
return this.show({ severity: 'warning', summary, detail });
|
|
133
|
+
}
|
|
134
|
+
/** Show an informational toast and return its ID. */
|
|
135
|
+
info(summary, detail) {
|
|
136
|
+
return this.show({ severity: 'info', summary, detail });
|
|
137
|
+
}
|
|
138
|
+
// ===== PRIVATE =====
|
|
139
|
+
scheduleAutoDismiss(id, duration) {
|
|
140
|
+
if (duration > 0) {
|
|
141
|
+
const timer = setTimeout(() => {
|
|
142
|
+
this.dismiss(id);
|
|
143
|
+
}, duration);
|
|
144
|
+
this.timers.set(id, timer);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
148
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ToastService, providedIn: 'root' });
|
|
149
|
+
}
|
|
150
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ToastService, decorators: [{
|
|
151
|
+
type: Injectable,
|
|
152
|
+
args: [{ providedIn: 'root' }]
|
|
153
|
+
}] });
|
|
154
|
+
/**
|
|
155
|
+
* Provide toast configuration at the application level.
|
|
156
|
+
*/
|
|
157
|
+
function provideToastConfig(config) {
|
|
158
|
+
return [{ provide: TOAST_CONFIG, useValue: config }];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Generated bundle index. Do not edit.
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
export { DEFAULT_TOAST_CONFIG, TOAST_CONFIG, TOAST_DATA, TOAST_REF, ToastRef, ToastService, provideToastConfig };
|
|
166
|
+
//# sourceMappingURL=frame-kit-ui-ng-services-toast.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-services-toast.mjs","sources":["../../../../packages/ui-ng/services/toast/toast.types.ts","../../../../packages/ui-ng/services/toast/toast-ref.ts","../../../../packages/ui-ng/services/toast/toast.service.ts","../../../../packages/ui-ng/services/toast/frame-kit-ui-ng-services-toast.ts"],"sourcesContent":["import type { Type } from '@angular/core';\n\nexport type ToastSeverity = 'success' | 'error' | 'warning' | 'info';\n\nexport interface Toast {\n id: string;\n severity: ToastSeverity;\n summary: string;\n detail?: string;\n duration: number;\n component?: Type<unknown>;\n data?: unknown;\n}\n\nexport interface ToastConfig {\n icons?: Partial<Record<ToastSeverity, string>>;\n defaultDuration?: number;\n errorDuration?: number;\n}\n\nexport const DEFAULT_TOAST_CONFIG: ToastConfig = {\n defaultDuration: 5000,\n errorDuration: 8000,\n};\n","import { InjectionToken } from '@angular/core';\n\nexport const TOAST_DATA = new InjectionToken<unknown>('TOAST_DATA');\nexport const TOAST_REF = new InjectionToken<ToastRef>('TOAST_REF');\n\n/**\n * Reference to an active toast. Injected into custom toast components\n * so they can dismiss themselves.\n */\nexport class ToastRef {\n constructor(\n readonly id: string,\n private readonly dismissFn: (id: string) => void,\n ) {}\n\n dismiss(): void {\n this.dismissFn(this.id);\n }\n}\n","import type { EnvironmentProviders, Provider, Type } from '@angular/core';\nimport { inject, Injectable, InjectionToken, signal } from '@angular/core';\n\nimport type { Toast, ToastConfig, ToastSeverity } from './toast.types';\nimport { DEFAULT_TOAST_CONFIG } from './toast.types';\nimport { ToastRef } from './toast-ref';\n\nexport const TOAST_CONFIG = new InjectionToken<ToastConfig>('TOAST_CONFIG');\n\nlet nextToastId = 0;\n\n/**\n * Global toast notification service.\n *\n * Default toasts:\n * ```ts\n * this.toast.success(\"Saved successfully\");\n * this.toast.error(\"Something went wrong\", \"Please try again.\");\n * ```\n *\n * Custom component toasts:\n * ```ts\n * this.toast.open(RetryToastComponent, {\n * severity: \"error\",\n * data: { message: \"Failed to save\", retryFn: () => this.save() },\n * });\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class ToastService {\n private readonly config = inject(TOAST_CONFIG, { optional: true });\n private readonly timers = new Map<string, ReturnType<typeof setTimeout>>();\n\n private readonly _toasts = signal<Toast[]>([]);\n\n /** Current toast stack (read-only). */\n readonly toasts = this._toasts.asReadonly();\n\n /** Resolved config with defaults. */\n readonly resolvedConfig: Required<\n Pick<ToastConfig, 'defaultDuration' | 'errorDuration'>\n > &\n ToastConfig = {\n ...DEFAULT_TOAST_CONFIG,\n ...this.config,\n defaultDuration:\n this.config?.defaultDuration ??\n DEFAULT_TOAST_CONFIG.defaultDuration ??\n 5000,\n errorDuration:\n this.config?.errorDuration ?? DEFAULT_TOAST_CONFIG.errorDuration ?? 8000,\n };\n\n /**\n * Show a default toast. Returns the toast ID for manual dismissal.\n */\n show(options: {\n severity: ToastSeverity;\n summary: string;\n detail?: string;\n duration?: number;\n }): string {\n const id = `fk-toast-${nextToastId++}`;\n\n const duration =\n options.duration ??\n (options.severity === 'error'\n ? this.resolvedConfig.errorDuration\n : this.resolvedConfig.defaultDuration);\n\n const toast: Toast = {\n id,\n severity: options.severity,\n summary: options.summary,\n detail: options.detail,\n duration,\n };\n\n this._toasts.update((list) => [...list, toast]);\n this.scheduleAutoDismiss(id, duration);\n\n return id;\n }\n\n /**\n * Show a custom component toast. The component receives TOAST_DATA\n * and TOAST_REF via injection. Returns a ToastRef for external dismissal.\n */\n open<TData = unknown>(\n component: Type<unknown>,\n options: {\n severity?: ToastSeverity;\n data?: TData;\n duration?: number;\n } = {},\n ): ToastRef {\n const id = `fk-toast-${nextToastId++}`;\n const severity = options.severity ?? 'info';\n\n const duration =\n options.duration ??\n (severity === 'error'\n ? this.resolvedConfig.errorDuration\n : this.resolvedConfig.defaultDuration);\n\n const toast: Toast = {\n id,\n severity,\n summary: '',\n duration,\n component,\n data: options.data,\n };\n\n this._toasts.update((list) => [...list, toast]);\n this.scheduleAutoDismiss(id, duration);\n\n return new ToastRef(id, (toastId) => this.dismiss(toastId));\n }\n\n /** Dismiss a specific toast by ID. */\n dismiss(id: string): void {\n const timer = this.timers.get(id);\n\n if (timer) {\n clearTimeout(timer);\n this.timers.delete(id);\n }\n\n this._toasts.update((list) => list.filter((t) => t.id !== id));\n }\n\n /** Clear all toasts. */\n clear(): void {\n for (const timer of this.timers.values()) {\n clearTimeout(timer);\n }\n\n this.timers.clear();\n this._toasts.set([]);\n }\n\n // ===== CONVENIENCE METHODS =====\n\n /** Show a success toast and return its ID. */\n success(summary: string, detail?: string): string {\n return this.show({ severity: 'success', summary, detail });\n }\n\n /** Show an error toast and return its ID. */\n error(summary: string, detail?: string): string {\n return this.show({ severity: 'error', summary, detail });\n }\n\n /** Show a warning toast and return its ID. */\n warning(summary: string, detail?: string): string {\n return this.show({ severity: 'warning', summary, detail });\n }\n\n /** Show an informational toast and return its ID. */\n info(summary: string, detail?: string): string {\n return this.show({ severity: 'info', summary, detail });\n }\n\n // ===== PRIVATE =====\n\n private scheduleAutoDismiss(id: string, duration: number): void {\n if (duration > 0) {\n const timer = setTimeout(() => {\n this.dismiss(id);\n }, duration);\n\n this.timers.set(id, timer);\n }\n }\n}\n\n/**\n * Provide toast configuration at the application level.\n */\nexport function provideToastConfig(\n config: ToastConfig,\n): (Provider | EnvironmentProviders)[] {\n return [{ provide: TOAST_CONFIG, useValue: config }];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, Directive, Injectable, inject, DestroyRef, input, contentChild, output, linkedSignal, computed, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
const FK_ACCORDION_CHEVRON = new InjectionToken('FK_ACCORDION_CHEVRON');
|
|
5
|
+
class FkAccordionChevronDirective {
|
|
6
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkAccordionChevronDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
7
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: FkAccordionChevronDirective, isStandalone: true, selector: "[fkAccordionChevron]", host: { attributes: { "aria-hidden": "true" } }, providers: [
|
|
8
|
+
{ provide: FK_ACCORDION_CHEVRON, useExisting: FkAccordionChevronDirective },
|
|
9
|
+
], ngImport: i0 });
|
|
10
|
+
}
|
|
11
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkAccordionChevronDirective, decorators: [{
|
|
12
|
+
type: Directive,
|
|
13
|
+
args: [{
|
|
14
|
+
selector: '[fkAccordionChevron]',
|
|
15
|
+
standalone: true,
|
|
16
|
+
providers: [
|
|
17
|
+
{ provide: FK_ACCORDION_CHEVRON, useExisting: FkAccordionChevronDirective },
|
|
18
|
+
],
|
|
19
|
+
host: {
|
|
20
|
+
'aria-hidden': 'true',
|
|
21
|
+
},
|
|
22
|
+
}]
|
|
23
|
+
}] });
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Coordinator scoped to a single `<fk-accordion-group>`. Any
|
|
27
|
+
* `<fk-accordion>` rendered inside a group picks this up via DI and
|
|
28
|
+
* reports its toggle state. The coordinator enforces single-open:
|
|
29
|
+
* when a new accordion opens, the previously active one is collapsed.
|
|
30
|
+
*/
|
|
31
|
+
class AccordionGroupCoordinator {
|
|
32
|
+
active = null;
|
|
33
|
+
register(accordion) {
|
|
34
|
+
if (accordion.expanded()) {
|
|
35
|
+
if (this.active && this.active !== accordion) {
|
|
36
|
+
accordion.setExpanded(false);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.active = accordion;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
unregister(accordion) {
|
|
44
|
+
if (this.active === accordion) {
|
|
45
|
+
this.active = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
notifyExpandedChange(accordion, nextExpanded) {
|
|
49
|
+
if (nextExpanded) {
|
|
50
|
+
const prev = this.active;
|
|
51
|
+
this.active = accordion;
|
|
52
|
+
if (prev && prev !== accordion) {
|
|
53
|
+
prev.setExpanded(false);
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (this.active === accordion) {
|
|
58
|
+
this.active = null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AccordionGroupCoordinator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
62
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AccordionGroupCoordinator });
|
|
63
|
+
}
|
|
64
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AccordionGroupCoordinator, decorators: [{
|
|
65
|
+
type: Injectable
|
|
66
|
+
}] });
|
|
67
|
+
|
|
68
|
+
const FK_ACCORDION_LEADING_ICON = new InjectionToken('FK_ACCORDION_LEADING_ICON');
|
|
69
|
+
class FkAccordionLeadingIconDirective {
|
|
70
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkAccordionLeadingIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
71
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: FkAccordionLeadingIconDirective, isStandalone: true, selector: "[fkAccordionLeadingIcon]", host: { attributes: { "aria-hidden": "true" } }, providers: [
|
|
72
|
+
{
|
|
73
|
+
provide: FK_ACCORDION_LEADING_ICON,
|
|
74
|
+
useExisting: FkAccordionLeadingIconDirective,
|
|
75
|
+
},
|
|
76
|
+
], ngImport: i0 });
|
|
77
|
+
}
|
|
78
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkAccordionLeadingIconDirective, decorators: [{
|
|
79
|
+
type: Directive,
|
|
80
|
+
args: [{
|
|
81
|
+
selector: '[fkAccordionLeadingIcon]',
|
|
82
|
+
standalone: true,
|
|
83
|
+
providers: [
|
|
84
|
+
{
|
|
85
|
+
provide: FK_ACCORDION_LEADING_ICON,
|
|
86
|
+
useExisting: FkAccordionLeadingIconDirective,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
host: {
|
|
90
|
+
'aria-hidden': 'true',
|
|
91
|
+
},
|
|
92
|
+
}]
|
|
93
|
+
}] });
|
|
94
|
+
|
|
95
|
+
let uid = 0;
|
|
96
|
+
class AccordionComponent {
|
|
97
|
+
group = inject(AccordionGroupCoordinator, {
|
|
98
|
+
optional: true,
|
|
99
|
+
});
|
|
100
|
+
destroyRef = inject(DestroyRef);
|
|
101
|
+
// ===== INPUTS =====
|
|
102
|
+
/** Heading text shown in the trigger row. */
|
|
103
|
+
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
104
|
+
/** Optional supporting text rendered beneath the title. */
|
|
105
|
+
description = input(null, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
106
|
+
/** Short label rendered to the leading side of the trigger row. */
|
|
107
|
+
leadingText = input(null, ...(ngDevMode ? [{ debugName: "leadingText" }] : /* istanbul ignore next */ []));
|
|
108
|
+
/** Controls the size variant of the accordion trigger and content. */
|
|
109
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
110
|
+
/** When true the accordion cannot be opened or closed by the user. */
|
|
111
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
112
|
+
/** Whether the panel starts in the expanded state on first render. */
|
|
113
|
+
defaultExpanded = input(false, ...(ngDevMode ? [{ debugName: "defaultExpanded" }] : /* istanbul ignore next */ []));
|
|
114
|
+
// ===== CONTENT CHILDREN =====
|
|
115
|
+
leadingIconRef = contentChild(FK_ACCORDION_LEADING_ICON, ...(ngDevMode ? [{ debugName: "leadingIconRef" }] : /* istanbul ignore next */ []));
|
|
116
|
+
chevronRef = contentChild(FK_ACCORDION_CHEVRON, ...(ngDevMode ? [{ debugName: "chevronRef" }] : /* istanbul ignore next */ []));
|
|
117
|
+
// ===== OUTPUTS =====
|
|
118
|
+
/** Fires whenever the panel opens or closes, emitting the new expanded state. */
|
|
119
|
+
expandedChange = output();
|
|
120
|
+
// ===== BASE PROPS =====
|
|
121
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
122
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
123
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
124
|
+
// ===== INTERNAL STATE =====
|
|
125
|
+
_expanded = linkedSignal(() => this.defaultExpanded(), ...(ngDevMode ? [{ debugName: "_expanded" }] : /* istanbul ignore next */ []));
|
|
126
|
+
uid = ++uid;
|
|
127
|
+
expanded = computed(() => this._expanded(), ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
128
|
+
triggerId = computed(() => `fk-accordion-${this.uid}-trigger`, ...(ngDevMode ? [{ debugName: "triggerId" }] : /* istanbul ignore next */ []));
|
|
129
|
+
panelId = computed(() => `fk-accordion-${this.uid}-panel`, ...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
|
|
130
|
+
// ===== COMPUTED =====
|
|
131
|
+
classes = computed(() => {
|
|
132
|
+
return [
|
|
133
|
+
'fk-accordion',
|
|
134
|
+
`fk-accordion--${this.size()}`,
|
|
135
|
+
this._expanded() ? 'fk-accordion--expanded' : '',
|
|
136
|
+
this.disabled() ? 'fk-accordion--disabled' : '',
|
|
137
|
+
this.className(),
|
|
138
|
+
]
|
|
139
|
+
.filter(Boolean)
|
|
140
|
+
.join(' ');
|
|
141
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
142
|
+
get hostClass() {
|
|
143
|
+
return this.classes();
|
|
144
|
+
}
|
|
145
|
+
// ===== LIFECYCLE =====
|
|
146
|
+
ngOnInit() {
|
|
147
|
+
if (!this.group) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
this.group.register(this);
|
|
151
|
+
this.destroyRef.onDestroy(() => this.group?.unregister(this));
|
|
152
|
+
}
|
|
153
|
+
// ===== ACTIONS =====
|
|
154
|
+
/** Toggles the expanded state if the accordion is not disabled. */
|
|
155
|
+
toggle() {
|
|
156
|
+
if (this.disabled()) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const next = !this._expanded();
|
|
160
|
+
this._expanded.set(next);
|
|
161
|
+
this.expandedChange.emit(next);
|
|
162
|
+
this.group?.notifyExpandedChange(this, next);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Set the expanded state imperatively. Reserved for
|
|
166
|
+
* `AccordionGroupCoordinator` to force-collapse siblings when a new
|
|
167
|
+
* accordion opens within the same group. Does not notify the
|
|
168
|
+
* coordinator (to avoid re-entrance loops).
|
|
169
|
+
*/
|
|
170
|
+
setExpanded(expanded) {
|
|
171
|
+
if (this._expanded() === expanded) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
this._expanded.set(expanded);
|
|
175
|
+
this.expandedChange.emit(expanded);
|
|
176
|
+
}
|
|
177
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AccordionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
178
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AccordionComponent, isStandalone: true, selector: "fk-accordion", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, leadingText: { classPropertyName: "leadingText", publicName: "leadingText", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, defaultExpanded: { classPropertyName: "defaultExpanded", publicName: "defaultExpanded", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expandedChange: "expandedChange" }, host: { properties: { "class": "this.hostClass" } }, queries: [{ propertyName: "leadingIconRef", first: true, predicate: FK_ACCORDION_LEADING_ICON, descendants: true, isSignal: true }, { propertyName: "chevronRef", first: true, predicate: FK_ACCORDION_CHEVRON, descendants: true, isSignal: true }], ngImport: i0, template: "<button\n type=\"button\"\n class=\"fk-accordion__header\"\n [id]=\"triggerId()\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"panelId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n @if (leadingIconRef()) {\n <span class=\"fk-accordion__leading-icon\">\n <ng-content select=\"[fkAccordionLeadingIcon]\" />\n </span>\n }\n\n <span class=\"fk-accordion__text\">\n @if (title()) {\n <span class=\"fk-accordion__title\">{{ title() }}</span>\n }\n\n @if (description()) {\n <span class=\"fk-accordion__description\">{{ description() }}</span>\n }\n </span>\n\n <span class=\"fk-accordion__trailing\">\n @if (leadingText()) {\n <span class=\"fk-accordion__leading-text\">{{ leadingText() }}</span>\n }\n\n @if (chevronRef()) {\n <ng-content select=\"[fkAccordionChevron]\" />\n } @else {\n <span\n class=\"fk-accordion__chevron\"\n [class.fk-accordion__chevron--open]=\"expanded()\"\n aria-hidden=\"true\"\n >\n <svg\n class=\"fk-accordion__chevron-svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 18 18\"\n >\n <path\n d=\"M4.5 6.75L9 11.25L13.5 6.75\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n fill=\"none\"\n />\n </svg>\n </span>\n }\n </span>\n</button>\n\n@if (expanded()) {\n <div\n class=\"fk-accordion__panel\"\n role=\"region\"\n [id]=\"panelId()\"\n [attr.aria-labelledby]=\"triggerId()\"\n >\n <ng-content />\n </div>\n}\n", styles: [":host{display:block;color:var(--fk-accordion-color, var(--fk-color-text, #121926));border:var(--fk-accordion-border-width, 1px) solid var(--fk-accordion-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-accordion-radius, var(--fk-radius-md, .375rem))}.fk-accordion__header{display:flex;align-items:center;width:100%;padding:var(--fk-accordion-header-padding-block, var(--fk-rhythm-3, .75rem)) var(--fk-accordion-header-padding-inline, var(--fk-rhythm-4, 1rem));background:var(--fk-accordion-header-bg, transparent);border:none;border-radius:var(--fk-accordion-radius, var(--fk-radius-md, .375rem));font-family:inherit;color:inherit;text-align:left;cursor:pointer}.fk-accordion__header:hover:not(:disabled){background:var(--fk-accordion-header-bg-hover, var(--fk-color-surface-muted, #f5f7fa))}.fk-accordion__header:focus-visible{outline:none;box-shadow:var(--fk-accordion-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-accordion__header:disabled{cursor:not-allowed;opacity:.6}.fk-accordion__leading-icon{display:inline-flex;align-items:center;flex:0 0 auto;margin-right:var(--fk-accordion-leading-icon-gap, var(--fk-rhythm-3, .75rem))}.fk-accordion__text{display:flex;flex:1 1 auto;flex-direction:column;min-width:0}.fk-accordion__title{font-size:var(--fk-accordion-title-font-size, var(--fk-typography-body-font-size, .9375rem));font-weight:var(--fk-accordion-title-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-accordion-title-color, var(--fk-color-text, #121926));line-height:1.4}.fk-accordion__description{margin-top:var(--fk-accordion-description-gap, var(--fk-rhythm-1, .25rem));font-size:var(--fk-accordion-description-font-size, var(--fk-typography-small-font-size, .8125rem));color:var(--fk-accordion-description-color, var(--fk-color-muted, #64748b));line-height:1.5}.fk-accordion__trailing{display:inline-flex;align-items:center;flex:0 0 auto;margin-left:var(--fk-accordion-trailing-gap, var(--fk-rhythm-3, .75rem))}.fk-accordion__leading-text{margin-right:var(--fk-accordion-leading-text-gap, var(--fk-rhythm-2, .5rem));font-size:var(--fk-accordion-leading-text-font-size, var(--fk-typography-small-font-size, .8125rem));font-weight:var(--fk-accordion-leading-text-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-accordion-leading-text-color, var(--fk-color-muted, #64748b));letter-spacing:.02em}.fk-accordion__chevron{display:inline-flex;align-items:center;justify-content:center;color:var(--fk-accordion-chevron-color, var(--fk-color-muted, #64748b));transition:transform .15s ease}.fk-accordion__chevron--open{transform:rotate(180deg)}.fk-accordion__chevron-svg{display:block}.fk-accordion__panel{margin-top:var(--fk-accordion-panel-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-accordion-panel-padding-block, var(--fk-rhythm-3, .75rem)) var(--fk-accordion-panel-padding-inline, var(--fk-rhythm-4, 1rem));color:var(--fk-accordion-panel-color, var(--fk-color-text, #121926))}:host.fk-accordion--expanded .fk-accordion__header{background:var(--fk-accordion-header-bg-expanded, var(--fk-accordion-header-bg-hover, var(--fk-color-surface-muted, #f5f7fa)))}:host.fk-accordion--sm .fk-accordion__header{padding:var(--fk-accordion-sm-header-padding-block, var(--fk-rhythm-2, .5rem)) var(--fk-accordion-sm-header-padding-inline, var(--fk-rhythm-3, .75rem))}:host.fk-accordion--sm .fk-accordion__title{font-size:var(--fk-accordion-sm-title-font-size, var(--fk-typography-small-font-size, .8125rem))}:host.fk-accordion--sm .fk-accordion__description{font-size:var(--fk-accordion-sm-description-font-size, .75rem)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
179
|
+
}
|
|
180
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AccordionComponent, decorators: [{
|
|
181
|
+
type: Component,
|
|
182
|
+
args: [{ selector: 'fk-accordion', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n type=\"button\"\n class=\"fk-accordion__header\"\n [id]=\"triggerId()\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"panelId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n @if (leadingIconRef()) {\n <span class=\"fk-accordion__leading-icon\">\n <ng-content select=\"[fkAccordionLeadingIcon]\" />\n </span>\n }\n\n <span class=\"fk-accordion__text\">\n @if (title()) {\n <span class=\"fk-accordion__title\">{{ title() }}</span>\n }\n\n @if (description()) {\n <span class=\"fk-accordion__description\">{{ description() }}</span>\n }\n </span>\n\n <span class=\"fk-accordion__trailing\">\n @if (leadingText()) {\n <span class=\"fk-accordion__leading-text\">{{ leadingText() }}</span>\n }\n\n @if (chevronRef()) {\n <ng-content select=\"[fkAccordionChevron]\" />\n } @else {\n <span\n class=\"fk-accordion__chevron\"\n [class.fk-accordion__chevron--open]=\"expanded()\"\n aria-hidden=\"true\"\n >\n <svg\n class=\"fk-accordion__chevron-svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 18 18\"\n >\n <path\n d=\"M4.5 6.75L9 11.25L13.5 6.75\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n fill=\"none\"\n />\n </svg>\n </span>\n }\n </span>\n</button>\n\n@if (expanded()) {\n <div\n class=\"fk-accordion__panel\"\n role=\"region\"\n [id]=\"panelId()\"\n [attr.aria-labelledby]=\"triggerId()\"\n >\n <ng-content />\n </div>\n}\n", styles: [":host{display:block;color:var(--fk-accordion-color, var(--fk-color-text, #121926));border:var(--fk-accordion-border-width, 1px) solid var(--fk-accordion-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-accordion-radius, var(--fk-radius-md, .375rem))}.fk-accordion__header{display:flex;align-items:center;width:100%;padding:var(--fk-accordion-header-padding-block, var(--fk-rhythm-3, .75rem)) var(--fk-accordion-header-padding-inline, var(--fk-rhythm-4, 1rem));background:var(--fk-accordion-header-bg, transparent);border:none;border-radius:var(--fk-accordion-radius, var(--fk-radius-md, .375rem));font-family:inherit;color:inherit;text-align:left;cursor:pointer}.fk-accordion__header:hover:not(:disabled){background:var(--fk-accordion-header-bg-hover, var(--fk-color-surface-muted, #f5f7fa))}.fk-accordion__header:focus-visible{outline:none;box-shadow:var(--fk-accordion-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-accordion__header:disabled{cursor:not-allowed;opacity:.6}.fk-accordion__leading-icon{display:inline-flex;align-items:center;flex:0 0 auto;margin-right:var(--fk-accordion-leading-icon-gap, var(--fk-rhythm-3, .75rem))}.fk-accordion__text{display:flex;flex:1 1 auto;flex-direction:column;min-width:0}.fk-accordion__title{font-size:var(--fk-accordion-title-font-size, var(--fk-typography-body-font-size, .9375rem));font-weight:var(--fk-accordion-title-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-accordion-title-color, var(--fk-color-text, #121926));line-height:1.4}.fk-accordion__description{margin-top:var(--fk-accordion-description-gap, var(--fk-rhythm-1, .25rem));font-size:var(--fk-accordion-description-font-size, var(--fk-typography-small-font-size, .8125rem));color:var(--fk-accordion-description-color, var(--fk-color-muted, #64748b));line-height:1.5}.fk-accordion__trailing{display:inline-flex;align-items:center;flex:0 0 auto;margin-left:var(--fk-accordion-trailing-gap, var(--fk-rhythm-3, .75rem))}.fk-accordion__leading-text{margin-right:var(--fk-accordion-leading-text-gap, var(--fk-rhythm-2, .5rem));font-size:var(--fk-accordion-leading-text-font-size, var(--fk-typography-small-font-size, .8125rem));font-weight:var(--fk-accordion-leading-text-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-accordion-leading-text-color, var(--fk-color-muted, #64748b));letter-spacing:.02em}.fk-accordion__chevron{display:inline-flex;align-items:center;justify-content:center;color:var(--fk-accordion-chevron-color, var(--fk-color-muted, #64748b));transition:transform .15s ease}.fk-accordion__chevron--open{transform:rotate(180deg)}.fk-accordion__chevron-svg{display:block}.fk-accordion__panel{margin-top:var(--fk-accordion-panel-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-accordion-panel-padding-block, var(--fk-rhythm-3, .75rem)) var(--fk-accordion-panel-padding-inline, var(--fk-rhythm-4, 1rem));color:var(--fk-accordion-panel-color, var(--fk-color-text, #121926))}:host.fk-accordion--expanded .fk-accordion__header{background:var(--fk-accordion-header-bg-expanded, var(--fk-accordion-header-bg-hover, var(--fk-color-surface-muted, #f5f7fa)))}:host.fk-accordion--sm .fk-accordion__header{padding:var(--fk-accordion-sm-header-padding-block, var(--fk-rhythm-2, .5rem)) var(--fk-accordion-sm-header-padding-inline, var(--fk-rhythm-3, .75rem))}:host.fk-accordion--sm .fk-accordion__title{font-size:var(--fk-accordion-sm-title-font-size, var(--fk-typography-small-font-size, .8125rem))}:host.fk-accordion--sm .fk-accordion__description{font-size:var(--fk-accordion-sm-description-font-size, .75rem)}\n"] }]
|
|
183
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], leadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingText", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], defaultExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultExpanded", required: false }] }], leadingIconRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FK_ACCORDION_LEADING_ICON), { isSignal: true }] }], chevronRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FK_ACCORDION_CHEVRON), { isSignal: true }] }], expandedChange: [{ type: i0.Output, args: ["expandedChange"] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hostClass: [{
|
|
184
|
+
type: HostBinding,
|
|
185
|
+
args: ['class']
|
|
186
|
+
}] } });
|
|
187
|
+
|
|
188
|
+
class AccordionGroupComponent {
|
|
189
|
+
// ===== BASE PROPS =====
|
|
190
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
191
|
+
// ===== COMPUTED =====
|
|
192
|
+
classes = computed(() => {
|
|
193
|
+
return ['fk-accordion-group', this.className()].filter(Boolean).join(' ');
|
|
194
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
195
|
+
get hostClass() {
|
|
196
|
+
return this.classes();
|
|
197
|
+
}
|
|
198
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AccordionGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
199
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: AccordionGroupComponent, isStandalone: true, selector: "fk-accordion-group", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass" } }, providers: [AccordionGroupCoordinator], ngImport: i0, template: "<ng-content />\n", styles: [":host{display:block}:host fk-accordion+fk-accordion{margin-top:var(--fk-accordion-group-gap, var(--fk-rhythm-3, .75rem))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
200
|
+
}
|
|
201
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AccordionGroupComponent, decorators: [{
|
|
202
|
+
type: Component,
|
|
203
|
+
args: [{ selector: 'fk-accordion-group', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, providers: [AccordionGroupCoordinator], template: "<ng-content />\n", styles: [":host{display:block}:host fk-accordion+fk-accordion{margin-top:var(--fk-accordion-group-gap, var(--fk-rhythm-3, .75rem))}\n"] }]
|
|
204
|
+
}], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], hostClass: [{
|
|
205
|
+
type: HostBinding,
|
|
206
|
+
args: ['class']
|
|
207
|
+
}] } });
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Generated bundle index. Do not edit.
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
export { AccordionComponent, AccordionGroupComponent, AccordionGroupCoordinator, FK_ACCORDION_CHEVRON, FK_ACCORDION_LEADING_ICON, FkAccordionChevronDirective, FkAccordionLeadingIconDirective };
|
|
214
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-accordion.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-accordion.mjs","sources":["../../../../packages/ui-ng/ui/accordion/accordion-chevron.directive.ts","../../../../packages/ui-ng/ui/accordion/accordion-group.service.ts","../../../../packages/ui-ng/ui/accordion/accordion-leading-icon.directive.ts","../../../../packages/ui-ng/ui/accordion/accordion.component.ts","../../../../packages/ui-ng/ui/accordion/accordion.component.html","../../../../packages/ui-ng/ui/accordion/accordion-group.component.ts","../../../../packages/ui-ng/ui/accordion/accordion-group.component.html","../../../../packages/ui-ng/ui/accordion/frame-kit-ui-ng-ui-accordion.ts"],"sourcesContent":["import { Directive, InjectionToken } from '@angular/core';\n\nexport const FK_ACCORDION_CHEVRON =\n new InjectionToken<FkAccordionChevronDirective>('FK_ACCORDION_CHEVRON');\n\n@Directive({\n selector: '[fkAccordionChevron]',\n standalone: true,\n providers: [\n { provide: FK_ACCORDION_CHEVRON, useExisting: FkAccordionChevronDirective },\n ],\n host: {\n 'aria-hidden': 'true',\n },\n})\nexport class FkAccordionChevronDirective {}\n","import { Injectable } from '@angular/core';\n\nimport type { AccordionComponent } from './accordion.component';\n\n/**\n * Coordinator scoped to a single `<fk-accordion-group>`. Any\n * `<fk-accordion>` rendered inside a group picks this up via DI and\n * reports its toggle state. The coordinator enforces single-open:\n * when a new accordion opens, the previously active one is collapsed.\n */\n@Injectable()\nexport class AccordionGroupCoordinator {\n private active: AccordionComponent | null = null;\n\n register(accordion: AccordionComponent): void {\n if (accordion.expanded()) {\n if (this.active && this.active !== accordion) {\n accordion.setExpanded(false);\n } else {\n this.active = accordion;\n }\n }\n }\n\n unregister(accordion: AccordionComponent): void {\n if (this.active === accordion) {\n this.active = null;\n }\n }\n\n notifyExpandedChange(\n accordion: AccordionComponent,\n nextExpanded: boolean,\n ): void {\n if (nextExpanded) {\n const prev = this.active;\n\n this.active = accordion;\n\n if (prev && prev !== accordion) {\n prev.setExpanded(false);\n }\n\n return;\n }\n\n if (this.active === accordion) {\n this.active = null;\n }\n }\n}\n","import { Directive, InjectionToken } from '@angular/core';\n\nexport const FK_ACCORDION_LEADING_ICON =\n new InjectionToken<FkAccordionLeadingIconDirective>(\n 'FK_ACCORDION_LEADING_ICON',\n );\n\n@Directive({\n selector: '[fkAccordionLeadingIcon]',\n standalone: true,\n providers: [\n {\n provide: FK_ACCORDION_LEADING_ICON,\n useExisting: FkAccordionLeadingIconDirective,\n },\n ],\n host: {\n 'aria-hidden': 'true',\n },\n})\nexport class FkAccordionLeadingIconDirective {}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n DestroyRef,\n HostBinding,\n inject,\n input,\n linkedSignal,\n OnInit,\n output,\n} from '@angular/core';\n\nimport type { AccordionSize } from './accordion.types';\nimport { FK_ACCORDION_CHEVRON } from './accordion-chevron.directive';\nimport { AccordionGroupCoordinator } from './accordion-group.service';\nimport { FK_ACCORDION_LEADING_ICON } from './accordion-leading-icon.directive';\n\nlet uid = 0;\n\n@Component({\n selector: 'fk-accordion',\n standalone: true,\n imports: [],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './accordion.component.html',\n styleUrl: './accordion.component.scss',\n})\nexport class AccordionComponent implements OnInit {\n private readonly group = inject(AccordionGroupCoordinator, {\n optional: true,\n });\n\n private readonly destroyRef = inject(DestroyRef);\n\n // ===== INPUTS =====\n /** Heading text shown in the trigger row. */\n readonly title = input<string>('');\n /** Optional supporting text rendered beneath the title. */\n readonly description = input<string | null>(null);\n /** Short label rendered to the leading side of the trigger row. */\n readonly leadingText = input<string | null>(null);\n /** Controls the size variant of the accordion trigger and content. */\n readonly size = input<AccordionSize>('md');\n /** When true the accordion cannot be opened or closed by the user. */\n readonly disabled = input<boolean>(false);\n /** Whether the panel starts in the expanded state on first render. */\n readonly defaultExpanded = input<boolean>(false);\n\n // ===== CONTENT CHILDREN =====\n readonly leadingIconRef = contentChild(FK_ACCORDION_LEADING_ICON);\n readonly chevronRef = contentChild(FK_ACCORDION_CHEVRON);\n\n // ===== OUTPUTS =====\n /** Fires whenever the panel opens or closes, emitting the new expanded state. */\n readonly expandedChange = output<boolean>();\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n\n // ===== INTERNAL STATE =====\n private readonly _expanded = linkedSignal<boolean>(() =>\n this.defaultExpanded(),\n );\n\n private readonly uid = ++uid;\n\n readonly expanded = computed(() => this._expanded());\n\n protected readonly triggerId = computed(\n () => `fk-accordion-${this.uid}-trigger`,\n );\n\n protected readonly panelId = computed(() => `fk-accordion-${this.uid}-panel`);\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n return [\n 'fk-accordion',\n `fk-accordion--${this.size()}`,\n this._expanded() ? 'fk-accordion--expanded' : '',\n this.disabled() ? 'fk-accordion--disabled' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n @HostBinding('class')\n get hostClass(): string {\n return this.classes();\n }\n\n // ===== LIFECYCLE =====\n ngOnInit(): void {\n if (!this.group) {\n return;\n }\n\n this.group.register(this);\n this.destroyRef.onDestroy(() => this.group?.unregister(this));\n }\n\n // ===== ACTIONS =====\n /** Toggles the expanded state if the accordion is not disabled. */\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n\n const next = !this._expanded();\n\n this._expanded.set(next);\n this.expandedChange.emit(next);\n this.group?.notifyExpandedChange(this, next);\n }\n\n /**\n * Set the expanded state imperatively. Reserved for\n * `AccordionGroupCoordinator` to force-collapse siblings when a new\n * accordion opens within the same group. Does not notify the\n * coordinator (to avoid re-entrance loops).\n */\n setExpanded(expanded: boolean): void {\n if (this._expanded() === expanded) {\n return;\n }\n\n this._expanded.set(expanded);\n this.expandedChange.emit(expanded);\n }\n}\n","<button\n type=\"button\"\n class=\"fk-accordion__header\"\n [id]=\"triggerId()\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"panelId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n @if (leadingIconRef()) {\n <span class=\"fk-accordion__leading-icon\">\n <ng-content select=\"[fkAccordionLeadingIcon]\" />\n </span>\n }\n\n <span class=\"fk-accordion__text\">\n @if (title()) {\n <span class=\"fk-accordion__title\">{{ title() }}</span>\n }\n\n @if (description()) {\n <span class=\"fk-accordion__description\">{{ description() }}</span>\n }\n </span>\n\n <span class=\"fk-accordion__trailing\">\n @if (leadingText()) {\n <span class=\"fk-accordion__leading-text\">{{ leadingText() }}</span>\n }\n\n @if (chevronRef()) {\n <ng-content select=\"[fkAccordionChevron]\" />\n } @else {\n <span\n class=\"fk-accordion__chevron\"\n [class.fk-accordion__chevron--open]=\"expanded()\"\n aria-hidden=\"true\"\n >\n <svg\n class=\"fk-accordion__chevron-svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 18 18\"\n >\n <path\n d=\"M4.5 6.75L9 11.25L13.5 6.75\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n fill=\"none\"\n />\n </svg>\n </span>\n }\n </span>\n</button>\n\n@if (expanded()) {\n <div\n class=\"fk-accordion__panel\"\n role=\"region\"\n [id]=\"panelId()\"\n [attr.aria-labelledby]=\"triggerId()\"\n >\n <ng-content />\n </div>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n input,\n} from '@angular/core';\n\nimport { AccordionGroupCoordinator } from './accordion-group.service';\n\n@Component({\n selector: 'fk-accordion-group',\n standalone: true,\n imports: [],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [AccordionGroupCoordinator],\n templateUrl: './accordion-group.component.html',\n styleUrl: './accordion-group.component.scss',\n})\nexport class AccordionGroupComponent {\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n return ['fk-accordion-group', this.className()].filter(Boolean).join(' ');\n });\n\n @HostBinding('class')\n get hostClass(): string {\n return this.classes();\n }\n}\n","<ng-content />\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;MAEa,oBAAoB,GAC/B,IAAI,cAAc,CAA8B,sBAAsB;MAY3D,2BAA2B,CAAA;uGAA3B,2BAA2B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAA3B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,2BAA2B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,EAAA,SAAA,EAP3B;AACT,YAAA,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,2BAA2B,EAAE;AAC5E,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAKU,2BAA2B,EAAA,UAAA,EAAA,CAAA;kBAVvC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,sBAAsB;AAChC,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,SAAS,EAAE;AACT,wBAAA,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,6BAA6B,EAAE;AAC5E,qBAAA;AACD,oBAAA,IAAI,EAAE;AACJ,wBAAA,aAAa,EAAE,MAAM;AACtB,qBAAA;AACF,iBAAA;;;ACVD;;;;;AAKG;MAEU,yBAAyB,CAAA;IAC5B,MAAM,GAA8B,IAAI;AAEhD,IAAA,QAAQ,CAAC,SAA6B,EAAA;AACpC,QAAA,IAAI,SAAS,CAAC,QAAQ,EAAE,EAAE;YACxB,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;AAC5C,gBAAA,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC;YAC9B;iBAAO;AACL,gBAAA,IAAI,CAAC,MAAM,GAAG,SAAS;YACzB;QACF;IACF;AAEA,IAAA,UAAU,CAAC,SAA6B,EAAA;AACtC,QAAA,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;AAC7B,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;QACpB;IACF;IAEA,oBAAoB,CAClB,SAA6B,EAC7B,YAAqB,EAAA;QAErB,IAAI,YAAY,EAAE;AAChB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM;AAExB,YAAA,IAAI,CAAC,MAAM,GAAG,SAAS;AAEvB,YAAA,IAAI,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE;AAC9B,gBAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;YACzB;YAEA;QACF;AAEA,QAAA,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;AAC7B,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;QACpB;IACF;uGAtCW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;2GAAzB,yBAAyB,EAAA,CAAA;;2FAAzB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBADrC;;;MCRY,yBAAyB,GACpC,IAAI,cAAc,CAChB,2BAA2B;MAgBlB,+BAA+B,CAAA;uGAA/B,+BAA+B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAA/B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,+BAA+B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,0BAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,EAAA,SAAA,EAV/B;AACT,YAAA;AACE,gBAAA,OAAO,EAAE,yBAAyB;AAClC,gBAAA,WAAW,EAAE,+BAA+B;AAC7C,aAAA;AACF,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAKU,+BAA+B,EAAA,UAAA,EAAA,CAAA;kBAb3C,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,0BAA0B;AACpC,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,SAAS,EAAE;AACT,wBAAA;AACE,4BAAA,OAAO,EAAE,yBAAyB;AAClC,4BAAA,WAAW,EAAA,+BAAiC;AAC7C,yBAAA;AACF,qBAAA;AACD,oBAAA,IAAI,EAAE;AACJ,wBAAA,aAAa,EAAE,MAAM;AACtB,qBAAA;AACF,iBAAA;;;ACAD,IAAI,GAAG,GAAG,CAAC;MAUE,kBAAkB,CAAA;AACZ,IAAA,KAAK,GAAG,MAAM,CAAC,yBAAyB,EAAE;AACzD,QAAA,QAAQ,EAAE,IAAI;AACf,KAAA,CAAC;AAEe,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;;;AAIvC,IAAA,KAAK,GAAG,KAAK,CAAS,EAAE,4EAAC;;AAEzB,IAAA,WAAW,GAAG,KAAK,CAAgB,IAAI,kFAAC;;AAExC,IAAA,WAAW,GAAG,KAAK,CAAgB,IAAI,kFAAC;;AAExC,IAAA,IAAI,GAAG,KAAK,CAAgB,IAAI,2EAAC;;AAEjC,IAAA,QAAQ,GAAG,KAAK,CAAU,KAAK,+EAAC;;AAEhC,IAAA,eAAe,GAAG,KAAK,CAAU,KAAK,sFAAC;;AAGvC,IAAA,cAAc,GAAG,YAAY,CAAC,yBAAyB,qFAAC;AACxD,IAAA,UAAU,GAAG,YAAY,CAAC,oBAAoB,iFAAC;;;IAI/C,cAAc,GAAG,MAAM,EAAW;;AAGlC,IAAA,SAAS,GAAG,KAAK,CAAS,EAAE,gFAAC;AAC7B,IAAA,EAAE,GAAG,KAAK,CAAgB,IAAI,yEAAC;AAC/B,IAAA,SAAS,GAAG,KAAK,CAAgB,IAAI,gFAAC;;IAG9B,SAAS,GAAG,YAAY,CAAU,MACjD,IAAI,CAAC,eAAe,EAAE,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,WAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CACvB;IAEgB,GAAG,GAAG,EAAE,GAAG;IAEnB,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,UAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;AAEjC,IAAA,SAAS,GAAG,QAAQ,CACrC,MAAM,CAAA,aAAA,EAAgB,IAAI,CAAC,GAAG,CAAA,QAAA,CAAU,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,WAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CACzC;AAEkB,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAA,aAAA,EAAgB,IAAI,CAAC,GAAG,CAAA,MAAA,CAAQ,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;;AAGpE,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;QAC/B,OAAO;YACL,cAAc;AACd,YAAA,CAAA,cAAA,EAAiB,IAAI,CAAC,IAAI,EAAE,CAAA,CAAE;YAC9B,IAAI,CAAC,SAAS,EAAE,GAAG,wBAAwB,GAAG,EAAE;YAChD,IAAI,CAAC,QAAQ,EAAE,GAAG,wBAAwB,GAAG,EAAE;YAC/C,IAAI,CAAC,SAAS,EAAE;AACjB;aACE,MAAM,CAAC,OAAO;aACd,IAAI,CAAC,GAAG,CAAC;AACd,IAAA,CAAC,8EAAC;AAEF,IAAA,IACI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE;IACvB;;IAGA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;YACf;QACF;AAEA,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;AACzB,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/D;;;IAIA,MAAM,GAAA;AACJ,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;YACnB;QACF;AAEA,QAAA,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE;AAE9B,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACxB,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC;IAC9C;AAEA;;;;;AAKG;AACH,IAAA,WAAW,CAAC,QAAiB,EAAA;AAC3B,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE,KAAK,QAAQ,EAAE;YACjC;QACF;AAEA,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC5B,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC;IACpC;uGAxGW,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,cAAA,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,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,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,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,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,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,EAAA,EAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,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,EAAA,OAAA,EAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAsBU,yBAAyB,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,YAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAC7B,oBAAoB,gECpDzD,ovDAsEA,EAAA,MAAA,EAAA,CAAA,uhHAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FDzCa,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAR9B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,cACZ,IAAI,EAAA,OAAA,EACP,EAAE,EAAA,eAAA,EACM,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,ovDAAA,EAAA,MAAA,EAAA,CAAA,uhHAAA,CAAA,EAAA;AA0BR,SAAA,CAAA,EAAA,cAAA,EAAA,EAAA,KAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,IAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,cAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,UAAA,CAAA,MAAA,yBAAyB,4FAC7B,oBAAoB,CAAA,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,cAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,CAAA,EAAA,SAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,WAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,IAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,SAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,WAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,SAAA,EAAA,CAAA;sBAuCtD,WAAW;uBAAC,OAAO;;;MExET,uBAAuB,CAAA;;AAEzB,IAAA,SAAS,GAAG,KAAK,CAAS,EAAE,gFAAC;;AAG7B,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AAC/B,QAAA,OAAO,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3E,IAAA,CAAC,8EAAC;AAEF,IAAA,IACI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE;IACvB;uGAZW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAvB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,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,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,SAAA,EAJvB,CAAC,yBAAyB,CAAC,0BCfxC,kBACA,EAAA,MAAA,EAAA,CAAA,6HAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FDkBa,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBATnC,SAAS;+BACE,oBAAoB,EAAA,UAAA,EAClB,IAAI,EAAA,OAAA,EACP,EAAE,EAAA,eAAA,EACM,uBAAuB,CAAC,MAAM,EAAA,SAAA,EACpC,CAAC,yBAAyB,CAAC,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,6HAAA,CAAA,EAAA;;sBAarC,WAAW;uBAAC,OAAO;;;AE5BtB;;AAEG;;;;"}
|