@bitforgehq/ui 0.4.0 → 0.5.0-next.3

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +303 -0
  2. package/README.md +12 -12
  3. package/ai/MANIFEST.index.json +65 -2
  4. package/ai/MANIFEST.json +2221 -737
  5. package/ai/REFERENCE.index.json +161 -0
  6. package/ai/REFERENCE.json +1336 -27
  7. package/ai/UI_GUIDE.md +61 -20
  8. package/ai/components/app-frame.md +1 -1
  9. package/ai/components/chat-composer.md +357 -0
  10. package/ai/components/chat-message.md +251 -0
  11. package/ai/components/chat-thread.md +521 -0
  12. package/ai/components/checkbox.md +7 -0
  13. package/ai/components/combobox.md +12 -0
  14. package/ai/components/date-input.md +9 -0
  15. package/ai/components/datetime-input.md +2 -0
  16. package/ai/components/field.md +10 -0
  17. package/ai/components/file-input.md +498 -0
  18. package/ai/components/header.md +1 -1
  19. package/ai/components/image-input.md +368 -0
  20. package/ai/components/image-viewer.md +309 -0
  21. package/ai/components/media-card.md +478 -0
  22. package/ai/components/menu-button.md +2 -0
  23. package/ai/components/menu.md +10 -0
  24. package/ai/components/multi-combobox.md +7 -0
  25. package/ai/components/nav-group.md +10 -3
  26. package/ai/components/nav-item.md +11 -2
  27. package/ai/components/number-input.md +2 -7
  28. package/ai/components/popover.md +13 -0
  29. package/ai/components/radio-group.md +6 -0
  30. package/ai/components/segmented.md +14 -2
  31. package/ai/components/select.md +100 -42
  32. package/ai/components/sidebar-toggle.md +16 -9
  33. package/ai/components/sidebar.md +41 -13
  34. package/ai/components/tab-group.md +18 -2
  35. package/ai/components/table.md +17 -2
  36. package/ai/components/theme-menu-button.md +1 -0
  37. package/ai/components/time-input.md +2 -0
  38. package/ai/components/toolbar.md +7 -18
  39. package/ai/reference/bf-chat-composer-harness.md +64 -0
  40. package/ai/reference/bf-chat-message-role.md +27 -0
  41. package/ai/reference/bf-chat-message-status.md +28 -0
  42. package/ai/reference/bf-fade-in-directive.md +18 -0
  43. package/ai/reference/bf-file-input-harness.md +67 -0
  44. package/ai/reference/bf-file-input-variant.md +27 -0
  45. package/ai/reference/bf-image-input-harness.md +67 -0
  46. package/ai/reference/bf-image-input-shape.md +27 -0
  47. package/ai/reference/bf-image-viewer-actions-context.md +29 -0
  48. package/ai/reference/bf-image-viewer-harness.md +87 -0
  49. package/ai/reference/bf-image-viewer-image.md +25 -0
  50. package/ai/reference/bf-image-viewer-options.md +33 -0
  51. package/ai/reference/bf-image-viewer-origin.md +23 -0
  52. package/ai/reference/bf-image-viewer-ref.md +55 -0
  53. package/ai/reference/bf-image-viewer-service.md +32 -0
  54. package/ai/reference/bf-labels.md +105 -75
  55. package/ai/reference/bf-media-card-aspect.md +28 -0
  56. package/ai/reference/bf-media-card-harness.md +66 -0
  57. package/ai/reference/bf-motion-list-directive.md +22 -0
  58. package/ai/reference/bf-prose-directive.md +16 -0
  59. package/ai/reference/bf-rejected-file-reason.md +28 -0
  60. package/ai/reference/bf-rejected-file.md +28 -0
  61. package/ai/reference/bf-select-harness.md +14 -5
  62. package/ai/reference/bf-select-option.md +2 -0
  63. package/ai/reference/bf-size.md +3 -0
  64. package/ai/reference/bf_table_sort_select.md +23 -0
  65. package/ai/reference/provide-bf-labels.md +10 -3
  66. package/ai/reference/provide-bf-select.md +20 -0
  67. package/bin/bf-ui.js +1 -0
  68. package/fesm2022/bitforgehq-ui-overlay.mjs +2649 -606
  69. package/fesm2022/bitforgehq-ui-overlay.mjs.map +1 -1
  70. package/fesm2022/bitforgehq-ui-testing.mjs +356 -10
  71. package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -1
  72. package/fesm2022/bitforgehq-ui.mjs +7531 -3989
  73. package/fesm2022/bitforgehq-ui.mjs.map +1 -1
  74. package/llms-full.txt +4151 -130
  75. package/llms.txt +31 -1
  76. package/package.json +1 -1
  77. package/theme.css +60 -0
  78. package/types/bitforgehq-ui-overlay.d.ts +684 -7
  79. package/types/bitforgehq-ui-testing.d.ts +434 -6
  80. package/types/bitforgehq-ui.d.ts +1473 -182
@@ -1 +1 @@
1
- {"version":3,"file":"bitforgehq-ui-overlay.mjs","names":[],"sources":["../../../projects/ui/overlay/core/overlay-ref.ts","../../../projects/ui/overlay/core/overlay-host.ts","../../../projects/ui/overlay/core/overlay-stack.service.ts","../../../projects/ui/overlay/core/motion.ts","../../../projects/ui/overlay/core/navigation.ts","../../../projects/ui/overlay/core/overlay-animations.ts","../../../projects/ui/overlay/core/overlay.service.ts","../../../projects/ui/overlay/core/overlay-heading.ts","../../../projects/ui/overlay/toast-core/toast-ref.ts","../../../projects/ui/overlay/toast-core/toast-queue.ts","../../../projects/ui/overlay/dialog/dialog-ref.ts","../../../projects/ui/overlay/dialog/dialog.component.ts","../../../projects/ui/overlay/dialog/dialog.service.ts","../../../projects/ui/overlay/desktop-toast/desktop-toast.component.ts","../../../projects/ui/overlay/desktop-toast/desktop-toast.service.ts","../../../projects/ui/overlay/core/anchored-overlay.ts","../../../projects/ui/overlay/menu/menu-trigger.directive.ts","../../../projects/ui/overlay/menu/menu.component.ts","../../../projects/ui/overlay/menu/menu-item.directive.ts","../../../projects/ui/overlay/menu-button/menu-button.component.ts","../../../projects/ui/overlay/theme-menu-button/theme-menu-button.component.ts","../../../projects/ui/overlay/tooltip/tooltip.component.ts","../../../projects/ui/overlay/tooltip/tooltip.directive.ts","../../../projects/ui/overlay/sidebar-toggle/sidebar-toggle.component.ts","../../../projects/ui/overlay/side-panel/side-panel-ref.ts","../../../projects/ui/overlay/side-panel/side-panel.component.ts","../../../projects/ui/overlay/side-panel/side-panel.service.ts","../../../projects/ui/overlay/popover/popover-trigger.directive.ts","../../../projects/ui/overlay/popover/popover.component.ts","../../../projects/ui/overlay/combobox/combobox-core.ts","../../../projects/ui/overlay/combobox/combobox-classes.ts","../../../projects/ui/overlay/combobox/combobox-listbox.component.ts","../../../projects/ui/overlay/combobox/combobox.component.ts","../../../projects/ui/overlay/combobox/multi-combobox.component.ts","../../../projects/ui/overlay/date-time-core/date-time-segments.ts","../../../projects/ui/overlay/date-time-core/date-time-field.component.ts","../../../projects/ui/overlay/date-input/date-input.component.ts","../../../projects/ui/overlay/time-input/time-input.component.ts","../../../projects/ui/overlay/datetime-input/datetime-input.component.ts"],"sourcesContent":["import { type ComponentRef, InjectionToken, type Signal, signal } from '@angular/core';\n\n/**\n * The `data` passed to `BfOverlayService.open()`, injectable in the overlay's content.\n *\n * @summary Injection token carrying the data an overlay was opened with, for its content\n * @since 0.2.0\n */\nexport const BF_OVERLAY_DATA = new InjectionToken<unknown>('BF_OVERLAY_DATA');\n\n/**\n * What the overlay service does for a ref. Exported for entries that extend `BfOverlayRef` with\n * their own controller (the `/mobile` `BfSheetRef`); apps never implement it.\n *\n * @summary What the overlay service does for a ref: close it and re-apply its position\n * @since 0.2.0\n */\nexport interface BfOverlayController {\n /** Plays the exit animation, detaches the overlay and cleans up. Never rejects. */\n close(): Promise<void>;\n /** Re-applies the overlay's position (after its size changed). */\n updatePosition(): void;\n}\n\nlet nextId = 0;\n\n/**\n * Handle to an open overlay, returned by `BfOverlayService.open()` and injectable in the\n * overlay's content. `close(result)` plays the exit animation, detaches the overlay and resolves\n * `afterClosed` with `result`; later calls are ignored.\n *\n * @example\n * const ref = overlays.open(PickerComponent, { data: { value } });\n * const picked = await ref.afterClosed;\n *\n * @summary Handle on an open overlay that closes it and resolves with its result\n * @since 0.2.0\n */\nexport class BfOverlayRef<T = unknown> {\n /** Unique id of the overlay (`bf-overlay-N`). */\n readonly id = `bf-overlay-${nextId++}`;\n /** Resolves with the result given to `close()` once the overlay is detached. */\n readonly afterClosed: Promise<T | undefined>;\n private readonly closedState = signal(false);\n /** True once the overlay has been detached. */\n readonly closed: Signal<boolean> = this.closedState.asReadonly();\n private closing = false;\n private resolveClosed: (result: T | undefined) => void = () => undefined;\n\n constructor(private readonly controller: BfOverlayController) {\n this.afterClosed = new Promise<T | undefined>((resolve) => {\n this.resolveClosed = resolve;\n });\n }\n\n /** True from the first `close()` call on (the exit animation may still be running). */\n get isClosing(): boolean {\n return this.closing;\n }\n\n /**\n * Closes the overlay with an optional result; ignored once closing.\n * @param result The value `afterClosed` resolves with.\n */\n close(result?: T): void {\n if (this.closing) {\n return;\n }\n this.closing = true;\n void this.controller.close().then(() => {\n this.closedState.set(true);\n this.resolveClosed(result);\n });\n }\n\n /** Re-applies the overlay's position (after its size changed). */\n updatePosition(): void {\n this.controller.updatePosition();\n }\n}\n\n/**\n * An overlay ref whose content is a component, exposing its `ComponentRef`.\n *\n * @summary Overlay handle whose content is a component, with access to its ComponentRef\n * @since 0.2.0\n */\nexport class BfComponentOverlayRef<C, T = unknown> extends BfOverlayRef<T> {\n private ref: ComponentRef<C> | null = null;\n\n /** The content component; available as soon as `open()` returns. */\n get componentRef(): ComponentRef<C> {\n if (!this.ref) {\n throw new Error('BfComponentOverlayRef: the content component is not attached yet');\n }\n return this.ref;\n }\n\n /** @internal Set by `BfOverlayService` once the component is attached. */\n setComponentRef(ref: ComponentRef<C>): void {\n this.ref = ref;\n }\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * What a host shell (the `/mobile` `provideBfShell()`) tells the overlay core. The core itself\n * depends on no platform code: without a host, overlays register no hardware back handler and\n * lock document scroll behind a modal overlay, and where the browser has `CloseWatcher`, its close\n * requests (Android back in Chrome) close the top overlay.\n *\n * @summary What a host shell tells the overlay core: back handling and document scroll\n * @since 0.3.0\n */\nexport interface BfOverlayHost {\n /**\n * Registers a hardware back handler at `priority`; returns its unregister function.\n * @param priority Higher runs first; the overlay core uses 100.\n * @param handler Returns (or resolves) true when it handled the back press.\n */\n registerBack(priority: number, handler: () => boolean | Promise<boolean>): () => void;\n /** False when the document never scrolls (the mobile shell): overlays skip the scroll lock. */\n readonly documentScrolls: boolean;\n /**\n * True when the host already delivers the system back action to `registerBack` (the mobile\n * shell on native Android, through Capacitor's `backButton` event): overlays then create no\n * `CloseWatcher` of their own, so one back press never closes two things.\n */\n readonly handlesSystemBack?: boolean;\n}\n\n/**\n * Optional; without it overlays register no back handler and lock document scroll.\n *\n * @summary Optional injection token through which a host shell plugs into the overlay core\n * @since 0.3.0\n */\nexport const BF_OVERLAY_HOST = new InjectionToken<BfOverlayHost>('BF_OVERLAY_HOST');\n","import { DOCUMENT, DestroyRef, Injectable, computed, inject, signal } from '@angular/core';\nimport { BF_OVERLAY_HOST } from './overlay-host';\n\n/**\n * What the stack needs of an overlay: a way to close it (a `BfOverlayRef` of any result type).\n *\n * @summary What the overlay stack needs of an overlay: a way to close it\n * @since 0.2.0\n */\nexport interface BfStackedOverlay {\n /** Closes the overlay (the stack calls it for the hardware back button). */\n close(): void;\n}\n\n/**\n * How an overlay takes part in the stack.\n *\n * @summary How an overlay takes part in the stack: its back priority and modal depth\n * @since 0.2.0\n */\nexport interface BfOverlayStackOptions {\n /**\n * Priority of its hardware back handler (default 100).\n * @default 100\n */\n backPriority?: number;\n /**\n * Counts towards `depth()` and `--bf-modal-depth` (page-sheet modals).\n * @default false\n */\n countsAsModal?: boolean;\n}\n\ninterface StackEntry {\n ref: BfStackedOverlay;\n countsAsModal: boolean;\n unregisterBack: () => void;\n}\n\n/**\n * The CDK overlay container's class (the CDK's DOM contract, like the announcer classes below).\n * The stack finds every container by it instead of injecting the CDK `OverlayContainer`, so a\n * shell app that only registers page roots (`bf-stack-outlet`, `bf-tabs`) bundles no CDK overlay\n * code. A custom container (`FullscreenOverlayContainer`) carries the same class.\n */\nconst OVERLAY_CONTAINER = '.cdk-overlay-container';\n\n/** Body children that never become `inert` behind an overlay (besides the overlay container). */\nconst KEEP_ACTIVE = [\n 'script',\n 'style',\n 'template',\n 'link',\n '.cdk-live-announcer-element',\n '.cdk-describedby-message-container',\n '[data-bf-overlay-keep]',\n].join(', ');\n\n/**\n * The open modal-like overlays, in order. While any is open, every registered page root (the\n * `/mobile` `bf-stack-outlet` hosts register themselves) is `inert`, and `--bf-modal-depth` on the\n * roots carries the number of open modals. With no registered root (a desktop page), every direct\n * child of `document.body` becomes `inert` instead, except those holding a CDK overlay container\n * (`.cdk-overlay-container`, found without importing the CDK), the CDK live\n * announcer and `AriaDescriber` containers, `script`/`style`/`template`/`link` and body children\n * carrying `data-bf-overlay-keep`; an element that was already `inert` keeps it on close. When\n * the stack's injector is destroyed (the app torn down with an overlay open), it removes every\n * `inert` and `--bf-modal-depth` it set. Under a `BF_OVERLAY_HOST`\n * (`provideBfShell()`) each pushed overlay registers a hardware back handler that closes it; on\n * equal priority the newest overlay closes first. Passive overlays (toasts) are never pushed.\n *\n * @summary Keeps the open overlays in order and makes the page behind them inert\n * @since 0.2.0\n */\n@Injectable({ providedIn: 'root' })\nexport class BfOverlayStack {\n private readonly host = inject(BF_OVERLAY_HOST, { optional: true });\n private readonly document = inject(DOCUMENT);\n private readonly roots = new Set<HTMLElement>();\n /** Body children the stack made `inert` (outside a shell), and only those. */\n private readonly inertBodyChildren = new Set<Element>();\n private readonly entries = signal<readonly StackEntry[]>([]);\n\n constructor() {\n // The page around the app (other apps, a host page) must never stay inert after teardown.\n inject(DestroyRef).onDestroy(() => {\n for (const el of this.inertBodyChildren) {\n el.removeAttribute('inert');\n }\n this.inertBodyChildren.clear();\n for (const root of this.roots) {\n root.removeAttribute('inert');\n root.style.removeProperty('--bf-modal-depth');\n }\n this.roots.clear();\n });\n }\n\n /** Number of open modal-like overlays. */\n readonly count = computed(() => this.entries().length);\n /** Number of open overlays that count as modals (drives `--bf-modal-depth`). */\n readonly depth = computed(() => this.entries().filter((e) => e.countsAsModal).length);\n\n /**\n * Registers a page root that becomes `inert` while an overlay is open. Returns a function that\n * unregisters it (and clears what the stack set on it).\n * @param el The page root, such as a `bf-stack-outlet` host.\n */\n registerRoot(el: HTMLElement): () => void {\n this.roots.add(el);\n this.applyTo(el);\n this.applyToBody();\n return () => {\n if (this.roots.delete(el)) {\n el.removeAttribute('inert');\n el.style.removeProperty('--bf-modal-depth');\n this.applyToBody();\n }\n };\n }\n\n /**\n * Adds an overlay on top of the stack. Outside a shell, every body child that holds a CDK\n * overlay container (`.cdk-overlay-container`) stays active, so an overlay created on the CDK\n * directly, not through `BfOverlayService`, can be pushed as well.\n * @param ref The overlay's ref.\n * @param options Its back priority and whether it counts as a modal.\n */\n push(ref: BfStackedOverlay, options: BfOverlayStackOptions = {}): void {\n if (this.entries().some((e) => e.ref === ref)) {\n return;\n }\n const unregisterBack =\n this.host?.registerBack(options.backPriority ?? 100, () => {\n ref.close();\n return true;\n }) ?? ((): void => undefined);\n this.entries.update((list) => [\n ...list,\n { ref, countsAsModal: options.countsAsModal ?? false, unregisterBack },\n ]);\n this.apply();\n }\n\n /**\n * Removes an overlay from the stack.\n * @param ref The overlay's ref.\n */\n pop(ref: BfStackedOverlay): void {\n const entry = this.entries().find((e) => e.ref === ref);\n if (!entry) {\n return;\n }\n entry.unregisterBack();\n this.entries.update((list) => list.filter((e) => e !== entry));\n this.apply();\n }\n\n /**\n * True when `ref` is the newest overlay in the stack (the one that answers `Escape`).\n * @param ref The overlay's ref.\n */\n isTop(ref: BfStackedOverlay): boolean {\n const list = this.entries();\n return list.length > 0 && list[list.length - 1].ref === ref;\n }\n\n /**\n * Stops the back handler of an overlay that is closing, while it stays in the stack.\n * @param ref The overlay's ref.\n */\n releaseBack(ref: BfStackedOverlay): void {\n this.entries()\n .find((e) => e.ref === ref)\n ?.unregisterBack();\n }\n\n /**\n * Written synchronously on every change rather than in an effect: an overlay restores focus\n * into a root right after popping, which fails while the root is still `inert`.\n */\n private apply(): void {\n for (const root of this.roots) {\n this.applyTo(root);\n }\n this.applyToBody();\n }\n\n /** Outside a shell (no registered root), isolates the page: body children become `inert`. */\n private applyToBody(): void {\n if (this.count() === 0 || this.roots.size > 0) {\n for (const el of this.inertBodyChildren) {\n el.removeAttribute('inert');\n }\n this.inertBodyChildren.clear();\n return;\n }\n const containers = Array.from(this.document.querySelectorAll(OVERLAY_CONTAINER));\n for (const child of Array.from(this.document.body.children)) {\n if (\n child.hasAttribute('inert') ||\n containers.some((container) => child.contains(container)) ||\n child.matches(KEEP_ACTIVE)\n ) {\n continue;\n }\n child.setAttribute('inert', '');\n this.inertBodyChildren.add(child);\n }\n }\n\n private applyTo(root: HTMLElement): void {\n if (this.count() > 0) {\n root.setAttribute('inert', '');\n } else {\n root.removeAttribute('inert');\n }\n const depth = this.depth();\n if (depth > 0) {\n root.style.setProperty('--bf-modal-depth', String(depth));\n } else {\n root.style.removeProperty('--bf-modal-depth');\n }\n }\n}\n","/**\n * Motion constants of the overlay core. `@bitforgehq/ui/mobile` reuses them for its own motion\n * (`DURATION_OVERLAY`, `DURATION_FAST`, `IOS_EASING`).\n */\n\n/**\n * Overlay enter and exit (ms).\n *\n * @summary The duration of every overlay enter and exit animation, in milliseconds\n * @since 0.2.0\n */\nexport const OVERLAY_DURATION = 260;\n/**\n * The overlays' curve: UIKit's navigation and sheet curve.\n *\n * @summary The easing curve of the overlay animations, the UIKit sheet curve\n * @since 0.2.0\n */\nexport const OVERLAY_EASING = 'cubic-bezier(0.32, 0.72, 0, 1)';\n/**\n * The opacity fade that replaces every overlay animation under reduced motion (ms).\n *\n * @summary The duration of the fade that replaces overlay motion under reduced motion\n * @since 0.3.0\n */\nexport const OVERLAY_REDUCED_DURATION = 150;\n\n/**\n * True when the user asked the system to minimise motion.\n *\n * @param view The window to ask, usually `document.defaultView`; none reads as false.\n * @summary Tells whether the user asked the system to minimise motion\n * @since 0.2.0\n */\nexport function prefersReducedMotion(view: Window | null | undefined): boolean {\n if (!view || typeof view.matchMedia !== 'function') {\n return false;\n }\n return view.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n","import { type Location } from '@angular/common';\n\n/** The URL path without its query and fragment. */\nexport function urlPath(url: string): string {\n const end = url.search(/[?#]/);\n return end === -1 ? url : url.slice(0, end);\n}\n\n/**\n * Calls `onChange` each time the URL path moves away from the one seen last — a router\n * navigation (`Location.go`/`replaceState`), a link, the browser's back and forward buttons —\n * never for a query- or fragment-only change. Built on `Location.onUrlChange()`, so no router is\n * needed. Returns the unregister function, which removes the listener after the current\n * notification: `Location` walks its listener array while a listener may be unregistering, and a\n * removal mid-walk would skip the next listener. Calling it again does nothing.\n */\nexport function watchPathChange(location: Location, onChange: () => void): () => void {\n let last = urlPath(location.path());\n const stop = location.onUrlChange(() => {\n const path = urlPath(location.path());\n if (path === last) {\n return;\n }\n last = path;\n onChange();\n });\n let stopped = false;\n return () => {\n // Location's remover splices by index: a second call would remove someone else's listener.\n if (stopped) {\n return;\n }\n stopped = true;\n queueMicrotask(stop);\n };\n}\n","/**\n * Enter and exit animations of the overlays, built from the Web Animations API. Every helper\n * runs 260 ms on the iOS sheet curve and falls back to a 150 ms opacity fade under\n * `prefers-reduced-motion`. Pass them as `enter`/`exit` to `BfOverlayService.open()`. Where the\n * Web Animations API is missing (jsdom in a consumer's unit tests), each applies its end state and\n * returns an already finished `Animation`, so overlays open and close without a polyfill.\n */\nimport {\n OVERLAY_DURATION,\n OVERLAY_EASING,\n OVERLAY_REDUCED_DURATION,\n prefersReducedMotion,\n} from './motion';\n\ntype Frame = Keyframe;\n\n/** Keyframe keys that are timing, not CSS properties. */\nconst TIMING_KEYS = new Set(['offset', 'easing', 'composite']);\n\n/**\n * The `Animation` handed back where the Web Animations API is missing (jsdom in a consumer's\n * Vitest or Jest run, a server render): already finished, every call a no-op.\n */\nclass BfFinishedAnimation extends EventTarget implements Animation {\n currentTime: CSSNumberish | null = null;\n effect: AnimationEffect | null = null;\n readonly finished: Promise<Animation> = Promise.resolve<Animation>(this);\n id = '';\n oncancel: ((this: Animation, ev: AnimationPlaybackEvent) => unknown) | null = null;\n onfinish: ((this: Animation, ev: AnimationPlaybackEvent) => unknown) | null = null;\n onremove: ((this: Animation, ev: Event) => unknown) | null = null;\n readonly overallProgress: number | null = 1;\n readonly pending = false;\n readonly playState: AnimationPlayState = 'finished';\n playbackRate = 1;\n readonly ready: Promise<Animation> = Promise.resolve<Animation>(this);\n readonly replaceState: AnimationReplaceState = 'active';\n startTime: CSSNumberish | null = null;\n timeline: AnimationTimeline | null = null;\n\n cancel(): void {\n // Nothing is running.\n }\n commitStyles(): void {\n // The end state is already on the element.\n }\n finish(): void {\n // Already finished.\n }\n pause(): void {\n // Nothing is running.\n }\n persist(): void {\n // Nothing to persist.\n }\n play(): void {\n // Nothing to play.\n }\n reverse(): void {\n // Nothing to reverse.\n }\n updatePlaybackRate(rate: number): void {\n this.playbackRate = rate;\n }\n}\n\n/**\n * `el.animate(frames, options)`, or, where the Web Animations API is missing, the end state at\n * once: a `forwards` fill writes the last frame onto `el.style` (an exit stays hidden), any other\n * fill leaves the element as it is (an enter ends in its natural state). The returned animation\n * is finished either way.\n */\nexport function animateOrSettle(\n el: HTMLElement,\n frames: Keyframe[],\n options: KeyframeAnimationOptions,\n): Animation {\n if (typeof el.animate === 'function') {\n return el.animate(frames, options);\n }\n const last = frames[frames.length - 1];\n if (last && (options.fill === 'forwards' || options.fill === 'both')) {\n for (const [key, value] of Object.entries(last)) {\n if (!TIMING_KEYS.has(key) && value !== null && value !== undefined) {\n el.style.setProperty(\n key.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`),\n String(value),\n );\n }\n }\n }\n return new BfFinishedAnimation();\n}\n\nfunction run(el: HTMLElement, frames: Frame[], entering: boolean): Animation {\n if (prefersReducedMotion(el.ownerDocument.defaultView)) {\n const fade = entering ? [{ opacity: 0 }, { opacity: 1 }] : [{ opacity: 1 }, { opacity: 0 }];\n return animateOrSettle(el, fade, {\n duration: OVERLAY_REDUCED_DURATION,\n easing: 'linear',\n fill: entering ? 'backwards' : 'forwards',\n });\n }\n return animateOrSettle(el, frames, {\n duration: OVERLAY_DURATION,\n easing: OVERLAY_EASING,\n // Entering: hold the first frame until the animation starts. Leaving: hold the last frame\n // until the overlay is detached, so it never flashes back in.\n fill: entering ? 'backwards' : 'forwards',\n });\n}\n\n/**\n * Slides `el` up into place from `distance` below it (default: its own height).\n *\n * @param el The element to animate, usually the overlay panel.\n * @param distance How far below its place it starts, as a CSS length.\n * @returns The running animation.\n * @summary Slides an element up into place, the enter animation of a bottom sheet\n * @since 0.2.0\n */\nexport function slideUp(el: HTMLElement, distance = '100%'): Animation {\n return run(\n el,\n [{ transform: `translate3d(0,${distance},0)` }, { transform: 'translate3d(0,0,0)' }],\n true,\n );\n}\n\n/**\n * Slides `el` down out of place by `distance` (default: its own height).\n *\n * @param el The element to animate, usually the overlay panel.\n * @param distance How far below its place it ends, as a CSS length.\n * @returns The running animation.\n * @summary Slides an element down out of place, the exit animation of a bottom sheet\n * @since 0.2.0\n */\nexport function slideDown(el: HTMLElement, distance = '100%'): Animation {\n return run(\n el,\n [{ transform: 'translate3d(0,0,0)' }, { transform: `translate3d(0,${distance},0)` }],\n false,\n );\n}\n\n/**\n * Fades `el` in.\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Fades an element in, the default enter animation of an overlay\n * @since 0.2.0\n */\nexport function fadeIn(el: HTMLElement): Animation {\n return run(el, [{ opacity: 0 }, { opacity: 1 }], true);\n}\n\n/**\n * Fades `el` out.\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Fades an element out, the default exit animation of an overlay\n * @since 0.2.0\n */\nexport function fadeOut(el: HTMLElement): Animation {\n return run(el, [{ opacity: 1 }, { opacity: 0 }], false);\n}\n\n/**\n * Scales `el` up from 92 % while fading it in (centred dialogs).\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Scales an element up while fading it in, the enter animation of centred dialogs\n * @since 0.2.0\n */\nexport function scaleIn(el: HTMLElement): Animation {\n return run(\n el,\n [\n { opacity: 0, transform: 'scale(0.92)' },\n { opacity: 1, transform: 'scale(1)' },\n ],\n true,\n );\n}\n\n/**\n * Fades `el` in while it rises by `distance` (default 16 px; the Material modal enter).\n *\n * @param el The element to animate, usually the overlay panel.\n * @param distance How far below its place it starts, as a CSS length.\n * @returns The running animation.\n * @summary Fades an element in while it rises, the Material modal enter animation\n * @since 0.2.0\n */\nexport function fadeUp(el: HTMLElement, distance = '16px'): Animation {\n return run(\n el,\n [\n { opacity: 0, transform: `translate3d(0,${distance},0)` },\n { opacity: 1, transform: 'translate3d(0,0,0)' },\n ],\n true,\n );\n}\n\n/**\n * Fades `el` out while it sinks by `distance` (default 16 px; the reverse of `fadeUp`).\n *\n * @param el The element to animate, usually the overlay panel.\n * @param distance How far below its place it ends, as a CSS length.\n * @returns The running animation.\n * @summary Fades an element out while it sinks, the reverse of the fadeUp animation\n * @since 0.2.0\n */\nexport function fadeDown(el: HTMLElement, distance = '16px'): Animation {\n return run(\n el,\n [\n { opacity: 1, transform: 'translate3d(0,0,0)' },\n { opacity: 0, transform: `translate3d(0,${distance},0)` },\n ],\n false,\n );\n}\n\n/** `-` under `dir=\"rtl\"` (the CDK sets `dir` on the overlay host), so the end edge is the left. */\nfunction towardsEnd(el: HTMLElement): string {\n return el.closest('[dir]')?.getAttribute('dir') === 'rtl' ? '-' : '';\n}\n\n/**\n * Slides `el` in from beyond the inline end edge of the viewport (the right, the left under\n * `dir=\"rtl\"`) by its own width: the enter animation of a side panel.\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Slides an element in from the inline end, the enter animation of a side panel\n * @since 0.3.1\n */\nexport function slideInFromEnd(el: HTMLElement): Animation {\n return run(\n el,\n [{ transform: `translate3d(${towardsEnd(el)}100%,0,0)` }, { transform: 'translate3d(0,0,0)' }],\n true,\n );\n}\n\n/**\n * Slides `el` out past the inline end edge of the viewport by its own width (the reverse of\n * `slideInFromEnd`): the exit animation of a side panel.\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Slides an element out past the inline end, the exit animation of a side panel\n * @since 0.3.1\n */\nexport function slideOutToEnd(el: HTMLElement): Animation {\n return run(\n el,\n [{ transform: 'translate3d(0,0,0)' }, { transform: `translate3d(${towardsEnd(el)}100%,0,0)` }],\n false,\n );\n}\n","import { FocusTrapFactory, type FocusTrap } from '@angular/cdk/a11y';\nimport { Overlay, OverlayConfig, type PositionStrategy } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { Location, NgTemplateOutlet } from '@angular/common';\nimport {\n Component,\n DOCUMENT,\n Injectable,\n Injector,\n type StaticProvider,\n TemplateRef,\n type Type,\n inject,\n input,\n} from '@angular/core';\nimport { type Subscription } from 'rxjs';\nimport { OVERLAY_DURATION, OVERLAY_EASING, prefersReducedMotion } from './motion';\nimport { watchPathChange } from './navigation';\nimport { animateOrSettle, fadeIn, fadeOut } from './overlay-animations';\nimport { BF_OVERLAY_HOST } from './overlay-host';\nimport { BF_OVERLAY_DATA, BfComponentOverlayRef, BfOverlayRef } from './overlay-ref';\nimport { BfOverlayStack } from './overlay-stack.service';\n\n/**\n * Where the overlay's panel sits in the viewport.\n *\n * @summary Where an overlay panel sits in the viewport: bottom, centre, top or fullscreen\n * @since 0.2.0\n */\nexport type BfOverlayPosition = 'bottom' | 'center' | 'top' | 'fullscreen';\n\n/**\n * Where an overlay panel sits: a `BfOverlayPosition`, or `end`, full height against the inline\n * end edge of the viewport (the right in a left-to-right page, the left under `dir=\"rtl\"`).\n *\n * @summary Where an overlay panel sits: a viewport position or full height at the end\n * @since 0.3.1\n */\nexport type BfOverlayPlacement = BfOverlayPosition | 'end';\n\n/**\n * The ARIA role of an overlay panel: a `dialog`, an `alertdialog` or a passive `status`.\n *\n * @summary The role an overlay panel carries: a dialog, an alert dialog or a status\n * @since 0.3.0\n */\nexport type BfOverlayRole = 'dialog' | 'alertdialog' | 'status';\n\n/**\n * Where focus goes when an overlay opens: the first tabbable element of the content\n * (`first-tabbable`, skipping the container's own controls such as `bf-sheet`'s hidden Close) or\n * the panel itself (`panel`).\n *\n * @summary Where focus lands when an overlay opens, its first control or the panel\n * @since 0.3.0\n */\nexport type BfOverlayAutoFocus = 'first-tabbable' | 'panel';\n\n/**\n * Options of `BfOverlayService.open()`.\n *\n * @summary Options of an overlay: its data, backdrop, focus, dismissal, position and motion\n * @since 0.2.0\n */\nexport interface BfOverlayOptions {\n /** Injected into the content as `BF_OVERLAY_DATA`. */\n data?: unknown;\n /** Extra classes on the panel (it always carries `bf-overlay-panel`). */\n panelClass?: string[];\n /**\n * Renders a backdrop behind the panel (default true; never for passive overlays).\n * @default true\n */\n backdrop?: boolean;\n /**\n * Class of the backdrop (default `bf-overlay-backdrop`: a black scrim, 40 % light / 60 % dark).\n * @default 'bf-overlay-backdrop'\n */\n backdropClass?: string;\n /**\n * A backdrop click closes the overlay (default true).\n * @default true\n */\n dismissOnBackdrop?: boolean;\n /**\n * `Escape` closes the overlay (default true).\n * @default true\n */\n dismissOnEscape?: boolean;\n /**\n * Runs instead of closing when the overlay is on top and `Escape` is pressed (e.g. an alert\n * resolving with its cancel button). The key is always claimed by the topmost non-passive\n * overlay, so it never reaches an overlay underneath.\n */\n onEscape?: () => void;\n /**\n * Role of the panel (default `dialog`; passive overlays get none unless one is given — a toast\n * is announced through `LiveAnnouncer`).\n * @default 'dialog'\n */\n role?: BfOverlayRole;\n /** Accessible name of the panel. */\n ariaLabel?: string;\n /**\n * Id of the element naming the panel. Dropped after the content renders when no element inside\n * the panel carries it and `ariaLabel` is unset, so the panel never points at nothing.\n */\n ariaLabelledBy?: string;\n /** Id of the element describing the panel (an alert's message). */\n ariaDescribedBy?: string;\n /**\n * Traps Tab focus inside the panel (default true).\n * @default true\n */\n trapFocus?: boolean;\n /**\n * Where focus goes on open (non-passive overlays): `first-tabbable` (default) — the element\n * marked `[autofocus]`/`[cdkFocusInitial]` when it is focusable (a control, or any element with\n * a `tabindex`, also `-1`), else the first tabbable element inside it, else (all its controls\n * disabled) the first tabbable element of the panel, else the panel; `panel` — the panel\n * itself, so a long text is read from its start (APG dialog pattern). `first-tabbable` skips the\n * library's own container controls (`bf-sheet`'s hidden Close and grabber button, marked with\n * the internal `data-bf-overlay-chrome`): they stay in the Tab order but never take the initial\n * focus, so it lands on your content.\n * @default 'first-tabbable'\n */\n autoFocus?: BfOverlayAutoFocus;\n /**\n * Returns focus to the previously focused element on close (default true); when that element\n * is gone, to the topmost overlay still open, else focus stays on the body (move it yourself,\n * e.g. to the next row after a delete).\n * @default true\n */\n restoreFocus?: boolean;\n /**\n * Placement of the panel (default `center`); `end` is full height at the inline end edge.\n * @default 'center'\n */\n position?: BfOverlayPlacement;\n /**\n * Closes the overlay when the URL path changes (default true; false for passive overlays): a\n * router navigation, a link, the browser's back and forward buttons. Query- or fragment-only\n * changes never close; a matrix-parameter change (`/a;x=1`) is a path change and closes. Read\n * from `Location.onUrlChange()`, so no router is needed, and a `history.pushState()` made\n * outside Angular's `Location` is not seen. An overlay opened before the first navigation ends\n * (root component, `APP_INITIALIZER`) closes when the start URL redirects: open it after the\n * first `NavigationEnd`, or pass false.\n * @default true\n */\n closeOnNavigation?: boolean;\n /**\n * Runs instead of `close()` when a navigation closes the overlay (e.g. an alert answering with\n * its cancel id); it should close the overlay.\n */\n onNavigation?: () => void;\n /**\n * Priority of the hardware back handler that closes the overlay (default 100).\n * @default 100\n */\n backPriority?: number;\n /**\n * Counts towards `BfOverlayStack.depth()` / `--bf-modal-depth` (default false).\n * @default false\n */\n countsAsModal?: boolean;\n /**\n * A passive overlay (a toast) has no backdrop, no focus trap, does not move focus, does not\n * count in `BfOverlayStack.count()`, registers no back handler and leaves the page interactive.\n * @default false\n */\n passive?: boolean;\n /**\n * A modal overlay (default true) has a backdrop, traps focus, is `aria-modal`, blocks document\n * scroll and makes the page behind it `inert`. A non-modal one (a side panel beside the page)\n * has none of these and is not in `BfOverlayStack`: focus moves in, the page stays usable,\n * `Escape` closes it only while focus is inside it, and on close focus returns to the opener\n * only from inside it. Ignored for passive overlays.\n * @default true\n */\n modal?: boolean;\n /**\n * Enter animation of the panel (default `fadeIn`); return null for none.\n * @default fadeIn\n */\n enter?: (el: HTMLElement) => Animation | null;\n /**\n * Exit animation of the panel (default `fadeOut`), awaited before detaching.\n * @default fadeOut\n */\n exit?: (el: HTMLElement) => Animation | null;\n /**\n * Parent of the content's injector (default the root injector), so the content resolves the\n * opener's providers, e.g. a feature-level `provideBfLabels()`.\n */\n injector?: Injector;\n /**\n * Extra providers of the content's injector, next to `BF_OVERLAY_DATA` and `BfOverlayRef`,\n * built with the new overlay's ref (e.g. a typed ref of a service built on the core).\n */\n providers?: (ref: BfOverlayRef<unknown>) => StaticProvider[];\n}\n\n/**\n * Context of a template opened as an overlay: `let-ref` and `let-data=\"data\"`.\n *\n * @summary The context a template opened as an overlay receives: its ref and data\n * @since 0.2.0\n */\nexport interface BfOverlayTemplateContext {\n /** The overlay's ref (`let-ref`), to close it with a result. */\n $implicit: BfOverlayRef<unknown>;\n /** The `data` the overlay was opened with (`let-data=\"data\"`). */\n data: unknown;\n}\n\n/** Renders a template opened through `BfOverlayService` inside the overlay pane. */\n@Component({\n selector: 'bf-overlay-template-host',\n imports: [NgTemplateOutlet],\n host: { style: 'display: contents' },\n template: `<ng-container\n [ngTemplateOutlet]=\"template()\"\n [ngTemplateOutletContext]=\"context()\"\n [ngTemplateOutletInjector]=\"injector()\"\n />`,\n})\nclass BfOverlayTemplateHostComponent {\n readonly template = input.required<TemplateRef<unknown>>();\n readonly context = input.required<BfOverlayTemplateContext>();\n readonly injector = input.required<Injector>();\n}\n\n/** The elements Tab stops at (without a negative tabindex). */\nexport const TABBABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n].join(',');\n\n/**\n * Where an overlay's initial focus goes inside `panel`: the `[autofocus]`/`[cdkFocusInitial]` mark,\n * else the first tabbable element that is not the container's own chrome. Shared with the popover.\n */\nexport function firstTabbable(panel: HTMLElement): HTMLElement | null {\n const autofocus = panel.querySelector<HTMLElement>('[autofocus], [cdkFocusInitial]');\n if (autofocus) {\n // A focusable mark (a control, or any element with a tabindex such as a tabindex=\"-1\"\n // region to start reading at) takes focus itself; a marked wrapper (a bf-button host) hands\n // it to the control inside. A wrapper whose controls are all disabled is skipped.\n if (autofocus.matches(TABBABLE) || autofocus.hasAttribute('tabindex')) {\n return autofocus;\n }\n const inner = autofocus.querySelector<HTMLElement>(TABBABLE);\n if (inner) {\n return inner;\n }\n }\n for (const el of Array.from(panel.querySelectorAll<HTMLElement>(TABBABLE))) {\n // A container's own controls (bf-sheet's screen-reader Close and grabber, marked\n // `data-bf-overlay-chrome`) stay in the Tab order but never take the initial focus.\n if (!el.closest('[inert]') && !el.hidden && !el.hasAttribute('data-bf-overlay-chrome')) {\n return el;\n }\n }\n return null;\n}\n\n/**\n * The part of the browser's `CloseWatcher` (Chromium 120+; not yet in TypeScript's `lib.dom`) the\n * core uses: `onclose` runs on a close request (Android back, `Escape` not already handled), and\n * `destroy()` stops watching without an event.\n */\ninterface BfCloseWatcher {\n onclose: (() => void) | null;\n destroy(): void;\n}\n\ntype BfCloseWatcherConstructor = new () => BfCloseWatcher;\n\nfunction isCloseWatcherConstructor(value: unknown): value is BfCloseWatcherConstructor {\n return typeof value === 'function';\n}\n\n/** The window's `CloseWatcher` constructor, or null where the browser has none. */\nfunction closeWatcherOf(view: Window | null): BfCloseWatcherConstructor | null {\n const constructor: unknown = view ? Reflect.get(view, 'CloseWatcher') : undefined;\n return isCloseWatcherConstructor(constructor) ? constructor : null;\n}\n\n/**\n * True when `event` started inside a CDK overlay pane other than `pane`, e.g. a CDK menu opened\n * from a dialog: its `Escape` is the menu's, so the dialog underneath stays open. Read from the\n * event path, which still holds the pane after the menu has closed and left the DOM.\n */\nfunction fromOtherPane(event: Event, pane: HTMLElement): boolean {\n for (const target of event.composedPath()) {\n if (target === pane) {\n return false;\n }\n if (target instanceof Element && target.classList.contains('cdk-overlay-pane')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Opens overlays on the Angular CDK `Overlay`: a component or template in a panel with a\n * backdrop, a focus trap, `role`/`aria-modal`/`aria-labelledby`, `Escape` and backdrop click\n * closing it, and the page behind it `inert` (see `BfOverlayStack`). A non-passive overlay blocks\n * document scroll (CDK `block()` scroll strategy); passive overlays, and every overlay under a\n * `BF_OVERLAY_HOST` whose document never scrolls (the `/mobile` `provideBfShell()`), use `noop()`.\n * Under `provideBfShell()` the hardware back button (priority 100) closes it too; without a host\n * no back handler is registered. Where the browser has `CloseWatcher` (Chromium 120+), a close\n * request (Android back in Chrome or a PWA) runs the `Escape` path on the top non-passive overlay,\n * unless the host handles the system back itself (`handlesSystemBack`). An overlay that does not\n * close on it (`dismissOnEscape: false` without `onEscape`, or an `onEscape` that keeps it open)\n * swallows Android web back for as long as it is open, as a non-dismissible sheet swallows the\n * hardware back button. A navigation to another URL path closes every non-passive\n * overlay (`closeOnNavigation`, read from `Location`, so no router is needed). `modal: false`\n * (a side panel beside the page) drops the backdrop, the trap, `aria-modal`, the scroll lock and\n * the `inert` page. The content injects `BF_OVERLAY_DATA` and `BfOverlayRef` (plus any\n * `providers`). `BfDialogService`, `BfSidePanelService` and the `/mobile` sheet, modal, toast,\n * action sheet and alert services build on it.\n *\n * @example\n * const ref = inject(BfOverlayService).open(ConfirmComponent, {\n * data: { name },\n * ariaLabelledBy: 'confirm-title',\n * });\n * const confirmed = await ref.afterClosed;\n *\n * @summary Opens a component or template in an overlay panel on the Angular CDK\n * @since 0.2.0\n */\n@Injectable({ providedIn: 'root' })\nexport class BfOverlayService {\n private readonly overlay = inject(Overlay);\n private readonly injector = inject(Injector);\n private readonly document = inject(DOCUMENT);\n private readonly stack = inject(BfOverlayStack);\n private readonly focusTrapFactory = inject(FocusTrapFactory);\n private readonly location = inject(Location);\n /** Panels of the open non-passive overlays, oldest first (focus fallback on close). */\n private readonly openPanels = new Set<HTMLElement>();\n private readonly host = inject(BF_OVERLAY_HOST, { optional: true });\n /** Under `provideBfShell()` the document never scrolls (the stack pages do). */\n private readonly documentScrolls = this.host?.documentScrolls !== false;\n\n /**\n * Opens `component` in an overlay.\n * @param component The component to render in the panel.\n * @param options The overlay's data, backdrop, focus, dismissal, position and motion.\n */\n open<C, T = unknown>(component: Type<C>, options?: BfOverlayOptions): BfComponentOverlayRef<C, T>;\n /**\n * Opens `template` in an overlay; its context is `{ $implicit: ref, data }`.\n * @param template The template to render in the panel.\n * @param options The overlay's data, backdrop, focus, dismissal, position and motion.\n */\n open<T = unknown>(template: TemplateRef<unknown>, options?: BfOverlayOptions): BfOverlayRef<T>;\n open<C, T = unknown>(\n content: Type<C> | TemplateRef<unknown>,\n options: BfOverlayOptions = {},\n ): BfOverlayRef<T> {\n const passive = options.passive ?? false;\n // A non-modal overlay leaves the page as it is: no backdrop, trap, inert or scroll lock.\n const modal = !passive && (options.modal ?? true);\n const previouslyFocused = this.document.activeElement as HTMLElement | null;\n const hasBackdrop = modal && (options.backdrop ?? true);\n const position = options.position ?? 'center';\n const overlayRef = this.overlay.create(\n new OverlayConfig({\n positionStrategy: this.positionStrategy(position),\n // A modal overlay blocks document scroll (no scroll bleed behind a dialog on desktop); a\n // passive toast never does, and a host whose document never scrolls needs no lock.\n scrollStrategy:\n !modal || !this.documentScrolls\n ? this.overlay.scrollStrategies.noop()\n : this.overlay.scrollStrategies.block(),\n hasBackdrop,\n backdropClass: options.backdropClass ?? 'bf-overlay-backdrop',\n panelClass: ['bf-overlay-panel', ...(options.panelClass ?? [])],\n ...(position === 'fullscreen' ? { width: '100%', height: '100%' } : {}),\n ...(position === 'end' ? { height: '100%' } : {}),\n }),\n );\n const panel = overlayRef.overlayElement;\n\n const subscriptions: Subscription[] = [];\n let focusTrap: FocusTrap | null = null;\n let enterAnimation: Animation | null = null;\n let stopNavigation: (() => void) | null = null;\n let closeWatcher: BfCloseWatcher | null = null;\n\n const controller = {\n close: async (): Promise<void> => {\n // A non-modal overlay hands focus back only from inside it: focus the user moved to the\n // page stays where it is.\n const active = this.document.activeElement;\n const focusInside = active === this.document.body || panel.contains(active);\n stopNavigation?.();\n closeWatcher?.destroy();\n closeWatcher = null;\n this.stack.releaseBack(ref);\n subscriptions.forEach((s) => s.unsubscribe());\n enterAnimation?.cancel();\n this.fadeOutBackdrop(overlayRef.backdropElement);\n try {\n const exit = (options.exit ?? fadeOut)(panel);\n await exit?.finished;\n } catch {\n // A cancelled exit animation still closes.\n }\n focusTrap?.destroy();\n overlayRef.dispose();\n this.stack.pop(ref);\n this.openPanels.delete(panel);\n if (!passive && (options.restoreFocus ?? true) && (modal || focusInside)) {\n // The opener may be gone (a deleted row, content re-rendered under a nested overlay):\n // then focus the topmost overlay still open, never the page behind it.\n const fallback = [...this.openPanels].at(-1);\n if (previouslyFocused?.isConnected) {\n previouslyFocused.focus({ preventScroll: true });\n } else if (fallback) {\n fallback.focus({ preventScroll: true });\n }\n }\n },\n updatePosition: (): void => overlayRef.updatePosition(),\n };\n\n const ref: BfOverlayRef<T> =\n content instanceof TemplateRef\n ? new BfOverlayRef<T>(controller)\n : new BfComponentOverlayRef<C, T>(controller);\n const contentInjector = Injector.create({\n parent: options.injector ?? this.injector,\n providers: [\n { provide: BF_OVERLAY_DATA, useValue: options.data },\n { provide: BfOverlayRef, useValue: ref },\n // A ref's result type only narrows what close() accepts; the providers see any result.\n ...(options.providers?.(ref as BfOverlayRef<unknown>) ?? []),\n ],\n });\n\n this.decoratePanel(panel, options, passive, modal);\n if (!passive) {\n this.openPanels.add(panel);\n }\n if (modal) {\n this.stack.push(ref, {\n backPriority: options.backPriority,\n countsAsModal: options.countsAsModal,\n });\n }\n\n if (content instanceof TemplateRef) {\n const host = overlayRef.attach(\n new ComponentPortal(BfOverlayTemplateHostComponent, null, contentInjector),\n );\n host.setInput('template', content);\n host.setInput('context', { $implicit: ref, data: options.data });\n host.setInput('injector', contentInjector);\n host.changeDetectorRef.detectChanges();\n } else {\n const componentRef = overlayRef.attach(new ComponentPortal(content, null, contentInjector));\n componentRef.changeDetectorRef.detectChanges();\n (ref as BfComponentOverlayRef<C, T>).setComponentRef(componentRef);\n }\n this.dropDanglingLabel(panel, options);\n\n if (!passive) {\n /** What `Escape` and a close request (Android web back) do on the top overlay. */\n const dismissByEscape = (): void => {\n if (options.onEscape) {\n options.onEscape();\n } else if (options.dismissOnEscape ?? true) {\n ref.close();\n }\n };\n // Always listen: the CDK hands a keydown to the topmost overlay that has listeners, so an\n // overlay that ignored Escape would let it fall through to the one underneath. Cancelling\n // the key also keeps it from reaching a `CloseWatcher` as a second close request.\n subscriptions.push(\n overlayRef.keydownEvents().subscribe((event) => {\n // A modal answers when it is the top one; a non-modal one (not in the stack) only for a\n // key pressed inside it, so Escape on the page beside it stays the page's.\n const target = event.target;\n const answers = modal\n ? this.stack.isTop(ref)\n : target instanceof Node && overlayRef.overlayElement.contains(target);\n if (\n event.key !== 'Escape' ||\n !answers ||\n fromOtherPane(event, overlayRef.overlayElement)\n ) {\n return;\n }\n event.preventDefault();\n dismissByEscape();\n }),\n );\n // Android back in a browser (Chrome, a PWA) is a close request: with a `CloseWatcher` it\n // closes the overlay instead of leaving the page. Not where the host already routes the\n // system back to `registerBack` (the shell on native Android).\n // A non-modal overlay leaves the back press to the page beside it.\n const Watcher =\n this.host?.handlesSystemBack || !modal ? null : closeWatcherOf(this.document.defaultView);\n const watch = (): void => {\n if (!Watcher) {\n return;\n }\n const watcher = new Watcher();\n watcher.onclose = (): void => {\n if (closeWatcher !== watcher) {\n return;\n }\n closeWatcher = null;\n if (ref.isClosing) {\n return;\n }\n if (this.stack.isTop(ref)) {\n dismissByEscape();\n }\n // Still open (not dismissible, or not the top one of a group the browser closed\n // together): keep claiming the next back press.\n if (!ref.isClosing) {\n watch();\n }\n };\n closeWatcher = watcher;\n };\n watch();\n // A press on the backdrop (not focusable) would move focus to <body>, out of the modal;\n // cancelling the mousedown keeps it where it was. The click still reaches backdropClick().\n overlayRef.backdropElement?.addEventListener('mousedown', (event) => event.preventDefault());\n if (hasBackdrop && (options.dismissOnBackdrop ?? true)) {\n subscriptions.push(overlayRef.backdropClick().subscribe(() => ref.close()));\n }\n if (modal && (options.trapFocus ?? true)) {\n focusTrap = this.focusTrapFactory.create(panel);\n }\n const target = options.autoFocus === 'panel' ? panel : (firstTabbable(panel) ?? panel);\n target.focus({ preventScroll: true });\n }\n\n if (options.closeOnNavigation ?? !passive) {\n stopNavigation = watchPathChange(this.location, () => {\n if (ref.isClosing) {\n return;\n }\n if (options.onNavigation) {\n options.onNavigation();\n } else {\n ref.close();\n }\n });\n }\n\n enterAnimation = (options.enter ?? fadeIn)(panel);\n return ref;\n }\n\n /** Fades the backdrop out alongside the panel's exit (instantly under reduced motion). */\n private fadeOutBackdrop(backdrop: HTMLElement | null): void {\n if (!backdrop) {\n return;\n }\n if (prefersReducedMotion(this.document.defaultView)) {\n backdrop.style.opacity = '0';\n return;\n }\n // Start from where the CDK's fade-in currently is (it may not have finished).\n const current = this.document.defaultView?.getComputedStyle(backdrop).opacity;\n const from = current === undefined || current === '' ? '1' : current;\n animateOrSettle(backdrop, [{ opacity: from }, { opacity: 0 }], {\n duration: OVERLAY_DURATION,\n easing: OVERLAY_EASING,\n fill: 'forwards',\n });\n }\n\n /** Removes an `aria-labelledby` whose id names no element inside the rendered panel. */\n private dropDanglingLabel(panel: HTMLElement, options: BfOverlayOptions): void {\n const id = options.ariaLabelledBy;\n if (!id || options.ariaLabel) {\n return;\n }\n const target = this.document.getElementById(id);\n if (!target || !panel.contains(target)) {\n panel.removeAttribute('aria-labelledby');\n }\n }\n\n private decoratePanel(\n panel: HTMLElement,\n options: BfOverlayOptions,\n passive: boolean,\n modal: boolean,\n ): void {\n const role = options.role ?? (passive ? null : 'dialog');\n if (role) {\n panel.setAttribute('role', role);\n }\n panel.setAttribute('tabindex', '-1');\n if (modal) {\n panel.setAttribute('aria-modal', 'true');\n }\n if (options.ariaLabel) {\n panel.setAttribute('aria-label', options.ariaLabel);\n }\n if (options.ariaLabelledBy) {\n panel.setAttribute('aria-labelledby', options.ariaLabelledBy);\n }\n if (options.ariaDescribedBy) {\n panel.setAttribute('aria-describedby', options.ariaDescribedBy);\n }\n }\n\n private positionStrategy(position: BfOverlayPlacement): PositionStrategy {\n const global = this.overlay.position().global();\n switch (position) {\n case 'bottom':\n return global.centerHorizontally().bottom('0');\n case 'top':\n return global.centerHorizontally().top('0');\n case 'fullscreen':\n return global.top('0').left('0');\n case 'end':\n // `end()` reads the overlay's direction: the right edge, or the left under rtl.\n return global.top('0').end('0');\n default:\n return global.centerHorizontally().centerVertically();\n }\n }\n}\n","let nextTitleId = 0;\n\n/** A heading inside an overlay's content: an `h1`–`h6` or a `[role=heading]`. */\nconst HEADING = 'h1, h2, h3, h4, h5, h6, [role=\"heading\"]';\n\n/**\n * Names an overlay panel by the first heading inside it that is not `aria-hidden` or `hidden`:\n * gives the heading an id when it has none (`bf-overlay-title-<n>`), points the panel's\n * `aria-labelledby` at it and drops the fallback `aria-label`. Leaves the panel as it is when\n * there is no heading. Returns whether it found one.\n */\nexport function labelPanelByHeading(panel: HTMLElement): boolean {\n const heading = Array.from(panel.querySelectorAll<HTMLElement>(HEADING)).find(\n (element) => !element.closest('[aria-hidden=\"true\"], [hidden]'),\n );\n if (!heading) {\n return false;\n }\n if (!heading.id) {\n heading.id = `bf-overlay-title-${nextTitleId++}`;\n }\n panel.setAttribute('aria-labelledby', heading.id);\n panel.removeAttribute('aria-label');\n return true;\n}\n\n/**\n * `labelPanelByHeading` now, and, while the content has no heading yet (content behind an `@if`\n * or a `resource()`), again whenever the panel's DOM changes, until the first heading appears.\n * Only that first heading names the panel; later changes are not followed. Returns a function\n * that stops watching; call it when the overlay closes.\n */\nexport function watchPanelHeading(panel: HTMLElement): () => void {\n if (labelPanelByHeading(panel)) {\n return () => undefined;\n }\n const observer = new MutationObserver(() => {\n if (labelPanelByHeading(panel)) {\n observer.disconnect();\n }\n });\n observer.observe(panel, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['role', 'aria-hidden', 'hidden'],\n });\n return () => observer.disconnect();\n}\n","/**\n * The action rendered as a real button inside a toast.\n *\n * @summary The action button of a toast: its label and what it runs when clicked\n * @since 0.2.0\n */\nexport interface BfToastAction {\n /** Text of the action button. */\n label: string;\n /** Runs before the toast closes with reason `'action'`. */\n handler?: () => void;\n}\n\n/**\n * Why a toast ended.\n *\n * @summary Why a toast ended: its time ran out, its action fired or it was dismissed\n * @since 0.2.0\n */\nexport type BfToastDismissReason = 'timeout' | 'action' | 'dismiss';\n\n/**\n * What the toast queue does for a toast ref; internal.\n *\n * @summary What the toast queue does for a toast ref: dismiss the toast now\n * @since 0.2.0\n */\nexport interface BfToastController {\n /** Ends the toast now: closes it if shown, or drops it from the queue if it never showed. */\n dismiss(): void;\n}\n\n/**\n * Handle to a toast, returned by `BfToastService.show()` (`/mobile`) and\n * `BfDesktopToastService.show()` (`/overlay`). `dismiss()` ends it immediately — closing it right\n * away if it is shown, or removing it from the queue before it ever shows. `afterDismissed`\n * resolves with why it ended: `'timeout'` (its duration elapsed), `'action'` (the action button\n * was clicked) or `'dismiss'` (`dismiss()` was called). The duration never runs out while the\n * toast is hovered or focused, and a toast with an action has none by default, so it only ends\n * with `'action'` or `'dismiss'` (`dismiss()`, `Escape` inside it, or the next `show()` replacing\n * it).\n *\n * @example\n * const ref = inject(BfToastService).show({ message: 'Saved' });\n * const reason = await ref.afterDismissed;\n * @since 0.2.0\n * @summary Handle on a shown or queued toast that dismisses it and reports why it ended\n */\nexport class BfToastRef {\n /** Resolves with why the toast ended. */\n readonly afterDismissed: Promise<BfToastDismissReason>;\n\n constructor(\n private readonly controller: BfToastController,\n afterDismissed: Promise<BfToastDismissReason>,\n ) {\n this.afterDismissed = afterDismissed;\n }\n\n /** Ends the toast now; see the class doc. */\n dismiss(): void {\n this.controller.dismiss();\n }\n}\n","/**\n * The toast engine shared by the `/mobile` `BfToastService` and the `/overlay`\n * `BfDesktopToastService`: timing, hold, replace, focus return, announcements and teardown.\n * Internal (`ɵ`-prefixed), not public API; it may change in any release.\n */\nimport type { LiveAnnouncer } from '@angular/cdk/a11y';\nimport type { DestroyRef } from '@angular/core';\nimport { type BfToastAction, type BfToastDismissReason, BfToastRef } from './toast-ref';\n\n/** One `show()` call; not public API. */\nexport interface ɵBfToastRequest {\n message: string;\n action?: BfToastAction;\n /** Default 3000 without an action, 0 (persistent) with one. */\n duration?: number;\n}\n\n/** What a presenter renders for one toast; not public API. */\nexport interface ɵBfToastView {\n readonly message: string;\n /** The action button, or null; `run()` calls the handler and closes with `'action'`. */\n readonly action: { label: string; run: () => void } | null;\n /** Pauses (`held: true`) or resumes this toast's timer. */\n hold(source: 'pointer' | 'focus', held: boolean): void;\n /** `Escape` inside the toast: dismisses it (`'dismiss'`). */\n escape(): void;\n}\n\n/** A rendered toast; not public API. */\nexport interface ɵBfToastHandle {\n /** The toast's element (focus inside it counts as \"in the toast\"). */\n readonly host: HTMLElement | null;\n /** Plays the exit and removes the toast; resolves once it is gone. */\n close(reason: BfToastDismissReason): Promise<void>;\n}\n\n/**\n * Renders toasts for the queue; `request` is the `show()` argument as given (a presenter reads\n * its own extra fields from it, e.g. the mobile `position`). Not public API.\n */\nexport interface ɵBfToastPresenter<R extends ɵBfToastRequest = ɵBfToastRequest> {\n present(view: ɵBfToastView, request: R): ɵBfToastHandle;\n}\n\n/** Options of `ɵBfToastQueue`; not public API. */\nexport interface ɵBfToastQueueOptions {\n /** How many toasts are shown at once (1 on mobile). */\n maxVisible: number;\n announcer: LiveAnnouncer;\n document: Document;\n /** Ends every toast (timers, listeners) when destroyed; later `show()` calls resolve `'dismiss'`. */\n destroyRef: DestroyRef;\n}\n\ninterface Entry<R> {\n request: R;\n message: string;\n action: BfToastAction | undefined;\n duration: number;\n resolve: (reason: BfToastDismissReason) => void;\n dismissed: boolean;\n /** Set once the toast is shown; ends it (idempotent). */\n finish?: (reason: BfToastDismissReason) => void;\n}\n\n/** Default lifetime of a toast without an action; one with an action persists (WCAG 2.2.1). */\nconst DEFAULT_DURATION = 3000;\n\n/** What the live announcer reads: the message, then the action label as its own sentence. */\nfunction announcement(message: string, action: BfToastAction | undefined): string {\n if (!action) {\n return message;\n }\n // A message that already ends in punctuation takes the label after a space (\"Failed: Retry\").\n const separator = /[.!?…:;,]$/.test(message.trim()) ? ' ' : '. ';\n return `${message.trim()}${separator}${action.label}`;\n}\n\n/**\n * Queues toasts and shows up to `maxVisible` at once through a presenter. A toast\n * auto-dismisses after `duration` ms (`'timeout'`); a persistent one (`duration` 0, the default\n * with an action) never blocks the queue: the next `show()` dismisses it, visible or waiting\n * (`'dismiss'`). The timer pauses while held (pointer or focus) and resumes with the rest. A\n * toast holding focus when it closes hands focus back to the element focused last outside it.\n * Each toast is announced once, politely, as it shows. Not public API.\n */\nexport class ɵBfToastQueue<R extends ɵBfToastRequest = ɵBfToastRequest> {\n private readonly waiting: Entry<R>[] = [];\n /** Shown toasts, oldest first, until their exit has finished (they hold their slot). */\n private readonly shown = new Set<Entry<R>>();\n private destroyed = false;\n\n constructor(\n private readonly presenter: ɵBfToastPresenter<R>,\n private readonly options: ɵBfToastQueueOptions,\n ) {\n // Ends every toast (clearing its timer and document listeners) with the injector.\n options.destroyRef.onDestroy(() => {\n this.destroyed = true;\n for (const entry of [...this.waiting, ...this.shown]) {\n this.dismissEntry(entry);\n }\n });\n }\n\n /**\n * Queues `request`; shows it now while fewer than `maxVisible` are shown, else once one ends.\n * Every persistent toast, shown or waiting, is dismissed first.\n */\n show(request: R): BfToastRef {\n let resolve: (reason: BfToastDismissReason) => void = () => undefined;\n const afterDismissed = new Promise<BfToastDismissReason>((res) => {\n resolve = res;\n });\n const entry: Entry<R> = {\n request,\n message: request.message,\n action: request.action,\n duration: request.duration ?? (request.action ? 0 : DEFAULT_DURATION),\n resolve,\n dismissed: false,\n };\n const ref = new BfToastRef({ dismiss: () => this.dismissEntry(entry) }, afterDismissed);\n if (this.destroyed) {\n entry.dismissed = true;\n resolve('dismiss');\n return ref;\n }\n for (const stale of [...this.waiting, ...this.shown]) {\n if (stale.duration <= 0) {\n this.dismissEntry(stale);\n }\n }\n this.waiting.push(entry);\n this.pump();\n return ref;\n }\n\n private dismissEntry(entry: Entry<R>): void {\n if (entry.dismissed) {\n return;\n }\n if (entry.finish) {\n entry.finish('dismiss');\n return;\n }\n const index = this.waiting.indexOf(entry);\n if (index >= 0) {\n this.waiting.splice(index, 1);\n }\n entry.dismissed = true;\n entry.resolve('dismiss');\n }\n\n private pump(): void {\n while (!this.destroyed && this.shown.size < this.options.maxVisible) {\n const entry = this.waiting.shift();\n if (!entry) {\n return;\n }\n this.shown.add(entry);\n this.present(entry);\n }\n }\n\n private present(entry: Entry<R>): void {\n const doc = this.options.document;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let remaining = entry.duration;\n let startedAt = 0;\n const holds = new Set<'pointer' | 'focus'>();\n let handle: ɵBfToastHandle | null = null;\n /** A reason given before the presenter returned its handle (closed right after). */\n let early: BfToastDismissReason | null = null;\n // Where focus goes back to if the toast still holds it when it closes: the element focused\n // last outside the toast (at open, or since), or nothing once focus fell to the page body.\n let returnTo = this.focusedElement();\n const inToast = (target: EventTarget | null): boolean =>\n target instanceof Node && (handle?.host?.contains(target) ?? false);\n const onDocumentFocusIn = (event: FocusEvent): void => {\n if (!inToast(event.target)) {\n returnTo = event.target instanceof HTMLElement ? event.target : null;\n }\n };\n const onDocumentFocusOut = (event: FocusEvent): void => {\n if (!inToast(event.target) && event.relatedTarget === null) {\n returnTo = null;\n }\n };\n\n const pauseTimer = (): void => {\n if (timer === null) {\n return;\n }\n clearTimeout(timer);\n timer = null;\n remaining -= Date.now() - startedAt;\n };\n const startTimer = (): void => {\n if (entry.duration <= 0 || entry.dismissed || timer !== null || holds.size > 0) {\n return;\n }\n startedAt = Date.now();\n timer = setTimeout(() => finish('timeout'), Math.max(0, remaining));\n };\n\n const close = (current: ɵBfToastHandle, reason: BfToastDismissReason): void => {\n void current.close(reason).then(() => {\n entry.resolve(reason);\n this.shown.delete(entry);\n this.pump();\n });\n };\n\n const finish = (reason: BfToastDismissReason): void => {\n if (entry.dismissed) {\n return;\n }\n entry.dismissed = true;\n pauseTimer();\n doc.removeEventListener('focusin', onDocumentFocusIn, true);\n doc.removeEventListener('focusout', onDocumentFocusOut, true);\n if (inToast(doc.activeElement) && returnTo?.isConnected) {\n returnTo.focus({ preventScroll: true });\n }\n if (handle) {\n close(handle, reason);\n } else {\n early = reason;\n }\n };\n entry.finish = finish;\n\n const view: ɵBfToastView = {\n message: entry.message,\n action: entry.action\n ? {\n label: entry.action.label,\n run: () => {\n if (entry.dismissed) {\n return;\n }\n entry.action?.handler?.();\n finish('action');\n },\n }\n : null,\n hold: (source, held) => {\n if (held) {\n holds.add(source);\n pauseTimer();\n } else {\n holds.delete(source);\n startTimer();\n }\n },\n escape: () => finish('dismiss'),\n };\n\n handle = this.presenter.present(view, entry.request);\n if (early) {\n close(handle, early);\n return;\n }\n doc.addEventListener('focusin', onDocumentFocusIn, true);\n doc.addEventListener('focusout', onDocumentFocusOut, true);\n void this.options.announcer.announce(announcement(entry.message, entry.action), 'polite');\n startTimer();\n }\n\n /** The focused element, or null when focus is on the body (nothing to return to). */\n private focusedElement(): HTMLElement | null {\n const active = this.options.document.activeElement;\n return active instanceof HTMLElement && active !== this.options.document.body ? active : null;\n }\n}\n","import { InjectionToken, type Signal } from '@angular/core';\nimport { type BfOverlayRef } from '../core/overlay-ref';\n\n/**\n * The dialog's own width scale (not `BfSize`, which is a control-height scale): `sm` 24 rem,\n * `md` 32 rem, `lg` 48 rem, `xl` 64 rem — each never wider than the viewport minus a gutter on\n * both sides — and `fullscreen`, edge to edge.\n *\n * @summary The dialog width scale from a 24 rem confirm to an edge-to-edge fullscreen dialog\n * @since 0.3.0\n */\nexport type BfDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';\n\n/**\n * The `data` passed to `BfDialogService.open()`, injectable in the dialog's content.\n *\n * @summary Injection token carrying the data a dialog was opened with, for its content\n * @since 0.3.0\n */\nexport const BF_DIALOG_DATA = new InjectionToken<unknown>('BF_DIALOG_DATA');\n\n/** @internal What `BfDialogService` tells the `bf-dialog` inside its content. */\nexport interface BfDialogContext {\n /** Id the `bf-dialog` title renders with; the panel's `aria-labelledby` points to it. */\n readonly titleId: string;\n readonly size: BfDialogSize;\n}\n\n/** @internal Provided by `BfDialogService` to the dialog's content. */\nexport const BF_DIALOG_CONTEXT = new InjectionToken<BfDialogContext>('BF_DIALOG_CONTEXT');\n\n/**\n * Handle to an open dialog, returned by `BfDialogService.open()` and injectable in the dialog's\n * content (`inject(BfDialogRef)`). `close(result)` plays the exit animation, detaches the dialog\n * and resolves `afterClosed` with `result`; later calls are ignored. Closing with `Escape`, the\n * backdrop or the `bf-dialog` close button resolves `undefined`.\n *\n * @example\n * const ref = inject(BfDialogService).open<RenameDialogComponent, { name: string }, string>(\n * RenameDialogComponent,\n * { data: { name } },\n * );\n * const newName = await ref.afterClosed;\n *\n * @summary Handle on an open dialog that closes it and resolves with its result\n * @since 0.3.0\n */\nexport class BfDialogRef<R = unknown, C = unknown> {\n /** Unique id of the dialog (its overlay's `bf-overlay-N`). */\n readonly id: string;\n /** Resolves with the result given to `close()`, or `undefined`, once the dialog is detached. */\n readonly afterClosed: Promise<R | undefined>;\n /** True once the dialog has been detached. */\n readonly closed: Signal<boolean>;\n\n /** @internal Created by `BfDialogService`; apps never construct it. */\n constructor(\n private readonly overlayRef: BfOverlayRef<unknown>,\n private readonly instance: () => C | null = () => null,\n ) {\n this.id = overlayRef.id;\n // The overlay resolves with whatever close() was given, which is typed R here.\n this.afterClosed = overlayRef.afterClosed as Promise<R | undefined>;\n this.closed = overlayRef.closed;\n }\n\n /** The content component; `null` for a dialog opened from a template. */\n get componentInstance(): C | null {\n return this.instance();\n }\n\n /**\n * Closes the dialog with an optional result; ignored once closing.\n * @param result The value `afterClosed` resolves with.\n */\n close(result?: R): void {\n this.overlayRef.close(result);\n }\n}\n\n/**\n * Context of a template opened with `BfDialogService.open()`: `let-ref` and `let-data=\"data\"`.\n *\n * @summary The context a template opened as a dialog receives: its ref and its data\n * @since 0.3.0\n */\nexport interface BfDialogTemplateContext<D = unknown, R = unknown> {\n /** The dialog's ref (`let-ref`), to close it with a result. */\n $implicit: BfDialogRef<R>;\n /** The `data` the dialog was opened with (`let-data=\"data\"`). */\n data: D;\n}\n","import {\n Component,\n DestroyRef,\n type ElementRef,\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { BF_LABELS, BfIconButtonComponent, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfIconComponent } from '@bitforgehq/ui/icons';\nimport { X } from 'lucide';\nimport { BF_DIALOG_CONTEXT, BfDialogRef, type BfDialogSize } from './dialog-ref';\n\nconst HOST_BASE = 'relative flex flex-col bg-surface text-text';\n\n/* The card sizes cap at their width and at the viewport minus a gutter on each side; fullscreen\n fills the pane that the service stretches over the viewport. A transparent border is invisible\n here but forced colours paints it CanvasText, giving the card an edge once its shadow and the\n scrim behind it both flatten to Canvas. */\nconst CARD =\n 'max-h-[calc(100dvh-2*var(--spacing-gutter))] rounded-card shadow-floating border border-transparent';\nconst SIZE: Record<BfDialogSize, string> = {\n sm: `w-[min(24rem,calc(100vw-2*var(--spacing-gutter)))] ${CARD}`,\n md: `w-[min(32rem,calc(100vw-2*var(--spacing-gutter)))] ${CARD}`,\n lg: `w-[min(48rem,calc(100vw-2*var(--spacing-gutter)))] ${CARD}`,\n xl: `w-[min(64rem,calc(100vw-2*var(--spacing-gutter)))] ${CARD}`,\n fullscreen: 'h-full w-full',\n};\n\n/* With a close button the header always renders (it holds the ×'s row) and keeps clear of it. */\nconst HEADER_BASE = 'flex min-w-0 shrink-0 items-start gap-3 px-6 pt-6';\nconst HEADER: Record<'close' | 'plain', string> = {\n close: `${HEADER_BASE} min-h-14 pe-14`,\n plain: `${HEADER_BASE} empty:hidden`,\n};\n\n/**\n * Layout of a modal dialog opened with `BfDialogService`: a title row, a scrolling body and a\n * footer of actions. The panel is labelled by the title, and the body becomes focusable only\n * while its content overflows, so keyboard users can scroll it (a region named by the title when\n * there is one).\n *\n * @example\n * const ref = inject(BfDialogService).open(RenameDialogComponent, { data: { name } });\n * // RenameDialogComponent template:\n * // <bf-dialog title=\"Rename project\"> …fields…\n * // <div bfSlot=\"footer\">…buttons…</div> </bf-dialog>\n * @summary Desktop modal dialog with a title, scrolling body, footer actions and focus trap\n * @category Overlays\n * @since 0.3.0\n * @slot header More header content after the title, such as a status badge.\n * @slot default The dialog body.\n * @slot footer The actions, aligned at the end.\n */\n@Component({\n selector: 'bf-dialog',\n imports: [BfIconButtonComponent, BfIconComponent],\n // `data-bf-dialog-id` (the dialog's own title id, also without a title) lets test harnesses find\n // the overlay panel this card sits in.\n host: { '[class]': 'hostClasses()', '[attr.data-bf-dialog-id]': 'titleId' },\n template: `\n <div data-dialog-header [class]=\"headerClasses()\">\n @if (title()) {\n <h2 [id]=\"titleId\" class=\"text-heading min-w-0 flex-1 wrap-anywhere\">{{ title() }}</h2>\n }\n <ng-content select=\"[bfSlot=header]\" />\n </div>\n <div\n #body\n data-dialog-body\n class=\"focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto overscroll-contain px-6 py-4 focus-visible:ring-4 focus-visible:outline-hidden focus-visible:ring-inset\"\n [attr.tabindex]=\"overflowing() ? 0 : null\"\n [attr.role]=\"overflowing() && title() ? 'region' : null\"\n [attr.aria-labelledby]=\"overflowing() && title() ? titleId : null\"\n >\n <div #content class=\"flex flex-col gap-4\"><ng-content /></div>\n </div>\n <!-- A projected wrapper (<div bfSlot=\"footer\">) lays out its buttons like the row itself. -->\n <div\n data-dialog-footer\n class=\"flex shrink-0 flex-wrap justify-end gap-2 px-6 pb-6 *:flex *:min-w-0 *:flex-wrap *:justify-end *:gap-2 empty:hidden\"\n >\n <ng-content select=\"[bfSlot=footer]\" />\n </div>\n @if (closeButton()) {\n <!-- Last in DOM order so first-tabbable focus lands on the content, not on the ×. -->\n <bf-icon-button\n data-dialog-close\n class=\"absolute end-3 top-3\"\n variant=\"text\"\n size=\"sm\"\n [label]=\"closeName()\"\n (clicked)=\"close()\"\n >\n <bf-icon [icon]=\"closeIcon\" />\n </bf-icon-button>\n }\n `,\n})\nexport class BfDialogComponent {\n private readonly labels = inject(BF_LABELS);\n private readonly context = inject(BF_DIALOG_CONTEXT, { optional: true });\n private readonly ref = inject(BfDialogRef, { optional: true });\n\n /** Heading of the dialog, rendered as the `h2` the dialog panel is labelled by. */\n readonly title = input('');\n /** Shows a close button (×) at the top end that closes the dialog with no result. */\n readonly closeButton = input(true, { transform: booleanAttribute });\n /** Accessible name of the close button; empty uses `provideBfLabels()`'s `close` (\"Close\"). */\n readonly closeLabel = input('');\n\n /** True while the body's content is taller than the body (it scrolls). */\n protected readonly overflowing = signal(false);\n\n protected readonly titleId = this.context?.titleId ?? uniqueId('bf-dialog-title');\n protected readonly closeIcon = X;\n private readonly size = this.context?.size ?? 'md';\n protected readonly hostClasses = computed(() => `${HOST_BASE} ${SIZE[this.size]}`);\n protected readonly headerClasses = computed(() => HEADER[this.closeButton() ? 'close' : 'plain']);\n protected readonly closeName = computed(() => this.closeLabel() || this.labels.close);\n\n private readonly body = viewChild.required<ElementRef<HTMLElement>>('body');\n private readonly content = viewChild.required<ElementRef<HTMLElement>>('content');\n\n constructor() {\n let observer: ResizeObserver | null = null;\n afterNextRender(() => {\n const body = this.body().nativeElement;\n const measure = (): void => this.overflowing.set(body.scrollHeight > body.clientHeight);\n measure();\n if (typeof ResizeObserver === 'function') {\n observer = new ResizeObserver(measure);\n observer.observe(body);\n observer.observe(this.content().nativeElement);\n }\n });\n inject(DestroyRef).onDestroy(() => observer?.disconnect());\n }\n\n /** Closes the dialog with no result (does nothing outside `BfDialogService`). */\n protected close(): void {\n this.ref?.close();\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n Component,\n InjectionToken,\n Injectable,\n Injector,\n type StaticProvider,\n TemplateRef,\n type Type,\n inject,\n} from '@angular/core';\nimport {\n BF_LABELS,\n BfButtonComponent,\n type BfButtonVariant,\n ɵuniqueId as uniqueId,\n} from '@bitforgehq/ui';\nimport { fadeIn, fadeOut, scaleIn } from '../core/overlay-animations';\nimport { watchPanelHeading } from '../core/overlay-heading';\nimport { type BfComponentOverlayRef, type BfOverlayRef } from '../core/overlay-ref';\nimport { type BfOverlayAutoFocus, BfOverlayService } from '../core/overlay.service';\nimport { BfDialogComponent } from './dialog.component';\nimport {\n BF_DIALOG_CONTEXT,\n BF_DIALOG_DATA,\n BfDialogRef,\n type BfDialogSize,\n type BfDialogTemplateContext,\n} from './dialog-ref';\n\n/**\n * Options of `BfDialogService.open()`.\n *\n * @summary Options of a dialog: its data, width, role, dismissal, focus and injector\n * @since 0.3.0\n */\nexport interface BfDialogConfig<D = unknown> {\n /** Injected into the content as `BF_DIALOG_DATA` (and a template's `data`). */\n data?: D;\n /**\n * Width of the `bf-dialog` in the content (default `md`, 32 rem).\n * @default 'md'\n */\n size?: BfDialogSize;\n /**\n * `alertdialog` for a dialog that demands an answer (default `dialog`).\n * @default 'dialog'\n */\n role?: BfDialogRole;\n /** Accessible name, when the content renders no `bf-dialog` title and no heading. */\n ariaLabel?: string;\n /** Id of the element describing the dialog (e.g. its message). */\n ariaDescribedBy?: string;\n /** A backdrop click closes the dialog (default true for `dialog`, false for `alertdialog`). */\n dismissOnBackdrop?: boolean;\n /**\n * `Escape` closes the dialog (default true); when false the key is claimed and ignored.\n * @default true\n */\n dismissOnEscape?: boolean;\n /**\n * Initial focus (default `first-tabbable`: an `[autofocus]`/`[cdkFocusInitial]` element, else\n * the first tabbable element); `panel` focuses the dialog itself, for long text.\n * @default 'first-tabbable'\n */\n autoFocus?: BfOverlayAutoFocus;\n /**\n * Returns focus to the element that had it before opening (default true).\n * @default true\n */\n restoreFocus?: boolean;\n /**\n * A navigation to another URL path closes the dialog with no result (default true).\n * @default true\n */\n closeOnNavigation?: boolean;\n /** Extra classes on the overlay panel (it always carries `bf-overlay-panel bf-dialog-panel`). */\n panelClass?: string[];\n /**\n * Parent of the content's injector and source of its labels (default the root injector). Pass\n * the opener's `inject(Injector)` so a feature-level `provideBfLabels()` reaches the dialog.\n */\n injector?: Injector;\n}\n\n/**\n * A button of `BfDialogService.confirm()`.\n *\n * @summary One button of a confirm dialog: its answer, its label and its role\n * @since 0.3.0\n */\nexport interface BfConfirmButton {\n /** The value `confirm()` resolves with (default the `label`). */\n id?: string;\n /** Button text. */\n label: string;\n /** `cancel` answers `Escape` and gets initial focus; `destructive` renders `danger`. */\n role?: BfConfirmButtonRole;\n}\n\n/**\n * The ARIA role of a dialog: `dialog`, or `alertdialog` for one that demands an answer.\n *\n * @summary The role a dialog carries, plain or an alert dialog that demands an answer\n * @since 0.3.0\n */\nexport type BfDialogRole = 'dialog' | 'alertdialog';\n\n/**\n * The role of a confirm dialog button: `cancel` answers `Escape`, `destructive` renders `danger`.\n *\n * @summary The role of a confirm dialog button, the cancel answer or a destructive action\n * @since 0.3.0\n */\nexport type BfConfirmButtonRole = 'cancel' | 'destructive';\n\n/**\n * The width of a confirm dialog: `sm` (24 rem) or `md`.\n *\n * @summary The two widths a confirm dialog comes in, small or medium\n * @since 0.3.0\n */\nexport type BfConfirmSize = 'sm' | 'md';\n\n/**\n * Options of `BfDialogService.confirm()`.\n *\n * @summary Options of a confirm dialog: its title, message, buttons and width\n * @since 0.3.0\n */\nexport interface BfConfirmOptions {\n /** Heading, rendered as the `h2` the alert dialog is labelled by. */\n title: string;\n /** Text under the title; the dialog's `aria-describedby` points to it. */\n message?: string;\n /**\n * Buttons, in order, right-aligned (default Cancel and OK from `provideBfLabels()`, ids\n * `cancel` and `ok`).\n */\n buttons?: readonly BfConfirmButton[];\n /**\n * Width (default `sm`, 24 rem).\n * @default 'sm'\n */\n size?: BfConfirmSize;\n /**\n * A navigation to another URL path closes the dialog, resolving the cancel button's answer, or\n * `undefined` without one (default true).\n * @default true\n */\n closeOnNavigation?: boolean;\n /** Source of the default button labels and parent of the content's injector. */\n injector?: Injector;\n}\n\n/** One confirm button as `bf-confirm-dialog` renders it. */\ninterface ConfirmButtonView {\n label: string;\n answer: string;\n variant: BfButtonVariant;\n initial: boolean;\n}\n\n/** What `confirm()` hands `bf-confirm-dialog` as its `BF_DIALOG_DATA`. */\ninterface ConfirmData {\n title: string;\n message: string | undefined;\n messageId: string;\n buttons: ConfirmButtonView[];\n}\n\n/** What the template host renders: the caller's template with the dialog context. */\ninterface DialogTemplate {\n template: TemplateRef<BfDialogTemplateContext<unknown, unknown>>;\n context: BfDialogTemplateContext<unknown, unknown>;\n}\n\nconst BF_DIALOG_TEMPLATE = new InjectionToken<DialogTemplate>('BF_DIALOG_TEMPLATE');\n\n/** Renders a template opened through `BfDialogService` inside the dialog pane. */\n@Component({\n selector: 'bf-dialog-template-host',\n imports: [NgTemplateOutlet],\n host: { style: 'display: contents' },\n template: `<ng-container\n [ngTemplateOutlet]=\"view.template\"\n [ngTemplateOutletContext]=\"view.context\"\n [ngTemplateOutletInjector]=\"injector\"\n />`,\n})\nclass BfDialogTemplateHostComponent {\n protected readonly view = inject(BF_DIALOG_TEMPLATE);\n protected readonly injector = inject(Injector);\n}\n\n/** The alert dialog of `BfDialogService.confirm()`, built from `bf-dialog`. */\n@Component({\n selector: 'bf-confirm-dialog',\n imports: [BfDialogComponent, BfButtonComponent],\n host: { style: 'display: contents' },\n template: `\n <bf-dialog [title]=\"data.title\" [closeButton]=\"false\">\n @if (data.message) {\n <p [id]=\"data.messageId\" class=\"text-body text-text-secondary\">{{ data.message }}</p>\n }\n <div bfSlot=\"footer\">\n @for (button of data.buttons; track $index) {\n <bf-button\n [variant]=\"button.variant\"\n [attr.cdkFocusInitial]=\"button.initial ? '' : null\"\n (clicked)=\"ref.close(button.answer)\"\n >\n {{ button.label }}\n </bf-button>\n }\n </div>\n </bf-dialog>\n `,\n})\nclass BfConfirmDialogComponent {\n protected readonly data = inject(BF_DIALOG_DATA) as ConfirmData;\n protected readonly ref = inject(BfDialogRef) as BfDialogRef<string>;\n}\n\n/**\n * Opens modal dialogs on the overlay core, centred over a backdrop: a component or a template in\n * a pane labelled by its `bf-dialog` title, with focus moved in and trapped, `Escape` and a\n * backdrop click closing it (never the backdrop for an `alertdialog`), focus returned to the\n * opener, document scroll locked and the page behind it `inert`. `confirm()` opens an alert\n * dialog with a title, a message and a row of buttons and resolves with the pressed button's\n * `id ?? label`.\n *\n * @example\n * const ref = inject(BfDialogService).open(RenameDialogComponent, { data: { name } });\n * const answer = await inject(BfDialogService).confirm({\n * title: 'Delete project?',\n * message: 'This cannot be undone.',\n * buttons: [\n * { id: 'cancel', label: 'Cancel', role: 'cancel' },\n * { id: 'delete', label: 'Delete', role: 'destructive' },\n * ],\n * });\n * @since 0.3.0\n * @summary Opens modal dialogs and confirm prompts, centred over the page with focus trapped\n */\n@Injectable({ providedIn: 'root' })\nexport class BfDialogService {\n private readonly overlays = inject(BfOverlayService);\n private readonly injector = inject(Injector);\n\n /**\n * Opens `component` as a dialog; it injects `BfDialogRef` and `BF_DIALOG_DATA`.\n * @param component The component to render; it injects `BfDialogRef` and `BF_DIALOG_DATA`.\n * @param config The dialog's data, width, role, dismissal, focus and injector.\n */\n open<C, D = unknown, R = unknown>(\n component: Type<C>,\n config?: BfDialogConfig<D>,\n ): BfDialogRef<R, C>;\n /**\n * Opens `template` as a dialog; its context is `{ $implicit: ref, data }`.\n * @param template The template to render, with the context `{ $implicit: ref, data }`.\n * @param config The dialog's data, width, role, dismissal, focus and injector.\n */\n open<D = unknown, R = unknown>(\n template: TemplateRef<BfDialogTemplateContext<D, R>>,\n config?: BfDialogConfig<D>,\n ): BfDialogRef<R>;\n open<C, D, R>(\n content: Type<C> | TemplateRef<BfDialogTemplateContext<D, R>>,\n config: BfDialogConfig<D> = {},\n ): BfDialogRef<R, C> {\n return this.openDialog<C, D, R>(content, config, {});\n }\n\n /**\n * Opens an alert dialog (`role=\"alertdialog\"`, described by `message`, no backdrop dismiss)\n * and resolves with the pressed button's `id ?? label`. Focus starts on the `cancel`-role\n * button, else the first button; `Escape` resolves the cancel button's answer, or is ignored\n * when there is none. A navigation to another path resolves the cancel button's answer, else\n * `undefined`.\n * @param options The title, message, buttons and width of the alert dialog.\n * @returns The pressed button's `id ?? label`, or `undefined`.\n */\n confirm(options: BfConfirmOptions): Promise<string | undefined> {\n const injector = options.injector ?? this.injector;\n const labels = injector.get(BF_LABELS);\n const buttons: readonly BfConfirmButton[] = options.buttons?.length\n ? options.buttons\n : [\n { id: 'cancel', label: labels.cancel, role: 'cancel' },\n { id: 'ok', label: labels.ok },\n ];\n const cancelIndex = buttons.findIndex((button) => button.role === 'cancel');\n const initialIndex = cancelIndex >= 0 ? cancelIndex : 0;\n let primaryAssigned = false;\n const views = buttons.map((button, index): ConfirmButtonView => {\n let variant: BfButtonVariant;\n if (button.role === 'cancel') {\n variant = 'outline';\n } else if (button.role === 'destructive') {\n variant = 'danger';\n } else if (!primaryAssigned) {\n variant = 'primary';\n primaryAssigned = true;\n } else {\n variant = 'tonal';\n }\n return {\n label: button.label,\n answer: button.id ?? button.label,\n variant,\n initial: index === initialIndex,\n };\n });\n const messageId = uniqueId('bf-confirm-message');\n const data: ConfirmData = {\n title: options.title,\n message: options.message,\n messageId,\n buttons: views,\n };\n const cancel = views[cancelIndex];\n const ref: BfDialogRef<string, BfConfirmDialogComponent> = this.openDialog(\n BfConfirmDialogComponent,\n {\n data,\n role: 'alertdialog',\n size: options.size ?? 'sm',\n ariaDescribedBy: options.message ? messageId : undefined,\n dismissOnBackdrop: false,\n closeOnNavigation: options.closeOnNavigation,\n injector,\n },\n {\n // Escape answers like the cancel button, or is claimed and ignored without one.\n onEscape: () => {\n if (cancel) {\n ref.close(cancel.answer);\n }\n },\n // A navigation always closes it: with the cancel answer, else with no answer.\n onNavigation: () => ref.close(cancel?.answer),\n },\n );\n return ref.afterClosed;\n }\n\n private openDialog<C, D, R>(\n content: Type<C> | TemplateRef<BfDialogTemplateContext<D, R>>,\n config: BfDialogConfig<D>,\n handlers: { onEscape?: () => void; onNavigation?: () => void },\n ): BfDialogRef<R, C> {\n const size = config.size ?? 'md';\n const role = config.role ?? 'dialog';\n const injector = config.injector ?? this.injector;\n // The shared counter, so an id never repeats one of a bf-dialog rendered in the page.\n const titleId = uniqueId('bf-dialog-title');\n let dialogRef: BfDialogRef<R, C> | null = null;\n let instance: C | null = null;\n\n const providers = (ref: BfOverlayRef<unknown>): StaticProvider[] => {\n const created = new BfDialogRef<R, C>(ref, () => instance);\n dialogRef = created;\n const list: StaticProvider[] = [\n { provide: BfDialogRef, useValue: created },\n { provide: BF_DIALOG_DATA, useValue: config.data },\n { provide: BF_DIALOG_CONTEXT, useValue: { titleId, size } },\n ];\n if (content instanceof TemplateRef) {\n const view: DialogTemplate = {\n template: content,\n context: { $implicit: created, data: config.data },\n };\n list.push({ provide: BF_DIALOG_TEMPLATE, useValue: view });\n }\n return list;\n };\n\n const options = {\n data: config.data,\n position: size === 'fullscreen' ? ('fullscreen' as const) : ('center' as const),\n role,\n ariaLabel: config.ariaLabel,\n ariaLabelledBy: config.ariaLabel ? undefined : titleId,\n ariaDescribedBy: config.ariaDescribedBy,\n dismissOnBackdrop: config.dismissOnBackdrop ?? role === 'dialog',\n dismissOnEscape: config.dismissOnEscape ?? true,\n onEscape: handlers.onEscape,\n closeOnNavigation: config.closeOnNavigation,\n onNavigation: handlers.onNavigation,\n autoFocus: config.autoFocus,\n restoreFocus: config.restoreFocus,\n panelClass: ['bf-dialog-panel', ...(config.panelClass ?? [])],\n injector,\n providers,\n enter: size === 'fullscreen' ? fadeIn : scaleIn,\n exit: fadeOut,\n };\n\n let overlayRef: BfComponentOverlayRef<unknown, R>;\n if (content instanceof TemplateRef) {\n overlayRef = this.overlays.open<BfDialogTemplateHostComponent, R>(\n BfDialogTemplateHostComponent,\n options,\n );\n } else {\n const componentRef = this.overlays.open<C, R>(content, options);\n instance = componentRef.componentRef.instance;\n overlayRef = componentRef;\n }\n if (!dialogRef) {\n throw new Error('BfDialogService: the overlay core did not build the dialog providers');\n }\n this.nameUnlabelledPanel(\n overlayRef.componentRef.location.nativeElement,\n overlayRef.afterClosed,\n config,\n injector,\n );\n return dialogRef;\n }\n\n /**\n * A dialog without an `ariaLabel` whose content rendered no `bf-dialog` title (the core then\n * drops the dangling `aria-labelledby`) is named by the first heading in its content, also one\n * that renders later, and by the `dialog` label until then.\n */\n private nameUnlabelledPanel(\n host: unknown,\n afterClosed: Promise<unknown>,\n config: BfDialogConfig<unknown>,\n injector: Injector,\n ): void {\n const panel =\n host instanceof HTMLElement ? host.closest<HTMLElement>('.bf-overlay-panel') : null;\n if (!panel || config.ariaLabel || panel.hasAttribute('aria-labelledby')) {\n return;\n }\n panel.setAttribute('aria-label', injector.get(BF_LABELS).dialog);\n const stop = watchPanelHeading(panel);\n void afterClosed.then(stop);\n }\n}\n","import { Component, input, output } from '@angular/core';\n\n/**\n * The card `BfDesktopToastService.show()` renders in its notification stack: the message and an\n * optional action button on a surface card. It is not a live region (the service announces each\n * toast once through CDK `LiveAnnouncer`) and has no close button; `Escape` with focus inside it\n * emits `escaped`, which dismisses the toast. Apps do not place it in templates.\n *\n * @example\n * const ref = inject(BfDesktopToastService).show({ message: 'Changes saved' });\n * @summary Desktop notification card in a bottom corner stack of up to three\n * @category Overlays\n * @since 0.3.0\n */\n@Component({\n selector: 'bf-desktop-toast',\n host: {\n class:\n 'bg-surface text-text border border-border rounded-card shadow-floating px-4 py-3 text-body ' +\n 'flex items-start gap-3 w-[min(24rem,calc(100vw-2*var(--spacing-gutter)))]',\n '(keydown)': 'keydown($event)',\n },\n template: `\n <span class=\"min-w-0 flex-1 wrap-anywhere\">{{ message() }}</span>\n @if (actionLabel()) {\n <button\n type=\"button\"\n class=\"text-primary-strong focus-visible:ring-ring rounded-tile -me-2 inline-flex min-h-6 shrink-0 cursor-pointer items-center px-2 font-bold hover:underline focus-visible:ring-4 focus-visible:outline-hidden\"\n (click)=\"actionClicked.emit()\"\n >\n {{ actionLabel() }}\n </button>\n }\n `,\n})\nexport class BfDesktopToastComponent {\n /** Text of the toast; long words wrap. */\n readonly message = input.required<string>();\n /** Text of the action button; empty renders no button. */\n readonly actionLabel = input('');\n /** The action button was clicked. */\n readonly actionClicked = output<void>();\n /** `Escape` was pressed with focus inside the toast (the key is claimed). */\n readonly escaped = output<void>();\n\n /** `Escape` inside the card is the toast's: claimed so no dialog underneath also closes. */\n protected keydown(event: Event): void {\n if (!(event instanceof KeyboardEvent) || event.key !== 'Escape') {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.escaped.emit();\n }\n}\n","import { LiveAnnouncer } from '@angular/cdk/a11y';\nimport { Directionality } from '@angular/cdk/bidi';\nimport { Overlay, type OverlayRef, type PositionStrategy } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n Component,\n type ComponentRef,\n DOCUMENT,\n DestroyRef,\n type EnvironmentProviders,\n InjectionToken,\n Injectable,\n Injector,\n inject,\n input,\n makeEnvironmentProviders,\n output,\n} from '@angular/core';\nimport { BF_LABELS } from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport { fadeOut, fadeUp } from '../core/overlay-animations';\nimport { BfOverlayStack } from '../core/overlay-stack.service';\nimport { type ɵBfToastHandle, ɵBfToastQueue, type ɵBfToastView } from '../toast-core/toast-queue';\nimport { type BfToastAction, type BfToastRef } from '../toast-core/toast-ref';\nimport { BfDesktopToastComponent } from './desktop-toast.component';\n\n/**\n * The viewport corner or edge the desktop toast stack anchors to.\n *\n * @summary The viewport corners and edges a desktop toast stack can anchor to\n * @since 0.3.0\n */\nexport type BfDesktopToastPosition = 'bottom-end' | 'bottom-center' | 'top-end' | 'top-center';\n\n/**\n * App-wide settings of `BfDesktopToastService`; set them with `provideBfDesktopToast()`.\n *\n * @summary App-wide settings of desktop toasts: where they sit and how many show at once\n * @since 0.3.0\n */\nexport interface BfDesktopToastConfig {\n /**\n * Where the stack sits (default `'bottom-end'`: bottom right, bottom left in RTL).\n * @default 'bottom-end'\n */\n position: BfDesktopToastPosition;\n /**\n * How many toasts are visible at once (default 3); later ones wait.\n * @default 3\n */\n maxVisible: number;\n /**\n * Name of the stack's region landmark; empty uses the `notifications` label (\"Notifications\").\n * @default ''\n */\n ariaLabel: string;\n}\n\n/**\n * The library defaults of `BfDesktopToastConfig`.\n *\n * @summary The library defaults of the desktop toast settings, bottom end with three visible\n * @since 0.3.0\n */\nexport const BF_DESKTOP_TOAST_DEFAULTS: Readonly<BfDesktopToastConfig> = Object.freeze({\n position: 'bottom-end',\n maxVisible: 3,\n ariaLabel: '',\n});\n\nconst BF_DESKTOP_TOAST_CONFIG = new InjectionToken<Readonly<BfDesktopToastConfig>>(\n 'BF_DESKTOP_TOAST_CONFIG',\n { providedIn: 'root', factory: () => BF_DESKTOP_TOAST_DEFAULTS },\n);\n\n/**\n * Sets where the desktop toast stack sits, how many toasts it shows at once and its region name,\n * merged over the defaults. Add it to `ApplicationConfig.providers`.\n *\n * @param config The settings to change; any left out keep `BF_DESKTOP_TOAST_DEFAULTS`.\n * @returns The providers of the desktop toast settings.\n * @summary Sets where desktop toasts appear and how many show at once, app-wide\n * @since 0.3.0\n */\nexport function provideBfDesktopToast(\n config: Partial<BfDesktopToastConfig> = {},\n): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: BF_DESKTOP_TOAST_CONFIG,\n useValue: Object.freeze({ ...BF_DESKTOP_TOAST_DEFAULTS, ...config }),\n },\n ]);\n}\n\n/**\n * Options of `BfDesktopToastService.show()`.\n *\n * @summary Options of one desktop toast: its message, an action and its duration\n * @since 0.3.0\n */\nexport interface BfDesktopToastOptions {\n /** Text of the toast. */\n message: string;\n /** An optional action button (the toast then persists by default). */\n action?: BfToastAction;\n /**\n * Milliseconds before the toast auto-dismisses, not counting time the pointer is over the\n * stack or focus is inside it; `0` keeps it until dismissed or its action fires (default 3000\n * without an action, `0` with one).\n * @default 3000\n */\n duration?: number;\n /**\n * Source of the region's labels when this toast opens the stack (default the root injector):\n * pass the feature's `inject(Injector)` so its `provideBfLabels()` names the region.\n */\n injector?: Injector;\n}\n\n/** One rendered toast of the stack. */\ninterface StackItem {\n readonly id: number;\n readonly view: ɵBfToastView;\n}\n\ntype HoldSource = 'pointer' | 'focus';\n\n/** The pane's content: the region landmark holding the visible toasts. */\n@Component({\n selector: 'bf-desktop-toast-stack',\n imports: [BfDesktopToastComponent],\n host: {\n role: 'region',\n '[attr.aria-label]': 'label()',\n class: 'flex flex-col gap-2',\n '(pointerenter)': \"held.emit({ source: 'pointer', held: true })\",\n '(pointerleave)': \"held.emit({ source: 'pointer', held: false })\",\n '(focusin)': \"held.emit({ source: 'focus', held: true })\",\n '(focusout)': 'focusLeft($event)',\n },\n template: `\n @for (item of items(); track item.id) {\n <bf-desktop-toast\n [attr.data-bf-toast]=\"item.id\"\n [message]=\"item.view.message\"\n [actionLabel]=\"item.view.action?.label ?? ''\"\n (actionClicked)=\"item.view.action?.run()\"\n (escaped)=\"item.view.escape()\"\n />\n }\n `,\n})\nclass BfDesktopToastStackComponent {\n readonly label = input('');\n /** In DOM (and visual) order: the newest sits nearest the anchored edge. */\n readonly items = input<readonly StackItem[]>([]);\n readonly held = output<{ source: HoldSource; held: boolean }>();\n\n protected focusLeft(event: FocusEvent): void {\n const to = event.relatedTarget;\n const self = event.currentTarget;\n if (to instanceof Node && self instanceof Node && self.contains(to)) {\n return;\n }\n this.held.emit({ source: 'focus', held: false });\n }\n}\n\n/** The stack's inset from the viewport edges: 24 px plus the safe area (the end edge is the\n * physical left in a right-to-left page). */\nconst INSET = {\n top: 'calc(24px + var(--spacing-safe-top, 0px))',\n bottom: 'calc(24px + var(--spacing-safe-bottom, 0px))',\n endLtr: 'calc(24px + var(--spacing-safe-right, 0px))',\n endRtl: 'calc(24px + var(--spacing-safe-left, 0px))',\n};\n\n/**\n * Shows desktop notifications: `show(options)` adds a `bf-desktop-toast` card to one passive\n * overlay stack (bottom right by default, 24 px in, a `region` landmark named \"Notifications\")\n * and returns a `BfToastRef`. Up to three are visible at once, the newest nearest the anchored\n * edge; later calls wait and show as earlier ones end. A toast auto-dismisses after `duration` ms\n * (default 3000, `'timeout'`); one with an action persists by default until its action\n * (`'action'`), `Escape` inside it or `dismiss()` (`'dismiss'`), and the next `show()` replaces it\n * (`'dismiss'`), visible or waiting. The pointer over the stack or focus inside it pauses every\n * visible toast, which resume with their remaining time. Each toast is announced once, politely,\n * through CDK `LiveAnnouncer`; focus never moves on show, and returns to the element focused\n * last outside a toast that closes while holding it. `F6` from the page moves focus to the\n * action of the newest toast that has one, and `F6` inside the stack moves it back (otherwise\n * the key is left to the browser); it does nothing while a modal overlay is open\n * (`BfOverlayStack.count() > 0`), since that overlay's focus trap must not be escaped. No\n * backdrop, no scroll lock, nothing inert, and a navigation never closes it (a \"Saved\" survives\n * the navigation after the save). Needs `@angular/cdk`, no Capacitor.\n *\n * @example\n * const ref = inject(BfDesktopToastService).show({\n * message: 'Invoice deleted',\n * action: { label: 'Undo', handler: () => restore(invoice) },\n * });\n * const reason = await ref.afterDismissed;\n * @since 0.3.0\n * @summary Shows brief desktop notifications in a stack at a corner of the viewport\n */\n@Injectable({ providedIn: 'root' })\nexport class BfDesktopToastService {\n private readonly overlay = inject(Overlay);\n private readonly injector = inject(Injector);\n private readonly document = inject(DOCUMENT);\n private readonly config = inject(BF_DESKTOP_TOAST_CONFIG);\n private readonly directionality = inject(Directionality);\n private readonly overlayStack = inject(BfOverlayStack);\n /** Where the last `F6` into the stack came from; the next `F6` inside it goes back there. */\n private f6ReturnTo: HTMLElement | null = null;\n private readonly onKeydown = (event: KeyboardEvent): void => this.keydown(event);\n /** Shown toasts, oldest first (a leaving one stays until its exit has played). */\n private items: readonly StackItem[] = [];\n /** What holds the stack now; applied to every toast, also one that shows while held. */\n private readonly holds = new Set<HoldSource>();\n private pane: {\n overlayRef: OverlayRef;\n stack: ComponentRef<BfDesktopToastStackComponent>;\n } | null = null;\n /** Re-applies the position strategy on a `dir` change while the pane lives (N2). */\n private dirSubscription: Subscription | null = null;\n private nextId = 0;\n private readonly queue = new ɵBfToastQueue<BfDesktopToastOptions>(\n { present: (view, options) => this.present(view, options) },\n {\n maxVisible: Math.max(1, Math.floor(this.config.maxVisible)),\n announcer: inject(LiveAnnouncer),\n document: this.document,\n destroyRef: inject(DestroyRef),\n },\n );\n\n constructor() {\n // After the queue's own teardown (registered first) has ended every toast.\n inject(DestroyRef).onDestroy(() => this.disposePane());\n }\n\n /**\n * Queues `options` as a toast; shows it now while fewer than `maxVisible` are visible, else once\n * one ends. Every persistent toast (`duration` 0, the default with an action), visible or\n * waiting, is dismissed first (`'dismiss'`).\n * @param options The toast's message, action, duration and injector.\n * @returns The toast's ref, to dismiss it or await why it ended.\n */\n show(options: BfDesktopToastOptions): BfToastRef {\n return this.queue.show(options);\n }\n\n private present(view: ɵBfToastView, options: BfDesktopToastOptions): ɵBfToastHandle {\n const pane = this.ensurePane(options.injector ?? this.injector);\n const item: StackItem = { id: this.nextId++, view };\n this.items = [...this.items, item];\n this.render();\n for (const source of this.holds) {\n view.hold(source, true);\n }\n const host = pane.overlayRef.overlayElement.querySelector<HTMLElement>(\n `[data-bf-toast=\"${item.id}\"]`,\n );\n if (host) {\n // Fade in while sliding 8 px in from the anchored edge; reduced motion: fade only.\n fadeUp(host, this.anchoredTop() ? '-8px' : '8px');\n }\n return {\n host,\n close: async () => {\n if (host) {\n try {\n await fadeOut(host).finished;\n } catch {\n // A cancelled exit still removes the toast.\n }\n }\n this.remove(item);\n },\n };\n }\n\n private remove(item: StackItem): void {\n if (!this.pane) {\n return;\n }\n this.items = this.items.filter((i) => i !== item);\n if (this.items.length === 0) {\n this.disposePane();\n return;\n }\n this.render();\n // A removed card fires no focusout: release a focus hold that no card holds any more.\n if (\n this.holds.has('focus') &&\n !this.pane.overlayRef.overlayElement.contains(this.document.activeElement)\n ) {\n this.setHold('focus', false);\n }\n }\n\n private render(): void {\n const pane = this.pane;\n if (!pane) {\n return;\n }\n // Newest nearest the anchored edge: last in a bottom stack, first in a top one.\n pane.stack.setInput('items', this.anchoredTop() ? [...this.items].reverse() : this.items);\n pane.stack.changeDetectorRef.detectChanges();\n }\n\n private setHold(source: HoldSource, held: boolean): void {\n if (held === this.holds.has(source)) {\n return;\n }\n if (held) {\n this.holds.add(source);\n } else {\n this.holds.delete(source);\n }\n for (const item of this.items) {\n item.view.hold(source, held);\n }\n }\n\n private ensurePane(injector: Injector): NonNullable<BfDesktopToastService['pane']> {\n if (this.pane) {\n return this.pane;\n }\n const overlayRef = this.overlay.create({\n positionStrategy: this.positionStrategy(),\n // A toast never locks scroll, traps focus or blocks the page.\n scrollStrategy: this.overlay.scrollStrategies.noop(),\n hasBackdrop: false,\n panelClass: 'bf-desktop-toast-pane',\n });\n const stack = overlayRef.attach(\n new ComponentPortal(BfDesktopToastStackComponent, null, injector),\n );\n stack.setInput('label', this.config.ariaLabel || injector.get(BF_LABELS).notifications);\n stack.instance.held.subscribe(({ source, held }) => this.setHold(source, held));\n // Place the pane now, not on the next render, so the first toast enters at its corner.\n overlayRef.updatePosition();\n this.document.addEventListener('keydown', this.onKeydown);\n // A `dir` change while the pane lives moves the anchored end to the new physical side: the\n // overlay's own direction (which GlobalPositionStrategy.apply() reads to pick left vs right)\n // is a one-time snapshot from creation, so it is updated explicitly before reapplying.\n this.dirSubscription = this.directionality.change.subscribe((dir) => {\n overlayRef.setDirection(dir);\n overlayRef.updatePositionStrategy(this.positionStrategy());\n });\n this.pane = { overlayRef, stack };\n return this.pane;\n }\n\n private disposePane(): void {\n if (this.pane) {\n this.document.removeEventListener('keydown', this.onKeydown);\n }\n this.dirSubscription?.unsubscribe();\n this.dirSubscription = null;\n this.pane?.overlayRef.dispose();\n this.pane = null;\n this.items = [];\n this.holds.clear();\n this.f6ReturnTo = null;\n }\n\n /**\n * `F6` (no Ctrl, Alt or Meta) from the page moves focus to the action of the newest toast that\n * has one; `F6` inside the stack moves it back to where it came from. Never moves focus out of\n * an open modal overlay (`BfOverlayStack.count() > 0`): that overlay's focus trap is APG-modal\n * (focus never leaves it), so a toast surfacing behind it stays reachable only by pointer while\n * it is open. Otherwise the key is left to the browser.\n */\n private keydown(event: KeyboardEvent): void {\n const pane = this.pane;\n if (!pane || event.key !== 'F6' || event.ctrlKey || event.altKey || event.metaKey) {\n return;\n }\n const active = this.document.activeElement;\n if (active instanceof Node && pane.overlayRef.overlayElement.contains(active)) {\n const back = this.f6ReturnTo;\n if (back?.isConnected) {\n event.preventDefault();\n this.f6ReturnTo = null;\n back.focus();\n }\n return;\n }\n if (this.overlayStack.count() > 0) {\n return;\n }\n const newest = [...this.items].reverse().find((item) => item.view.action);\n const button = newest\n ? pane.overlayRef.overlayElement.querySelector<HTMLElement>(\n `[data-bf-toast=\"${newest.id}\"] button`,\n )\n : null;\n if (!button) {\n return;\n }\n event.preventDefault();\n this.f6ReturnTo =\n active instanceof HTMLElement && active !== this.document.body ? active : null;\n button.focus();\n }\n\n private anchoredTop(): boolean {\n return this.config.position.startsWith('top');\n }\n\n private positionStrategy(): PositionStrategy {\n const global = this.overlay.position().global();\n const vertical = this.anchoredTop() ? global.top(INSET.top) : global.bottom(INSET.bottom);\n return this.config.position.endsWith('center')\n ? vertical.centerHorizontally()\n : vertical.end(this.directionality.value === 'rtl' ? INSET.endRtl : INSET.endLtr);\n }\n}\n","import { type Direction } from '@angular/cdk/bidi';\nimport { type ConnectedPosition, type Overlay, type OverlayRef } from '@angular/cdk/overlay';\n\n/**\n * Connected positioning shared by every panel anchored to an element: the menu, the popover (and\n * the inputs built on it) and the tooltip. One place decides the gap, the flip order and the\n * overlay config, so all anchored panels move and flip alike. Internal to the overlay entry.\n */\n\n/** Where a panel opens below or above its anchor, aligned to its inline start or end. */\nexport type AnchoredBlockPlacement = 'below-start' | 'below-end' | 'above-start' | 'above-end';\n\n/** Which side of its anchor a small label (a tooltip) sits on; `start`/`end` are logical. */\nexport type AnchoredSidePlacement = 'top' | 'bottom' | 'start' | 'end';\n\n/** Space between a panel and its anchor (px). */\nexport const ANCHOR_GAP = 4;\n/** Space between a tooltip and its anchor (px): a little more, so the pill never touches it. */\nexport const TOOLTIP_GAP = 8;\n/** The smallest distance a panel keeps from the viewport edges (px). */\nexport const VIEWPORT_MARGIN = 8;\n\nconst BELOW_START: ConnectedPosition = {\n originX: 'start',\n originY: 'bottom',\n overlayX: 'start',\n overlayY: 'top',\n offsetY: ANCHOR_GAP,\n};\nconst BELOW_END: ConnectedPosition = {\n originX: 'end',\n originY: 'bottom',\n overlayX: 'end',\n overlayY: 'top',\n offsetY: ANCHOR_GAP,\n};\nconst ABOVE_START: ConnectedPosition = {\n originX: 'start',\n originY: 'top',\n overlayX: 'start',\n overlayY: 'bottom',\n offsetY: -ANCHOR_GAP,\n};\nconst ABOVE_END: ConnectedPosition = {\n originX: 'end',\n originY: 'top',\n overlayX: 'end',\n overlayY: 'bottom',\n offsetY: -ANCHOR_GAP,\n};\n\n/* The preferred position first, then the vertical flip, then the other alignment (and its flip)\n when the panel would overflow the viewport. */\nconst BLOCK_POSITIONS: Record<AnchoredBlockPlacement, readonly ConnectedPosition[]> = {\n 'below-start': [BELOW_START, ABOVE_START, BELOW_END, ABOVE_END],\n 'below-end': [BELOW_END, ABOVE_END, BELOW_START, ABOVE_START],\n 'above-start': [ABOVE_START, BELOW_START, ABOVE_END, BELOW_END],\n 'above-end': [ABOVE_END, BELOW_END, ABOVE_START, BELOW_START],\n};\n\nconst TOP: ConnectedPosition = {\n originX: 'center',\n originY: 'top',\n overlayX: 'center',\n overlayY: 'bottom',\n offsetY: -TOOLTIP_GAP,\n};\nconst BOTTOM: ConnectedPosition = {\n originX: 'center',\n originY: 'bottom',\n overlayX: 'center',\n overlayY: 'top',\n offsetY: TOOLTIP_GAP,\n};\n/* `start`/`end` are logical: the CDK mirrors them under a right-to-left direction. The offset is\n physical, so it is mirrored with them by `sidePositions`. */\nconst START: ConnectedPosition = {\n originX: 'start',\n originY: 'center',\n overlayX: 'end',\n overlayY: 'center',\n offsetX: -TOOLTIP_GAP,\n};\nconst END: ConnectedPosition = {\n originX: 'end',\n originY: 'center',\n overlayX: 'start',\n overlayY: 'center',\n offsetX: TOOLTIP_GAP,\n};\n\n/* The preferred side, then the opposite side, then the two others. */\nconst SIDE_POSITIONS: Record<AnchoredSidePlacement, readonly ConnectedPosition[]> = {\n top: [TOP, BOTTOM, END, START],\n bottom: [BOTTOM, TOP, END, START],\n start: [START, END, TOP, BOTTOM],\n end: [END, START, TOP, BOTTOM],\n};\n\n/** The CDK positions of a block placement, with the flips to try when it overflows. */\nexport function blockPositions(placement: AnchoredBlockPlacement): ConnectedPosition[] {\n return [...BLOCK_POSITIONS[placement]];\n}\n\n/**\n * The CDK positions of a side placement, with the flips to try when it overflows. Under `rtl`\n * the horizontal offsets change sign, because the CDK mirrors the logical `start`/`end` but not\n * the pixel offset.\n */\nexport function sidePositions(\n placement: AnchoredSidePlacement,\n direction: Direction = 'ltr',\n): ConnectedPosition[] {\n return SIDE_POSITIONS[placement].map((position) =>\n direction === 'rtl' && position.offsetX\n ? { ...position, offsetX: -position.offsetX }\n : position,\n );\n}\n\n/** What `createAnchoredOverlay` needs besides the anchor. */\nexport interface AnchoredOverlayOptions {\n /** The positions to try, in order. */\n positions: ConnectedPosition[];\n /** The text direction the logical positions follow. */\n direction: Direction;\n /** Classes on the overlay pane. */\n panelClass: string[];\n}\n\n/** An anchored overlay and the way to move it to other positions while it is open. */\nexport interface AnchoredOverlay {\n /** The CDK overlay. */\n ref: OverlayRef;\n /** Swaps the positions to try (a placement input that changed while open) and re-applies them. */\n setPositions(positions: ConnectedPosition[]): void;\n}\n\n/**\n * Creates an overlay connected to `anchor`: it flips through `positions` when one would overflow,\n * keeps `VIEWPORT_MARGIN` from the edges, never pushes the panel over its anchor and repositions\n * as the page scrolls. No backdrop: anchored panels are non-modal.\n */\nexport function createAnchoredOverlay(\n overlay: Overlay,\n anchor: HTMLElement,\n options: AnchoredOverlayOptions,\n): AnchoredOverlay {\n const strategy = overlay\n .position()\n .flexibleConnectedTo(anchor)\n .withPositions(options.positions)\n .withFlexibleDimensions(false)\n .withPush(false)\n .withViewportMargin(VIEWPORT_MARGIN);\n const ref = overlay.create({\n positionStrategy: strategy,\n scrollStrategy: overlay.scrollStrategies.reposition(),\n direction: options.direction,\n hasBackdrop: false,\n panelClass: options.panelClass,\n });\n return {\n ref,\n setPositions: (positions) => {\n strategy.withPositions(positions);\n ref.updatePosition();\n },\n };\n}\n","import { type ConnectedPosition } from '@angular/cdk/overlay';\nimport { Location } from '@angular/common';\nimport { CDK_MENU, CdkMenuTrigger } from '@angular/cdk/menu';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n SimpleChange,\n effect,\n inject,\n input,\n} from '@angular/core';\nimport { ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { blockPositions } from '../core/anchored-overlay';\nimport { watchPathChange } from '../core/navigation';\n\n/**\n * Where a menu opens against its trigger; `start`/`end` follow the text direction.\n *\n * @summary Where a menu opens against its trigger, above or below, at either end\n * @since 0.3.0\n */\nexport type BfMenuPlacement = 'below-start' | 'below-end' | 'above-start' | 'above-end';\n\n/**\n * Opens a `bf-menu` template from any element on the Angular CDK menu trigger: it sets\n * `aria-haspopup=\"menu\"` and `aria-expanded`, opens on click, `Enter`, `Space` and `ArrowDown`\n * (first item focused) or `ArrowUp` (last item), and takes focus back when the menu closes. A\n * navigation to another URL path closes the open menu (with its submenus); the URL is watched\n * only while the menu is open. On a\n * `bfMenuItem` it opens a submenu beside the item instead (`ArrowRight`, `ArrowLeft` in RTL).\n * `bf-menu-button` wraps it in a styled button.\n *\n * @example\n * <button type=\"button\" [bfMenuTriggerFor]=\"menu\" bfMenuPlacement=\"below-end\">Options</button>\n * <ng-template #menu><bf-menu>…</bf-menu></ng-template>\n * @binding bfMenuTriggerFor The `ng-template` holding the `bf-menu` this element opens.\n * @binding bfMenuTriggerData The context the menu template receives, for a menu shared by many triggers.\n * @binding bfMenuOpened Emits when the menu opens.\n * @binding bfMenuClosed Emits when the menu closes (an item, `Escape`, a click outside or a navigation).\n * @summary Opens a menu from any element with the keyboard and focus rules of menus\n * @since 0.3.0\n */\n@Directive({\n selector: '[bfMenuTriggerFor]',\n hostDirectives: [\n {\n directive: CdkMenuTrigger,\n inputs: ['cdkMenuTriggerFor: bfMenuTriggerFor', 'cdkMenuTriggerData: bfMenuTriggerData'],\n outputs: ['cdkMenuOpened: bfMenuOpened', 'cdkMenuClosed: bfMenuClosed'],\n },\n ],\n})\nexport class BfMenuTriggerDirective {\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /** Where the menu opens (flipping when it would overflow). A submenu always opens beside its\n * item, at the inline end, and ignores it. */\n readonly bfMenuPlacement = input<BfMenuPlacement>('below-start');\n\n constructor() {\n const trigger = inject(CdkMenuTrigger, { self: true });\n const isSubmenu = inject(CDK_MENU, { optional: true }) !== null;\n if (isSubmenu) {\n return;\n }\n // The page the menu acts on is gone: close it, as every non-passive overlay. Watched only\n // while the menu is open, so a table of row-action menus holds no listeners at rest.\n const location = inject(Location);\n let stop: (() => void) | null = null;\n const unwatch = (): void => {\n stop?.();\n stop = null;\n };\n const opened = trigger.opened.subscribe(() => {\n unwatch();\n stop = watchPathChange(location, () => {\n if (trigger.isOpen()) {\n trigger.close();\n }\n });\n });\n const closed = trigger.closed.subscribe(unwatch);\n inject(DestroyRef).onDestroy(() => {\n opened.unsubscribe();\n closed.unsubscribe();\n unwatch();\n });\n let previous: ConnectedPosition[] | undefined;\n effect(() => {\n const positions = blockPositions(this.bfMenuPlacement());\n // effect-justified: CdkMenuTrigger is this directive's own host directive; placement to positions needs a transform no host-directive input mapping does\n trigger.menuPosition = positions;\n if (previous) {\n // Re-applies the position strategy of an overlay created with the old placement.\n // effect-justified: the CDK re-reads menuPosition only in its own ngOnChanges\n trigger.ngOnChanges({ menuPosition: new SimpleChange(previous, positions, false) });\n }\n previous = positions;\n });\n }\n\n /** The trigger element's id (assigned when it has none), which names the menu it opens. It is\n * read when the menu opens: an `[id]` bound on the trigger that changes while the menu is open\n * names the menu from its next opening. */\n labelId(): string {\n if (!this.el.id) {\n this.el.id = uniqueId('bf-menu-trigger');\n }\n return this.el.id;\n }\n}\n","import { CdkMenu, CdkTargetMenuAim } from '@angular/cdk/menu';\nimport { Component, computed, inject, input } from '@angular/core';\nimport { BF_DEFAULTS, type BfSize } from '@bitforgehq/ui';\nimport { BfMenuTriggerDirective } from './menu-trigger.directive';\n\n/**\n * Menu panel of actions, choices and submenus on the Angular CDK menu (role `menu`, arrow keys,\n * Home/End, type-ahead, `Escape` returning focus to the trigger). Put it in an `ng-template` that\n * a `bf-menu-button` or a `[bfMenuTriggerFor]` opens, and fill it with `bfMenuItem`,\n * `bfMenuItemCheckbox`, `bfMenuItemRadio` (in a `bfMenuGroup`) and `bfMenuDivider` parts.\n *\n * @example\n * <bf-menu-button [menu]=\"rowActions\">Actions</bf-menu-button>\n * <ng-template #rowActions>\n * <bf-menu>\n * <button bfMenuItem (triggered)=\"rename()\">Rename</button>\n * <button bfMenuItem [bfMenuTriggerFor]=\"moveTo\">Move to</button>\n * <div bfMenuDivider></div>\n * <button bfMenuItem (triggered)=\"remove()\">Delete</button>\n * </bf-menu>\n * </ng-template>\n * @summary Keyboard-operable menu panel with items, checkbox and radio items, groups and submenus\n * @category Overlays\n * @since 0.3.0\n * @slot default The items (`bfMenuItem`, `bfMenuItemCheckbox`, `bfMenuItemRadio`), groups and dividers.\n */\n@Component({\n selector: 'bf-menu',\n // CdkTargetMenuAim keeps an open submenu while the pointer moves diagonally towards it.\n hostDirectives: [CdkMenu, CdkTargetMenuAim],\n host: {\n // Scrolls past 24 rem or the viewport minus 1 rem each side; p-1 keeps the rounded item\n // highlight inside the card's corners.\n class:\n 'flex flex-col bg-surface text-text border border-border rounded-card shadow-floating p-1 min-w-48 ' +\n 'max-h-[min(24rem,calc(100dvh-2rem))] overflow-y-auto overscroll-contain',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'labelledBy()',\n },\n template: '<ng-content />',\n})\nexport class BfMenuComponent {\n private readonly defaults = inject(BF_DEFAULTS);\n /** The `bfMenuTriggerFor` that opened this menu (a button, or the parent item of a submenu). */\n private readonly trigger = inject(BfMenuTriggerDirective, { optional: true });\n\n /** Row height of its items: sm 32, md 36, lg 44 px (44 px under a coarse pointer); unset follows\n * `provideBfDefaults()` (`controlSize`, `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Accessible name of the menu. Empty: the menu is named by the trigger that opened it (APG). */\n readonly ariaLabel = input('');\n /** Id of the element that names the menu; wins over the trigger. */\n readonly ariaLabelledby = input('');\n\n /** The item height in effect: `size`, else the app's `controlSize` default. */\n readonly resolvedSize = computed(() => this.size() ?? this.defaults.controlSize);\n\n private readonly triggerId = this.trigger?.labelId() ?? null;\n protected readonly labelledBy = computed(\n () => this.ariaLabelledby() || (this.ariaLabel() ? null : this.triggerId),\n );\n}\n","import {\n CdkMenuGroup,\n CdkMenuItem,\n CdkMenuItemCheckbox,\n CdkMenuItemRadio,\n} from '@angular/cdk/menu';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n computed,\n effect,\n inject,\n model,\n output,\n} from '@angular/core';\nimport { BF_DEFAULTS, type BfSize } from '@bitforgehq/ui';\nimport { BfMenuComponent } from './menu.component';\n\n/* One row of a menu. Focus (keyboard or programmatic) and hover share the muted fill; keyboard\n focus adds the ring. Under forced colours the focused row opts out of the adjustment and its\n Highlight fill is the focus indicator (the transparent `focus:outline-hidden` outline stays\n transparent there). A focused disabled row keeps GrayText on Canvas with a Highlight outline\n instead, so it stays legible and reads as disabled. A disabled row stays focusable (APG) but\n gets no hover fill. */\nconst ITEM =\n 'relative flex w-full items-center gap-3 px-3 text-text text-start rounded-field cursor-pointer select-none ' +\n 'focus:outline-hidden no-underline! focus:bg-surface-muted not-aria-disabled:hover:bg-surface-muted ' +\n 'focus-visible:ring-4 focus-visible:ring-ring focus-visible:ring-inset ' +\n 'aria-disabled:text-text-disabled aria-disabled:cursor-not-allowed ' +\n 'forced-colors:aria-disabled:text-[GrayText] forced-colors:focus:forced-color-adjust-none ' +\n 'forced-colors:focus:bg-[Highlight] forced-colors:focus:text-[HighlightText] ' +\n 'forced-colors:focus:aria-disabled:bg-[Canvas] forced-colors:focus:aria-disabled:text-[GrayText] ' +\n 'forced-colors:focus:aria-disabled:outline-2 forced-colors:focus:aria-disabled:-outline-offset-2 ' +\n 'forced-colors:focus:aria-disabled:outline-[Highlight]';\n\n/* Row heights 32/36/44 px. The row projects its label, so the touch size is a min-height under a\n coarse pointer (never an ::after extension), as bf-checkbox rows. */\nconst SIZE: Record<BfSize, string> = {\n sm: 'min-h-8 py-1 text-label-sm pointer-coarse:min-h-hit',\n md: 'min-h-9 py-1.5 text-body pointer-coarse:min-h-hit',\n lg: 'min-h-11 py-2 text-body',\n};\n\n/* A row that opens a submenu shows a chevron at the inline end, pointing there (mirrored under\n dir=\"rtl\"). Drawn with borders in currentColor, so forced colours keep it and it adds nothing\n to the accessible name. */\nconst SUBMENU_CHEVRON =\n \"aria-[haspopup=menu]:after:ms-auto aria-[haspopup=menu]:after:size-2 aria-[haspopup=menu]:after:shrink-0 aria-[haspopup=menu]:after:-translate-x-0.5 aria-[haspopup=menu]:after:rotate-45 rtl:aria-[haspopup=menu]:after:translate-x-0.5 rtl:aria-[haspopup=menu]:after:-rotate-135 aria-[haspopup=menu]:after:border-t-[1.5px] aria-[haspopup=menu]:after:border-r-[1.5px] aria-[haspopup=menu]:after:border-current aria-[haspopup=menu]:after:content-['']\";\n\n/* The 16 px indicator slot before the label: a check mark or a dot, drawn with borders in\n currentColor (visible under forced colours, nothing added to the name). Unchecked rows keep the\n slot with no border at all (forced colours would paint even a transparent one), so labels line\n up. The check is not mirrored in RTL. */\nconst CHECK =\n \"before:mx-[5px] before:h-[11px] before:w-[6px] before:shrink-0 before:-translate-y-px before:rotate-45 before:border-current aria-checked:before:border-r-2 aria-checked:before:border-b-2 before:content-['']\";\nconst DOT =\n \"before:mx-1 before:size-2 before:shrink-0 before:rounded-full before:border-current aria-checked:before:border-4 before:content-['']\";\n\ntype BfMenuItemKind = 'item' | 'checkbox' | 'radio';\nconst INDICATOR: Record<BfMenuItemKind, string> = { item: '', checkbox: CHECK, radio: DOT };\n\n/** The item's classes for the size of its menu (or the app default outside a `bf-menu`). */\nfunction itemClasses(kind: BfMenuItemKind): () => string {\n const menu = inject(BfMenuComponent, { optional: true });\n const defaults = inject(BF_DEFAULTS);\n return computed(() => {\n const size = menu?.resolvedSize() ?? defaults.controlSize;\n return [ITEM, SIZE[size], SUBMENU_CHEVRON, INDICATOR[kind]].filter(Boolean).join(' ');\n });\n}\n\n/**\n * Keyboard and pointer rules of a link item (`a[bfMenuItem]`), listened in the capture phase on\n * the link so they run before the CDK and before the app's `routerLink` on the same element:\n * - `Space` follows the link, like `Enter` (a native `<a>` only answers `Enter`, and the CDK would\n * close the menu without navigating); the synthetic click is the one activation, and held-down\n * auto-repeats are ignored.\n * - While disabled (`aria-disabled=\"true\"`), a click and `Enter` are cancelled and stopped, so\n * neither the browser, the CDK nor `routerLink` (which ignores `defaultPrevented`) navigates.\n */\nfunction linkItemRules(): void {\n const el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n if (el.tagName !== 'A') {\n return;\n }\n const disabled = (): boolean => el.getAttribute('aria-disabled') === 'true';\n const block = (event: Event): void => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n const onClick = (event: MouseEvent): void => {\n if (disabled()) {\n block(event);\n }\n };\n const onKeydown = (event: KeyboardEvent): void => {\n if (event.key === 'Enter' && disabled()) {\n block(event);\n return;\n }\n if (\n event.key !== ' ' ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey ||\n disabled()\n ) {\n return;\n }\n block(event);\n if (!event.repeat) {\n el.click();\n }\n };\n el.addEventListener('click', onClick, { capture: true });\n el.addEventListener('keydown', onKeydown, { capture: true });\n inject(DestroyRef).onDestroy(() => {\n el.removeEventListener('click', onClick, { capture: true });\n el.removeEventListener('keydown', onKeydown, { capture: true });\n });\n}\n\n/**\n * An action row of a `bf-menu` (role `menuitem`), on a native `<button>` or a link (`<a>` with\n * `href` or `routerLink`). Activating it (click, `Enter`, `Space`) emits `triggered`, closes every\n * open menu and returns focus to the trigger. With `[bfMenuTriggerFor]` on the same element it\n * opens a submenu instead (and shows a chevron). A disabled item stays focusable and announces\n * itself as disabled, but does not activate; a disabled link does not navigate either, also with\n * `routerLink`.\n *\n * @example\n * <button bfMenuItem (triggered)=\"rename()\">Rename</button>\n * <a bfMenuItem routerLink=\"/settings\">Settings</a>\n * @binding bfMenuItemDisabled Whether the item is disabled: it stays focusable and announced, but does not activate.\n * @binding bfMenuItemTypeahead The text typeahead matches the item by (default: its text content).\n * @binding triggered Emits when the item is activated (click, `Enter` or `Space`), unless it opens a submenu.\n * @summary An action row of a menu on a native button or link, with keyboard rules\n * @since 0.3.0\n */\n@Directive({\n selector: 'button[bfMenuItem], a[bfMenuItem]',\n hostDirectives: [\n {\n directive: CdkMenuItem,\n inputs: [\n 'cdkMenuItemDisabled: bfMenuItemDisabled',\n 'cdkMenuitemTypeaheadLabel: bfMenuItemTypeahead',\n ],\n outputs: ['cdkMenuItemTriggered: triggered'],\n },\n ],\n host: { '[class]': 'classes()' },\n})\nexport class BfMenuItemDirective {\n protected readonly classes = itemClasses('item');\n\n constructor() {\n linkItemRules();\n }\n}\n\n/**\n * A toggle row of a `bf-menu` (role `menuitemcheckbox`) with a check mark while `checked`.\n * Activating it (click, `Enter`, `Space`) flips its own `checked` (`aria-checked`), emits\n * `triggered`, then `changed` (and `checkedChange`) with the new state, and closes the menu. Bind\n * it two-way, `[(checked)]`, so your state always follows the item.\n *\n * @example\n * <button bfMenuItemCheckbox [(checked)]=\"showGrid\">Show grid</button>\n * @binding bfMenuItemDisabled Whether the item is disabled: it stays focusable and announced, but does not activate.\n * @binding bfMenuItemTypeahead The text typeahead matches the item by (default: its text content).\n * @binding triggered Emits when the item is activated (click, `Enter` or `Space`), before `checked` flips.\n * @summary A menu row that toggles an option on and off with a check mark\n * @since 0.3.0\n */\n@Directive({\n selector: 'button[bfMenuItemCheckbox]',\n hostDirectives: [\n {\n directive: CdkMenuItemCheckbox,\n inputs: [\n 'cdkMenuItemDisabled: bfMenuItemDisabled',\n 'cdkMenuitemTypeaheadLabel: bfMenuItemTypeahead',\n ],\n outputs: ['cdkMenuItemTriggered: triggered'],\n },\n ],\n host: { '[class]': 'classes()' },\n})\nexport class BfMenuItemCheckboxDirective {\n /** Whether the item is checked. The item flips it itself on activation (and emits\n * `checkedChange`), so bind it two-way: `[(checked)]`. */\n readonly checked = model(false);\n /** Emitted with the new state right after the user toggles the item. */\n readonly changed = output<boolean>();\n\n protected readonly classes = itemClasses('checkbox');\n\n constructor() {\n const item = inject(CdkMenuItemCheckbox, { self: true });\n effect(() => {\n // effect-justified: CdkMenuItemCheckbox is this directive's own host directive; its checked is a plain @Input with no signal to derive from\n item.checked = this.checked();\n });\n // The CDK emits `triggered` just before it flips its own `checked` (and never while disabled).\n const subscription = item.triggered.subscribe(() => {\n const next = !item.checked;\n this.checked.set(next);\n this.changed.emit(next);\n });\n inject(DestroyRef).onDestroy(() => subscription.unsubscribe());\n }\n}\n\n/**\n * One choice of a set (role `menuitemradio`) with a dot while `checked`. Put the choices of one\n * set in a `bfMenuGroup`: choosing one (click, `Enter`, `Space`) unchecks the others, emits\n * `triggered` and closes the menu.\n *\n * @example\n * <div bfMenuGroup aria-label=\"Density\">\n * <button bfMenuItemRadio [checked]=\"density() === 'compact'\" (triggered)=\"density.set('compact')\">\n * Compact\n * </button>\n * </div>\n * @binding checked Whether this choice is the selected one of its group (shown with a dot).\n * @binding bfMenuItemDisabled Whether the item is disabled: it stays focusable and announced, but does not activate.\n * @binding bfMenuItemTypeahead The text typeahead matches the item by (default: its text content).\n * @binding triggered Emits when the choice is activated (click, `Enter` or `Space`); set your state here.\n * @summary One choice of a set of exclusive options in a menu, marked with a dot\n * @since 0.3.0\n */\n@Directive({\n selector: 'button[bfMenuItemRadio]',\n hostDirectives: [\n {\n directive: CdkMenuItemRadio,\n inputs: [\n 'cdkMenuItemChecked: checked',\n 'cdkMenuItemDisabled: bfMenuItemDisabled',\n 'cdkMenuitemTypeaheadLabel: bfMenuItemTypeahead',\n ],\n outputs: ['cdkMenuItemTriggered: triggered'],\n },\n ],\n host: { '[class]': 'classes()' },\n})\nexport class BfMenuItemRadioDirective {\n protected readonly classes = itemClasses('radio');\n}\n\n/**\n * A group of menu items (role `group`); radio items in one group are exclusive. Name it with\n * `aria-label` when its items share a topic (\"Density\").\n *\n * @example\n * <div bfMenuGroup aria-label=\"Density\">…radio items…</div>\n * @summary Groups related menu items; radio items in one group exclude each other\n * @since 0.3.0\n */\n@Directive({\n selector: '[bfMenuGroup]',\n hostDirectives: [CdkMenuGroup],\n host: { class: 'flex flex-col' },\n})\nexport class BfMenuGroupDirective {}\n\n/**\n * A line between groups of menu items (role `separator`, not focusable).\n *\n * @example\n * <div bfMenuDivider></div>\n * @summary A line between groups of menu items that keyboard focus never lands on\n * @since 0.3.0\n */\n@Directive({\n selector: '[bfMenuDivider]',\n // A border, not a fill: forced colours keep borders.\n host: { role: 'separator', class: 'my-1 block h-0 border-t border-border' },\n})\nexport class BfMenuDividerDirective {}\n","import {\n Component,\n type TemplateRef,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n} from '@angular/core';\nimport {\n BF_DEFAULTS,\n type BfSize,\n ɵBF_BUTTON_CLASSES,\n ɵBF_ICON_BUTTON_CLASSES,\n ɵPILL_HIT,\n} from '@bitforgehq/ui';\nimport { type BfMenuPlacement, BfMenuTriggerDirective } from '../menu/menu-trigger.directive';\n\n/**\n * The visual style of a `bf-menu-button`: outline, text or tonal, as `bf-button`'s.\n *\n * @summary The three visual styles of a menu button, matching the button styles\n * @since 0.3.0\n */\nexport type BfMenuButtonVariant = 'outline' | 'text' | 'tonal';\n\n/* The look comes from bf-button's and bf-icon-button's own class maps (internal root exports), so\n the three never drift. Only the caret's padding is local: the label button keeps less padding at\n the inline end, where the caret sits. */\nconst BUTTON = ɵBF_BUTTON_CLASSES;\nconst ICON = ɵBF_ICON_BUTTON_CLASSES;\nconst CARET_PADDING: Record<BfSize, string> = {\n sm: 'ps-3.5 pe-3',\n md: 'ps-4.5 pe-4',\n lg: 'ps-6 pe-5',\n};\n\n/**\n * Button that opens a `bf-menu`: a native `<button>` styled like `bf-button` (or `bf-icon-button`\n * with `iconOnly`) in the outline, text or tonal variant, with `aria-haspopup=\"menu\"` and\n * `aria-expanded`. Click, `Enter`, `Space` or `ArrowDown` open the menu with its first item\n * focused, `ArrowUp` with its last; closing it returns focus here.\n *\n * @example\n * <bf-menu-button [menu]=\"actions\">Actions</bf-menu-button>\n * <bf-menu-button [menu]=\"actions\" iconOnly label=\"More actions\" variant=\"text\">\n * <bf-icon [icon]=\"Ellipsis\" />\n * </bf-menu-button>\n * <ng-template #actions>\n * <bf-menu><button bfMenuItem (triggered)=\"rename()\">Rename</button></bf-menu>\n * </ng-template>\n * @summary Styled button that opens a menu, with outline, text, tonal and icon-only looks\n * @category Overlays\n * @since 0.3.0\n * @slot icon-start An icon before the label.\n * @slot default The label (the accessible name of an icon-only button).\n */\n@Component({\n selector: 'bf-menu-button',\n imports: [BfMenuTriggerDirective],\n host: { class: 'inline-flex max-w-full' },\n template: `\n <button\n type=\"button\"\n [bfMenuTriggerFor]=\"menu()\"\n [bfMenuPlacement]=\"placement()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label() || null\"\n [class]=\"classes()\"\n (bfMenuOpened)=\"opened.emit()\"\n (bfMenuClosed)=\"closed.emit()\"\n >\n <ng-content select=\"[bfSlot=icon-start]\" />\n <span data-label [class]=\"labelClasses()\"><ng-content /></span>\n @if (!iconOnly()) {\n <!-- A CSS caret pointing down in either direction (physical borders), in the text colour; nothing in the accessible name. -->\n <span\n data-caret\n class=\"size-2 shrink-0 -translate-y-0.5 rotate-45 border-r-[1.5px] border-b-[1.5px] border-current\"\n ></span>\n }\n </button>\n `,\n})\nexport class BfMenuButtonComponent {\n private readonly defaults = inject(BF_DEFAULTS);\n\n /** The `ng-template` holding the `bf-menu` to open. */\n readonly menu = input.required<TemplateRef<unknown>>();\n /** Visual style: outline (default), text, tonal. */\n readonly variant = input<BfMenuButtonVariant>('outline');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`controlSize`,\n * `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Where the menu opens against the button; it flips when it would overflow. */\n readonly placement = input<BfMenuPlacement>('below-start');\n /** Accessible name (`aria-label`). Required with `iconOnly`; with a visible label leave it empty\n * or start it with the visible text. */\n readonly label = input('');\n /** Square button holding only the projected icon, like `bf-icon-button`; set `label`. */\n readonly iconOnly = input(false, { transform: booleanAttribute });\n /** Disables the button; the menu cannot open. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /** The menu opened. */\n readonly opened = output<void>();\n /** The menu closed. */\n readonly closed = output<void>();\n\n /** The size in effect: `size`, else the app's `controlSize` default. */\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.controlSize);\n\n /* Icon-only: the wrapper drops out of layout so the icon centres in the square. */\n protected readonly labelClasses = computed(() =>\n this.iconOnly() ? 'contents' : 'max-w-full min-w-0 truncate',\n );\n\n protected readonly classes = computed(() => {\n const size = this.resolvedSize();\n const variant = this.variant();\n const hit = ɵPILL_HIT[size][variant === 'outline' ? 'bordered' : 'plain'];\n if (this.iconOnly()) {\n const pressed = this.disabled() ? '' : ICON.pressed[variant];\n return [ICON.base, ICON.variant[variant], pressed, ICON.size[size], hit]\n .filter(Boolean)\n .join(' ');\n }\n // bf-button sets its pointer through its loading state; a menu button is never loading.\n const padding = variant === 'text' ? BUTTON.textPadding[size] : CARET_PADDING[size];\n const pressed = this.disabled() ? '' : BUTTON.pressed[variant];\n return [\n BUTTON.base,\n 'cursor-pointer',\n BUTTON.variant[variant],\n pressed,\n BUTTON.size[size],\n padding,\n hit,\n ]\n .filter(Boolean)\n .join(' ');\n });\n}\n","import { Component, booleanAttribute, computed, inject, input, model, output } from '@angular/core';\nimport { BF_LABELS, type BfColorScheme, type BfSize } from '@bitforgehq/ui';\nimport { BfMenuComponent } from '../menu/menu.component';\nimport { BfMenuItemRadioDirective } from '../menu/menu-item.directive';\nimport { type BfMenuPlacement } from '../menu/menu-trigger.directive';\nimport {\n BfMenuButtonComponent,\n type BfMenuButtonVariant,\n} from '../menu-button/menu-button.component';\n\n/** One choice of the theme menu: the scheme and its label. */\ninterface ThemeChoice {\n readonly value: BfColorScheme;\n readonly label: string;\n}\n\n/**\n * The colour scheme switch as a menu button, for a crowded top bar: a `bf-menu-button` whose menu\n * holds System, Light and Dark as radio items, the current one marked with a dot. It holds a\n * `BfColorScheme` and injects no service, so the app binds its own state, usually\n * `BfColorSchemeService.scheme` (`BfPlatformService.theme` in a Capacitor app). The button shows\n * `label` (\"Theme\") next to an optional icon, or only the icon with `iconOnly`.\n *\n * @example\n * <bf-theme-menu-button iconOnly variant=\"text\" [(value)]=\"colorScheme.scheme\">\n * <bf-icon bfSlot=\"icon\" [icon]=\"colorScheme.dark() ? Moon : Sun\" />\n * </bf-theme-menu-button>\n * @summary Menu button with System, Light and Dark radio items bound to the colour scheme\n * @category Overlays\n * @since 0.3.1\n * @slot icon The icon before the label, or the whole button with `iconOnly` (a sun or a moon).\n */\n@Component({\n selector: 'bf-theme-menu-button',\n imports: [BfMenuButtonComponent, BfMenuComponent, BfMenuItemRadioDirective],\n host: { class: 'inline-flex max-w-full' },\n template: `\n <bf-menu-button\n [menu]=\"themeMenu\"\n [variant]=\"variant()\"\n [size]=\"size()\"\n [placement]=\"placement()\"\n [iconOnly]=\"iconOnly()\"\n [label]=\"iconOnly() ? resolvedLabel() : ''\"\n >\n <!-- display: contents, so the projected icon is the button's own flex item. -->\n <span bfSlot=\"icon-start\" class=\"contents\"><ng-content select=\"[bfSlot=icon]\" /></span>\n @if (!iconOnly()) {\n {{ resolvedLabel() }}\n }\n </bf-menu-button>\n <ng-template #themeMenu>\n <bf-menu>\n @for (choice of choices; track choice.value) {\n <button\n bfMenuItemRadio\n [checked]=\"value() === choice.value\"\n (triggered)=\"select(choice.value)\"\n >\n {{ choice.label }}\n </button>\n }\n </bf-menu>\n </ng-template>\n `,\n})\nexport class BfThemeMenuButtonComponent {\n private readonly labels = inject(BF_LABELS);\n\n /** The colour scheme choice; bind it two-way, usually to `BfColorSchemeService.scheme`. */\n readonly value = model<BfColorScheme>('system');\n /** The button's text, and its accessible name with `iconOnly`; empty falls back to the `theme`\n * label. */\n readonly label = input('');\n /** Square button holding only the projected icon, like `bf-icon-button`. */\n readonly iconOnly = input(false, { transform: booleanAttribute });\n /** Visual style: outline (default), text, tonal. */\n readonly variant = input<BfMenuButtonVariant>('outline');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`controlSize`,\n * `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Where the menu opens against the button; it flips when it would overflow. */\n readonly placement = input<BfMenuPlacement>('below-end');\n\n /** Emitted with the new choice right after the user picks another item. */\n readonly changed = output<BfColorScheme>();\n\n /** The three items, labelled by `themeSystem`, `themeLight` and `themeDark`. */\n protected readonly choices: readonly ThemeChoice[] = [\n { value: 'system', label: this.labels.themeSystem },\n { value: 'light', label: this.labels.themeLight },\n { value: 'dark', label: this.labels.themeDark },\n ];\n /** The button's name: `label`, else the `theme` label. */\n protected readonly resolvedLabel = computed(() => this.label() || this.labels.theme);\n\n /**\n * Takes the item the user picked; the current choice again changes nothing.\n * @internal\n */\n select(next: BfColorScheme): void {\n if (next === this.value()) {\n return;\n }\n this.value.set(next);\n this.changed.emit(next);\n }\n}\n","import { Component, input } from '@angular/core';\n\n/**\n * The small dark pill of a tooltip (role `tooltip`). A `[bfTooltip]` directive renders it in the\n * CDK overlay beside its element while the pointer rests on it or it has keyboard focus, so you\n * rarely place it yourself; the directive is how you add a tooltip.\n *\n * @example\n * <bf-icon-button label=\"Copy link\" bfTooltip=\"Copy link\"><bf-icon [icon]=\"link\" /></bf-icon-button>\n * @summary Short hint beside a control on hover or keyboard focus, for desktop\n * @category Overlays\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-tooltip',\n host: {\n role: 'tooltip',\n // The transparent border becomes visible under forced colours, where the fill is dropped.\n class:\n 'block max-w-xs rounded-field border border-transparent bg-tooltip px-2.5 py-1 ' +\n 'text-label-xs text-on-tooltip shadow-raised break-words',\n },\n template: '{{ text() }}',\n})\nexport class BfTooltipComponent {\n /** The tooltip's text: a few words that repeat or explain the control's name. */\n readonly text = input('');\n}\n","import { Directionality } from '@angular/cdk/bidi';\nimport { Overlay } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n DOCUMENT,\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n inject,\n input,\n inputBinding,\n} from '@angular/core';\nimport { ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport {\n type AnchoredOverlay,\n createAnchoredOverlay,\n sidePositions,\n} from '../core/anchored-overlay';\nimport { prefersReducedMotion } from '../core/motion';\nimport { animateOrSettle } from '../core/overlay-animations';\nimport { TABBABLE } from '../core/overlay.service';\nimport { BfTooltipComponent } from './tooltip.component';\n\n/**\n * Which side of its element a tooltip sits on; `start` and `end` follow the text direction.\n *\n * @summary Which side of its element a tooltip sits on: top, bottom, start or end\n * @since 0.3.1\n */\nexport type BfTooltipPlacement = 'top' | 'bottom' | 'start' | 'end';\n\n/** How long the pointer rests on the element before the tooltip shows (ms). */\nconst SHOW_DELAY = 500;\n/** How long a tooltip stays after the pointer leaves, so it can move onto the tooltip (ms). */\nconst HIDE_GRACE = 100;\n/** The tooltip's fade-in (ms); none under reduced motion. */\nconst FADE = 120;\n\n/**\n * Shows a short `bf-tooltip` beside an element: after a 500 ms rest of a fine pointer, at once on\n * keyboard focus. It hides when the pointer leaves (it stays while the pointer moves onto the\n * tooltip itself), on blur and on `Escape`, and while it shows, the focusable element (the host,\n * or the first control inside it, so it works on a `bf-icon-button`) is described by it\n * (`aria-describedby`). Nothing shows under a coarse pointer (touch), so never put information\n * only in a tooltip. The tooltip flips to the opposite side when it would overflow the viewport.\n *\n * @example\n * <bf-icon-button label=\"Archive\" bfTooltip=\"Archive\" bfTooltipPlacement=\"bottom\">\n * <bf-icon [icon]=\"archive\" />\n * </bf-icon-button>\n * @summary Adds a hover and keyboard-focus tooltip to any control on desktop\n * @since 0.3.1\n */\n@Directive({\n selector: '[bfTooltip]',\n host: {\n // Marks the host for the /testing harness, whatever binds the text.\n 'data-bf-tooltip': '',\n '(mouseenter)': 'pointerEntered()',\n '(mouseleave)': 'pointerLeft()',\n '(focusin)': 'focused($event)',\n '(focusout)': 'hide()',\n },\n})\nexport class BfTooltipDirective {\n private readonly overlay = inject(Overlay);\n private readonly document = inject(DOCUMENT);\n private readonly injector = inject(Injector);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /** The tooltip's text; empty shows no tooltip. */\n readonly bfTooltip = input.required<string>();\n /** The side it shows on (flipping when it would overflow), read each time it shows. */\n readonly bfTooltipPlacement = input<BfTooltipPlacement>('top');\n\n private readonly id = uniqueId('bf-tooltip');\n private anchored: AnchoredOverlay | null = null;\n private described: HTMLElement | null = null;\n private keys: Subscription | null = null;\n private showTimer: ReturnType<typeof setTimeout> | null = null;\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.hide());\n }\n\n /** Whether the tooltip is showing. */\n isShown(): boolean {\n return this.anchored !== null;\n }\n\n /** Shows the tooltip now (no delay). Does nothing under a coarse pointer or without text. */\n show(): void {\n this.clearTimers();\n if (this.anchored || !this.bfTooltip() || this.coarsePointer()) {\n return;\n }\n const direction = this.dir?.value ?? 'ltr';\n const anchored = createAnchoredOverlay(this.overlay, this.host, {\n positions: sidePositions(this.bfTooltipPlacement(), direction),\n direction,\n panelClass: ['bf-tooltip-panel'],\n });\n const tooltip = anchored.ref.attach(\n new ComponentPortal(BfTooltipComponent, null, this.injector, null, [\n inputBinding('text', this.bfTooltip),\n ]),\n );\n tooltip.changeDetectorRef.detectChanges();\n const pill = tooltip.location.nativeElement as HTMLElement;\n pill.id = this.id;\n const pane = anchored.ref.overlayElement;\n // A pointer moving from the element onto the tooltip keeps it (WCAG 1.4.13, hoverable).\n pane.addEventListener('mouseenter', () => this.clearTimers());\n pane.addEventListener('mouseleave', () => this.pointerLeft());\n // Escape hides it wherever focus is (1.4.13, dismissible). The CDK hands a key to the topmost\n // overlay that listens, so a dialog or popover underneath stays open; cancelling the key keeps\n // it from a CloseWatcher. No host listener: it would hide first and let the key fall through.\n this.keys = anchored.ref.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.hide();\n }\n });\n this.anchored = anchored;\n this.describe();\n anchored.ref.updatePosition();\n if (!prefersReducedMotion(this.document.defaultView)) {\n animateOrSettle(pane, [{ opacity: 0 }, { opacity: 1 }], { duration: FADE, easing: 'linear' });\n }\n }\n\n /** Hides the tooltip now and cancels a pending show. */\n hide(): void {\n this.clearTimers();\n this.keys?.unsubscribe();\n this.keys = null;\n this.undescribe();\n this.anchored?.ref.dispose();\n this.anchored = null;\n }\n\n /** @internal */\n pointerEntered(): void {\n if (this.anchored) {\n this.clearTimers();\n return;\n }\n this.clearTimers();\n this.showTimer = setTimeout(() => this.show(), SHOW_DELAY);\n }\n\n /** @internal */\n pointerLeft(): void {\n if (this.showTimer !== null) {\n this.clearTimers();\n return;\n }\n if (this.anchored && this.hideTimer === null) {\n this.hideTimer = setTimeout(() => this.hide(), HIDE_GRACE);\n }\n }\n\n /** @internal */\n focused(event: FocusEvent): void {\n // Keyboard focus only: a click that focuses the control leaves it to the hover delay.\n if (event.target instanceof HTMLElement && this.focusVisible(event.target)) {\n this.show();\n }\n }\n\n private clearTimers(): void {\n if (this.showTimer !== null) {\n clearTimeout(this.showTimer);\n this.showTimer = null;\n }\n if (this.hideTimer !== null) {\n clearTimeout(this.hideTimer);\n this.hideTimer = null;\n }\n }\n\n /** No hover under a coarse pointer: a tooltip would only show after a tap, over the finger. */\n private coarsePointer(): boolean {\n const view = this.document.defaultView;\n return typeof view?.matchMedia === 'function' && view.matchMedia('(pointer: coarse)').matches;\n }\n\n private focusVisible(el: HTMLElement): boolean {\n try {\n return el.matches(':focus-visible');\n } catch {\n // An engine without :focus-visible (an old jsdom): treat every focus as keyboard focus.\n return true;\n }\n }\n\n /** The element the tooltip describes: the host when it takes focus, else its first control. */\n private describedElement(): HTMLElement {\n if (this.host.matches(TABBABLE) || this.host.hasAttribute('tabindex')) {\n return this.host;\n }\n return this.host.querySelector<HTMLElement>(TABBABLE) ?? this.host;\n }\n\n private describe(): void {\n const el = this.describedElement();\n const ids = (el.getAttribute('aria-describedby') ?? '').split(/\\s+/).filter(Boolean);\n if (!ids.includes(this.id)) {\n el.setAttribute('aria-describedby', [...ids, this.id].join(' '));\n }\n this.described = el;\n }\n\n private undescribe(): void {\n const el = this.described;\n if (!el) {\n return;\n }\n const ids = (el.getAttribute('aria-describedby') ?? '')\n .split(/\\s+/)\n .filter((id) => id && id !== this.id);\n if (ids.length) {\n el.setAttribute('aria-describedby', ids.join(' '));\n } else {\n el.removeAttribute('aria-describedby');\n }\n this.described = null;\n }\n}\n","import { Component, computed, inject, input } from '@angular/core';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n type BfSize,\n ɵBF_ICON_BUTTON_CLASSES,\n ɵBF_NAV,\n ɵPILL_HIT,\n} from '@bitforgehq/ui';\nimport { BfTooltipDirective } from '../tooltip/tooltip.directive';\n\n/* bf-icon-button's text variant, from its own class maps (internal root exports), so the toggle\n and an icon button beside it never drift. */\nconst ICON = ɵBF_ICON_BUTTON_CLASSES;\n\n/* Shown inside a sidebar, nothing elsewhere (a top nav, or no nav at all). */\ntype BfSidebarToggleForm = 'shown' | 'none';\nconst HOST: Record<BfSidebarToggleForm, string> = {\n shown: 'inline-flex',\n none: 'hidden',\n};\n\n/**\n * The collapse button of a `bf-sidebar`: a text icon button placed inside the sidebar (usually in\n * its header or footer) that flips the sidebar between full width and an icon rail. Its name and\n * tooltip say what the next press does (\"Collapse sidebar\", \"Expand sidebar\"), `aria-expanded`\n * follows the sidebar and `aria-controls` points at its `nav`. It shows the `collapse-icon` slot\n * while expanded and the `expand-icon` slot while collapsed. It reads and writes the sidebar's\n * `collapsed` model, so `[(collapsed)]` on the sidebar sees every press. Outside a `bf-sidebar`\n * (in a `bf-top-nav`, or on its own) it renders nothing.\n *\n * @example\n * <bf-sidebar [(collapsed)]=\"sidebarState.collapsed\">\n * <bf-sidebar-toggle bfSlot=\"footer\">\n * <bf-icon bfSlot=\"collapse-icon\" [icon]=\"PanelLeftClose\" />\n * <bf-icon bfSlot=\"expand-icon\" [icon]=\"PanelLeftOpen\" />\n * </bf-sidebar-toggle>\n * </bf-sidebar>\n * @summary Icon button inside a sidebar that collapses it to an icon rail and back\n * @category Navigation\n * @since 0.3.2\n * @slot collapse-icon The icon shown while the sidebar is expanded (a panel closing).\n * @slot expand-icon The icon shown while the sidebar is an icon rail (a panel opening).\n */\n@Component({\n selector: 'bf-sidebar-toggle',\n imports: [BfTooltipDirective],\n host: { '[class]': 'hostClasses()' },\n template: `\n @if (nav) {\n <button\n type=\"button\"\n [class]=\"classes()\"\n [attr.aria-label]=\"name()\"\n [attr.aria-expanded]=\"!collapsed()\"\n [attr.aria-controls]=\"nav.navId\"\n [bfTooltip]=\"name()\"\n [bfTooltipPlacement]=\"collapsed() ? 'end' : 'top'\"\n (click)=\"toggle()\"\n >\n <!-- display: contents, so the projected icon is the button's own flex item. -->\n <span [class]=\"collapsed() ? 'hidden' : 'contents'\"\n ><ng-content select=\"[bfSlot=collapse-icon]\"\n /></span>\n <span [class]=\"collapsed() ? 'contents' : 'hidden'\"\n ><ng-content select=\"[bfSlot=expand-icon]\"\n /></span>\n </button>\n }\n `,\n})\nexport class BfSidebarToggleComponent {\n private readonly defaults = inject(BF_DEFAULTS);\n private readonly labels = inject(BF_LABELS);\n private readonly host = inject(ɵBF_NAV, { optional: true });\n /** The enclosing sidebar's context; null outside a sidebar (a top nav never collapses). */\n protected readonly nav = this.host?.layout === 'sidebar' ? this.host : null;\n\n /** Height step: sm 32, md 40, lg 48 px (square); unset follows `provideBfDefaults()`\n * (`controlSize`, `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n\n /** Whether the sidebar is an icon rail now. */\n protected readonly collapsed = computed(() => this.nav?.collapsed() ?? false);\n /** What the next press does: `sidebarExpand` while collapsed, else `sidebarCollapse`. */\n protected readonly name = computed(() =>\n this.collapsed() ? this.labels.sidebarExpand : this.labels.sidebarCollapse,\n );\n protected readonly hostClasses = computed(() => HOST[this.nav ? 'shown' : 'none']);\n protected readonly classes = computed(() => {\n const size = this.size() ?? this.defaults.controlSize;\n return [ICON.base, ICON.variant.text, ICON.pressed.text, ICON.size[size], ɵPILL_HIT[size].plain]\n .filter(Boolean)\n .join(' ');\n });\n\n /**\n * Flips the sidebar between full width and an icon rail.\n * @internal\n */\n toggle(): void {\n this.nav?.setCollapsed(!this.collapsed());\n }\n}\n","import { InjectionToken, type Signal } from '@angular/core';\nimport { type BfOverlayRef } from '../core/overlay-ref';\n\n/**\n * The side panel's width scale: `sm` 360 px, `md` 480 px, `lg` 640 px (22.5, 30 and 40 rem), each\n * never wider than the viewport.\n *\n * @summary The side panel widths, from a 360 px detail list to a 640 px form\n * @since 0.3.1\n */\nexport type BfSidePanelWidth = 'sm' | 'md' | 'lg';\n\n/**\n * The `data` passed to `BfSidePanelService.open()`, injectable in the panel's content.\n *\n * @summary Injection token carrying the data a side panel was opened with, for its content\n * @since 0.3.1\n */\nexport const BF_SIDE_PANEL_DATA = new InjectionToken<unknown>('BF_SIDE_PANEL_DATA');\n\n/** @internal What `BfSidePanelService` tells the `bf-side-panel` inside its content. */\nexport interface BfSidePanelContext {\n /** Id the `bf-side-panel` title renders with; the panel's `aria-labelledby` points to it. */\n readonly titleId: string;\n readonly width: BfSidePanelWidth;\n}\n\n/** @internal Provided by `BfSidePanelService` to the panel's content. */\nexport const BF_SIDE_PANEL_CONTEXT = new InjectionToken<BfSidePanelContext>(\n 'BF_SIDE_PANEL_CONTEXT',\n);\n\n/**\n * Handle to an open side panel, returned by `BfSidePanelService.open()` and injectable in the\n * panel's content (`inject(BfSidePanelRef)`). `close(result)` slides the panel out, detaches it\n * and resolves `afterClosed` with `result`; later calls are ignored. Closing with `Escape`, the\n * backdrop, the `bf-side-panel` close button or a navigation resolves `undefined`.\n *\n * @example\n * const ref = inject(BfSidePanelService).open<InvoiceDetailsComponent, Invoice, Invoice>(\n * InvoiceDetailsComponent,\n * { data: invoice },\n * );\n * const saved = await ref.afterClosed;\n *\n * @summary Handle on an open side panel that closes it and resolves with its result\n * @since 0.3.1\n */\nexport class BfSidePanelRef<R = unknown, C = unknown> {\n /** Unique id of the side panel (its overlay's `bf-overlay-N`). */\n readonly id: string;\n /** Resolves with the result given to `close()`, or `undefined`, once the panel is detached. */\n readonly afterClosed: Promise<R | undefined>;\n /** True once the panel has been detached. */\n readonly closed: Signal<boolean>;\n\n /** @internal Created by `BfSidePanelService`; apps never construct it. */\n constructor(\n private readonly overlayRef: BfOverlayRef<unknown>,\n private readonly instance: () => C | null = () => null,\n ) {\n this.id = overlayRef.id;\n // The overlay resolves with whatever close() was given, which is typed R here.\n this.afterClosed = overlayRef.afterClosed as Promise<R | undefined>;\n this.closed = overlayRef.closed;\n }\n\n /** The content component; `null` for a panel opened from a template. */\n get componentInstance(): C | null {\n return this.instance();\n }\n\n /**\n * Closes the panel with an optional result; ignored once closing.\n * @param result The value `afterClosed` resolves with.\n */\n close(result?: R): void {\n this.overlayRef.close(result);\n }\n}\n\n/**\n * Context of a template opened with `BfSidePanelService.open()`: `let-ref` and `let-data=\"data\"`.\n *\n * @summary The context a template opened as a side panel receives: its ref and its data\n * @since 0.3.1\n */\nexport interface BfSidePanelTemplateContext<D = unknown, R = unknown> {\n /** The panel's ref (`let-ref`), to close it with a result. */\n $implicit: BfSidePanelRef<R>;\n /** The `data` the panel was opened with (`let-data=\"data\"`). */\n data: D;\n}\n","import {\n Component,\n DestroyRef,\n type ElementRef,\n afterNextRender,\n computed,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { BF_LABELS, BfIconButtonComponent, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfIconComponent } from '@bitforgehq/ui/icons';\nimport { X } from 'lucide';\nimport { BF_SIDE_PANEL_CONTEXT, BfSidePanelRef, type BfSidePanelWidth } from './side-panel-ref';\n\n/* Full height of the pane the service stretches over the viewport, against its inline end edge:\n a start border (the line between page and panel, also in forced colours) and the floating\n shadow cast onto the page. */\nconst HOST_BASE =\n 'relative flex h-full flex-col border-s border-border bg-surface text-text shadow-floating';\nconst WIDTH: Record<BfSidePanelWidth, string> = {\n sm: 'w-[min(22.5rem,100vw)]',\n md: 'w-[min(30rem,100vw)]',\n lg: 'w-[min(40rem,100vw)]',\n};\n\n/**\n * Layout of a side panel opened with `BfSidePanelService`: a title row with a close button, a\n * scrolling body and a footer of actions kept at the bottom. The panel is labelled by the title,\n * and the body becomes focusable only while its content overflows, so keyboard users can scroll\n * it (a region named by the title).\n *\n * @example\n * const ref = inject(BfSidePanelService).open(InvoiceDetailsComponent, { data: invoice });\n * // InvoiceDetailsComponent template:\n * // <bf-side-panel title=\"INV-204\"> …details…\n * // <div bfSlot=\"footer\">…buttons…</div> </bf-side-panel>\n * @summary Desktop panel sliding in from the end edge, with a title, body and footer actions\n * @category Overlays\n * @since 0.3.1\n * @slot header More header content after the title, such as a status badge.\n * @slot default The panel body.\n * @slot footer The actions, aligned at the end and kept at the bottom.\n */\n@Component({\n selector: 'bf-side-panel',\n imports: [BfIconButtonComponent, BfIconComponent],\n // `data-bf-side-panel-id` (the panel's own title id, also without a title) lets test harnesses\n // find the overlay panel this one sits in.\n host: { '[class]': 'hostClasses()', '[attr.data-bf-side-panel-id]': 'titleId' },\n template: `\n <div\n data-side-panel-header\n class=\"border-border flex min-h-16 min-w-0 shrink-0 items-center gap-3 border-b py-4 ps-6 pe-14\"\n >\n @if (title()) {\n <h2 [id]=\"titleId\" class=\"text-heading min-w-0 flex-1 wrap-anywhere\">{{ title() }}</h2>\n }\n <ng-content select=\"[bfSlot=header]\" />\n </div>\n <div\n #body\n data-side-panel-body\n class=\"focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto overscroll-contain px-6 py-4 focus-visible:ring-4 focus-visible:outline-hidden focus-visible:ring-inset\"\n [attr.tabindex]=\"overflowing() ? 0 : null\"\n [attr.role]=\"overflowing() && title() ? 'region' : null\"\n [attr.aria-labelledby]=\"overflowing() && title() ? titleId : null\"\n >\n <div #content class=\"flex flex-col gap-4\"><ng-content /></div>\n </div>\n <!-- A projected wrapper (<div bfSlot=\"footer\">) lays out its buttons like the row itself. -->\n <div\n data-side-panel-footer\n class=\"border-border flex shrink-0 flex-wrap justify-end gap-2 border-t px-6 py-4 *:flex *:min-w-0 *:flex-wrap *:justify-end *:gap-2 empty:hidden\"\n >\n <ng-content select=\"[bfSlot=footer]\" />\n </div>\n <!-- Last in DOM order so first-tabbable focus lands on the content, not on the ×. -->\n <bf-icon-button\n data-side-panel-close\n class=\"absolute end-3 top-4\"\n variant=\"text\"\n size=\"sm\"\n [label]=\"closeName()\"\n (clicked)=\"close()\"\n >\n <bf-icon [icon]=\"closeIcon\" />\n </bf-icon-button>\n `,\n})\nexport class BfSidePanelComponent {\n private readonly labels = inject(BF_LABELS);\n private readonly context = inject(BF_SIDE_PANEL_CONTEXT, { optional: true });\n private readonly ref = inject(BfSidePanelRef, { optional: true });\n\n /** Heading of the panel, rendered as the `h2` the side panel is labelled by. */\n readonly title = input('');\n /** Accessible name of the close button; empty uses `provideBfLabels()`'s `close` (\"Close\"). */\n readonly closeLabel = input('');\n\n /** True while the body's content is taller than the body (it scrolls). */\n protected readonly overflowing = signal(false);\n\n protected readonly titleId = this.context?.titleId ?? uniqueId('bf-side-panel-title');\n protected readonly closeIcon = X;\n private readonly width = this.context?.width ?? 'md';\n protected readonly hostClasses = computed(() => `${HOST_BASE} ${WIDTH[this.width]}`);\n protected readonly closeName = computed(() => this.closeLabel() || this.labels.close);\n\n private readonly body = viewChild.required<ElementRef<HTMLElement>>('body');\n private readonly content = viewChild.required<ElementRef<HTMLElement>>('content');\n\n constructor() {\n let observer: ResizeObserver | null = null;\n afterNextRender(() => {\n const body = this.body().nativeElement;\n const measure = (): void => this.overflowing.set(body.scrollHeight > body.clientHeight);\n measure();\n if (typeof ResizeObserver === 'function') {\n observer = new ResizeObserver(measure);\n observer.observe(body);\n observer.observe(this.content().nativeElement);\n }\n });\n inject(DestroyRef).onDestroy(() => observer?.disconnect());\n }\n\n /** Closes the panel with no result (does nothing outside `BfSidePanelService`). */\n protected close(): void {\n this.ref?.close();\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n Component,\n InjectionToken,\n Injectable,\n Injector,\n type StaticProvider,\n TemplateRef,\n type Type,\n inject,\n} from '@angular/core';\nimport { BF_LABELS, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { slideInFromEnd, slideOutToEnd } from '../core/overlay-animations';\nimport { watchPanelHeading } from '../core/overlay-heading';\nimport { type BfComponentOverlayRef, type BfOverlayRef } from '../core/overlay-ref';\nimport { BfOverlayService } from '../core/overlay.service';\nimport {\n BF_SIDE_PANEL_CONTEXT,\n BF_SIDE_PANEL_DATA,\n BfSidePanelRef,\n type BfSidePanelTemplateContext,\n type BfSidePanelWidth,\n} from './side-panel-ref';\n\n/**\n * Options of `BfSidePanelService.open()`.\n *\n * @summary Options of a side panel: its data, width, modality, name and injector\n * @since 0.3.1\n */\nexport interface BfSidePanelConfig<D = unknown> {\n /** Injected into the content as `BF_SIDE_PANEL_DATA` (and a template's `data`). */\n data?: D;\n /**\n * Width of the `bf-side-panel` in the content (default `md`, 480 px), capped at the viewport.\n * @default 'md'\n */\n width?: BfSidePanelWidth;\n /**\n * A modal panel (default true) has a scrim, traps focus and makes the page behind it inert;\n * `false` keeps the page usable beside it.\n * @default true\n */\n modal?: boolean;\n /** Accessible name, when the content renders no `bf-side-panel` title and no heading. */\n ariaLabel?: string;\n /**\n * Parent of the content's injector and source of its labels (default the root injector). Pass\n * the opener's `inject(Injector)` so a feature-level `provideBfLabels()` reaches the panel.\n */\n injector?: Injector;\n}\n\n/** What the template host renders: the caller's template with the side panel context. */\ninterface SidePanelTemplate {\n template: TemplateRef<BfSidePanelTemplateContext<unknown, unknown>>;\n context: BfSidePanelTemplateContext<unknown, unknown>;\n}\n\nconst BF_SIDE_PANEL_TEMPLATE = new InjectionToken<SidePanelTemplate>('BF_SIDE_PANEL_TEMPLATE');\n\n/** Renders a template opened through `BfSidePanelService` inside the panel's pane. */\n@Component({\n selector: 'bf-side-panel-template-host',\n imports: [NgTemplateOutlet],\n host: { style: 'display: contents' },\n template: `<ng-container\n [ngTemplateOutlet]=\"view.template\"\n [ngTemplateOutletContext]=\"view.context\"\n [ngTemplateOutletInjector]=\"injector\"\n />`,\n})\nclass BfSidePanelTemplateHostComponent {\n protected readonly view = inject(BF_SIDE_PANEL_TEMPLATE);\n protected readonly injector = inject(Injector);\n}\n\n/** Marks the pane while it slides out, so a harness reads a closing panel as closed. */\nfunction exitPanel(el: HTMLElement): Animation {\n el.setAttribute('data-bf-closing', '');\n return slideOutToEnd(el);\n}\n\n/**\n * Opens side panels on the overlay core: a component or template in a full-height pane that\n * slides in from the inline end edge (the right, the left under `dir=\"rtl\"`; a cross-fade under\n * reduced motion), labelled by its `bf-side-panel` title, with focus moved in, `Escape` closing\n * it and focus returned to the opener. A modal panel (the default) adds a scrim that closes it on\n * a click, traps focus, locks document scroll and makes the page behind it `inert`, as a dialog\n * does; `modal: false` keeps the page usable and scrollable beside it, and `Escape` closes it\n * only while focus is inside it. A navigation to another URL path closes it. Desktop only.\n *\n * @example\n * const ref = inject(BfSidePanelService).open(InvoiceDetailsComponent, {\n * data: invoice,\n * width: 'lg',\n * });\n * const saved = await ref.afterClosed;\n * @since 0.3.1\n * @summary Opens a full-height panel from the end edge, modal or beside the page\n */\n@Injectable({ providedIn: 'root' })\nexport class BfSidePanelService {\n private readonly overlays = inject(BfOverlayService);\n private readonly injector = inject(Injector);\n\n /**\n * Opens `component` as a side panel; it injects `BfSidePanelRef` and `BF_SIDE_PANEL_DATA`.\n * @param component The component to render; it injects `BfSidePanelRef` and `BF_SIDE_PANEL_DATA`.\n * @param config The panel's data, width, modality, name and injector.\n */\n open<C, D = unknown, R = unknown>(\n component: Type<C>,\n config?: BfSidePanelConfig<D>,\n ): BfSidePanelRef<R, C>;\n /**\n * Opens `template` as a side panel; its context is `{ $implicit: ref, data }`.\n * @param template The template to render, with the context `{ $implicit: ref, data }`.\n * @param config The panel's data, width, modality, name and injector.\n */\n open<D = unknown, R = unknown>(\n template: TemplateRef<BfSidePanelTemplateContext<D, R>>,\n config?: BfSidePanelConfig<D>,\n ): BfSidePanelRef<R>;\n open<C, D, R>(\n content: Type<C> | TemplateRef<BfSidePanelTemplateContext<D, R>>,\n config: BfSidePanelConfig<D> = {},\n ): BfSidePanelRef<R, C> {\n const width = config.width ?? 'md';\n const injector = config.injector ?? this.injector;\n // The shared counter, so an id never repeats one of a bf-side-panel rendered in the page.\n const titleId = uniqueId('bf-side-panel-title');\n let panelRef: BfSidePanelRef<R, C> | null = null;\n let instance: C | null = null;\n\n const providers = (ref: BfOverlayRef<unknown>): StaticProvider[] => {\n const created = new BfSidePanelRef<R, C>(ref, () => instance);\n panelRef = created;\n const list: StaticProvider[] = [\n { provide: BfSidePanelRef, useValue: created },\n { provide: BF_SIDE_PANEL_DATA, useValue: config.data },\n { provide: BF_SIDE_PANEL_CONTEXT, useValue: { titleId, width } },\n ];\n if (content instanceof TemplateRef) {\n const view: SidePanelTemplate = {\n template: content,\n context: { $implicit: created, data: config.data },\n };\n list.push({ provide: BF_SIDE_PANEL_TEMPLATE, useValue: view });\n }\n return list;\n };\n\n const options = {\n data: config.data,\n position: 'end' as const,\n modal: config.modal ?? true,\n ariaLabel: config.ariaLabel,\n ariaLabelledBy: config.ariaLabel ? undefined : titleId,\n panelClass: ['bf-side-panel-panel'],\n injector,\n providers,\n enter: slideInFromEnd,\n exit: exitPanel,\n };\n\n let overlayRef: BfComponentOverlayRef<unknown, R>;\n if (content instanceof TemplateRef) {\n overlayRef = this.overlays.open<BfSidePanelTemplateHostComponent, R>(\n BfSidePanelTemplateHostComponent,\n options,\n );\n } else {\n const componentRef = this.overlays.open<C, R>(content, options);\n instance = componentRef.componentRef.instance;\n overlayRef = componentRef;\n }\n if (!panelRef) {\n throw new Error('BfSidePanelService: the overlay core did not build the panel providers');\n }\n this.nameUnlabelledPanel(\n overlayRef.componentRef.location.nativeElement,\n overlayRef.afterClosed,\n config,\n injector,\n );\n return panelRef;\n }\n\n /**\n * A panel without an `ariaLabel` whose content rendered no `bf-side-panel` title (the core then\n * drops the dangling `aria-labelledby`) is named by the first heading in its content, also one\n * that renders later, and by the `dialog` label until then.\n */\n private nameUnlabelledPanel(\n host: unknown,\n afterClosed: Promise<unknown>,\n config: BfSidePanelConfig<unknown>,\n injector: Injector,\n ): void {\n const panel =\n host instanceof HTMLElement ? host.closest<HTMLElement>('.bf-overlay-panel') : null;\n if (!panel || config.ariaLabel || panel.hasAttribute('aria-labelledby')) {\n return;\n }\n panel.setAttribute('aria-label', injector.get(BF_LABELS).dialog);\n const stop = watchPanelHeading(panel);\n void afterClosed.then(stop);\n }\n}\n","import { Directionality } from '@angular/cdk/bidi';\nimport { Overlay } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport { Location } from '@angular/common';\nimport {\n DOCUMENT,\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n type TemplateRef,\n ViewContainerRef,\n afterRenderEffect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport {\n type AnchoredOverlay,\n blockPositions,\n createAnchoredOverlay,\n} from '../core/anchored-overlay';\nimport { watchPathChange } from '../core/navigation';\nimport { watchPanelHeading } from '../core/overlay-heading';\nimport { TABBABLE, firstTabbable } from '../core/overlay.service';\n\n/**\n * Where a popover opens against its trigger; `start`/`end` follow the text direction.\n *\n * @summary Where a popover opens against its trigger, above or below, at either end\n * @since 0.3.1\n */\nexport type BfPopoverPlacement = 'below-start' | 'below-end' | 'above-start' | 'above-end';\n\n/**\n * Opens an `ng-template` (usually a `bf-popover`) as a non-modal panel anchored to the element:\n * a click (`Enter` or `Space` on a button) toggles it, focus moves to its first control, `Tab`\n * moves through it and on out (closing it, past the trigger), and `Escape`, a click outside or a\n * navigation to another URL path close it, returning focus to the trigger. The control it\n * decorates (the host, or the first control inside it, such as a `bf-button`'s button) carries\n * `aria-haspopup=\"dialog\"`, `aria-expanded` and, while open, `aria-controls`. Export it as\n * `bfPopoverTrigger` to open and close it from code or from inside the panel.\n *\n * @example\n * <button type=\"button\" [bfPopoverTriggerFor]=\"filters\" #trigger=\"bfPopoverTrigger\">Filters</button>\n * <ng-template #filters>\n * <bf-popover><h2>Filters</h2>…<button (click)=\"trigger.close()\">Apply</button></bf-popover>\n * </ng-template>\n * @summary Opens an anchored, non-modal popover panel from any element or button\n * @since 0.3.1\n */\n@Directive({\n selector: '[bfPopoverTriggerFor]',\n exportAs: 'bfPopoverTrigger',\n // The attribute marks the host for the /testing harness, whatever binds the template.\n host: { 'data-bf-popover-trigger': '', '(click)': 'toggle()' },\n})\nexport class BfPopoverTriggerDirective {\n private readonly overlay = inject(Overlay);\n private readonly document = inject(DOCUMENT);\n private readonly injector = inject(Injector);\n private readonly viewContainer = inject(ViewContainerRef);\n private readonly location = inject(Location);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /** The `ng-template` holding the panel (a `bf-popover`) this element opens. */\n readonly bfPopoverTriggerFor = input.required<TemplateRef<unknown>>();\n /** Where the panel opens (flipping when it would overflow), read each time it opens. */\n readonly bfPopoverPlacement = input<BfPopoverPlacement>('below-start');\n /** Accessible name of the panel. Empty: its first heading names it, else the trigger. */\n readonly bfPopoverLabel = input('');\n /** Emits when the panel opens. */\n readonly bfPopoverOpened = output<void>();\n /** Emits when the panel closes (`Escape`, a click outside, `Tab` out, a navigation or code). */\n readonly bfPopoverClosed = output<void>();\n\n private readonly openState = signal(false);\n /** Whether the panel is open. */\n readonly isOpen = this.openState.asReadonly();\n /** The id the `bf-popover` panel takes, which the trigger's `aria-controls` points at. */\n readonly panelId = uniqueId('bf-popover');\n\n private anchored: AnchoredOverlay | null = null;\n private subscriptions: Subscription[] = [];\n private stopNavigation: (() => void) | null = null;\n private stopHeading: (() => void) | null = null;\n\n constructor() {\n afterRenderEffect({\n write: () => {\n const control = this.control();\n const open = this.isOpen();\n control.setAttribute('aria-haspopup', 'dialog');\n control.setAttribute('aria-expanded', String(open));\n if (open) {\n control.setAttribute('aria-controls', this.panelId);\n } else {\n control.removeAttribute('aria-controls');\n }\n },\n });\n inject(DestroyRef).onDestroy(() => this.teardown());\n }\n\n /** Opens the panel and moves focus into it; does nothing while it is open. */\n open(): void {\n if (this.anchored) {\n return;\n }\n const direction = this.dir?.value ?? 'ltr';\n const anchored = createAnchoredOverlay(this.overlay, this.host, {\n positions: blockPositions(this.bfPopoverPlacement()),\n direction,\n panelClass: ['bf-popover-panel'],\n });\n this.anchored = anchored;\n anchored.ref.attach(\n new TemplatePortal(this.bfPopoverTriggerFor(), this.viewContainer, undefined, this.injector),\n );\n const pane = anchored.ref.overlayElement;\n this.subscriptions = [\n // The CDK hands a key to the topmost overlay that listens: a dialog underneath stays open.\n anchored.ref.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n // Cancelled, so it never reaches a CloseWatcher as a second close request.\n event.preventDefault();\n this.close();\n }\n }),\n anchored.ref.outsidePointerEvents().subscribe((event) => {\n // A click on the trigger toggles it closed itself.\n if (event.target instanceof Node && this.host.contains(event.target)) {\n return;\n }\n // Focus returns only when it would otherwise be lost: a click on another control keeps it.\n const active = this.document.activeElement;\n this.close(!active || active === this.document.body || pane.contains(active));\n }),\n ];\n pane.addEventListener('keydown', (event) => this.tabbed(event, pane));\n this.stopNavigation = watchPathChange(this.location, () => this.close(false));\n this.openState.set(true);\n const panel = pane.querySelector<HTMLElement>('bf-popover') ?? pane;\n this.name(panel);\n (firstTabbable(panel) ?? panel).focus({ preventScroll: true });\n this.bfPopoverOpened.emit();\n }\n\n /**\n * Closes the panel; does nothing while it is closed.\n * @param restoreFocus Moves focus back to the trigger (default true).\n */\n close(restoreFocus = true): void {\n if (!this.anchored) {\n return;\n }\n this.teardown();\n this.openState.set(false);\n if (restoreFocus) {\n this.control().focus({ preventScroll: true });\n }\n this.bfPopoverClosed.emit();\n }\n\n /** Opens the panel when it is closed, closes it when it is open. */\n toggle(): void {\n if (this.anchored) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /** The id of the trigger's control (assigned when it has none), which names a bare panel. */\n private labelId(): string {\n const control = this.control();\n if (!control.id) {\n control.id = uniqueId('bf-popover-trigger');\n }\n return control.id;\n }\n\n /** The element that takes focus and carries the ARIA state: the host, or its first control. */\n private control(): HTMLElement {\n if (this.host.matches(TABBABLE) || this.host.hasAttribute('tabindex')) {\n return this.host;\n }\n return this.host.querySelector<HTMLElement>(TABBABLE) ?? this.host;\n }\n\n /**\n * `Tab` is not trapped: past the panel's last control it closes the panel and continues from the\n * trigger (the browser moves on to the control after it); `Shift+Tab` before the first control\n * closes it onto the trigger.\n */\n private tabbed(event: KeyboardEvent, pane: HTMLElement): void {\n if (event.key !== 'Tab') {\n return;\n }\n const stops = Array.from(pane.querySelectorAll<HTMLElement>(TABBABLE)).filter(\n (el) => !el.closest('[inert]') && !el.hidden,\n );\n const active = this.document.activeElement;\n const leaving = event.shiftKey\n ? !stops.length || active === stops[0] || active === pane.firstElementChild\n : !stops.length || active === stops[stops.length - 1];\n if (!leaving) {\n return;\n }\n if (event.shiftKey) {\n event.preventDefault();\n }\n // Focus the trigger before the browser's own Tab step, which then starts from it.\n this.close(true);\n }\n\n /**\n * Names the panel before focus moves in, so it is announced with its name: `bfPopoverLabel`\n * (bound by `bf-popover` itself), else its first heading (watched while it has none yet), else\n * the trigger.\n */\n private name(panel: HTMLElement): void {\n if (this.bfPopoverLabel()) {\n return;\n }\n panel.setAttribute('aria-labelledby', this.labelId());\n this.stopHeading = watchPanelHeading(panel);\n }\n\n private teardown(): void {\n this.stopHeading?.();\n this.stopHeading = null;\n this.subscriptions.forEach((s) => s.unsubscribe());\n this.subscriptions = [];\n this.stopNavigation?.();\n this.stopNavigation = null;\n this.anchored?.ref.dispose();\n this.anchored = null;\n }\n}\n","import { Component, computed, inject } from '@angular/core';\nimport { ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfPopoverTriggerDirective } from './popover-trigger.directive';\n\n/**\n * The popover panel's surface without its padding, shared with the picker panels of the date and\n * time inputs. It scrolls past the viewport minus 1 rem each side; the panel itself takes focus\n * only when it holds no control, so it draws no ring. Internal to the overlay entry.\n */\nexport const POPOVER_SURFACE =\n 'block bg-surface text-text border border-border rounded-card shadow-floating ' +\n 'max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto overscroll-contain ' +\n 'outline-hidden';\n\n/**\n * Non-modal panel anchored to a trigger, for filters, details or a small form (role `dialog`).\n * Put it in an `ng-template` that a `[bfPopoverTriggerFor]` opens; it takes the id the trigger's\n * `aria-controls` points at and is named by `bfPopoverLabel`, else by its first heading, else by\n * the trigger.\n *\n * @example\n * <button type=\"button\" [bfPopoverTriggerFor]=\"details\">Details</button>\n * <ng-template #details>\n * <bf-popover><h2 class=\"text-label\">Delivery</h2><p>Arrives Thursday.</p></bf-popover>\n * </ng-template>\n * @summary Anchored, non-modal panel for filters, details or a small form\n * @category Overlays\n * @since 0.3.1\n * @slot default The panel's content: a heading, text, fields and actions.\n */\n@Component({\n selector: 'bf-popover',\n host: {\n role: 'dialog',\n tabindex: '-1',\n '[id]': 'id',\n '[attr.aria-label]': 'label() || null',\n class: `${POPOVER_SURFACE} p-card`,\n },\n template: '<ng-content />',\n})\nexport class BfPopoverComponent {\n /** The `bfPopoverTriggerFor` that opened this panel. */\n private readonly trigger = inject(BfPopoverTriggerDirective, { optional: true });\n\n protected readonly id = this.trigger?.panelId ?? uniqueId('bf-popover');\n protected readonly label = computed(() => this.trigger?.bfPopoverLabel() ?? '');\n}\n","import { Directionality } from '@angular/cdk/bidi';\nimport { Overlay } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n DestroyRef,\n Injector,\n type Signal,\n type Type,\n ViewContainerRef,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { type BfCompareWith, type BfSize, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport {\n type AnchoredOverlay,\n blockPositions,\n createAnchoredOverlay,\n} from '../core/anchored-overlay';\n\n/**\n * One choice of `bf-combobox` and `bf-multi-combobox`; `value` is any type (a string by default).\n *\n * @summary One combobox choice with its value, label, description, group and disabled flag\n * @since 0.3.1\n */\nexport interface BfComboboxOption<T = string> {\n /** The value the combobox takes when this option is picked. */\n value: T;\n /** The option's text in the list, and the field's text once it is picked. */\n label: string;\n /** A second, muted line under the label (an email, a role). */\n description?: string;\n /** Whether this option cannot be picked; it stays in the list, skipped by the arrow keys. */\n disabled?: boolean;\n /** The heading this option is listed under; options with the same group are listed together. */\n group?: string;\n}\n\n/**\n * Whether an option matches the typed query (the `filter` of the comboboxes). Called only for a\n * query that is not empty.\n *\n * @summary Decides whether a combobox option matches the text typed into the field\n * @since 0.3.1\n */\nexport type BfComboboxFilter<T = string> = (option: BfComboboxOption<T>, query: string) => boolean;\n\n/** Lower case without accents (`É` → `e`), so `\"zoe\"` finds `\"Zoë\"`. */\nexport function foldText(text: string): string {\n return text.normalize('NFD').replace(/\\p{M}/gu, '').toLocaleLowerCase();\n}\n\n/** The default `filter`: the option's label contains the query, ignoring case and accents. */\nexport function labelContains(option: BfComboboxOption<unknown>, query: string): boolean {\n return foldText(option.label).includes(foldText(query.trim()));\n}\n\n/** A visible option and the ids the listbox gives it. */\nexport interface ComboboxItem<T> {\n /** The option. */\n option: BfComboboxOption<T>;\n /** Its position in `options`, which keys its id. */\n index: number;\n /** The option element's id, which `aria-activedescendant` names while it is active. */\n id: string;\n}\n\n/** A run of visible options under one heading (`label` null: the ungrouped options). */\nexport interface ComboboxSection<T> {\n /** The group's heading, or null for the options without a group. */\n label: string | null;\n /** The heading's id, which names the `role=\"group\"`. */\n id: string;\n /** The options in the section, in their `options` order. */\n items: ComboboxItem<T>[];\n}\n\n/** What the combobox core reads from the component that owns it. */\nexport interface ComboboxHost<T> {\n /** The options to choose from. */\n options: Signal<readonly BfComboboxOption<T>[]>;\n /** The match function, or null for no local filtering. */\n filter: Signal<BfComboboxFilter<T> | null>;\n /** Whether an option is picked (shows `aria-selected` and the check mark). */\n isSelected(option: BfComboboxOption<T>): boolean;\n /** Picks an option the user chose with `Enter` or a click. */\n pick(item: ComboboxItem<T>): void;\n /** The element the panel is anchored to and as wide as: the field box. */\n anchor(): HTMLElement;\n /** The panel component to open (the internal listbox). */\n panel: Type<unknown>;\n /** The listbox's accessible name: `aria-label` and `aria-labelledby` values. */\n listboxLabel: Signal<string | null>;\n /** The listbox's `aria-labelledby` value. */\n listboxLabelledby: Signal<string | null>;\n /** Whether the list allows several picks (`aria-multiselectable`). */\n multiple: boolean;\n /** Whether a request is running: the panel shows a spinner row. */\n loading: Signal<boolean>;\n /** The empty row's text. */\n emptyText: Signal<string>;\n /** The size of the field, which the option rows follow. */\n size: Signal<BfSize>;\n /** Emits the query each time the user changes it. */\n queried(query: string): void;\n}\n\n/**\n * The state and behaviour `bf-combobox` and `bf-multi-combobox` share: the query, the filtered and\n * grouped options, the active option, the keyboard and the anchored panel. Created in a field\n * initializer of the component (it injects the overlay and the component's view container), so\n * each component keeps its own typed value model. Internal to the overlay entry.\n */\nexport class ComboboxCore<T> {\n private readonly overlay = inject(Overlay);\n private readonly injector = inject(Injector);\n private readonly viewContainer = inject(ViewContainerRef);\n private readonly dir = inject(Directionality, { optional: true });\n\n /** The listbox's id, which the input's `aria-controls` names. */\n readonly listboxId = uniqueId('bf-combobox-listbox');\n\n /** The text typed since the last pick; null while the field shows its value. */\n private readonly queryState = signal<string | null>(null);\n readonly query = this.queryState.asReadonly();\n private readonly openState = signal(false);\n /** Whether the panel is open. */\n readonly isOpen = this.openState.asReadonly();\n /** The `index` of the active option, null for none. */\n private readonly activeIndex = signal<number | null>(null);\n\n /** The options that match the query, ungrouped first, then each group in first-seen order. */\n readonly sections = computed<ComboboxSection<T>[]>(() => {\n const query = this.query()?.trim() ?? '';\n const filter = this.host.filter();\n const ungrouped: ComboboxSection<T> = { label: null, id: `${this.listboxId}-g`, items: [] };\n const groups = new Map<string, ComboboxSection<T>>();\n this.host.options().forEach((option, index) => {\n if (query && filter && !filter(option, query)) {\n return;\n }\n const item = { option, index, id: `${this.listboxId}-${index}` };\n if (option.group === undefined || option.group === '') {\n ungrouped.items.push(item);\n return;\n }\n let section = groups.get(option.group);\n if (!section) {\n section = { label: option.group, id: `${this.listboxId}-g${groups.size}`, items: [] };\n groups.set(option.group, section);\n }\n section.items.push(item);\n });\n return [ungrouped, ...groups.values()].filter((section) => section.items.length > 0);\n });\n /** The visible options in list order: the order the arrow keys move through. */\n readonly items = computed(() => this.sections().flatMap((section) => section.items));\n /** The active option while it is visible and the panel is open. */\n readonly active = computed(() => {\n const index = this.activeIndex();\n return this.isOpen() ? (this.items().find((item) => item.index === index) ?? null) : null;\n });\n /** `aria-controls`: the listbox while it is rendered. */\n readonly controls = computed(() =>\n this.isOpen() && this.items().length > 0 ? this.listboxId : null,\n );\n\n private anchored: AnchoredOverlay | null = null;\n private subscriptions: Subscription[] = [];\n\n constructor(readonly host: ComboboxHost<T>) {\n inject(DestroyRef).onDestroy(() => this.teardown());\n }\n\n /**\n * Sets the typed text and emits `queried` when it changed; null shows the value again.\n * @param query The text, or null.\n */\n setQuery(query: string | null): void {\n const before = this.queryState() ?? '';\n this.queryState.set(query);\n if ((query ?? '') !== before) {\n this.host.queried(query ?? '');\n }\n }\n\n /**\n * The user typed: the text becomes the query, the panel opens and the first match is active.\n * @param text The input's text.\n */\n typed(text: string): void {\n this.setQuery(text);\n this.open();\n this.activeIndex.set(text.trim() ? (this.firstEnabled(this.items())?.index ?? null) : null);\n }\n\n /** Opens the panel anchored to the field; does nothing while it is open. */\n open(): void {\n if (this.anchored) {\n return;\n }\n const anchor = this.host.anchor();\n const anchored = createAnchoredOverlay(this.overlay, anchor, {\n positions: blockPositions('below-start'),\n direction: this.dir?.value ?? 'ltr',\n panelClass: ['bf-combobox-panel'],\n });\n this.anchored = anchored;\n anchored.ref.updateSize({ width: anchor.getBoundingClientRect().width || undefined });\n const panel = anchored.ref.attach(\n new ComponentPortal(this.host.panel, this.viewContainer, this.injector),\n );\n panel.setInput('core', this);\n this.subscriptions = [\n // The CDK hands a key to the topmost overlay that listens: while the list is open, Escape is\n // the list's, so a dialog underneath stays open. Focus stays in the input throughout.\n anchored.ref.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n // Cancelled, so it never reaches a CloseWatcher as a second close request.\n event.preventDefault();\n this.close();\n }\n }),\n anchored.ref.outsidePointerEvents().subscribe((event) => {\n if (!(event.target instanceof Node && anchor.contains(event.target))) {\n this.close();\n }\n }),\n ];\n this.openState.set(true);\n }\n\n /** Closes the panel; does nothing while it is closed. */\n close(): void {\n if (!this.anchored) {\n return;\n }\n this.teardown();\n this.openState.set(false);\n this.activeIndex.set(null);\n }\n\n /** Follows the field's size and place while open (chips that wrap make it taller). */\n reposition(): void {\n if (this.anchored) {\n const width = this.host.anchor().getBoundingClientRect().width;\n this.anchored.ref.updateSize({ width: width || undefined });\n this.anchored.ref.updatePosition();\n }\n }\n\n /**\n * Makes an option the active one (the pointer moved over it); a disabled one is skipped.\n * @param item The option.\n */\n activate(item: ComboboxItem<T>): void {\n if (!item.option.disabled) {\n this.activeIndex.set(item.index);\n }\n }\n\n /**\n * Picks an option the user clicked; a disabled one does nothing.\n * @param item The option.\n */\n choose(item: ComboboxItem<T>): void {\n if (!item.option.disabled) {\n this.activeIndex.set(item.index);\n this.host.pick(item);\n }\n }\n\n /**\n * The list keys: arrows open and move (wrapping), `Home`/`End` move to the ends of the open\n * list, `Enter` picks the active option. Returns whether the key was handled (and cancelled).\n * @param event The input's keydown.\n */\n keydown(event: KeyboardEvent): boolean {\n const items = this.items().filter((item) => !item.option.disabled);\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp': {\n const down = event.key === 'ArrowDown';\n if (!this.isOpen()) {\n this.open();\n const selected = items.find((item) => this.host.isSelected(item.option));\n this.activeIndex.set((selected ?? (down ? items[0] : items.at(-1)))?.index ?? null);\n } else if (!event.altKey) {\n this.move(items, down ? 1 : -1);\n }\n event.preventDefault();\n return true;\n }\n case 'Home':\n case 'End':\n if (!this.isOpen() || !items.length) {\n return false;\n }\n this.activeIndex.set((event.key === 'Home' ? items[0] : items.at(-1))?.index ?? null);\n event.preventDefault();\n return true;\n case 'Enter': {\n if (!this.isOpen()) {\n return false;\n }\n const active = this.active();\n if (active) {\n this.host.pick(active);\n }\n event.preventDefault();\n return true;\n }\n default:\n return false;\n }\n }\n\n /** Moves the active option by `step` through the enabled ones, wrapping at the ends. */\n private move(items: ComboboxItem<T>[], step: 1 | -1): void {\n if (!items.length) {\n return;\n }\n const at = items.findIndex((item) => item.index === this.active()?.index);\n const next =\n at < 0 ? (step > 0 ? 0 : items.length - 1) : (at + step + items.length) % items.length;\n this.activeIndex.set(items[next]?.index ?? null);\n }\n\n private firstEnabled(items: ComboboxItem<T>[]): ComboboxItem<T> | undefined {\n return items.find((item) => !item.option.disabled);\n }\n\n private teardown(): void {\n this.subscriptions.forEach((s) => s.unsubscribe());\n this.subscriptions = [];\n this.anchored?.ref.dispose();\n this.anchored = null;\n }\n}\n\n/** Equality of an option's value and a picked value under `compareWith`, never for `null`. */\nexport function sameValue<T>(compare: BfCompareWith<T>, optionValue: T, value: T | null): boolean {\n return value !== null && compare(optionValue, value);\n}\n","import { type BfSize } from '@bitforgehq/ui';\n\n/* Class maps of the combobox fields, shared by bf-combobox and bf-multi-combobox so both look like\n bf-input and bf-select. Internal to the overlay entry. */\n\n/* bf-input's box (bfFieldControlClass): border, surface, focus, read-only and disabled treatment. */\nexport const COMBOBOX_FIELD_BASE =\n 'block w-full rounded-field border bg-surface text-text placeholder:text-text-muted ' +\n 'transition-colors focus:outline-hidden focus:border-primary focus:ring-2 focus:ring-ring ' +\n 'read-only:bg-surface-muted disabled:cursor-not-allowed disabled:border-surface-sunken disabled:bg-surface-muted disabled:text-text-disabled';\n\n/* The text stops short of the chevron at the inline end, as on bf-select. */\nexport const COMBOBOX_PADDING_END: Record<BfSize, string> = {\n sm: 'pe-9',\n md: 'pe-10',\n lg: 'pe-11',\n};\n\n/* bf-select's chevron: a rotated square drawn with borders on the field's wrapper, pointing down\n (no mirroring); only its inset from the inline end follows the size. */\nexport const COMBOBOX_CHEVRON =\n 'relative after:pointer-events-none after:absolute after:top-1/2 after:h-2.5 after:w-2.5 ' +\n \"after:-translate-y-[70%] after:rotate-45 after:border-r-[1.5px] after:border-b-[1.5px] after:border-text-subtle after:content-['']\";\nexport const COMBOBOX_CHEVRON_INSET: Record<BfSize, string> = {\n sm: 'after:end-3.5',\n md: 'after:end-4',\n lg: 'after:end-4.5',\n};\n","import { Component, ElementRef, afterRenderEffect, computed, inject, input } from '@angular/core';\nimport { BF_LABELS, BfSpinnerComponent, type BfSize } from '@bitforgehq/ui';\nimport { type ComboboxCore } from './combobox-core';\n\n/* The menu's card: surface, border, floating shadow; scrolls past 18 rem or the viewport minus\n 1 rem each side, and p-1 keeps the rounded option highlight inside the card's corners. */\nconst PANEL =\n 'block bg-surface text-text border border-border rounded-card shadow-floating p-1 ' +\n 'max-h-[min(18rem,calc(100dvh-2rem))] overflow-y-auto overscroll-contain';\n\n/* The active option (the keyboard's or the pointer's) takes the hover surface; in forced colours\n the system highlight. The check mark is drawn with two borders and shows while selected. */\nconst OPTION =\n 'flex w-full items-start gap-2 rounded-field px-2 text-start cursor-pointer select-none ' +\n 'data-active:bg-surface-muted aria-disabled:cursor-not-allowed aria-disabled:text-text-disabled ' +\n \"before:mt-[0.3em] before:h-[11px] before:w-[6px] before:mx-[5px] before:shrink-0 before:rotate-45 before:border-current before:content-[''] \" +\n 'aria-selected:before:border-r-2 aria-selected:before:border-b-2 aria-selected:text-primary-text ' +\n 'forced-colors:data-active:forced-color-adjust-none forced-colors:data-active:bg-[Highlight] ' +\n 'forced-colors:data-active:text-[HighlightText] forced-colors:aria-disabled:text-[GrayText]';\n\n/* The menu item's heights (32 / 36 / 44 px), at least 44 px under a coarse pointer. */\nconst SIZE: Record<BfSize, string> = {\n sm: 'min-h-8 py-1.5 text-label-sm pointer-coarse:min-h-hit',\n md: 'min-h-9 py-2 text-body pointer-coarse:min-h-hit',\n lg: 'min-h-11 py-2.5 text-body',\n};\n\n/**\n * The panel of `bf-combobox` and `bf-multi-combobox`: the listbox of the filtered options (in\n * `role=\"group\"` sections for grouped ones) and a status row for loading and no results. Opened\n * by the combobox core into the overlay; focus stays in the combobox's input, so a press here is\n * cancelled. Internal to the overlay entry.\n */\n@Component({\n selector: 'bf-combobox-listbox',\n imports: [BfSpinnerComponent],\n // The option rows take no focus and no keys of their own (the combobox's input has both), so a\n // press and a click are handled here for the row they land on.\n host: {\n '[class]': 'panelClasses',\n '(mousedown)': '$event.preventDefault()',\n '(pointermove)': 'onPointer($event, false)',\n '(click)': 'onPointer($event, true)',\n },\n template: `\n @if (core().items().length) {\n <div\n role=\"listbox\"\n [id]=\"core().listboxId\"\n [attr.aria-label]=\"core().host.listboxLabel()\"\n [attr.aria-labelledby]=\"core().host.listboxLabelledby()\"\n [attr.aria-multiselectable]=\"core().host.multiple ? 'true' : null\"\n >\n @for (section of core().sections(); track section.id) {\n <!-- The ungrouped options sit in a plain wrapper, each group in a named role=\"group\". -->\n <div\n [attr.role]=\"section.label ? 'group' : 'presentation'\"\n [attr.aria-labelledby]=\"section.label ? section.id : null\"\n >\n @if (section.label) {\n <div\n [id]=\"section.id\"\n role=\"presentation\"\n class=\"text-caption text-text-muted px-2 pt-2 pb-1\"\n >\n {{ section.label }}\n </div>\n }\n @for (item of section.items; track item.index) {\n <div\n role=\"option\"\n [id]=\"item.id\"\n [attr.aria-selected]=\"core().host.isSelected(item.option) ? 'true' : 'false'\"\n [attr.aria-disabled]=\"item.option.disabled ? 'true' : null\"\n [attr.data-index]=\"item.index\"\n [attr.data-active]=\"core().active()?.index === item.index ? '' : null\"\n [class]=\"optionClasses()\"\n >\n <span class=\"flex min-w-0 flex-col\">\n <span data-label class=\"wrap-anywhere\">{{ item.option.label }}</span>\n @if (item.option.description) {\n <span class=\"text-caption text-text-muted wrap-anywhere\">{{\n item.option.description\n }}</span>\n }\n </span>\n </div>\n }\n </div>\n }\n </div>\n }\n <div role=\"status\" class=\"text-text-muted text-label-sm empty:hidden\">\n @if (core().host.loading()) {\n <div class=\"flex items-center gap-2 px-2 py-2\">\n <bf-spinner size=\"sm\" decorative />{{ labels.loading }}\n </div>\n } @else if (!core().items().length) {\n <div class=\"px-2 py-2\">{{ core().host.emptyText() }}</div>\n }\n </div>\n `,\n})\nexport class BfComboboxListboxComponent {\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n protected readonly labels = inject(BF_LABELS);\n\n /** The combobox core whose options and state this panel shows. */\n readonly core = input.required<ComboboxCore<unknown>>();\n\n protected readonly panelClasses = PANEL;\n protected readonly optionClasses = computed(() => `${OPTION} ${SIZE[this.core().host.size()]}`);\n\n constructor() {\n // Keeps the active option in view as the arrow keys move it.\n afterRenderEffect({\n write: () => {\n const active = this.core().active();\n const option = active ? this.host.querySelector(`[id=\"${active.id}\"]`) : null;\n option?.scrollIntoView?.({ block: 'nearest' });\n },\n });\n }\n\n /**\n * The pointer moved over an option (it becomes the active one) or clicked it (it is picked).\n * @internal\n */\n onPointer(event: Event, pick: boolean): void {\n const row = event.target instanceof Element ? event.target.closest('[role=\"option\"]') : null;\n const index = Number(row?.getAttribute('data-index'));\n const item = this.core()\n .items()\n .find((i) => i.index === index);\n if (!row || !item) {\n return;\n }\n if (pick) {\n this.core().choose(item);\n } else {\n this.core().activate(item);\n }\n }\n}\n","import {\n Component,\n type ElementRef,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n type BfCompareWith,\n BfFieldComponent,\n type BfSize,\n ɵFIELD_BOX as FIELD_BOX,\n ɵFIELD_PADDING_START as FIELD_PADDING_START,\n ɵfieldDescribedBy as fieldDescribedBy,\n ɵfieldErrorMessageId as fieldErrorMessageId,\n ɵfieldErrorText as fieldErrorText,\n ɵfieldShowsError as fieldShowsError,\n ɵuniqueId as uniqueId,\n} from '@bitforgehq/ui';\nimport {\n type BfComboboxFilter,\n type BfComboboxOption,\n ComboboxCore,\n type ComboboxItem,\n foldText,\n labelContains,\n sameValue,\n} from './combobox-core';\nimport {\n COMBOBOX_CHEVRON,\n COMBOBOX_CHEVRON_INSET,\n COMBOBOX_FIELD_BASE,\n COMBOBOX_PADDING_END,\n} from './combobox-classes';\nimport { BfComboboxListboxComponent } from './combobox-listbox.component';\n\n/**\n * Text field with a filtered list of options to pick one value from (the ARIA combobox pattern).\n * Typing filters the list by label, ignoring case and accents; the arrow keys move through it\n * and `Enter` picks. Generic over the option value (a string by default); `null` means nothing is\n * picked. For several values use `bf-multi-combobox`.\n *\n * @example\n * <bf-combobox label=\"Assignee\" placeholder=\"Search people\" [options]=\"people\" [(value)]=\"assigneeId\" />\n * <bf-combobox label=\"Owner\" [options]=\"people\" [formField]=\"task.ownerId\" />\n * @summary Text field that filters a list of options as you type and picks one\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-combobox',\n imports: [BfFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-field\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [error]=\"errorText()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n [controlId]=\"id()\"\n >\n <div #anchor [class]=\"wrapperClasses()\">\n <input\n #el\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n aria-autocomplete=\"list\"\n [id]=\"id()\"\n [attr.name]=\"name() || null\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [attr.aria-expanded]=\"core.isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"core.controls()\"\n [attr.aria-activedescendant]=\"core.active()?.id ?? null\"\n [attr.aria-label]=\"ariaLabelAttr()\"\n [attr.aria-labelledby]=\"ariaLabelledbyAttr()\"\n [attr.aria-invalid]=\"showError() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-errormessage]=\"errorMessageId()\"\n [class]=\"classes()\"\n (input)=\"onInput(el)\"\n (keydown)=\"onKeydown($event)\"\n (click)=\"onClick()\"\n (focus)=\"focused.emit($event)\"\n (blur)=\"onBlur($event)\"\n />\n </div>\n </bf-field>\n `,\n})\nexport class BfComboboxComponent<T = string> implements FormValueControl<T | null> {\n /** The picked option's value, `null` while nothing is picked; two-way bindable and bound by\n * `[formField]`. */\n readonly value = model<T | null>(null);\n /** The options to choose from; with server search, the latest results (keep the picked one). */\n readonly options = input.required<readonly BfComboboxOption<T>[]>();\n /** Equality for matching `value` to an option (default `Object.is`); pass one for object values. */\n readonly compareWith = input<BfCompareWith<T>>(Object.is);\n /** Whether an option matches the typed text (default: its label contains it, ignoring case and\n * accents); `null` shows `options` unfiltered, for results filtered by a server. */\n readonly filter = input<BfComboboxFilter<T> | null>(labelContains);\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`\n * by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Hint text shown in the empty field. */\n readonly placeholder = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over Signal Forms errors. */\n readonly errorMessage = input('');\n /** Text of the list's row when no option matches; empty uses the `comboboxEmpty` label. */\n readonly emptyLabel = input('');\n /** Shows a loading row in the list, while a server search for the typed text runs. */\n readonly loading = input(false, { transform: booleanAttribute });\n /** Disables the field. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the value but blocks changes; the field stays focusable and the list never opens. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the text input. */\n readonly name = input('');\n /** Input id; generated when not set. */\n readonly id = input(uniqueId('bf-combobox'));\n\n /** Emitted with the new value after the user picks an option, or `null` after clearing the text. */\n readonly changed = output<T | null>();\n /** Emitted with the typed text each time the user changes it (`''` once it is cleared), for a\n * server search. */\n readonly queried = output<string>();\n /** Emitted when the input gains focus. */\n readonly focused = output<FocusEvent>();\n /** Emitted when the input loses focus. */\n readonly blurred = output<FocusEvent>();\n /** Emitted on blur so Signal Forms marks the field touched. */\n readonly touch = output<void>();\n\n private readonly el = viewChild.required<ElementRef<HTMLInputElement>>('el');\n private readonly anchorEl = viewChild.required<ElementRef<HTMLElement>>('anchor');\n private readonly defaults = inject(BF_DEFAULTS);\n private readonly labels = inject(BF_LABELS);\n\n /** The label of the last option the user picked, for a value no current option matches (the\n * results of a later server search). */\n private readonly pickedLabel = signal<{ value: T; label: string } | null>(null);\n\n /** The size in effect: `size`, else the app's `fieldSize` default. */\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.fieldSize);\n\n protected readonly core = new ComboboxCore<T>({\n options: this.options,\n filter: this.filter,\n isSelected: (option) => sameValue(this.compareWith(), option.value, this.value()),\n pick: (item) => this.pick(item),\n anchor: () => this.anchorEl().nativeElement,\n panel: BfComboboxListboxComponent,\n listboxLabel: computed(() => this.label() || this.ariaLabel() || null),\n listboxLabelledby: computed(() => (this.label() ? null : this.ariaLabelledby() || null)),\n multiple: false,\n loading: this.loading,\n emptyText: computed(() => this.emptyLabel() || this.labels.comboboxEmpty),\n size: this.resolvedSize,\n queried: (query) => this.queried.emit(query),\n });\n\n /** The picked option's label, `''` while nothing is picked. */\n readonly valueLabel = computed(() => {\n const value = this.value();\n if (value === null) {\n return '';\n }\n const compare = this.compareWith();\n const option = this.options().find((o) => compare(o.value, value));\n const picked = this.pickedLabel();\n return option?.label ?? (picked && compare(picked.value, value) ? picked.label : '');\n });\n /** The input's text: what the user is typing, else the picked option's label. */\n protected readonly text = computed(() => this.core.query() ?? this.valueLabel());\n\n readonly errorText = computed(() =>\n fieldErrorText(this.errorMessage(), this.touched(), this.errors(), this.labels.validation),\n );\n readonly showError = computed(() =>\n fieldShowsError(this.errorText(), this.invalid(), this.touched()),\n );\n readonly describedBy = computed(() =>\n fieldDescribedBy(this.id(), this.errorText(), this.helpText()),\n );\n /** `aria-errormessage`: the error paragraph while `aria-invalid` is set. */\n readonly errorMessageId = computed(() =>\n fieldErrorMessageId(this.id(), this.errorText(), this.showError()),\n );\n /** `aria-label` value: only when there is no visible label. */\n readonly ariaLabelAttr = computed(() => (this.label() ? null : this.ariaLabel() || null));\n /** `aria-labelledby` value, under the same rule as `ariaLabelAttr`. */\n readonly ariaLabelledbyAttr = computed(() =>\n this.label() ? null : this.ariaLabelledby() || null,\n );\n readonly wrapperClasses = computed(\n () => `${COMBOBOX_CHEVRON} ${COMBOBOX_CHEVRON_INSET[this.resolvedSize()]}`,\n );\n readonly classes = computed(() =>\n [\n COMBOBOX_FIELD_BASE,\n FIELD_BOX[this.resolvedSize()],\n FIELD_PADDING_START[this.resolvedSize()].text,\n COMBOBOX_PADDING_END[this.resolvedSize()],\n /* Plain hover sorts before focus: and disabled:, so the focus and disabled borders still win. */\n this.showError()\n ? 'border-danger-border hover:border-danger'\n : 'border-border-strong hover:border-text-muted',\n ].join(' '),\n );\n\n /**\n * Focuses the input; Signal Forms calls it from `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.el().nativeElement.focus(options);\n }\n\n /**\n * Typing filters the list and opens it.\n * @internal\n */\n onInput(el: HTMLInputElement): void {\n if (this.readonly()) {\n return;\n }\n this.core.typed(el.value);\n }\n\n /**\n * Opens the list on a click into the field.\n * @internal\n */\n onClick(): void {\n if (!this.readonly() && !this.disabled()) {\n this.core.open();\n }\n }\n\n /**\n * The list keys (arrows, `Home`, `End`, `Enter`), and `Escape` on a closed list, which drops the\n * typed text. `Escape` on an open list is the panel's: it closes it.\n * @internal\n */\n onKeydown(event: KeyboardEvent): void {\n if (this.readonly()) {\n return;\n }\n if (this.core.keydown(event)) {\n return;\n }\n if (event.key === 'Escape' && !this.core.isOpen() && this.core.query() !== null) {\n this.resetQuery(null);\n }\n }\n\n /**\n * Leaving the field closes the list. Typed text that names an option exactly picks it; empty\n * text clears the value; any other text reverts to the picked option's label. Marks the field\n * touched.\n * @internal\n */\n onBlur(event: FocusEvent): void {\n this.core.close();\n const query = this.core.query();\n if (query !== null) {\n const typed = foldText(query.trim());\n const match = this.options().find((o) => !o.disabled && foldText(o.label) === typed);\n if (!typed && this.value() !== null) {\n this.set(null);\n } else if (typed && match && !sameValue(this.compareWith(), match.value, this.value())) {\n this.set(match.value, match.label);\n }\n this.resetQuery(null);\n }\n this.blurred.emit(event);\n this.touch.emit();\n }\n\n /** Picks an option (Enter or a click): the value, the field's text, and the list closes. */\n private pick(item: ComboboxItem<T>): void {\n if (!sameValue(this.compareWith(), item.option.value, this.value())) {\n this.set(item.option.value, item.option.label);\n }\n this.resetQuery(null);\n this.core.close();\n }\n\n private set(value: T | null, label = ''): void {\n this.pickedLabel.set(value === null ? null : { value, label });\n this.value.set(value);\n this.changed.emit(value);\n }\n\n /**\n * Drops the typed text and writes the field's text to the input at once: a pick can follow the\n * last keystroke before change detection has run, when the binding alone would see no change.\n */\n private resetQuery(query: string | null): void {\n this.core.setQuery(query);\n this.el().nativeElement.value = this.text();\n }\n}\n","import {\n Component,\n type ElementRef,\n afterRenderEffect,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n type BfCompareWith,\n BfFieldComponent,\n type BfSize,\n ɵFIELD_PADDING_START as FIELD_PADDING_START,\n ɵfieldDescribedBy as fieldDescribedBy,\n ɵfieldErrorMessageId as fieldErrorMessageId,\n ɵfieldErrorText as fieldErrorText,\n ɵfieldShowsError as fieldShowsError,\n ɵuniqueId as uniqueId,\n} from '@bitforgehq/ui';\nimport { COMBOBOX_CHEVRON, COMBOBOX_CHEVRON_INSET, COMBOBOX_PADDING_END } from './combobox-classes';\nimport {\n type BfComboboxFilter,\n type BfComboboxOption,\n ComboboxCore,\n type ComboboxItem,\n labelContains,\n} from './combobox-core';\nimport { BfComboboxListboxComponent } from './combobox-listbox.component';\n\n/* The field box around the tags and the input: bf-input's border, surface and focus ring, on the\n wrapper (focus-within), growing in height as the tags wrap. */\nconst BOX =\n 'flex w-full flex-wrap items-center gap-1 rounded-field border py-1 ' +\n 'transition-colors focus-within:border-primary focus-within:ring-2 focus-within:ring-ring';\n\n/* At least the text fields' heights (32 / 40 / 48 px) and their type. */\nconst BOX_SIZE: Record<BfSize, string> = {\n sm: 'min-h-8 text-label-xs',\n md: 'min-h-10 text-label-sm',\n lg: 'min-h-12 text-label',\n};\n\ntype BfMultiComboboxMode = 'editable' | 'readonly' | 'disabled';\n/* The surface, text and cursor per mode, each set once so no two classes compete. */\nconst MODE: Record<BfMultiComboboxMode, string> = {\n editable: 'cursor-text bg-surface text-text',\n readonly: 'cursor-text bg-surface-muted text-text',\n disabled: 'cursor-not-allowed border-surface-sunken bg-surface-muted text-text-disabled',\n};\n\n/* The input inside the box: no box of its own, at least 4 rem wide so there is room to type. */\nconst INPUT =\n 'h-6 min-w-16 flex-1 bg-transparent outline-hidden placeholder:text-text-muted ' +\n 'disabled:cursor-not-allowed';\n\n/* A picked value: a small primary-soft tag (bf-chip's selected tonal colours) with a remove\n button at the inline end. */\nconst TAG =\n 'inline-flex h-6 max-w-full min-w-0 items-center rounded-control bg-primary-soft ps-2 ' +\n 'text-label-xs font-bold text-primary-strong';\n/* The remove button: 24 px, extended to 44 px under a coarse pointer. Its × is two borders on a\n child span, so the button's ::after stays free for the hit extension. */\nconst REMOVE =\n 'relative inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-control ' +\n 'hover:bg-primary-soft-hover active:bg-primary-soft-pressed ' +\n 'focus-visible:outline-hidden focus-visible:ring-4 focus-visible:ring-ring ' +\n \"pointer-coarse:after:absolute pointer-coarse:after:-inset-2.5 pointer-coarse:after:content-['']\";\nconst CROSS =\n 'relative block size-2.5 ' +\n \"before:absolute before:inset-x-0 before:top-1/2 before:h-[1.5px] before:-translate-y-1/2 before:rotate-45 before:bg-current before:content-[''] \" +\n \"after:absolute after:inset-x-0 after:top-1/2 after:h-[1.5px] after:-translate-y-1/2 after:-rotate-45 after:bg-current after:content-['']\";\n\n/** A picked value as a tag: its label, for the tag and its remove button's name. */\ninterface BfMultiComboboxTag<T> {\n value: T;\n label: string;\n}\n\n/**\n * Text field with a filtered list of options to pick several values from, shown as removable tags\n * inside the field (the ARIA combobox pattern with a multi-select listbox). Typing filters the\n * list by label, ignoring case and accents; `Enter` or a click adds or removes the active option\n * and the list stays open. Generic over the option value (a string by default); the value is an\n * array, empty while nothing is picked. For one value use `bf-combobox`.\n *\n * @example\n * <bf-multi-combobox label=\"Labels\" placeholder=\"Add labels\" [options]=\"labels\" [(value)]=\"picked\" />\n * <bf-multi-combobox label=\"Reviewers\" [options]=\"people\" [formField]=\"task.reviewerIds\" />\n * @summary Text field that filters options as you type and picks several as tags\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-multi-combobox',\n imports: [BfFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-field\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [error]=\"errorText()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n [controlId]=\"id()\"\n >\n <!-- A press on the box outside the tags puts the caret in the input. -->\n <div #anchor [class]=\"boxClasses()\" (mousedown)=\"onBoxMousedown($event)\">\n @for (tag of tags(); track $index) {\n <span data-chip [class]=\"tagClasses\">\n <span data-label class=\"min-w-0 truncate\">{{ tag.label }}</span>\n @if (editable()) {\n <button\n type=\"button\"\n [class]=\"removeClasses\"\n [attr.aria-label]=\"labels.comboboxRemove(tag.label)\"\n (click)=\"remove($index)\"\n >\n <span aria-hidden=\"true\" [class]=\"crossClasses\"></span>\n </button>\n } @else {\n <span class=\"pe-2\"></span>\n }\n </span>\n }\n <input\n #el\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n aria-autocomplete=\"list\"\n [id]=\"id()\"\n [attr.name]=\"name() || null\"\n [value]=\"core.query() ?? ''\"\n [placeholder]=\"tags().length ? '' : placeholder()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required() && !tags().length\"\n [attr.aria-expanded]=\"core.isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"core.controls()\"\n [attr.aria-activedescendant]=\"core.active()?.id ?? null\"\n [attr.aria-label]=\"ariaLabelAttr()\"\n [attr.aria-labelledby]=\"ariaLabelledbyAttr()\"\n [attr.aria-invalid]=\"showError() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-errormessage]=\"errorMessageId()\"\n [class]=\"inputClasses\"\n (input)=\"onInput(el)\"\n (keydown)=\"onKeydown($event)\"\n (click)=\"onClick()\"\n (focus)=\"focused.emit($event)\"\n (blur)=\"onBlur($event)\"\n />\n </div>\n </bf-field>\n `,\n})\nexport class BfMultiComboboxComponent<T = string> implements FormValueControl<readonly T[]> {\n /** The picked options' values in the order they were picked, empty while nothing is picked;\n * two-way bindable and bound by `[formField]`. */\n readonly value = model<readonly T[]>([]);\n /** The options to choose from; with server search, the latest results. */\n readonly options = input.required<readonly BfComboboxOption<T>[]>();\n /** Equality for matching `value` to an option (default `Object.is`); pass one for object values. */\n readonly compareWith = input<BfCompareWith<T>>(Object.is);\n /** Whether an option matches the typed text (default: its label contains it, ignoring case and\n * accents); `null` shows `options` unfiltered, for results filtered by a server. */\n readonly filter = input<BfComboboxFilter<T> | null>(labelContains);\n /** Height step of the field (its minimum height): sm 32, md 40, lg 48 px; unset follows\n * `provideBfDefaults()` (`fieldSize`, `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Hint text shown while nothing is picked. */\n readonly placeholder = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over Signal Forms errors. */\n readonly errorMessage = input('');\n /** Text of the list's row when no option matches; empty uses the `comboboxEmpty` label. */\n readonly emptyLabel = input('');\n /** Shows a loading row in the list, while a server search for the typed text runs. */\n readonly loading = input(false, { transform: booleanAttribute });\n /** Disables the field and its tags. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the tags but blocks changes: no remove buttons, and the list never opens. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required (at least one value). */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the text input. */\n readonly name = input('');\n /** Input id; generated when not set. */\n readonly id = input(uniqueId('bf-multi-combobox'));\n\n /** Emitted with the new values after the user adds or removes one. */\n readonly changed = output<readonly T[]>();\n /** Emitted with the typed text each time the user changes it (`''` once it is cleared), for a\n * server search. */\n readonly queried = output<string>();\n /** Emitted when the input gains focus. */\n readonly focused = output<FocusEvent>();\n /** Emitted when the input loses focus. */\n readonly blurred = output<FocusEvent>();\n /** Emitted on blur so Signal Forms marks the field touched. */\n readonly touch = output<void>();\n\n private readonly el = viewChild.required<ElementRef<HTMLInputElement>>('el');\n private readonly anchorEl = viewChild.required<ElementRef<HTMLElement>>('anchor');\n private readonly defaults = inject(BF_DEFAULTS);\n protected readonly labels = inject(BF_LABELS);\n\n /** The labels of the options the user picked, for values no current option matches (the\n * results of a later server search). */\n private readonly pickedLabels = signal<readonly BfMultiComboboxTag<T>[]>([]);\n\n /** The size in effect: `size`, else the app's `fieldSize` default. */\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.fieldSize);\n\n protected readonly core = new ComboboxCore<T>({\n options: this.options,\n filter: this.filter,\n isSelected: (option) => this.indexOf(option.value) >= 0,\n pick: (item) => this.toggle(item),\n anchor: () => this.anchorEl().nativeElement,\n panel: BfComboboxListboxComponent,\n listboxLabel: computed(() => this.label() || this.ariaLabel() || null),\n listboxLabelledby: computed(() => (this.label() ? null : this.ariaLabelledby() || null)),\n multiple: true,\n loading: this.loading,\n emptyText: computed(() => this.emptyLabel() || this.labels.comboboxEmpty),\n size: this.resolvedSize,\n queried: (query) => this.queried.emit(query),\n });\n\n /** The picked values with their labels, in `value` order. */\n protected readonly tags = computed<BfMultiComboboxTag<T>[]>(() => {\n const compare = this.compareWith();\n return this.value().map((value) => {\n const label =\n this.options().find((o) => compare(o.value, value))?.label ??\n this.pickedLabels().find((t) => compare(t.value, value))?.label ??\n String(value);\n return { value, label };\n });\n });\n /** Whether the user can change the value (not disabled, not read-only). */\n protected readonly editable = computed(() => !this.disabled() && !this.readonly());\n\n readonly errorText = computed(() =>\n fieldErrorText(this.errorMessage(), this.touched(), this.errors(), this.labels.validation),\n );\n readonly showError = computed(() =>\n fieldShowsError(this.errorText(), this.invalid(), this.touched()),\n );\n readonly describedBy = computed(() =>\n fieldDescribedBy(this.id(), this.errorText(), this.helpText()),\n );\n /** `aria-errormessage`: the error paragraph while `aria-invalid` is set. */\n readonly errorMessageId = computed(() =>\n fieldErrorMessageId(this.id(), this.errorText(), this.showError()),\n );\n /** `aria-label` value: only when there is no visible label. */\n readonly ariaLabelAttr = computed(() => (this.label() ? null : this.ariaLabel() || null));\n /** `aria-labelledby` value, under the same rule as `ariaLabelAttr`. */\n readonly ariaLabelledbyAttr = computed(() =>\n this.label() ? null : this.ariaLabelledby() || null,\n );\n readonly boxClasses = computed(() => {\n const size = this.resolvedSize();\n const mode: BfMultiComboboxMode = this.disabled()\n ? 'disabled'\n : this.readonly()\n ? 'readonly'\n : 'editable';\n return [\n BOX,\n BOX_SIZE[size],\n FIELD_PADDING_START[size].text,\n COMBOBOX_PADDING_END[size],\n COMBOBOX_CHEVRON,\n COMBOBOX_CHEVRON_INSET[size],\n MODE[mode],\n /* Hover darkens the border only while the box has no focus, so the focus border wins. */\n mode === 'disabled'\n ? ''\n : this.showError()\n ? 'border-danger-border hover:not-focus-within:border-danger'\n : 'border-border-strong hover:not-focus-within:border-text-muted',\n ]\n .filter(Boolean)\n .join(' ');\n });\n protected readonly inputClasses = INPUT;\n protected readonly tagClasses = TAG;\n protected readonly removeClasses = REMOVE;\n protected readonly crossClasses = CROSS;\n\n constructor() {\n // Tags that wrap change the field's height: the open list follows its bottom edge.\n afterRenderEffect({\n write: () => {\n this.tags();\n this.core.reposition();\n },\n });\n }\n\n /**\n * Focuses the input; Signal Forms calls it from `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.el().nativeElement.focus(options);\n }\n\n /**\n * Typing filters the list and opens it.\n * @internal\n */\n onInput(el: HTMLInputElement): void {\n if (this.editable()) {\n this.core.typed(el.value);\n }\n }\n\n /**\n * Opens the list on a click into the input.\n * @internal\n */\n onClick(): void {\n if (this.editable()) {\n this.core.open();\n }\n }\n\n /**\n * A press on the box itself (not a tag's button, not the input) focuses the input and opens the\n * list.\n * @internal\n */\n onBoxMousedown(event: MouseEvent): void {\n const target = event.target;\n if (!(target instanceof Element) || target.closest('button, input') || this.disabled()) {\n return;\n }\n event.preventDefault();\n this.focus();\n this.onClick();\n }\n\n /**\n * The list keys (arrows, `Home`, `End`, `Enter`), `Backspace` in the empty input (removes the last\n * tag) and `Escape` on a closed list (drops the typed text).\n * @internal\n */\n onKeydown(event: KeyboardEvent): void {\n if (!this.editable() || this.core.keydown(event)) {\n return;\n }\n const query = this.core.query() ?? '';\n if (event.key === 'Backspace' && query === '' && this.value().length) {\n event.preventDefault();\n this.remove(this.value().length - 1);\n } else if (event.key === 'Escape' && !this.core.isOpen() && query !== '') {\n this.resetQuery(null);\n }\n }\n\n /**\n * Leaving the field closes the list and drops the typed text; marks the field touched.\n * @internal\n */\n onBlur(event: FocusEvent): void {\n this.core.close();\n this.resetQuery(null);\n this.blurred.emit(event);\n this.touch.emit();\n }\n\n /**\n * Removes the value at `index` (a tag's remove button) and returns focus to the input.\n * @internal\n */\n remove(index: number): void {\n const next = this.value().filter((_, i) => i !== index);\n this.value.set(next);\n this.changed.emit(next);\n this.focus();\n }\n\n /** Adds a picked option, or removes it when it is picked already; the typed text clears and the\n * list stays open. */\n private toggle(item: ComboboxItem<T>): void {\n const at = this.indexOf(item.option.value);\n let next: readonly T[];\n if (at >= 0) {\n next = this.value().filter((_, i) => i !== at);\n } else {\n next = [...this.value(), item.option.value];\n const tag = { value: item.option.value, label: item.option.label };\n this.pickedLabels.update((tags) => [...tags, tag]);\n }\n this.value.set(next);\n this.changed.emit(next);\n this.resetQuery('');\n }\n\n private indexOf(value: T): number {\n const compare = this.compareWith();\n return this.value().findIndex((v) => compare(value, v));\n }\n\n /**\n * Drops the typed text and writes the field's text to the input at once: a pick can follow the\n * last keystroke before change detection has run, when the binding alone would see no change.\n */\n private resetQuery(query: string | null): void {\n this.core.setQuery(query);\n this.el().nativeElement.value = '';\n }\n}\n","import {\n ɵdaysInMonth as daysInMonth,\n ɵformatIsoDate as formatIsoDate,\n ɵparseIsoDate as parseIsoDate,\n} from '@bitforgehq/ui';\n\n/*\n * The segmented field of bf-date-input, bf-time-input and bf-datetime-input as plain functions:\n * which parts a locale shows in which order, each part's range, typing digits, stepping, and\n * turning the parts into the ISO value and back. A date is never a `Date` here: the parts are\n * numbers, the value an ISO string ('YYYY-MM-DD', 'HH:mm', 'YYYY-MM-DDTHH:mm'), so no time zone or\n * daylight-saving shift can move what the user typed. A `Date` is built only at UTC, to hand to\n * `Intl.DateTimeFormat` with `timeZone: 'UTC'`. Internal to the overlay entry.\n */\n\n/** One editable part of the field. */\nexport type SegmentKind = 'day' | 'month' | 'year' | 'hour' | 'minute' | 'second' | 'dayPeriod';\n\n/** What the field edits: a date, a time of day, or both. */\nexport type DateTimeMode = 'date' | 'time' | 'datetime';\n\n/** How hours count: 0–11 or 1–12 with a day period (AM/PM), or 0–23. */\nexport type HourCycle = 'h11' | 'h12' | 'h23';\n\n/** One item of the field's layout: an editable part, or the text between two parts. */\nexport type LayoutItem =\n | { readonly type: 'segment'; readonly kind: SegmentKind }\n | { readonly type: 'literal'; readonly text: string };\n\n/** The parts as numbers, `null` (or missing) while empty; a day period is 0 (AM) or 1 (PM). */\nexport type SegmentValues = Readonly<Partial<Record<SegmentKind, number | null>>>;\n\n/** A segment's inclusive range. */\nexport interface SegmentRange {\n readonly min: number;\n readonly max: number;\n}\n\n/** The outcome of typing one digit into a segment. */\nexport interface TypedDigit {\n /** The segment's new value, `null` while what is typed is not a value yet (a lone \"0\" day). */\n readonly value: number | null;\n /** The digits typed into the segment so far. */\n readonly text: string;\n /** Whether no further digit could follow, so focus moves to the next segment. */\n readonly advance: boolean;\n}\n\nconst DATE_KINDS: readonly SegmentKind[] = ['day', 'month', 'year'];\nconst ISO_TIME = /^(\\d{2}):(\\d{2})(?::(\\d{2}))?$/;\n/* Bidirectional marks some locales put around the separators; the field lays out its own parts. */\nconst BIDI_MARKS = /[‎‏؜‪-‮⁦-⁩]/g;\n\nconst PART_KINDS: Readonly<Record<string, SegmentKind>> = {\n day: 'day',\n month: 'month',\n year: 'year',\n hour: 'hour',\n minute: 'minute',\n second: 'second',\n dayPeriod: 'dayPeriod',\n};\n\nfunction pad(value: number, length: number): string {\n return String(value).padStart(length, '0');\n}\n\n/** A `Date` at the UTC time of the parts, only for `Intl.DateTimeFormat` with `timeZone: 'UTC'`. */\nfunction utcInstant(year: number, month: number, day: number, minutes: number): Date {\n const date = new Date(0);\n // setUTCFullYear, not Date.UTC: Date.UTC maps the years 0–99 to 1900–1999.\n date.setUTCFullYear(year, month - 1, day);\n date.setUTCMinutes(minutes);\n return date;\n}\n\n/** The time parts the field edits for `hourCycle`, with seconds when asked. */\nfunction timeKinds(seconds: boolean, hourCycle: HourCycle): SegmentKind[] {\n return [\n 'hour',\n 'minute',\n ...(seconds ? (['second'] as const) : []),\n ...(hourCycle === 'h23' ? [] : (['dayPeriod'] as const)),\n ];\n}\n\n/** The parts the field edits, in no particular order. */\nexport function segmentKinds(\n mode: DateTimeMode,\n seconds: boolean,\n hourCycle: HourCycle,\n): SegmentKind[] {\n return [\n ...(mode === 'time' ? [] : DATE_KINDS),\n ...(mode === 'date' ? [] : timeKinds(seconds, hourCycle)),\n ];\n}\n\n/**\n * The hour cycle of `locale` (`Intl`'s `hourCycle`, h24 read as h23), or `override` when set.\n */\nexport function resolveHourCycle(locale: string, override?: 'h12' | 'h23'): HourCycle {\n if (override) {\n return override;\n }\n const cycle = new Intl.DateTimeFormat(locale, { hour: 'numeric' }).resolvedOptions().hourCycle;\n return cycle === 'h11' || cycle === 'h12' ? cycle : 'h23';\n}\n\n/**\n * The field's parts and separators in the order `locale` writes them, from\n * `Intl.DateTimeFormat.formatToParts` (Gregorian calendar, Latin digits). Separators are kept as\n * the locale writes them, without bidirectional marks; a part the locale leaves out (never the\n * case for these options) is added at the end, so every part stays editable.\n */\nexport function segmentLayout(\n locale: string,\n mode: DateTimeMode,\n seconds: boolean,\n hourCycle: HourCycle,\n): LayoutItem[] {\n const options: Intl.DateTimeFormatOptions = {\n calendar: 'gregory',\n numberingSystem: 'latn',\n timeZone: 'UTC',\n ...(mode === 'time' ? {} : { year: 'numeric', month: '2-digit', day: '2-digit' }),\n ...(mode === 'date'\n ? {}\n : {\n hour: '2-digit',\n minute: '2-digit',\n hourCycle,\n ...(seconds ? { second: '2-digit' } : {}),\n }),\n };\n const parts = new Intl.DateTimeFormat(locale, options).formatToParts(utcInstant(2001, 2, 3, 245));\n const wanted = new Set(segmentKinds(mode, seconds, hourCycle));\n const items: LayoutItem[] = [];\n for (const part of parts) {\n const kind = PART_KINDS[part.type];\n if (kind && wanted.has(kind)) {\n wanted.delete(kind);\n items.push({ type: 'segment', kind });\n } else if (part.type === 'literal') {\n const text = part.value.replace(BIDI_MARKS, '');\n const last = items[items.length - 1];\n if (last?.type === 'literal') {\n items[items.length - 1] = { type: 'literal', text: last.text + text };\n } else if (text) {\n items.push({ type: 'literal', text });\n }\n }\n }\n for (const kind of wanted) {\n items.push({ type: 'literal', text: ' ' }, { type: 'segment', kind });\n }\n // A separator before the first or after the last part that is only space adds nothing.\n return items.filter(\n (item, index) =>\n item.type === 'segment' || item.text.trim() !== '' || (index > 0 && index < items.length - 1),\n );\n}\n\n/** The localized names of the two day periods, AM first, from `Intl` in `locale`. */\nexport function dayPeriodNames(locale: string): readonly [string, string] {\n const format = new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n hourCycle: 'h12',\n timeZone: 'UTC',\n });\n const name = (hour: number): string =>\n format.formatToParts(utcInstant(2001, 1, 1, hour * 60)).find((p) => p.type === 'dayPeriod')\n ?.value ?? (hour < 12 ? 'AM' : 'PM');\n return [name(1), name(13)];\n}\n\n/** How many digits a segment takes: four for the year, none for the day period, else two. */\nexport function segmentDigits(kind: SegmentKind): number {\n return kind === 'year' ? 4 : kind === 'dayPeriod' ? 0 : 2;\n}\n\n/**\n * A segment's range; the day's follows the month (and the year, for 29 February) once they are\n * set, else it is 1–31 (29 February is allowed until the year says otherwise).\n */\nexport function segmentRange(\n kind: SegmentKind,\n values: SegmentValues,\n hourCycle: HourCycle,\n): SegmentRange {\n switch (kind) {\n case 'day': {\n const month = values.month;\n return { min: 1, max: month ? daysInMonth(values.year ?? 2000, month) : 31 };\n }\n case 'month':\n return { min: 1, max: 12 };\n case 'year':\n return { min: 1, max: 9999 };\n case 'hour':\n return hourCycle === 'h12'\n ? { min: 1, max: 12 }\n : { min: 0, max: hourCycle === 'h11' ? 11 : 23 };\n case 'dayPeriod':\n return { min: 0, max: 1 };\n default:\n return { min: 0, max: 59 };\n }\n}\n\n/**\n * Types `digit` after the digits `text` already typed into a segment. When the digits so far\n * would pass the segment's maximum, typing starts over from `digit`. Focus moves on once the\n * segment has all its digits or no further digit could keep it in range (\"4\" in a month); the\n * field writes `value` then, or when focus leaves the segment (see `commitTyped`). A year has a\n * value only at four digits.\n */\nexport function typeDigit(\n kind: SegmentKind,\n text: string,\n digit: string,\n values: SegmentValues,\n hourCycle: HourCycle,\n): TypedDigit {\n const { min, max } = segmentRange(kind, values, hourCycle);\n const digits = segmentDigits(kind);\n let next = text + digit;\n if (Number(next) > max || next.length > digits) {\n next = digit;\n }\n const number = Number(next);\n const advance = next.length >= digits || number * 10 > max;\n const complete = kind !== 'year' || next.length >= digits;\n return { value: complete && number >= min ? number : null, text: next, advance };\n}\n\n/**\n * The value of what was typed into a segment when focus leaves it: a year of one or two digits is\n * one of the 2000s (\"26\" is 2026), any other text its number when in range, else `null`.\n */\nexport function commitTyped(\n kind: SegmentKind,\n text: string,\n values: SegmentValues,\n hourCycle: HourCycle,\n): number | null {\n if (!text) {\n return values[kind] ?? null;\n }\n const number = Number(text);\n if (kind === 'year') {\n return text.length <= 2 ? 2000 + number : Math.max(1, number);\n }\n const { min, max } = segmentRange(kind, values, hourCycle);\n return number >= min && number <= max ? number : null;\n}\n\n/**\n * A segment moved by `delta` (Arrow Up +1, Arrow Down -1), wrapping inside its range. An empty\n * segment starts at `todayYear` for the year, else at its first value going up and its last going\n * down.\n */\nexport function stepSegment(\n kind: SegmentKind,\n values: SegmentValues,\n delta: number,\n hourCycle: HourCycle,\n todayYear: number,\n): number {\n const { min, max } = segmentRange(kind, values, hourCycle);\n const value = values[kind];\n if (value === null || value === undefined) {\n return kind === 'year' ? todayYear : delta > 0 ? min : max;\n }\n const size = max - min + 1;\n return min + ((((value - min + delta) % size) + size) % size);\n}\n\n/** The ISO date of the parts, or `null` while one is missing or the day is not in the month. */\nexport function composeDate(values: SegmentValues): string | null {\n const { day, month, year } = values;\n if (!day || !month || !year || day > daysInMonth(year, month)) {\n return null;\n }\n return formatIsoDate({ year, month, day });\n}\n\n/** The 24-hour hour of the hour and day-period parts, or `null` while one is missing. */\nfunction hour24(values: SegmentValues, hourCycle: HourCycle): number | null {\n const hour = values.hour;\n if (hour === null || hour === undefined) {\n return null;\n }\n if (hourCycle === 'h23') {\n return hour;\n }\n const period = values.dayPeriod;\n if (period === null || period === undefined) {\n return null;\n }\n return (hourCycle === 'h12' ? hour % 12 : hour) + period * 12;\n}\n\n/** The ISO time 'HH:mm' (or 'HH:mm:ss' with `seconds`) of the parts, or `null` while one is missing. */\nexport function composeTime(\n values: SegmentValues,\n hourCycle: HourCycle,\n seconds: boolean,\n): string | null {\n const hour = hour24(values, hourCycle);\n const { minute, second } = values;\n if (hour === null || minute === null || minute === undefined) {\n return null;\n }\n if (!seconds) {\n return `${pad(hour, 2)}:${pad(minute, 2)}`;\n }\n return second === null || second === undefined\n ? null\n : `${pad(hour, 2)}:${pad(minute, 2)}:${pad(second, 2)}`;\n}\n\n/** The field's ISO value of the parts, `null` while the entry is empty or incomplete. */\nexport function composeValue(\n mode: DateTimeMode,\n values: SegmentValues,\n hourCycle: HourCycle,\n seconds: boolean,\n): string | null {\n const date = mode === 'time' ? '' : composeDate(values);\n const time = mode === 'date' ? '' : composeTime(values, hourCycle, seconds);\n if (date === null || time === null) {\n return null;\n }\n return mode === 'datetime' ? `${date}T${time}` : date || time;\n}\n\n/** The hour, minute and second of an ISO time ('HH:mm' or 'HH:mm:ss'), or `null`. */\nexport function parseIsoTime(\n value: string | null | undefined,\n): { hour: number; minute: number; second: number } | null {\n const match = ISO_TIME.exec(value ?? '');\n if (!match) {\n return null;\n }\n const [hour, minute, second] = [Number(match[1]), Number(match[2]), Number(match[3] ?? 0)];\n return hour < 24 && minute < 60 && second < 60 ? { hour, minute, second } : null;\n}\n\n/** The date part of a value ('YYYY-MM-DD' of a date or a datetime), or `null`. */\nexport function datePartOf(mode: DateTimeMode, value: string | null | undefined): string | null {\n if (mode === 'time' || !value) {\n return null;\n }\n const date = mode === 'datetime' ? value.split('T')[0] : value;\n return parseIsoDate(date) ? (date ?? null) : null;\n}\n\n/** The time part of a value ('HH:mm[:ss]' of a time or a datetime), or `null`. */\nexport function timePartOf(mode: DateTimeMode, value: string | null | undefined): string | null {\n if (mode === 'date' || !value) {\n return null;\n }\n const time = mode === 'datetime' ? value.split('T')[1] : value;\n return parseIsoTime(time) ? (time ?? null) : null;\n}\n\n/** The parts of a valid ISO value for `mode`, or no parts for anything else. */\nexport function valuesFrom(\n mode: DateTimeMode,\n value: string | null | undefined,\n hourCycle: HourCycle,\n): SegmentValues {\n const date = parseIsoDate(datePartOf(mode, value));\n const time = parseIsoTime(timePartOf(mode, value));\n if ((mode !== 'time' && !date) || (mode !== 'date' && !time)) {\n return {};\n }\n return { ...(date ?? {}), ...(time ? timeValues(time, hourCycle) : {}) };\n}\n\nfunction timeValues(\n time: { hour: number; minute: number; second: number },\n hourCycle: HourCycle,\n): SegmentValues {\n const period = time.hour >= 12 ? 1 : 0;\n const hour =\n hourCycle === 'h23' ? time.hour : hourCycle === 'h12' ? time.hour % 12 || 12 : time.hour % 12;\n return {\n hour,\n minute: time.minute,\n second: time.second,\n ...(hourCycle === 'h23' ? {} : { dayPeriod: period }),\n };\n}\n\n/** The parts of an ISO date, to write into the field from the calendar. */\nexport function dateValues(iso: string): SegmentValues {\n return parseIsoDate(iso) ?? {};\n}\n\n/** The parts of an ISO time, to write into the field from the time list. */\nexport function timeValuesOf(iso: string, hourCycle: HourCycle): SegmentValues {\n const time = parseIsoTime(iso);\n return time ? timeValues(time, hourCycle) : {};\n}\n\n/** How far an entry is: nothing typed, some parts typed, or every part typed (valid or not). */\nexport type EntryState = 'empty' | 'partial' | 'filled';\n\n/** The entry state of `kinds` in `values`. */\nexport function entryState(kinds: readonly SegmentKind[], values: SegmentValues): EntryState {\n const filled = kinds.filter((kind) => values[kind] !== null && values[kind] !== undefined);\n return filled.length === 0 ? 'empty' : filled.length === kinds.length ? 'filled' : 'partial';\n}\n\n/** The time parts of `segmentKinds` (hour, minute, second, day period). */\nexport function timeKindsOf(kinds: readonly SegmentKind[]): SegmentKind[] {\n return kinds.filter((kind) => !DATE_KINDS.includes(kind));\n}\n\n/** The date parts of `segmentKinds` (day, month, year). */\nexport function dateKindsOf(kinds: readonly SegmentKind[]): SegmentKind[] {\n return kinds.filter((kind) => DATE_KINDS.includes(kind));\n}\n\n/** One time in the picker list. */\nexport interface TimeOption {\n /** The ISO time, 'HH:mm' (or 'HH:mm:ss'). */\n readonly value: string;\n /** The time as the locale writes it. */\n readonly label: string;\n}\n\n/** A formatter of ISO times ('HH:mm[:ss]') in `locale` and `hourCycle`. */\nexport function timeFormatter(\n locale: string,\n hourCycle: HourCycle,\n seconds: boolean,\n): (iso: string) => string {\n const format = new Intl.DateTimeFormat(locale, {\n hour: '2-digit',\n minute: '2-digit',\n ...(seconds ? { second: '2-digit' } : {}),\n hourCycle,\n numberingSystem: 'latn',\n timeZone: 'UTC',\n });\n return (iso) => {\n const time = parseIsoTime(iso);\n if (!time) {\n return iso;\n }\n const date = utcInstant(2001, 1, 1, time.hour * 60 + time.minute);\n date.setUTCSeconds(time.second);\n return format.format(date);\n };\n}\n\n/** The times of a day every `step` minutes from midnight, written by `format`. */\nexport function timeOptions(\n step: number,\n seconds: boolean,\n format: (iso: string) => string,\n): TimeOption[] {\n const every = Math.min(Math.max(Math.round(step) || 30, 1), 720);\n const options: TimeOption[] = [];\n for (let minutes = 0; minutes < 1440; minutes += every) {\n const value = `${pad(Math.floor(minutes / 60), 2)}:${pad(minutes % 60, 2)}${seconds ? ':00' : ''}`;\n options.push({ value, label: format(value) });\n }\n return options;\n}\n\n/** A segment's text: the value padded to its digits, or the day period's name. */\nexport function segmentText(\n kind: SegmentKind,\n value: number,\n periods: readonly [string, string],\n): string {\n return kind === 'dayPeriod' ? (periods[value] ?? '') : pad(value, segmentDigits(kind));\n}\n\n/**\n * An empty segment's placeholder: the first letter of its name, once per digit (\"Day\" → \"dd\",\n * \"Jahr\" → \"jjjj\"); the day period shows two dashes.\n */\nexport function segmentPlaceholder(kind: SegmentKind, name: string): string {\n const letter = name.trim().charAt(0).toLocaleLowerCase();\n return kind === 'dayPeriod' || !letter ? '––' : letter.repeat(segmentDigits(kind));\n}\n","import { Overlay } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport { Location } from '@angular/common';\nimport {\n Component,\n DOCUMENT,\n DestroyRef,\n ElementRef,\n Injector,\n type TemplateRef,\n ViewContainerRef,\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n linkedSignal,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { type ValidationError } from '@angular/forms/signals';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n BfCalendarComponent,\n type BfCalendarDisabledDate,\n BfFieldComponent,\n type BfSize,\n bfFieldControlClass,\n ɵFIELD_BOX as FIELD_BOX,\n ɵFIELD_PADDING_END as FIELD_PADDING_END,\n ɵFIELD_PADDING_START as FIELD_PADDING_START,\n ɵfieldDescribedBy as fieldDescribedBy,\n ɵfieldErrorMessageId as fieldErrorMessageId,\n ɵfieldErrorText as fieldErrorText,\n ɵfieldShowsError as fieldShowsError,\n ɵlocalIsoDate as localIsoDate,\n ɵparseIsoDate as parseIsoDate,\n} from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport {\n type AnchoredOverlay,\n blockPositions,\n createAnchoredOverlay,\n} from '../core/anchored-overlay';\nimport { watchPathChange } from '../core/navigation';\nimport { TABBABLE } from '../core/overlay.service';\nimport { POPOVER_SURFACE } from '../popover/popover.component';\nimport {\n type DateTimeMode,\n type HourCycle,\n type LayoutItem,\n type SegmentKind,\n type SegmentValues,\n type TimeOption,\n commitTyped,\n composeDate,\n composeValue,\n dateKindsOf,\n datePartOf,\n dateValues,\n dayPeriodNames,\n entryState,\n parseIsoTime,\n resolveHourCycle,\n segmentKinds,\n segmentLayout,\n segmentPlaceholder,\n segmentRange,\n segmentText,\n stepSegment,\n timeFormatter,\n timeKindsOf,\n timeOptions,\n timePartOf,\n timeValuesOf,\n typeDigit,\n valuesFrom,\n} from './date-time-segments';\n\n/** One rendered segment of the field, as the template binds it. */\ninterface SegmentView {\n readonly type: 'segment';\n readonly kind: SegmentKind;\n readonly id: string;\n readonly name: string;\n readonly text: string;\n readonly empty: boolean;\n readonly min: number;\n readonly max: number;\n readonly now: number | null;\n readonly valueText: string | null;\n}\n\n/** The text between two parts. */\ntype LiteralItem = Extract<LayoutItem, { type: 'literal' }>;\n\n/** One rendered time of the picker list. */\ninterface TimeOptionView extends TimeOption {\n readonly id: string;\n readonly disabled: boolean;\n readonly selected: boolean;\n readonly active: boolean;\n}\n\n/** Digits typed into one segment since it took focus. */\ninterface Typing {\n readonly kind: SegmentKind;\n readonly text: string;\n}\n\n/* The field box: bf-input's look on a group of segments, with the focus ring drawn while any part\n inside it has focus. */\nconst BOX_BASE =\n 'relative flex w-full items-center gap-1 rounded-field border transition-colors ' +\n 'focus-within:border-primary focus-within:ring-2 focus-within:ring-ring';\n/* Room at the inline end for the picker button, which sits 3 px inside the border at every step. */\nconst PICKER_PADDING_END: Record<BfSize, string> = { sm: 'pe-1', md: 'pe-1', lg: 'pe-1' };\n\n/* A part: at least 24 × 24 px (the fine-pointer target size), tinted while it has focus. */\nconst SEGMENT =\n 'inline-flex h-6 min-w-6 items-center justify-center rounded-checkbox px-0.5 tabular-nums ' +\n 'outline-hidden select-none focus:bg-primary-soft focus:text-primary-text';\n\n/* The picker button: square, 3 px inside the field's border, 44 px under a coarse pointer. */\nconst TRIGGER_BASE =\n 'relative inline-flex shrink-0 cursor-pointer items-center justify-center rounded-control text-text-muted ' +\n 'transition-colors duration-150 enabled:hover:bg-surface-muted enabled:hover:text-text enabled:active:bg-surface-pressed ' +\n 'focus-visible:outline-hidden focus-visible:ring-4 focus-visible:ring-ring disabled:cursor-not-allowed disabled:text-text-disabled ' +\n \"pointer-coarse:after:absolute pointer-coarse:after:content-['']\";\nconst TRIGGER_SIZE: Record<BfSize, string> = {\n sm: 'size-6 pointer-coarse:after:-inset-2.5',\n md: 'size-8 pointer-coarse:after:-inset-1.5',\n lg: 'size-10 pointer-coarse:after:-inset-0.5',\n};\n\n/* The marks are CSS borders, so no icon is imported: a calendar sheet with two rings on top, and a\n clock face with its hands from the centre. */\nconst CALENDAR_MARK =\n 'relative block h-3.5 w-4 border-[1.5px] border-t-[3px] border-current ' +\n \"before:absolute before:-top-[6px] before:start-[2px] before:h-1 before:w-[1.5px] before:bg-current before:content-[''] \" +\n \"after:absolute after:-top-[6px] after:end-[2px] after:h-1 after:w-[1.5px] after:bg-current after:content-['']\";\nconst CLOCK_MARK =\n 'relative block size-4 rounded-control border-[1.5px] border-current ' +\n 'after:absolute after:start-[calc(50%-0.75px)] after:bottom-[calc(50%-0.75px)] after:h-1.5 after:w-1 ' +\n \"after:border-s-[1.5px] after:border-b-[1.5px] after:border-current after:content-['']\";\n\n/* The time list: a column of pills, as tall as the calendar beside it. The active option carries\n the focus ring while the list has keyboard focus. */\nconst LIST =\n 'group/list relative flex max-h-72 w-32 shrink-0 flex-col gap-0.5 overflow-y-auto overscroll-contain outline-hidden';\nconst OPTION =\n 'flex h-9 shrink-0 items-center justify-center rounded-control px-3 text-label-sm tabular-nums select-none ' +\n 'transition-colors duration-150 pointer-coarse:h-hit';\ntype OptionState = 'normal' | 'selected' | 'disabled';\nconst OPTION_STATE: Record<OptionState, string> = {\n normal: 'cursor-pointer text-text hover:bg-surface-muted',\n selected: 'cursor-pointer bg-primary font-bold text-on-primary',\n disabled: 'cursor-not-allowed text-text-disabled',\n};\nconst OPTION_ACTIVE =\n 'group-focus-visible/list:ring-2 group-focus-visible/list:ring-ring group-focus-visible/list:ring-inset';\n\n/** `locale` when the runtime accepts the tag, else `null`. */\nfunction supportedLocale(locale: string): string | null {\n try {\n return locale ? new Intl.Locale(locale).toString() : null;\n } catch {\n return null;\n }\n}\n\n/** A time ('HH:mm' or 'HH:mm:ss') with its seconds, so two times compare as strings. */\nfunction timeKey(time: string): string {\n return time.length === 5 ? `${time}:00` : time;\n}\n\n/** A value of `mode` written so two values compare in time order as strings. */\nfunction comparable(mode: DateTimeMode, value: string): string {\n if (mode === 'date') {\n return value;\n }\n if (mode === 'time') {\n return timeKey(value);\n }\n const [date = '', time = ''] = value.split('T');\n return `${date}T${timeKey(time)}`;\n}\n\n/** A local `Date` of an ISO date, for the `minDate` / `maxDate` validation messages only. */\nfunction localDate(iso: string): Date {\n const parts = parseIsoDate(iso);\n const date = new Date(2000, 0, 1);\n if (parts) {\n date.setFullYear(parts.year, parts.month - 1, parts.day);\n }\n return date;\n}\n\n/**\n * The segmented field behind `bf-date-input`, `bf-time-input` and `bf-datetime-input`: the label,\n * help and error text of `bf-field` around a group of spinbutton parts in the locale's order, a\n * picker button opening a calendar and/or a list of times in an anchored panel, and a native\n * `input` under a coarse pointer when `native` is set. Internal: the public components wrap it\n * and pass every input through.\n */\n@Component({\n selector: 'bf-date-time-field',\n imports: [BfFieldComponent, BfCalendarComponent],\n host: { class: 'block', '(click)': 'onHostClick($event)' },\n template: `\n <bf-field\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [error]=\"errorText()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n [controlId]=\"id()\"\n >\n @if (nativeMode()) {\n <input\n #nativeInput\n [type]=\"nativeType()\"\n [id]=\"id()\"\n [name]=\"name()\"\n [value]=\"value() ?? ''\"\n [attr.min]=\"validMin()\"\n [attr.max]=\"validMax()\"\n [attr.step]=\"nativeStep()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [attr.aria-label]=\"ariaLabelAttr()\"\n [attr.aria-labelledby]=\"ariaLabelledbyAttr()\"\n [attr.aria-invalid]=\"showError() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-errormessage]=\"errorMessageId()\"\n [class]=\"nativeClasses()\"\n (change)=\"onNativeChange(nativeInput)\"\n (blur)=\"markLeft()\"\n />\n } @else {\n <div\n #box\n role=\"group\"\n [id]=\"id()\"\n [attr.aria-label]=\"label() || ariaLabelAttr()\"\n [attr.aria-labelledby]=\"ariaLabelledbyAttr()\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n [attr.data-value]=\"value() ?? ''\"\n [class]=\"boxClasses()\"\n (focusout)=\"onFocusout($event)\"\n >\n <div class=\"flex min-w-0 flex-1 items-center whitespace-nowrap\">\n @for (item of segments(); track $index) {\n @if (item.type === 'literal') {\n <span aria-hidden=\"true\" [class]=\"literalClasses()\">{{ item.text }}</span>\n } @else {\n <span\n role=\"spinbutton\"\n [id]=\"item.id\"\n [attr.data-segment]=\"item.kind\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-label]=\"item.name\"\n [attr.aria-valuemin]=\"item.min\"\n [attr.aria-valuemax]=\"item.max\"\n [attr.aria-valuenow]=\"item.now\"\n [attr.aria-valuetext]=\"item.valueText\"\n [attr.aria-invalid]=\"showError() ? 'true' : null\"\n [attr.aria-errormessage]=\"errorMessageId()\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-readonly]=\"readonly() ? 'true' : null\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n [class]=\"segmentClasses(item)\"\n (keydown)=\"onSegmentKeydown($event, item.kind)\"\n (blur)=\"onSegmentBlur(item.kind)\"\n >{{ item.text }}</span\n >\n }\n }\n </div>\n @if (picker()) {\n <button\n #trigger\n type=\"button\"\n [id]=\"id() + '-trigger'\"\n [disabled]=\"disabled() || readonly()\"\n [attr.aria-label]=\"triggerLabel()\"\n aria-haspopup=\"dialog\"\n [attr.aria-expanded]=\"pickerOpen()\"\n [attr.aria-controls]=\"pickerOpen() ? panelId() : null\"\n [attr.data-bf-date-time-trigger]=\"''\"\n [class]=\"triggerClasses()\"\n (click)=\"togglePicker()\"\n >\n <span\n aria-hidden=\"true\"\n [class]=\"mode() === 'time' ? clockMark : calendarMark\"\n ></span>\n </button>\n }\n </div>\n }\n </bf-field>\n\n <ng-template #panel>\n <div\n role=\"dialog\"\n [id]=\"panelId()\"\n [attr.aria-labelledby]=\"id() + '-trigger'\"\n [class]=\"panelClasses()\"\n >\n <div class=\"flex flex-wrap items-start gap-3\">\n @if (mode() !== 'time') {\n <bf-calendar\n [label]=\"label() || ariaLabel() || triggerLabel()\"\n [value]=\"datePart()\"\n [min]=\"calendarMin()\"\n [max]=\"calendarMax()\"\n [disabledDate]=\"disabledDate()\"\n [locale]=\"resolvedLocale()\"\n (picked)=\"onDatePicked($event)\"\n />\n }\n @if (mode() !== 'date') {\n <div\n #list\n role=\"listbox\"\n tabindex=\"0\"\n [id]=\"id() + '-times'\"\n [attr.aria-label]=\"labels.timeInputOpenList\"\n [attr.aria-activedescendant]=\"activeOptionId()\"\n [class]=\"listClasses()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n >\n @for (option of timeOptionViews(); track option.value) {\n <div\n role=\"option\"\n [id]=\"option.id\"\n [attr.data-time]=\"option.value\"\n [attr.aria-selected]=\"option.selected\"\n [attr.aria-disabled]=\"option.disabled ? 'true' : null\"\n [class]=\"optionClasses(option)\"\n >\n {{ option.label }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n </ng-template>\n `,\n})\nexport class BfDateTimeFieldComponent {\n private readonly overlay = inject(Overlay);\n private readonly document = inject(DOCUMENT);\n private readonly injector = inject(Injector);\n private readonly viewContainer = inject(ViewContainerRef);\n private readonly location = inject(Location);\n private readonly defaults = inject(BF_DEFAULTS);\n private readonly hostEl = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n /** The strings in effect; the template reads the list name from them. */\n protected readonly labels = inject(BF_LABELS);\n\n /** What the field edits: a date, a time of day, or both. */\n readonly mode = input.required<DateTimeMode>();\n /** The ISO value, `null` while empty or incomplete. */\n readonly value = model<string | null>(null);\n /** The earliest valid value (ISO, in the mode's format). */\n readonly min = input<string | undefined>(undefined);\n /** The latest valid value (ISO, in the mode's format). */\n readonly max = input<string | undefined>(undefined);\n /** Dates the calendar shows disabled, and that show an error when typed. */\n readonly disabledDate = input<BfCalendarDisabledDate | null>(null);\n /** Whether the field has a picker button. */\n readonly picker = input(true, { transform: booleanAttribute });\n /** Renders the platform's input under a coarse pointer. */\n readonly native = input(false, { transform: booleanAttribute });\n /** Adds a seconds part (time mode only). */\n readonly seconds = input(false, { transform: booleanAttribute });\n /** Minutes between the times of the list. */\n readonly step = input(30);\n /** Forces a 12- or 24-hour clock; unset follows the locale. */\n readonly hourCycle = input<'h12' | 'h23' | undefined>(undefined);\n /** BCP 47 locale; empty follows the document's `lang`, else English. */\n readonly locale = input('');\n /** Height step; unset follows `fieldSize`. */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name without a visible label. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field without a visible label. */\n readonly ariaLabelledby = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text. */\n readonly errorMessage = input('');\n /** Disables the field. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the value but blocks changes. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute (native mode). */\n readonly name = input('');\n /** The field's id. */\n readonly id = input.required<string>();\n\n /** Emitted with the new value right after a user change. */\n readonly changed = output<string | null>();\n /** Emitted when focus leaves the field (not into its picker). */\n readonly touch = output<void>();\n\n private readonly box = viewChild<ElementRef<HTMLElement>>('box');\n private readonly trigger = viewChild<ElementRef<HTMLButtonElement>>('trigger');\n private readonly panel = viewChild.required<TemplateRef<unknown>>('panel');\n\n /** Whether the primary pointer is coarse (touch), from `matchMedia`. */\n private readonly coarse = signal(false);\n /** Digits typed into the focused segment since it took focus. */\n private readonly typing = signal<Typing | null>(null);\n /** Whether focus has left the field once; its own errors show from then on. */\n private readonly left = signal(false);\n /** Whether the picker panel is open. */\n protected readonly pickerOpen = signal(false);\n /** The time the list's keyboard focus is on. */\n private readonly activeTime = signal<string | null>(null);\n\n protected readonly calendarMark = CALENDAR_MARK;\n protected readonly clockMark = CLOCK_MARK;\n\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.fieldSize);\n /** The locale in effect: `locale`, else the document's `lang`, else English. */\n readonly resolvedLocale = computed(\n () =>\n supportedLocale(this.locale()) ?? supportedLocale(this.document.documentElement.lang) ?? 'en',\n );\n /** Whether the field has a seconds part. */\n private readonly hasSeconds = computed(() => this.mode() === 'time' && this.seconds());\n /** The hour cycle in effect: `hourCycle`, else the locale's. */\n readonly cycle = computed<HourCycle>(() =>\n this.mode() === 'date' ? 'h23' : resolveHourCycle(this.resolvedLocale(), this.hourCycle()),\n );\n private readonly kinds = computed(() =>\n segmentKinds(this.mode(), this.hasSeconds(), this.cycle()),\n );\n private readonly layout = computed<LayoutItem[]>(() =>\n segmentLayout(this.resolvedLocale(), this.mode(), this.hasSeconds(), this.cycle()),\n );\n /** The segments in the order they are laid out. */\n private readonly order = computed(() =>\n this.layout().flatMap((item) => (item.type === 'segment' ? [item.kind] : [])),\n );\n private readonly periods = computed(() => dayPeriodNames(this.resolvedLocale()));\n private readonly monthNames = computed(() => {\n const format = new Intl.DateTimeFormat(this.resolvedLocale(), {\n month: 'long',\n timeZone: 'UTC',\n });\n return Array.from({ length: 12 }, (_, i) => format.format(new Date(Date.UTC(2001, i, 1))));\n });\n private readonly formatTime = computed(() =>\n timeFormatter(this.resolvedLocale(), this.cycle(), this.hasSeconds()),\n );\n\n /**\n * The parts on show. They follow `value`; a value the parts already stand for (an incomplete\n * entry is `null`) keeps them, so typing is never undone by its own value.\n */\n private readonly parts = linkedSignal<\n { value: string | null; mode: DateTimeMode; cycle: HourCycle; seconds: boolean },\n SegmentValues\n >({\n source: () => ({\n value: this.value(),\n mode: this.mode(),\n cycle: this.cycle(),\n seconds: this.hasSeconds(),\n }),\n computation: (source, previous) =>\n previous?.source.cycle === source.cycle &&\n previous.source.mode === source.mode &&\n composeValue(source.mode, previous.value, source.cycle, source.seconds) === source.value\n ? previous.value\n : valuesFrom(source.mode, source.value, source.cycle),\n });\n\n private readonly segmentNames = computed<Record<SegmentKind, string>>(() => ({\n day: this.labels.dateInputDay,\n month: this.labels.dateInputMonth,\n year: this.labels.dateInputYear,\n hour: this.labels.timeInputHour,\n minute: this.labels.timeInputMinute,\n second: this.labels.timeInputSecond,\n dayPeriod: this.labels.timeInputDayPeriod,\n }));\n\n /** The layout with each segment's text and ARIA state. */\n protected readonly segments = computed<(SegmentView | LiteralItem)[]>(() => {\n const values = this.parts();\n const typing = this.typing();\n const names = this.segmentNames();\n return this.layout().map((item) => {\n if (item.type === 'literal') {\n return item;\n }\n const kind = item.kind;\n const value = values[kind] ?? null;\n const typed = typing?.kind === kind ? typing.text : '';\n const range = segmentRange(kind, values, this.cycle());\n const text =\n typed ||\n (value === null\n ? segmentPlaceholder(kind, names[kind])\n : segmentText(kind, value, this.periods()));\n return {\n type: 'segment',\n kind,\n id: `${this.id()}-${kind}`,\n name: names[kind],\n text,\n empty: !typed && value === null,\n min: range.min,\n max: range.max,\n now: value,\n valueText: typed || (value === null ? null : this.valueText(kind, value)),\n };\n });\n });\n\n /** The value's date part, for the calendar. */\n protected readonly datePart = computed(() => datePartOf(this.mode(), this.value()));\n /** `min` when it is a valid value of the mode, else `null`. */\n protected readonly validMin = computed(() => this.validBound(this.min()));\n /** `max` when it is a valid value of the mode, else `null`. */\n protected readonly validMax = computed(() => this.validBound(this.max()));\n protected readonly calendarMin = computed(\n () => datePartOf(this.mode(), this.validMin()) ?? undefined,\n );\n protected readonly calendarMax = computed(\n () => datePartOf(this.mode(), this.validMax()) ?? undefined,\n );\n\n /** The field's own error: an incomplete or impossible entry, or a value outside the limits. */\n private readonly ownError = computed(() => {\n const values = this.parts();\n const kinds = this.kinds();\n const date = entryState(dateKindsOf(kinds), values);\n const time = entryState(timeKindsOf(kinds), values);\n if (date === 'empty' && time === 'empty') {\n return '';\n }\n if (this.mode() !== 'time' && (date !== 'filled' || composeDate(values) === null)) {\n return this.labels.dateInputInvalid;\n }\n if (this.mode() !== 'date' && time !== 'filled') {\n return this.labels.timeInputInvalid;\n }\n const value = this.value();\n return value ? this.rangeError(value) : '';\n });\n\n /** The error shown: `errorMessage`, else the field's own once left, else the form's. */\n protected readonly errorText = computed(() => {\n const own = this.left() || this.touched() ? this.ownError() : '';\n return (\n this.errorMessage() ||\n own ||\n fieldErrorText('', this.touched(), this.errors(), this.labels.validation)\n );\n });\n protected readonly showError = computed(() =>\n fieldShowsError(this.errorText(), this.invalid(), this.touched()),\n );\n protected readonly describedBy = computed(() =>\n fieldDescribedBy(this.id(), this.errorText(), this.helpText()),\n );\n protected readonly errorMessageId = computed(() =>\n fieldErrorMessageId(this.id(), this.errorText(), this.showError()),\n );\n protected readonly ariaLabelAttr = computed(() =>\n this.label() ? null : this.ariaLabel() || null,\n );\n protected readonly ariaLabelledbyAttr = computed(() =>\n this.label() ? null : this.ariaLabelledby() || null,\n );\n\n /** Whether the platform's input is rendered instead of the segments. */\n protected readonly nativeMode = computed(() => this.native() && this.coarse());\n protected readonly nativeType = computed(() =>\n this.mode() === 'datetime' ? 'datetime-local' : this.mode(),\n );\n protected readonly nativeStep = computed(() => (this.hasSeconds() ? 1 : null));\n protected readonly nativeClasses = computed(() =>\n bfFieldControlClass({\n size: this.resolvedSize(),\n invalid: this.showError(),\n disabled: this.disabled(),\n readonly: this.readonly(),\n }),\n );\n\n protected readonly triggerLabel = computed(() =>\n this.mode() === 'time' ? this.labels.timeInputOpenList : this.labels.dateInputOpenCalendar,\n );\n protected readonly panelId = computed(() => `${this.id()}-picker`);\n\n protected readonly boxClasses = computed(() => {\n const size = this.resolvedSize();\n const state = this.disabled()\n ? 'cursor-not-allowed border-surface-sunken bg-surface-muted text-text-disabled'\n : [\n this.readonly() ? 'bg-surface-muted text-text' : 'bg-surface text-text cursor-text',\n this.showError()\n ? 'border-danger-border hover:border-danger'\n : 'border-border-strong hover:border-text-muted',\n ].join(' ');\n return [\n BOX_BASE,\n FIELD_BOX[size],\n FIELD_PADDING_START[size].text,\n this.picker() ? PICKER_PADDING_END[size] : FIELD_PADDING_END[size].text,\n state,\n ].join(' ');\n });\n protected readonly literalClasses = computed(() =>\n this.disabled() ? 'whitespace-pre text-text-disabled' : 'whitespace-pre text-text-muted',\n );\n protected readonly triggerClasses = computed(\n () => `${TRIGGER_BASE} ${TRIGGER_SIZE[this.resolvedSize()]}`,\n );\n protected readonly panelClasses = computed(\n () => `${POPOVER_SURFACE} ${this.mode() === 'time' ? 'p-1.5' : 'p-3'}`,\n );\n protected readonly listClasses = computed(() => LIST);\n\n /** The times of the list, with their state. */\n private readonly options = computed(() =>\n timeOptions(this.step(), this.hasSeconds(), this.formatTime()),\n );\n /** The time limits of the list: `min`/`max` of a time, or of a datetime on the limit's day. */\n private readonly timeBounds = computed(() => {\n const mode = this.mode();\n const min = this.validMin();\n const max = this.validMax();\n if (mode === 'time') {\n return { lower: min, upper: max };\n }\n const date = composeDate(this.parts());\n return {\n lower: min && date === datePartOf(mode, min) ? timePartOf(mode, min) : null,\n upper: max && date === datePartOf(mode, max) ? timePartOf(mode, max) : null,\n };\n });\n protected readonly timeOptionViews = computed<TimeOptionView[]>(() => {\n const selected = timePartOf(this.mode(), this.value());\n const active = this.activeTime();\n return this.options().map((option) => ({\n ...option,\n id: `${this.id()}-time-${option.value.replace(/:/g, '')}`,\n disabled: this.timeDisabled(option.value),\n selected: selected !== null && timeKey(selected) === timeKey(option.value),\n active: option.value === active,\n }));\n });\n protected readonly activeOptionId = computed(\n () => this.timeOptionViews().find((option) => option.active)?.id ?? null,\n );\n\n private anchored: AnchoredOverlay | null = null;\n private subscriptions: Subscription[] = [];\n private stopNavigation: (() => void) | null = null;\n\n constructor() {\n const media = this.document.defaultView?.matchMedia?.('(pointer: coarse)');\n if (media) {\n this.coarse.set(media.matches);\n const onChange = (event: MediaQueryListEvent): void => this.coarse.set(event.matches);\n media.addEventListener?.('change', onChange);\n inject(DestroyRef).onDestroy(() => media.removeEventListener?.('change', onChange));\n }\n inject(DestroyRef).onDestroy(() => this.teardown());\n }\n\n /**\n * Focuses the first empty part (else the first part), or the native input.\n * @param options Passed on to the native `focus()`.\n */\n focus(options?: FocusOptions): void {\n const native = this.hostEl.querySelector<HTMLElement>('input');\n if (native) {\n native.focus(options);\n return;\n }\n const values = this.parts();\n const kind = this.order().find((k) => values[k] === null || values[k] === undefined);\n this.segmentElement(kind ?? this.order()[0])?.focus(options);\n }\n\n /** Opens the picker panel; does nothing while it is open, disabled or read-only. */\n openPicker(): void {\n const box = this.box()?.nativeElement;\n if (this.anchored || !box || !this.picker() || this.disabled() || this.readonly()) {\n return;\n }\n const direction = getComputedStyle(box).direction === 'rtl' ? 'rtl' : 'ltr';\n const anchored = createAnchoredOverlay(this.overlay, box, {\n positions: blockPositions('below-start'),\n direction,\n panelClass: ['bf-date-time-panel'],\n });\n this.anchored = anchored;\n this.activeTime.set(this.initialTime());\n anchored.ref.attach(\n new TemplatePortal(this.panel(), this.viewContainer, undefined, this.injector),\n );\n const pane = anchored.ref.overlayElement;\n this.subscriptions = [\n // The CDK hands a key to the topmost overlay: a dialog underneath stays open.\n anchored.ref.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.closePicker();\n }\n }),\n anchored.ref.outsidePointerEvents().subscribe((event) => {\n // A click on the button toggles the panel itself.\n const trigger = this.trigger()?.nativeElement;\n if (trigger && event.target instanceof Node && trigger.contains(event.target)) {\n return;\n }\n // Focus returns only when it would otherwise be lost: a click on a part keeps it there.\n const active = this.document.activeElement;\n this.closePicker(!active || active === this.document.body || pane.contains(active));\n }),\n ];\n pane.addEventListener('keydown', (event) => this.tabbed(event, pane));\n this.stopNavigation = watchPathChange(this.location, () => this.closePicker(false));\n this.pickerOpen.set(true);\n afterNextRender(() => this.focusPanel(pane), { injector: this.injector });\n }\n\n /**\n * Closes the picker panel; does nothing while it is closed.\n * @param restoreFocus Moves focus back to the picker button (default true).\n */\n closePicker(restoreFocus = true): void {\n if (!this.anchored) {\n return;\n }\n this.teardown();\n this.pickerOpen.set(false);\n if (restoreFocus) {\n this.trigger()?.nativeElement.focus({ preventScroll: true });\n } else if (!this.hostEl.contains(this.document.activeElement)) {\n this.markLeft();\n }\n }\n\n /**\n * The picker button: opens the panel, or closes it when open.\n * @internal\n */\n togglePicker(): void {\n if (this.anchored) {\n this.closePicker();\n } else {\n this.openPicker();\n }\n }\n\n /**\n * A click on the label or on the field box outside the parts focuses the first empty part.\n * @internal\n */\n onHostClick(event: MouseEvent): void {\n const target = event.target;\n if (this.disabled() || this.nativeMode() || !(target instanceof Element)) {\n return;\n }\n if (target.closest('[data-segment], button')) {\n return;\n }\n if (target.closest('label') || this.box()?.nativeElement.contains(target)) {\n this.focus();\n }\n }\n\n /**\n * The keys of one part: digits type, arrows step and move, Backspace clears.\n * @internal\n */\n onSegmentKeydown(event: KeyboardEvent, kind: SegmentKind): void {\n if (event.ctrlKey || event.metaKey) {\n return;\n }\n const key = event.key;\n if (event.altKey) {\n if (key === 'ArrowDown' && this.picker()) {\n event.preventDefault();\n this.openPicker();\n }\n return;\n }\n const editable = !this.disabled() && !this.readonly();\n if (key === 'ArrowLeft' || key === 'ArrowRight') {\n event.preventDefault();\n const rtl = getComputedStyle(event.target as Element).direction === 'rtl';\n this.moveFocus(kind, (key === 'ArrowRight') !== rtl ? 1 : -1);\n return;\n }\n if (!editable) {\n return;\n }\n if (key === 'ArrowUp' || key === 'ArrowDown') {\n event.preventDefault();\n this.typing.set(null);\n const values = this.parts();\n const today = Number(localIsoDate().slice(0, 4));\n const delta = key === 'ArrowUp' ? 1 : -1;\n this.writeParts({ ...values, [kind]: stepSegment(kind, values, delta, this.cycle(), today) });\n } else if (key === 'Backspace' || key === 'Delete') {\n event.preventDefault();\n this.clearSegment(kind, key === 'Backspace');\n } else if (/^\\d$/.test(key) && kind !== 'dayPeriod') {\n event.preventDefault();\n this.typeInto(kind, key);\n } else if (kind === 'dayPeriod' && key.length === 1) {\n const locale = this.resolvedLocale();\n const typed = key.toLocaleLowerCase(locale);\n const period = this.periods().findIndex((name) =>\n name.toLocaleLowerCase(locale).startsWith(typed),\n );\n if (period >= 0) {\n event.preventDefault();\n this.writeParts({ ...this.parts(), dayPeriod: period });\n }\n } else if (key.length === 1 && /[\\s./\\-:,]/.test(key)) {\n // A separator moves on from a part that holds something, as typing \"14/\" would.\n event.preventDefault();\n if (this.typing()?.kind === kind || (this.parts()[kind] ?? null) !== null) {\n this.moveFocus(kind, 1);\n }\n }\n }\n\n /**\n * Leaving a part commits what was typed into it (\"26\" in the year is 2026).\n * @internal\n */\n onSegmentBlur(kind: SegmentKind): void {\n const typing = this.typing();\n if (typing?.kind !== kind) {\n return;\n }\n this.typing.set(null);\n const values = this.parts();\n this.writeParts({ ...values, [kind]: commitTyped(kind, typing.text, values, this.cycle()) });\n }\n\n /**\n * Focus leaving the field (not into its picker) marks it touched.\n * @internal\n */\n onFocusout(event: FocusEvent): void {\n const next = event.relatedTarget;\n if (next instanceof Node && this.box()?.nativeElement.contains(next)) {\n return;\n }\n if (\n this.pickerOpen() ||\n (next instanceof Node && this.anchored?.ref.overlayElement.contains(next))\n ) {\n return;\n }\n this.markLeft();\n }\n\n /**\n * Marks the field left and touched.\n * @internal\n */\n markLeft(): void {\n this.left.set(true);\n this.touch.emit();\n }\n\n /**\n * The native input's value, written to the model.\n * @internal\n */\n onNativeChange(el: HTMLInputElement): void {\n const raw = el.value;\n const mode = this.mode();\n const value =\n mode === 'datetime'\n ? raw.slice(0, 16)\n : mode === 'time' && !this.hasSeconds()\n ? raw.slice(0, 5)\n : raw;\n const next = this.validBound(value);\n if (next !== this.value()) {\n this.value.set(next);\n this.changed.emit(next);\n }\n }\n\n /**\n * The calendar's pick: the date in a date input (closing the panel), the date part in a\n * datetime input (moving on to the time list).\n * @internal\n */\n onDatePicked(iso: string): void {\n this.typing.set(null);\n this.writeParts({ ...this.parts(), ...dateValues(iso) });\n if (this.mode() === 'date') {\n this.closePicker();\n return;\n }\n this.activeTime.set(this.initialTime());\n const pane = this.anchored?.ref.overlayElement;\n if (pane) {\n afterNextRender(() => this.focusList(pane), { injector: this.injector });\n }\n }\n\n /**\n * Picks a time from the list and closes the panel; ignored for a disabled time.\n * @internal\n */\n pickTime(time: string): void {\n if (this.timeDisabled(time)) {\n return;\n }\n this.typing.set(null);\n this.writeParts({ ...this.parts(), ...timeValuesOf(time, this.cycle()) });\n this.closePicker();\n }\n\n /**\n * A click on a time of the list picks it.\n * @internal\n */\n onListClick(event: MouseEvent): void {\n const option =\n event.target instanceof Element ? event.target.closest<HTMLElement>('[data-time]') : null;\n const time = option?.dataset['time'];\n if (time) {\n this.pickTime(time);\n }\n }\n\n /**\n * The list's keys: arrows, Home and End move, Enter and Space pick.\n * @internal\n */\n onListKeydown(event: KeyboardEvent): void {\n const enabled = this.timeOptionViews().filter((option) => !option.disabled);\n const index = enabled.findIndex((option) => option.active);\n let next: TimeOptionView | undefined;\n switch (event.key) {\n case 'ArrowDown':\n next = enabled[Math.min(index + 1, enabled.length - 1)];\n break;\n case 'ArrowUp':\n next = enabled[Math.max(index - 1, 0)];\n break;\n case 'Home':\n next = enabled[0];\n break;\n case 'End':\n next = enabled[enabled.length - 1];\n break;\n case 'Enter':\n case ' ': {\n event.preventDefault();\n const active = this.activeTime();\n if (active) {\n this.pickTime(active);\n }\n return;\n }\n default:\n return;\n }\n event.preventDefault();\n if (next) {\n this.activeTime.set(next.value);\n const list = event.currentTarget as HTMLElement;\n afterNextRender(() => this.scrollToActive(list, false), { injector: this.injector });\n }\n }\n\n /** @internal */\n segmentClasses(item: SegmentView): string {\n return item.empty && !this.disabled() ? `${SEGMENT} text-text-muted` : SEGMENT;\n }\n\n /** @internal */\n optionClasses(option: TimeOptionView): string {\n const state: OptionState = option.disabled\n ? 'disabled'\n : option.selected\n ? 'selected'\n : 'normal';\n const active = option.active\n ? ` ${OPTION_ACTIVE}${state === 'normal' ? ' bg-surface-muted' : ''}`\n : '';\n return `${OPTION} ${OPTION_STATE[state]}${active}`;\n }\n\n private valueText(kind: SegmentKind, value: number): string {\n if (kind === 'month') {\n return this.monthNames()[value - 1] ?? String(value);\n }\n if (kind === 'dayPeriod') {\n return this.periods()[value] ?? String(value);\n }\n return String(value);\n }\n\n /** `bound` when it is a valid value of the mode, else `null`. */\n private validBound(bound: string | null | undefined): string | null {\n const mode = this.mode();\n if (!bound) {\n return null;\n }\n if (mode === 'date') {\n return datePartOf(mode, bound);\n }\n if (mode === 'time') {\n return parseIsoTime(bound) ? bound : null;\n }\n return datePartOf(mode, bound) && timePartOf(mode, bound) && bound.length >= 16 ? bound : null;\n }\n\n /** The error for a complete value outside `min`…`max` or ruled out by `disabledDate`. */\n private rangeError(value: string): string {\n const mode = this.mode();\n const validation = this.labels.validation;\n const date = datePartOf(mode, value);\n if (date && this.disabledDate()?.(date)) {\n return this.labels.dateInputUnavailable;\n }\n const min = this.validMin();\n const max = this.validMax();\n const below = min !== null && comparable(mode, value) < comparable(mode, min);\n const above = max !== null && comparable(mode, value) > comparable(mode, max);\n const limit = below ? min : above ? max : null;\n if (!limit) {\n return '';\n }\n const limitDate = datePartOf(mode, limit);\n if (limitDate && (mode === 'date' || date !== limitDate)) {\n return below\n ? validation.minDate(localDate(limitDate))\n : validation.maxDate(localDate(limitDate));\n }\n const time = this.formatTime()(timePartOf(mode, limit) ?? limit);\n return below ? this.labels.timeInputMin(time) : this.labels.timeInputMax(time);\n }\n\n private timeDisabled(time: string): boolean {\n const { lower, upper } = this.timeBounds();\n return (\n (lower !== null && timeKey(time) < timeKey(lower)) ||\n (upper !== null && timeKey(time) > timeKey(upper))\n );\n }\n\n /** The list's first active time: the value's, else the first time from now on (or from it). */\n private initialTime(): string | null {\n const options = this.options().filter((option) => !this.timeDisabled(option.value));\n const selected = timePartOf(this.mode(), this.value());\n const now = new Date();\n const from = timeKey(\n selected ??\n `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`,\n );\n return (\n options.find((option) => timeKey(option.value) >= from)?.value ??\n options[options.length - 1]?.value ??\n null\n );\n }\n\n private writeParts(values: SegmentValues): void {\n this.parts.set(values);\n const next = composeValue(this.mode(), values, this.cycle(), this.hasSeconds());\n if (next !== this.value()) {\n this.value.set(next);\n this.changed.emit(next);\n }\n }\n\n private typeInto(kind: SegmentKind, digit: string): void {\n const typing = this.typing();\n const text = typing?.kind === kind ? typing.text : '';\n const values = this.parts();\n const typed = typeDigit(kind, text, digit, values, this.cycle());\n // The part takes its value once it is complete; until then the digits show as typed, so \"3\"\n // on the way to \"30\" minutes never reaches the value. Leaving the part commits them.\n if (typed.advance) {\n this.typing.set(null);\n this.writeParts({ ...values, [kind]: typed.value });\n this.moveFocus(kind, 1);\n } else {\n this.typing.set({ kind, text: typed.text });\n }\n }\n\n private clearSegment(kind: SegmentKind, backspace: boolean): void {\n const typing = this.typing();\n const values = this.parts();\n this.typing.set(null);\n const empty = (values[kind] ?? null) === null && typing?.kind !== kind;\n if (empty && backspace) {\n this.moveFocus(kind, -1);\n return;\n }\n this.writeParts({ ...values, [kind]: null });\n }\n\n private moveFocus(kind: SegmentKind, offset: number): void {\n const order = this.order();\n const next = order[order.indexOf(kind) + offset];\n if (next) {\n this.segmentElement(next)?.focus();\n }\n }\n\n private segmentElement(kind: SegmentKind | undefined): HTMLElement | null {\n return kind\n ? (this.box()?.nativeElement.querySelector<HTMLElement>(`[data-segment=\"${kind}\"]`) ?? null)\n : null;\n }\n\n /** Focus on open: the calendar's tab stop day, else the time list. */\n private focusPanel(pane: HTMLElement): void {\n const day = pane.querySelector<HTMLElement>('[data-bf-calendar-grid] td[tabindex=\"0\"]');\n const list = pane.querySelector<HTMLElement>('[role=\"listbox\"]');\n if (list) {\n this.scrollToActive(list, true);\n }\n (day ?? list)?.focus({ preventScroll: true });\n }\n\n private focusList(pane: HTMLElement): void {\n const list = pane.querySelector<HTMLElement>('[role=\"listbox\"]');\n if (list) {\n this.scrollToActive(list, true);\n list.focus({ preventScroll: true });\n }\n }\n\n /** Scrolls the list (not the page) so the active time shows: centred, or just inside. */\n private scrollToActive(list: HTMLElement, center: boolean): void {\n const option = list.querySelector<HTMLElement>(`[id=\"${this.activeOptionId() ?? ''}\"]`);\n if (!option) {\n return;\n }\n const top = option.offsetTop;\n const bottom = top + option.offsetHeight;\n if (center) {\n list.scrollTop = top - (list.clientHeight - option.offsetHeight) / 2;\n } else if (top < list.scrollTop) {\n list.scrollTop = top;\n } else if (bottom > list.scrollTop + list.clientHeight) {\n list.scrollTop = bottom - list.clientHeight;\n }\n }\n\n /**\n * `Tab` is not trapped: past the panel's last control it closes the panel onto the picker\n * button (the browser then moves on from it); `Shift+Tab` before the first control closes it\n * onto the button.\n */\n private tabbed(event: KeyboardEvent, pane: HTMLElement): void {\n if (event.key !== 'Tab') {\n return;\n }\n const stops = Array.from(pane.querySelectorAll<HTMLElement>(TABBABLE)).filter(\n (el) => !el.closest('[inert]') && !el.hidden,\n );\n const active = this.document.activeElement;\n const leaving = event.shiftKey\n ? !stops.length || active === stops[0]\n : !stops.length || active === stops[stops.length - 1];\n if (!leaving) {\n return;\n }\n if (event.shiftKey) {\n event.preventDefault();\n }\n this.closePicker(true);\n }\n\n private teardown(): void {\n this.subscriptions.forEach((s) => s.unsubscribe());\n this.subscriptions = [];\n this.stopNavigation?.();\n this.stopNavigation = null;\n this.anchored?.ref.dispose();\n this.anchored = null;\n }\n}\n","import { Component, booleanAttribute, input, model, output, viewChild } from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport { type BfCalendarDisabledDate, type BfSize, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfDateTimeFieldComponent } from '../date-time-core/date-time-field.component';\n\n/**\n * How `bf-date-input` picks a date besides typing: `calendar` adds a button that opens a\n * `bf-calendar` in a popover, `none` keeps the field typed only.\n *\n * @summary Whether a date input offers a calendar popover besides typing\n * @since 0.3.1\n */\nexport type BfDateInputPicker = 'calendar' | 'none';\n\n/**\n * Date field typed part by part (day, month and year in the locale's order) with a calendar\n * popover, valued as an ISO date string and bound like any other field.\n *\n * @example\n * <bf-date-input label=\"Due date\" min=\"2026-01-01\" [(value)]=\"due\" />\n * <bf-date-input label=\"Birthday\" picker=\"none\" [formField]=\"profile.birthday\" />\n * @summary Typed date field with a calendar popover, valued as an ISO date string\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-date-input',\n imports: [BfDateTimeFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-date-time-field\n mode=\"date\"\n [id]=\"id()\"\n [(value)]=\"value\"\n [min]=\"min()\"\n [max]=\"max()\"\n [disabledDate]=\"disabledDate()\"\n [picker]=\"picker() === 'calendar'\"\n [native]=\"native()\"\n [locale]=\"locale()\"\n [size]=\"size()\"\n [label]=\"label()\"\n [ariaLabel]=\"ariaLabel()\"\n [ariaLabelledby]=\"ariaLabelledby()\"\n [helpText]=\"helpText()\"\n [errorMessage]=\"errorMessage()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [invalid]=\"invalid()\"\n [touched]=\"touched()\"\n [errors]=\"errors()\"\n [name]=\"name()\"\n (changed)=\"changed.emit($event)\"\n (touch)=\"touch.emit()\"\n />\n `,\n})\nexport class BfDateInputComponent implements FormValueControl<string | null> {\n /** The date as an ISO string ('YYYY-MM-DD'), `null` while empty or incomplete; two-way bindable\n * and bound by `[formField]`. */\n readonly value = model<string | null>(null);\n /** The earliest valid date (ISO): earlier dates show an error, and the calendar stops there. */\n readonly min = input<string | undefined>(undefined);\n /** The latest valid date (ISO): later dates show an error, and the calendar stops there. */\n readonly max = input<string | undefined>(undefined);\n /** Rules out more dates (weekends, booked days): disabled in the calendar, an error when typed. */\n readonly disabledDate = input<BfCalendarDisabledDate | null>(null);\n /** `calendar` adds the button that opens a calendar popover; `none` keeps the field typed only. */\n readonly picker = input<BfDateInputPicker>('calendar');\n /** Renders the platform's date picker (`input type=\"date\"`) under a coarse pointer (touch). */\n readonly native = input(false, { transform: booleanAttribute });\n /** BCP 47 locale of the part order, the separators and the calendar; empty follows the\n * document's `lang`, else English. */\n readonly locale = input('');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`\n * by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over the field's own errors and Signal Forms errors. */\n readonly errorMessage = input('');\n /** Disables the field and its calendar button. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the date but blocks changes; the parts stay focusable and expose `aria-readonly`. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the platform input (`native` under a coarse pointer). */\n readonly name = input('');\n /** Field id; generated when not set. */\n readonly id = input(uniqueId('bf-date-input'));\n\n /** Emitted with the new date right after a user change: `null` once it is cleared or incomplete. */\n readonly changed = output<string | null>();\n /** Emitted when focus leaves the field (not into its calendar), so Signal Forms marks it touched. */\n readonly touch = output<void>();\n\n private readonly field = viewChild.required(BfDateTimeFieldComponent);\n\n /**\n * Focuses the first empty part (else the first part); Signal Forms calls it from\n * `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.field().focus(options);\n }\n\n /** Opens the calendar popover; does nothing without a picker, or while disabled or read-only. */\n openPicker(): void {\n this.field().openPicker();\n }\n\n /** Closes the calendar popover, focus back on its button; does nothing while it is closed. */\n closePicker(): void {\n this.field().closePicker();\n }\n}\n","import {\n Component,\n booleanAttribute,\n input,\n model,\n numberAttribute,\n output,\n viewChild,\n} from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport { type BfSize, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfDateTimeFieldComponent } from '../date-time-core/date-time-field.component';\n\n/**\n * How `bf-time-input` picks a time besides typing: `list` adds a button that opens a list of\n * times every `step` minutes, `none` keeps the field typed only.\n *\n * @summary Whether a time input offers a popover list of times besides typing\n * @since 0.3.1\n */\nexport type BfTimeInputPicker = 'list' | 'none';\n\n/**\n * The clock of a time field: `h12` counts 1–12 with an AM/PM part, `h23` counts 0–23.\n *\n * @summary A twelve-hour clock with AM and PM, or a twenty-four-hour clock\n * @since 0.3.1\n */\nexport type BfTimeInputHourCycle = 'h12' | 'h23';\n\n/**\n * Time field typed part by part (hour, minute, optional seconds, AM/PM under a 12-hour clock)\n * with a popover list of times, valued as an ISO time string.\n *\n * @example\n * <bf-time-input label=\"Start\" [step]=\"15\" [(value)]=\"start\" />\n * <bf-time-input label=\"Alarm\" hourCycle=\"h12\" [formField]=\"settings.alarm\" />\n * @summary Typed time-of-day field with a popover list of times, valued as an ISO string\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-time-input',\n imports: [BfDateTimeFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-date-time-field\n mode=\"time\"\n [id]=\"id()\"\n [(value)]=\"value\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\"\n [seconds]=\"seconds()\"\n [hourCycle]=\"hourCycle()\"\n [picker]=\"picker() === 'list'\"\n [native]=\"native()\"\n [locale]=\"locale()\"\n [size]=\"size()\"\n [label]=\"label()\"\n [ariaLabel]=\"ariaLabel()\"\n [ariaLabelledby]=\"ariaLabelledby()\"\n [helpText]=\"helpText()\"\n [errorMessage]=\"errorMessage()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [invalid]=\"invalid()\"\n [touched]=\"touched()\"\n [errors]=\"errors()\"\n [name]=\"name()\"\n (changed)=\"changed.emit($event)\"\n (touch)=\"touch.emit()\"\n />\n `,\n})\nexport class BfTimeInputComponent implements FormValueControl<string | null> {\n /** The time as an ISO string ('HH:mm', 'HH:mm:ss' with `seconds`), `null` while empty or\n * incomplete; two-way bindable and bound by `[formField]`. */\n readonly value = model<string | null>(null);\n /** The earliest valid time ('HH:mm'): earlier times show an error and are disabled in the list. */\n readonly min = input<string | undefined>(undefined);\n /** The latest valid time ('HH:mm'): later times show an error and are disabled in the list. */\n readonly max = input<string | undefined>(undefined);\n /** Minutes between the times of the list, from midnight (1–720). */\n readonly step = input(30, { transform: numberAttribute });\n /** Adds a seconds part; the value becomes 'HH:mm:ss'. */\n readonly seconds = input(false, { transform: booleanAttribute });\n /** Forces a 12-hour (`h12`, with AM/PM) or 24-hour (`h23`) clock; unset follows the locale. */\n readonly hourCycle = input<BfTimeInputHourCycle | undefined>(undefined);\n /** `list` adds the button that opens the list of times; `none` keeps the field typed only. */\n readonly picker = input<BfTimeInputPicker>('list');\n /** Renders the platform's time picker (`input type=\"time\"`) under a coarse pointer (touch). */\n readonly native = input(false, { transform: booleanAttribute });\n /** BCP 47 locale of the part order, the separators, the clock and the AM/PM names; empty\n * follows the document's `lang`, else English. */\n readonly locale = input('');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`\n * by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over the field's own errors and Signal Forms errors. */\n readonly errorMessage = input('');\n /** Disables the field and its list button. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the time but blocks changes; the parts stay focusable and expose `aria-readonly`. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the platform input (`native` under a coarse pointer). */\n readonly name = input('');\n /** Field id; generated when not set. */\n readonly id = input(uniqueId('bf-time-input'));\n\n /** Emitted with the new time right after a user change: `null` once it is cleared or incomplete. */\n readonly changed = output<string | null>();\n /** Emitted when focus leaves the field (not into its list), so Signal Forms marks it touched. */\n readonly touch = output<void>();\n\n private readonly field = viewChild.required(BfDateTimeFieldComponent);\n\n /**\n * Focuses the first empty part (else the first part); Signal Forms calls it from\n * `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.field().focus(options);\n }\n\n /** Opens the list of times; does nothing without a picker, or while disabled or read-only. */\n openPicker(): void {\n this.field().openPicker();\n }\n\n /** Closes the list of times, focus back on its button; does nothing while it is closed. */\n closePicker(): void {\n this.field().closePicker();\n }\n}\n","import {\n Component,\n booleanAttribute,\n input,\n model,\n numberAttribute,\n output,\n viewChild,\n} from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport { type BfCalendarDisabledDate, type BfSize, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfDateTimeFieldComponent } from '../date-time-core/date-time-field.component';\nimport { type BfTimeInputHourCycle } from '../time-input/time-input.component';\n\n/**\n * How `bf-datetime-input` picks a date and time besides typing: `popover` adds a button that\n * opens a calendar and a list of times side by side, `none` keeps the field typed only.\n *\n * @summary Whether a date and time input offers a calendar and time list popover\n * @since 0.3.1\n */\nexport type BfDateTimeInputPicker = 'popover' | 'none';\n\n/**\n * Date and time field typed part by part, with a popover holding a calendar and a list of\n * times, valued as a local ISO date and time without a zone.\n *\n * @example\n * <bf-datetime-input label=\"Meeting\" [step]=\"15\" [(value)]=\"meeting\" />\n * <bf-datetime-input label=\"Publish at\" [formField]=\"post.publishAt\" />\n * @summary Typed date and time field with a calendar and time list in one popover\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-datetime-input',\n imports: [BfDateTimeFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-date-time-field\n mode=\"datetime\"\n [id]=\"id()\"\n [(value)]=\"value\"\n [min]=\"min()\"\n [max]=\"max()\"\n [disabledDate]=\"disabledDate()\"\n [step]=\"step()\"\n [hourCycle]=\"hourCycle()\"\n [picker]=\"picker() === 'popover'\"\n [native]=\"native()\"\n [locale]=\"locale()\"\n [size]=\"size()\"\n [label]=\"label()\"\n [ariaLabel]=\"ariaLabel()\"\n [ariaLabelledby]=\"ariaLabelledby()\"\n [helpText]=\"helpText()\"\n [errorMessage]=\"errorMessage()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [invalid]=\"invalid()\"\n [touched]=\"touched()\"\n [errors]=\"errors()\"\n [name]=\"name()\"\n (changed)=\"changed.emit($event)\"\n (touch)=\"touch.emit()\"\n />\n `,\n})\nexport class BfDateTimeInputComponent implements FormValueControl<string | null> {\n /** The local date and time as an ISO string without a zone ('YYYY-MM-DDTHH:mm'), `null` while\n * empty or incomplete; two-way bindable and bound by `[formField]`. */\n readonly value = model<string | null>(null);\n /** The earliest valid date and time ('YYYY-MM-DDTHH:mm'): earlier values show an error, and the\n * calendar and the list stop there. */\n readonly min = input<string | undefined>(undefined);\n /** The latest valid date and time ('YYYY-MM-DDTHH:mm'): later values show an error, and the\n * calendar and the list stop there. */\n readonly max = input<string | undefined>(undefined);\n /** Rules out more dates (weekends, booked days): disabled in the calendar, an error when typed. */\n readonly disabledDate = input<BfCalendarDisabledDate | null>(null);\n /** Minutes between the times of the list, from midnight (1–720). */\n readonly step = input(30, { transform: numberAttribute });\n /** Forces a 12-hour (`h12`, with AM/PM) or 24-hour (`h23`) clock; unset follows the locale. */\n readonly hourCycle = input<BfTimeInputHourCycle | undefined>(undefined);\n /** `popover` adds the button that opens the calendar and the time list; `none` keeps the field\n * typed only. */\n readonly picker = input<BfDateTimeInputPicker>('popover');\n /** Renders the platform's picker (`input type=\"datetime-local\"`) under a coarse pointer (touch). */\n readonly native = input(false, { transform: booleanAttribute });\n /** BCP 47 locale of the part order, the separators, the clock and the calendar; empty follows\n * the document's `lang`, else English. */\n readonly locale = input('');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`\n * by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over the field's own errors and Signal Forms errors. */\n readonly errorMessage = input('');\n /** Disables the field and its picker button. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the value but blocks changes; the parts stay focusable and expose `aria-readonly`. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the platform input (`native` under a coarse pointer). */\n readonly name = input('');\n /** Field id; generated when not set. */\n readonly id = input(uniqueId('bf-datetime-input'));\n\n /** Emitted with the new value right after a user change: `null` once it is cleared or\n * incomplete. */\n readonly changed = output<string | null>();\n /** Emitted when focus leaves the field (not into its popover), so Signal Forms marks it touched. */\n readonly touch = output<void>();\n\n private readonly field = viewChild.required(BfDateTimeFieldComponent);\n\n /**\n * Focuses the first empty part (else the first part); Signal Forms calls it from\n * `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.field().focus(options);\n }\n\n /** Opens the calendar and time popover; does nothing without a picker, or while disabled or\n * read-only. */\n openPicker(): void {\n this.field().openPicker();\n }\n\n /** Closes the popover, focus back on its button; does nothing while it is closed. */\n closePicker(): void {\n this.field().closePicker();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bitforgehq-ui-overlay.mjs","names":[],"sources":["../../../projects/ui/overlay/core/overlay-ref.ts","../../../projects/ui/overlay/core/overlay-host.ts","../../../projects/ui/overlay/core/overlay-stack.service.ts","../../../projects/ui/overlay/core/motion.ts","../../../projects/ui/overlay/core/navigation.ts","../../../projects/ui/overlay/core/overlay-animations.ts","../../../projects/ui/overlay/core/overlay.service.ts","../../../projects/ui/overlay/core/overlay-heading.ts","../../../projects/ui/overlay/toast-core/toast-ref.ts","../../../projects/ui/overlay/toast-core/toast-queue.ts","../../../projects/ui/overlay/dialog/dialog-ref.ts","../../../projects/ui/overlay/dialog/dialog.component.ts","../../../projects/ui/overlay/dialog/dialog.service.ts","../../../projects/ui/overlay/desktop-toast/desktop-toast.component.ts","../../../projects/ui/overlay/desktop-toast/desktop-toast.service.ts","../../../projects/ui/overlay/core/anchored-motion.ts","../../../projects/ui/overlay/core/anchored-overlay.ts","../../../projects/ui/overlay/menu/menu-trigger.directive.ts","../../../projects/ui/overlay/menu/menu.component.ts","../../../projects/ui/overlay/menu/menu-item.directive.ts","../../../projects/ui/overlay/menu-button/menu-button.component.ts","../../../projects/ui/overlay/theme-menu-button/theme-menu-button.component.ts","../../../projects/ui/overlay/tooltip/tooltip.component.ts","../../../projects/ui/overlay/tooltip/tooltip.directive.ts","../../../projects/ui/overlay/sidebar-toggle/sidebar-toggle.component.ts","../../../projects/ui/overlay/chat-composer/chat-composer.component.ts","../../../projects/ui/overlay/side-panel/side-panel-ref.ts","../../../projects/ui/overlay/side-panel/side-panel.component.ts","../../../projects/ui/overlay/side-panel/side-panel.service.ts","../../../projects/ui/overlay/popover/popover-trigger.directive.ts","../../../projects/ui/overlay/popover/popover.component.ts","../../../projects/ui/overlay/combobox/combobox-core.ts","../../../projects/ui/overlay/combobox/combobox-classes.ts","../../../projects/ui/overlay/combobox/combobox-listbox.component.ts","../../../projects/ui/overlay/combobox/combobox.component.ts","../../../projects/ui/overlay/combobox/multi-combobox.component.ts","../../../projects/ui/overlay/select/select.component.ts","../../../projects/ui/overlay/select/provide-bf-select.ts","../../../projects/ui/overlay/date-time-core/date-time-segments.ts","../../../projects/ui/overlay/date-time-core/date-time-field.component.ts","../../../projects/ui/overlay/date-input/date-input.component.ts","../../../projects/ui/overlay/time-input/time-input.component.ts","../../../projects/ui/overlay/datetime-input/datetime-input.component.ts","../../../projects/ui/overlay/image-viewer/image-viewer-motion.ts","../../../projects/ui/overlay/image-viewer/image-viewer-ref.ts","../../../projects/ui/overlay/image-viewer/image-viewer.component.ts","../../../projects/ui/overlay/image-viewer/image-viewer.service.ts"],"sourcesContent":["import { type ComponentRef, InjectionToken, type Signal, signal } from '@angular/core';\n\n/**\n * The `data` passed to `BfOverlayService.open()`, injectable in the overlay's content.\n *\n * @summary Injection token carrying the data an overlay was opened with, for its content\n * @since 0.2.0\n */\nexport const BF_OVERLAY_DATA = new InjectionToken<unknown>('BF_OVERLAY_DATA');\n\n/**\n * What the overlay service does for a ref. Exported for entries that extend `BfOverlayRef` with\n * their own controller (the `/mobile` `BfSheetRef`); apps never implement it.\n *\n * @summary What the overlay service does for a ref: close it and re-apply its position\n * @since 0.2.0\n */\nexport interface BfOverlayController {\n /** Plays the exit animation, detaches the overlay and cleans up. Never rejects. */\n close(): Promise<void>;\n /** Re-applies the overlay's position (after its size changed). */\n updatePosition(): void;\n}\n\nlet nextId = 0;\n\n/**\n * Handle to an open overlay, returned by `BfOverlayService.open()` and injectable in the\n * overlay's content. `close(result)` plays the exit animation, detaches the overlay and resolves\n * `afterClosed` with `result`; later calls are ignored.\n *\n * @example\n * const ref = overlays.open(PickerComponent, { data: { value } });\n * const picked = await ref.afterClosed;\n *\n * @summary Handle on an open overlay that closes it and resolves with its result\n * @since 0.2.0\n */\nexport class BfOverlayRef<T = unknown> {\n /** Unique id of the overlay (`bf-overlay-N`). */\n readonly id = `bf-overlay-${nextId++}`;\n /** Resolves with the result given to `close()` once the overlay is detached. */\n readonly afterClosed: Promise<T | undefined>;\n private readonly closedState = signal(false);\n /** True once the overlay has been detached. */\n readonly closed: Signal<boolean> = this.closedState.asReadonly();\n private closing = false;\n private resolveClosed: (result: T | undefined) => void = () => undefined;\n\n constructor(private readonly controller: BfOverlayController) {\n this.afterClosed = new Promise<T | undefined>((resolve) => {\n this.resolveClosed = resolve;\n });\n }\n\n /** True from the first `close()` call on (the exit animation may still be running). */\n get isClosing(): boolean {\n return this.closing;\n }\n\n /**\n * Closes the overlay with an optional result; ignored once closing.\n * @param result The value `afterClosed` resolves with.\n */\n close(result?: T): void {\n if (this.closing) {\n return;\n }\n this.closing = true;\n void this.controller.close().then(() => {\n this.closedState.set(true);\n this.resolveClosed(result);\n });\n }\n\n /** Re-applies the overlay's position (after its size changed). */\n updatePosition(): void {\n this.controller.updatePosition();\n }\n}\n\n/**\n * An overlay ref whose content is a component, exposing its `ComponentRef`.\n *\n * @summary Overlay handle whose content is a component, with access to its ComponentRef\n * @since 0.2.0\n */\nexport class BfComponentOverlayRef<C, T = unknown> extends BfOverlayRef<T> {\n private ref: ComponentRef<C> | null = null;\n\n /** The content component; available as soon as `open()` returns. */\n get componentRef(): ComponentRef<C> {\n if (!this.ref) {\n throw new Error('BfComponentOverlayRef: the content component is not attached yet');\n }\n return this.ref;\n }\n\n /** @internal Set by `BfOverlayService` once the component is attached. */\n setComponentRef(ref: ComponentRef<C>): void {\n this.ref = ref;\n }\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * What a host shell (the `/mobile` `provideBfShell()`) tells the overlay core. The core itself\n * depends on no platform code: without a host, overlays register no hardware back handler and\n * lock document scroll behind a modal overlay, and where the browser has `CloseWatcher`, its close\n * requests (Android back in Chrome) close the top overlay.\n *\n * @summary What a host shell tells the overlay core: back handling and document scroll\n * @since 0.3.0\n */\nexport interface BfOverlayHost {\n /**\n * Registers a hardware back handler at `priority`; returns its unregister function.\n * @param priority Higher runs first; the overlay core uses 100.\n * @param handler Returns (or resolves) true when it handled the back press.\n */\n registerBack(priority: number, handler: () => boolean | Promise<boolean>): () => void;\n /** False when the document never scrolls (the mobile shell): overlays skip the scroll lock. */\n readonly documentScrolls: boolean;\n /**\n * True when the host already delivers the system back action to `registerBack` (the mobile\n * shell on native Android, through Capacitor's `backButton` event): overlays then create no\n * `CloseWatcher` of their own, so one back press never closes two things.\n */\n readonly handlesSystemBack?: boolean;\n}\n\n/**\n * Optional; without it overlays register no back handler and lock document scroll.\n *\n * @summary Optional injection token through which a host shell plugs into the overlay core\n * @since 0.3.0\n */\nexport const BF_OVERLAY_HOST = new InjectionToken<BfOverlayHost>('BF_OVERLAY_HOST');\n","import { DOCUMENT, DestroyRef, Injectable, computed, inject, signal } from '@angular/core';\nimport { BF_OVERLAY_HOST } from './overlay-host';\n\n/**\n * What the stack needs of an overlay: a way to close it (a `BfOverlayRef` of any result type).\n *\n * @summary What the overlay stack needs of an overlay: a way to close it\n * @since 0.2.0\n */\nexport interface BfStackedOverlay {\n /** Closes the overlay (the stack calls it for the hardware back button). */\n close(): void;\n}\n\n/**\n * How an overlay takes part in the stack.\n *\n * @summary How an overlay takes part in the stack: its back priority and modal depth\n * @since 0.2.0\n */\nexport interface BfOverlayStackOptions {\n /**\n * Priority of its hardware back handler (default 100).\n * @default 100\n */\n backPriority?: number;\n /**\n * Counts towards `depth()` and `--bf-modal-depth` (page-sheet modals).\n * @default false\n */\n countsAsModal?: boolean;\n}\n\ninterface StackEntry {\n ref: BfStackedOverlay;\n countsAsModal: boolean;\n unregisterBack: () => void;\n}\n\n/**\n * The CDK overlay container's class (the CDK's DOM contract, like the announcer classes below).\n * The stack finds every container by it instead of injecting the CDK `OverlayContainer`, so a\n * shell app that only registers page roots (`bf-stack-outlet`, `bf-tabs`) bundles no CDK overlay\n * code. A custom container (`FullscreenOverlayContainer`) carries the same class.\n */\nconst OVERLAY_CONTAINER = '.cdk-overlay-container';\n\n/** Body children that never become `inert` behind an overlay (besides the overlay container). */\nconst KEEP_ACTIVE = [\n 'script',\n 'style',\n 'template',\n 'link',\n '.cdk-live-announcer-element',\n '.cdk-describedby-message-container',\n '[data-bf-overlay-keep]',\n].join(', ');\n\n/**\n * The open modal-like overlays, in order. While any is open, every registered page root (the\n * `/mobile` `bf-stack-outlet` hosts register themselves) is `inert`, and `--bf-modal-depth` on the\n * roots carries the number of open modals. With no registered root (a desktop page), every direct\n * child of `document.body` becomes `inert` instead, except those holding a CDK overlay container\n * (`.cdk-overlay-container`, found without importing the CDK), the CDK live\n * announcer and `AriaDescriber` containers, `script`/`style`/`template`/`link` and body children\n * carrying `data-bf-overlay-keep`; an element that was already `inert` keeps it on close. When\n * the stack's injector is destroyed (the app torn down with an overlay open), it removes every\n * `inert` and `--bf-modal-depth` it set. Under a `BF_OVERLAY_HOST`\n * (`provideBfShell()`) each pushed overlay registers a hardware back handler that closes it; on\n * equal priority the newest overlay closes first. Passive overlays (toasts) are never pushed.\n *\n * @summary Keeps the open overlays in order and makes the page behind them inert\n * @since 0.2.0\n */\n@Injectable({ providedIn: 'root' })\nexport class BfOverlayStack {\n private readonly host = inject(BF_OVERLAY_HOST, { optional: true });\n private readonly document = inject(DOCUMENT);\n private readonly roots = new Set<HTMLElement>();\n /** Body children the stack made `inert` (outside a shell), and only those. */\n private readonly inertBodyChildren = new Set<Element>();\n private readonly entries = signal<readonly StackEntry[]>([]);\n\n constructor() {\n // The page around the app (other apps, a host page) must never stay inert after teardown.\n inject(DestroyRef).onDestroy(() => {\n for (const el of this.inertBodyChildren) {\n el.removeAttribute('inert');\n }\n this.inertBodyChildren.clear();\n for (const root of this.roots) {\n root.removeAttribute('inert');\n root.style.removeProperty('--bf-modal-depth');\n }\n this.roots.clear();\n });\n }\n\n /** Number of open modal-like overlays. */\n readonly count = computed(() => this.entries().length);\n /** Number of open overlays that count as modals (drives `--bf-modal-depth`). */\n readonly depth = computed(() => this.entries().filter((e) => e.countsAsModal).length);\n\n /**\n * Registers a page root that becomes `inert` while an overlay is open. Returns a function that\n * unregisters it (and clears what the stack set on it).\n * @param el The page root, such as a `bf-stack-outlet` host.\n */\n registerRoot(el: HTMLElement): () => void {\n this.roots.add(el);\n this.applyTo(el);\n this.applyToBody();\n return () => {\n if (this.roots.delete(el)) {\n el.removeAttribute('inert');\n el.style.removeProperty('--bf-modal-depth');\n this.applyToBody();\n }\n };\n }\n\n /**\n * Adds an overlay on top of the stack. Outside a shell, every body child that holds a CDK\n * overlay container (`.cdk-overlay-container`) stays active, so an overlay created on the CDK\n * directly, not through `BfOverlayService`, can be pushed as well.\n * @param ref The overlay's ref.\n * @param options Its back priority and whether it counts as a modal.\n */\n push(ref: BfStackedOverlay, options: BfOverlayStackOptions = {}): void {\n if (this.entries().some((e) => e.ref === ref)) {\n return;\n }\n const unregisterBack =\n this.host?.registerBack(options.backPriority ?? 100, () => {\n ref.close();\n return true;\n }) ?? ((): void => undefined);\n this.entries.update((list) => [\n ...list,\n { ref, countsAsModal: options.countsAsModal ?? false, unregisterBack },\n ]);\n this.apply();\n }\n\n /**\n * Removes an overlay from the stack.\n * @param ref The overlay's ref.\n */\n pop(ref: BfStackedOverlay): void {\n const entry = this.entries().find((e) => e.ref === ref);\n if (!entry) {\n return;\n }\n entry.unregisterBack();\n this.entries.update((list) => list.filter((e) => e !== entry));\n this.apply();\n }\n\n /**\n * True when `ref` is the newest overlay in the stack (the one that answers `Escape`).\n * @param ref The overlay's ref.\n */\n isTop(ref: BfStackedOverlay): boolean {\n const list = this.entries();\n return list.length > 0 && list[list.length - 1].ref === ref;\n }\n\n /**\n * Stops the back handler of an overlay that is closing, while it stays in the stack.\n * @param ref The overlay's ref.\n */\n releaseBack(ref: BfStackedOverlay): void {\n this.entries()\n .find((e) => e.ref === ref)\n ?.unregisterBack();\n }\n\n /**\n * Written synchronously on every change rather than in an effect: an overlay restores focus\n * into a root right after popping, which fails while the root is still `inert`.\n */\n private apply(): void {\n for (const root of this.roots) {\n this.applyTo(root);\n }\n this.applyToBody();\n }\n\n /** Outside a shell (no registered root), isolates the page: body children become `inert`. */\n private applyToBody(): void {\n if (this.count() === 0 || this.roots.size > 0) {\n for (const el of this.inertBodyChildren) {\n el.removeAttribute('inert');\n }\n this.inertBodyChildren.clear();\n return;\n }\n const containers = Array.from(this.document.querySelectorAll(OVERLAY_CONTAINER));\n for (const child of Array.from(this.document.body.children)) {\n if (\n child.hasAttribute('inert') ||\n containers.some((container) => child.contains(container)) ||\n child.matches(KEEP_ACTIVE)\n ) {\n continue;\n }\n child.setAttribute('inert', '');\n this.inertBodyChildren.add(child);\n }\n }\n\n private applyTo(root: HTMLElement): void {\n if (this.count() > 0) {\n root.setAttribute('inert', '');\n } else {\n root.removeAttribute('inert');\n }\n const depth = this.depth();\n if (depth > 0) {\n root.style.setProperty('--bf-modal-depth', String(depth));\n } else {\n root.style.removeProperty('--bf-modal-depth');\n }\n }\n}\n","/**\n * Motion constants of the overlay core. `@bitforgehq/ui/mobile` reuses them for its own motion\n * (`DURATION_OVERLAY`, `DURATION_FAST`, `IOS_EASING`).\n */\n\n/**\n * Overlay enter and exit (ms).\n *\n * @summary The duration of every overlay enter and exit animation, in milliseconds\n * @since 0.2.0\n */\nexport const OVERLAY_DURATION = 260;\n/**\n * The overlays' curve: UIKit's navigation and sheet curve.\n *\n * @summary The easing curve of the overlay animations, the UIKit sheet curve\n * @since 0.2.0\n */\nexport const OVERLAY_EASING = 'cubic-bezier(0.32, 0.72, 0, 1)';\n/**\n * The opacity fade that replaces every overlay animation under reduced motion (ms).\n *\n * @summary The duration of the fade that replaces overlay motion under reduced motion\n * @since 0.3.0\n */\nexport const OVERLAY_REDUCED_DURATION = 150;\n\n/**\n * True when the user asked the system to minimise motion.\n *\n * @param view The window to ask, usually `document.defaultView`; none reads as false.\n * @summary Tells whether the user asked the system to minimise motion\n * @since 0.2.0\n */\nexport function prefersReducedMotion(view: Window | null | undefined): boolean {\n if (!view || typeof view.matchMedia !== 'function') {\n return false;\n }\n return view.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n","import { type Location } from '@angular/common';\n\n/** The URL path without its query and fragment. */\nexport function urlPath(url: string): string {\n const end = url.search(/[?#]/);\n return end === -1 ? url : url.slice(0, end);\n}\n\n/**\n * Calls `onChange` each time the URL path moves away from the one seen last — a router\n * navigation (`Location.go`/`replaceState`), a link, the browser's back and forward buttons —\n * never for a query- or fragment-only change. Built on `Location.onUrlChange()`, so no router is\n * needed. Returns the unregister function, which removes the listener after the current\n * notification: `Location` walks its listener array while a listener may be unregistering, and a\n * removal mid-walk would skip the next listener. Calling it again does nothing.\n */\nexport function watchPathChange(location: Location, onChange: () => void): () => void {\n let last = urlPath(location.path());\n const stop = location.onUrlChange(() => {\n const path = urlPath(location.path());\n if (path === last) {\n return;\n }\n last = path;\n onChange();\n });\n let stopped = false;\n return () => {\n // Location's remover splices by index: a second call would remove someone else's listener.\n if (stopped) {\n return;\n }\n stopped = true;\n queueMicrotask(stop);\n };\n}\n","/**\n * Enter and exit animations of the overlays, built from the Web Animations API. Every helper\n * runs 260 ms on the iOS sheet curve and falls back to a 150 ms opacity fade under\n * `prefers-reduced-motion`. Pass them as `enter`/`exit` to `BfOverlayService.open()`. Where the\n * Web Animations API is missing (jsdom in a consumer's unit tests), each applies its end state and\n * returns an already finished `Animation`, so overlays open and close without a polyfill.\n */\nimport {\n OVERLAY_DURATION,\n OVERLAY_EASING,\n OVERLAY_REDUCED_DURATION,\n prefersReducedMotion,\n} from './motion';\n\ntype Frame = Keyframe;\n\n/** Keyframe keys that are timing, not CSS properties. */\nconst TIMING_KEYS = new Set(['offset', 'easing', 'composite']);\n\n/**\n * The `Animation` handed back where the Web Animations API is missing (jsdom in a consumer's\n * Vitest or Jest run, a server render): already finished, every call a no-op.\n */\nclass BfFinishedAnimation extends EventTarget implements Animation {\n currentTime: CSSNumberish | null = null;\n effect: AnimationEffect | null = null;\n readonly finished: Promise<Animation> = Promise.resolve<Animation>(this);\n id = '';\n oncancel: ((this: Animation, ev: AnimationPlaybackEvent) => unknown) | null = null;\n onfinish: ((this: Animation, ev: AnimationPlaybackEvent) => unknown) | null = null;\n onremove: ((this: Animation, ev: Event) => unknown) | null = null;\n readonly overallProgress: number | null = 1;\n readonly pending = false;\n readonly playState: AnimationPlayState = 'finished';\n playbackRate = 1;\n readonly ready: Promise<Animation> = Promise.resolve<Animation>(this);\n readonly replaceState: AnimationReplaceState = 'active';\n startTime: CSSNumberish | null = null;\n timeline: AnimationTimeline | null = null;\n\n cancel(): void {\n // Nothing is running.\n }\n commitStyles(): void {\n // The end state is already on the element.\n }\n finish(): void {\n // Already finished.\n }\n pause(): void {\n // Nothing is running.\n }\n persist(): void {\n // Nothing to persist.\n }\n play(): void {\n // Nothing to play.\n }\n reverse(): void {\n // Nothing to reverse.\n }\n updatePlaybackRate(rate: number): void {\n this.playbackRate = rate;\n }\n}\n\n/**\n * `el.animate(frames, options)`, or, where the Web Animations API is missing, the end state at\n * once: a `forwards` fill writes the last frame onto `el.style` (an exit stays hidden), any other\n * fill leaves the element as it is (an enter ends in its natural state). The returned animation\n * is finished either way.\n */\nexport function animateOrSettle(\n el: HTMLElement,\n frames: Keyframe[],\n options: KeyframeAnimationOptions,\n): Animation {\n if (typeof el.animate === 'function') {\n return el.animate(frames, options);\n }\n const last = frames[frames.length - 1];\n if (last && (options.fill === 'forwards' || options.fill === 'both')) {\n for (const [key, value] of Object.entries(last)) {\n if (!TIMING_KEYS.has(key) && value !== null && value !== undefined) {\n el.style.setProperty(\n key.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`),\n String(value),\n );\n }\n }\n }\n return new BfFinishedAnimation();\n}\n\nfunction run(el: HTMLElement, frames: Frame[], entering: boolean): Animation {\n if (prefersReducedMotion(el.ownerDocument.defaultView)) {\n const fade = entering ? [{ opacity: 0 }, { opacity: 1 }] : [{ opacity: 1 }, { opacity: 0 }];\n return animateOrSettle(el, fade, {\n duration: OVERLAY_REDUCED_DURATION,\n easing: 'linear',\n fill: entering ? 'backwards' : 'forwards',\n });\n }\n return animateOrSettle(el, frames, {\n duration: OVERLAY_DURATION,\n easing: OVERLAY_EASING,\n // Entering: hold the first frame until the animation starts. Leaving: hold the last frame\n // until the overlay is detached, so it never flashes back in.\n fill: entering ? 'backwards' : 'forwards',\n });\n}\n\n/**\n * Slides `el` up into place from `distance` below it (default: its own height).\n *\n * @param el The element to animate, usually the overlay panel.\n * @param distance How far below its place it starts, as a CSS length.\n * @returns The running animation.\n * @summary Slides an element up into place, the enter animation of a bottom sheet\n * @since 0.2.0\n */\nexport function slideUp(el: HTMLElement, distance = '100%'): Animation {\n return run(\n el,\n [{ transform: `translate3d(0,${distance},0)` }, { transform: 'translate3d(0,0,0)' }],\n true,\n );\n}\n\n/**\n * Slides `el` down out of place by `distance` (default: its own height).\n *\n * @param el The element to animate, usually the overlay panel.\n * @param distance How far below its place it ends, as a CSS length.\n * @returns The running animation.\n * @summary Slides an element down out of place, the exit animation of a bottom sheet\n * @since 0.2.0\n */\nexport function slideDown(el: HTMLElement, distance = '100%'): Animation {\n return run(\n el,\n [{ transform: 'translate3d(0,0,0)' }, { transform: `translate3d(0,${distance},0)` }],\n false,\n );\n}\n\n/**\n * Fades `el` in.\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Fades an element in, the default enter animation of an overlay\n * @since 0.2.0\n */\nexport function fadeIn(el: HTMLElement): Animation {\n return run(el, [{ opacity: 0 }, { opacity: 1 }], true);\n}\n\n/**\n * Fades `el` out.\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Fades an element out, the default exit animation of an overlay\n * @since 0.2.0\n */\nexport function fadeOut(el: HTMLElement): Animation {\n return run(el, [{ opacity: 1 }, { opacity: 0 }], false);\n}\n\n/**\n * Scales `el` up from 92 % while fading it in (centred dialogs).\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Scales an element up while fading it in, the enter animation of centred dialogs\n * @since 0.2.0\n */\nexport function scaleIn(el: HTMLElement): Animation {\n return run(\n el,\n [\n { opacity: 0, transform: 'scale(0.92)' },\n { opacity: 1, transform: 'scale(1)' },\n ],\n true,\n );\n}\n\n/**\n * Fades `el` in while it rises by `distance` (default 16 px; the Material modal enter).\n *\n * @param el The element to animate, usually the overlay panel.\n * @param distance How far below its place it starts, as a CSS length.\n * @returns The running animation.\n * @summary Fades an element in while it rises, the Material modal enter animation\n * @since 0.2.0\n */\nexport function fadeUp(el: HTMLElement, distance = '16px'): Animation {\n return run(\n el,\n [\n { opacity: 0, transform: `translate3d(0,${distance},0)` },\n { opacity: 1, transform: 'translate3d(0,0,0)' },\n ],\n true,\n );\n}\n\n/**\n * Fades `el` out while it sinks by `distance` (default 16 px; the reverse of `fadeUp`).\n *\n * @param el The element to animate, usually the overlay panel.\n * @param distance How far below its place it ends, as a CSS length.\n * @returns The running animation.\n * @summary Fades an element out while it sinks, the reverse of the fadeUp animation\n * @since 0.2.0\n */\nexport function fadeDown(el: HTMLElement, distance = '16px'): Animation {\n return run(\n el,\n [\n { opacity: 1, transform: 'translate3d(0,0,0)' },\n { opacity: 0, transform: `translate3d(0,${distance},0)` },\n ],\n false,\n );\n}\n\n/** `-` under `dir=\"rtl\"` (the CDK sets `dir` on the overlay host), so the end edge is the left. */\nfunction towardsEnd(el: HTMLElement): string {\n return el.closest('[dir]')?.getAttribute('dir') === 'rtl' ? '-' : '';\n}\n\n/**\n * Slides `el` in from beyond the inline end edge of the viewport (the right, the left under\n * `dir=\"rtl\"`) by its own width: the enter animation of a side panel.\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Slides an element in from the inline end, the enter animation of a side panel\n * @since 0.3.1\n */\nexport function slideInFromEnd(el: HTMLElement): Animation {\n return run(\n el,\n [{ transform: `translate3d(${towardsEnd(el)}100%,0,0)` }, { transform: 'translate3d(0,0,0)' }],\n true,\n );\n}\n\n/**\n * Slides `el` out past the inline end edge of the viewport by its own width (the reverse of\n * `slideInFromEnd`): the exit animation of a side panel.\n *\n * @param el The element to animate, usually the overlay panel.\n * @returns The running animation.\n * @summary Slides an element out past the inline end, the exit animation of a side panel\n * @since 0.3.1\n */\nexport function slideOutToEnd(el: HTMLElement): Animation {\n return run(\n el,\n [{ transform: 'translate3d(0,0,0)' }, { transform: `translate3d(${towardsEnd(el)}100%,0,0)` }],\n false,\n );\n}\n","import { FocusTrapFactory, type FocusTrap } from '@angular/cdk/a11y';\nimport {\n OverlayConfig,\n type PositionStrategy,\n createBlockScrollStrategy,\n createGlobalPositionStrategy,\n createNoopScrollStrategy,\n createOverlayRef,\n} from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { Location, NgTemplateOutlet } from '@angular/common';\nimport {\n Component,\n DOCUMENT,\n Injectable,\n Injector,\n type StaticProvider,\n TemplateRef,\n type Type,\n inject,\n input,\n} from '@angular/core';\nimport { type Subscription } from 'rxjs';\nimport { OVERLAY_DURATION, OVERLAY_EASING, prefersReducedMotion } from './motion';\nimport { watchPathChange } from './navigation';\nimport { animateOrSettle, fadeIn, fadeOut } from './overlay-animations';\nimport { BF_OVERLAY_HOST } from './overlay-host';\nimport { BF_OVERLAY_DATA, BfComponentOverlayRef, BfOverlayRef } from './overlay-ref';\nimport { BfOverlayStack } from './overlay-stack.service';\n\n/**\n * Where the overlay's panel sits in the viewport.\n *\n * @summary Where an overlay panel sits in the viewport: bottom, centre, top or fullscreen\n * @since 0.2.0\n */\nexport type BfOverlayPosition = 'bottom' | 'center' | 'top' | 'fullscreen';\n\n/**\n * Where an overlay panel sits: a `BfOverlayPosition`, or `end`, full height against the inline\n * end edge of the viewport (the right in a left-to-right page, the left under `dir=\"rtl\"`).\n *\n * @summary Where an overlay panel sits: a viewport position or full height at the end\n * @since 0.3.1\n */\nexport type BfOverlayPlacement = BfOverlayPosition | 'end';\n\n/**\n * The ARIA role of an overlay panel: a `dialog`, an `alertdialog` or a passive `status`.\n *\n * @summary The role an overlay panel carries: a dialog, an alert dialog or a status\n * @since 0.3.0\n */\nexport type BfOverlayRole = 'dialog' | 'alertdialog' | 'status';\n\n/**\n * Where focus goes when an overlay opens: the first tabbable element of the content\n * (`first-tabbable`, skipping the container's own controls such as `bf-sheet`'s hidden Close) or\n * the panel itself (`panel`).\n *\n * @summary Where focus lands when an overlay opens, its first control or the panel\n * @since 0.3.0\n */\nexport type BfOverlayAutoFocus = 'first-tabbable' | 'panel';\n\n/**\n * Options of `BfOverlayService.open()`.\n *\n * @summary Options of an overlay: its data, backdrop, focus, dismissal, position and motion\n * @since 0.2.0\n */\nexport interface BfOverlayOptions {\n /** Injected into the content as `BF_OVERLAY_DATA`. */\n data?: unknown;\n /** Extra classes on the panel (it always carries `bf-overlay-panel`). */\n panelClass?: string[];\n /**\n * Renders a backdrop behind the panel (default true; never for passive overlays).\n * @default true\n */\n backdrop?: boolean;\n /**\n * Class of the backdrop (default `bf-overlay-backdrop`: a black scrim, 40 % light / 60 % dark).\n * @default 'bf-overlay-backdrop'\n */\n backdropClass?: string;\n /**\n * A backdrop click closes the overlay (default true).\n * @default true\n */\n dismissOnBackdrop?: boolean;\n /**\n * `Escape` closes the overlay (default true).\n * @default true\n */\n dismissOnEscape?: boolean;\n /**\n * Runs instead of closing when the overlay is on top and `Escape` is pressed (e.g. an alert\n * resolving with its cancel button). The key is always claimed by the topmost non-passive\n * overlay, so it never reaches an overlay underneath.\n */\n onEscape?: () => void;\n /**\n * Role of the panel (default `dialog`; passive overlays get none unless one is given — a toast\n * is announced through `LiveAnnouncer`).\n * @default 'dialog'\n */\n role?: BfOverlayRole;\n /** Accessible name of the panel. */\n ariaLabel?: string;\n /**\n * Id of the element naming the panel. Dropped after the content renders when no element inside\n * the panel carries it and `ariaLabel` is unset, so the panel never points at nothing.\n */\n ariaLabelledBy?: string;\n /** Id of the element describing the panel (an alert's message). */\n ariaDescribedBy?: string;\n /**\n * Traps Tab focus inside the panel (default true).\n * @default true\n */\n trapFocus?: boolean;\n /**\n * Where focus goes on open (non-passive overlays): `first-tabbable` (default) — the element\n * marked `[autofocus]`/`[cdkFocusInitial]` when it is focusable (a control, or any element with\n * a `tabindex`, also `-1`), else the first tabbable element inside it, else (all its controls\n * disabled) the first tabbable element of the panel, else the panel; `panel` — the panel\n * itself, so a long text is read from its start (APG dialog pattern). `first-tabbable` skips the\n * library's own container controls (`bf-sheet`'s hidden Close and grabber button, marked with\n * the internal `data-bf-overlay-chrome`): they stay in the Tab order but never take the initial\n * focus, so it lands on your content.\n * @default 'first-tabbable'\n */\n autoFocus?: BfOverlayAutoFocus;\n /**\n * Returns focus to the previously focused element on close (default true); when that element\n * is gone, to the topmost overlay still open, else focus stays on the body (move it yourself,\n * e.g. to the next row after a delete).\n * @default true\n */\n restoreFocus?: boolean;\n /**\n * Placement of the panel (default `center`); `end` is full height at the inline end edge.\n * @default 'center'\n */\n position?: BfOverlayPlacement;\n /**\n * Closes the overlay when the URL path changes (default true; false for passive overlays): a\n * router navigation, a link, the browser's back and forward buttons. Query- or fragment-only\n * changes never close; a matrix-parameter change (`/a;x=1`) is a path change and closes. Read\n * from `Location.onUrlChange()`, so no router is needed, and a `history.pushState()` made\n * outside Angular's `Location` is not seen. An overlay opened before the first navigation ends\n * (root component, `APP_INITIALIZER`) closes when the start URL redirects: open it after the\n * first `NavigationEnd`, or pass false.\n * @default true\n */\n closeOnNavigation?: boolean;\n /**\n * Runs instead of `close()` when a navigation closes the overlay (e.g. an alert answering with\n * its cancel id); it should close the overlay.\n */\n onNavigation?: () => void;\n /**\n * Priority of the hardware back handler that closes the overlay (default 100).\n * @default 100\n */\n backPriority?: number;\n /**\n * Counts towards `BfOverlayStack.depth()` / `--bf-modal-depth` (default false).\n * @default false\n */\n countsAsModal?: boolean;\n /**\n * A passive overlay (a toast) has no backdrop, no focus trap, does not move focus, does not\n * count in `BfOverlayStack.count()`, registers no back handler and leaves the page interactive.\n * @default false\n */\n passive?: boolean;\n /**\n * A modal overlay (default true) has a backdrop, traps focus, is `aria-modal`, blocks document\n * scroll and makes the page behind it `inert`. A non-modal one (a side panel beside the page)\n * has none of these and is not in `BfOverlayStack`: focus moves in, the page stays usable,\n * `Escape` closes it only while focus is inside it, and on close focus returns to the opener\n * only from inside it. Ignored for passive overlays.\n * @default true\n */\n modal?: boolean;\n /**\n * Enter animation of the panel (default `fadeIn`); return null for none.\n * @default fadeIn\n */\n enter?: (el: HTMLElement) => Animation | null;\n /**\n * Exit animation of the panel (default `fadeOut`), awaited before detaching.\n * @default fadeOut\n */\n exit?: (el: HTMLElement) => Animation | null;\n /**\n * Parent of the content's injector (default the root injector), so the content resolves the\n * opener's providers, e.g. a feature-level `provideBfLabels()`.\n */\n injector?: Injector;\n /**\n * Extra providers of the content's injector, next to `BF_OVERLAY_DATA` and `BfOverlayRef`,\n * built with the new overlay's ref (e.g. a typed ref of a service built on the core).\n */\n providers?: (ref: BfOverlayRef<unknown>) => StaticProvider[];\n}\n\n/**\n * Context of a template opened as an overlay: `let-ref` and `let-data=\"data\"`.\n *\n * @summary The context a template opened as an overlay receives: its ref and data\n * @since 0.2.0\n */\nexport interface BfOverlayTemplateContext {\n /** The overlay's ref (`let-ref`), to close it with a result. */\n $implicit: BfOverlayRef<unknown>;\n /** The `data` the overlay was opened with (`let-data=\"data\"`). */\n data: unknown;\n}\n\n/** Renders a template opened through `BfOverlayService` inside the overlay pane. */\n@Component({\n selector: 'bf-overlay-template-host',\n imports: [NgTemplateOutlet],\n host: { style: 'display: contents' },\n template: `<ng-container\n [ngTemplateOutlet]=\"template()\"\n [ngTemplateOutletContext]=\"context()\"\n [ngTemplateOutletInjector]=\"injector()\"\n />`,\n})\nclass BfOverlayTemplateHostComponent {\n readonly template = input.required<TemplateRef<unknown>>();\n readonly context = input.required<BfOverlayTemplateContext>();\n readonly injector = input.required<Injector>();\n}\n\n/** The elements Tab stops at (without a negative tabindex). */\nexport const TABBABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n].join(',');\n\n/**\n * Where an overlay's initial focus goes inside `panel`: the `[autofocus]`/`[cdkFocusInitial]` mark,\n * else the first tabbable element that is not the container's own chrome. Shared with the popover.\n */\nexport function firstTabbable(panel: HTMLElement): HTMLElement | null {\n const autofocus = panel.querySelector<HTMLElement>('[autofocus], [cdkFocusInitial]');\n if (autofocus) {\n // A focusable mark (a control, or any element with a tabindex such as a tabindex=\"-1\"\n // region to start reading at) takes focus itself; a marked wrapper (a bf-button host) hands\n // it to the control inside. A wrapper whose controls are all disabled is skipped.\n if (autofocus.matches(TABBABLE) || autofocus.hasAttribute('tabindex')) {\n return autofocus;\n }\n const inner = autofocus.querySelector<HTMLElement>(TABBABLE);\n if (inner) {\n return inner;\n }\n }\n for (const el of Array.from(panel.querySelectorAll<HTMLElement>(TABBABLE))) {\n // A container's own controls (bf-sheet's screen-reader Close and grabber, marked\n // `data-bf-overlay-chrome`) stay in the Tab order but never take the initial focus.\n if (!el.closest('[inert]') && !el.hidden && !el.hasAttribute('data-bf-overlay-chrome')) {\n return el;\n }\n }\n return null;\n}\n\n/**\n * The part of the browser's `CloseWatcher` (Chromium 120+; not yet in TypeScript's `lib.dom`) the\n * core uses: `onclose` runs on a close request (Android back, `Escape` not already handled), and\n * `destroy()` stops watching without an event.\n */\ninterface BfCloseWatcher {\n onclose: (() => void) | null;\n destroy(): void;\n}\n\ntype BfCloseWatcherConstructor = new () => BfCloseWatcher;\n\nfunction isCloseWatcherConstructor(value: unknown): value is BfCloseWatcherConstructor {\n return typeof value === 'function';\n}\n\n/** The window's `CloseWatcher` constructor, or null where the browser has none. */\nfunction closeWatcherOf(view: Window | null): BfCloseWatcherConstructor | null {\n const constructor: unknown = view ? Reflect.get(view, 'CloseWatcher') : undefined;\n return isCloseWatcherConstructor(constructor) ? constructor : null;\n}\n\n/**\n * True when `event` started inside a CDK overlay pane other than `pane`, e.g. a CDK menu opened\n * from a dialog: its `Escape` is the menu's, so the dialog underneath stays open. Read from the\n * event path, which still holds the pane after the menu has closed and left the DOM.\n */\nfunction fromOtherPane(event: Event, pane: HTMLElement): boolean {\n for (const target of event.composedPath()) {\n if (target === pane) {\n return false;\n }\n if (target instanceof Element && target.classList.contains('cdk-overlay-pane')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Opens overlays on the Angular CDK `Overlay`: a component or template in a panel with a\n * backdrop, a focus trap, `role`/`aria-modal`/`aria-labelledby`, `Escape` and backdrop click\n * closing it, and the page behind it `inert` (see `BfOverlayStack`). A non-passive overlay blocks\n * document scroll (CDK `block()` scroll strategy); passive overlays, and every overlay under a\n * `BF_OVERLAY_HOST` whose document never scrolls (the `/mobile` `provideBfShell()`), use `noop()`.\n * Under `provideBfShell()` the hardware back button (priority 100) closes it too; without a host\n * no back handler is registered. Where the browser has `CloseWatcher` (Chromium 120+), a close\n * request (Android back in Chrome or a PWA) runs the `Escape` path on the top non-passive overlay,\n * unless the host handles the system back itself (`handlesSystemBack`). An overlay that does not\n * close on it (`dismissOnEscape: false` without `onEscape`, or an `onEscape` that keeps it open)\n * swallows Android web back for as long as it is open, as a non-dismissible sheet swallows the\n * hardware back button. A navigation to another URL path closes every non-passive\n * overlay (`closeOnNavigation`, read from `Location`, so no router is needed). `modal: false`\n * (a side panel beside the page) drops the backdrop, the trap, `aria-modal`, the scroll lock and\n * the `inert` page. The content injects `BF_OVERLAY_DATA` and `BfOverlayRef` (plus any\n * `providers`). `BfDialogService`, `BfSidePanelService` and the `/mobile` sheet, modal, toast,\n * action sheet and alert services build on it.\n *\n * @example\n * const ref = inject(BfOverlayService).open(ConfirmComponent, {\n * data: { name },\n * ariaLabelledBy: 'confirm-title',\n * });\n * const confirmed = await ref.afterClosed;\n *\n * @summary Opens a component or template in an overlay panel on the Angular CDK\n * @since 0.2.0\n */\n@Injectable({ providedIn: 'root' })\nexport class BfOverlayService {\n private readonly injector = inject(Injector);\n private readonly document = inject(DOCUMENT);\n private readonly stack = inject(BfOverlayStack);\n private readonly focusTrapFactory = inject(FocusTrapFactory);\n private readonly location = inject(Location);\n /** Panels of the open non-passive overlays, oldest first (focus fallback on close). */\n private readonly openPanels = new Set<HTMLElement>();\n private readonly host = inject(BF_OVERLAY_HOST, { optional: true });\n /** Under `provideBfShell()` the document never scrolls (the stack pages do). */\n private readonly documentScrolls = this.host?.documentScrolls !== false;\n\n /**\n * Opens `component` in an overlay.\n * @param component The component to render in the panel.\n * @param options The overlay's data, backdrop, focus, dismissal, position and motion.\n */\n open<C, T = unknown>(component: Type<C>, options?: BfOverlayOptions): BfComponentOverlayRef<C, T>;\n /**\n * Opens `template` in an overlay; its context is `{ $implicit: ref, data }`.\n * @param template The template to render in the panel.\n * @param options The overlay's data, backdrop, focus, dismissal, position and motion.\n */\n open<T = unknown>(template: TemplateRef<unknown>, options?: BfOverlayOptions): BfOverlayRef<T>;\n open<C, T = unknown>(\n content: Type<C> | TemplateRef<unknown>,\n options: BfOverlayOptions = {},\n ): BfOverlayRef<T> {\n const passive = options.passive ?? false;\n // A non-modal overlay leaves the page as it is: no backdrop, trap, inert or scroll lock.\n const modal = !passive && (options.modal ?? true);\n const previouslyFocused = this.document.activeElement as HTMLElement | null;\n const hasBackdrop = modal && (options.backdrop ?? true);\n const position = options.position ?? 'center';\n // The CDK's standalone factories, not its `Overlay` service, which would pull every scroll and\n // position strategy into an app's bundle.\n const overlayRef = createOverlayRef(\n this.injector,\n new OverlayConfig({\n positionStrategy: this.positionStrategy(position),\n // A modal overlay blocks document scroll (no scroll bleed behind a dialog on desktop); a\n // passive toast never does, and a host whose document never scrolls needs no lock.\n scrollStrategy:\n !modal || !this.documentScrolls\n ? createNoopScrollStrategy()\n : createBlockScrollStrategy(this.injector),\n hasBackdrop,\n backdropClass: options.backdropClass ?? 'bf-overlay-backdrop',\n panelClass: ['bf-overlay-panel', ...(options.panelClass ?? [])],\n ...(position === 'fullscreen' ? { width: '100%', height: '100%' } : {}),\n ...(position === 'end' ? { height: '100%' } : {}),\n }),\n );\n const panel = overlayRef.overlayElement;\n\n const subscriptions: Subscription[] = [];\n let focusTrap: FocusTrap | null = null;\n let enterAnimation: Animation | null = null;\n let stopNavigation: (() => void) | null = null;\n let closeWatcher: BfCloseWatcher | null = null;\n\n const controller = {\n close: async (): Promise<void> => {\n // A non-modal overlay hands focus back only from inside it: focus the user moved to the\n // page stays where it is.\n const active = this.document.activeElement;\n const focusInside = active === this.document.body || panel.contains(active);\n stopNavigation?.();\n closeWatcher?.destroy();\n closeWatcher = null;\n this.stack.releaseBack(ref);\n subscriptions.forEach((s) => s.unsubscribe());\n enterAnimation?.cancel();\n this.fadeOutBackdrop(overlayRef.backdropElement);\n try {\n const exit = (options.exit ?? fadeOut)(panel);\n await exit?.finished;\n } catch {\n // A cancelled exit animation still closes.\n }\n focusTrap?.destroy();\n overlayRef.dispose();\n this.stack.pop(ref);\n this.openPanels.delete(panel);\n if (!passive && (options.restoreFocus ?? true) && (modal || focusInside)) {\n // The opener may be gone (a deleted row, content re-rendered under a nested overlay):\n // then focus the topmost overlay still open, never the page behind it.\n const fallback = [...this.openPanels].at(-1);\n if (previouslyFocused?.isConnected) {\n previouslyFocused.focus({ preventScroll: true });\n } else if (fallback) {\n fallback.focus({ preventScroll: true });\n }\n }\n },\n updatePosition: (): void => overlayRef.updatePosition(),\n };\n\n const ref: BfOverlayRef<T> =\n content instanceof TemplateRef\n ? new BfOverlayRef<T>(controller)\n : new BfComponentOverlayRef<C, T>(controller);\n const contentInjector = Injector.create({\n parent: options.injector ?? this.injector,\n providers: [\n { provide: BF_OVERLAY_DATA, useValue: options.data },\n { provide: BfOverlayRef, useValue: ref },\n // A ref's result type only narrows what close() accepts; the providers see any result.\n ...(options.providers?.(ref as BfOverlayRef<unknown>) ?? []),\n ],\n });\n\n this.decoratePanel(panel, options, passive, modal);\n if (!passive) {\n this.openPanels.add(panel);\n }\n if (modal) {\n this.stack.push(ref, {\n backPriority: options.backPriority,\n countsAsModal: options.countsAsModal,\n });\n }\n\n if (content instanceof TemplateRef) {\n const host = overlayRef.attach(\n new ComponentPortal(BfOverlayTemplateHostComponent, null, contentInjector),\n );\n host.setInput('template', content);\n host.setInput('context', { $implicit: ref, data: options.data });\n host.setInput('injector', contentInjector);\n host.changeDetectorRef.detectChanges();\n } else {\n const componentRef = overlayRef.attach(new ComponentPortal(content, null, contentInjector));\n componentRef.changeDetectorRef.detectChanges();\n (ref as BfComponentOverlayRef<C, T>).setComponentRef(componentRef);\n }\n this.dropDanglingLabel(panel, options);\n\n if (!passive) {\n /** What `Escape` and a close request (Android web back) do on the top overlay. */\n const dismissByEscape = (): void => {\n if (options.onEscape) {\n options.onEscape();\n } else if (options.dismissOnEscape ?? true) {\n ref.close();\n }\n };\n // Always listen: the CDK hands a keydown to the topmost overlay that has listeners, so an\n // overlay that ignored Escape would let it fall through to the one underneath. Cancelling\n // the key also keeps it from reaching a `CloseWatcher` as a second close request.\n subscriptions.push(\n overlayRef.keydownEvents().subscribe((event) => {\n // A modal answers when it is the top one; a non-modal one (not in the stack) only for a\n // key pressed inside it, so Escape on the page beside it stays the page's.\n const target = event.target;\n const answers = modal\n ? this.stack.isTop(ref)\n : target instanceof Node && overlayRef.overlayElement.contains(target);\n if (\n event.key !== 'Escape' ||\n !answers ||\n fromOtherPane(event, overlayRef.overlayElement)\n ) {\n return;\n }\n event.preventDefault();\n dismissByEscape();\n }),\n );\n // Android back in a browser (Chrome, a PWA) is a close request: with a `CloseWatcher` it\n // closes the overlay instead of leaving the page. Not where the host already routes the\n // system back to `registerBack` (the shell on native Android).\n // A non-modal overlay leaves the back press to the page beside it.\n const Watcher =\n this.host?.handlesSystemBack || !modal ? null : closeWatcherOf(this.document.defaultView);\n const watch = (): void => {\n if (!Watcher) {\n return;\n }\n const watcher = new Watcher();\n watcher.onclose = (): void => {\n if (closeWatcher !== watcher) {\n return;\n }\n closeWatcher = null;\n if (ref.isClosing) {\n return;\n }\n if (this.stack.isTop(ref)) {\n dismissByEscape();\n }\n // Still open (not dismissible, or not the top one of a group the browser closed\n // together): keep claiming the next back press.\n if (!ref.isClosing) {\n watch();\n }\n };\n closeWatcher = watcher;\n };\n watch();\n // A press on the backdrop (not focusable) would move focus to <body>, out of the modal;\n // cancelling the mousedown keeps it where it was. The click still reaches backdropClick().\n overlayRef.backdropElement?.addEventListener('mousedown', (event) => event.preventDefault());\n if (hasBackdrop && (options.dismissOnBackdrop ?? true)) {\n subscriptions.push(overlayRef.backdropClick().subscribe(() => ref.close()));\n }\n if (modal && (options.trapFocus ?? true)) {\n focusTrap = this.focusTrapFactory.create(panel);\n }\n const target = options.autoFocus === 'panel' ? panel : (firstTabbable(panel) ?? panel);\n target.focus({ preventScroll: true });\n }\n\n if (options.closeOnNavigation ?? !passive) {\n stopNavigation = watchPathChange(this.location, () => {\n if (ref.isClosing) {\n return;\n }\n if (options.onNavigation) {\n options.onNavigation();\n } else {\n ref.close();\n }\n });\n }\n\n enterAnimation = (options.enter ?? fadeIn)(panel);\n return ref;\n }\n\n /** Fades the backdrop out alongside the panel's exit (instantly under reduced motion). */\n private fadeOutBackdrop(backdrop: HTMLElement | null): void {\n if (!backdrop) {\n return;\n }\n if (prefersReducedMotion(this.document.defaultView)) {\n backdrop.style.opacity = '0';\n return;\n }\n // Start from where the CDK's fade-in currently is (it may not have finished).\n const current = this.document.defaultView?.getComputedStyle(backdrop).opacity;\n const from = current === undefined || current === '' ? '1' : current;\n animateOrSettle(backdrop, [{ opacity: from }, { opacity: 0 }], {\n duration: OVERLAY_DURATION,\n easing: OVERLAY_EASING,\n fill: 'forwards',\n });\n }\n\n /** Removes an `aria-labelledby` whose id names no element inside the rendered panel. */\n private dropDanglingLabel(panel: HTMLElement, options: BfOverlayOptions): void {\n const id = options.ariaLabelledBy;\n if (!id || options.ariaLabel) {\n return;\n }\n const target = this.document.getElementById(id);\n if (!target || !panel.contains(target)) {\n panel.removeAttribute('aria-labelledby');\n }\n }\n\n private decoratePanel(\n panel: HTMLElement,\n options: BfOverlayOptions,\n passive: boolean,\n modal: boolean,\n ): void {\n const role = options.role ?? (passive ? null : 'dialog');\n if (role) {\n panel.setAttribute('role', role);\n }\n panel.setAttribute('tabindex', '-1');\n if (modal) {\n panel.setAttribute('aria-modal', 'true');\n }\n if (options.ariaLabel) {\n panel.setAttribute('aria-label', options.ariaLabel);\n }\n if (options.ariaLabelledBy) {\n panel.setAttribute('aria-labelledby', options.ariaLabelledBy);\n }\n if (options.ariaDescribedBy) {\n panel.setAttribute('aria-describedby', options.ariaDescribedBy);\n }\n }\n\n private positionStrategy(position: BfOverlayPlacement): PositionStrategy {\n const global = createGlobalPositionStrategy(this.injector);\n switch (position) {\n case 'bottom':\n return global.centerHorizontally().bottom('0');\n case 'top':\n return global.centerHorizontally().top('0');\n case 'fullscreen':\n return global.top('0').left('0');\n case 'end':\n // `end()` reads the overlay's direction: the right edge, or the left under rtl.\n return global.top('0').end('0');\n default:\n return global.centerHorizontally().centerVertically();\n }\n }\n}\n","let nextTitleId = 0;\n\n/** A heading inside an overlay's content: an `h1`–`h6` or a `[role=heading]`. */\nconst HEADING = 'h1, h2, h3, h4, h5, h6, [role=\"heading\"]';\n\n/**\n * Names an overlay panel by the first heading inside it that is not `aria-hidden` or `hidden`:\n * gives the heading an id when it has none (`bf-overlay-title-<n>`), points the panel's\n * `aria-labelledby` at it and drops the fallback `aria-label`. Leaves the panel as it is when\n * there is no heading. Returns whether it found one.\n */\nexport function labelPanelByHeading(panel: HTMLElement): boolean {\n const heading = Array.from(panel.querySelectorAll<HTMLElement>(HEADING)).find(\n (element) => !element.closest('[aria-hidden=\"true\"], [hidden]'),\n );\n if (!heading) {\n return false;\n }\n if (!heading.id) {\n heading.id = `bf-overlay-title-${nextTitleId++}`;\n }\n panel.setAttribute('aria-labelledby', heading.id);\n panel.removeAttribute('aria-label');\n return true;\n}\n\n/**\n * `labelPanelByHeading` now, and, while the content has no heading yet (content behind an `@if`\n * or a `resource()`), again whenever the panel's DOM changes, until the first heading appears.\n * Only that first heading names the panel; later changes are not followed. Returns a function\n * that stops watching; call it when the overlay closes.\n */\nexport function watchPanelHeading(panel: HTMLElement): () => void {\n if (labelPanelByHeading(panel)) {\n return () => undefined;\n }\n const observer = new MutationObserver(() => {\n if (labelPanelByHeading(panel)) {\n observer.disconnect();\n }\n });\n observer.observe(panel, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['role', 'aria-hidden', 'hidden'],\n });\n return () => observer.disconnect();\n}\n","/**\n * The action rendered as a real button inside a toast.\n *\n * @summary The action button of a toast: its label and what it runs when clicked\n * @since 0.2.0\n */\nexport interface BfToastAction {\n /** Text of the action button. */\n label: string;\n /** Runs before the toast closes with reason `'action'`. */\n handler?: () => void;\n}\n\n/**\n * Why a toast ended.\n *\n * @summary Why a toast ended: its time ran out, its action fired or it was dismissed\n * @since 0.2.0\n */\nexport type BfToastDismissReason = 'timeout' | 'action' | 'dismiss';\n\n/**\n * What the toast queue does for a toast ref; internal.\n *\n * @summary What the toast queue does for a toast ref: dismiss the toast now\n * @since 0.2.0\n */\nexport interface BfToastController {\n /** Ends the toast now: closes it if shown, or drops it from the queue if it never showed. */\n dismiss(): void;\n}\n\n/**\n * Handle to a toast, returned by `BfToastService.show()` (`/mobile`) and\n * `BfDesktopToastService.show()` (`/overlay`). `dismiss()` ends it immediately — closing it right\n * away if it is shown, or removing it from the queue before it ever shows. `afterDismissed`\n * resolves with why it ended: `'timeout'` (its duration elapsed), `'action'` (the action button\n * was clicked) or `'dismiss'` (`dismiss()` was called). The duration never runs out while the\n * toast is hovered or focused, and a toast with an action has none by default, so it only ends\n * with `'action'` or `'dismiss'` (`dismiss()`, `Escape` inside it, or the next `show()` replacing\n * it).\n *\n * @example\n * const ref = inject(BfToastService).show({ message: 'Saved' });\n * const reason = await ref.afterDismissed;\n * @since 0.2.0\n * @summary Handle on a shown or queued toast that dismisses it and reports why it ended\n */\nexport class BfToastRef {\n /** Resolves with why the toast ended. */\n readonly afterDismissed: Promise<BfToastDismissReason>;\n\n constructor(\n private readonly controller: BfToastController,\n afterDismissed: Promise<BfToastDismissReason>,\n ) {\n this.afterDismissed = afterDismissed;\n }\n\n /** Ends the toast now; see the class doc. */\n dismiss(): void {\n this.controller.dismiss();\n }\n}\n","/**\n * The toast engine shared by the `/mobile` `BfToastService` and the `/overlay`\n * `BfDesktopToastService`: timing, hold, replace, focus return, announcements and teardown.\n * Internal (`ɵ`-prefixed), not public API; it may change in any release.\n */\nimport type { LiveAnnouncer } from '@angular/cdk/a11y';\nimport type { DestroyRef } from '@angular/core';\nimport { type BfToastAction, type BfToastDismissReason, BfToastRef } from './toast-ref';\n\n/** One `show()` call; not public API. */\nexport interface ɵBfToastRequest {\n message: string;\n action?: BfToastAction;\n /** Default 3000 without an action, 0 (persistent) with one. */\n duration?: number;\n}\n\n/** What a presenter renders for one toast; not public API. */\nexport interface ɵBfToastView {\n readonly message: string;\n /** The action button, or null; `run()` calls the handler and closes with `'action'`. */\n readonly action: { label: string; run: () => void } | null;\n /** Pauses (`held: true`) or resumes this toast's timer. */\n hold(source: 'pointer' | 'focus', held: boolean): void;\n /** `Escape` inside the toast: dismisses it (`'dismiss'`). */\n escape(): void;\n}\n\n/** A rendered toast; not public API. */\nexport interface ɵBfToastHandle {\n /** The toast's element (focus inside it counts as \"in the toast\"). */\n readonly host: HTMLElement | null;\n /** Plays the exit and removes the toast; resolves once it is gone. */\n close(reason: BfToastDismissReason): Promise<void>;\n}\n\n/**\n * Renders toasts for the queue; `request` is the `show()` argument as given (a presenter reads\n * its own extra fields from it, e.g. the mobile `position`). Not public API.\n */\nexport interface ɵBfToastPresenter<R extends ɵBfToastRequest = ɵBfToastRequest> {\n present(view: ɵBfToastView, request: R): ɵBfToastHandle;\n}\n\n/** Options of `ɵBfToastQueue`; not public API. */\nexport interface ɵBfToastQueueOptions {\n /** How many toasts are shown at once (1 on mobile). */\n maxVisible: number;\n announcer: LiveAnnouncer;\n document: Document;\n /** Ends every toast (timers, listeners) when destroyed; later `show()` calls resolve `'dismiss'`. */\n destroyRef: DestroyRef;\n}\n\ninterface Entry<R> {\n request: R;\n message: string;\n action: BfToastAction | undefined;\n duration: number;\n resolve: (reason: BfToastDismissReason) => void;\n dismissed: boolean;\n /** Set once the toast is shown; ends it (idempotent). */\n finish?: (reason: BfToastDismissReason) => void;\n}\n\n/** Default lifetime of a toast without an action; one with an action persists (WCAG 2.2.1). */\nconst DEFAULT_DURATION = 3000;\n\n/** What the live announcer reads: the message, then the action label as its own sentence. */\nfunction announcement(message: string, action: BfToastAction | undefined): string {\n if (!action) {\n return message;\n }\n // A message that already ends in punctuation takes the label after a space (\"Failed: Retry\").\n const separator = /[.!?…:;,]$/.test(message.trim()) ? ' ' : '. ';\n return `${message.trim()}${separator}${action.label}`;\n}\n\n/**\n * Queues toasts and shows up to `maxVisible` at once through a presenter. A toast\n * auto-dismisses after `duration` ms (`'timeout'`); a persistent one (`duration` 0, the default\n * with an action) never blocks the queue: the next `show()` dismisses it, visible or waiting\n * (`'dismiss'`). The timer pauses while held (pointer or focus) and resumes with the rest. A\n * toast holding focus when it closes hands focus back to the element focused last outside it.\n * Each toast is announced once, politely, as it shows. Not public API.\n */\nexport class ɵBfToastQueue<R extends ɵBfToastRequest = ɵBfToastRequest> {\n private readonly waiting: Entry<R>[] = [];\n /** Shown toasts, oldest first, until their exit has finished (they hold their slot). */\n private readonly shown = new Set<Entry<R>>();\n private destroyed = false;\n\n constructor(\n private readonly presenter: ɵBfToastPresenter<R>,\n private readonly options: ɵBfToastQueueOptions,\n ) {\n // Ends every toast (clearing its timer and document listeners) with the injector.\n options.destroyRef.onDestroy(() => {\n this.destroyed = true;\n for (const entry of [...this.waiting, ...this.shown]) {\n this.dismissEntry(entry);\n }\n });\n }\n\n /**\n * Queues `request`; shows it now while fewer than `maxVisible` are shown, else once one ends.\n * Every persistent toast, shown or waiting, is dismissed first.\n */\n show(request: R): BfToastRef {\n let resolve: (reason: BfToastDismissReason) => void = () => undefined;\n const afterDismissed = new Promise<BfToastDismissReason>((res) => {\n resolve = res;\n });\n const entry: Entry<R> = {\n request,\n message: request.message,\n action: request.action,\n duration: request.duration ?? (request.action ? 0 : DEFAULT_DURATION),\n resolve,\n dismissed: false,\n };\n const ref = new BfToastRef({ dismiss: () => this.dismissEntry(entry) }, afterDismissed);\n if (this.destroyed) {\n entry.dismissed = true;\n resolve('dismiss');\n return ref;\n }\n for (const stale of [...this.waiting, ...this.shown]) {\n if (stale.duration <= 0) {\n this.dismissEntry(stale);\n }\n }\n this.waiting.push(entry);\n this.pump();\n return ref;\n }\n\n private dismissEntry(entry: Entry<R>): void {\n if (entry.dismissed) {\n return;\n }\n if (entry.finish) {\n entry.finish('dismiss');\n return;\n }\n const index = this.waiting.indexOf(entry);\n if (index >= 0) {\n this.waiting.splice(index, 1);\n }\n entry.dismissed = true;\n entry.resolve('dismiss');\n }\n\n private pump(): void {\n while (!this.destroyed && this.shown.size < this.options.maxVisible) {\n const entry = this.waiting.shift();\n if (!entry) {\n return;\n }\n this.shown.add(entry);\n this.present(entry);\n }\n }\n\n private present(entry: Entry<R>): void {\n const doc = this.options.document;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let remaining = entry.duration;\n let startedAt = 0;\n const holds = new Set<'pointer' | 'focus'>();\n let handle: ɵBfToastHandle | null = null;\n /** A reason given before the presenter returned its handle (closed right after). */\n let early: BfToastDismissReason | null = null;\n // Where focus goes back to if the toast still holds it when it closes: the element focused\n // last outside the toast (at open, or since), or nothing once focus fell to the page body.\n let returnTo = this.focusedElement();\n const inToast = (target: EventTarget | null): boolean =>\n target instanceof Node && (handle?.host?.contains(target) ?? false);\n const onDocumentFocusIn = (event: FocusEvent): void => {\n if (!inToast(event.target)) {\n returnTo = event.target instanceof HTMLElement ? event.target : null;\n }\n };\n const onDocumentFocusOut = (event: FocusEvent): void => {\n if (!inToast(event.target) && event.relatedTarget === null) {\n returnTo = null;\n }\n };\n\n const pauseTimer = (): void => {\n if (timer === null) {\n return;\n }\n clearTimeout(timer);\n timer = null;\n remaining -= Date.now() - startedAt;\n };\n const startTimer = (): void => {\n if (entry.duration <= 0 || entry.dismissed || timer !== null || holds.size > 0) {\n return;\n }\n startedAt = Date.now();\n timer = setTimeout(() => finish('timeout'), Math.max(0, remaining));\n };\n\n const close = (current: ɵBfToastHandle, reason: BfToastDismissReason): void => {\n void current.close(reason).then(() => {\n entry.resolve(reason);\n this.shown.delete(entry);\n this.pump();\n });\n };\n\n const finish = (reason: BfToastDismissReason): void => {\n if (entry.dismissed) {\n return;\n }\n entry.dismissed = true;\n pauseTimer();\n doc.removeEventListener('focusin', onDocumentFocusIn, true);\n doc.removeEventListener('focusout', onDocumentFocusOut, true);\n if (inToast(doc.activeElement) && returnTo?.isConnected) {\n returnTo.focus({ preventScroll: true });\n }\n if (handle) {\n close(handle, reason);\n } else {\n early = reason;\n }\n };\n entry.finish = finish;\n\n const view: ɵBfToastView = {\n message: entry.message,\n action: entry.action\n ? {\n label: entry.action.label,\n run: () => {\n if (entry.dismissed) {\n return;\n }\n entry.action?.handler?.();\n finish('action');\n },\n }\n : null,\n hold: (source, held) => {\n if (held) {\n holds.add(source);\n pauseTimer();\n } else {\n holds.delete(source);\n startTimer();\n }\n },\n escape: () => finish('dismiss'),\n };\n\n handle = this.presenter.present(view, entry.request);\n if (early) {\n close(handle, early);\n return;\n }\n doc.addEventListener('focusin', onDocumentFocusIn, true);\n doc.addEventListener('focusout', onDocumentFocusOut, true);\n void this.options.announcer.announce(announcement(entry.message, entry.action), 'polite');\n startTimer();\n }\n\n /** The focused element, or null when focus is on the body (nothing to return to). */\n private focusedElement(): HTMLElement | null {\n const active = this.options.document.activeElement;\n return active instanceof HTMLElement && active !== this.options.document.body ? active : null;\n }\n}\n","import { InjectionToken, type Signal } from '@angular/core';\nimport { type BfOverlayRef } from '../core/overlay-ref';\n\n/**\n * The dialog's own width scale (not `BfSize`, which is a control-height scale): `sm` 24 rem,\n * `md` 32 rem, `lg` 48 rem, `xl` 64 rem — each never wider than the viewport minus a gutter on\n * both sides — and `fullscreen`, edge to edge.\n *\n * @summary The dialog width scale from a 24 rem confirm to an edge-to-edge fullscreen dialog\n * @since 0.3.0\n */\nexport type BfDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';\n\n/**\n * The `data` passed to `BfDialogService.open()`, injectable in the dialog's content.\n *\n * @summary Injection token carrying the data a dialog was opened with, for its content\n * @since 0.3.0\n */\nexport const BF_DIALOG_DATA = new InjectionToken<unknown>('BF_DIALOG_DATA');\n\n/** @internal What `BfDialogService` tells the `bf-dialog` inside its content. */\nexport interface BfDialogContext {\n /** Id the `bf-dialog` title renders with; the panel's `aria-labelledby` points to it. */\n readonly titleId: string;\n readonly size: BfDialogSize;\n}\n\n/** @internal Provided by `BfDialogService` to the dialog's content. */\nexport const BF_DIALOG_CONTEXT = new InjectionToken<BfDialogContext>('BF_DIALOG_CONTEXT');\n\n/**\n * Handle to an open dialog, returned by `BfDialogService.open()` and injectable in the dialog's\n * content (`inject(BfDialogRef)`). `close(result)` plays the exit animation, detaches the dialog\n * and resolves `afterClosed` with `result`; later calls are ignored. Closing with `Escape`, the\n * backdrop or the `bf-dialog` close button resolves `undefined`.\n *\n * @example\n * const ref = inject(BfDialogService).open<RenameDialogComponent, { name: string }, string>(\n * RenameDialogComponent,\n * { data: { name } },\n * );\n * const newName = await ref.afterClosed;\n *\n * @summary Handle on an open dialog that closes it and resolves with its result\n * @since 0.3.0\n */\nexport class BfDialogRef<R = unknown, C = unknown> {\n /** Unique id of the dialog (its overlay's `bf-overlay-N`). */\n readonly id: string;\n /** Resolves with the result given to `close()`, or `undefined`, once the dialog is detached. */\n readonly afterClosed: Promise<R | undefined>;\n /** True once the dialog has been detached. */\n readonly closed: Signal<boolean>;\n\n /** @internal Created by `BfDialogService`; apps never construct it. */\n constructor(\n private readonly overlayRef: BfOverlayRef<unknown>,\n private readonly instance: () => C | null = () => null,\n ) {\n this.id = overlayRef.id;\n // The overlay resolves with whatever close() was given, which is typed R here.\n this.afterClosed = overlayRef.afterClosed as Promise<R | undefined>;\n this.closed = overlayRef.closed;\n }\n\n /** The content component; `null` for a dialog opened from a template. */\n get componentInstance(): C | null {\n return this.instance();\n }\n\n /**\n * Closes the dialog with an optional result; ignored once closing.\n * @param result The value `afterClosed` resolves with.\n */\n close(result?: R): void {\n this.overlayRef.close(result);\n }\n}\n\n/**\n * Context of a template opened with `BfDialogService.open()`: `let-ref` and `let-data=\"data\"`.\n *\n * @summary The context a template opened as a dialog receives: its ref and its data\n * @since 0.3.0\n */\nexport interface BfDialogTemplateContext<D = unknown, R = unknown> {\n /** The dialog's ref (`let-ref`), to close it with a result. */\n $implicit: BfDialogRef<R>;\n /** The `data` the dialog was opened with (`let-data=\"data\"`). */\n data: D;\n}\n","import {\n Component,\n DestroyRef,\n type ElementRef,\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { BF_LABELS, BfIconButtonComponent, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfIconComponent } from '@bitforgehq/ui/icons';\nimport { X } from 'lucide';\nimport { BF_DIALOG_CONTEXT, BfDialogRef, type BfDialogSize } from './dialog-ref';\n\nconst HOST_BASE = 'relative flex flex-col bg-surface text-text';\n\n/* The card sizes cap at their width and at the viewport minus a gutter on each side; fullscreen\n fills the pane that the service stretches over the viewport. A transparent border is invisible\n here but forced colours paints it CanvasText, giving the card an edge once its shadow and the\n scrim behind it both flatten to Canvas. */\nconst CARD =\n 'max-h-[calc(100dvh-2*var(--spacing-gutter))] rounded-card shadow-floating border border-transparent';\nconst SIZE: Record<BfDialogSize, string> = {\n sm: `w-[min(24rem,calc(100vw-2*var(--spacing-gutter)))] ${CARD}`,\n md: `w-[min(32rem,calc(100vw-2*var(--spacing-gutter)))] ${CARD}`,\n lg: `w-[min(48rem,calc(100vw-2*var(--spacing-gutter)))] ${CARD}`,\n xl: `w-[min(64rem,calc(100vw-2*var(--spacing-gutter)))] ${CARD}`,\n fullscreen: 'h-full w-full',\n};\n\n/* With a close button the header always renders (it holds the ×'s row) and keeps clear of it. */\nconst HEADER_BASE = 'flex min-w-0 shrink-0 items-start gap-3 px-6 pt-6';\nconst HEADER: Record<'close' | 'plain', string> = {\n close: `${HEADER_BASE} min-h-14 pe-14`,\n plain: `${HEADER_BASE} empty:hidden`,\n};\n\n/**\n * Layout of a modal dialog opened with `BfDialogService`: a title row, a scrolling body and a\n * footer of actions. The panel is labelled by the title, and the body becomes focusable only\n * while its content overflows, so keyboard users can scroll it (a region named by the title when\n * there is one).\n *\n * @example\n * const ref = inject(BfDialogService).open(RenameDialogComponent, { data: { name } });\n * // RenameDialogComponent template:\n * // <bf-dialog title=\"Rename project\"> …fields…\n * // <div bfSlot=\"footer\">…buttons…</div> </bf-dialog>\n * @summary Desktop modal dialog with a title, scrolling body, footer actions and focus trap\n * @category Overlays\n * @since 0.3.0\n * @slot header More header content after the title, such as a status badge.\n * @slot default The dialog body.\n * @slot footer The actions, aligned at the end.\n */\n@Component({\n selector: 'bf-dialog',\n imports: [BfIconButtonComponent, BfIconComponent],\n // `data-bf-dialog-id` (the dialog's own title id, also without a title) lets test harnesses find\n // the overlay panel this card sits in.\n host: { '[class]': 'hostClasses()', '[attr.data-bf-dialog-id]': 'titleId' },\n template: `\n <div data-dialog-header [class]=\"headerClasses()\">\n @if (title()) {\n <h2 [id]=\"titleId\" class=\"text-heading min-w-0 flex-1 wrap-anywhere\">{{ title() }}</h2>\n }\n <ng-content select=\"[bfSlot=header]\" />\n </div>\n <div\n #body\n data-dialog-body\n class=\"focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto overscroll-contain px-6 py-4 focus-visible:ring-4 focus-visible:outline-hidden focus-visible:ring-inset\"\n [attr.tabindex]=\"overflowing() ? 0 : null\"\n [attr.role]=\"overflowing() && title() ? 'region' : null\"\n [attr.aria-labelledby]=\"overflowing() && title() ? titleId : null\"\n >\n <div #content class=\"flex flex-col gap-4\"><ng-content /></div>\n </div>\n <!-- A projected wrapper (<div bfSlot=\"footer\">) lays out its buttons like the row itself. -->\n <div\n data-dialog-footer\n class=\"flex shrink-0 flex-wrap justify-end gap-2 px-6 pb-6 *:flex *:min-w-0 *:flex-wrap *:justify-end *:gap-2 empty:hidden\"\n >\n <ng-content select=\"[bfSlot=footer]\" />\n </div>\n @if (closeButton()) {\n <!-- Last in DOM order so first-tabbable focus lands on the content, not on the ×. -->\n <bf-icon-button\n data-dialog-close\n class=\"absolute end-3 top-3\"\n variant=\"text\"\n size=\"sm\"\n [label]=\"closeName()\"\n (clicked)=\"close()\"\n >\n <bf-icon [icon]=\"closeIcon\" />\n </bf-icon-button>\n }\n `,\n})\nexport class BfDialogComponent {\n private readonly labels = inject(BF_LABELS);\n private readonly context = inject(BF_DIALOG_CONTEXT, { optional: true });\n private readonly ref = inject(BfDialogRef, { optional: true });\n\n /** Heading of the dialog, rendered as the `h2` the dialog panel is labelled by. */\n readonly title = input('');\n /** Shows a close button (×) at the top end that closes the dialog with no result. */\n readonly closeButton = input(true, { transform: booleanAttribute });\n /** Accessible name of the close button; empty uses `provideBfLabels()`'s `close` (\"Close\"). */\n readonly closeLabel = input('');\n\n /** True while the body's content is taller than the body (it scrolls). */\n protected readonly overflowing = signal(false);\n\n protected readonly titleId = this.context?.titleId ?? uniqueId('bf-dialog-title');\n protected readonly closeIcon = X;\n private readonly size = this.context?.size ?? 'md';\n protected readonly hostClasses = computed(() => `${HOST_BASE} ${SIZE[this.size]}`);\n protected readonly headerClasses = computed(() => HEADER[this.closeButton() ? 'close' : 'plain']);\n protected readonly closeName = computed(() => this.closeLabel() || this.labels.close);\n\n private readonly body = viewChild.required<ElementRef<HTMLElement>>('body');\n private readonly content = viewChild.required<ElementRef<HTMLElement>>('content');\n\n constructor() {\n let observer: ResizeObserver | null = null;\n afterNextRender(() => {\n const body = this.body().nativeElement;\n const measure = (): void => this.overflowing.set(body.scrollHeight > body.clientHeight);\n measure();\n if (typeof ResizeObserver === 'function') {\n observer = new ResizeObserver(measure);\n observer.observe(body);\n observer.observe(this.content().nativeElement);\n }\n });\n inject(DestroyRef).onDestroy(() => observer?.disconnect());\n }\n\n /** Closes the dialog with no result (does nothing outside `BfDialogService`). */\n protected close(): void {\n this.ref?.close();\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n Component,\n InjectionToken,\n Injectable,\n Injector,\n type StaticProvider,\n TemplateRef,\n type Type,\n inject,\n} from '@angular/core';\nimport {\n BF_LABELS,\n BfButtonComponent,\n type BfButtonVariant,\n ɵuniqueId as uniqueId,\n} from '@bitforgehq/ui';\nimport { fadeIn, fadeOut, scaleIn } from '../core/overlay-animations';\nimport { watchPanelHeading } from '../core/overlay-heading';\nimport { type BfComponentOverlayRef, type BfOverlayRef } from '../core/overlay-ref';\nimport { type BfOverlayAutoFocus, BfOverlayService } from '../core/overlay.service';\nimport { BfDialogComponent } from './dialog.component';\nimport {\n BF_DIALOG_CONTEXT,\n BF_DIALOG_DATA,\n BfDialogRef,\n type BfDialogSize,\n type BfDialogTemplateContext,\n} from './dialog-ref';\n\n/**\n * Options of `BfDialogService.open()`.\n *\n * @summary Options of a dialog: its data, width, role, dismissal, focus and injector\n * @since 0.3.0\n */\nexport interface BfDialogConfig<D = unknown> {\n /** Injected into the content as `BF_DIALOG_DATA` (and a template's `data`). */\n data?: D;\n /**\n * Width of the `bf-dialog` in the content (default `md`, 32 rem).\n * @default 'md'\n */\n size?: BfDialogSize;\n /**\n * `alertdialog` for a dialog that demands an answer (default `dialog`).\n * @default 'dialog'\n */\n role?: BfDialogRole;\n /** Accessible name, when the content renders no `bf-dialog` title and no heading. */\n ariaLabel?: string;\n /** Id of the element describing the dialog (e.g. its message). */\n ariaDescribedBy?: string;\n /** A backdrop click closes the dialog (default true for `dialog`, false for `alertdialog`). */\n dismissOnBackdrop?: boolean;\n /**\n * `Escape` closes the dialog (default true); when false the key is claimed and ignored.\n * @default true\n */\n dismissOnEscape?: boolean;\n /**\n * Initial focus (default `first-tabbable`: an `[autofocus]`/`[cdkFocusInitial]` element, else\n * the first tabbable element); `panel` focuses the dialog itself, for long text.\n * @default 'first-tabbable'\n */\n autoFocus?: BfOverlayAutoFocus;\n /**\n * Returns focus to the element that had it before opening (default true).\n * @default true\n */\n restoreFocus?: boolean;\n /**\n * A navigation to another URL path closes the dialog with no result (default true).\n * @default true\n */\n closeOnNavigation?: boolean;\n /** Extra classes on the overlay panel (it always carries `bf-overlay-panel bf-dialog-panel`). */\n panelClass?: string[];\n /**\n * Parent of the content's injector and source of its labels (default the root injector). Pass\n * the opener's `inject(Injector)` so a feature-level `provideBfLabels()` reaches the dialog.\n */\n injector?: Injector;\n}\n\n/**\n * A button of `BfDialogService.confirm()`.\n *\n * @summary One button of a confirm dialog: its answer, its label and its role\n * @since 0.3.0\n */\nexport interface BfConfirmButton {\n /** The value `confirm()` resolves with (default the `label`). */\n id?: string;\n /** Button text. */\n label: string;\n /** `cancel` answers `Escape` and gets initial focus; `destructive` renders `danger`. */\n role?: BfConfirmButtonRole;\n}\n\n/**\n * The ARIA role of a dialog: `dialog`, or `alertdialog` for one that demands an answer.\n *\n * @summary The role a dialog carries, plain or an alert dialog that demands an answer\n * @since 0.3.0\n */\nexport type BfDialogRole = 'dialog' | 'alertdialog';\n\n/**\n * The role of a confirm dialog button: `cancel` answers `Escape`, `destructive` renders `danger`.\n *\n * @summary The role of a confirm dialog button, the cancel answer or a destructive action\n * @since 0.3.0\n */\nexport type BfConfirmButtonRole = 'cancel' | 'destructive';\n\n/**\n * The width of a confirm dialog: `sm` (24 rem) or `md`.\n *\n * @summary The two widths a confirm dialog comes in, small or medium\n * @since 0.3.0\n */\nexport type BfConfirmSize = 'sm' | 'md';\n\n/**\n * Options of `BfDialogService.confirm()`.\n *\n * @summary Options of a confirm dialog: its title, message, buttons and width\n * @since 0.3.0\n */\nexport interface BfConfirmOptions {\n /** Heading, rendered as the `h2` the alert dialog is labelled by. */\n title: string;\n /** Text under the title; the dialog's `aria-describedby` points to it. */\n message?: string;\n /**\n * Buttons, in order, right-aligned (default Cancel and OK from `provideBfLabels()`, ids\n * `cancel` and `ok`).\n */\n buttons?: readonly BfConfirmButton[];\n /**\n * Width (default `sm`, 24 rem).\n * @default 'sm'\n */\n size?: BfConfirmSize;\n /**\n * A navigation to another URL path closes the dialog, resolving the cancel button's answer, or\n * `undefined` without one (default true).\n * @default true\n */\n closeOnNavigation?: boolean;\n /** Source of the default button labels and parent of the content's injector. */\n injector?: Injector;\n}\n\n/** One confirm button as `bf-confirm-dialog` renders it. */\ninterface ConfirmButtonView {\n label: string;\n answer: string;\n variant: BfButtonVariant;\n initial: boolean;\n}\n\n/** What `confirm()` hands `bf-confirm-dialog` as its `BF_DIALOG_DATA`. */\ninterface ConfirmData {\n title: string;\n message: string | undefined;\n messageId: string;\n buttons: ConfirmButtonView[];\n}\n\n/** What the template host renders: the caller's template with the dialog context. */\ninterface DialogTemplate {\n template: TemplateRef<BfDialogTemplateContext<unknown, unknown>>;\n context: BfDialogTemplateContext<unknown, unknown>;\n}\n\nconst BF_DIALOG_TEMPLATE = new InjectionToken<DialogTemplate>('BF_DIALOG_TEMPLATE');\n\n/** Renders a template opened through `BfDialogService` inside the dialog pane. */\n@Component({\n selector: 'bf-dialog-template-host',\n imports: [NgTemplateOutlet],\n host: { style: 'display: contents' },\n template: `<ng-container\n [ngTemplateOutlet]=\"view.template\"\n [ngTemplateOutletContext]=\"view.context\"\n [ngTemplateOutletInjector]=\"injector\"\n />`,\n})\nclass BfDialogTemplateHostComponent {\n protected readonly view = inject(BF_DIALOG_TEMPLATE);\n protected readonly injector = inject(Injector);\n}\n\n/** The alert dialog of `BfDialogService.confirm()`, built from `bf-dialog`. */\n@Component({\n selector: 'bf-confirm-dialog',\n imports: [BfDialogComponent, BfButtonComponent],\n host: { style: 'display: contents' },\n template: `\n <bf-dialog [title]=\"data.title\" [closeButton]=\"false\">\n @if (data.message) {\n <p [id]=\"data.messageId\" class=\"text-body text-text-secondary\">{{ data.message }}</p>\n }\n <div bfSlot=\"footer\">\n @for (button of data.buttons; track $index) {\n <bf-button\n [variant]=\"button.variant\"\n [attr.cdkFocusInitial]=\"button.initial ? '' : null\"\n (clicked)=\"ref.close(button.answer)\"\n >\n {{ button.label }}\n </bf-button>\n }\n </div>\n </bf-dialog>\n `,\n})\nclass BfConfirmDialogComponent {\n protected readonly data = inject(BF_DIALOG_DATA) as ConfirmData;\n protected readonly ref = inject(BfDialogRef) as BfDialogRef<string>;\n}\n\n/**\n * Opens modal dialogs on the overlay core, centred over a backdrop: a component or a template in\n * a pane labelled by its `bf-dialog` title, with focus moved in and trapped, `Escape` and a\n * backdrop click closing it (never the backdrop for an `alertdialog`), focus returned to the\n * opener, document scroll locked and the page behind it `inert`. `confirm()` opens an alert\n * dialog with a title, a message and a row of buttons and resolves with the pressed button's\n * `id ?? label`.\n *\n * @example\n * const ref = inject(BfDialogService).open(RenameDialogComponent, { data: { name } });\n * const answer = await inject(BfDialogService).confirm({\n * title: 'Delete project?',\n * message: 'This cannot be undone.',\n * buttons: [\n * { id: 'cancel', label: 'Cancel', role: 'cancel' },\n * { id: 'delete', label: 'Delete', role: 'destructive' },\n * ],\n * });\n * @since 0.3.0\n * @summary Opens modal dialogs and confirm prompts, centred over the page with focus trapped\n */\n@Injectable({ providedIn: 'root' })\nexport class BfDialogService {\n private readonly overlays = inject(BfOverlayService);\n private readonly injector = inject(Injector);\n\n /**\n * Opens `component` as a dialog; it injects `BfDialogRef` and `BF_DIALOG_DATA`.\n * @param component The component to render; it injects `BfDialogRef` and `BF_DIALOG_DATA`.\n * @param config The dialog's data, width, role, dismissal, focus and injector.\n */\n open<C, D = unknown, R = unknown>(\n component: Type<C>,\n config?: BfDialogConfig<D>,\n ): BfDialogRef<R, C>;\n /**\n * Opens `template` as a dialog; its context is `{ $implicit: ref, data }`.\n * @param template The template to render, with the context `{ $implicit: ref, data }`.\n * @param config The dialog's data, width, role, dismissal, focus and injector.\n */\n open<D = unknown, R = unknown>(\n template: TemplateRef<BfDialogTemplateContext<D, R>>,\n config?: BfDialogConfig<D>,\n ): BfDialogRef<R>;\n open<C, D, R>(\n content: Type<C> | TemplateRef<BfDialogTemplateContext<D, R>>,\n config: BfDialogConfig<D> = {},\n ): BfDialogRef<R, C> {\n return this.openDialog<C, D, R>(content, config, {});\n }\n\n /**\n * Opens an alert dialog (`role=\"alertdialog\"`, described by `message`, no backdrop dismiss)\n * and resolves with the pressed button's `id ?? label`. Focus starts on the `cancel`-role\n * button, else the first button; `Escape` resolves the cancel button's answer, or is ignored\n * when there is none. A navigation to another path resolves the cancel button's answer, else\n * `undefined`.\n * @param options The title, message, buttons and width of the alert dialog.\n * @returns The pressed button's `id ?? label`, or `undefined`.\n */\n confirm(options: BfConfirmOptions): Promise<string | undefined> {\n const injector = options.injector ?? this.injector;\n const labels = injector.get(BF_LABELS);\n const buttons: readonly BfConfirmButton[] = options.buttons?.length\n ? options.buttons\n : [\n { id: 'cancel', label: labels.cancel, role: 'cancel' },\n { id: 'ok', label: labels.ok },\n ];\n const cancelIndex = buttons.findIndex((button) => button.role === 'cancel');\n const initialIndex = cancelIndex >= 0 ? cancelIndex : 0;\n let primaryAssigned = false;\n const views = buttons.map((button, index): ConfirmButtonView => {\n let variant: BfButtonVariant;\n if (button.role === 'cancel') {\n variant = 'outline';\n } else if (button.role === 'destructive') {\n variant = 'danger';\n } else if (!primaryAssigned) {\n variant = 'primary';\n primaryAssigned = true;\n } else {\n variant = 'tonal';\n }\n return {\n label: button.label,\n answer: button.id ?? button.label,\n variant,\n initial: index === initialIndex,\n };\n });\n const messageId = uniqueId('bf-confirm-message');\n const data: ConfirmData = {\n title: options.title,\n message: options.message,\n messageId,\n buttons: views,\n };\n const cancel = views[cancelIndex];\n const ref: BfDialogRef<string, BfConfirmDialogComponent> = this.openDialog(\n BfConfirmDialogComponent,\n {\n data,\n role: 'alertdialog',\n size: options.size ?? 'sm',\n ariaDescribedBy: options.message ? messageId : undefined,\n dismissOnBackdrop: false,\n closeOnNavigation: options.closeOnNavigation,\n injector,\n },\n {\n // Escape answers like the cancel button, or is claimed and ignored without one.\n onEscape: () => {\n if (cancel) {\n ref.close(cancel.answer);\n }\n },\n // A navigation always closes it: with the cancel answer, else with no answer.\n onNavigation: () => ref.close(cancel?.answer),\n },\n );\n return ref.afterClosed;\n }\n\n private openDialog<C, D, R>(\n content: Type<C> | TemplateRef<BfDialogTemplateContext<D, R>>,\n config: BfDialogConfig<D>,\n handlers: { onEscape?: () => void; onNavigation?: () => void },\n ): BfDialogRef<R, C> {\n const size = config.size ?? 'md';\n const role = config.role ?? 'dialog';\n const injector = config.injector ?? this.injector;\n // The shared counter, so an id never repeats one of a bf-dialog rendered in the page.\n const titleId = uniqueId('bf-dialog-title');\n let dialogRef: BfDialogRef<R, C> | null = null;\n let instance: C | null = null;\n\n const providers = (ref: BfOverlayRef<unknown>): StaticProvider[] => {\n const created = new BfDialogRef<R, C>(ref, () => instance);\n dialogRef = created;\n const list: StaticProvider[] = [\n { provide: BfDialogRef, useValue: created },\n { provide: BF_DIALOG_DATA, useValue: config.data },\n { provide: BF_DIALOG_CONTEXT, useValue: { titleId, size } },\n ];\n if (content instanceof TemplateRef) {\n const view: DialogTemplate = {\n template: content,\n context: { $implicit: created, data: config.data },\n };\n list.push({ provide: BF_DIALOG_TEMPLATE, useValue: view });\n }\n return list;\n };\n\n const options = {\n data: config.data,\n position: size === 'fullscreen' ? ('fullscreen' as const) : ('center' as const),\n role,\n ariaLabel: config.ariaLabel,\n ariaLabelledBy: config.ariaLabel ? undefined : titleId,\n ariaDescribedBy: config.ariaDescribedBy,\n dismissOnBackdrop: config.dismissOnBackdrop ?? role === 'dialog',\n dismissOnEscape: config.dismissOnEscape ?? true,\n onEscape: handlers.onEscape,\n closeOnNavigation: config.closeOnNavigation,\n onNavigation: handlers.onNavigation,\n autoFocus: config.autoFocus,\n restoreFocus: config.restoreFocus,\n panelClass: ['bf-dialog-panel', ...(config.panelClass ?? [])],\n injector,\n providers,\n enter: size === 'fullscreen' ? fadeIn : scaleIn,\n exit: fadeOut,\n };\n\n let overlayRef: BfComponentOverlayRef<unknown, R>;\n if (content instanceof TemplateRef) {\n overlayRef = this.overlays.open<BfDialogTemplateHostComponent, R>(\n BfDialogTemplateHostComponent,\n options,\n );\n } else {\n const componentRef = this.overlays.open<C, R>(content, options);\n instance = componentRef.componentRef.instance;\n overlayRef = componentRef;\n }\n if (!dialogRef) {\n throw new Error('BfDialogService: the overlay core did not build the dialog providers');\n }\n this.nameUnlabelledPanel(\n overlayRef.componentRef.location.nativeElement,\n overlayRef.afterClosed,\n config,\n injector,\n );\n return dialogRef;\n }\n\n /**\n * A dialog without an `ariaLabel` whose content rendered no `bf-dialog` title (the core then\n * drops the dangling `aria-labelledby`) is named by the first heading in its content, also one\n * that renders later, and by the `dialog` label until then.\n */\n private nameUnlabelledPanel(\n host: unknown,\n afterClosed: Promise<unknown>,\n config: BfDialogConfig<unknown>,\n injector: Injector,\n ): void {\n const panel =\n host instanceof HTMLElement ? host.closest<HTMLElement>('.bf-overlay-panel') : null;\n if (!panel || config.ariaLabel || panel.hasAttribute('aria-labelledby')) {\n return;\n }\n panel.setAttribute('aria-label', injector.get(BF_LABELS).dialog);\n const stop = watchPanelHeading(panel);\n void afterClosed.then(stop);\n }\n}\n","import { Component, input, output } from '@angular/core';\n\n/**\n * The card `BfDesktopToastService.show()` renders in its notification stack: the message and an\n * optional action button on a surface card. It is not a live region (the service announces each\n * toast once through CDK `LiveAnnouncer`) and has no close button; `Escape` with focus inside it\n * emits `escaped`, which dismisses the toast. Apps do not place it in templates.\n *\n * @example\n * const ref = inject(BfDesktopToastService).show({ message: 'Changes saved' });\n * @summary Desktop notification card in a bottom corner stack of up to three\n * @category Overlays\n * @since 0.3.0\n */\n@Component({\n selector: 'bf-desktop-toast',\n host: {\n class:\n 'bg-surface text-text border border-border rounded-card shadow-floating px-4 py-3 text-body ' +\n 'flex items-start gap-3 w-[min(24rem,calc(100vw-2*var(--spacing-gutter)))]',\n '(keydown)': 'keydown($event)',\n },\n template: `\n <span class=\"min-w-0 flex-1 wrap-anywhere\">{{ message() }}</span>\n @if (actionLabel()) {\n <button\n type=\"button\"\n class=\"text-primary-strong focus-visible:ring-ring rounded-tile -me-2 inline-flex min-h-6 shrink-0 cursor-pointer items-center px-2 font-bold hover:underline focus-visible:ring-4 focus-visible:outline-hidden\"\n (click)=\"actionClicked.emit()\"\n >\n {{ actionLabel() }}\n </button>\n }\n `,\n})\nexport class BfDesktopToastComponent {\n /** Text of the toast; long words wrap. */\n readonly message = input.required<string>();\n /** Text of the action button; empty renders no button. */\n readonly actionLabel = input('');\n /** The action button was clicked. */\n readonly actionClicked = output<void>();\n /** `Escape` was pressed with focus inside the toast (the key is claimed). */\n readonly escaped = output<void>();\n\n /** `Escape` inside the card is the toast's: claimed so no dialog underneath also closes. */\n protected keydown(event: Event): void {\n if (!(event instanceof KeyboardEvent) || event.key !== 'Escape') {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.escaped.emit();\n }\n}\n","import { LiveAnnouncer } from '@angular/cdk/a11y';\nimport { Directionality } from '@angular/cdk/bidi';\nimport {\n type OverlayRef,\n type PositionStrategy,\n createGlobalPositionStrategy,\n createNoopScrollStrategy,\n createOverlayRef,\n} from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n Component,\n type ComponentRef,\n DOCUMENT,\n DestroyRef,\n type EnvironmentProviders,\n InjectionToken,\n Injectable,\n Injector,\n inject,\n input,\n makeEnvironmentProviders,\n output,\n} from '@angular/core';\nimport { BF_LABELS } from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport { fadeOut, fadeUp } from '../core/overlay-animations';\nimport { BfOverlayStack } from '../core/overlay-stack.service';\nimport { type ɵBfToastHandle, ɵBfToastQueue, type ɵBfToastView } from '../toast-core/toast-queue';\nimport { type BfToastAction, type BfToastRef } from '../toast-core/toast-ref';\nimport { BfDesktopToastComponent } from './desktop-toast.component';\n\n/**\n * The viewport corner or edge the desktop toast stack anchors to.\n *\n * @summary The viewport corners and edges a desktop toast stack can anchor to\n * @since 0.3.0\n */\nexport type BfDesktopToastPosition = 'bottom-end' | 'bottom-center' | 'top-end' | 'top-center';\n\n/**\n * App-wide settings of `BfDesktopToastService`; set them with `provideBfDesktopToast()`.\n *\n * @summary App-wide settings of desktop toasts: where they sit and how many show at once\n * @since 0.3.0\n */\nexport interface BfDesktopToastConfig {\n /**\n * Where the stack sits (default `'bottom-end'`: bottom right, bottom left in RTL).\n * @default 'bottom-end'\n */\n position: BfDesktopToastPosition;\n /**\n * How many toasts are visible at once (default 3); later ones wait.\n * @default 3\n */\n maxVisible: number;\n /**\n * Name of the stack's region landmark; empty uses the `notifications` label (\"Notifications\").\n * @default ''\n */\n ariaLabel: string;\n}\n\n/**\n * The library defaults of `BfDesktopToastConfig`.\n *\n * @summary The library defaults of the desktop toast settings, bottom end with three visible\n * @since 0.3.0\n */\nexport const BF_DESKTOP_TOAST_DEFAULTS: Readonly<BfDesktopToastConfig> = Object.freeze({\n position: 'bottom-end',\n maxVisible: 3,\n ariaLabel: '',\n});\n\nconst BF_DESKTOP_TOAST_CONFIG = new InjectionToken<Readonly<BfDesktopToastConfig>>(\n 'BF_DESKTOP_TOAST_CONFIG',\n { providedIn: 'root', factory: () => BF_DESKTOP_TOAST_DEFAULTS },\n);\n\n/**\n * Sets where the desktop toast stack sits, how many toasts it shows at once and its region name,\n * merged over the defaults. Add it to `ApplicationConfig.providers`.\n *\n * @param config The settings to change; any left out keep `BF_DESKTOP_TOAST_DEFAULTS`.\n * @returns The providers of the desktop toast settings.\n * @summary Sets where desktop toasts appear and how many show at once, app-wide\n * @since 0.3.0\n */\nexport function provideBfDesktopToast(\n config: Partial<BfDesktopToastConfig> = {},\n): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: BF_DESKTOP_TOAST_CONFIG,\n useValue: Object.freeze({ ...BF_DESKTOP_TOAST_DEFAULTS, ...config }),\n },\n ]);\n}\n\n/**\n * Options of `BfDesktopToastService.show()`.\n *\n * @summary Options of one desktop toast: its message, an action and its duration\n * @since 0.3.0\n */\nexport interface BfDesktopToastOptions {\n /** Text of the toast. */\n message: string;\n /** An optional action button (the toast then persists by default). */\n action?: BfToastAction;\n /**\n * Milliseconds before the toast auto-dismisses, not counting time the pointer is over the\n * stack or focus is inside it; `0` keeps it until dismissed or its action fires (default 3000\n * without an action, `0` with one).\n * @default 3000\n */\n duration?: number;\n /**\n * Source of the region's labels when this toast opens the stack (default the root injector):\n * pass the feature's `inject(Injector)` so its `provideBfLabels()` names the region.\n */\n injector?: Injector;\n}\n\n/** One rendered toast of the stack. */\ninterface StackItem {\n readonly id: number;\n readonly view: ɵBfToastView;\n}\n\ntype HoldSource = 'pointer' | 'focus';\n\n/** The pane's content: the region landmark holding the visible toasts. */\n@Component({\n selector: 'bf-desktop-toast-stack',\n imports: [BfDesktopToastComponent],\n host: {\n role: 'region',\n '[attr.aria-label]': 'label()',\n class: 'flex flex-col gap-2',\n '(pointerenter)': \"held.emit({ source: 'pointer', held: true })\",\n '(pointerleave)': \"held.emit({ source: 'pointer', held: false })\",\n '(focusin)': \"held.emit({ source: 'focus', held: true })\",\n '(focusout)': 'focusLeft($event)',\n },\n template: `\n @for (item of items(); track item.id) {\n <bf-desktop-toast\n [attr.data-bf-toast]=\"item.id\"\n [message]=\"item.view.message\"\n [actionLabel]=\"item.view.action?.label ?? ''\"\n (actionClicked)=\"item.view.action?.run()\"\n (escaped)=\"item.view.escape()\"\n />\n }\n `,\n})\nclass BfDesktopToastStackComponent {\n readonly label = input('');\n /** In DOM (and visual) order: the newest sits nearest the anchored edge. */\n readonly items = input<readonly StackItem[]>([]);\n readonly held = output<{ source: HoldSource; held: boolean }>();\n\n protected focusLeft(event: FocusEvent): void {\n const to = event.relatedTarget;\n const self = event.currentTarget;\n if (to instanceof Node && self instanceof Node && self.contains(to)) {\n return;\n }\n this.held.emit({ source: 'focus', held: false });\n }\n}\n\n/** The stack's inset from the viewport edges: 24 px plus the safe area (the end edge is the\n * physical left in a right-to-left page). */\nconst INSET = {\n top: 'calc(24px + var(--spacing-safe-top, 0px))',\n bottom: 'calc(24px + var(--spacing-safe-bottom, 0px))',\n endLtr: 'calc(24px + var(--spacing-safe-right, 0px))',\n endRtl: 'calc(24px + var(--spacing-safe-left, 0px))',\n};\n\n/**\n * Shows desktop notifications: `show(options)` adds a `bf-desktop-toast` card to one passive\n * overlay stack (bottom right by default, 24 px in, a `region` landmark named \"Notifications\")\n * and returns a `BfToastRef`. Up to three are visible at once, the newest nearest the anchored\n * edge; later calls wait and show as earlier ones end. A toast auto-dismisses after `duration` ms\n * (default 3000, `'timeout'`); one with an action persists by default until its action\n * (`'action'`), `Escape` inside it or `dismiss()` (`'dismiss'`), and the next `show()` replaces it\n * (`'dismiss'`), visible or waiting. The pointer over the stack or focus inside it pauses every\n * visible toast, which resume with their remaining time. Each toast is announced once, politely,\n * through CDK `LiveAnnouncer`; focus never moves on show, and returns to the element focused\n * last outside a toast that closes while holding it. `F6` from the page moves focus to the\n * action of the newest toast that has one, and `F6` inside the stack moves it back (otherwise\n * the key is left to the browser); it does nothing while a modal overlay is open\n * (`BfOverlayStack.count() > 0`), since that overlay's focus trap must not be escaped. No\n * backdrop, no scroll lock, nothing inert, and a navigation never closes it (a \"Saved\" survives\n * the navigation after the save). Needs `@angular/cdk`, no Capacitor.\n *\n * @example\n * const ref = inject(BfDesktopToastService).show({\n * message: 'Invoice deleted',\n * action: { label: 'Undo', handler: () => restore(invoice) },\n * });\n * const reason = await ref.afterDismissed;\n * @since 0.3.0\n * @summary Shows brief desktop notifications in a stack at a corner of the viewport\n */\n@Injectable({ providedIn: 'root' })\nexport class BfDesktopToastService {\n private readonly injector = inject(Injector);\n private readonly document = inject(DOCUMENT);\n private readonly config = inject(BF_DESKTOP_TOAST_CONFIG);\n private readonly directionality = inject(Directionality);\n private readonly overlayStack = inject(BfOverlayStack);\n /** Where the last `F6` into the stack came from; the next `F6` inside it goes back there. */\n private f6ReturnTo: HTMLElement | null = null;\n private readonly onKeydown = (event: KeyboardEvent): void => this.keydown(event);\n /** Shown toasts, oldest first (a leaving one stays until its exit has played). */\n private items: readonly StackItem[] = [];\n /** What holds the stack now; applied to every toast, also one that shows while held. */\n private readonly holds = new Set<HoldSource>();\n private pane: {\n overlayRef: OverlayRef;\n stack: ComponentRef<BfDesktopToastStackComponent>;\n } | null = null;\n /** Re-applies the position strategy on a `dir` change while the pane lives (N2). */\n private dirSubscription: Subscription | null = null;\n private nextId = 0;\n private readonly queue = new ɵBfToastQueue<BfDesktopToastOptions>(\n { present: (view, options) => this.present(view, options) },\n {\n maxVisible: Math.max(1, Math.floor(this.config.maxVisible)),\n announcer: inject(LiveAnnouncer),\n document: this.document,\n destroyRef: inject(DestroyRef),\n },\n );\n\n constructor() {\n // After the queue's own teardown (registered first) has ended every toast.\n inject(DestroyRef).onDestroy(() => this.disposePane());\n }\n\n /**\n * Queues `options` as a toast; shows it now while fewer than `maxVisible` are visible, else once\n * one ends. Every persistent toast (`duration` 0, the default with an action), visible or\n * waiting, is dismissed first (`'dismiss'`).\n * @param options The toast's message, action, duration and injector.\n * @returns The toast's ref, to dismiss it or await why it ended.\n */\n show(options: BfDesktopToastOptions): BfToastRef {\n return this.queue.show(options);\n }\n\n private present(view: ɵBfToastView, options: BfDesktopToastOptions): ɵBfToastHandle {\n const pane = this.ensurePane(options.injector ?? this.injector);\n const item: StackItem = { id: this.nextId++, view };\n this.items = [...this.items, item];\n this.render();\n for (const source of this.holds) {\n view.hold(source, true);\n }\n const host = pane.overlayRef.overlayElement.querySelector<HTMLElement>(\n `[data-bf-toast=\"${item.id}\"]`,\n );\n if (host) {\n // Fade in while sliding 8 px in from the anchored edge; reduced motion: fade only.\n fadeUp(host, this.anchoredTop() ? '-8px' : '8px');\n }\n return {\n host,\n close: async () => {\n if (host) {\n try {\n await fadeOut(host).finished;\n } catch {\n // A cancelled exit still removes the toast.\n }\n }\n this.remove(item);\n },\n };\n }\n\n private remove(item: StackItem): void {\n if (!this.pane) {\n return;\n }\n this.items = this.items.filter((i) => i !== item);\n if (this.items.length === 0) {\n this.disposePane();\n return;\n }\n this.render();\n // A removed card fires no focusout: release a focus hold that no card holds any more.\n if (\n this.holds.has('focus') &&\n !this.pane.overlayRef.overlayElement.contains(this.document.activeElement)\n ) {\n this.setHold('focus', false);\n }\n }\n\n private render(): void {\n const pane = this.pane;\n if (!pane) {\n return;\n }\n // Newest nearest the anchored edge: last in a bottom stack, first in a top one.\n pane.stack.setInput('items', this.anchoredTop() ? [...this.items].reverse() : this.items);\n pane.stack.changeDetectorRef.detectChanges();\n }\n\n private setHold(source: HoldSource, held: boolean): void {\n if (held === this.holds.has(source)) {\n return;\n }\n if (held) {\n this.holds.add(source);\n } else {\n this.holds.delete(source);\n }\n for (const item of this.items) {\n item.view.hold(source, held);\n }\n }\n\n private ensurePane(injector: Injector): NonNullable<BfDesktopToastService['pane']> {\n if (this.pane) {\n return this.pane;\n }\n const overlayRef = createOverlayRef(this.injector, {\n positionStrategy: this.positionStrategy(),\n // A toast never locks scroll, traps focus or blocks the page.\n scrollStrategy: createNoopScrollStrategy(),\n hasBackdrop: false,\n panelClass: 'bf-desktop-toast-pane',\n });\n const stack = overlayRef.attach(\n new ComponentPortal(BfDesktopToastStackComponent, null, injector),\n );\n stack.setInput('label', this.config.ariaLabel || injector.get(BF_LABELS).notifications);\n stack.instance.held.subscribe(({ source, held }) => this.setHold(source, held));\n // Place the pane now, not on the next render, so the first toast enters at its corner.\n overlayRef.updatePosition();\n this.document.addEventListener('keydown', this.onKeydown);\n // A `dir` change while the pane lives moves the anchored end to the new physical side: the\n // overlay's own direction (which GlobalPositionStrategy.apply() reads to pick left vs right)\n // is a one-time snapshot from creation, so it is updated explicitly before reapplying.\n this.dirSubscription = this.directionality.change.subscribe((dir) => {\n overlayRef.setDirection(dir);\n overlayRef.updatePositionStrategy(this.positionStrategy());\n });\n this.pane = { overlayRef, stack };\n return this.pane;\n }\n\n private disposePane(): void {\n if (this.pane) {\n this.document.removeEventListener('keydown', this.onKeydown);\n }\n this.dirSubscription?.unsubscribe();\n this.dirSubscription = null;\n this.pane?.overlayRef.dispose();\n this.pane = null;\n this.items = [];\n this.holds.clear();\n this.f6ReturnTo = null;\n }\n\n /**\n * `F6` (no Ctrl, Alt or Meta) from the page moves focus to the action of the newest toast that\n * has one; `F6` inside the stack moves it back to where it came from. Never moves focus out of\n * an open modal overlay (`BfOverlayStack.count() > 0`): that overlay's focus trap is APG-modal\n * (focus never leaves it), so a toast surfacing behind it stays reachable only by pointer while\n * it is open. Otherwise the key is left to the browser.\n */\n private keydown(event: KeyboardEvent): void {\n const pane = this.pane;\n if (!pane || event.key !== 'F6' || event.ctrlKey || event.altKey || event.metaKey) {\n return;\n }\n const active = this.document.activeElement;\n if (active instanceof Node && pane.overlayRef.overlayElement.contains(active)) {\n const back = this.f6ReturnTo;\n if (back?.isConnected) {\n event.preventDefault();\n this.f6ReturnTo = null;\n back.focus();\n }\n return;\n }\n if (this.overlayStack.count() > 0) {\n return;\n }\n const newest = [...this.items].reverse().find((item) => item.view.action);\n const button = newest\n ? pane.overlayRef.overlayElement.querySelector<HTMLElement>(\n `[data-bf-toast=\"${newest.id}\"] button`,\n )\n : null;\n if (!button) {\n return;\n }\n event.preventDefault();\n this.f6ReturnTo =\n active instanceof HTMLElement && active !== this.document.body ? active : null;\n button.focus();\n }\n\n private anchoredTop(): boolean {\n return this.config.position.startsWith('top');\n }\n\n private positionStrategy(): PositionStrategy {\n const global = createGlobalPositionStrategy(this.injector);\n const vertical = this.anchoredTop() ? global.top(INSET.top) : global.bottom(INSET.bottom);\n return this.config.position.endsWith('center')\n ? vertical.centerHorizontally()\n : vertical.end(this.directionality.value === 'rtl' ? INSET.endRtl : INSET.endLtr);\n }\n}\n","import { type OverlayRef } from '@angular/cdk/overlay';\nimport { prefersReducedMotion } from './motion';\nimport { animateOrSettle } from './overlay-animations';\n\n/**\n * Open and close motion of the panels anchored to an element: the popover, the menu, the styled\n * select, the comboboxes and the date and time pickers. The panel grows out of its anchor: it\n * fades in while it scales from 96 % and moves 4 px away from the anchor, with its transform\n * origin on the anchor's corner. It leaves the same way, a little faster. Under\n * `prefers-reduced-motion` it only fades. Internal to the overlay entry.\n */\n\n/** The enter (ms). */\nexport const ANCHORED_ENTER_DURATION = 180;\n/** The exit (ms): a little faster than the enter, so a closing panel never holds things up. */\nexport const ANCHORED_EXIT_DURATION = 130;\n/** The enter's curve: a quick start that settles softly (ease-out). */\nexport const ANCHORED_ENTER_EASING = 'cubic-bezier(0.16, 1, 0.3, 1)';\n/** The exit's curve: accelerates away (ease-in). */\nexport const ANCHORED_EXIT_EASING = 'cubic-bezier(0.4, 0, 1, 1)';\n/** The scale a panel grows from and shrinks to. */\nexport const ANCHORED_SCALE = 0.96;\n/** How far (px) a panel starts towards its anchor and moves out from it. */\nexport const ANCHORED_OFFSET = 4;\n\n/** The resting frame every enter ends on and every exit starts from. */\nconst OPEN: Keyframe = { opacity: 1, transform: 'none' };\n\n/**\n * The hidden frame of `panel` against `anchor`: below the anchor it starts a little higher (it\n * comes out of the anchor's bottom edge), above it a little lower, beside it (a submenu) a little\n * towards the anchor. The transform origin goes on the anchor's corner of the panel. Read from\n * the laid-out boxes, so it follows a placement the overlay flipped at runtime and the text\n * direction. Only an opacity frame under reduced motion.\n */\nfunction hiddenFrame(panel: HTMLElement, anchor: HTMLElement): Keyframe {\n if (prefersReducedMotion(panel.ownerDocument.defaultView)) {\n return { opacity: 0 };\n }\n const p = panel.getBoundingClientRect();\n const a = anchor.getBoundingClientRect();\n let x = 0;\n let y = 0;\n let originX: 'left' | 'right' | null = null;\n let originY: 'top' | 'bottom' = 'top';\n if (p.top >= a.bottom - 1) {\n y = -ANCHORED_OFFSET;\n } else if (p.bottom <= a.top + 1) {\n y = ANCHORED_OFFSET;\n originY = 'bottom';\n } else if (p.left >= a.right - 1) {\n x = -ANCHORED_OFFSET;\n originX = 'left';\n } else {\n x = ANCHORED_OFFSET;\n originX = 'right';\n }\n // Above or below: the corner on the edge the panel is aligned to.\n originX ??= Math.abs(p.left - a.left) <= Math.abs(p.right - a.right) ? 'left' : 'right';\n panel.style.transformOrigin = `${originX} ${originY}`;\n return {\n opacity: 0,\n transform: `translate3d(${x}px, ${y}px, 0) scale(${ANCHORED_SCALE})`,\n };\n}\n\n/**\n * Plays the enter of `panel`, which must already be in place against `anchor`. The first frame\n * holds until the animation starts, so the panel never shows at full size first.\n * @param panel The element to animate (the overlay pane, or the menu inside the CDK's pane).\n * @param anchor The element the panel opens from.\n */\nexport function animateAnchoredIn(panel: HTMLElement, anchor: HTMLElement): Animation {\n return animateOrSettle(panel, [hiddenFrame(panel, anchor), OPEN], {\n duration: ANCHORED_ENTER_DURATION,\n easing: ANCHORED_ENTER_EASING,\n fill: 'backwards',\n });\n}\n\n/**\n * Plays the exit of `panel` and holds its last frame. It starts from wherever the panel is, so a\n * close during the enter turns back smoothly.\n * @param panel The element to animate.\n * @param anchor The element the panel opened from.\n */\nexport function animateAnchoredOut(panel: HTMLElement, anchor: HTMLElement): Animation {\n return animateOrSettle(panel, [hiddenFrame(panel, anchor)], {\n duration: ANCHORED_EXIT_DURATION,\n easing: ANCHORED_EXIT_EASING,\n fill: 'forwards',\n });\n}\n\n/** What `AnchoredMotion` needs of the attached content: render it now, or freeze it. */\nexport interface AnchoredView {\n detectChanges(): void;\n detach(): void;\n}\n\n/**\n * The enter and exit of one owner's anchored overlay (a popover trigger, a combobox, a picker).\n * A closing overlay stays attached, inert and transparent to the pointer, until its exit has\n * played, and is disposed then. Opening again while it still leaves disposes it at once, so\n * there is never a second panel and never a leaked overlay. Where the Web Animations API is\n * missing or stubbed (jsdom) the overlay is disposed at once, as before.\n */\nexport class AnchoredMotion {\n private leaving: { ref: OverlayRef; animation: Animation } | null = null;\n\n /**\n * Renders the freshly attached content (so the pane has its size), positions the overlay and\n * plays the enter.\n * @param ref The overlay, attached.\n * @param anchor The element it is anchored to.\n * @param view The attached content, rendered before the pane is measured.\n */\n enter(ref: OverlayRef, anchor: HTMLElement, view?: AnchoredView): void {\n view?.detectChanges();\n ref.updatePosition();\n animateAnchoredIn(ref.overlayElement, anchor);\n }\n\n /**\n * Plays the exit of `ref` and disposes it once done. The owner has already dropped its\n * listeners, so the overlay takes no keys and no outside clicks while it leaves.\n * @param ref The overlay to close.\n * @param anchor The element it is anchored to.\n * @param freeze Content to stop rendering while it leaves (a list that would reflow).\n */\n leave(ref: OverlayRef, anchor: HTMLElement, freeze?: AnchoredView): void {\n this.flush();\n const pane = ref.overlayElement;\n pane.setAttribute('inert', '');\n pane.style.pointerEvents = 'none';\n freeze?.detach();\n const animation = animateAnchoredOut(pane, anchor);\n // Nothing to wait for: finished already (no Web Animations API), or a stand-in without an\n // effect (the jsdom shim of `@bitforgehq/ui/testing`), so unit tests see the panel go at once.\n if (animation.playState === 'finished' || animation.effect === null) {\n ref.dispose();\n return;\n }\n const entry = { ref, animation };\n this.leaving = entry;\n const done = (): void => {\n if (this.leaving === entry) {\n this.leaving = null;\n ref.dispose();\n }\n };\n animation.finished.then(done, done);\n }\n\n /** Disposes a leaving overlay now (before opening again, or when the owner is destroyed). */\n flush(): void {\n const entry = this.leaving;\n if (entry) {\n this.leaving = null;\n entry.animation.cancel();\n entry.ref.dispose();\n }\n }\n\n /** Whether an overlay is still playing its exit. */\n isLeaving(): boolean {\n return this.leaving !== null;\n }\n}\n","import { type Direction } from '@angular/cdk/bidi';\nimport {\n type ConnectedPosition,\n type OverlayRef,\n createFlexibleConnectedPositionStrategy,\n createOverlayRef,\n createRepositionScrollStrategy,\n} from '@angular/cdk/overlay';\nimport { type Injector } from '@angular/core';\n\n/**\n * Connected positioning shared by every panel anchored to an element: the menu, the popover (and\n * the inputs built on it) and the tooltip. One place decides the gap, the flip order and the\n * overlay config, so all anchored panels move and flip alike. Internal to the overlay entry.\n */\n\n/** Where a panel opens below or above its anchor, aligned to its inline start or end. */\nexport type AnchoredBlockPlacement = 'below-start' | 'below-end' | 'above-start' | 'above-end';\n\n/** Which side of its anchor a small label (a tooltip) sits on; `start`/`end` are logical. */\nexport type AnchoredSidePlacement = 'top' | 'bottom' | 'start' | 'end';\n\n/** Space between a panel and its anchor (px). */\nexport const ANCHOR_GAP = 4;\n/** Space between a tooltip and its anchor (px): a little more, so the pill never touches it. */\nexport const TOOLTIP_GAP = 8;\n/** The smallest distance a panel keeps from the viewport edges (px). */\nexport const VIEWPORT_MARGIN = 8;\n\nconst BELOW_START: ConnectedPosition = {\n originX: 'start',\n originY: 'bottom',\n overlayX: 'start',\n overlayY: 'top',\n offsetY: ANCHOR_GAP,\n};\nconst BELOW_END: ConnectedPosition = {\n originX: 'end',\n originY: 'bottom',\n overlayX: 'end',\n overlayY: 'top',\n offsetY: ANCHOR_GAP,\n};\nconst ABOVE_START: ConnectedPosition = {\n originX: 'start',\n originY: 'top',\n overlayX: 'start',\n overlayY: 'bottom',\n offsetY: -ANCHOR_GAP,\n};\nconst ABOVE_END: ConnectedPosition = {\n originX: 'end',\n originY: 'top',\n overlayX: 'end',\n overlayY: 'bottom',\n offsetY: -ANCHOR_GAP,\n};\n\n/* The preferred position first, then the vertical flip, then the other alignment (and its flip)\n when the panel would overflow the viewport. */\nconst BLOCK_POSITIONS: Record<AnchoredBlockPlacement, readonly ConnectedPosition[]> = {\n 'below-start': [BELOW_START, ABOVE_START, BELOW_END, ABOVE_END],\n 'below-end': [BELOW_END, ABOVE_END, BELOW_START, ABOVE_START],\n 'above-start': [ABOVE_START, BELOW_START, ABOVE_END, BELOW_END],\n 'above-end': [ABOVE_END, BELOW_END, ABOVE_START, BELOW_START],\n};\n\nconst TOP: ConnectedPosition = {\n originX: 'center',\n originY: 'top',\n overlayX: 'center',\n overlayY: 'bottom',\n offsetY: -TOOLTIP_GAP,\n};\nconst BOTTOM: ConnectedPosition = {\n originX: 'center',\n originY: 'bottom',\n overlayX: 'center',\n overlayY: 'top',\n offsetY: TOOLTIP_GAP,\n};\n/* `start`/`end` are logical: the CDK mirrors them under a right-to-left direction. The offset is\n physical, so it is mirrored with them by `sidePositions`. */\nconst START: ConnectedPosition = {\n originX: 'start',\n originY: 'center',\n overlayX: 'end',\n overlayY: 'center',\n offsetX: -TOOLTIP_GAP,\n};\nconst END: ConnectedPosition = {\n originX: 'end',\n originY: 'center',\n overlayX: 'start',\n overlayY: 'center',\n offsetX: TOOLTIP_GAP,\n};\n\n/* The preferred side, then the opposite side, then the two others. */\nconst SIDE_POSITIONS: Record<AnchoredSidePlacement, readonly ConnectedPosition[]> = {\n top: [TOP, BOTTOM, END, START],\n bottom: [BOTTOM, TOP, END, START],\n start: [START, END, TOP, BOTTOM],\n end: [END, START, TOP, BOTTOM],\n};\n\n/** The CDK positions of a block placement, with the flips to try when it overflows. */\nexport function blockPositions(placement: AnchoredBlockPlacement): ConnectedPosition[] {\n return [...BLOCK_POSITIONS[placement]];\n}\n\n/**\n * The CDK positions of a side placement, with the flips to try when it overflows. Under `rtl`\n * the horizontal offsets change sign, because the CDK mirrors the logical `start`/`end` but not\n * the pixel offset.\n */\nexport function sidePositions(\n placement: AnchoredSidePlacement,\n direction: Direction = 'ltr',\n): ConnectedPosition[] {\n return SIDE_POSITIONS[placement].map((position) =>\n direction === 'rtl' && position.offsetX\n ? { ...position, offsetX: -position.offsetX }\n : position,\n );\n}\n\n/** What `createAnchoredOverlay` needs besides the anchor. */\nexport interface AnchoredOverlayOptions {\n /** The positions to try, in order. */\n positions: ConnectedPosition[];\n /** The text direction the logical positions follow. */\n direction: Direction;\n /** Classes on the overlay pane. */\n panelClass: string[];\n}\n\n/** An anchored overlay and the way to move it to other positions while it is open. */\nexport interface AnchoredOverlay {\n /** The CDK overlay. */\n ref: OverlayRef;\n /** Swaps the positions to try (a placement input that changed while open) and re-applies them. */\n setPositions(positions: ConnectedPosition[]): void;\n}\n\n/**\n * Creates an overlay connected to `anchor`: it flips through `positions` when one would overflow,\n * keeps `VIEWPORT_MARGIN` from the edges, never pushes the panel over its anchor and repositions\n * as the page scrolls. No backdrop: anchored panels are non-modal. Built from the CDK's standalone\n * factories rather than the `Overlay` service, which would pull every scroll and position strategy\n * into an app's bundle. `injector` is the caller's `EnvironmentInjector`, as the service's is.\n */\nexport function createAnchoredOverlay(\n injector: Injector,\n anchor: HTMLElement,\n options: AnchoredOverlayOptions,\n): AnchoredOverlay {\n const strategy = createFlexibleConnectedPositionStrategy(injector, anchor)\n .withPositions(options.positions)\n .withFlexibleDimensions(false)\n .withPush(false)\n .withViewportMargin(VIEWPORT_MARGIN);\n const ref = createOverlayRef(injector, {\n positionStrategy: strategy,\n scrollStrategy: createRepositionScrollStrategy(injector),\n direction: options.direction,\n hasBackdrop: false,\n panelClass: options.panelClass,\n });\n return {\n ref,\n setPositions: (positions) => {\n strategy.withPositions(positions);\n ref.updatePosition();\n },\n };\n}\n","import { type ConnectedPosition } from '@angular/cdk/overlay';\nimport { Location } from '@angular/common';\nimport { CDK_MENU, CdkMenuTrigger } from '@angular/cdk/menu';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n SimpleChange,\n effect,\n inject,\n input,\n} from '@angular/core';\nimport { ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { blockPositions } from '../core/anchored-overlay';\nimport { watchPathChange } from '../core/navigation';\n\n/**\n * Where a menu opens against its trigger; `start`/`end` follow the text direction.\n *\n * @summary Where a menu opens against its trigger, above or below, at either end\n * @since 0.3.0\n */\nexport type BfMenuPlacement = 'below-start' | 'below-end' | 'above-start' | 'above-end';\n\n/**\n * Opens a `bf-menu` template from any element on the Angular CDK menu trigger: it sets\n * `aria-haspopup=\"menu\"` and `aria-expanded`, opens on click, `Enter`, `Space` and `ArrowDown`\n * (first item focused) or `ArrowUp` (last item), and takes focus back when the menu closes. A\n * navigation to another URL path closes the open menu (with its submenus); the URL is watched\n * only while the menu is open. On a\n * `bfMenuItem` it opens a submenu beside the item instead (`ArrowRight`, `ArrowLeft` in RTL).\n * `bf-menu-button` wraps it in a styled button.\n *\n * @example\n * <button type=\"button\" [bfMenuTriggerFor]=\"menu\" bfMenuPlacement=\"below-end\">Options</button>\n * <ng-template #menu><bf-menu>…</bf-menu></ng-template>\n * @binding bfMenuTriggerFor The `ng-template` holding the `bf-menu` this element opens.\n * @binding bfMenuTriggerData The context the menu template receives, for a menu shared by many triggers.\n * @binding bfMenuOpened Emits when the menu opens.\n * @binding bfMenuClosed Emits when the menu closes (an item, `Escape`, a click outside or a navigation).\n * @summary Opens a menu from any element with the keyboard and focus rules of menus\n * @since 0.3.0\n */\n@Directive({\n selector: '[bfMenuTriggerFor]',\n hostDirectives: [\n {\n directive: CdkMenuTrigger,\n inputs: ['cdkMenuTriggerFor: bfMenuTriggerFor', 'cdkMenuTriggerData: bfMenuTriggerData'],\n outputs: ['cdkMenuOpened: bfMenuOpened', 'cdkMenuClosed: bfMenuClosed'],\n },\n ],\n})\nexport class BfMenuTriggerDirective {\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /** Where the menu opens (flipping when it would overflow). A submenu always opens beside its\n * item, at the inline end, and ignores it. */\n readonly bfMenuPlacement = input<BfMenuPlacement>('below-start');\n\n constructor() {\n const trigger = inject(CdkMenuTrigger, { self: true });\n const isSubmenu = inject(CDK_MENU, { optional: true }) !== null;\n if (isSubmenu) {\n return;\n }\n // The page the menu acts on is gone: close it, as every non-passive overlay. Watched only\n // while the menu is open, so a table of row-action menus holds no listeners at rest.\n const location = inject(Location);\n let stop: (() => void) | null = null;\n const unwatch = (): void => {\n stop?.();\n stop = null;\n };\n const opened = trigger.opened.subscribe(() => {\n unwatch();\n stop = watchPathChange(location, () => {\n if (trigger.isOpen()) {\n trigger.close();\n }\n });\n });\n const closed = trigger.closed.subscribe(unwatch);\n inject(DestroyRef).onDestroy(() => {\n opened.unsubscribe();\n closed.unsubscribe();\n unwatch();\n });\n let previous: ConnectedPosition[] | undefined;\n effect(() => {\n const positions = blockPositions(this.bfMenuPlacement());\n // effect-justified: CdkMenuTrigger is this directive's own host directive; placement to positions needs a transform no host-directive input mapping does\n trigger.menuPosition = positions;\n if (previous) {\n // Re-applies the position strategy of an overlay created with the old placement.\n // effect-justified: the CDK re-reads menuPosition only in its own ngOnChanges\n trigger.ngOnChanges({ menuPosition: new SimpleChange(previous, positions, false) });\n }\n previous = positions;\n });\n }\n\n /**\n * The trigger element, which the opening menu grows out of.\n * @internal\n */\n anchorElement(): HTMLElement {\n return this.el;\n }\n\n /** The trigger element's id (assigned when it has none), which names the menu it opens. It is\n * read when the menu opens: an `[id]` bound on the trigger that changes while the menu is open\n * names the menu from its next opening. */\n labelId(): string {\n if (!this.el.id) {\n this.el.id = uniqueId('bf-menu-trigger');\n }\n return this.el.id;\n }\n}\n","import { CdkMenu, CdkTargetMenuAim } from '@angular/cdk/menu';\nimport { Component, ElementRef, afterNextRender, computed, inject, input } from '@angular/core';\nimport { BF_DEFAULTS, type BfSize } from '@bitforgehq/ui';\nimport { animateAnchoredIn } from '../core/anchored-motion';\nimport { BfMenuTriggerDirective } from './menu-trigger.directive';\n\n/**\n * Menu panel of actions, choices and submenus on the Angular CDK menu (role `menu`, arrow keys,\n * Home/End, type-ahead, `Escape` returning focus to the trigger). Put it in an `ng-template` that\n * a `bf-menu-button` or a `[bfMenuTriggerFor]` opens, and fill it with `bfMenuItem`,\n * `bfMenuItemCheckbox`, `bfMenuItemRadio` (in a `bfMenuGroup`) and `bfMenuDivider` parts.\n *\n * @example\n * <bf-menu-button [menu]=\"rowActions\">Actions</bf-menu-button>\n * <ng-template #rowActions>\n * <bf-menu>\n * <button bfMenuItem (triggered)=\"rename()\">Rename</button>\n * <button bfMenuItem [bfMenuTriggerFor]=\"moveTo\">Move to</button>\n * <div bfMenuDivider></div>\n * <button bfMenuItem (triggered)=\"remove()\">Delete</button>\n * </bf-menu>\n * </ng-template>\n * @summary Keyboard-operable menu panel with items, checkbox and radio items, groups and submenus\n * @category Overlays\n * @since 0.3.0\n * @slot default The items (`bfMenuItem`, `bfMenuItemCheckbox`, `bfMenuItemRadio`), groups and dividers.\n */\n@Component({\n selector: 'bf-menu',\n // CdkTargetMenuAim keeps an open submenu while the pointer moves diagonally towards it.\n hostDirectives: [CdkMenu, CdkTargetMenuAim],\n host: {\n // Scrolls past 24 rem or the viewport minus 1 rem each side; p-1 keeps the rounded item\n // highlight inside the card's corners.\n class:\n 'flex flex-col bg-surface text-text border border-border rounded-card shadow-floating p-1 min-w-48 ' +\n 'max-h-[min(24rem,calc(100dvh-2rem))] overflow-y-auto overscroll-contain',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'labelledBy()',\n },\n template: '<ng-content />',\n})\nexport class BfMenuComponent {\n private readonly defaults = inject(BF_DEFAULTS);\n /** The `bfMenuTriggerFor` that opened this menu (a button, or the parent item of a submenu). */\n private readonly trigger = inject(BfMenuTriggerDirective, { optional: true });\n\n /** Row height of its items: sm 32, md 36, lg 44 px (44 px under a coarse pointer); unset follows\n * `provideBfDefaults()` (`controlSize`, `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Accessible name of the menu. Empty: the menu is named by the trigger that opened it (APG). */\n readonly ariaLabel = input('');\n /** Id of the element that names the menu; wins over the trigger. */\n readonly ariaLabelledby = input('');\n\n /** The item height in effect: `size`, else the app's `controlSize` default. */\n readonly resolvedSize = computed(() => this.size() ?? this.defaults.controlSize);\n\n private readonly triggerId = this.trigger?.labelId() ?? null;\n protected readonly labelledBy = computed(\n () => this.ariaLabelledby() || (this.ariaLabel() ? null : this.triggerId),\n );\n\n constructor() {\n const trigger = this.trigger;\n if (!trigger) {\n return;\n }\n const host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n // Grows out of its trigger once the CDK has placed it: the CDK positions the overlay after the\n // first render (mixed read-write phase), so the read phase sees the final place. Enter only:\n // the CDK detaches a closing menu at once, so there is nothing left to animate out.\n afterNextRender({ read: () => animateAnchoredIn(host, trigger.anchorElement()) });\n }\n}\n","import {\n CdkMenuGroup,\n CdkMenuItem,\n CdkMenuItemCheckbox,\n CdkMenuItemRadio,\n} from '@angular/cdk/menu';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n computed,\n effect,\n inject,\n model,\n output,\n} from '@angular/core';\nimport { BF_DEFAULTS, type BfSize } from '@bitforgehq/ui';\nimport { BfMenuComponent } from './menu.component';\n\n/* One row of a menu. Focus (keyboard or programmatic) and hover share the muted fill; keyboard\n focus adds the ring. Under forced colours the focused row opts out of the adjustment and its\n Highlight fill is the focus indicator (the transparent `focus:outline-hidden` outline stays\n transparent there). A focused disabled row keeps GrayText on Canvas with a Highlight outline\n instead, so it stays legible and reads as disabled. A disabled row stays focusable (APG) but\n gets no hover fill. */\nconst ITEM =\n 'relative flex w-full items-center gap-3 px-3 text-text text-start rounded-field cursor-pointer select-none ' +\n 'focus:outline-hidden no-underline! focus:bg-surface-muted not-aria-disabled:hover:bg-surface-muted ' +\n 'focus-visible:ring-4 focus-visible:ring-ring focus-visible:ring-inset ' +\n 'aria-disabled:text-text-disabled aria-disabled:cursor-not-allowed ' +\n 'forced-colors:aria-disabled:text-[GrayText] forced-colors:focus:forced-color-adjust-none ' +\n 'forced-colors:focus:bg-[Highlight] forced-colors:focus:text-[HighlightText] ' +\n 'forced-colors:focus:aria-disabled:bg-[Canvas] forced-colors:focus:aria-disabled:text-[GrayText] ' +\n 'forced-colors:focus:aria-disabled:outline-2 forced-colors:focus:aria-disabled:-outline-offset-2 ' +\n 'forced-colors:focus:aria-disabled:outline-[Highlight]';\n\n/* Row heights 32/36/44 px. The row projects its label, so the touch size is a min-height under a\n coarse pointer (never an ::after extension), as bf-checkbox rows. */\nconst SIZE: Record<BfSize, string> = {\n sm: 'min-h-8 py-1 text-label-sm pointer-coarse:min-h-hit',\n md: 'min-h-9 py-1.5 text-body pointer-coarse:min-h-hit',\n lg: 'min-h-11 py-2 text-body',\n};\n\n/* A row that opens a submenu shows a chevron at the inline end, pointing there (mirrored under\n dir=\"rtl\"). Drawn with borders in currentColor, so forced colours keep it and it adds nothing\n to the accessible name. */\nconst SUBMENU_CHEVRON =\n \"aria-[haspopup=menu]:after:ms-auto aria-[haspopup=menu]:after:size-2 aria-[haspopup=menu]:after:shrink-0 aria-[haspopup=menu]:after:-translate-x-0.5 aria-[haspopup=menu]:after:rotate-45 rtl:aria-[haspopup=menu]:after:translate-x-0.5 rtl:aria-[haspopup=menu]:after:-rotate-135 aria-[haspopup=menu]:after:border-t-[1.5px] aria-[haspopup=menu]:after:border-r-[1.5px] aria-[haspopup=menu]:after:border-current aria-[haspopup=menu]:after:content-['']\";\n\n/* The 16 px indicator slot before the label: a check mark or a dot, drawn with borders in\n currentColor (visible under forced colours, nothing added to the name). Unchecked rows keep the\n slot with no border at all (forced colours would paint even a transparent one), so labels line\n up. The check is not mirrored in RTL. */\nconst CHECK =\n \"before:mx-[5px] before:h-[11px] before:w-[6px] before:shrink-0 before:-translate-y-px before:rotate-45 before:border-current aria-checked:before:border-r-2 aria-checked:before:border-b-2 before:content-['']\";\nconst DOT =\n \"before:mx-1 before:size-2 before:shrink-0 before:rounded-full before:border-current aria-checked:before:border-4 before:content-['']\";\n\ntype BfMenuItemKind = 'item' | 'checkbox' | 'radio';\nconst INDICATOR: Record<BfMenuItemKind, string> = { item: '', checkbox: CHECK, radio: DOT };\n\n/** The item's classes for the size of its menu (or the app default outside a `bf-menu`). */\nfunction itemClasses(kind: BfMenuItemKind): () => string {\n const menu = inject(BfMenuComponent, { optional: true });\n const defaults = inject(BF_DEFAULTS);\n return computed(() => {\n const size = menu?.resolvedSize() ?? defaults.controlSize;\n return [ITEM, SIZE[size], SUBMENU_CHEVRON, INDICATOR[kind]].filter(Boolean).join(' ');\n });\n}\n\n/**\n * Keyboard and pointer rules of a link item (`a[bfMenuItem]`), listened in the capture phase on\n * the link so they run before the CDK and before the app's `routerLink` on the same element:\n * - `Space` follows the link, like `Enter` (a native `<a>` only answers `Enter`, and the CDK would\n * close the menu without navigating); the synthetic click is the one activation, and held-down\n * auto-repeats are ignored.\n * - While disabled (`aria-disabled=\"true\"`), a click and `Enter` are cancelled and stopped, so\n * neither the browser, the CDK nor `routerLink` (which ignores `defaultPrevented`) navigates.\n */\nfunction linkItemRules(): void {\n const el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n if (el.tagName !== 'A') {\n return;\n }\n const disabled = (): boolean => el.getAttribute('aria-disabled') === 'true';\n const block = (event: Event): void => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n const onClick = (event: MouseEvent): void => {\n if (disabled()) {\n block(event);\n }\n };\n const onKeydown = (event: KeyboardEvent): void => {\n if (event.key === 'Enter' && disabled()) {\n block(event);\n return;\n }\n if (\n event.key !== ' ' ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey ||\n disabled()\n ) {\n return;\n }\n block(event);\n if (!event.repeat) {\n el.click();\n }\n };\n el.addEventListener('click', onClick, { capture: true });\n el.addEventListener('keydown', onKeydown, { capture: true });\n inject(DestroyRef).onDestroy(() => {\n el.removeEventListener('click', onClick, { capture: true });\n el.removeEventListener('keydown', onKeydown, { capture: true });\n });\n}\n\n/**\n * An action row of a `bf-menu` (role `menuitem`), on a native `<button>` or a link (`<a>` with\n * `href` or `routerLink`). Activating it (click, `Enter`, `Space`) emits `triggered`, closes every\n * open menu and returns focus to the trigger. With `[bfMenuTriggerFor]` on the same element it\n * opens a submenu instead (and shows a chevron). A disabled item stays focusable and announces\n * itself as disabled, but does not activate; a disabled link does not navigate either, also with\n * `routerLink`.\n *\n * @example\n * <button bfMenuItem (triggered)=\"rename()\">Rename</button>\n * <a bfMenuItem routerLink=\"/settings\">Settings</a>\n * @binding bfMenuItemDisabled Whether the item is disabled: it stays focusable and announced, but does not activate.\n * @binding bfMenuItemTypeahead The text typeahead matches the item by (default: its text content).\n * @binding triggered Emits when the item is activated (click, `Enter` or `Space`), unless it opens a submenu.\n * @summary An action row of a menu on a native button or link, with keyboard rules\n * @since 0.3.0\n */\n@Directive({\n selector: 'button[bfMenuItem], a[bfMenuItem]',\n hostDirectives: [\n {\n directive: CdkMenuItem,\n inputs: [\n 'cdkMenuItemDisabled: bfMenuItemDisabled',\n 'cdkMenuitemTypeaheadLabel: bfMenuItemTypeahead',\n ],\n outputs: ['cdkMenuItemTriggered: triggered'],\n },\n ],\n host: { '[class]': 'classes()' },\n})\nexport class BfMenuItemDirective {\n protected readonly classes = itemClasses('item');\n\n constructor() {\n linkItemRules();\n }\n}\n\n/**\n * A toggle row of a `bf-menu` (role `menuitemcheckbox`) with a check mark while `checked`.\n * Activating it (click, `Enter`, `Space`) flips its own `checked` (`aria-checked`), emits\n * `triggered`, then `changed` (and `checkedChange`) with the new state, and closes the menu. Bind\n * it two-way, `[(checked)]`, so your state always follows the item.\n *\n * @example\n * <button bfMenuItemCheckbox [(checked)]=\"showGrid\">Show grid</button>\n * @binding bfMenuItemDisabled Whether the item is disabled: it stays focusable and announced, but does not activate.\n * @binding bfMenuItemTypeahead The text typeahead matches the item by (default: its text content).\n * @binding triggered Emits when the item is activated (click, `Enter` or `Space`), before `checked` flips.\n * @summary A menu row that toggles an option on and off with a check mark\n * @since 0.3.0\n */\n@Directive({\n selector: 'button[bfMenuItemCheckbox]',\n hostDirectives: [\n {\n directive: CdkMenuItemCheckbox,\n inputs: [\n 'cdkMenuItemDisabled: bfMenuItemDisabled',\n 'cdkMenuitemTypeaheadLabel: bfMenuItemTypeahead',\n ],\n outputs: ['cdkMenuItemTriggered: triggered'],\n },\n ],\n host: { '[class]': 'classes()' },\n})\nexport class BfMenuItemCheckboxDirective {\n /** Whether the item is checked. The item flips it itself on activation (and emits\n * `checkedChange`), so bind it two-way: `[(checked)]`. */\n readonly checked = model(false);\n /** Emitted with the new state right after the user toggles the item. */\n readonly changed = output<boolean>();\n\n protected readonly classes = itemClasses('checkbox');\n\n constructor() {\n const item = inject(CdkMenuItemCheckbox, { self: true });\n effect(() => {\n // effect-justified: CdkMenuItemCheckbox is this directive's own host directive; its checked is a plain @Input with no signal to derive from\n item.checked = this.checked();\n });\n // The CDK emits `triggered` just before it flips its own `checked` (and never while disabled).\n const subscription = item.triggered.subscribe(() => {\n const next = !item.checked;\n this.checked.set(next);\n this.changed.emit(next);\n });\n inject(DestroyRef).onDestroy(() => subscription.unsubscribe());\n }\n}\n\n/**\n * One choice of a set (role `menuitemradio`) with a dot while `checked`. Put the choices of one\n * set in a `bfMenuGroup`: choosing one (click, `Enter`, `Space`) unchecks the others, emits\n * `triggered` and closes the menu.\n *\n * @example\n * <div bfMenuGroup aria-label=\"Density\">\n * <button bfMenuItemRadio [checked]=\"density() === 'compact'\" (triggered)=\"density.set('compact')\">\n * Compact\n * </button>\n * </div>\n * @binding checked Whether this choice is the selected one of its group (shown with a dot).\n * @binding bfMenuItemDisabled Whether the item is disabled: it stays focusable and announced, but does not activate.\n * @binding bfMenuItemTypeahead The text typeahead matches the item by (default: its text content).\n * @binding triggered Emits when the choice is activated (click, `Enter` or `Space`); set your state here.\n * @summary One choice of a set of exclusive options in a menu, marked with a dot\n * @since 0.3.0\n */\n@Directive({\n selector: 'button[bfMenuItemRadio]',\n hostDirectives: [\n {\n directive: CdkMenuItemRadio,\n inputs: [\n 'cdkMenuItemChecked: checked',\n 'cdkMenuItemDisabled: bfMenuItemDisabled',\n 'cdkMenuitemTypeaheadLabel: bfMenuItemTypeahead',\n ],\n outputs: ['cdkMenuItemTriggered: triggered'],\n },\n ],\n host: { '[class]': 'classes()' },\n})\nexport class BfMenuItemRadioDirective {\n protected readonly classes = itemClasses('radio');\n}\n\n/**\n * A group of menu items (role `group`); radio items in one group are exclusive. Name it with\n * `aria-label` when its items share a topic (\"Density\").\n *\n * @example\n * <div bfMenuGroup aria-label=\"Density\">…radio items…</div>\n * @summary Groups related menu items; radio items in one group exclude each other\n * @since 0.3.0\n */\n@Directive({\n selector: '[bfMenuGroup]',\n hostDirectives: [CdkMenuGroup],\n host: { class: 'flex flex-col' },\n})\nexport class BfMenuGroupDirective {}\n\n/**\n * A line between groups of menu items (role `separator`, not focusable).\n *\n * @example\n * <div bfMenuDivider></div>\n * @summary A line between groups of menu items that keyboard focus never lands on\n * @since 0.3.0\n */\n@Directive({\n selector: '[bfMenuDivider]',\n // A border, not a fill: forced colours keep borders.\n host: { role: 'separator', class: 'my-1 block h-0 border-t border-border' },\n})\nexport class BfMenuDividerDirective {}\n","import {\n Component,\n type TemplateRef,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n} from '@angular/core';\nimport {\n BF_DEFAULTS,\n type BfSize,\n ɵBF_BUTTON_CLASSES,\n ɵBF_ICON_BUTTON_CLASSES,\n ɵPILL_HIT,\n} from '@bitforgehq/ui';\nimport { type BfMenuPlacement, BfMenuTriggerDirective } from '../menu/menu-trigger.directive';\n\n/**\n * The visual style of a `bf-menu-button`: outline, text or tonal, as `bf-button`'s.\n *\n * @summary The three visual styles of a menu button, matching the button styles\n * @since 0.3.0\n */\nexport type BfMenuButtonVariant = 'outline' | 'text' | 'tonal';\n\n/* The look comes from bf-button's and bf-icon-button's own class maps (internal root exports), so\n the three never drift. Only the caret's padding is local: the label button keeps less padding at\n the inline end, where the caret sits. */\nconst BUTTON = ɵBF_BUTTON_CLASSES;\nconst ICON = ɵBF_ICON_BUTTON_CLASSES;\nconst CARET_PADDING: Record<BfSize, string> = {\n sm: 'ps-3.5 pe-3',\n md: 'ps-4.5 pe-4',\n lg: 'ps-6 pe-5',\n};\n\n/**\n * Button that opens a `bf-menu`: a native `<button>` styled like `bf-button` (or `bf-icon-button`\n * with `iconOnly`) in the outline, text or tonal variant, with `aria-haspopup=\"menu\"` and\n * `aria-expanded`. Click, `Enter`, `Space` or `ArrowDown` open the menu with its first item\n * focused, `ArrowUp` with its last; closing it returns focus here.\n *\n * @example\n * <bf-menu-button [menu]=\"actions\">Actions</bf-menu-button>\n * <bf-menu-button [menu]=\"actions\" iconOnly label=\"More actions\" variant=\"text\">\n * <bf-icon [icon]=\"Ellipsis\" />\n * </bf-menu-button>\n * <ng-template #actions>\n * <bf-menu><button bfMenuItem (triggered)=\"rename()\">Rename</button></bf-menu>\n * </ng-template>\n * @summary Styled button that opens a menu, with outline, text, tonal and icon-only looks\n * @category Overlays\n * @since 0.3.0\n * @slot icon-start An icon before the label.\n * @slot default The label (the accessible name of an icon-only button).\n */\n@Component({\n selector: 'bf-menu-button',\n imports: [BfMenuTriggerDirective],\n host: { class: 'inline-flex max-w-full' },\n template: `\n <button\n type=\"button\"\n [bfMenuTriggerFor]=\"menu()\"\n [bfMenuPlacement]=\"placement()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label() || null\"\n [class]=\"classes()\"\n (bfMenuOpened)=\"opened.emit()\"\n (bfMenuClosed)=\"closed.emit()\"\n >\n <ng-content select=\"[bfSlot=icon-start]\" />\n <span data-label [class]=\"labelClasses()\"><ng-content /></span>\n @if (!iconOnly()) {\n <!-- A CSS caret pointing down in either direction (physical borders), in the text colour; nothing in the accessible name. -->\n <span\n data-caret\n class=\"size-2 shrink-0 -translate-y-0.5 rotate-45 border-r-[1.5px] border-b-[1.5px] border-current\"\n ></span>\n }\n </button>\n `,\n})\nexport class BfMenuButtonComponent {\n private readonly defaults = inject(BF_DEFAULTS);\n\n /** The `ng-template` holding the `bf-menu` to open. */\n readonly menu = input.required<TemplateRef<unknown>>();\n /** Visual style: outline (default), text, tonal. */\n readonly variant = input<BfMenuButtonVariant>('outline');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`controlSize`,\n * `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Where the menu opens against the button; it flips when it would overflow. */\n readonly placement = input<BfMenuPlacement>('below-start');\n /** Accessible name (`aria-label`). Required with `iconOnly`; with a visible label leave it empty\n * or start it with the visible text. */\n readonly label = input('');\n /** Square button holding only the projected icon, like `bf-icon-button`; set `label`. */\n readonly iconOnly = input(false, { transform: booleanAttribute });\n /** Disables the button; the menu cannot open. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /** The menu opened. */\n readonly opened = output<void>();\n /** The menu closed. */\n readonly closed = output<void>();\n\n /** The size in effect: `size`, else the app's `controlSize` default. */\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.controlSize);\n\n /* Icon-only: the wrapper drops out of layout so the icon centres in the square. */\n protected readonly labelClasses = computed(() =>\n this.iconOnly() ? 'contents' : 'max-w-full min-w-0 truncate',\n );\n\n protected readonly classes = computed(() => {\n const size = this.resolvedSize();\n const variant = this.variant();\n const hit = ɵPILL_HIT[size][variant === 'outline' ? 'bordered' : 'plain'];\n if (this.iconOnly()) {\n const pressed = this.disabled() ? '' : ICON.pressed[variant];\n return [ICON.base, ICON.variant[variant], pressed, ICON.size[size], hit]\n .filter(Boolean)\n .join(' ');\n }\n // bf-button sets its pointer through its loading state; a menu button is never loading.\n const padding = variant === 'text' ? BUTTON.textPadding[size] : CARET_PADDING[size];\n const pressed = this.disabled() ? '' : BUTTON.pressed[variant];\n return [\n BUTTON.base,\n 'cursor-pointer',\n BUTTON.variant[variant],\n pressed,\n BUTTON.size[size],\n padding,\n hit,\n ]\n .filter(Boolean)\n .join(' ');\n });\n}\n","import { Component, booleanAttribute, computed, inject, input, model, output } from '@angular/core';\nimport { BF_LABELS, type BfColorScheme, type BfSize } from '@bitforgehq/ui';\nimport { BfMenuComponent } from '../menu/menu.component';\nimport { BfMenuItemRadioDirective } from '../menu/menu-item.directive';\nimport { type BfMenuPlacement } from '../menu/menu-trigger.directive';\nimport {\n BfMenuButtonComponent,\n type BfMenuButtonVariant,\n} from '../menu-button/menu-button.component';\n\n/** One choice of the theme menu: the scheme and its label. */\ninterface ThemeChoice {\n readonly value: BfColorScheme;\n readonly label: string;\n}\n\n/**\n * The colour scheme switch as a menu button, for a crowded top bar: a `bf-menu-button` whose menu\n * holds System, Light and Dark as radio items, the current one marked with a dot. It holds a\n * `BfColorScheme` and injects no service, so the app binds its own state, usually\n * `BfColorSchemeService.scheme` (`BfPlatformService.theme` in a Capacitor app). The button shows\n * `label` (\"Theme\") next to an optional icon, or only the icon with `iconOnly`.\n *\n * @example\n * <bf-theme-menu-button iconOnly variant=\"text\" [(value)]=\"colorScheme.scheme\">\n * <bf-icon bfSlot=\"icon\" [icon]=\"colorScheme.dark() ? Moon : Sun\" />\n * </bf-theme-menu-button>\n * @summary Menu button with System, Light and Dark radio items bound to the colour scheme\n * @category Overlays\n * @since 0.3.1\n * @slot icon The icon before the label, or the whole button with `iconOnly` (a sun or a moon).\n */\n@Component({\n selector: 'bf-theme-menu-button',\n imports: [BfMenuButtonComponent, BfMenuComponent, BfMenuItemRadioDirective],\n host: { class: 'inline-flex max-w-full' },\n template: `\n <bf-menu-button\n [menu]=\"themeMenu\"\n [variant]=\"variant()\"\n [size]=\"size()\"\n [placement]=\"placement()\"\n [iconOnly]=\"iconOnly()\"\n [label]=\"iconOnly() ? resolvedLabel() : ''\"\n >\n <!-- display: contents, so the projected icon is the button's own flex item. -->\n <span bfSlot=\"icon-start\" class=\"contents\"><ng-content select=\"[bfSlot=icon]\" /></span>\n @if (!iconOnly()) {\n {{ resolvedLabel() }}\n }\n </bf-menu-button>\n <ng-template #themeMenu>\n <bf-menu>\n @for (choice of choices; track choice.value) {\n <button\n bfMenuItemRadio\n [checked]=\"value() === choice.value\"\n (triggered)=\"select(choice.value)\"\n >\n {{ choice.label }}\n </button>\n }\n </bf-menu>\n </ng-template>\n `,\n})\nexport class BfThemeMenuButtonComponent {\n private readonly labels = inject(BF_LABELS);\n\n /** The colour scheme choice; bind it two-way, usually to `BfColorSchemeService.scheme`. */\n readonly value = model<BfColorScheme>('system');\n /** The button's text, and its accessible name with `iconOnly`; empty falls back to the `theme`\n * label. */\n readonly label = input('');\n /** Square button holding only the projected icon, like `bf-icon-button`. */\n readonly iconOnly = input(false, { transform: booleanAttribute });\n /** Visual style: outline (default), text, tonal. */\n readonly variant = input<BfMenuButtonVariant>('outline');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`controlSize`,\n * `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Where the menu opens against the button; it flips when it would overflow. */\n readonly placement = input<BfMenuPlacement>('below-end');\n\n /** Emitted with the new choice right after the user picks another item. */\n readonly changed = output<BfColorScheme>();\n\n /** The three items, labelled by `themeSystem`, `themeLight` and `themeDark`. */\n protected readonly choices: readonly ThemeChoice[] = [\n { value: 'system', label: this.labels.themeSystem },\n { value: 'light', label: this.labels.themeLight },\n { value: 'dark', label: this.labels.themeDark },\n ];\n /** The button's name: `label`, else the `theme` label. */\n protected readonly resolvedLabel = computed(() => this.label() || this.labels.theme);\n\n /**\n * Takes the item the user picked; the current choice again changes nothing.\n * @internal\n */\n select(next: BfColorScheme): void {\n if (next === this.value()) {\n return;\n }\n this.value.set(next);\n this.changed.emit(next);\n }\n}\n","import { Component, input } from '@angular/core';\n\n/**\n * The small dark pill of a tooltip (role `tooltip`). A `[bfTooltip]` directive renders it in the\n * CDK overlay beside its element while the pointer rests on it or it has keyboard focus, so you\n * rarely place it yourself; the directive is how you add a tooltip.\n *\n * @example\n * <bf-icon-button label=\"Copy link\" bfTooltip=\"Copy link\"><bf-icon [icon]=\"link\" /></bf-icon-button>\n * @summary Short hint beside a control on hover or keyboard focus, for desktop\n * @category Overlays\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-tooltip',\n host: {\n role: 'tooltip',\n // The transparent border becomes visible under forced colours, where the fill is dropped.\n class:\n 'block max-w-xs rounded-field border border-transparent bg-tooltip px-2.5 py-1 ' +\n 'text-label-xs text-on-tooltip shadow-raised break-words',\n },\n template: '{{ text() }}',\n})\nexport class BfTooltipComponent {\n /** The tooltip's text: a few words that repeat or explain the control's name. */\n readonly text = input('');\n}\n","import { Directionality } from '@angular/cdk/bidi';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n DOCUMENT,\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n inject,\n input,\n inputBinding,\n EnvironmentInjector,\n} from '@angular/core';\nimport { ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport {\n type AnchoredOverlay,\n createAnchoredOverlay,\n sidePositions,\n} from '../core/anchored-overlay';\nimport { prefersReducedMotion } from '../core/motion';\nimport { animateOrSettle } from '../core/overlay-animations';\nimport { TABBABLE } from '../core/overlay.service';\nimport { BfTooltipComponent } from './tooltip.component';\n\n/**\n * Which side of its element a tooltip sits on; `start` and `end` follow the text direction.\n *\n * @summary Which side of its element a tooltip sits on: top, bottom, start or end\n * @since 0.3.1\n */\nexport type BfTooltipPlacement = 'top' | 'bottom' | 'start' | 'end';\n\n/** How long the pointer rests on the element before the tooltip shows (ms). */\nconst SHOW_DELAY = 500;\n/** How long a tooltip stays after the pointer leaves, so it can move onto the tooltip (ms). */\nconst HIDE_GRACE = 100;\n/** The tooltip's fade-in (ms); none under reduced motion. */\nconst FADE = 120;\n\n/**\n * Shows a short `bf-tooltip` beside an element: after a 500 ms rest of a fine pointer, at once on\n * keyboard focus. It hides when the pointer leaves (it stays while the pointer moves onto the\n * tooltip itself), on blur and on `Escape`, and while it shows, the focusable element (the host,\n * or the first control inside it, so it works on a `bf-icon-button`) is described by it\n * (`aria-describedby`). Nothing shows under a coarse pointer (touch), so never put information\n * only in a tooltip. The tooltip flips to the opposite side when it would overflow the viewport.\n *\n * @example\n * <bf-icon-button label=\"Archive\" bfTooltip=\"Archive\" bfTooltipPlacement=\"bottom\">\n * <bf-icon [icon]=\"archive\" />\n * </bf-icon-button>\n * @summary Adds a hover and keyboard-focus tooltip to any control on desktop\n * @since 0.3.1\n */\n@Directive({\n selector: '[bfTooltip]',\n host: {\n // Marks the host for the /testing harness, whatever binds the text.\n 'data-bf-tooltip': '',\n '(mouseenter)': 'pointerEntered()',\n '(mouseleave)': 'pointerLeft()',\n '(focusin)': 'focused($event)',\n '(focusout)': 'hide()',\n },\n})\nexport class BfTooltipDirective {\n private readonly environment = inject(EnvironmentInjector);\n private readonly document = inject(DOCUMENT);\n private readonly injector = inject(Injector);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /** The tooltip's text; empty shows no tooltip. */\n readonly bfTooltip = input.required<string>();\n /** The side it shows on (flipping when it would overflow), read each time it shows. */\n readonly bfTooltipPlacement = input<BfTooltipPlacement>('top');\n\n private readonly id = uniqueId('bf-tooltip');\n private anchored: AnchoredOverlay | null = null;\n private described: HTMLElement | null = null;\n private keys: Subscription | null = null;\n private showTimer: ReturnType<typeof setTimeout> | null = null;\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.hide());\n }\n\n /** Whether the tooltip is showing. */\n isShown(): boolean {\n return this.anchored !== null;\n }\n\n /** Shows the tooltip now (no delay). Does nothing under a coarse pointer or without text. */\n show(): void {\n this.clearTimers();\n if (this.anchored || !this.bfTooltip() || this.coarsePointer()) {\n return;\n }\n const direction = this.dir?.value ?? 'ltr';\n const anchored = createAnchoredOverlay(this.environment, this.host, {\n positions: sidePositions(this.bfTooltipPlacement(), direction),\n direction,\n panelClass: ['bf-tooltip-panel'],\n });\n const tooltip = anchored.ref.attach(\n new ComponentPortal(BfTooltipComponent, null, this.injector, null, [\n inputBinding('text', this.bfTooltip),\n ]),\n );\n tooltip.changeDetectorRef.detectChanges();\n const pill = tooltip.location.nativeElement as HTMLElement;\n pill.id = this.id;\n const pane = anchored.ref.overlayElement;\n // A pointer moving from the element onto the tooltip keeps it (WCAG 1.4.13, hoverable).\n pane.addEventListener('mouseenter', () => this.clearTimers());\n pane.addEventListener('mouseleave', () => this.pointerLeft());\n // Escape hides it wherever focus is (1.4.13, dismissible). The CDK hands a key to the topmost\n // overlay that listens, so a dialog or popover underneath stays open; cancelling the key keeps\n // it from a CloseWatcher. No host listener: it would hide first and let the key fall through.\n this.keys = anchored.ref.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.hide();\n }\n });\n this.anchored = anchored;\n this.describe();\n anchored.ref.updatePosition();\n if (!prefersReducedMotion(this.document.defaultView)) {\n animateOrSettle(pane, [{ opacity: 0 }, { opacity: 1 }], { duration: FADE, easing: 'linear' });\n }\n }\n\n /** Hides the tooltip now and cancels a pending show. */\n hide(): void {\n this.clearTimers();\n this.keys?.unsubscribe();\n this.keys = null;\n this.undescribe();\n this.anchored?.ref.dispose();\n this.anchored = null;\n }\n\n /** @internal */\n pointerEntered(): void {\n if (this.anchored) {\n this.clearTimers();\n return;\n }\n this.clearTimers();\n this.showTimer = setTimeout(() => this.show(), SHOW_DELAY);\n }\n\n /** @internal */\n pointerLeft(): void {\n if (this.showTimer !== null) {\n this.clearTimers();\n return;\n }\n if (this.anchored && this.hideTimer === null) {\n this.hideTimer = setTimeout(() => this.hide(), HIDE_GRACE);\n }\n }\n\n /** @internal */\n focused(event: FocusEvent): void {\n // Keyboard focus only: a click that focuses the control leaves it to the hover delay.\n if (event.target instanceof HTMLElement && this.focusVisible(event.target)) {\n this.show();\n }\n }\n\n private clearTimers(): void {\n if (this.showTimer !== null) {\n clearTimeout(this.showTimer);\n this.showTimer = null;\n }\n if (this.hideTimer !== null) {\n clearTimeout(this.hideTimer);\n this.hideTimer = null;\n }\n }\n\n /** No hover under a coarse pointer: a tooltip would only show after a tap, over the finger. */\n private coarsePointer(): boolean {\n const view = this.document.defaultView;\n return typeof view?.matchMedia === 'function' && view.matchMedia('(pointer: coarse)').matches;\n }\n\n private focusVisible(el: HTMLElement): boolean {\n try {\n return el.matches(':focus-visible');\n } catch {\n // An engine without :focus-visible (an old jsdom): treat every focus as keyboard focus.\n return true;\n }\n }\n\n /** The element the tooltip describes: the host when it takes focus, else its first control. */\n private describedElement(): HTMLElement {\n if (this.host.matches(TABBABLE) || this.host.hasAttribute('tabindex')) {\n return this.host;\n }\n return this.host.querySelector<HTMLElement>(TABBABLE) ?? this.host;\n }\n\n private describe(): void {\n const el = this.describedElement();\n const ids = (el.getAttribute('aria-describedby') ?? '').split(/\\s+/).filter(Boolean);\n if (!ids.includes(this.id)) {\n el.setAttribute('aria-describedby', [...ids, this.id].join(' '));\n }\n this.described = el;\n }\n\n private undescribe(): void {\n const el = this.described;\n if (!el) {\n return;\n }\n const ids = (el.getAttribute('aria-describedby') ?? '')\n .split(/\\s+/)\n .filter((id) => id && id !== this.id);\n if (ids.length) {\n el.setAttribute('aria-describedby', ids.join(' '));\n } else {\n el.removeAttribute('aria-describedby');\n }\n this.described = null;\n }\n}\n","import { Component, computed, inject, input } from '@angular/core';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n type BfSize,\n ɵBF_ICON_BUTTON_CLASSES,\n ɵBF_NAV,\n ɵPILL_HIT,\n} from '@bitforgehq/ui';\nimport { BfTooltipDirective } from '../tooltip/tooltip.directive';\n\n/* bf-icon-button's text variant, from its own class maps (internal root exports), so the toggle\n and an icon button beside it never drift. */\nconst ICON = ɵBF_ICON_BUTTON_CLASSES;\n\n/* Shown inside a sidebar, nothing elsewhere (a top nav, or no nav at all). */\ntype BfSidebarToggleForm = 'shown' | 'none';\nconst HOST: Record<BfSidebarToggleForm, string> = {\n shown: 'inline-flex',\n none: 'hidden',\n};\n\n/**\n * The collapse button of a `bf-sidebar`: a text icon button placed inside the sidebar (usually in\n * its header or footer) that flips the sidebar between full width and an icon rail. Its name and\n * tooltip say what the next press does (\"Collapse sidebar\", \"Expand sidebar\"), `aria-expanded`\n * follows the sidebar and `aria-controls` points at its `nav`. It shows the `collapse-icon` slot\n * while expanded and the `expand-icon` slot while collapsed. It reads and writes the sidebar's\n * `collapsed` model, so `[(collapsed)]` on the sidebar sees every press. Outside a `bf-sidebar`\n * (in a `bf-top-nav`, or on its own) it renders nothing.\n *\n * @example\n * <bf-sidebar [(collapsed)]=\"sidebarState.collapsed\">\n * <bf-sidebar-toggle bfSlot=\"footer\">\n * <bf-icon bfSlot=\"collapse-icon\" [icon]=\"PanelLeftClose\" />\n * <bf-icon bfSlot=\"expand-icon\" [icon]=\"PanelLeftOpen\" />\n * </bf-sidebar-toggle>\n * </bf-sidebar>\n * @summary Icon button inside a sidebar that collapses it to an icon rail and back\n * @category Navigation\n * @since 0.3.2\n * @slot collapse-icon The icon shown while the sidebar is expanded (a panel closing).\n * @slot expand-icon The icon shown while the sidebar is an icon rail (a panel opening).\n */\n@Component({\n selector: 'bf-sidebar-toggle',\n imports: [BfTooltipDirective],\n host: { '[class]': 'hostClasses()' },\n template: `\n @if (nav) {\n <button\n type=\"button\"\n [class]=\"classes()\"\n [attr.aria-label]=\"name()\"\n [attr.aria-expanded]=\"!collapsed()\"\n [attr.aria-controls]=\"nav.navId\"\n [bfTooltip]=\"name()\"\n [bfTooltipPlacement]=\"collapsed() ? 'end' : 'top'\"\n (click)=\"toggle()\"\n >\n <!-- display: contents, so the projected icon is the button's own flex item. -->\n <span [class]=\"collapsed() ? 'hidden' : 'contents'\"\n ><ng-content select=\"[bfSlot=collapse-icon]\"\n /></span>\n <span [class]=\"collapsed() ? 'contents' : 'hidden'\"\n ><ng-content select=\"[bfSlot=expand-icon]\"\n /></span>\n </button>\n }\n `,\n})\nexport class BfSidebarToggleComponent {\n private readonly defaults = inject(BF_DEFAULTS);\n private readonly labels = inject(BF_LABELS);\n private readonly host = inject(ɵBF_NAV, { optional: true });\n /** The enclosing sidebar's context; null outside a sidebar (a top nav never collapses). */\n protected readonly nav = this.host?.layout === 'sidebar' ? this.host : null;\n\n /** Height step: sm 32, md 40, lg 48 px (square); unset follows `provideBfDefaults()`\n * (`controlSize`, `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n\n /** Whether the sidebar is an icon rail now. */\n protected readonly collapsed = computed(() => this.nav?.collapsed() ?? false);\n /** What the next press does: `sidebarExpand` while collapsed, else `sidebarCollapse`. */\n protected readonly name = computed(() =>\n this.collapsed() ? this.labels.sidebarExpand : this.labels.sidebarCollapse,\n );\n protected readonly hostClasses = computed(() => HOST[this.nav ? 'shown' : 'none']);\n protected readonly classes = computed(() => {\n const size = this.size() ?? this.defaults.controlSize;\n return [ICON.base, ICON.variant.text, ICON.pressed.text, ICON.size[size], ɵPILL_HIT[size].plain]\n .filter(Boolean)\n .join(' ');\n });\n\n /**\n * Flips the sidebar between full width and an icon rail.\n * @internal\n */\n toggle(): void {\n this.nav?.setCollapsed(!this.collapsed());\n }\n}\n","import {\n Component,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n output,\n viewChild,\n} from '@angular/core';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n BfTextareaComponent,\n type BfSize,\n ɵBF_BUTTON_CLASSES,\n ɵPILL_HIT,\n} from '@bitforgehq/ui';\nimport { BfTooltipDirective } from '../tooltip/tooltip.directive';\n\n/* bf-button's class maps (internal root exports), so the send button never drifts from it. */\nconst BUTTON = ɵBF_BUTTON_CLASSES;\n\n/* What the one button does now: send the text, or stop the running reply. */\ntype BfChatComposerAction = 'send' | 'stop';\nconst VARIANT: Record<BfChatComposerAction, 'primary' | 'tonal'> = {\n send: 'primary',\n stop: 'tonal',\n};\n/* With an icon projected the button is a square of the step's height (the text label stays as\n its sr-only name); without one it is a pill with the text. */\nconst SQUARE: Record<BfSize, string> = {\n sm: 'has-[[data-icon]>*]:w-8 has-[[data-icon]>*]:px-0',\n md: 'has-[[data-icon]>*]:w-10 has-[[data-icon]>*]:px-0',\n lg: 'has-[[data-icon]>*]:w-12 has-[[data-icon]>*]:px-0',\n};\n/* A one-line field as tall as the button beside it (32/40/48 px): bf-textarea's single row is\n 2 px short at sm and md and 2 px tall at lg, so the bottom edges would not line up. */\nconst FIELD_HEIGHT: Record<BfSize, string> = {\n sm: '[&_textarea]:min-h-8',\n md: '[&_textarea]:min-h-10',\n lg: '[&_textarea]:min-h-12 [&_textarea]:py-[11px]',\n};\n/* Disabled with a reason: `aria-disabled` (it stays focusable, so the tooltip can show on focus),\n drawn like bf-button's disabled state, with no hover or pressed step. */\nconst BLOCKED = 'cursor-not-allowed bg-surface-sunken text-text-disabled';\n\n/**\n * The input row of a chat: a `bf-textarea` that grows with the text (`autoResize`, up to\n * `maxRows`, then it scrolls), a start and an end slot for extra controls, and one button that\n * sends the text or, while a reply is `running`, stops it. `Enter` sends and `Shift+Enter`\n * starts a new line; nothing sends during IME composition or\n * when the text is only whitespace. After a send the text clears and focus stays in the field.\n * `disabled` with a `disabledReason` shows the reason as the button's tooltip and as the empty\n * field's placeholder.\n *\n * @example\n * <bf-chat-composer [(value)]=\"draft\" [running]=\"replying()\" (sent)=\"ask($event)\" (stopped)=\"cancel()\">\n * <bf-icon bfSlot=\"send-icon\" [icon]=\"ArrowUp\" />\n * <bf-icon bfSlot=\"stop-icon\" [icon]=\"Square\" />\n * </bf-chat-composer>\n * @summary Chat input that grows with the text and sends on Enter, or stops a reply\n * @category Forms\n * @since 0.5.0\n * @slot start Controls before the field, such as a preset picker or an attach button.\n * @slot end Controls between the field and the send button.\n * @slot send-icon The send button's icon; without one the button shows its text.\n * @slot stop-icon The stop button's icon; without one the button shows its text.\n */\n@Component({\n selector: 'bf-chat-composer',\n imports: [BfTextareaComponent, BfTooltipDirective],\n host: { class: 'flex items-end gap-2', '[attr.data-running]': \"running() ? '' : null\" },\n template: `\n <div data-start class=\"flex shrink-0 items-center gap-1 empty:hidden\">\n <ng-content select=\"[bfSlot=start]\" />\n </div>\n <bf-textarea\n [class]=\"fieldClasses()\"\n autoResize\n [rows]=\"1\"\n [maxRows]=\"maxRows()\"\n [size]=\"resolvedSize()\"\n [label]=\"label()\"\n [ariaLabel]=\"fieldName()\"\n [ariaLabelledby]=\"ariaLabelledby()\"\n [placeholder]=\"fieldPlaceholder()\"\n [disabled]=\"disabled()\"\n [maxLength]=\"maxLength()\"\n [name]=\"name()\"\n [value]=\"value()\"\n (changed)=\"onChanged($event)\"\n (keydown)=\"onKeydown($event)\"\n />\n <div data-end class=\"flex shrink-0 items-center gap-1 empty:hidden\">\n <ng-content select=\"[bfSlot=end]\" />\n </div>\n <button\n type=\"button\"\n data-action\n [attr.data-mode]=\"action()\"\n [class]=\"buttonClasses()\"\n [disabled]=\"nativeDisabled()\"\n [attr.aria-disabled]=\"blocked() ? 'true' : null\"\n [bfTooltip]=\"blocked() ? disabledReason() : ''\"\n (click)=\"onButton()\"\n >\n <!-- display: contents, so a projected icon is the button's own flex item. -->\n <span\n [class]=\"action() === 'send' ? 'contents' : 'hidden'\"\n [attr.data-icon]=\"action() === 'send' ? '' : null\"\n ><ng-content select=\"[bfSlot=send-icon]\"\n /></span>\n <span\n [class]=\"action() === 'stop' ? 'contents' : 'hidden'\"\n [attr.data-icon]=\"action() === 'stop' ? '' : null\"\n ><ng-content select=\"[bfSlot=stop-icon]\"\n /></span>\n <span data-text class=\"[[data-icon]:has(>*)~&]:sr-only\">{{ buttonName() }}</span>\n </button>\n `,\n})\nexport class BfChatComposerComponent {\n private readonly defaults = inject(BF_DEFAULTS);\n private readonly labels = inject(BF_LABELS);\n\n /** The text being written; two-way bindable. Cleared after a send. */\n readonly value = model('');\n /** A reply is running: the button stops it (`stopped`) instead of sending. */\n readonly running = input(false, { transform: booleanAttribute });\n /** Nothing can be written or sent. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Why it is disabled, shown as the button's tooltip and the empty field's placeholder. */\n readonly disabledReason = input('');\n /** Visible label above the field; usually left empty in a chat. */\n readonly label = input('');\n /** The field's accessible name without a visible label; empty uses the `chatComposer` label\n * (\"Message\"). */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field without a visible label. */\n readonly ariaLabelledby = input('');\n /** Example text shown while the field is empty. */\n readonly placeholder = input('');\n /** The lines the field grows to at most; past them it scrolls. */\n readonly maxRows = input(8);\n /** Maximum number of characters (native `maxlength`). */\n readonly maxLength = input<number | undefined>(undefined);\n /** Native name attribute of the textarea. */\n readonly name = input('');\n /** Padding, type and button step: sm, md, lg; unset follows `provideBfDefaults()`\n * (`fieldSize`, `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n\n /** Emitted with the new text right after the user changes it (each keystroke or paste). */\n readonly changed = output<string>();\n /** Emitted with the trimmed text when the user sends it (Enter or the send button). */\n readonly sent = output<string>();\n /** Emitted when the user presses the stop button while `running`. */\n readonly stopped = output<void>();\n\n private readonly field = viewChild.required(BfTextareaComponent);\n\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.fieldSize);\n /** The field's one-line height, matched to the button. */\n protected readonly fieldClasses = computed(\n () => `min-w-0 flex-1 ${FIELD_HEIGHT[this.resolvedSize()]}`,\n );\n protected readonly action = computed<BfChatComposerAction>(() =>\n this.running() ? 'stop' : 'send',\n );\n /** Disabled with a reason: focusable, `aria-disabled`, with the reason as a tooltip. */\n protected readonly blocked = computed(() => this.disabled() && this.disabledReason() !== '');\n /** Native `disabled`: disabled without a reason, or nothing to send yet. */\n protected readonly nativeDisabled = computed(\n () =>\n !this.blocked() &&\n (this.disabled() || (this.action() === 'send' && this.value().trim() === '')),\n );\n protected readonly buttonName = computed(() =>\n this.action() === 'stop' ? this.labels.chatStop : this.labels.chatSend,\n );\n /** The field's `aria-label`: `ariaLabel`, else the label key while nothing else names it. */\n protected readonly fieldName = computed(\n () => this.ariaLabel() || (this.ariaLabelledby() ? '' : this.labels.chatComposer),\n );\n protected readonly fieldPlaceholder = computed(() =>\n this.disabled() && this.disabledReason() ? this.disabledReason() : this.placeholder(),\n );\n protected readonly buttonClasses = computed(() => {\n const size = this.resolvedSize();\n const variant = VARIANT[this.action()];\n return [\n BUTTON.base,\n this.blocked()\n ? BLOCKED\n : `${BUTTON.variant[variant]} ${BUTTON.pressed[variant]} cursor-pointer`,\n BUTTON.size[size],\n BUTTON.padding[size],\n SQUARE[size],\n ɵPILL_HIT[size].plain,\n ].join(' ');\n });\n\n /** Sends the text: emits `sent` with it trimmed, clears the field and keeps focus in it. Does\n * nothing while disabled or running, or when the text is only whitespace. */\n send(): void {\n const text = this.value().trim();\n if (this.disabled() || this.running() || text === '') {\n return;\n }\n this.sent.emit(text);\n this.value.set('');\n this.field().focus();\n }\n\n /** Focuses the text field. */\n focus(): void {\n this.field().focus();\n }\n\n /** @internal */\n onChanged(text: string): void {\n this.value.set(text);\n this.changed.emit(text);\n }\n\n /** @internal */\n onButton(): void {\n if (this.blocked()) {\n return;\n }\n if (this.action() === 'stop') {\n this.stopped.emit();\n return;\n }\n this.send();\n }\n\n /** @internal */\n onKeydown(event: KeyboardEvent): void {\n // keyCode 229: the key that ends an IME composition in browsers without isComposing on it.\n const composing = event.isComposing || event.keyCode === 229;\n if (event.key !== 'Enter' || event.shiftKey || composing) {\n return;\n }\n event.preventDefault();\n this.send();\n }\n}\n","import { InjectionToken, type Signal } from '@angular/core';\nimport { type BfOverlayRef } from '../core/overlay-ref';\n\n/**\n * The side panel's width scale: `sm` 360 px, `md` 480 px, `lg` 640 px (22.5, 30 and 40 rem), each\n * never wider than the viewport.\n *\n * @summary The side panel widths, from a 360 px detail list to a 640 px form\n * @since 0.3.1\n */\nexport type BfSidePanelWidth = 'sm' | 'md' | 'lg';\n\n/**\n * The `data` passed to `BfSidePanelService.open()`, injectable in the panel's content.\n *\n * @summary Injection token carrying the data a side panel was opened with, for its content\n * @since 0.3.1\n */\nexport const BF_SIDE_PANEL_DATA = new InjectionToken<unknown>('BF_SIDE_PANEL_DATA');\n\n/** @internal What `BfSidePanelService` tells the `bf-side-panel` inside its content. */\nexport interface BfSidePanelContext {\n /** Id the `bf-side-panel` title renders with; the panel's `aria-labelledby` points to it. */\n readonly titleId: string;\n readonly width: BfSidePanelWidth;\n}\n\n/** @internal Provided by `BfSidePanelService` to the panel's content. */\nexport const BF_SIDE_PANEL_CONTEXT = new InjectionToken<BfSidePanelContext>(\n 'BF_SIDE_PANEL_CONTEXT',\n);\n\n/**\n * Handle to an open side panel, returned by `BfSidePanelService.open()` and injectable in the\n * panel's content (`inject(BfSidePanelRef)`). `close(result)` slides the panel out, detaches it\n * and resolves `afterClosed` with `result`; later calls are ignored. Closing with `Escape`, the\n * backdrop, the `bf-side-panel` close button or a navigation resolves `undefined`.\n *\n * @example\n * const ref = inject(BfSidePanelService).open<InvoiceDetailsComponent, Invoice, Invoice>(\n * InvoiceDetailsComponent,\n * { data: invoice },\n * );\n * const saved = await ref.afterClosed;\n *\n * @summary Handle on an open side panel that closes it and resolves with its result\n * @since 0.3.1\n */\nexport class BfSidePanelRef<R = unknown, C = unknown> {\n /** Unique id of the side panel (its overlay's `bf-overlay-N`). */\n readonly id: string;\n /** Resolves with the result given to `close()`, or `undefined`, once the panel is detached. */\n readonly afterClosed: Promise<R | undefined>;\n /** True once the panel has been detached. */\n readonly closed: Signal<boolean>;\n\n /** @internal Created by `BfSidePanelService`; apps never construct it. */\n constructor(\n private readonly overlayRef: BfOverlayRef<unknown>,\n private readonly instance: () => C | null = () => null,\n ) {\n this.id = overlayRef.id;\n // The overlay resolves with whatever close() was given, which is typed R here.\n this.afterClosed = overlayRef.afterClosed as Promise<R | undefined>;\n this.closed = overlayRef.closed;\n }\n\n /** The content component; `null` for a panel opened from a template. */\n get componentInstance(): C | null {\n return this.instance();\n }\n\n /**\n * Closes the panel with an optional result; ignored once closing.\n * @param result The value `afterClosed` resolves with.\n */\n close(result?: R): void {\n this.overlayRef.close(result);\n }\n}\n\n/**\n * Context of a template opened with `BfSidePanelService.open()`: `let-ref` and `let-data=\"data\"`.\n *\n * @summary The context a template opened as a side panel receives: its ref and its data\n * @since 0.3.1\n */\nexport interface BfSidePanelTemplateContext<D = unknown, R = unknown> {\n /** The panel's ref (`let-ref`), to close it with a result. */\n $implicit: BfSidePanelRef<R>;\n /** The `data` the panel was opened with (`let-data=\"data\"`). */\n data: D;\n}\n","import {\n Component,\n DestroyRef,\n type ElementRef,\n afterNextRender,\n computed,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { BF_LABELS, BfIconButtonComponent, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfIconComponent } from '@bitforgehq/ui/icons';\nimport { X } from 'lucide';\nimport { BF_SIDE_PANEL_CONTEXT, BfSidePanelRef, type BfSidePanelWidth } from './side-panel-ref';\n\n/* Full height of the pane the service stretches over the viewport, against its inline end edge:\n a start border (the line between page and panel, also in forced colours) and the floating\n shadow cast onto the page. */\nconst HOST_BASE =\n 'relative flex h-full flex-col border-s border-border bg-surface text-text shadow-floating';\nconst WIDTH: Record<BfSidePanelWidth, string> = {\n sm: 'w-[min(22.5rem,100vw)]',\n md: 'w-[min(30rem,100vw)]',\n lg: 'w-[min(40rem,100vw)]',\n};\n\n/**\n * Layout of a side panel opened with `BfSidePanelService`: a title row with a close button, a\n * scrolling body and a footer of actions kept at the bottom. The panel is labelled by the title,\n * and the body becomes focusable only while its content overflows, so keyboard users can scroll\n * it (a region named by the title).\n *\n * @example\n * const ref = inject(BfSidePanelService).open(InvoiceDetailsComponent, { data: invoice });\n * // InvoiceDetailsComponent template:\n * // <bf-side-panel title=\"INV-204\"> …details…\n * // <div bfSlot=\"footer\">…buttons…</div> </bf-side-panel>\n * @summary Desktop panel sliding in from the end edge, with a title, body and footer actions\n * @category Overlays\n * @since 0.3.1\n * @slot header More header content after the title, such as a status badge.\n * @slot default The panel body.\n * @slot footer The actions, aligned at the end and kept at the bottom.\n */\n@Component({\n selector: 'bf-side-panel',\n imports: [BfIconButtonComponent, BfIconComponent],\n // `data-bf-side-panel-id` (the panel's own title id, also without a title) lets test harnesses\n // find the overlay panel this one sits in.\n host: { '[class]': 'hostClasses()', '[attr.data-bf-side-panel-id]': 'titleId' },\n template: `\n <div\n data-side-panel-header\n class=\"border-border flex min-h-16 min-w-0 shrink-0 items-center gap-3 border-b py-4 ps-6 pe-14\"\n >\n @if (title()) {\n <h2 [id]=\"titleId\" class=\"text-heading min-w-0 flex-1 wrap-anywhere\">{{ title() }}</h2>\n }\n <ng-content select=\"[bfSlot=header]\" />\n </div>\n <div\n #body\n data-side-panel-body\n class=\"focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto overscroll-contain px-6 py-4 focus-visible:ring-4 focus-visible:outline-hidden focus-visible:ring-inset\"\n [attr.tabindex]=\"overflowing() ? 0 : null\"\n [attr.role]=\"overflowing() && title() ? 'region' : null\"\n [attr.aria-labelledby]=\"overflowing() && title() ? titleId : null\"\n >\n <div #content class=\"flex flex-col gap-4\"><ng-content /></div>\n </div>\n <!-- A projected wrapper (<div bfSlot=\"footer\">) lays out its buttons like the row itself. -->\n <div\n data-side-panel-footer\n class=\"border-border flex shrink-0 flex-wrap justify-end gap-2 border-t px-6 py-4 *:flex *:min-w-0 *:flex-wrap *:justify-end *:gap-2 empty:hidden\"\n >\n <ng-content select=\"[bfSlot=footer]\" />\n </div>\n <!-- Last in DOM order so first-tabbable focus lands on the content, not on the ×. -->\n <bf-icon-button\n data-side-panel-close\n class=\"absolute end-3 top-4\"\n variant=\"text\"\n size=\"sm\"\n [label]=\"closeName()\"\n (clicked)=\"close()\"\n >\n <bf-icon [icon]=\"closeIcon\" />\n </bf-icon-button>\n `,\n})\nexport class BfSidePanelComponent {\n private readonly labels = inject(BF_LABELS);\n private readonly context = inject(BF_SIDE_PANEL_CONTEXT, { optional: true });\n private readonly ref = inject(BfSidePanelRef, { optional: true });\n\n /** Heading of the panel, rendered as the `h2` the side panel is labelled by. */\n readonly title = input('');\n /** Accessible name of the close button; empty uses `provideBfLabels()`'s `close` (\"Close\"). */\n readonly closeLabel = input('');\n\n /** True while the body's content is taller than the body (it scrolls). */\n protected readonly overflowing = signal(false);\n\n protected readonly titleId = this.context?.titleId ?? uniqueId('bf-side-panel-title');\n protected readonly closeIcon = X;\n private readonly width = this.context?.width ?? 'md';\n protected readonly hostClasses = computed(() => `${HOST_BASE} ${WIDTH[this.width]}`);\n protected readonly closeName = computed(() => this.closeLabel() || this.labels.close);\n\n private readonly body = viewChild.required<ElementRef<HTMLElement>>('body');\n private readonly content = viewChild.required<ElementRef<HTMLElement>>('content');\n\n constructor() {\n let observer: ResizeObserver | null = null;\n afterNextRender(() => {\n const body = this.body().nativeElement;\n const measure = (): void => this.overflowing.set(body.scrollHeight > body.clientHeight);\n measure();\n if (typeof ResizeObserver === 'function') {\n observer = new ResizeObserver(measure);\n observer.observe(body);\n observer.observe(this.content().nativeElement);\n }\n });\n inject(DestroyRef).onDestroy(() => observer?.disconnect());\n }\n\n /** Closes the panel with no result (does nothing outside `BfSidePanelService`). */\n protected close(): void {\n this.ref?.close();\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n Component,\n InjectionToken,\n Injectable,\n Injector,\n type StaticProvider,\n TemplateRef,\n type Type,\n inject,\n} from '@angular/core';\nimport { BF_LABELS, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { slideInFromEnd, slideOutToEnd } from '../core/overlay-animations';\nimport { watchPanelHeading } from '../core/overlay-heading';\nimport { type BfComponentOverlayRef, type BfOverlayRef } from '../core/overlay-ref';\nimport { BfOverlayService } from '../core/overlay.service';\nimport {\n BF_SIDE_PANEL_CONTEXT,\n BF_SIDE_PANEL_DATA,\n BfSidePanelRef,\n type BfSidePanelTemplateContext,\n type BfSidePanelWidth,\n} from './side-panel-ref';\n\n/**\n * Options of `BfSidePanelService.open()`.\n *\n * @summary Options of a side panel: its data, width, modality, name and injector\n * @since 0.3.1\n */\nexport interface BfSidePanelConfig<D = unknown> {\n /** Injected into the content as `BF_SIDE_PANEL_DATA` (and a template's `data`). */\n data?: D;\n /**\n * Width of the `bf-side-panel` in the content (default `md`, 480 px), capped at the viewport.\n * @default 'md'\n */\n width?: BfSidePanelWidth;\n /**\n * A modal panel (default true) has a scrim, traps focus and makes the page behind it inert;\n * `false` keeps the page usable beside it.\n * @default true\n */\n modal?: boolean;\n /** Accessible name, when the content renders no `bf-side-panel` title and no heading. */\n ariaLabel?: string;\n /**\n * Parent of the content's injector and source of its labels (default the root injector). Pass\n * the opener's `inject(Injector)` so a feature-level `provideBfLabels()` reaches the panel.\n */\n injector?: Injector;\n}\n\n/** What the template host renders: the caller's template with the side panel context. */\ninterface SidePanelTemplate {\n template: TemplateRef<BfSidePanelTemplateContext<unknown, unknown>>;\n context: BfSidePanelTemplateContext<unknown, unknown>;\n}\n\nconst BF_SIDE_PANEL_TEMPLATE = new InjectionToken<SidePanelTemplate>('BF_SIDE_PANEL_TEMPLATE');\n\n/** Renders a template opened through `BfSidePanelService` inside the panel's pane. */\n@Component({\n selector: 'bf-side-panel-template-host',\n imports: [NgTemplateOutlet],\n host: { style: 'display: contents' },\n template: `<ng-container\n [ngTemplateOutlet]=\"view.template\"\n [ngTemplateOutletContext]=\"view.context\"\n [ngTemplateOutletInjector]=\"injector\"\n />`,\n})\nclass BfSidePanelTemplateHostComponent {\n protected readonly view = inject(BF_SIDE_PANEL_TEMPLATE);\n protected readonly injector = inject(Injector);\n}\n\n/** Marks the pane while it slides out, so a harness reads a closing panel as closed. */\nfunction exitPanel(el: HTMLElement): Animation {\n el.setAttribute('data-bf-closing', '');\n return slideOutToEnd(el);\n}\n\n/**\n * Opens side panels on the overlay core: a component or template in a full-height pane that\n * slides in from the inline end edge (the right, the left under `dir=\"rtl\"`; a cross-fade under\n * reduced motion), labelled by its `bf-side-panel` title, with focus moved in, `Escape` closing\n * it and focus returned to the opener. A modal panel (the default) adds a scrim that closes it on\n * a click, traps focus, locks document scroll and makes the page behind it `inert`, as a dialog\n * does; `modal: false` keeps the page usable and scrollable beside it, and `Escape` closes it\n * only while focus is inside it. A navigation to another URL path closes it. Desktop only.\n *\n * @example\n * const ref = inject(BfSidePanelService).open(InvoiceDetailsComponent, {\n * data: invoice,\n * width: 'lg',\n * });\n * const saved = await ref.afterClosed;\n * @since 0.3.1\n * @summary Opens a full-height panel from the end edge, modal or beside the page\n */\n@Injectable({ providedIn: 'root' })\nexport class BfSidePanelService {\n private readonly overlays = inject(BfOverlayService);\n private readonly injector = inject(Injector);\n\n /**\n * Opens `component` as a side panel; it injects `BfSidePanelRef` and `BF_SIDE_PANEL_DATA`.\n * @param component The component to render; it injects `BfSidePanelRef` and `BF_SIDE_PANEL_DATA`.\n * @param config The panel's data, width, modality, name and injector.\n */\n open<C, D = unknown, R = unknown>(\n component: Type<C>,\n config?: BfSidePanelConfig<D>,\n ): BfSidePanelRef<R, C>;\n /**\n * Opens `template` as a side panel; its context is `{ $implicit: ref, data }`.\n * @param template The template to render, with the context `{ $implicit: ref, data }`.\n * @param config The panel's data, width, modality, name and injector.\n */\n open<D = unknown, R = unknown>(\n template: TemplateRef<BfSidePanelTemplateContext<D, R>>,\n config?: BfSidePanelConfig<D>,\n ): BfSidePanelRef<R>;\n open<C, D, R>(\n content: Type<C> | TemplateRef<BfSidePanelTemplateContext<D, R>>,\n config: BfSidePanelConfig<D> = {},\n ): BfSidePanelRef<R, C> {\n const width = config.width ?? 'md';\n const injector = config.injector ?? this.injector;\n // The shared counter, so an id never repeats one of a bf-side-panel rendered in the page.\n const titleId = uniqueId('bf-side-panel-title');\n let panelRef: BfSidePanelRef<R, C> | null = null;\n let instance: C | null = null;\n\n const providers = (ref: BfOverlayRef<unknown>): StaticProvider[] => {\n const created = new BfSidePanelRef<R, C>(ref, () => instance);\n panelRef = created;\n const list: StaticProvider[] = [\n { provide: BfSidePanelRef, useValue: created },\n { provide: BF_SIDE_PANEL_DATA, useValue: config.data },\n { provide: BF_SIDE_PANEL_CONTEXT, useValue: { titleId, width } },\n ];\n if (content instanceof TemplateRef) {\n const view: SidePanelTemplate = {\n template: content,\n context: { $implicit: created, data: config.data },\n };\n list.push({ provide: BF_SIDE_PANEL_TEMPLATE, useValue: view });\n }\n return list;\n };\n\n const options = {\n data: config.data,\n position: 'end' as const,\n modal: config.modal ?? true,\n ariaLabel: config.ariaLabel,\n ariaLabelledBy: config.ariaLabel ? undefined : titleId,\n panelClass: ['bf-side-panel-panel'],\n injector,\n providers,\n enter: slideInFromEnd,\n exit: exitPanel,\n };\n\n let overlayRef: BfComponentOverlayRef<unknown, R>;\n if (content instanceof TemplateRef) {\n overlayRef = this.overlays.open<BfSidePanelTemplateHostComponent, R>(\n BfSidePanelTemplateHostComponent,\n options,\n );\n } else {\n const componentRef = this.overlays.open<C, R>(content, options);\n instance = componentRef.componentRef.instance;\n overlayRef = componentRef;\n }\n if (!panelRef) {\n throw new Error('BfSidePanelService: the overlay core did not build the panel providers');\n }\n this.nameUnlabelledPanel(\n overlayRef.componentRef.location.nativeElement,\n overlayRef.afterClosed,\n config,\n injector,\n );\n return panelRef;\n }\n\n /**\n * A panel without an `ariaLabel` whose content rendered no `bf-side-panel` title (the core then\n * drops the dangling `aria-labelledby`) is named by the first heading in its content, also one\n * that renders later, and by the `dialog` label until then.\n */\n private nameUnlabelledPanel(\n host: unknown,\n afterClosed: Promise<unknown>,\n config: BfSidePanelConfig<unknown>,\n injector: Injector,\n ): void {\n const panel =\n host instanceof HTMLElement ? host.closest<HTMLElement>('.bf-overlay-panel') : null;\n if (!panel || config.ariaLabel || panel.hasAttribute('aria-labelledby')) {\n return;\n }\n panel.setAttribute('aria-label', injector.get(BF_LABELS).dialog);\n const stop = watchPanelHeading(panel);\n void afterClosed.then(stop);\n }\n}\n","import { Directionality } from '@angular/cdk/bidi';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport { Location } from '@angular/common';\nimport {\n DOCUMENT,\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n type TemplateRef,\n ViewContainerRef,\n afterRenderEffect,\n inject,\n input,\n output,\n signal,\n EnvironmentInjector,\n} from '@angular/core';\nimport { ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport {\n type AnchoredOverlay,\n blockPositions,\n createAnchoredOverlay,\n} from '../core/anchored-overlay';\nimport { AnchoredMotion } from '../core/anchored-motion';\nimport { watchPathChange } from '../core/navigation';\nimport { watchPanelHeading } from '../core/overlay-heading';\nimport { TABBABLE, firstTabbable } from '../core/overlay.service';\n\n/**\n * Where a popover opens against its trigger; `start`/`end` follow the text direction.\n *\n * @summary Where a popover opens against its trigger, above or below, at either end\n * @since 0.3.1\n */\nexport type BfPopoverPlacement = 'below-start' | 'below-end' | 'above-start' | 'above-end';\n\n/**\n * Opens an `ng-template` (usually a `bf-popover`) as a non-modal panel anchored to the element:\n * a click (`Enter` or `Space` on a button) toggles it, focus moves to its first control, `Tab`\n * moves through it and on out (closing it, past the trigger), and `Escape`, a click outside or a\n * navigation to another URL path close it, returning focus to the trigger. The control it\n * decorates (the host, or the first control inside it, such as a `bf-button`'s button) carries\n * `aria-haspopup=\"dialog\"`, `aria-expanded` and, while open, `aria-controls`. Export it as\n * `bfPopoverTrigger` to open and close it from code or from inside the panel.\n *\n * @example\n * <button type=\"button\" [bfPopoverTriggerFor]=\"filters\" #trigger=\"bfPopoverTrigger\">Filters</button>\n * <ng-template #filters>\n * <bf-popover><h2>Filters</h2>…<button (click)=\"trigger.close()\">Apply</button></bf-popover>\n * </ng-template>\n * @summary Opens an anchored, non-modal popover panel from any element or button\n * @since 0.3.1\n */\n@Directive({\n selector: '[bfPopoverTriggerFor]',\n exportAs: 'bfPopoverTrigger',\n // The attribute marks the host for the /testing harness, whatever binds the template.\n host: { 'data-bf-popover-trigger': '', '(click)': 'toggle()' },\n})\nexport class BfPopoverTriggerDirective {\n private readonly environment = inject(EnvironmentInjector);\n private readonly document = inject(DOCUMENT);\n private readonly injector = inject(Injector);\n private readonly viewContainer = inject(ViewContainerRef);\n private readonly location = inject(Location);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /** The `ng-template` holding the panel (a `bf-popover`) this element opens. */\n readonly bfPopoverTriggerFor = input.required<TemplateRef<unknown>>();\n /** Where the panel opens (flipping when it would overflow), read each time it opens. */\n readonly bfPopoverPlacement = input<BfPopoverPlacement>('below-start');\n /** Accessible name of the panel. Empty: its first heading names it, else the trigger. */\n readonly bfPopoverLabel = input('');\n /** Emits when the panel opens. */\n readonly bfPopoverOpened = output<void>();\n /** Emits when the panel closes (`Escape`, a click outside, `Tab` out, a navigation or code). */\n readonly bfPopoverClosed = output<void>();\n\n private readonly openState = signal(false);\n /** Whether the panel is open. */\n readonly isOpen = this.openState.asReadonly();\n /** The id the `bf-popover` panel takes, which the trigger's `aria-controls` points at. */\n readonly panelId = uniqueId('bf-popover');\n\n private anchored: AnchoredOverlay | null = null;\n private readonly motion = new AnchoredMotion();\n private subscriptions: Subscription[] = [];\n private stopNavigation: (() => void) | null = null;\n private stopHeading: (() => void) | null = null;\n\n constructor() {\n afterRenderEffect({\n write: () => {\n const control = this.control();\n const open = this.isOpen();\n control.setAttribute('aria-haspopup', 'dialog');\n control.setAttribute('aria-expanded', String(open));\n if (open) {\n control.setAttribute('aria-controls', this.panelId);\n } else {\n control.removeAttribute('aria-controls');\n }\n },\n });\n inject(DestroyRef).onDestroy(() => {\n this.teardown(false);\n this.motion.flush();\n });\n }\n\n /** Opens the panel and moves focus into it; does nothing while it is open. */\n open(): void {\n if (this.anchored) {\n return;\n }\n // A panel still playing its exit goes now: never two panels with the same id.\n this.motion.flush();\n const direction = this.dir?.value ?? 'ltr';\n const anchored = createAnchoredOverlay(this.environment, this.host, {\n positions: blockPositions(this.bfPopoverPlacement()),\n direction,\n panelClass: ['bf-popover-panel'],\n });\n this.anchored = anchored;\n const view = anchored.ref.attach(\n new TemplatePortal(this.bfPopoverTriggerFor(), this.viewContainer, undefined, this.injector),\n );\n const pane = anchored.ref.overlayElement;\n this.subscriptions = [\n // The CDK hands a key to the topmost overlay that listens: a dialog underneath stays open.\n anchored.ref.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n // Cancelled, so it never reaches a CloseWatcher as a second close request.\n event.preventDefault();\n this.close();\n }\n }),\n anchored.ref.outsidePointerEvents().subscribe((event) => {\n // A click on the trigger toggles it closed itself.\n if (event.target instanceof Node && this.host.contains(event.target)) {\n return;\n }\n // Focus returns only when it would otherwise be lost: a click on another control keeps it.\n const active = this.document.activeElement;\n this.close(!active || active === this.document.body || pane.contains(active));\n }),\n ];\n pane.addEventListener('keydown', (event) => this.tabbed(event, pane));\n this.stopNavigation = watchPathChange(this.location, () => this.close(false));\n this.openState.set(true);\n this.motion.enter(anchored.ref, this.host, view);\n const panel = pane.querySelector<HTMLElement>('bf-popover') ?? pane;\n this.name(panel);\n (firstTabbable(panel) ?? panel).focus({ preventScroll: true });\n this.bfPopoverOpened.emit();\n }\n\n /**\n * Closes the panel; does nothing while it is closed.\n * @param restoreFocus Moves focus back to the trigger (default true).\n */\n close(restoreFocus = true): void {\n if (!this.anchored) {\n return;\n }\n this.teardown(true);\n this.openState.set(false);\n if (restoreFocus) {\n this.control().focus({ preventScroll: true });\n }\n this.bfPopoverClosed.emit();\n }\n\n /** Opens the panel when it is closed, closes it when it is open. */\n toggle(): void {\n if (this.anchored) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /** The id of the trigger's control (assigned when it has none), which names a bare panel. */\n private labelId(): string {\n const control = this.control();\n if (!control.id) {\n control.id = uniqueId('bf-popover-trigger');\n }\n return control.id;\n }\n\n /** The element that takes focus and carries the ARIA state: the host, or its first control. */\n private control(): HTMLElement {\n if (this.host.matches(TABBABLE) || this.host.hasAttribute('tabindex')) {\n return this.host;\n }\n return this.host.querySelector<HTMLElement>(TABBABLE) ?? this.host;\n }\n\n /**\n * `Tab` is not trapped: past the panel's last control it closes the panel and continues from the\n * trigger (the browser moves on to the control after it); `Shift+Tab` before the first control\n * closes it onto the trigger.\n */\n private tabbed(event: KeyboardEvent, pane: HTMLElement): void {\n if (event.key !== 'Tab') {\n return;\n }\n const stops = Array.from(pane.querySelectorAll<HTMLElement>(TABBABLE)).filter(\n (el) => !el.closest('[inert]') && !el.hidden,\n );\n const active = this.document.activeElement;\n const leaving = event.shiftKey\n ? !stops.length || active === stops[0] || active === pane.firstElementChild\n : !stops.length || active === stops[stops.length - 1];\n if (!leaving) {\n return;\n }\n if (event.shiftKey) {\n event.preventDefault();\n }\n // Focus the trigger before the browser's own Tab step, which then starts from it.\n this.close(true);\n }\n\n /**\n * Names the panel before focus moves in, so it is announced with its name: `bfPopoverLabel`\n * (bound by `bf-popover` itself), else its first heading (watched while it has none yet), else\n * the trigger.\n */\n private name(panel: HTMLElement): void {\n if (this.bfPopoverLabel()) {\n return;\n }\n panel.setAttribute('aria-labelledby', this.labelId());\n this.stopHeading = watchPanelHeading(panel);\n }\n\n /**\n * Drops the listeners and closes the overlay: with its exit animation (it stays attached, inert,\n * until the exit has played), or at once when the directive is destroyed.\n */\n private teardown(animate: boolean): void {\n this.stopHeading?.();\n this.stopHeading = null;\n this.subscriptions.forEach((s) => s.unsubscribe());\n this.subscriptions = [];\n this.stopNavigation?.();\n this.stopNavigation = null;\n const ref = this.anchored?.ref;\n this.anchored = null;\n if (ref && animate) {\n this.motion.leave(ref, this.host);\n } else {\n ref?.dispose();\n }\n }\n}\n","import { Component, computed, inject } from '@angular/core';\nimport { ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfPopoverTriggerDirective } from './popover-trigger.directive';\n\n/**\n * The popover panel's surface without its padding, shared with the picker panels of the date and\n * time inputs. It scrolls past the viewport minus 1 rem each side; the panel itself takes focus\n * only when it holds no control, so it draws no ring. Internal to the overlay entry.\n */\nexport const POPOVER_SURFACE =\n 'block bg-surface text-text border border-border rounded-card shadow-floating ' +\n 'max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto overscroll-contain ' +\n 'outline-hidden';\n\n/**\n * Non-modal panel anchored to a trigger, for filters, details or a small form (role `dialog`).\n * Put it in an `ng-template` that a `[bfPopoverTriggerFor]` opens; it takes the id the trigger's\n * `aria-controls` points at and is named by `bfPopoverLabel`, else by its first heading, else by\n * the trigger.\n *\n * @example\n * <button type=\"button\" [bfPopoverTriggerFor]=\"details\">Details</button>\n * <ng-template #details>\n * <bf-popover><h2 class=\"text-label\">Delivery</h2><p>Arrives Thursday.</p></bf-popover>\n * </ng-template>\n * @summary Anchored, non-modal panel for filters, details or a small form\n * @category Overlays\n * @since 0.3.1\n * @slot default The panel's content: a heading, text, fields and actions.\n */\n@Component({\n selector: 'bf-popover',\n host: {\n role: 'dialog',\n tabindex: '-1',\n '[id]': 'id',\n '[attr.aria-label]': 'label() || null',\n class: `${POPOVER_SURFACE} p-card`,\n },\n template: '<ng-content />',\n})\nexport class BfPopoverComponent {\n /** The `bfPopoverTriggerFor` that opened this panel. */\n private readonly trigger = inject(BfPopoverTriggerDirective, { optional: true });\n\n protected readonly id = this.trigger?.panelId ?? uniqueId('bf-popover');\n protected readonly label = computed(() => this.trigger?.bfPopoverLabel() ?? '');\n}\n","import { Directionality } from '@angular/cdk/bidi';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n DestroyRef,\n Injector,\n type Signal,\n type Type,\n ViewContainerRef,\n computed,\n inject,\n signal,\n EnvironmentInjector,\n} from '@angular/core';\nimport { type BfCompareWith, type BfSize, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport {\n type AnchoredOverlay,\n blockPositions,\n createAnchoredOverlay,\n} from '../core/anchored-overlay';\nimport { AnchoredMotion, type AnchoredView } from '../core/anchored-motion';\n\n/**\n * One choice of `bf-combobox` and `bf-multi-combobox`; `value` is any type (a string by default).\n *\n * @summary One combobox choice with its value, label, description, group and disabled flag\n * @since 0.3.1\n */\nexport interface BfComboboxOption<T = string> {\n /** The value the combobox takes when this option is picked. */\n value: T;\n /** The option's text in the list, and the field's text once it is picked. */\n label: string;\n /** A second, muted line under the label (an email, a role). */\n description?: string;\n /** Whether this option cannot be picked; it stays in the list, skipped by the arrow keys. */\n disabled?: boolean;\n /** The heading this option is listed under; options with the same group are listed together. */\n group?: string;\n}\n\n/**\n * Whether an option matches the typed query (the `filter` of the comboboxes). Called only for a\n * query that is not empty.\n *\n * @summary Decides whether a combobox option matches the text typed into the field\n * @since 0.3.1\n */\nexport type BfComboboxFilter<T = string> = (option: BfComboboxOption<T>, query: string) => boolean;\n\n/** Lower case without accents (`É` → `e`), so `\"zoe\"` finds `\"Zoë\"`. */\nexport function foldText(text: string): string {\n return text.normalize('NFD').replace(/\\p{M}/gu, '').toLocaleLowerCase();\n}\n\n/** The default `filter`: the option's label contains the query, ignoring case and accents. */\nexport function labelContains(option: BfComboboxOption<unknown>, query: string): boolean {\n return foldText(option.label).includes(foldText(query.trim()));\n}\n\n/** A visible option and the ids the listbox gives it. */\nexport interface ComboboxItem<T> {\n /** The option. */\n option: BfComboboxOption<T>;\n /** Its position in `options`, which keys its id. */\n index: number;\n /** The option element's id, which `aria-activedescendant` names while it is active. */\n id: string;\n}\n\n/** A run of visible options under one heading (`label` null: the ungrouped options). */\nexport interface ComboboxSection<T> {\n /** The group's heading, or null for the options without a group. */\n label: string | null;\n /** The heading's id, which names the `role=\"group\"`. */\n id: string;\n /** The options in the section, in their `options` order. */\n items: ComboboxItem<T>[];\n}\n\n/** What the combobox core reads from the component that owns it. */\nexport interface ComboboxHost<T> {\n /** The options to choose from. */\n options: Signal<readonly BfComboboxOption<T>[]>;\n /** The match function, or null for no local filtering. */\n filter: Signal<BfComboboxFilter<T> | null>;\n /** Whether an option is picked (shows `aria-selected` and the check mark). */\n isSelected(option: BfComboboxOption<T>): boolean;\n /** Picks an option the user chose with `Enter` or a click. */\n pick(item: ComboboxItem<T>): void;\n /** The element the panel is anchored to and as wide as: the field box. */\n anchor(): HTMLElement;\n /** The panel component to open (the internal listbox). */\n panel: Type<unknown>;\n /** The listbox's accessible name: `aria-label` and `aria-labelledby` values. */\n listboxLabel: Signal<string | null>;\n /** The listbox's `aria-labelledby` value. */\n listboxLabelledby: Signal<string | null>;\n /** Whether the list allows several picks (`aria-multiselectable`). */\n multiple: boolean;\n /** Whether a request is running: the panel shows a spinner row. */\n loading: Signal<boolean>;\n /** The empty row's text. */\n emptyText: Signal<string>;\n /** The size of the field, which the option rows follow. */\n size: Signal<BfSize>;\n /** Emits the query each time the user changes it. */\n queried(query: string): void;\n}\n\n/**\n * The state and behaviour `bf-combobox` and `bf-multi-combobox` share: the query, the filtered and\n * grouped options, the active option, the keyboard and the anchored panel. Created in a field\n * initializer of the component (it injects the overlay and the component's view container), so\n * each component keeps its own typed value model. Internal to the overlay entry.\n */\nexport class ComboboxCore<T> {\n private readonly environment = inject(EnvironmentInjector);\n private readonly injector = inject(Injector);\n private readonly viewContainer = inject(ViewContainerRef);\n private readonly dir = inject(Directionality, { optional: true });\n\n /** The listbox's id, which the input's `aria-controls` names. */\n readonly listboxId = uniqueId('bf-combobox-listbox');\n\n /** The text typed since the last pick; null while the field shows its value. */\n private readonly queryState = signal<string | null>(null);\n readonly query = this.queryState.asReadonly();\n private readonly openState = signal(false);\n /** Whether the panel is open. */\n readonly isOpen = this.openState.asReadonly();\n /** The `index` of the active option, null for none. */\n private readonly activeIndex = signal<number | null>(null);\n\n /** The options that match the query, ungrouped first, then each group in first-seen order. */\n readonly sections = computed<ComboboxSection<T>[]>(() => {\n const query = this.query()?.trim() ?? '';\n const filter = this.host.filter();\n const ungrouped: ComboboxSection<T> = { label: null, id: `${this.listboxId}-g`, items: [] };\n const groups = new Map<string, ComboboxSection<T>>();\n this.host.options().forEach((option, index) => {\n if (query && filter && !filter(option, query)) {\n return;\n }\n const item = { option, index, id: `${this.listboxId}-${index}` };\n if (option.group === undefined || option.group === '') {\n ungrouped.items.push(item);\n return;\n }\n let section = groups.get(option.group);\n if (!section) {\n section = { label: option.group, id: `${this.listboxId}-g${groups.size}`, items: [] };\n groups.set(option.group, section);\n }\n section.items.push(item);\n });\n return [ungrouped, ...groups.values()].filter((section) => section.items.length > 0);\n });\n /** The visible options in list order: the order the arrow keys move through. */\n readonly items = computed(() => this.sections().flatMap((section) => section.items));\n /** The active option while it is visible and the panel is open. */\n readonly active = computed(() => {\n const index = this.activeIndex();\n return this.isOpen() ? (this.items().find((item) => item.index === index) ?? null) : null;\n });\n /** `aria-controls`: the listbox while it is rendered. */\n readonly controls = computed(() =>\n this.isOpen() && this.items().length > 0 ? this.listboxId : null,\n );\n\n private anchored: AnchoredOverlay | null = null;\n /** The listbox component's view, frozen while the panel plays its exit. */\n private panelView: AnchoredView | null = null;\n private readonly motion = new AnchoredMotion();\n private subscriptions: Subscription[] = [];\n\n constructor(readonly host: ComboboxHost<T>) {\n inject(DestroyRef).onDestroy(() => {\n this.teardown(false);\n this.motion.flush();\n });\n }\n\n /**\n * Sets the typed text and emits `queried` when it changed; null shows the value again.\n * @param query The text, or null.\n */\n setQuery(query: string | null): void {\n const before = this.queryState() ?? '';\n this.queryState.set(query);\n if ((query ?? '') !== before) {\n this.host.queried(query ?? '');\n }\n }\n\n /**\n * The user typed: the text becomes the query, the panel opens and the first match is active.\n * @param text The input's text.\n */\n typed(text: string): void {\n this.setQuery(text);\n this.open();\n this.activeIndex.set(text.trim() ? (this.firstEnabled(this.items())?.index ?? null) : null);\n }\n\n /** Opens the panel anchored to the field; does nothing while it is open. */\n open(): void {\n if (this.anchored) {\n return;\n }\n // A list still playing its exit goes now: never two listboxes with the same id.\n this.motion.flush();\n const anchor = this.host.anchor();\n const anchored = createAnchoredOverlay(this.environment, anchor, {\n positions: blockPositions('below-start'),\n direction: this.dir?.value ?? 'ltr',\n panelClass: ['bf-combobox-panel'],\n });\n this.anchored = anchored;\n anchored.ref.updateSize({ width: anchor.getBoundingClientRect().width || undefined });\n const panel = anchored.ref.attach(\n new ComponentPortal(this.host.panel, this.viewContainer, this.injector),\n );\n panel.setInput('core', this);\n this.panelView = panel.changeDetectorRef;\n this.subscriptions = [\n // The CDK hands a key to the topmost overlay that listens: while the list is open, Escape is\n // the list's, so a dialog underneath stays open. Focus stays in the input throughout.\n anchored.ref.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n // Cancelled, so it never reaches a CloseWatcher as a second close request.\n event.preventDefault();\n this.close();\n }\n }),\n anchored.ref.outsidePointerEvents().subscribe((event) => {\n if (!(event.target instanceof Node && anchor.contains(event.target))) {\n this.close();\n }\n }),\n ];\n this.openState.set(true);\n this.motion.enter(anchored.ref, anchor, panel.changeDetectorRef);\n }\n\n /** Closes the panel; does nothing while it is closed. */\n close(): void {\n if (!this.anchored) {\n return;\n }\n this.teardown(true);\n this.openState.set(false);\n this.activeIndex.set(null);\n }\n\n /** Follows the field's size and place while open (chips that wrap make it taller). */\n reposition(): void {\n if (this.anchored) {\n const width = this.host.anchor().getBoundingClientRect().width;\n this.anchored.ref.updateSize({ width: width || undefined });\n this.anchored.ref.updatePosition();\n }\n }\n\n /**\n * Makes an option the active one (the pointer moved over it); a disabled one is skipped.\n * @param item The option.\n */\n activate(item: ComboboxItem<T>): void {\n if (!item.option.disabled) {\n this.activeIndex.set(item.index);\n }\n }\n\n /**\n * Picks an option the user clicked; a disabled one does nothing.\n * @param item The option.\n */\n choose(item: ComboboxItem<T>): void {\n if (!item.option.disabled) {\n this.activeIndex.set(item.index);\n this.host.pick(item);\n }\n }\n\n /**\n * The list keys: arrows open and move (wrapping), `Home`/`End` move to the ends of the open\n * list, `Enter` picks the active option. Returns whether the key was handled (and cancelled).\n * @param event The input's keydown.\n */\n keydown(event: KeyboardEvent): boolean {\n const items = this.items().filter((item) => !item.option.disabled);\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp': {\n const down = event.key === 'ArrowDown';\n if (!this.isOpen()) {\n this.open();\n const selected = items.find((item) => this.host.isSelected(item.option));\n this.activeIndex.set((selected ?? (down ? items[0] : items.at(-1)))?.index ?? null);\n } else if (!event.altKey) {\n this.move(items, down ? 1 : -1);\n }\n event.preventDefault();\n return true;\n }\n case 'Home':\n case 'End':\n if (!this.isOpen() || !items.length) {\n return false;\n }\n this.activeIndex.set((event.key === 'Home' ? items[0] : items.at(-1))?.index ?? null);\n event.preventDefault();\n return true;\n case 'Enter': {\n if (!this.isOpen()) {\n return false;\n }\n const active = this.active();\n if (active) {\n this.host.pick(active);\n }\n event.preventDefault();\n return true;\n }\n default:\n return false;\n }\n }\n\n /** Moves the active option by `step` through the enabled ones, wrapping at the ends. */\n private move(items: ComboboxItem<T>[], step: 1 | -1): void {\n if (!items.length) {\n return;\n }\n const at = items.findIndex((item) => item.index === this.active()?.index);\n const next =\n at < 0 ? (step > 0 ? 0 : items.length - 1) : (at + step + items.length) % items.length;\n this.activeIndex.set(items[next]?.index ?? null);\n }\n\n private firstEnabled(items: ComboboxItem<T>[]): ComboboxItem<T> | undefined {\n return items.find((item) => !item.option.disabled);\n }\n\n /**\n * Drops the listeners and closes the overlay: with its exit animation (the list frozen as it\n * was, so a reset query never reflows it while it fades), or at once on destroy.\n */\n private teardown(animate: boolean): void {\n this.subscriptions.forEach((s) => s.unsubscribe());\n this.subscriptions = [];\n const ref = this.anchored?.ref;\n const view = this.panelView;\n this.anchored = null;\n this.panelView = null;\n if (ref && animate) {\n this.motion.leave(ref, this.host.anchor(), view ?? undefined);\n } else {\n ref?.dispose();\n }\n }\n}\n\n/** Equality of an option's value and a picked value under `compareWith`, never for `null`. */\nexport function sameValue<T>(compare: BfCompareWith<T>, optionValue: T, value: T | null): boolean {\n return value !== null && compare(optionValue, value);\n}\n","import { type BfSize } from '@bitforgehq/ui';\n\n/* Class maps of the combobox fields, shared by bf-combobox and bf-multi-combobox so both look like\n bf-input and bf-select. Internal to the overlay entry. */\n\n/* bf-input's box (bfFieldControlClass): border, surface, focus, read-only and disabled treatment. */\nexport const COMBOBOX_FIELD_BASE =\n 'block w-full rounded-field border bg-surface text-text placeholder:text-text-muted ' +\n 'transition-colors focus:outline-hidden focus:border-primary focus:ring-2 focus:ring-ring ' +\n 'read-only:bg-surface-muted disabled:cursor-not-allowed disabled:border-surface-sunken disabled:bg-surface-muted disabled:text-text-disabled';\n\n/* The text stops short of the chevron at the inline end, as on bf-select. */\nexport const COMBOBOX_PADDING_END: Record<BfSize, string> = {\n sm: 'pe-9',\n md: 'pe-10',\n lg: 'pe-11',\n};\n\n/* bf-select's chevron: a rotated square drawn with borders on the field's wrapper, pointing down\n (no mirroring); only its inset from the inline end follows the size. */\nexport const COMBOBOX_CHEVRON =\n 'relative after:pointer-events-none after:absolute after:top-1/2 after:h-2.5 after:w-2.5 ' +\n \"after:-translate-y-[70%] after:rotate-45 after:border-r-[1.5px] after:border-b-[1.5px] after:border-text-subtle after:content-['']\";\nexport const COMBOBOX_CHEVRON_INSET: Record<BfSize, string> = {\n sm: 'after:end-3.5',\n md: 'after:end-4',\n lg: 'after:end-4.5',\n};\n","import { Component, ElementRef, afterRenderEffect, computed, inject, input } from '@angular/core';\nimport { BF_LABELS, BfSpinnerComponent, type BfSize } from '@bitforgehq/ui';\nimport { type ComboboxCore } from './combobox-core';\n\n/* The menu's card: surface, border, floating shadow; scrolls past 18 rem or the viewport minus\n 1 rem each side, and p-1 keeps the rounded option highlight inside the card's corners. */\nconst PANEL =\n 'block w-full min-w-0 bg-surface text-text border border-border rounded-card shadow-floating p-1 ' +\n 'max-h-[min(18rem,calc(100dvh-2rem))] overflow-y-auto overscroll-contain';\n\n/* The active option (the keyboard's or the pointer's) takes the hover surface; in forced colours\n the system highlight. The check mark is drawn with two borders and shows while selected. */\nconst OPTION =\n 'flex w-full items-start gap-2 rounded-field px-2 text-start cursor-pointer select-none ' +\n 'data-active:bg-surface-muted aria-disabled:cursor-not-allowed aria-disabled:text-text-disabled ' +\n \"before:mt-[0.3em] before:h-[11px] before:w-[6px] before:mx-[5px] before:shrink-0 before:rotate-45 before:border-current before:content-[''] \" +\n 'aria-selected:before:border-r-2 aria-selected:before:border-b-2 aria-selected:text-primary-text ' +\n 'forced-colors:data-active:forced-color-adjust-none forced-colors:data-active:bg-[Highlight] ' +\n 'forced-colors:data-active:text-[HighlightText] forced-colors:aria-disabled:text-[GrayText]';\n\n/* The menu item's heights (32 / 36 / 44 px), at least 44 px under a coarse pointer. */\nconst SIZE: Record<BfSize, string> = {\n sm: 'min-h-8 py-1.5 text-label-sm pointer-coarse:min-h-hit',\n md: 'min-h-9 py-2 text-body pointer-coarse:min-h-hit',\n lg: 'min-h-11 py-2.5 text-body',\n};\n\n/**\n * The panel of `bf-combobox` and `bf-multi-combobox`: the listbox of the filtered options (in\n * `role=\"group\"` sections for grouped ones) and a status row for loading and no results. Opened\n * by the combobox core into the overlay; focus stays in the combobox's input, so a press here is\n * cancelled. Internal to the overlay entry.\n */\n@Component({\n selector: 'bf-combobox-listbox',\n imports: [BfSpinnerComponent],\n // The option rows take no focus and no keys of their own (the combobox's input has both), so a\n // press and a click are handled here for the row they land on.\n host: {\n '[class]': 'panelClasses',\n '(mousedown)': '$event.preventDefault()',\n '(pointermove)': 'onPointer($event, false)',\n '(click)': 'onPointer($event, true)',\n },\n template: `\n @if (core().items().length) {\n <div\n role=\"listbox\"\n [id]=\"core().listboxId\"\n [attr.aria-label]=\"core().host.listboxLabel()\"\n [attr.aria-labelledby]=\"core().host.listboxLabelledby()\"\n [attr.aria-multiselectable]=\"core().host.multiple ? 'true' : null\"\n >\n @for (section of core().sections(); track section.id) {\n <!-- The ungrouped options sit in a plain wrapper, each group in a named role=\"group\". -->\n <div\n [attr.role]=\"section.label ? 'group' : 'presentation'\"\n [attr.aria-labelledby]=\"section.label ? section.id : null\"\n >\n @if (section.label) {\n <div\n [id]=\"section.id\"\n role=\"presentation\"\n class=\"text-caption text-text-muted px-2 pt-2 pb-1\"\n >\n {{ section.label }}\n </div>\n }\n @for (item of section.items; track item.index) {\n <div\n role=\"option\"\n [id]=\"item.id\"\n [attr.aria-selected]=\"core().host.isSelected(item.option) ? 'true' : 'false'\"\n [attr.aria-disabled]=\"item.option.disabled ? 'true' : null\"\n [attr.data-index]=\"item.index\"\n [attr.data-active]=\"core().active()?.index === item.index ? '' : null\"\n [class]=\"optionClasses()\"\n >\n <span class=\"flex min-w-0 flex-col\">\n <span data-label class=\"wrap-anywhere\">{{ item.option.label }}</span>\n @if (item.option.description) {\n <span class=\"text-caption text-text-muted wrap-anywhere\">{{\n item.option.description\n }}</span>\n }\n </span>\n </div>\n }\n </div>\n }\n </div>\n }\n <div role=\"status\" class=\"text-text-muted text-label-sm empty:hidden\">\n @if (core().host.loading()) {\n <div class=\"flex items-center gap-2 px-2 py-2\">\n <bf-spinner size=\"sm\" decorative />{{ labels.loading }}\n </div>\n } @else if (!core().items().length) {\n <div class=\"px-2 py-2\">{{ core().host.emptyText() }}</div>\n }\n </div>\n `,\n})\nexport class BfComboboxListboxComponent {\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n protected readonly labels = inject(BF_LABELS);\n\n /** The combobox core whose options and state this panel shows. */\n readonly core = input.required<ComboboxCore<unknown>>();\n\n protected readonly panelClasses = PANEL;\n protected readonly optionClasses = computed(() => `${OPTION} ${SIZE[this.core().host.size()]}`);\n\n constructor() {\n // Keeps the active option in view as the arrow keys move it.\n afterRenderEffect({\n write: () => {\n const active = this.core().active();\n const option = active ? this.host.querySelector(`[id=\"${active.id}\"]`) : null;\n option?.scrollIntoView?.({ block: 'nearest' });\n },\n });\n }\n\n /**\n * The pointer moved over an option (it becomes the active one) or clicked it (it is picked).\n * @internal\n */\n onPointer(event: Event, pick: boolean): void {\n const row = event.target instanceof Element ? event.target.closest('[role=\"option\"]') : null;\n const index = Number(row?.getAttribute('data-index'));\n const item = this.core()\n .items()\n .find((i) => i.index === index);\n if (!row || !item) {\n return;\n }\n if (pick) {\n this.core().choose(item);\n } else {\n this.core().activate(item);\n }\n }\n}\n","import {\n Component,\n type ElementRef,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n type BfCompareWith,\n BfFieldComponent,\n type BfSize,\n ɵFIELD_BOX as FIELD_BOX,\n ɵFIELD_PADDING_START as FIELD_PADDING_START,\n ɵfieldDescribedBy as fieldDescribedBy,\n ɵfieldErrorMessageId as fieldErrorMessageId,\n ɵfieldErrorText as fieldErrorText,\n ɵfieldShowsError as fieldShowsError,\n ɵuniqueId as uniqueId,\n} from '@bitforgehq/ui';\nimport {\n type BfComboboxFilter,\n type BfComboboxOption,\n ComboboxCore,\n type ComboboxItem,\n foldText,\n labelContains,\n sameValue,\n} from './combobox-core';\nimport {\n COMBOBOX_CHEVRON,\n COMBOBOX_CHEVRON_INSET,\n COMBOBOX_FIELD_BASE,\n COMBOBOX_PADDING_END,\n} from './combobox-classes';\nimport { BfComboboxListboxComponent } from './combobox-listbox.component';\n\n/**\n * Text field with a filtered list of options to pick one value from (the ARIA combobox pattern).\n * Typing filters the list by label, ignoring case and accents; the arrow keys move through it\n * and `Enter` picks. Generic over the option value (a string by default); `null` means nothing is\n * picked. For several values use `bf-multi-combobox`.\n *\n * @example\n * <bf-combobox label=\"Assignee\" placeholder=\"Search people\" [options]=\"people\" [(value)]=\"assigneeId\" />\n * <bf-combobox label=\"Owner\" [options]=\"people\" [formField]=\"task.ownerId\" />\n * @summary Text field that filters a list of options as you type and picks one\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-combobox',\n imports: [BfFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-field\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [error]=\"errorText()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n [controlId]=\"id()\"\n >\n <div #anchor [class]=\"wrapperClasses()\">\n <input\n #el\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n aria-autocomplete=\"list\"\n [id]=\"id()\"\n [attr.name]=\"name() || null\"\n [value]=\"text()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [attr.aria-expanded]=\"core.isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"core.controls()\"\n [attr.aria-activedescendant]=\"core.active()?.id ?? null\"\n [attr.aria-label]=\"ariaLabelAttr()\"\n [attr.aria-labelledby]=\"ariaLabelledbyAttr()\"\n [attr.aria-invalid]=\"showError() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-errormessage]=\"errorMessageId()\"\n [class]=\"classes()\"\n (input)=\"onInput(el)\"\n (keydown)=\"onKeydown($event)\"\n (click)=\"onClick()\"\n (focus)=\"focused.emit($event)\"\n (blur)=\"onBlur($event)\"\n />\n </div>\n </bf-field>\n `,\n})\nexport class BfComboboxComponent<T = string> implements FormValueControl<T | null> {\n /** The picked option's value, `null` while nothing is picked; two-way bindable and bound by\n * `[formField]`. */\n readonly value = model<T | null>(null);\n /** The options to choose from; with server search, the latest results (keep the picked one). */\n readonly options = input.required<readonly BfComboboxOption<T>[]>();\n /** Equality for matching `value` to an option (default `Object.is`); pass one for object values. */\n readonly compareWith = input<BfCompareWith<T>>(Object.is);\n /** Whether an option matches the typed text (default: its label contains it, ignoring case and\n * accents); `null` shows `options` unfiltered, for results filtered by a server. */\n readonly filter = input<BfComboboxFilter<T> | null>(labelContains);\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`\n * by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Hint text shown in the empty field. */\n readonly placeholder = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over Signal Forms errors. */\n readonly errorMessage = input('');\n /** Text of the list's row when no option matches; empty uses the `comboboxEmpty` label. */\n readonly emptyLabel = input('');\n /** Shows a loading row in the list, while a server search for the typed text runs. */\n readonly loading = input(false, { transform: booleanAttribute });\n /** Disables the field. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the value but blocks changes; the field stays focusable and the list never opens. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the text input. */\n readonly name = input('');\n /** Input id; generated when not set. */\n readonly id = input(uniqueId('bf-combobox'));\n\n /** Emitted with the new value after the user picks an option, or `null` after clearing the text. */\n readonly changed = output<T | null>();\n /** Emitted with the typed text each time the user changes it (`''` once it is cleared), for a\n * server search. */\n readonly queried = output<string>();\n /** Emitted when the input gains focus. */\n readonly focused = output<FocusEvent>();\n /** Emitted when the input loses focus. */\n readonly blurred = output<FocusEvent>();\n /** Emitted on blur so Signal Forms marks the field touched. */\n readonly touch = output<void>();\n\n private readonly el = viewChild.required<ElementRef<HTMLInputElement>>('el');\n private readonly anchorEl = viewChild.required<ElementRef<HTMLElement>>('anchor');\n private readonly defaults = inject(BF_DEFAULTS);\n private readonly labels = inject(BF_LABELS);\n\n /** The label of the last option the user picked, for a value no current option matches (the\n * results of a later server search). */\n private readonly pickedLabel = signal<{ value: T; label: string } | null>(null);\n\n /** The size in effect: `size`, else the app's `fieldSize` default. */\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.fieldSize);\n\n protected readonly core = new ComboboxCore<T>({\n options: this.options,\n filter: this.filter,\n isSelected: (option) => sameValue(this.compareWith(), option.value, this.value()),\n pick: (item) => this.pick(item),\n anchor: () => this.anchorEl().nativeElement,\n panel: BfComboboxListboxComponent,\n listboxLabel: computed(() => this.label() || this.ariaLabel() || null),\n listboxLabelledby: computed(() => (this.label() ? null : this.ariaLabelledby() || null)),\n multiple: false,\n loading: this.loading,\n emptyText: computed(() => this.emptyLabel() || this.labels.comboboxEmpty),\n size: this.resolvedSize,\n queried: (query) => this.queried.emit(query),\n });\n\n /** The picked option's label, `''` while nothing is picked. */\n readonly valueLabel = computed(() => {\n const value = this.value();\n if (value === null) {\n return '';\n }\n const compare = this.compareWith();\n const option = this.options().find((o) => compare(o.value, value));\n const picked = this.pickedLabel();\n return option?.label ?? (picked && compare(picked.value, value) ? picked.label : '');\n });\n /** The input's text: what the user is typing, else the picked option's label. */\n protected readonly text = computed(() => this.core.query() ?? this.valueLabel());\n\n readonly errorText = computed(() =>\n fieldErrorText(this.errorMessage(), this.touched(), this.errors(), this.labels.validation),\n );\n readonly showError = computed(() =>\n fieldShowsError(this.errorText(), this.invalid(), this.touched()),\n );\n readonly describedBy = computed(() =>\n fieldDescribedBy(this.id(), this.errorText(), this.helpText()),\n );\n /** `aria-errormessage`: the error paragraph while `aria-invalid` is set. */\n readonly errorMessageId = computed(() =>\n fieldErrorMessageId(this.id(), this.errorText(), this.showError()),\n );\n /** `aria-label` value: only when there is no visible label. */\n readonly ariaLabelAttr = computed(() => (this.label() ? null : this.ariaLabel() || null));\n /** `aria-labelledby` value, under the same rule as `ariaLabelAttr`. */\n readonly ariaLabelledbyAttr = computed(() =>\n this.label() ? null : this.ariaLabelledby() || null,\n );\n readonly wrapperClasses = computed(\n () => `${COMBOBOX_CHEVRON} ${COMBOBOX_CHEVRON_INSET[this.resolvedSize()]}`,\n );\n readonly classes = computed(() =>\n [\n COMBOBOX_FIELD_BASE,\n FIELD_BOX[this.resolvedSize()],\n FIELD_PADDING_START[this.resolvedSize()].text,\n COMBOBOX_PADDING_END[this.resolvedSize()],\n /* Plain hover sorts before focus: and disabled:, so the focus and disabled borders still win. */\n this.showError()\n ? 'border-danger-border hover:border-danger'\n : 'border-border-strong hover:border-text-muted',\n ].join(' '),\n );\n\n /**\n * Focuses the input; Signal Forms calls it from `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.el().nativeElement.focus(options);\n }\n\n /**\n * Typing filters the list and opens it.\n * @internal\n */\n onInput(el: HTMLInputElement): void {\n if (this.readonly()) {\n return;\n }\n this.core.typed(el.value);\n }\n\n /**\n * Opens the list on a click into the field.\n * @internal\n */\n onClick(): void {\n if (!this.readonly() && !this.disabled()) {\n this.core.open();\n }\n }\n\n /**\n * The list keys (arrows, `Home`, `End`, `Enter`), and `Escape` on a closed list, which drops the\n * typed text. `Escape` on an open list is the panel's: it closes it.\n * @internal\n */\n onKeydown(event: KeyboardEvent): void {\n if (this.readonly()) {\n return;\n }\n if (this.core.keydown(event)) {\n return;\n }\n if (event.key === 'Escape' && !this.core.isOpen() && this.core.query() !== null) {\n this.resetQuery(null);\n }\n }\n\n /**\n * Leaving the field closes the list. Typed text that names an option exactly picks it; empty\n * text clears the value; any other text reverts to the picked option's label. Marks the field\n * touched.\n * @internal\n */\n onBlur(event: FocusEvent): void {\n this.core.close();\n const query = this.core.query();\n if (query !== null) {\n const typed = foldText(query.trim());\n const match = this.options().find((o) => !o.disabled && foldText(o.label) === typed);\n if (!typed && this.value() !== null) {\n this.set(null);\n } else if (typed && match && !sameValue(this.compareWith(), match.value, this.value())) {\n this.set(match.value, match.label);\n }\n this.resetQuery(null);\n }\n this.blurred.emit(event);\n this.touch.emit();\n }\n\n /** Picks an option (Enter or a click): the value, the field's text, and the list closes. */\n private pick(item: ComboboxItem<T>): void {\n if (!sameValue(this.compareWith(), item.option.value, this.value())) {\n this.set(item.option.value, item.option.label);\n }\n this.resetQuery(null);\n this.core.close();\n }\n\n private set(value: T | null, label = ''): void {\n this.pickedLabel.set(value === null ? null : { value, label });\n this.value.set(value);\n this.changed.emit(value);\n }\n\n /**\n * Drops the typed text and writes the field's text to the input at once: a pick can follow the\n * last keystroke before change detection has run, when the binding alone would see no change.\n */\n private resetQuery(query: string | null): void {\n this.core.setQuery(query);\n this.el().nativeElement.value = this.text();\n }\n}\n","import {\n Component,\n type ElementRef,\n afterRenderEffect,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n type BfCompareWith,\n BfFieldComponent,\n type BfSize,\n ɵFIELD_PADDING_START as FIELD_PADDING_START,\n ɵfieldDescribedBy as fieldDescribedBy,\n ɵfieldErrorMessageId as fieldErrorMessageId,\n ɵfieldErrorText as fieldErrorText,\n ɵfieldShowsError as fieldShowsError,\n ɵuniqueId as uniqueId,\n} from '@bitforgehq/ui';\nimport { COMBOBOX_CHEVRON, COMBOBOX_CHEVRON_INSET, COMBOBOX_PADDING_END } from './combobox-classes';\nimport {\n type BfComboboxFilter,\n type BfComboboxOption,\n ComboboxCore,\n type ComboboxItem,\n labelContains,\n} from './combobox-core';\nimport { BfComboboxListboxComponent } from './combobox-listbox.component';\n\n/* The field box around the tags and the input: bf-input's border, surface and focus ring, on the\n wrapper (focus-within), growing in height as the tags wrap. */\nconst BOX =\n 'flex w-full flex-wrap items-center gap-1 rounded-field border py-1 ' +\n 'transition-colors focus-within:border-primary focus-within:ring-2 focus-within:ring-ring';\n\n/* At least the text fields' heights (32 / 40 / 48 px) and their type. */\nconst BOX_SIZE: Record<BfSize, string> = {\n sm: 'min-h-8 text-label-xs',\n md: 'min-h-10 text-label-sm',\n lg: 'min-h-12 text-label',\n};\n\ntype BfMultiComboboxMode = 'editable' | 'readonly' | 'disabled';\n/* The surface, text and cursor per mode, each set once so no two classes compete. */\nconst MODE: Record<BfMultiComboboxMode, string> = {\n editable: 'cursor-text bg-surface text-text',\n readonly: 'cursor-text bg-surface-muted text-text',\n disabled: 'cursor-not-allowed border-surface-sunken bg-surface-muted text-text-disabled',\n};\n\n/* The input inside the box: no box of its own, at least 4 rem wide so there is room to type. */\nconst INPUT =\n 'h-6 min-w-16 flex-1 border-0 p-0 shadow-none focus:ring-0 focus:shadow-none bg-transparent ' +\n 'outline-hidden placeholder:text-text-muted ' +\n 'disabled:cursor-not-allowed';\n\n/* A picked value: a small primary-soft tag (bf-chip's selected tonal colours) with a remove\n button at the inline end. */\nconst TAG =\n 'inline-flex h-6 max-w-full min-w-0 items-center rounded-control bg-primary-soft ps-2 ' +\n 'text-label-xs font-bold text-primary-strong';\n/* The remove button: 24 px, extended to 44 px under a coarse pointer. Its × is two borders on a\n child span, so the button's ::after stays free for the hit extension. */\nconst REMOVE =\n 'relative inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-control ' +\n 'hover:bg-primary-soft-hover active:bg-primary-soft-pressed ' +\n 'focus-visible:outline-hidden focus-visible:ring-4 focus-visible:ring-ring ' +\n \"pointer-coarse:after:absolute pointer-coarse:after:-inset-2.5 pointer-coarse:after:content-['']\";\nconst CROSS =\n 'relative block size-2.5 ' +\n \"before:absolute before:inset-x-0 before:top-1/2 before:h-[1.5px] before:-translate-y-1/2 before:rotate-45 before:bg-current before:content-[''] \" +\n \"after:absolute after:inset-x-0 after:top-1/2 after:h-[1.5px] after:-translate-y-1/2 after:-rotate-45 after:bg-current after:content-['']\";\n\n/** A picked value as a tag: its label, for the tag and its remove button's name. */\ninterface BfMultiComboboxTag<T> {\n value: T;\n label: string;\n}\n\n/**\n * Text field with a filtered list of options to pick several values from, shown as removable tags\n * inside the field (the ARIA combobox pattern with a multi-select listbox). Typing filters the\n * list by label, ignoring case and accents; `Enter` or a click adds or removes the active option\n * and the list stays open. Generic over the option value (a string by default); the value is an\n * array, empty while nothing is picked. For one value use `bf-combobox`.\n *\n * @example\n * <bf-multi-combobox label=\"Labels\" placeholder=\"Add labels\" [options]=\"labels\" [(value)]=\"picked\" />\n * <bf-multi-combobox label=\"Reviewers\" [options]=\"people\" [formField]=\"task.reviewerIds\" />\n * @summary Text field that filters options as you type and picks several as tags\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-multi-combobox',\n imports: [BfFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-field\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [error]=\"errorText()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n [controlId]=\"id()\"\n >\n <!-- A press on the box outside the tags puts the caret in the input. -->\n <div #anchor [class]=\"boxClasses()\" (mousedown)=\"onBoxMousedown($event)\">\n @for (tag of tags(); track $index) {\n <span data-chip [class]=\"tagClasses\">\n <span data-label class=\"min-w-0 truncate\">{{ tag.label }}</span>\n @if (editable()) {\n <button\n type=\"button\"\n [class]=\"removeClasses\"\n [attr.aria-label]=\"labels.comboboxRemove(tag.label)\"\n (click)=\"remove($index)\"\n >\n <span aria-hidden=\"true\" [class]=\"crossClasses\"></span>\n </button>\n } @else {\n <span class=\"pe-2\"></span>\n }\n </span>\n }\n <input\n #el\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n aria-autocomplete=\"list\"\n [id]=\"id()\"\n [attr.name]=\"name() || null\"\n [value]=\"core.query() ?? ''\"\n [placeholder]=\"tags().length ? '' : placeholder()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required() && !tags().length\"\n [attr.aria-expanded]=\"core.isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"core.controls()\"\n [attr.aria-activedescendant]=\"core.active()?.id ?? null\"\n [attr.aria-label]=\"ariaLabelAttr()\"\n [attr.aria-labelledby]=\"ariaLabelledbyAttr()\"\n [attr.aria-invalid]=\"showError() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-errormessage]=\"errorMessageId()\"\n [class]=\"inputClasses\"\n (input)=\"onInput(el)\"\n (keydown)=\"onKeydown($event)\"\n (click)=\"onClick()\"\n (focus)=\"focused.emit($event)\"\n (blur)=\"onBlur($event)\"\n />\n </div>\n </bf-field>\n `,\n})\nexport class BfMultiComboboxComponent<T = string> implements FormValueControl<readonly T[]> {\n /** The picked options' values in the order they were picked, empty while nothing is picked;\n * two-way bindable and bound by `[formField]`. */\n readonly value = model<readonly T[]>([]);\n /** The options to choose from; with server search, the latest results. */\n readonly options = input.required<readonly BfComboboxOption<T>[]>();\n /** Equality for matching `value` to an option (default `Object.is`); pass one for object values. */\n readonly compareWith = input<BfCompareWith<T>>(Object.is);\n /** Whether an option matches the typed text (default: its label contains it, ignoring case and\n * accents); `null` shows `options` unfiltered, for results filtered by a server. */\n readonly filter = input<BfComboboxFilter<T> | null>(labelContains);\n /** Height step of the field (its minimum height): sm 32, md 40, lg 48 px; unset follows\n * `provideBfDefaults()` (`fieldSize`, `md` by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Hint text shown while nothing is picked. */\n readonly placeholder = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over Signal Forms errors. */\n readonly errorMessage = input('');\n /** Text of the list's row when no option matches; empty uses the `comboboxEmpty` label. */\n readonly emptyLabel = input('');\n /** Shows a loading row in the list, while a server search for the typed text runs. */\n readonly loading = input(false, { transform: booleanAttribute });\n /** Disables the field and its tags. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the tags but blocks changes: no remove buttons, and the list never opens. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required (at least one value). */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the text input. */\n readonly name = input('');\n /** Input id; generated when not set. */\n readonly id = input(uniqueId('bf-multi-combobox'));\n\n /** Emitted with the new values after the user adds or removes one. */\n readonly changed = output<readonly T[]>();\n /** Emitted with the typed text each time the user changes it (`''` once it is cleared), for a\n * server search. */\n readonly queried = output<string>();\n /** Emitted when the input gains focus. */\n readonly focused = output<FocusEvent>();\n /** Emitted when the input loses focus. */\n readonly blurred = output<FocusEvent>();\n /** Emitted on blur so Signal Forms marks the field touched. */\n readonly touch = output<void>();\n\n private readonly el = viewChild.required<ElementRef<HTMLInputElement>>('el');\n private readonly anchorEl = viewChild.required<ElementRef<HTMLElement>>('anchor');\n private readonly defaults = inject(BF_DEFAULTS);\n protected readonly labels = inject(BF_LABELS);\n\n /** The labels of the options the user picked, for values no current option matches (the\n * results of a later server search). */\n private readonly pickedLabels = signal<readonly BfMultiComboboxTag<T>[]>([]);\n\n /** The size in effect: `size`, else the app's `fieldSize` default. */\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.fieldSize);\n\n protected readonly core = new ComboboxCore<T>({\n options: this.options,\n filter: this.filter,\n isSelected: (option) => this.indexOf(option.value) >= 0,\n pick: (item) => this.toggle(item),\n anchor: () => this.anchorEl().nativeElement,\n panel: BfComboboxListboxComponent,\n listboxLabel: computed(() => this.label() || this.ariaLabel() || null),\n listboxLabelledby: computed(() => (this.label() ? null : this.ariaLabelledby() || null)),\n multiple: true,\n loading: this.loading,\n emptyText: computed(() => this.emptyLabel() || this.labels.comboboxEmpty),\n size: this.resolvedSize,\n queried: (query) => this.queried.emit(query),\n });\n\n /** The picked values with their labels, in `value` order. */\n protected readonly tags = computed<BfMultiComboboxTag<T>[]>(() => {\n const compare = this.compareWith();\n return this.value().map((value) => {\n const label =\n this.options().find((o) => compare(o.value, value))?.label ??\n this.pickedLabels().find((t) => compare(t.value, value))?.label ??\n String(value);\n return { value, label };\n });\n });\n /** Whether the user can change the value (not disabled, not read-only). */\n protected readonly editable = computed(() => !this.disabled() && !this.readonly());\n\n readonly errorText = computed(() =>\n fieldErrorText(this.errorMessage(), this.touched(), this.errors(), this.labels.validation),\n );\n readonly showError = computed(() =>\n fieldShowsError(this.errorText(), this.invalid(), this.touched()),\n );\n readonly describedBy = computed(() =>\n fieldDescribedBy(this.id(), this.errorText(), this.helpText()),\n );\n /** `aria-errormessage`: the error paragraph while `aria-invalid` is set. */\n readonly errorMessageId = computed(() =>\n fieldErrorMessageId(this.id(), this.errorText(), this.showError()),\n );\n /** `aria-label` value: only when there is no visible label. */\n readonly ariaLabelAttr = computed(() => (this.label() ? null : this.ariaLabel() || null));\n /** `aria-labelledby` value, under the same rule as `ariaLabelAttr`. */\n readonly ariaLabelledbyAttr = computed(() =>\n this.label() ? null : this.ariaLabelledby() || null,\n );\n readonly boxClasses = computed(() => {\n const size = this.resolvedSize();\n const mode: BfMultiComboboxMode = this.disabled()\n ? 'disabled'\n : this.readonly()\n ? 'readonly'\n : 'editable';\n return [\n BOX,\n BOX_SIZE[size],\n FIELD_PADDING_START[size].text,\n COMBOBOX_PADDING_END[size],\n COMBOBOX_CHEVRON,\n COMBOBOX_CHEVRON_INSET[size],\n MODE[mode],\n /* Hover darkens the border only while the box has no focus, so the focus border wins. */\n mode === 'disabled'\n ? ''\n : this.showError()\n ? 'border-danger-border hover:not-focus-within:border-danger'\n : 'border-border-strong hover:not-focus-within:border-text-muted',\n ]\n .filter(Boolean)\n .join(' ');\n });\n protected readonly inputClasses = INPUT;\n protected readonly tagClasses = TAG;\n protected readonly removeClasses = REMOVE;\n protected readonly crossClasses = CROSS;\n\n constructor() {\n // Tags that wrap change the field's height: the open list follows its bottom edge.\n afterRenderEffect({\n write: () => {\n this.tags();\n this.core.reposition();\n },\n });\n }\n\n /**\n * Focuses the input; Signal Forms calls it from `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.el().nativeElement.focus(options);\n }\n\n /**\n * Typing filters the list and opens it.\n * @internal\n */\n onInput(el: HTMLInputElement): void {\n if (this.editable()) {\n this.core.typed(el.value);\n }\n }\n\n /**\n * Opens the list on a click into the input.\n * @internal\n */\n onClick(): void {\n if (this.editable()) {\n this.core.open();\n }\n }\n\n /**\n * A press on the box itself (not a tag's button, not the input) focuses the input and opens the\n * list.\n * @internal\n */\n onBoxMousedown(event: MouseEvent): void {\n const target = event.target;\n if (!(target instanceof Element) || target.closest('button, input') || this.disabled()) {\n return;\n }\n event.preventDefault();\n this.focus();\n this.onClick();\n }\n\n /**\n * The list keys (arrows, `Home`, `End`, `Enter`), `Backspace` in the empty input (removes the last\n * tag) and `Escape` on a closed list (drops the typed text).\n * @internal\n */\n onKeydown(event: KeyboardEvent): void {\n if (!this.editable() || this.core.keydown(event)) {\n return;\n }\n const query = this.core.query() ?? '';\n if (event.key === 'Backspace' && query === '' && this.value().length) {\n event.preventDefault();\n this.remove(this.value().length - 1);\n } else if (event.key === 'Escape' && !this.core.isOpen() && query !== '') {\n this.resetQuery(null);\n }\n }\n\n /**\n * Leaving the field closes the list and drops the typed text; marks the field touched.\n * @internal\n */\n onBlur(event: FocusEvent): void {\n this.core.close();\n this.resetQuery(null);\n this.blurred.emit(event);\n this.touch.emit();\n }\n\n /**\n * Removes the value at `index` (a tag's remove button) and returns focus to the input.\n * @internal\n */\n remove(index: number): void {\n const next = this.value().filter((_, i) => i !== index);\n this.value.set(next);\n this.changed.emit(next);\n this.focus();\n }\n\n /** Adds a picked option, or removes it when it is picked already; the typed text clears and the\n * list stays open. */\n private toggle(item: ComboboxItem<T>): void {\n const at = this.indexOf(item.option.value);\n let next: readonly T[];\n if (at >= 0) {\n next = this.value().filter((_, i) => i !== at);\n } else {\n next = [...this.value(), item.option.value];\n const tag = { value: item.option.value, label: item.option.label };\n this.pickedLabels.update((tags) => [...tags, tag]);\n }\n this.value.set(next);\n this.changed.emit(next);\n this.resetQuery('');\n }\n\n private indexOf(value: T): number {\n const compare = this.compareWith();\n return this.value().findIndex((v) => compare(value, v));\n }\n\n /**\n * Drops the typed text and writes the field's text to the input at once: a pick can follow the\n * last keystroke before change detection has run, when the binding alone would see no change.\n */\n private resetQuery(query: string | null): void {\n this.core.setQuery(query);\n this.el().nativeElement.value = '';\n }\n}\n","import {\n Component,\n DOCUMENT,\n DestroyRef,\n type ElementRef,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n type BfCompareWith,\n BfFieldComponent,\n type BfSelectOption,\n type BfSize,\n ɵBfNativeSelectComponent as BfNativeSelectComponent,\n ɵFIELD_BOX as FIELD_BOX,\n ɵFIELD_PADDING_START as FIELD_PADDING_START,\n ɵchoiceIndex as choiceIndex,\n ɵchoiceKey as choiceKey,\n ɵfieldDescribedBy as fieldDescribedBy,\n ɵfieldErrorMessageId as fieldErrorMessageId,\n ɵfieldErrorText as fieldErrorText,\n ɵfieldShowsError as fieldShowsError,\n ɵuniqueId as uniqueId,\n} from '@bitforgehq/ui';\nimport {\n type BfComboboxOption,\n ComboboxCore,\n type ComboboxItem,\n foldText,\n} from '../combobox/combobox-core';\nimport {\n COMBOBOX_CHEVRON,\n COMBOBOX_CHEVRON_INSET,\n COMBOBOX_PADDING_END,\n} from '../combobox/combobox-classes';\nimport { BfComboboxListboxComponent } from '../combobox/combobox-listbox.component';\n\n/* The native select's box without its native-control resets; a div has no :disabled, so the\n disabled treatment keys off aria-disabled. */\nconst BASE =\n 'flex w-full items-center rounded-field border text-text select-none ' +\n 'transition-colors focus:outline-hidden focus:border-primary focus:ring-2 focus:ring-ring ' +\n 'aria-disabled:cursor-not-allowed aria-disabled:border-surface-sunken aria-disabled:bg-surface-muted aria-disabled:text-text-disabled ' +\n /* Forced colours drop the muted look; GrayText marks it disabled, as on the list's options. */\n 'forced-colors:aria-disabled:border-[GrayText] forced-colors:aria-disabled:text-[GrayText]';\n\n/* Read-only shows the muted surface and the plain cursor, as on the native select. */\nconst MODE: Record<'editable' | 'readonly', string> = {\n editable: 'cursor-pointer bg-surface',\n readonly: 'cursor-default bg-surface-muted',\n};\n\n/* Keys that would scroll the page from a focused field; cancelled while read-only. */\nconst SCROLL_KEYS = new Set([' ', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown']);\n\n/* PageUp and PageDown move this many enabled options. */\nconst PAGE = 10;\n/* Keys typed within this many milliseconds of the last one extend the typeahead search. */\nconst TYPEAHEAD_MS = 500;\n\n/**\n * Single-choice dropdown styled like the text field, with a placeholder and Signal Forms binding.\n * Under a mouse it opens a styled list (the combobox's) that follows the select-only combobox\n * pattern: the arrow keys, `Home`, `End`, `PageUp`/`PageDown` and typeahead move through it,\n * `Enter`, `Space` or `Tab` pick. Under a coarse pointer (touch) it renders the platform's native\n * select instead. Generic over the option value (a string by default); `null` means nothing is\n * selected. Moved from `@bitforgehq/ui` to `@bitforgehq/ui/overlay` in 0.5.0.\n *\n * @example\n * <bf-select label=\"Project\" placeholder=\"Pick a project\" [options]=\"projects\" [(value)]=\"projectId\" />\n * <bf-select label=\"Team\" placeholder=\"Pick a team\" [options]=\"teams\" [formField]=\"task.teamId\" />\n * @summary Single-choice dropdown with a styled list, native under touch, with Signal Forms binding\n * @category Forms\n * @since 0.1.0\n */\n@Component({\n selector: 'bf-select',\n imports: [BfFieldComponent, BfNativeSelectComponent],\n host: { class: 'block', '[attr.id]': 'null', '(click)': 'onHostClick($event)' },\n template: `\n @if (coarse()) {\n <bf-native-select\n #native\n [options]=\"options()\"\n [compareWith]=\"compareWith()\"\n [size]=\"size()\"\n [label]=\"label()\"\n [ariaLabel]=\"ariaLabel()\"\n [ariaLabelledby]=\"ariaLabelledby()\"\n [placeholder]=\"placeholder()\"\n [helpText]=\"helpText()\"\n [errorMessage]=\"errorMessage()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [invalid]=\"invalid()\"\n [touched]=\"touched()\"\n [errors]=\"errors()\"\n [name]=\"name()\"\n [id]=\"id()\"\n [(value)]=\"value\"\n (changed)=\"changed.emit($event)\"\n (focused)=\"focused.emit($event)\"\n (blurred)=\"blurred.emit($event)\"\n (touch)=\"touch.emit()\"\n />\n } @else {\n <bf-field\n #box\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [error]=\"errorText()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n [controlId]=\"id()\"\n >\n <div #anchor [class]=\"wrapperClasses()\">\n <div\n #field\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [id]=\"id()\"\n [attr.tabindex]=\"disabled() ? null : 0\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n [attr.aria-readonly]=\"readonly() ? 'true' : null\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-expanded]=\"core.isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"core.controls()\"\n [attr.aria-activedescendant]=\"core.active()?.id ?? null\"\n [attr.aria-label]=\"ariaLabelAttr()\"\n [attr.aria-labelledby]=\"label() ? box.labelId() : ariaLabelledbyAttr()\"\n [attr.aria-invalid]=\"showError() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-errormessage]=\"errorMessageId()\"\n [attr.data-placeholder]=\"selectedIndex() === -1 ? '' : null\"\n [class]=\"classes()\"\n (click)=\"onClick()\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"focused.emit($event)\"\n (blur)=\"onBlur($event)\"\n >\n <span class=\"min-w-0 truncate\">{{ selectedLabel() ?? placeholder() }}</span>\n </div>\n </div>\n @if (name()) {\n <input type=\"hidden\" [name]=\"name()\" [value]=\"formKey()\" [disabled]=\"disabled()\" />\n }\n <!-- The option labels for BfSelectHarness, readable while the list cannot open (disabled,\n read-only); hidden, so never rendered or announced. -->\n <span hidden data-bf-select-options>\n @for (option of options(); track $index) {\n <span [attr.data-disabled]=\"option.disabled ? '' : null\">{{ option.label }}</span>\n }\n </span>\n </bf-field>\n }\n `,\n})\nexport class BfSelectComponent<T = string> implements FormValueControl<T | null> {\n /** The selected option's value, `null` while nothing is selected; two-way bindable and bound by\n * `[formField]`. */\n readonly value = model<T | null>(null);\n /** The options to choose from. */\n readonly options = input.required<readonly BfSelectOption<T>[]>();\n /** Equality for matching `value` to an option (default `Object.is`); pass one for object values. */\n readonly compareWith = input<BfCompareWith<T>>(Object.is);\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`\n * by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the control. */\n readonly label = input('');\n /**\n * Accessible name when no visible label is rendered (e.g. a table filter). Ignored when `label`\n * is set.\n */\n readonly ariaLabel = input('');\n /**\n * Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set.\n */\n readonly ariaLabelledby = input('');\n /** Muted text shown while nothing is selected. */\n readonly placeholder = input('');\n /** Helper text under the control. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over Signal Forms errors. */\n readonly errorMessage = input('');\n /** Disables the control. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the value but blocks changes; the select stays focusable and exposes `aria-readonly`. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the control required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Form name: of a hidden input carrying the selected option's key, or of the native select. */\n readonly name = input('');\n /** Control id; generated when not set. */\n readonly id = input(uniqueId('bf-select'));\n\n /** Emitted with the chosen value after a user change (never `null`). */\n readonly changed = output<T>();\n /** Emitted when the control gains focus. */\n readonly focused = output<FocusEvent>();\n /** Emitted when the control loses focus. */\n readonly blurred = output<FocusEvent>();\n /** Emitted on blur so Signal Forms marks the field touched. */\n readonly touch = output<void>();\n\n private readonly fieldEl = viewChild<ElementRef<HTMLElement>>('field');\n private readonly anchorEl = viewChild<ElementRef<HTMLElement>>('anchor');\n private readonly nativeSelect = viewChild<BfNativeSelectComponent<T>>('native');\n private readonly defaults = inject(BF_DEFAULTS);\n private readonly labels = inject(BF_LABELS);\n private readonly document = inject(DOCUMENT);\n\n /** Whether the primary pointer is coarse (touch), from `matchMedia`: the native mode. */\n protected readonly coarse = signal(false);\n\n /** The size in effect: `size`, else the app's `fieldSize` default. */\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.fieldSize);\n /** Index of the option matching `value`, `-1` while nothing (or `null`) is selected. */\n protected readonly selectedIndex = computed(() =>\n choiceIndex(this.options(), this.value(), this.compareWith()),\n );\n /** The selected option's label, null while nothing is selected. */\n protected readonly selectedLabel = computed<string | null>(\n () => this.options()[this.selectedIndex()]?.label ?? null,\n );\n /** The hidden input's value: the selected option's key (its index for an object), else `''`. */\n protected readonly formKey = computed(() => {\n const index = this.selectedIndex();\n const option = this.options()[index];\n return option ? choiceKey(option.value, index) : '';\n });\n /** The options as the list shows them; the selected one is matched by identity. */\n private readonly listOptions = computed<BfComboboxOption<T>[]>(() =>\n this.options().map(({ value, label, disabled }) => ({ value, label, disabled })),\n );\n\n protected readonly core = new ComboboxCore<T>({\n options: this.listOptions,\n filter: signal(null),\n isSelected: (option) => this.listOptions()[this.selectedIndex()] === option,\n pick: (item) => this.pick(item),\n anchor: () => this.anchorEl()!.nativeElement,\n panel: BfComboboxListboxComponent,\n listboxLabel: computed(() => this.label() || this.ariaLabel() || null),\n listboxLabelledby: computed(() => (this.label() ? null : this.ariaLabelledby() || null)),\n multiple: false,\n loading: signal(false),\n emptyText: signal(''),\n size: this.resolvedSize,\n queried: () => undefined,\n });\n\n protected readonly errorText = computed(() =>\n fieldErrorText(this.errorMessage(), this.touched(), this.errors(), this.labels.validation),\n );\n protected readonly showError = computed(() =>\n fieldShowsError(this.errorText(), this.invalid(), this.touched()),\n );\n protected readonly describedBy = computed(() =>\n fieldDescribedBy(this.id(), this.errorText(), this.helpText()),\n );\n /** `aria-errormessage`: the error paragraph while `aria-invalid` is set. */\n protected readonly errorMessageId = computed(() =>\n fieldErrorMessageId(this.id(), this.errorText(), this.showError()),\n );\n /**\n * `aria-label` value: only when there is no visible label, so the label stays the sole accessible\n * name.\n */\n protected readonly ariaLabelAttr = computed(() =>\n this.label() ? null : this.ariaLabel() || null,\n );\n /**\n * `aria-labelledby` value while there is no visible label; with one, the field points\n * `aria-labelledby` at the label's id instead (a `<label for>` cannot name a div).\n */\n protected readonly ariaLabelledbyAttr = computed(() =>\n this.label() ? null : this.ariaLabelledby() || null,\n );\n protected readonly wrapperClasses = computed(\n () => `${COMBOBOX_CHEVRON} ${COMBOBOX_CHEVRON_INSET[this.resolvedSize()]}`,\n );\n protected readonly classes = computed(() =>\n [\n BASE,\n FIELD_BOX[this.resolvedSize()],\n FIELD_PADDING_START[this.resolvedSize()].text,\n COMBOBOX_PADDING_END[this.resolvedSize()],\n MODE[this.readonly() ? 'readonly' : 'editable'],\n /* Plain hover sorts before focus: and aria-disabled:, so their borders still win. */\n this.showError()\n ? 'border-danger-border hover:border-danger'\n : 'border-border-strong hover:border-text-muted',\n this.selectedIndex() === -1 ? 'text-text-muted' : '',\n ]\n .filter(Boolean)\n .join(' '),\n );\n\n /** The typed typeahead text and when its last key came. */\n private typeahead = '';\n private typedAt = 0;\n\n constructor() {\n const media = this.document.defaultView?.matchMedia?.('(pointer: coarse)');\n if (media) {\n this.coarse.set(media.matches);\n const onChange = (event: MediaQueryListEvent): void => this.coarse.set(event.matches);\n media.addEventListener?.('change', onChange);\n inject(DestroyRef).onDestroy(() => media.removeEventListener?.('change', onChange));\n }\n // The list never stays open on a field that can no longer open it (or is gone).\n effect(() => {\n if (this.coarse() || this.disabled() || this.readonly()) {\n this.core.close();\n }\n });\n }\n\n /**\n * Focuses the field, or the native select under a coarse pointer; Signal Forms calls it from\n * `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n const native = this.nativeSelect();\n if (native) {\n native.focus(options);\n } else {\n this.fieldEl()?.nativeElement.focus(options);\n }\n }\n\n /**\n * A click on the label focuses the field (a label's `for` cannot name a div).\n * @internal\n */\n onHostClick(event: MouseEvent): void {\n if (\n !this.coarse() &&\n !this.disabled() &&\n event.target instanceof Element &&\n event.target.closest('label')\n ) {\n this.focus();\n }\n }\n\n /**\n * A click on the field opens or closes the list.\n * @internal\n */\n onClick(): void {\n if (this.core.isOpen()) {\n this.core.close();\n } else {\n this.openList();\n }\n }\n\n /**\n * The select-only combobox keys: `Enter`, `Space` and the arrows open; while open the arrows,\n * `Home`, `End`, `PageUp` and `PageDown` move, `Enter`, `Space` and `Tab` pick; printable keys\n * search by label. `Escape` on an open list is the panel's: it closes it.\n * @internal\n */\n onKeydown(event: KeyboardEvent): void {\n if (this.disabled()) {\n return;\n }\n if (this.readonly()) {\n if (SCROLL_KEYS.has(event.key)) {\n event.preventDefault();\n }\n return;\n }\n const key = event.key;\n const printable = key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey;\n // A Space while a search is being typed is part of it (\"New York\").\n if (printable && (key !== ' ' || this.typing())) {\n this.search(key);\n event.preventDefault();\n return;\n }\n if (!this.core.isOpen()) {\n if (key === 'Enter' || key === ' ' || key === 'ArrowDown' || key === 'ArrowUp') {\n this.openList();\n event.preventDefault();\n }\n return;\n }\n switch (key) {\n case ' ': {\n this.pickActive();\n event.preventDefault();\n return;\n }\n case 'Tab':\n // Picks and lets the focus move on (APG): the Tab is not cancelled.\n this.pickActive();\n this.core.close();\n return;\n case 'PageUp':\n case 'PageDown':\n this.page(key === 'PageDown' ? PAGE : -PAGE);\n event.preventDefault();\n return;\n default:\n this.core.keydown(event);\n }\n }\n\n /**\n * Leaving the field closes the list, emits `blurred` and marks the field touched. A press in the\n * list never moves the focus (the listbox cancels it), so this runs only when the field is left.\n * @internal\n */\n onBlur(event: FocusEvent): void {\n this.core.close();\n this.blurred.emit(event);\n this.touch.emit();\n }\n\n /** Opens the list with the selected option active, else the first enabled one. */\n private openList(): void {\n if (this.disabled() || this.readonly() || this.core.isOpen()) {\n return;\n }\n const items = this.enabledItems();\n if (!items.length) {\n return;\n }\n this.core.open();\n const selected = items.find((item) => this.core.host.isSelected(item.option));\n this.core.activate(selected ?? items[0]);\n }\n\n /** Picks an option: the value and `changed` when it differs, and the list closes. */\n private pick(item: ComboboxItem<T>): void {\n const index = this.listOptions().indexOf(item.option);\n if (index !== this.selectedIndex()) {\n this.value.set(item.option.value);\n this.changed.emit(item.option.value);\n }\n this.core.close();\n }\n\n private pickActive(): void {\n const active = this.core.active();\n if (active) {\n this.pick(active);\n }\n }\n\n /** Moves the active option by `step` enabled options, stopping at the ends. */\n private page(step: number): void {\n const items = this.enabledItems();\n const at = items.findIndex((item) => item.index === this.core.active()?.index);\n const next = Math.min(Math.max((at < 0 ? 0 : at) + step, 0), items.length - 1);\n const item = items[next];\n if (item) {\n this.core.activate(item);\n }\n }\n\n /** Whether a typeahead search is still being typed. */\n private typing(): boolean {\n return this.typeahead !== '' && Date.now() - this.typedAt <= TYPEAHEAD_MS;\n }\n\n /**\n * Adds a key to the typeahead search, opens the list and activates the next enabled option whose\n * label starts with the search, ignoring case and accents. One letter repeated cycles through the\n * options starting with it; a longer search keeps the active option while it still matches.\n */\n private search(key: string): void {\n this.typeahead = (this.typing() ? this.typeahead : '') + key;\n this.typedAt = Date.now();\n const typed = foldText(this.typeahead);\n const repeated = [...typed].every((char) => char === typed[0]);\n const query = repeated ? typed[0] : typed;\n const items = this.enabledItems();\n const from = this.core.isOpen()\n ? this.core.active()\n : items.find((item) => this.core.host.isSelected(item.option));\n const at = from ? items.findIndex((item) => item.index === from.index) : -1;\n // A new letter searches after the current option, a longer search from it.\n const start = at < 0 ? 0 : repeated ? at + 1 : at;\n const ordered = [...items.slice(start), ...items.slice(0, start)];\n const match = ordered.find((item) => foldText(item.option.label).startsWith(query));\n if (match) {\n this.openList();\n this.core.activate(match);\n }\n }\n\n /** The list's enabled options in list order. */\n private enabledItems(): ComboboxItem<T>[] {\n return this.core.items().filter((item) => !item.option.disabled);\n }\n}\n","import { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { BF_TABLE_SORT_SELECT } from '@bitforgehq/ui';\nimport { BfSelectComponent } from './select.component';\n\n/**\n * Makes the library's built-in selects use the styled `bf-select`: a stacked `bf-table` then\n * renders its Sort by select as a `bf-select` (the native `<select>` under a coarse pointer, as\n * `bf-select` itself does) instead of the plain native one. Add it to\n * `ApplicationConfig.providers`.\n *\n * @returns The providers that fill `BF_TABLE_SORT_SELECT` with `BfSelectComponent`.\n * @summary Makes a stacked table's Sort by select the styled bf-select, app-wide\n * @since 0.5.0\n */\nexport function provideBfSelect(): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: BF_TABLE_SORT_SELECT, useValue: BfSelectComponent }]);\n}\n","import {\n ɵdaysInMonth as daysInMonth,\n ɵformatIsoDate as formatIsoDate,\n ɵparseIsoDate as parseIsoDate,\n} from '@bitforgehq/ui';\n\n/*\n * The segmented field of bf-date-input, bf-time-input and bf-datetime-input as plain functions:\n * which parts a locale shows in which order, each part's range, typing digits, stepping, and\n * turning the parts into the ISO value and back. A date is never a `Date` here: the parts are\n * numbers, the value an ISO string ('YYYY-MM-DD', 'HH:mm', 'YYYY-MM-DDTHH:mm'), so no time zone or\n * daylight-saving shift can move what the user typed. A `Date` is built only at UTC, to hand to\n * `Intl.DateTimeFormat` with `timeZone: 'UTC'`. Internal to the overlay entry.\n */\n\n/** One editable part of the field. */\nexport type SegmentKind = 'day' | 'month' | 'year' | 'hour' | 'minute' | 'second' | 'dayPeriod';\n\n/** What the field edits: a date, a time of day, or both. */\nexport type DateTimeMode = 'date' | 'time' | 'datetime';\n\n/** How hours count: 0–11 or 1–12 with a day period (AM/PM), or 0–23. */\nexport type HourCycle = 'h11' | 'h12' | 'h23';\n\n/** One item of the field's layout: an editable part, or the text between two parts. */\nexport type LayoutItem =\n | { readonly type: 'segment'; readonly kind: SegmentKind }\n | { readonly type: 'literal'; readonly text: string };\n\n/** The parts as numbers, `null` (or missing) while empty; a day period is 0 (AM) or 1 (PM). */\nexport type SegmentValues = Readonly<Partial<Record<SegmentKind, number | null>>>;\n\n/** A segment's inclusive range. */\nexport interface SegmentRange {\n readonly min: number;\n readonly max: number;\n}\n\n/** The outcome of typing one digit into a segment. */\nexport interface TypedDigit {\n /** The segment's new value, `null` while what is typed is not a value yet (a lone \"0\" day). */\n readonly value: number | null;\n /** The digits typed into the segment so far. */\n readonly text: string;\n /** Whether no further digit could follow, so focus moves to the next segment. */\n readonly advance: boolean;\n}\n\nconst DATE_KINDS: readonly SegmentKind[] = ['day', 'month', 'year'];\nconst ISO_TIME = /^(\\d{2}):(\\d{2})(?::(\\d{2}))?$/;\n/* Bidirectional marks some locales put around the separators; the field lays out its own parts. */\nconst BIDI_MARKS = /[‎‏؜‪-‮⁦-⁩]/g;\n\nconst PART_KINDS: Readonly<Record<string, SegmentKind>> = {\n day: 'day',\n month: 'month',\n year: 'year',\n hour: 'hour',\n minute: 'minute',\n second: 'second',\n dayPeriod: 'dayPeriod',\n};\n\nfunction pad(value: number, length: number): string {\n return String(value).padStart(length, '0');\n}\n\n/** A `Date` at the UTC time of the parts, only for `Intl.DateTimeFormat` with `timeZone: 'UTC'`. */\nfunction utcInstant(year: number, month: number, day: number, minutes: number): Date {\n const date = new Date(0);\n // setUTCFullYear, not Date.UTC: Date.UTC maps the years 0–99 to 1900–1999.\n date.setUTCFullYear(year, month - 1, day);\n date.setUTCMinutes(minutes);\n return date;\n}\n\n/** The time parts the field edits for `hourCycle`, with seconds when asked. */\nfunction timeKinds(seconds: boolean, hourCycle: HourCycle): SegmentKind[] {\n return [\n 'hour',\n 'minute',\n ...(seconds ? (['second'] as const) : []),\n ...(hourCycle === 'h23' ? [] : (['dayPeriod'] as const)),\n ];\n}\n\n/** The parts the field edits, in no particular order. */\nexport function segmentKinds(\n mode: DateTimeMode,\n seconds: boolean,\n hourCycle: HourCycle,\n): SegmentKind[] {\n return [\n ...(mode === 'time' ? [] : DATE_KINDS),\n ...(mode === 'date' ? [] : timeKinds(seconds, hourCycle)),\n ];\n}\n\n/**\n * The hour cycle of `locale` (`Intl`'s `hourCycle`, h24 read as h23), or `override` when set.\n */\nexport function resolveHourCycle(locale: string, override?: 'h12' | 'h23'): HourCycle {\n if (override) {\n return override;\n }\n const cycle = new Intl.DateTimeFormat(locale, { hour: 'numeric' }).resolvedOptions().hourCycle;\n return cycle === 'h11' || cycle === 'h12' ? cycle : 'h23';\n}\n\n/**\n * The field's parts and separators in the order `locale` writes them, from\n * `Intl.DateTimeFormat.formatToParts` (Gregorian calendar, Latin digits). Separators are kept as\n * the locale writes them, without bidirectional marks; a part the locale leaves out (never the\n * case for these options) is added at the end, so every part stays editable.\n */\nexport function segmentLayout(\n locale: string,\n mode: DateTimeMode,\n seconds: boolean,\n hourCycle: HourCycle,\n): LayoutItem[] {\n const options: Intl.DateTimeFormatOptions = {\n calendar: 'gregory',\n numberingSystem: 'latn',\n timeZone: 'UTC',\n ...(mode === 'time' ? {} : { year: 'numeric', month: '2-digit', day: '2-digit' }),\n ...(mode === 'date'\n ? {}\n : {\n hour: '2-digit',\n minute: '2-digit',\n hourCycle,\n ...(seconds ? { second: '2-digit' } : {}),\n }),\n };\n const parts = new Intl.DateTimeFormat(locale, options).formatToParts(utcInstant(2001, 2, 3, 245));\n const wanted = new Set(segmentKinds(mode, seconds, hourCycle));\n const items: LayoutItem[] = [];\n for (const part of parts) {\n const kind = PART_KINDS[part.type];\n if (kind && wanted.has(kind)) {\n wanted.delete(kind);\n items.push({ type: 'segment', kind });\n } else if (part.type === 'literal') {\n const text = part.value.replace(BIDI_MARKS, '');\n const last = items[items.length - 1];\n if (last?.type === 'literal') {\n items[items.length - 1] = { type: 'literal', text: last.text + text };\n } else if (text) {\n items.push({ type: 'literal', text });\n }\n }\n }\n for (const kind of wanted) {\n items.push({ type: 'literal', text: ' ' }, { type: 'segment', kind });\n }\n // A separator before the first or after the last part that is only space adds nothing.\n return items.filter(\n (item, index) =>\n item.type === 'segment' || item.text.trim() !== '' || (index > 0 && index < items.length - 1),\n );\n}\n\n/** The localized names of the two day periods, AM first, from `Intl` in `locale`. */\nexport function dayPeriodNames(locale: string): readonly [string, string] {\n const format = new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n hourCycle: 'h12',\n timeZone: 'UTC',\n });\n const name = (hour: number): string =>\n format.formatToParts(utcInstant(2001, 1, 1, hour * 60)).find((p) => p.type === 'dayPeriod')\n ?.value ?? (hour < 12 ? 'AM' : 'PM');\n return [name(1), name(13)];\n}\n\n/** How many digits a segment takes: four for the year, none for the day period, else two. */\nexport function segmentDigits(kind: SegmentKind): number {\n return kind === 'year' ? 4 : kind === 'dayPeriod' ? 0 : 2;\n}\n\n/**\n * A segment's range; the day's follows the month (and the year, for 29 February) once they are\n * set, else it is 1–31 (29 February is allowed until the year says otherwise).\n */\nexport function segmentRange(\n kind: SegmentKind,\n values: SegmentValues,\n hourCycle: HourCycle,\n): SegmentRange {\n switch (kind) {\n case 'day': {\n const month = values.month;\n return { min: 1, max: month ? daysInMonth(values.year ?? 2000, month) : 31 };\n }\n case 'month':\n return { min: 1, max: 12 };\n case 'year':\n return { min: 1, max: 9999 };\n case 'hour':\n return hourCycle === 'h12'\n ? { min: 1, max: 12 }\n : { min: 0, max: hourCycle === 'h11' ? 11 : 23 };\n case 'dayPeriod':\n return { min: 0, max: 1 };\n default:\n return { min: 0, max: 59 };\n }\n}\n\n/**\n * Types `digit` after the digits `text` already typed into a segment. When the digits so far\n * would pass the segment's maximum, typing starts over from `digit`. Focus moves on once the\n * segment has all its digits or no further digit could keep it in range (\"4\" in a month); the\n * field writes `value` then, or when focus leaves the segment (see `commitTyped`). A year has a\n * value only at four digits.\n */\nexport function typeDigit(\n kind: SegmentKind,\n text: string,\n digit: string,\n values: SegmentValues,\n hourCycle: HourCycle,\n): TypedDigit {\n const { min, max } = segmentRange(kind, values, hourCycle);\n const digits = segmentDigits(kind);\n let next = text + digit;\n if (Number(next) > max || next.length > digits) {\n next = digit;\n }\n const number = Number(next);\n const advance = next.length >= digits || number * 10 > max;\n const complete = kind !== 'year' || next.length >= digits;\n return { value: complete && number >= min ? number : null, text: next, advance };\n}\n\n/**\n * The value of what was typed into a segment when focus leaves it: a year of one or two digits is\n * one of the 2000s (\"26\" is 2026), any other text its number when in range, else `null`.\n */\nexport function commitTyped(\n kind: SegmentKind,\n text: string,\n values: SegmentValues,\n hourCycle: HourCycle,\n): number | null {\n if (!text) {\n return values[kind] ?? null;\n }\n const number = Number(text);\n if (kind === 'year') {\n return text.length <= 2 ? 2000 + number : Math.max(1, number);\n }\n const { min, max } = segmentRange(kind, values, hourCycle);\n return number >= min && number <= max ? number : null;\n}\n\n/**\n * A segment moved by `delta` (Arrow Up +1, Arrow Down -1), wrapping inside its range. An empty\n * segment starts at `todayYear` for the year, else at its first value going up and its last going\n * down.\n */\nexport function stepSegment(\n kind: SegmentKind,\n values: SegmentValues,\n delta: number,\n hourCycle: HourCycle,\n todayYear: number,\n): number {\n const { min, max } = segmentRange(kind, values, hourCycle);\n const value = values[kind];\n if (value === null || value === undefined) {\n return kind === 'year' ? todayYear : delta > 0 ? min : max;\n }\n const size = max - min + 1;\n return min + ((((value - min + delta) % size) + size) % size);\n}\n\n/** The ISO date of the parts, or `null` while one is missing or the day is not in the month. */\nexport function composeDate(values: SegmentValues): string | null {\n const { day, month, year } = values;\n if (!day || !month || !year || day > daysInMonth(year, month)) {\n return null;\n }\n return formatIsoDate({ year, month, day });\n}\n\n/** The 24-hour hour of the hour and day-period parts, or `null` while one is missing. */\nfunction hour24(values: SegmentValues, hourCycle: HourCycle): number | null {\n const hour = values.hour;\n if (hour === null || hour === undefined) {\n return null;\n }\n if (hourCycle === 'h23') {\n return hour;\n }\n const period = values.dayPeriod;\n if (period === null || period === undefined) {\n return null;\n }\n return (hourCycle === 'h12' ? hour % 12 : hour) + period * 12;\n}\n\n/** The ISO time 'HH:mm' (or 'HH:mm:ss' with `seconds`) of the parts, or `null` while one is missing. */\nexport function composeTime(\n values: SegmentValues,\n hourCycle: HourCycle,\n seconds: boolean,\n): string | null {\n const hour = hour24(values, hourCycle);\n const { minute, second } = values;\n if (hour === null || minute === null || minute === undefined) {\n return null;\n }\n if (!seconds) {\n return `${pad(hour, 2)}:${pad(minute, 2)}`;\n }\n return second === null || second === undefined\n ? null\n : `${pad(hour, 2)}:${pad(minute, 2)}:${pad(second, 2)}`;\n}\n\n/** The field's ISO value of the parts, `null` while the entry is empty or incomplete. */\nexport function composeValue(\n mode: DateTimeMode,\n values: SegmentValues,\n hourCycle: HourCycle,\n seconds: boolean,\n): string | null {\n const date = mode === 'time' ? '' : composeDate(values);\n const time = mode === 'date' ? '' : composeTime(values, hourCycle, seconds);\n if (date === null || time === null) {\n return null;\n }\n return mode === 'datetime' ? `${date}T${time}` : date || time;\n}\n\n/** The hour, minute and second of an ISO time ('HH:mm' or 'HH:mm:ss'), or `null`. */\nexport function parseIsoTime(\n value: string | null | undefined,\n): { hour: number; minute: number; second: number } | null {\n const match = ISO_TIME.exec(value ?? '');\n if (!match) {\n return null;\n }\n const [hour, minute, second] = [Number(match[1]), Number(match[2]), Number(match[3] ?? 0)];\n return hour < 24 && minute < 60 && second < 60 ? { hour, minute, second } : null;\n}\n\n/** The date part of a value ('YYYY-MM-DD' of a date or a datetime), or `null`. */\nexport function datePartOf(mode: DateTimeMode, value: string | null | undefined): string | null {\n if (mode === 'time' || !value) {\n return null;\n }\n const date = mode === 'datetime' ? value.split('T')[0] : value;\n return parseIsoDate(date) ? (date ?? null) : null;\n}\n\n/** The time part of a value ('HH:mm[:ss]' of a time or a datetime), or `null`. */\nexport function timePartOf(mode: DateTimeMode, value: string | null | undefined): string | null {\n if (mode === 'date' || !value) {\n return null;\n }\n const time = mode === 'datetime' ? value.split('T')[1] : value;\n return parseIsoTime(time) ? (time ?? null) : null;\n}\n\n/** The parts of a valid ISO value for `mode`, or no parts for anything else. */\nexport function valuesFrom(\n mode: DateTimeMode,\n value: string | null | undefined,\n hourCycle: HourCycle,\n): SegmentValues {\n const date = parseIsoDate(datePartOf(mode, value));\n const time = parseIsoTime(timePartOf(mode, value));\n if ((mode !== 'time' && !date) || (mode !== 'date' && !time)) {\n return {};\n }\n return { ...(date ?? {}), ...(time ? timeValues(time, hourCycle) : {}) };\n}\n\nfunction timeValues(\n time: { hour: number; minute: number; second: number },\n hourCycle: HourCycle,\n): SegmentValues {\n const period = time.hour >= 12 ? 1 : 0;\n const hour =\n hourCycle === 'h23' ? time.hour : hourCycle === 'h12' ? time.hour % 12 || 12 : time.hour % 12;\n return {\n hour,\n minute: time.minute,\n second: time.second,\n ...(hourCycle === 'h23' ? {} : { dayPeriod: period }),\n };\n}\n\n/** The parts of an ISO date, to write into the field from the calendar. */\nexport function dateValues(iso: string): SegmentValues {\n return parseIsoDate(iso) ?? {};\n}\n\n/** The parts of an ISO time, to write into the field from the time list. */\nexport function timeValuesOf(iso: string, hourCycle: HourCycle): SegmentValues {\n const time = parseIsoTime(iso);\n return time ? timeValues(time, hourCycle) : {};\n}\n\n/** How far an entry is: nothing typed, some parts typed, or every part typed (valid or not). */\nexport type EntryState = 'empty' | 'partial' | 'filled';\n\n/** The entry state of `kinds` in `values`. */\nexport function entryState(kinds: readonly SegmentKind[], values: SegmentValues): EntryState {\n const filled = kinds.filter((kind) => values[kind] !== null && values[kind] !== undefined);\n return filled.length === 0 ? 'empty' : filled.length === kinds.length ? 'filled' : 'partial';\n}\n\n/** The time parts of `segmentKinds` (hour, minute, second, day period). */\nexport function timeKindsOf(kinds: readonly SegmentKind[]): SegmentKind[] {\n return kinds.filter((kind) => !DATE_KINDS.includes(kind));\n}\n\n/** The date parts of `segmentKinds` (day, month, year). */\nexport function dateKindsOf(kinds: readonly SegmentKind[]): SegmentKind[] {\n return kinds.filter((kind) => DATE_KINDS.includes(kind));\n}\n\n/** One time in the picker list. */\nexport interface TimeOption {\n /** The ISO time, 'HH:mm' (or 'HH:mm:ss'). */\n readonly value: string;\n /** The time as the locale writes it. */\n readonly label: string;\n}\n\n/** A formatter of ISO times ('HH:mm[:ss]') in `locale` and `hourCycle`. */\nexport function timeFormatter(\n locale: string,\n hourCycle: HourCycle,\n seconds: boolean,\n): (iso: string) => string {\n const format = new Intl.DateTimeFormat(locale, {\n hour: '2-digit',\n minute: '2-digit',\n ...(seconds ? { second: '2-digit' } : {}),\n hourCycle,\n numberingSystem: 'latn',\n timeZone: 'UTC',\n });\n return (iso) => {\n const time = parseIsoTime(iso);\n if (!time) {\n return iso;\n }\n const date = utcInstant(2001, 1, 1, time.hour * 60 + time.minute);\n date.setUTCSeconds(time.second);\n return format.format(date);\n };\n}\n\n/** The times of a day every `step` minutes from midnight, written by `format`. */\nexport function timeOptions(\n step: number,\n seconds: boolean,\n format: (iso: string) => string,\n): TimeOption[] {\n const every = Math.min(Math.max(Math.round(step) || 30, 1), 720);\n const options: TimeOption[] = [];\n for (let minutes = 0; minutes < 1440; minutes += every) {\n const value = `${pad(Math.floor(minutes / 60), 2)}:${pad(minutes % 60, 2)}${seconds ? ':00' : ''}`;\n options.push({ value, label: format(value) });\n }\n return options;\n}\n\n/** A segment's text: the value padded to its digits, or the day period's name. */\nexport function segmentText(\n kind: SegmentKind,\n value: number,\n periods: readonly [string, string],\n): string {\n return kind === 'dayPeriod' ? (periods[value] ?? '') : pad(value, segmentDigits(kind));\n}\n\n/**\n * An empty segment's placeholder: the first letter of its name, once per digit (\"Day\" → \"dd\",\n * \"Jahr\" → \"jjjj\"); the day period shows two dashes.\n */\nexport function segmentPlaceholder(kind: SegmentKind, name: string): string {\n const letter = name.trim().charAt(0).toLocaleLowerCase();\n return kind === 'dayPeriod' || !letter ? '––' : letter.repeat(segmentDigits(kind));\n}\n","import { TemplatePortal } from '@angular/cdk/portal';\nimport { Location } from '@angular/common';\nimport {\n Component,\n DOCUMENT,\n DestroyRef,\n ElementRef,\n Injector,\n type TemplateRef,\n ViewContainerRef,\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n linkedSignal,\n model,\n output,\n signal,\n viewChild,\n EnvironmentInjector,\n} from '@angular/core';\nimport { type ValidationError } from '@angular/forms/signals';\nimport {\n BF_DEFAULTS,\n BF_LABELS,\n BfCalendarComponent,\n type BfCalendarDisabledDate,\n BfFieldComponent,\n type BfSize,\n bfFieldControlClass,\n ɵFIELD_BOX as FIELD_BOX,\n ɵFIELD_PADDING_END as FIELD_PADDING_END,\n ɵFIELD_PADDING_START as FIELD_PADDING_START,\n ɵfieldDescribedBy as fieldDescribedBy,\n ɵfieldErrorMessageId as fieldErrorMessageId,\n ɵfieldErrorText as fieldErrorText,\n ɵfieldShowsError as fieldShowsError,\n ɵlocalIsoDate as localIsoDate,\n ɵparseIsoDate as parseIsoDate,\n} from '@bitforgehq/ui';\nimport { type Subscription } from 'rxjs';\nimport {\n type AnchoredOverlay,\n blockPositions,\n createAnchoredOverlay,\n} from '../core/anchored-overlay';\nimport { AnchoredMotion } from '../core/anchored-motion';\nimport { watchPathChange } from '../core/navigation';\nimport { TABBABLE } from '../core/overlay.service';\nimport { POPOVER_SURFACE } from '../popover/popover.component';\nimport {\n type DateTimeMode,\n type HourCycle,\n type LayoutItem,\n type SegmentKind,\n type SegmentValues,\n type TimeOption,\n commitTyped,\n composeDate,\n composeValue,\n dateKindsOf,\n datePartOf,\n dateValues,\n dayPeriodNames,\n entryState,\n parseIsoTime,\n resolveHourCycle,\n segmentKinds,\n segmentLayout,\n segmentPlaceholder,\n segmentRange,\n segmentText,\n stepSegment,\n timeFormatter,\n timeKindsOf,\n timeOptions,\n timePartOf,\n timeValuesOf,\n typeDigit,\n valuesFrom,\n} from './date-time-segments';\n\n/** One rendered segment of the field, as the template binds it. */\ninterface SegmentView {\n readonly type: 'segment';\n readonly kind: SegmentKind;\n readonly id: string;\n readonly name: string;\n readonly text: string;\n readonly empty: boolean;\n readonly min: number;\n readonly max: number;\n readonly now: number | null;\n readonly valueText: string | null;\n}\n\n/** The text between two parts. */\ntype LiteralItem = Extract<LayoutItem, { type: 'literal' }>;\n\n/** One rendered time of the picker list. */\ninterface TimeOptionView extends TimeOption {\n readonly id: string;\n readonly disabled: boolean;\n readonly selected: boolean;\n readonly active: boolean;\n}\n\n/** Digits typed into one segment since it took focus. */\ninterface Typing {\n readonly kind: SegmentKind;\n readonly text: string;\n}\n\n/* The field box: bf-input's look on a group of segments, with the focus ring drawn while any part\n inside it has focus. */\nconst BOX_BASE =\n 'relative flex w-full items-center gap-1 rounded-field border transition-colors ' +\n 'focus-within:border-primary focus-within:ring-2 focus-within:ring-ring';\n/* Room at the inline end for the picker button, which sits 3 px inside the border at every step. */\nconst PICKER_PADDING_END: Record<BfSize, string> = { sm: 'pe-1', md: 'pe-1', lg: 'pe-1' };\n\n/* A part: at least 24 × 24 px (the fine-pointer target size), tinted while it has focus. */\nconst SEGMENT =\n 'inline-flex h-6 min-w-6 items-center justify-center rounded-checkbox px-0.5 tabular-nums ' +\n 'outline-hidden select-none focus:bg-primary-soft focus:text-primary-text';\n\n/* The picker button: square, 3 px inside the field's border, 44 px under a coarse pointer. */\nconst TRIGGER_BASE =\n 'relative inline-flex shrink-0 cursor-pointer items-center justify-center rounded-control text-text-muted ' +\n 'transition-colors duration-150 enabled:hover:bg-surface-muted enabled:hover:text-text enabled:active:bg-surface-pressed ' +\n 'focus-visible:outline-hidden focus-visible:ring-4 focus-visible:ring-ring disabled:cursor-not-allowed disabled:text-text-disabled ' +\n \"pointer-coarse:after:absolute pointer-coarse:after:content-['']\";\nconst TRIGGER_SIZE: Record<BfSize, string> = {\n sm: 'size-6 pointer-coarse:after:-inset-2.5',\n md: 'size-8 pointer-coarse:after:-inset-1.5',\n lg: 'size-10 pointer-coarse:after:-inset-0.5',\n};\n\n/* The marks are CSS borders, so no icon is imported: a calendar sheet with two rings on top, and a\n clock face with its hands from the centre. */\nconst CALENDAR_MARK =\n 'relative block h-3.5 w-4 border-[1.5px] border-t-[3px] border-current ' +\n \"before:absolute before:-top-[6px] before:start-[2px] before:h-1 before:w-[1.5px] before:bg-current before:content-[''] \" +\n \"after:absolute after:-top-[6px] after:end-[2px] after:h-1 after:w-[1.5px] after:bg-current after:content-['']\";\nconst CLOCK_MARK =\n 'relative block size-4 rounded-control border-[1.5px] border-current ' +\n 'after:absolute after:start-[calc(50%-0.75px)] after:bottom-[calc(50%-0.75px)] after:h-1.5 after:w-1 ' +\n \"after:border-s-[1.5px] after:border-b-[1.5px] after:border-current after:content-['']\";\n\n/* The time list: a column of pills, as tall as the calendar beside it. The active option carries\n the focus ring while the list has keyboard focus. */\nconst LIST =\n 'group/list relative flex max-h-72 w-32 shrink-0 flex-col gap-0.5 overflow-y-auto overscroll-contain outline-hidden';\nconst OPTION =\n 'flex h-9 shrink-0 items-center justify-center rounded-control px-3 text-label-sm tabular-nums select-none ' +\n 'transition-colors duration-150 pointer-coarse:h-hit';\ntype OptionState = 'normal' | 'selected' | 'disabled';\nconst OPTION_STATE: Record<OptionState, string> = {\n normal: 'cursor-pointer text-text hover:bg-surface-muted',\n selected: 'cursor-pointer bg-primary font-bold text-on-primary',\n disabled: 'cursor-not-allowed text-text-disabled',\n};\nconst OPTION_ACTIVE =\n 'group-focus-visible/list:ring-2 group-focus-visible/list:ring-ring group-focus-visible/list:ring-inset';\n\n/** `locale` when the runtime accepts the tag, else `null`. */\nfunction supportedLocale(locale: string): string | null {\n try {\n return locale ? new Intl.Locale(locale).toString() : null;\n } catch {\n return null;\n }\n}\n\n/** A time ('HH:mm' or 'HH:mm:ss') with its seconds, so two times compare as strings. */\nfunction timeKey(time: string): string {\n return time.length === 5 ? `${time}:00` : time;\n}\n\n/** A value of `mode` written so two values compare in time order as strings. */\nfunction comparable(mode: DateTimeMode, value: string): string {\n if (mode === 'date') {\n return value;\n }\n if (mode === 'time') {\n return timeKey(value);\n }\n const [date = '', time = ''] = value.split('T');\n return `${date}T${timeKey(time)}`;\n}\n\n/** A local `Date` of an ISO date, for the `minDate` / `maxDate` validation messages only. */\nfunction localDate(iso: string): Date {\n const parts = parseIsoDate(iso);\n const date = new Date(2000, 0, 1);\n if (parts) {\n date.setFullYear(parts.year, parts.month - 1, parts.day);\n }\n return date;\n}\n\n/**\n * The segmented field behind `bf-date-input`, `bf-time-input` and `bf-datetime-input`: the label,\n * help and error text of `bf-field` around a group of spinbutton parts in the locale's order, a\n * picker button opening a calendar and/or a list of times in an anchored panel, and a native\n * `input` under a coarse pointer when `native` is set. Internal: the public components wrap it\n * and pass every input through.\n */\n@Component({\n selector: 'bf-date-time-field',\n imports: [BfFieldComponent, BfCalendarComponent],\n host: { class: 'block', '(click)': 'onHostClick($event)' },\n template: `\n <bf-field\n [label]=\"label()\"\n [helpText]=\"helpText()\"\n [error]=\"errorText()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n [controlId]=\"id()\"\n >\n @if (nativeMode()) {\n <input\n #nativeInput\n [type]=\"nativeType()\"\n [id]=\"id()\"\n [name]=\"name()\"\n [value]=\"value() ?? ''\"\n [attr.min]=\"validMin()\"\n [attr.max]=\"validMax()\"\n [attr.step]=\"nativeStep()\"\n [disabled]=\"disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [attr.aria-label]=\"ariaLabelAttr()\"\n [attr.aria-labelledby]=\"ariaLabelledbyAttr()\"\n [attr.aria-invalid]=\"showError() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-errormessage]=\"errorMessageId()\"\n [class]=\"nativeClasses()\"\n (change)=\"onNativeChange(nativeInput)\"\n (blur)=\"markLeft()\"\n />\n } @else {\n <div\n #box\n role=\"group\"\n [id]=\"id()\"\n [attr.aria-label]=\"label() || ariaLabelAttr()\"\n [attr.aria-labelledby]=\"ariaLabelledbyAttr()\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n [attr.data-value]=\"value() ?? ''\"\n [class]=\"boxClasses()\"\n (focusout)=\"onFocusout($event)\"\n >\n <div class=\"flex min-w-0 flex-1 items-center whitespace-nowrap\">\n @for (item of segments(); track $index) {\n @if (item.type === 'literal') {\n <span aria-hidden=\"true\" [class]=\"literalClasses()\">{{ item.text }}</span>\n } @else {\n <span\n role=\"spinbutton\"\n [id]=\"item.id\"\n [attr.data-segment]=\"item.kind\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-label]=\"item.name\"\n [attr.aria-valuemin]=\"item.min\"\n [attr.aria-valuemax]=\"item.max\"\n [attr.aria-valuenow]=\"item.now\"\n [attr.aria-valuetext]=\"item.valueText\"\n [attr.aria-invalid]=\"showError() ? 'true' : null\"\n [attr.aria-errormessage]=\"errorMessageId()\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-readonly]=\"readonly() ? 'true' : null\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n [class]=\"segmentClasses(item)\"\n (keydown)=\"onSegmentKeydown($event, item.kind)\"\n (blur)=\"onSegmentBlur(item.kind)\"\n >{{ item.text }}</span\n >\n }\n }\n </div>\n @if (picker()) {\n <button\n #trigger\n type=\"button\"\n [id]=\"id() + '-trigger'\"\n [disabled]=\"disabled() || readonly()\"\n [attr.aria-label]=\"triggerLabel()\"\n aria-haspopup=\"dialog\"\n [attr.aria-expanded]=\"pickerOpen()\"\n [attr.aria-controls]=\"pickerOpen() ? panelId() : null\"\n [attr.data-bf-date-time-trigger]=\"''\"\n [class]=\"triggerClasses()\"\n (click)=\"togglePicker()\"\n >\n <span\n aria-hidden=\"true\"\n [class]=\"mode() === 'time' ? clockMark : calendarMark\"\n ></span>\n </button>\n }\n </div>\n }\n </bf-field>\n\n <ng-template #panel>\n <div\n role=\"dialog\"\n [id]=\"panelId()\"\n [attr.aria-labelledby]=\"id() + '-trigger'\"\n [class]=\"panelClasses()\"\n >\n <div class=\"flex flex-wrap items-start gap-3\">\n @if (mode() !== 'time') {\n <bf-calendar\n [label]=\"label() || ariaLabel() || triggerLabel()\"\n [value]=\"datePart()\"\n [min]=\"calendarMin()\"\n [max]=\"calendarMax()\"\n [disabledDate]=\"disabledDate()\"\n [locale]=\"resolvedLocale()\"\n (picked)=\"onDatePicked($event)\"\n />\n }\n @if (mode() !== 'date') {\n <div\n #list\n role=\"listbox\"\n tabindex=\"0\"\n [id]=\"id() + '-times'\"\n [attr.aria-label]=\"labels.timeInputOpenList\"\n [attr.aria-activedescendant]=\"activeOptionId()\"\n [class]=\"listClasses()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n >\n @for (option of timeOptionViews(); track option.value) {\n <div\n role=\"option\"\n [id]=\"option.id\"\n [attr.data-time]=\"option.value\"\n [attr.aria-selected]=\"option.selected\"\n [attr.aria-disabled]=\"option.disabled ? 'true' : null\"\n [class]=\"optionClasses(option)\"\n >\n {{ option.label }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n </ng-template>\n `,\n})\nexport class BfDateTimeFieldComponent {\n private readonly environment = inject(EnvironmentInjector);\n private readonly document = inject(DOCUMENT);\n private readonly injector = inject(Injector);\n private readonly viewContainer = inject(ViewContainerRef);\n private readonly location = inject(Location);\n private readonly defaults = inject(BF_DEFAULTS);\n private readonly hostEl = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n /** The strings in effect; the template reads the list name from them. */\n protected readonly labels = inject(BF_LABELS);\n\n /** What the field edits: a date, a time of day, or both. */\n readonly mode = input.required<DateTimeMode>();\n /** The ISO value, `null` while empty or incomplete. */\n readonly value = model<string | null>(null);\n /** The earliest valid value (ISO, in the mode's format). */\n readonly min = input<string | undefined>(undefined);\n /** The latest valid value (ISO, in the mode's format). */\n readonly max = input<string | undefined>(undefined);\n /** Dates the calendar shows disabled, and that show an error when typed. */\n readonly disabledDate = input<BfCalendarDisabledDate | null>(null);\n /** Whether the field has a picker button. */\n readonly picker = input(true, { transform: booleanAttribute });\n /** Renders the platform's input under a coarse pointer. */\n readonly native = input(false, { transform: booleanAttribute });\n /** Adds a seconds part (time mode only). */\n readonly seconds = input(false, { transform: booleanAttribute });\n /** Minutes between the times of the list. */\n readonly step = input(30);\n /** Forces a 12- or 24-hour clock; unset follows the locale. */\n readonly hourCycle = input<'h12' | 'h23' | undefined>(undefined);\n /** BCP 47 locale; empty follows the document's `lang`, else English. */\n readonly locale = input('');\n /** Height step; unset follows `fieldSize`. */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name without a visible label. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field without a visible label. */\n readonly ariaLabelledby = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text. */\n readonly errorMessage = input('');\n /** Disables the field. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the value but blocks changes. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute (native mode). */\n readonly name = input('');\n /** The field's id. */\n readonly id = input.required<string>();\n\n /** Emitted with the new value right after a user change. */\n readonly changed = output<string | null>();\n /** Emitted when focus leaves the field (not into its picker). */\n readonly touch = output<void>();\n\n private readonly box = viewChild<ElementRef<HTMLElement>>('box');\n private readonly trigger = viewChild<ElementRef<HTMLButtonElement>>('trigger');\n private readonly panel = viewChild.required<TemplateRef<unknown>>('panel');\n\n /** Whether the primary pointer is coarse (touch), from `matchMedia`. */\n private readonly coarse = signal(false);\n /** Digits typed into the focused segment since it took focus. */\n private readonly typing = signal<Typing | null>(null);\n /** Whether focus has left the field once; its own errors show from then on. */\n private readonly left = signal(false);\n /** Whether the picker panel is open. */\n protected readonly pickerOpen = signal(false);\n /** The time the list's keyboard focus is on. */\n private readonly activeTime = signal<string | null>(null);\n\n protected readonly calendarMark = CALENDAR_MARK;\n protected readonly clockMark = CLOCK_MARK;\n\n protected readonly resolvedSize = computed(() => this.size() ?? this.defaults.fieldSize);\n /** The locale in effect: `locale`, else the document's `lang`, else English. */\n readonly resolvedLocale = computed(\n () =>\n supportedLocale(this.locale()) ?? supportedLocale(this.document.documentElement.lang) ?? 'en',\n );\n /** Whether the field has a seconds part. */\n private readonly hasSeconds = computed(() => this.mode() === 'time' && this.seconds());\n /** The hour cycle in effect: `hourCycle`, else the locale's. */\n readonly cycle = computed<HourCycle>(() =>\n this.mode() === 'date' ? 'h23' : resolveHourCycle(this.resolvedLocale(), this.hourCycle()),\n );\n private readonly kinds = computed(() =>\n segmentKinds(this.mode(), this.hasSeconds(), this.cycle()),\n );\n private readonly layout = computed<LayoutItem[]>(() =>\n segmentLayout(this.resolvedLocale(), this.mode(), this.hasSeconds(), this.cycle()),\n );\n /** The segments in the order they are laid out. */\n private readonly order = computed(() =>\n this.layout().flatMap((item) => (item.type === 'segment' ? [item.kind] : [])),\n );\n private readonly periods = computed(() => dayPeriodNames(this.resolvedLocale()));\n private readonly monthNames = computed(() => {\n const format = new Intl.DateTimeFormat(this.resolvedLocale(), {\n month: 'long',\n timeZone: 'UTC',\n });\n return Array.from({ length: 12 }, (_, i) => format.format(new Date(Date.UTC(2001, i, 1))));\n });\n private readonly formatTime = computed(() =>\n timeFormatter(this.resolvedLocale(), this.cycle(), this.hasSeconds()),\n );\n\n /**\n * The parts on show. They follow `value`; a value the parts already stand for (an incomplete\n * entry is `null`) keeps them, so typing is never undone by its own value.\n */\n private readonly parts = linkedSignal<\n { value: string | null; mode: DateTimeMode; cycle: HourCycle; seconds: boolean },\n SegmentValues\n >({\n source: () => ({\n value: this.value(),\n mode: this.mode(),\n cycle: this.cycle(),\n seconds: this.hasSeconds(),\n }),\n computation: (source, previous) =>\n previous?.source.cycle === source.cycle &&\n previous.source.mode === source.mode &&\n composeValue(source.mode, previous.value, source.cycle, source.seconds) === source.value\n ? previous.value\n : valuesFrom(source.mode, source.value, source.cycle),\n });\n\n private readonly segmentNames = computed<Record<SegmentKind, string>>(() => ({\n day: this.labels.dateInputDay,\n month: this.labels.dateInputMonth,\n year: this.labels.dateInputYear,\n hour: this.labels.timeInputHour,\n minute: this.labels.timeInputMinute,\n second: this.labels.timeInputSecond,\n dayPeriod: this.labels.timeInputDayPeriod,\n }));\n\n /** The layout with each segment's text and ARIA state. */\n protected readonly segments = computed<(SegmentView | LiteralItem)[]>(() => {\n const values = this.parts();\n const typing = this.typing();\n const names = this.segmentNames();\n return this.layout().map((item) => {\n if (item.type === 'literal') {\n return item;\n }\n const kind = item.kind;\n const value = values[kind] ?? null;\n const typed = typing?.kind === kind ? typing.text : '';\n const range = segmentRange(kind, values, this.cycle());\n const text =\n typed ||\n (value === null\n ? segmentPlaceholder(kind, names[kind])\n : segmentText(kind, value, this.periods()));\n return {\n type: 'segment',\n kind,\n id: `${this.id()}-${kind}`,\n name: names[kind],\n text,\n empty: !typed && value === null,\n min: range.min,\n max: range.max,\n now: value,\n valueText: typed || (value === null ? null : this.valueText(kind, value)),\n };\n });\n });\n\n /** The value's date part, for the calendar. */\n protected readonly datePart = computed(() => datePartOf(this.mode(), this.value()));\n /** `min` when it is a valid value of the mode, else `null`. */\n protected readonly validMin = computed(() => this.validBound(this.min()));\n /** `max` when it is a valid value of the mode, else `null`. */\n protected readonly validMax = computed(() => this.validBound(this.max()));\n protected readonly calendarMin = computed(\n () => datePartOf(this.mode(), this.validMin()) ?? undefined,\n );\n protected readonly calendarMax = computed(\n () => datePartOf(this.mode(), this.validMax()) ?? undefined,\n );\n\n /** The field's own error: an incomplete or impossible entry, or a value outside the limits. */\n private readonly ownError = computed(() => {\n const values = this.parts();\n const kinds = this.kinds();\n const date = entryState(dateKindsOf(kinds), values);\n const time = entryState(timeKindsOf(kinds), values);\n if (date === 'empty' && time === 'empty') {\n return '';\n }\n if (this.mode() !== 'time' && (date !== 'filled' || composeDate(values) === null)) {\n return this.labels.dateInputInvalid;\n }\n if (this.mode() !== 'date' && time !== 'filled') {\n return this.labels.timeInputInvalid;\n }\n const value = this.value();\n return value ? this.rangeError(value) : '';\n });\n\n /** The error shown: `errorMessage`, else the field's own once left, else the form's. */\n protected readonly errorText = computed(() => {\n const own = this.left() || this.touched() ? this.ownError() : '';\n return (\n this.errorMessage() ||\n own ||\n fieldErrorText('', this.touched(), this.errors(), this.labels.validation)\n );\n });\n protected readonly showError = computed(() =>\n fieldShowsError(this.errorText(), this.invalid(), this.touched()),\n );\n protected readonly describedBy = computed(() =>\n fieldDescribedBy(this.id(), this.errorText(), this.helpText()),\n );\n protected readonly errorMessageId = computed(() =>\n fieldErrorMessageId(this.id(), this.errorText(), this.showError()),\n );\n protected readonly ariaLabelAttr = computed(() =>\n this.label() ? null : this.ariaLabel() || null,\n );\n protected readonly ariaLabelledbyAttr = computed(() =>\n this.label() ? null : this.ariaLabelledby() || null,\n );\n\n /** Whether the platform's input is rendered instead of the segments. */\n protected readonly nativeMode = computed(() => this.native() && this.coarse());\n protected readonly nativeType = computed(() =>\n this.mode() === 'datetime' ? 'datetime-local' : this.mode(),\n );\n protected readonly nativeStep = computed(() => (this.hasSeconds() ? 1 : null));\n protected readonly nativeClasses = computed(() =>\n bfFieldControlClass({\n size: this.resolvedSize(),\n invalid: this.showError(),\n disabled: this.disabled(),\n readonly: this.readonly(),\n }),\n );\n\n protected readonly triggerLabel = computed(() =>\n this.mode() === 'time' ? this.labels.timeInputOpenList : this.labels.dateInputOpenCalendar,\n );\n protected readonly panelId = computed(() => `${this.id()}-picker`);\n\n protected readonly boxClasses = computed(() => {\n const size = this.resolvedSize();\n const state = this.disabled()\n ? 'cursor-not-allowed border-surface-sunken bg-surface-muted text-text-disabled'\n : [\n this.readonly() ? 'bg-surface-muted text-text' : 'bg-surface text-text cursor-text',\n this.showError()\n ? 'border-danger-border hover:border-danger'\n : 'border-border-strong hover:border-text-muted',\n ].join(' ');\n return [\n BOX_BASE,\n FIELD_BOX[size],\n FIELD_PADDING_START[size].text,\n this.picker() ? PICKER_PADDING_END[size] : FIELD_PADDING_END[size].text,\n state,\n ].join(' ');\n });\n protected readonly literalClasses = computed(() =>\n this.disabled() ? 'whitespace-pre text-text-disabled' : 'whitespace-pre text-text-muted',\n );\n protected readonly triggerClasses = computed(\n () => `${TRIGGER_BASE} ${TRIGGER_SIZE[this.resolvedSize()]}`,\n );\n protected readonly panelClasses = computed(\n () => `${POPOVER_SURFACE} ${this.mode() === 'time' ? 'p-1.5' : 'p-3'}`,\n );\n protected readonly listClasses = computed(() => LIST);\n\n /** The times of the list, with their state. */\n private readonly options = computed(() =>\n timeOptions(this.step(), this.hasSeconds(), this.formatTime()),\n );\n /** The time limits of the list: `min`/`max` of a time, or of a datetime on the limit's day. */\n private readonly timeBounds = computed(() => {\n const mode = this.mode();\n const min = this.validMin();\n const max = this.validMax();\n if (mode === 'time') {\n return { lower: min, upper: max };\n }\n const date = composeDate(this.parts());\n return {\n lower: min && date === datePartOf(mode, min) ? timePartOf(mode, min) : null,\n upper: max && date === datePartOf(mode, max) ? timePartOf(mode, max) : null,\n };\n });\n protected readonly timeOptionViews = computed<TimeOptionView[]>(() => {\n const selected = timePartOf(this.mode(), this.value());\n const active = this.activeTime();\n return this.options().map((option) => ({\n ...option,\n id: `${this.id()}-time-${option.value.replace(/:/g, '')}`,\n disabled: this.timeDisabled(option.value),\n selected: selected !== null && timeKey(selected) === timeKey(option.value),\n active: option.value === active,\n }));\n });\n protected readonly activeOptionId = computed(\n () => this.timeOptionViews().find((option) => option.active)?.id ?? null,\n );\n\n private anchored: AnchoredOverlay | null = null;\n private readonly motion = new AnchoredMotion();\n private subscriptions: Subscription[] = [];\n private stopNavigation: (() => void) | null = null;\n\n constructor() {\n const media = this.document.defaultView?.matchMedia?.('(pointer: coarse)');\n if (media) {\n this.coarse.set(media.matches);\n const onChange = (event: MediaQueryListEvent): void => this.coarse.set(event.matches);\n media.addEventListener?.('change', onChange);\n inject(DestroyRef).onDestroy(() => media.removeEventListener?.('change', onChange));\n }\n inject(DestroyRef).onDestroy(() => {\n this.teardown(false);\n this.motion.flush();\n });\n }\n\n /**\n * Focuses the first empty part (else the first part), or the native input.\n * @param options Passed on to the native `focus()`.\n */\n focus(options?: FocusOptions): void {\n const native = this.hostEl.querySelector<HTMLElement>('input');\n if (native) {\n native.focus(options);\n return;\n }\n const values = this.parts();\n const kind = this.order().find((k) => values[k] === null || values[k] === undefined);\n this.segmentElement(kind ?? this.order()[0])?.focus(options);\n }\n\n /** Opens the picker panel; does nothing while it is open, disabled or read-only. */\n openPicker(): void {\n const box = this.box()?.nativeElement;\n if (this.anchored || !box || !this.picker() || this.disabled() || this.readonly()) {\n return;\n }\n // A panel still playing its exit goes now: never two panels with the same id.\n this.motion.flush();\n const direction = getComputedStyle(box).direction === 'rtl' ? 'rtl' : 'ltr';\n const anchored = createAnchoredOverlay(this.environment, box, {\n positions: blockPositions('below-start'),\n direction,\n panelClass: ['bf-date-time-panel'],\n });\n this.anchored = anchored;\n this.activeTime.set(this.initialTime());\n const view = anchored.ref.attach(\n new TemplatePortal(this.panel(), this.viewContainer, undefined, this.injector),\n );\n const pane = anchored.ref.overlayElement;\n this.subscriptions = [\n // The CDK hands a key to the topmost overlay: a dialog underneath stays open.\n anchored.ref.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.closePicker();\n }\n }),\n anchored.ref.outsidePointerEvents().subscribe((event) => {\n // A click on the button toggles the panel itself.\n const trigger = this.trigger()?.nativeElement;\n if (trigger && event.target instanceof Node && trigger.contains(event.target)) {\n return;\n }\n // Focus returns only when it would otherwise be lost: a click on a part keeps it there.\n const active = this.document.activeElement;\n this.closePicker(!active || active === this.document.body || pane.contains(active));\n }),\n ];\n pane.addEventListener('keydown', (event) => this.tabbed(event, pane));\n this.stopNavigation = watchPathChange(this.location, () => this.closePicker(false));\n this.pickerOpen.set(true);\n this.motion.enter(anchored.ref, box, view);\n afterNextRender(() => this.focusPanel(pane), { injector: this.injector });\n }\n\n /**\n * Closes the picker panel; does nothing while it is closed.\n * @param restoreFocus Moves focus back to the picker button (default true).\n */\n closePicker(restoreFocus = true): void {\n if (!this.anchored) {\n return;\n }\n this.teardown(true);\n this.pickerOpen.set(false);\n if (restoreFocus) {\n this.trigger()?.nativeElement.focus({ preventScroll: true });\n } else if (!this.hostEl.contains(this.document.activeElement)) {\n this.markLeft();\n }\n }\n\n /**\n * The picker button: opens the panel, or closes it when open.\n * @internal\n */\n togglePicker(): void {\n if (this.anchored) {\n this.closePicker();\n } else {\n this.openPicker();\n }\n }\n\n /**\n * A click on the label or on the field box outside the parts focuses the first empty part.\n * @internal\n */\n onHostClick(event: MouseEvent): void {\n const target = event.target;\n if (this.disabled() || this.nativeMode() || !(target instanceof Element)) {\n return;\n }\n if (target.closest('[data-segment], button')) {\n return;\n }\n if (target.closest('label') || this.box()?.nativeElement.contains(target)) {\n this.focus();\n }\n }\n\n /**\n * The keys of one part: digits type, arrows step and move, Backspace clears.\n * @internal\n */\n onSegmentKeydown(event: KeyboardEvent, kind: SegmentKind): void {\n if (event.ctrlKey || event.metaKey) {\n return;\n }\n const key = event.key;\n if (event.altKey) {\n if (key === 'ArrowDown' && this.picker()) {\n event.preventDefault();\n this.openPicker();\n }\n return;\n }\n const editable = !this.disabled() && !this.readonly();\n if (key === 'ArrowLeft' || key === 'ArrowRight') {\n event.preventDefault();\n const rtl = getComputedStyle(event.target as Element).direction === 'rtl';\n this.moveFocus(kind, (key === 'ArrowRight') !== rtl ? 1 : -1);\n return;\n }\n if (!editable) {\n return;\n }\n if (key === 'ArrowUp' || key === 'ArrowDown') {\n event.preventDefault();\n this.typing.set(null);\n const values = this.parts();\n const today = Number(localIsoDate().slice(0, 4));\n const delta = key === 'ArrowUp' ? 1 : -1;\n this.writeParts({ ...values, [kind]: stepSegment(kind, values, delta, this.cycle(), today) });\n } else if (key === 'Backspace' || key === 'Delete') {\n event.preventDefault();\n this.clearSegment(kind, key === 'Backspace');\n } else if (/^\\d$/.test(key) && kind !== 'dayPeriod') {\n event.preventDefault();\n this.typeInto(kind, key);\n } else if (kind === 'dayPeriod' && key.length === 1) {\n const locale = this.resolvedLocale();\n const typed = key.toLocaleLowerCase(locale);\n const period = this.periods().findIndex((name) =>\n name.toLocaleLowerCase(locale).startsWith(typed),\n );\n if (period >= 0) {\n event.preventDefault();\n this.writeParts({ ...this.parts(), dayPeriod: period });\n }\n } else if (key.length === 1 && /[\\s./\\-:,]/.test(key)) {\n // A separator moves on from a part that holds something, as typing \"14/\" would.\n event.preventDefault();\n if (this.typing()?.kind === kind || (this.parts()[kind] ?? null) !== null) {\n this.moveFocus(kind, 1);\n }\n }\n }\n\n /**\n * Leaving a part commits what was typed into it (\"26\" in the year is 2026).\n * @internal\n */\n onSegmentBlur(kind: SegmentKind): void {\n const typing = this.typing();\n if (typing?.kind !== kind) {\n return;\n }\n this.typing.set(null);\n const values = this.parts();\n this.writeParts({ ...values, [kind]: commitTyped(kind, typing.text, values, this.cycle()) });\n }\n\n /**\n * Focus leaving the field (not into its picker) marks it touched.\n * @internal\n */\n onFocusout(event: FocusEvent): void {\n const next = event.relatedTarget;\n if (next instanceof Node && this.box()?.nativeElement.contains(next)) {\n return;\n }\n if (\n this.pickerOpen() ||\n (next instanceof Node && this.anchored?.ref.overlayElement.contains(next))\n ) {\n return;\n }\n this.markLeft();\n }\n\n /**\n * Marks the field left and touched.\n * @internal\n */\n markLeft(): void {\n this.left.set(true);\n this.touch.emit();\n }\n\n /**\n * The native input's value, written to the model.\n * @internal\n */\n onNativeChange(el: HTMLInputElement): void {\n const raw = el.value;\n const mode = this.mode();\n const value =\n mode === 'datetime'\n ? raw.slice(0, 16)\n : mode === 'time' && !this.hasSeconds()\n ? raw.slice(0, 5)\n : raw;\n const next = this.validBound(value);\n if (next !== this.value()) {\n this.value.set(next);\n this.changed.emit(next);\n }\n }\n\n /**\n * The calendar's pick: the date in a date input (closing the panel), the date part in a\n * datetime input (moving on to the time list).\n * @internal\n */\n onDatePicked(iso: string): void {\n this.typing.set(null);\n this.writeParts({ ...this.parts(), ...dateValues(iso) });\n if (this.mode() === 'date') {\n this.closePicker();\n return;\n }\n this.activeTime.set(this.initialTime());\n const pane = this.anchored?.ref.overlayElement;\n if (pane) {\n afterNextRender(() => this.focusList(pane), { injector: this.injector });\n }\n }\n\n /**\n * Picks a time from the list and closes the panel; ignored for a disabled time.\n * @internal\n */\n pickTime(time: string): void {\n if (this.timeDisabled(time)) {\n return;\n }\n this.typing.set(null);\n this.writeParts({ ...this.parts(), ...timeValuesOf(time, this.cycle()) });\n this.closePicker();\n }\n\n /**\n * A click on a time of the list picks it.\n * @internal\n */\n onListClick(event: MouseEvent): void {\n const option =\n event.target instanceof Element ? event.target.closest<HTMLElement>('[data-time]') : null;\n const time = option?.dataset['time'];\n if (time) {\n this.pickTime(time);\n }\n }\n\n /**\n * The list's keys: arrows, Home and End move, Enter and Space pick.\n * @internal\n */\n onListKeydown(event: KeyboardEvent): void {\n const enabled = this.timeOptionViews().filter((option) => !option.disabled);\n const index = enabled.findIndex((option) => option.active);\n let next: TimeOptionView | undefined;\n switch (event.key) {\n case 'ArrowDown':\n next = enabled[Math.min(index + 1, enabled.length - 1)];\n break;\n case 'ArrowUp':\n next = enabled[Math.max(index - 1, 0)];\n break;\n case 'Home':\n next = enabled[0];\n break;\n case 'End':\n next = enabled[enabled.length - 1];\n break;\n case 'Enter':\n case ' ': {\n event.preventDefault();\n const active = this.activeTime();\n if (active) {\n this.pickTime(active);\n }\n return;\n }\n default:\n return;\n }\n event.preventDefault();\n if (next) {\n this.activeTime.set(next.value);\n const list = event.currentTarget as HTMLElement;\n afterNextRender(() => this.scrollToActive(list, false), { injector: this.injector });\n }\n }\n\n /** @internal */\n segmentClasses(item: SegmentView): string {\n return item.empty && !this.disabled() ? `${SEGMENT} text-text-muted` : SEGMENT;\n }\n\n /** @internal */\n optionClasses(option: TimeOptionView): string {\n const state: OptionState = option.disabled\n ? 'disabled'\n : option.selected\n ? 'selected'\n : 'normal';\n const active = option.active\n ? ` ${OPTION_ACTIVE}${state === 'normal' ? ' bg-surface-muted' : ''}`\n : '';\n return `${OPTION} ${OPTION_STATE[state]}${active}`;\n }\n\n private valueText(kind: SegmentKind, value: number): string {\n if (kind === 'month') {\n return this.monthNames()[value - 1] ?? String(value);\n }\n if (kind === 'dayPeriod') {\n return this.periods()[value] ?? String(value);\n }\n return String(value);\n }\n\n /** `bound` when it is a valid value of the mode, else `null`. */\n private validBound(bound: string | null | undefined): string | null {\n const mode = this.mode();\n if (!bound) {\n return null;\n }\n if (mode === 'date') {\n return datePartOf(mode, bound);\n }\n if (mode === 'time') {\n return parseIsoTime(bound) ? bound : null;\n }\n return datePartOf(mode, bound) && timePartOf(mode, bound) && bound.length >= 16 ? bound : null;\n }\n\n /** The error for a complete value outside `min`…`max` or ruled out by `disabledDate`. */\n private rangeError(value: string): string {\n const mode = this.mode();\n const validation = this.labels.validation;\n const date = datePartOf(mode, value);\n if (date && this.disabledDate()?.(date)) {\n return this.labels.dateInputUnavailable;\n }\n const min = this.validMin();\n const max = this.validMax();\n const below = min !== null && comparable(mode, value) < comparable(mode, min);\n const above = max !== null && comparable(mode, value) > comparable(mode, max);\n const limit = below ? min : above ? max : null;\n if (!limit) {\n return '';\n }\n const limitDate = datePartOf(mode, limit);\n if (limitDate && (mode === 'date' || date !== limitDate)) {\n return below\n ? validation.minDate(localDate(limitDate))\n : validation.maxDate(localDate(limitDate));\n }\n const time = this.formatTime()(timePartOf(mode, limit) ?? limit);\n return below ? this.labels.timeInputMin(time) : this.labels.timeInputMax(time);\n }\n\n private timeDisabled(time: string): boolean {\n const { lower, upper } = this.timeBounds();\n return (\n (lower !== null && timeKey(time) < timeKey(lower)) ||\n (upper !== null && timeKey(time) > timeKey(upper))\n );\n }\n\n /** The list's first active time: the value's, else the first time from now on (or from it). */\n private initialTime(): string | null {\n const options = this.options().filter((option) => !this.timeDisabled(option.value));\n const selected = timePartOf(this.mode(), this.value());\n const now = new Date();\n const from = timeKey(\n selected ??\n `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`,\n );\n return (\n options.find((option) => timeKey(option.value) >= from)?.value ??\n options[options.length - 1]?.value ??\n null\n );\n }\n\n private writeParts(values: SegmentValues): void {\n this.parts.set(values);\n const next = composeValue(this.mode(), values, this.cycle(), this.hasSeconds());\n if (next !== this.value()) {\n this.value.set(next);\n this.changed.emit(next);\n }\n }\n\n private typeInto(kind: SegmentKind, digit: string): void {\n const typing = this.typing();\n const text = typing?.kind === kind ? typing.text : '';\n const values = this.parts();\n const typed = typeDigit(kind, text, digit, values, this.cycle());\n // The part takes its value once it is complete; until then the digits show as typed, so \"3\"\n // on the way to \"30\" minutes never reaches the value. Leaving the part commits them.\n if (typed.advance) {\n this.typing.set(null);\n this.writeParts({ ...values, [kind]: typed.value });\n this.moveFocus(kind, 1);\n } else {\n this.typing.set({ kind, text: typed.text });\n }\n }\n\n private clearSegment(kind: SegmentKind, backspace: boolean): void {\n const typing = this.typing();\n const values = this.parts();\n this.typing.set(null);\n const empty = (values[kind] ?? null) === null && typing?.kind !== kind;\n if (empty && backspace) {\n this.moveFocus(kind, -1);\n return;\n }\n this.writeParts({ ...values, [kind]: null });\n }\n\n private moveFocus(kind: SegmentKind, offset: number): void {\n const order = this.order();\n const next = order[order.indexOf(kind) + offset];\n if (next) {\n this.segmentElement(next)?.focus();\n }\n }\n\n private segmentElement(kind: SegmentKind | undefined): HTMLElement | null {\n return kind\n ? (this.box()?.nativeElement.querySelector<HTMLElement>(`[data-segment=\"${kind}\"]`) ?? null)\n : null;\n }\n\n /** Focus on open: the calendar's tab stop day, else the time list. */\n private focusPanel(pane: HTMLElement): void {\n const day = pane.querySelector<HTMLElement>('[data-bf-calendar-grid] td[tabindex=\"0\"]');\n const list = pane.querySelector<HTMLElement>('[role=\"listbox\"]');\n if (list) {\n this.scrollToActive(list, true);\n }\n (day ?? list)?.focus({ preventScroll: true });\n }\n\n private focusList(pane: HTMLElement): void {\n const list = pane.querySelector<HTMLElement>('[role=\"listbox\"]');\n if (list) {\n this.scrollToActive(list, true);\n list.focus({ preventScroll: true });\n }\n }\n\n /** Scrolls the list (not the page) so the active time shows: centred, or just inside. */\n private scrollToActive(list: HTMLElement, center: boolean): void {\n const option = list.querySelector<HTMLElement>(`[id=\"${this.activeOptionId() ?? ''}\"]`);\n if (!option) {\n return;\n }\n const top = option.offsetTop;\n const bottom = top + option.offsetHeight;\n if (center) {\n list.scrollTop = top - (list.clientHeight - option.offsetHeight) / 2;\n } else if (top < list.scrollTop) {\n list.scrollTop = top;\n } else if (bottom > list.scrollTop + list.clientHeight) {\n list.scrollTop = bottom - list.clientHeight;\n }\n }\n\n /**\n * `Tab` is not trapped: past the panel's last control it closes the panel onto the picker\n * button (the browser then moves on from it); `Shift+Tab` before the first control closes it\n * onto the button.\n */\n private tabbed(event: KeyboardEvent, pane: HTMLElement): void {\n if (event.key !== 'Tab') {\n return;\n }\n const stops = Array.from(pane.querySelectorAll<HTMLElement>(TABBABLE)).filter(\n (el) => !el.closest('[inert]') && !el.hidden,\n );\n const active = this.document.activeElement;\n const leaving = event.shiftKey\n ? !stops.length || active === stops[0]\n : !stops.length || active === stops[stops.length - 1];\n if (!leaving) {\n return;\n }\n if (event.shiftKey) {\n event.preventDefault();\n }\n this.closePicker(true);\n }\n\n /**\n * Drops the listeners and closes the overlay: with its exit animation (it stays attached, inert,\n * until the exit has played), or at once when the field is destroyed.\n */\n private teardown(animate: boolean): void {\n this.subscriptions.forEach((s) => s.unsubscribe());\n this.subscriptions = [];\n this.stopNavigation?.();\n this.stopNavigation = null;\n const ref = this.anchored?.ref;\n this.anchored = null;\n const box = this.box()?.nativeElement;\n if (ref && animate && box) {\n this.motion.leave(ref, box);\n } else {\n ref?.dispose();\n }\n }\n}\n","import { Component, booleanAttribute, input, model, output, viewChild } from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport { type BfCalendarDisabledDate, type BfSize, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfDateTimeFieldComponent } from '../date-time-core/date-time-field.component';\n\n/**\n * How `bf-date-input` picks a date besides typing: `calendar` adds a button that opens a\n * `bf-calendar` in a popover, `none` keeps the field typed only.\n *\n * @summary Whether a date input offers a calendar popover besides typing\n * @since 0.3.1\n */\nexport type BfDateInputPicker = 'calendar' | 'none';\n\n/**\n * Date field typed part by part (day, month and year in the locale's order) with a calendar\n * popover, valued as an ISO date string and bound like any other field.\n *\n * @example\n * <bf-date-input label=\"Due date\" min=\"2026-01-01\" [(value)]=\"due\" />\n * <bf-date-input label=\"Birthday\" picker=\"none\" [formField]=\"profile.birthday\" />\n * @summary Typed date field with a calendar popover, valued as an ISO date string\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-date-input',\n imports: [BfDateTimeFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-date-time-field\n mode=\"date\"\n [id]=\"id()\"\n [(value)]=\"value\"\n [min]=\"min()\"\n [max]=\"max()\"\n [disabledDate]=\"disabledDate()\"\n [picker]=\"picker() === 'calendar'\"\n [native]=\"native()\"\n [locale]=\"locale()\"\n [size]=\"size()\"\n [label]=\"label()\"\n [ariaLabel]=\"ariaLabel()\"\n [ariaLabelledby]=\"ariaLabelledby()\"\n [helpText]=\"helpText()\"\n [errorMessage]=\"errorMessage()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [invalid]=\"invalid()\"\n [touched]=\"touched()\"\n [errors]=\"errors()\"\n [name]=\"name()\"\n (changed)=\"changed.emit($event)\"\n (touch)=\"touch.emit()\"\n />\n `,\n})\nexport class BfDateInputComponent implements FormValueControl<string | null> {\n /** The date as an ISO string ('YYYY-MM-DD'), `null` while empty or incomplete; two-way bindable\n * and bound by `[formField]`. */\n readonly value = model<string | null>(null);\n /** The earliest valid date (ISO): earlier dates show an error, and the calendar stops there. */\n readonly min = input<string | undefined>(undefined);\n /** The latest valid date (ISO): later dates show an error, and the calendar stops there. */\n readonly max = input<string | undefined>(undefined);\n /** Rules out more dates (weekends, booked days): disabled in the calendar, an error when typed. */\n readonly disabledDate = input<BfCalendarDisabledDate | null>(null);\n /** `calendar` adds the button that opens a calendar popover; `none` keeps the field typed only. */\n readonly picker = input<BfDateInputPicker>('calendar');\n /** Renders the platform's date picker (`input type=\"date\"`) under a coarse pointer (touch). */\n readonly native = input(false, { transform: booleanAttribute });\n /** BCP 47 locale of the part order, the separators and the calendar; empty follows the\n * document's `lang`, else English. */\n readonly locale = input('');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`\n * by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over the field's own errors and Signal Forms errors. */\n readonly errorMessage = input('');\n /** Disables the field and its calendar button. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the date but blocks changes; the parts stay focusable and expose `aria-readonly`. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the platform input (`native` under a coarse pointer). */\n readonly name = input('');\n /** Field id; generated when not set. */\n readonly id = input(uniqueId('bf-date-input'));\n\n /** Emitted with the new date right after a user change: `null` once it is cleared or incomplete. */\n readonly changed = output<string | null>();\n /** Emitted when focus leaves the field (not into its calendar), so Signal Forms marks it touched. */\n readonly touch = output<void>();\n\n private readonly field = viewChild.required(BfDateTimeFieldComponent);\n\n /**\n * Focuses the first empty part (else the first part); Signal Forms calls it from\n * `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.field().focus(options);\n }\n\n /** Opens the calendar popover; does nothing without a picker, or while disabled or read-only. */\n openPicker(): void {\n this.field().openPicker();\n }\n\n /** Closes the calendar popover, focus back on its button; does nothing while it is closed. */\n closePicker(): void {\n this.field().closePicker();\n }\n}\n","import {\n Component,\n booleanAttribute,\n input,\n model,\n numberAttribute,\n output,\n viewChild,\n} from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport { type BfSize, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfDateTimeFieldComponent } from '../date-time-core/date-time-field.component';\n\n/**\n * How `bf-time-input` picks a time besides typing: `list` adds a button that opens a list of\n * times every `step` minutes, `none` keeps the field typed only.\n *\n * @summary Whether a time input offers a popover list of times besides typing\n * @since 0.3.1\n */\nexport type BfTimeInputPicker = 'list' | 'none';\n\n/**\n * The clock of a time field: `h12` counts 1–12 with an AM/PM part, `h23` counts 0–23.\n *\n * @summary A twelve-hour clock with AM and PM, or a twenty-four-hour clock\n * @since 0.3.1\n */\nexport type BfTimeInputHourCycle = 'h12' | 'h23';\n\n/**\n * Time field typed part by part (hour, minute, optional seconds, AM/PM under a 12-hour clock)\n * with a popover list of times, valued as an ISO time string.\n *\n * @example\n * <bf-time-input label=\"Start\" [step]=\"15\" [(value)]=\"start\" />\n * <bf-time-input label=\"Alarm\" hourCycle=\"h12\" [formField]=\"settings.alarm\" />\n * @summary Typed time-of-day field with a popover list of times, valued as an ISO string\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-time-input',\n imports: [BfDateTimeFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-date-time-field\n mode=\"time\"\n [id]=\"id()\"\n [(value)]=\"value\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\"\n [seconds]=\"seconds()\"\n [hourCycle]=\"hourCycle()\"\n [picker]=\"picker() === 'list'\"\n [native]=\"native()\"\n [locale]=\"locale()\"\n [size]=\"size()\"\n [label]=\"label()\"\n [ariaLabel]=\"ariaLabel()\"\n [ariaLabelledby]=\"ariaLabelledby()\"\n [helpText]=\"helpText()\"\n [errorMessage]=\"errorMessage()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [invalid]=\"invalid()\"\n [touched]=\"touched()\"\n [errors]=\"errors()\"\n [name]=\"name()\"\n (changed)=\"changed.emit($event)\"\n (touch)=\"touch.emit()\"\n />\n `,\n})\nexport class BfTimeInputComponent implements FormValueControl<string | null> {\n /** The time as an ISO string ('HH:mm', 'HH:mm:ss' with `seconds`), `null` while empty or\n * incomplete; two-way bindable and bound by `[formField]`. */\n readonly value = model<string | null>(null);\n /** The earliest valid time ('HH:mm'): earlier times show an error and are disabled in the list. */\n readonly min = input<string | undefined>(undefined);\n /** The latest valid time ('HH:mm'): later times show an error and are disabled in the list. */\n readonly max = input<string | undefined>(undefined);\n /** Minutes between the times of the list, from midnight (1–720). */\n readonly step = input(30, { transform: numberAttribute });\n /** Adds a seconds part; the value becomes 'HH:mm:ss'. */\n readonly seconds = input(false, { transform: booleanAttribute });\n /** Forces a 12-hour (`h12`, with AM/PM) or 24-hour (`h23`) clock; unset follows the locale. */\n readonly hourCycle = input<BfTimeInputHourCycle | undefined>(undefined);\n /** `list` adds the button that opens the list of times; `none` keeps the field typed only. */\n readonly picker = input<BfTimeInputPicker>('list');\n /** Renders the platform's time picker (`input type=\"time\"`) under a coarse pointer (touch). */\n readonly native = input(false, { transform: booleanAttribute });\n /** BCP 47 locale of the part order, the separators, the clock and the AM/PM names; empty\n * follows the document's `lang`, else English. */\n readonly locale = input('');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`\n * by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over the field's own errors and Signal Forms errors. */\n readonly errorMessage = input('');\n /** Disables the field and its list button. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the time but blocks changes; the parts stay focusable and expose `aria-readonly`. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the platform input (`native` under a coarse pointer). */\n readonly name = input('');\n /** Field id; generated when not set. */\n readonly id = input(uniqueId('bf-time-input'));\n\n /** Emitted with the new time right after a user change: `null` once it is cleared or incomplete. */\n readonly changed = output<string | null>();\n /** Emitted when focus leaves the field (not into its list), so Signal Forms marks it touched. */\n readonly touch = output<void>();\n\n private readonly field = viewChild.required(BfDateTimeFieldComponent);\n\n /**\n * Focuses the first empty part (else the first part); Signal Forms calls it from\n * `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.field().focus(options);\n }\n\n /** Opens the list of times; does nothing without a picker, or while disabled or read-only. */\n openPicker(): void {\n this.field().openPicker();\n }\n\n /** Closes the list of times, focus back on its button; does nothing while it is closed. */\n closePicker(): void {\n this.field().closePicker();\n }\n}\n","import {\n Component,\n booleanAttribute,\n input,\n model,\n numberAttribute,\n output,\n viewChild,\n} from '@angular/core';\nimport { type FormValueControl, type ValidationError } from '@angular/forms/signals';\nimport { type BfCalendarDisabledDate, type BfSize, ɵuniqueId as uniqueId } from '@bitforgehq/ui';\nimport { BfDateTimeFieldComponent } from '../date-time-core/date-time-field.component';\nimport { type BfTimeInputHourCycle } from '../time-input/time-input.component';\n\n/**\n * How `bf-datetime-input` picks a date and time besides typing: `popover` adds a button that\n * opens a calendar and a list of times side by side, `none` keeps the field typed only.\n *\n * @summary Whether a date and time input offers a calendar and time list popover\n * @since 0.3.1\n */\nexport type BfDateTimeInputPicker = 'popover' | 'none';\n\n/**\n * Date and time field typed part by part, with a popover holding a calendar and a list of\n * times, valued as a local ISO date and time without a zone.\n *\n * @example\n * <bf-datetime-input label=\"Meeting\" [step]=\"15\" [(value)]=\"meeting\" />\n * <bf-datetime-input label=\"Publish at\" [formField]=\"post.publishAt\" />\n * @summary Typed date and time field with a calendar and time list in one popover\n * @category Forms\n * @since 0.3.1\n */\n@Component({\n selector: 'bf-datetime-input',\n imports: [BfDateTimeFieldComponent],\n host: { class: 'block', '[attr.id]': 'null' },\n template: `\n <bf-date-time-field\n mode=\"datetime\"\n [id]=\"id()\"\n [(value)]=\"value\"\n [min]=\"min()\"\n [max]=\"max()\"\n [disabledDate]=\"disabledDate()\"\n [step]=\"step()\"\n [hourCycle]=\"hourCycle()\"\n [picker]=\"picker() === 'popover'\"\n [native]=\"native()\"\n [locale]=\"locale()\"\n [size]=\"size()\"\n [label]=\"label()\"\n [ariaLabel]=\"ariaLabel()\"\n [ariaLabelledby]=\"ariaLabelledby()\"\n [helpText]=\"helpText()\"\n [errorMessage]=\"errorMessage()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [invalid]=\"invalid()\"\n [touched]=\"touched()\"\n [errors]=\"errors()\"\n [name]=\"name()\"\n (changed)=\"changed.emit($event)\"\n (touch)=\"touch.emit()\"\n />\n `,\n})\nexport class BfDateTimeInputComponent implements FormValueControl<string | null> {\n /** The local date and time as an ISO string without a zone ('YYYY-MM-DDTHH:mm'), `null` while\n * empty or incomplete; two-way bindable and bound by `[formField]`. */\n readonly value = model<string | null>(null);\n /** The earliest valid date and time ('YYYY-MM-DDTHH:mm'): earlier values show an error, and the\n * calendar and the list stop there. */\n readonly min = input<string | undefined>(undefined);\n /** The latest valid date and time ('YYYY-MM-DDTHH:mm'): later values show an error, and the\n * calendar and the list stop there. */\n readonly max = input<string | undefined>(undefined);\n /** Rules out more dates (weekends, booked days): disabled in the calendar, an error when typed. */\n readonly disabledDate = input<BfCalendarDisabledDate | null>(null);\n /** Minutes between the times of the list, from midnight (1–720). */\n readonly step = input(30, { transform: numberAttribute });\n /** Forces a 12-hour (`h12`, with AM/PM) or 24-hour (`h23`) clock; unset follows the locale. */\n readonly hourCycle = input<BfTimeInputHourCycle | undefined>(undefined);\n /** `popover` adds the button that opens the calendar and the time list; `none` keeps the field\n * typed only. */\n readonly picker = input<BfDateTimeInputPicker>('popover');\n /** Renders the platform's picker (`input type=\"datetime-local\"`) under a coarse pointer (touch). */\n readonly native = input(false, { transform: booleanAttribute });\n /** BCP 47 locale of the part order, the separators, the clock and the calendar; empty follows\n * the document's `lang`, else English. */\n readonly locale = input('');\n /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`\n * by default). */\n readonly size = input<BfSize | undefined>(undefined);\n /** Visible label above the field. */\n readonly label = input('');\n /** Accessible name when no visible label is rendered. Ignored when `label` is set. */\n readonly ariaLabel = input('');\n /** Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when\n * `label` is set. */\n readonly ariaLabelledby = input('');\n /** Helper text under the field. */\n readonly helpText = input('');\n /** Explicit error text; takes precedence over the field's own errors and Signal Forms errors. */\n readonly errorMessage = input('');\n /** Disables the field and its picker button. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Shows the value but blocks changes; the parts stay focusable and expose `aria-readonly`. */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Marks the field required. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Field validity from Signal Forms. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Whether the user has left the field. */\n readonly touched = input(false, { transform: booleanAttribute });\n /** Validation errors from Signal Forms. */\n readonly errors = input<readonly ValidationError.WithOptionalFieldTree[]>([]);\n /** Native name attribute of the platform input (`native` under a coarse pointer). */\n readonly name = input('');\n /** Field id; generated when not set. */\n readonly id = input(uniqueId('bf-datetime-input'));\n\n /** Emitted with the new value right after a user change: `null` once it is cleared or\n * incomplete. */\n readonly changed = output<string | null>();\n /** Emitted when focus leaves the field (not into its popover), so Signal Forms marks it touched. */\n readonly touch = output<void>();\n\n private readonly field = viewChild.required(BfDateTimeFieldComponent);\n\n /**\n * Focuses the first empty part (else the first part); Signal Forms calls it from\n * `focusBoundControl()`.\n * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.\n */\n focus(options?: FocusOptions): void {\n this.field().focus(options);\n }\n\n /** Opens the calendar and time popover; does nothing without a picker, or while disabled or\n * read-only. */\n openPicker(): void {\n this.field().openPicker();\n }\n\n /** Closes the popover, focus back on its button; does nothing while it is closed. */\n closePicker(): void {\n this.field().closePicker();\n }\n}\n","/**\n * Open and close motion of `bf-image-viewer`, internal to the overlay entry. The image's frame\n * zooms out of the clicked thumbnail (a FLIP: it starts scaled and moved onto the thumbnail's box,\n * cropped to it as the thumbnail crops the picture, and runs to its own box) while the scrim and\n * the controls fade in; closing runs it backwards when the thumbnail is still on screen, else the\n * viewer fades out. 260 ms on the overlay curve (`--ease-ios`). Under reduced motion every open and\n * close is the overlay core's 150 ms opacity fade. Built on `animateOrSettle`, so where the Web\n * Animations API is missing (jsdom) each one settles at once.\n */\nimport { OVERLAY_DURATION, OVERLAY_EASING, OVERLAY_REDUCED_DURATION } from '../core/motion';\nimport { animateOrSettle } from '../core/overlay-animations';\n\n/** The elements one open or close animates. */\nexport interface ViewerParts {\n /** The viewer's host, faded as a whole when there is no thumbnail to zoom from. */\n host: HTMLElement;\n /** The image's frame, zoomed from and to the thumbnail. */\n frame: HTMLElement;\n /** The scrim and the controls, faded around the zoom. */\n chrome: readonly HTMLElement[];\n}\n\n/** True when `rect` has a size and at least a part of it is inside the viewport. */\nexport function onScreen(rect: DOMRect, view: Window | null): boolean {\n if (!view || rect.width <= 0 || rect.height <= 0) {\n return false;\n }\n return (\n rect.bottom > 0 && rect.right > 0 && rect.top < view.innerHeight && rect.left < view.innerWidth\n );\n}\n\n/**\n * The frame's keyframe on `origin`: scaled to cover the thumbnail's box, centred on it and\n * cropped to it (the thumbnail's corner radius too), or null when either box has no size.\n */\nexport function zoomedFrame(frame: DOMRect, origin: DOMRect, radius: number): Keyframe | null {\n if (frame.width <= 0 || frame.height <= 0 || origin.width <= 0 || origin.height <= 0) {\n return null;\n }\n const scale = Math.max(origin.width / frame.width, origin.height / frame.height);\n const dx = origin.left + origin.width / 2 - (frame.left + frame.width / 2);\n const dy = origin.top + origin.height / 2 - (frame.top + frame.height / 2);\n // In the frame's own (unscaled) pixels: the part that lands on the thumbnail stays visible.\n const insetX = Math.max(0, (frame.width - origin.width / scale) / 2);\n const insetY = Math.max(0, (frame.height - origin.height / scale) / 2);\n const round = radius > 0 ? radius / scale : 0;\n return {\n transform: `translate(${dx}px, ${dy}px) scale(${scale})`,\n clipPath: `inset(${insetY}px ${insetX}px round ${round}px)`,\n };\n}\n\nconst OPEN_FRAME: Keyframe = { transform: 'none', clipPath: 'inset(0px 0px round 0px)' };\n\nfunction fade(el: HTMLElement, entering: boolean, duration: number, easing: string): Animation {\n return animateOrSettle(\n el,\n entering ? [{ opacity: 0 }, { opacity: 1 }] : [{ opacity: 1 }, { opacity: 0 }],\n {\n duration,\n easing,\n // Entering holds the first frame until it starts; leaving holds the last until detached.\n fill: entering ? 'backwards' : 'forwards',\n },\n );\n}\n\n/**\n * Plays the open or the close of the viewer and returns the animation to wait for: the zoom from\n * or to `origin` when it is given and on screen, else a fade of the whole viewer.\n */\nexport function playViewerMotion(\n parts: ViewerParts,\n origin: HTMLElement | null,\n entering: boolean,\n reduced: boolean,\n): Animation {\n if (reduced) {\n return fade(parts.host, entering, OVERLAY_REDUCED_DURATION, 'linear');\n }\n const view = parts.host.ownerDocument.defaultView;\n const originRect = origin?.isConnected ? origin.getBoundingClientRect() : null;\n const zoomed =\n origin && originRect && onScreen(originRect, view)\n ? zoomedFrame(parts.frame.getBoundingClientRect(), originRect, radiusOf(origin, view))\n : null;\n if (!zoomed) {\n return fade(parts.host, entering, OVERLAY_DURATION, OVERLAY_EASING);\n }\n for (const el of parts.chrome) {\n fade(el, entering, OVERLAY_DURATION, OVERLAY_EASING);\n }\n return animateOrSettle(parts.frame, entering ? [zoomed, OPEN_FRAME] : [OPEN_FRAME, zoomed], {\n duration: OVERLAY_DURATION,\n easing: OVERLAY_EASING,\n fill: entering ? 'backwards' : 'forwards',\n });\n}\n\n/** The thumbnail's top-start corner radius in px (0 when it has none or it cannot be read). */\nfunction radiusOf(origin: HTMLElement, view: Window | null): number {\n const value = view?.getComputedStyle(origin).borderTopLeftRadius ?? '';\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n","import {\n InjectionToken,\n type Signal,\n type TemplateRef,\n type WritableSignal,\n signal,\n} from '@angular/core';\nimport { type BfOverlayRef } from '../core/overlay-ref';\n\n/**\n * One image of a `BfImageViewerService.open()` set.\n *\n * @summary One image the viewer shows: its URL, its name as alternative text and a caption\n * @since 0.5.0\n */\nexport interface BfImageViewerImage {\n /** URL of the full-size image. */\n src: string;\n /**\n * The image's name: its alternative text (`alt`), read when it shows and announced after a step\n * (required: the viewer shows nothing else that names it).\n */\n label: string;\n /** Text shown under the image; none shows no caption. */\n caption?: string;\n}\n\n/**\n * Handle to an open image viewer, returned by `BfImageViewerService.open()` and injectable in\n * its actions template (`inject(BfImageViewerRef)`). `index` is the shown image; `next()`,\n * `previous()` and `goTo()` step through the set (wrapping at both ends), `close()` plays the\n * exit motion and resolves `afterClosed`.\n *\n * @example\n * const ref = inject(BfImageViewerService).open({ images, index: 2, origin: thumb });\n * ref.next();\n * await ref.afterClosed;\n * @summary Handle on an open image viewer that steps through its images and closes it\n * @since 0.5.0\n */\nexport class BfImageViewerRef {\n /** Unique id of the viewer (its overlay's `bf-overlay-N`). */\n readonly id: string;\n /** The images of the set, in order. */\n readonly images: readonly BfImageViewerImage[];\n /** Resolves once the viewer has closed and left the page. */\n readonly afterClosed: Promise<void>;\n /** True once the viewer has been detached. */\n readonly closed: Signal<boolean>;\n private readonly current: WritableSignal<number>;\n /** Index (0-based) of the image the viewer shows. */\n readonly index: Signal<number>;\n\n /** @internal Created by `BfImageViewerService`; apps never construct it. */\n constructor(\n private readonly overlayRef: BfOverlayRef<unknown>,\n images: readonly BfImageViewerImage[],\n start: number,\n ) {\n this.id = overlayRef.id;\n this.images = images;\n this.current = signal(start);\n this.index = this.current.asReadonly();\n this.afterClosed = overlayRef.afterClosed.then(() => undefined);\n this.closed = overlayRef.closed;\n }\n\n /** Shows the next image; after the last one, the first. */\n next(): void {\n this.goTo(this.current() + 1);\n }\n\n /** Shows the previous image; before the first one, the last. */\n previous(): void {\n this.goTo(this.current() - 1);\n }\n\n /**\n * Shows the image at `index`, wrapped into the set (`-1` is the last one).\n * @param index The 0-based index of the image to show.\n */\n goTo(index: number): void {\n const count = this.images.length;\n if (count === 0 || !Number.isFinite(index)) {\n return;\n }\n this.current.set(((Math.trunc(index) % count) + count) % count);\n }\n\n /** Closes the viewer: it zooms back into its thumbnail, or fades out. Ignored once closing. */\n close(): void {\n this.overlayRef.close();\n }\n}\n\n/**\n * Where the viewer zooms from and back to: the thumbnail that was clicked, or a function that\n * returns the thumbnail of any image of the set (so closing after stepping zooms into the right\n * one), `null` for none.\n *\n * @summary The thumbnail an image viewer zooms from and back into, or a lookup per image\n * @since 0.5.0\n */\nexport type BfImageViewerOrigin =\n HTMLElement | ((index: number) => HTMLElement | null | undefined) | null;\n\n/**\n * Context of the `actions` template of `BfImageViewerService.open()`: `let-image`,\n * `let-index=\"index\"` and `let-ref=\"ref\"`.\n *\n * @summary What the viewer's actions template receives: the shown image, its index and the ref\n * @since 0.5.0\n */\nexport interface BfImageViewerActionsContext {\n /** The image the viewer shows (`let-image`). */\n $implicit: BfImageViewerImage;\n /** Its 0-based index in the set (`let-index=\"index\"`). */\n index: number;\n /** The viewer's ref (`let-ref=\"ref\"`), to close it or step. */\n ref: BfImageViewerRef;\n}\n\n/** @internal What `BfImageViewerService` hands the `bf-image-viewer` it opens. */\nexport interface BfImageViewerContext {\n readonly start: number;\n /** The viewer's accessible name. */\n readonly label: string;\n readonly origin: BfImageViewerOrigin;\n readonly actions: TemplateRef<BfImageViewerActionsContext> | null;\n /** Called by the viewer as it is created, so the overlay's enter and exit can run its motion. */\n readonly register: (motion: BfImageViewerMotion) => void;\n}\n\n/** @internal The open and close motion of a `bf-image-viewer`. */\nexport interface BfImageViewerMotion {\n enter(): Animation;\n exit(): Animation;\n}\n\n/** @internal Provided by `BfImageViewerService` to the viewer it opens. */\nexport const BF_IMAGE_VIEWER_CONTEXT = new InjectionToken<BfImageViewerContext>(\n 'BF_IMAGE_VIEWER_CONTEXT',\n);\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n Component,\n DOCUMENT,\n ElementRef,\n Injector,\n computed,\n inject,\n linkedSignal,\n signal,\n viewChild,\n} from '@angular/core';\nimport {\n BF_LABELS,\n BfFadeInDirective,\n BfIconButtonComponent,\n BfSpinnerComponent,\n} from '@bitforgehq/ui';\nimport { BfIconComponent } from '@bitforgehq/ui/icons';\nimport { ChevronLeft, ChevronRight, X } from 'lucide';\nimport { prefersReducedMotion } from '../core/motion';\nimport { playViewerMotion } from './image-viewer-motion';\nimport {\n BF_IMAGE_VIEWER_CONTEXT,\n type BfImageViewerActionsContext,\n type BfImageViewerImage,\n type BfImageViewerMotion,\n BfImageViewerRef,\n} from './image-viewer-ref';\n\n/** How far one image got. */\ntype ImageStatus = 'pending' | 'loaded' | 'error';\n\n/* Clicks here never close the viewer: the image, the controls and the app's own content. */\nconst KEEP_OPEN =\n '[data-frame], button, a, input, select, textarea, label, [data-caption], [data-actions]';\n\n/* The image's frame: sized to the image's aspect ratio inside the stage (a size container) when\n it is known, else the whole stage, with the image contained in it. */\nconst FRAME = 'relative max-h-full max-w-full';\n/* As wide as fits the stage at the image's ratio (`cq` units of the stage), the ratio carried by\n the host's `--bf-image-viewer-ratio`. */\nconst FRAME_SIZED =\n 'aspect-(--bf-image-viewer-ratio) w-[min(100cqw,calc(100cqh*var(--bf-image-viewer-ratio)))]';\n\n/* The controls: tonal icon buttons on the dark scrim (the viewer is a `.dark` sub-tree, so every\n token takes its dark value in both colour schemes). */\nconst NAV = 'pointer-events-auto absolute top-1/2 -translate-y-1/2';\n\n/**\n * The full-screen image viewer (lightbox) `BfImageViewerService.open()` renders: one image large\n * over a dark scrim, with a counter, previous and next buttons, a close button, an optional\n * caption and actions. It opens with a zoom out of the clicked thumbnail and steps with a\n * cross-fade. Apps do not place it in templates; open it with the service.\n *\n * @example\n * const ref = inject(BfImageViewerService).open({\n * images: [{ src: '/art/1.jpg', label: 'Neon skyline', caption: 'Concept 1' }],\n * index: 0,\n * origin: thumbnailElement,\n * });\n * @summary Full-screen image viewer that zooms from a thumbnail and steps through a set\n * @category Overlays\n * @since 0.5.0\n */\n@Component({\n selector: 'bf-image-viewer',\n imports: [\n NgTemplateOutlet,\n BfFadeInDirective,\n BfIconButtonComponent,\n BfIconComponent,\n BfSpinnerComponent,\n ],\n host: {\n class: 'dark fixed inset-0 flex flex-col text-text',\n 'data-bf-image-viewer': '',\n '[style.--bf-image-viewer-ratio]': 'ratio()',\n // For test harnesses: the shown image, the set's size and the viewer's name.\n '[attr.data-index]': 'index()',\n '[attr.data-count]': 'count()',\n '[attr.data-label]': 'context.label',\n '(keydown)': 'keydown($event)',\n '(click)': 'clicked($event)',\n },\n template: `\n <div #scrim data-scrim class=\"bg-scrim/90 absolute inset-0\"></div>\n <div #top data-chrome class=\"relative flex shrink-0 items-center gap-3 p-3\">\n <span data-counter class=\"text-label min-w-0 flex-1 ps-2\" [class.invisible]=\"count() < 2\">\n {{ counter() }}\n </span>\n <bf-icon-button data-close cdkFocusInitial [label]=\"labels.close\" (clicked)=\"ref.close()\">\n <bf-icon [icon]=\"closeIcon\" />\n </bf-icon-button>\n </div>\n <div class=\"relative min-h-0 flex-1\">\n <div\n data-stage\n class=\"[container-type:size] absolute inset-0 grid place-items-center px-3 sm:px-16\"\n >\n <div #frame data-frame [attr.data-status]=\"status()\" [class]=\"frameClasses()\">\n @if (placeholder(); as thumb) {\n <img\n data-placeholder\n aria-hidden=\"true\"\n alt=\"\"\n class=\"absolute inset-0 size-full object-contain\"\n [src]=\"thumb\"\n />\n }\n @for (item of shown(); track item.index) {\n <img\n bfFadeIn\n data-image\n class=\"absolute inset-0 size-full object-contain\"\n animate.leave=\"opacity-0 transition-opacity duration-slow ease-md motion-reduce:transition-none\"\n [src]=\"item.image.src\"\n [alt]=\"item.image.label\"\n (load)=\"imageLoaded($event, item.index)\"\n (error)=\"imageFailed(item.index)\"\n />\n }\n @if (status() === 'pending') {\n <div class=\"absolute inset-0 grid place-items-center\">\n <bf-spinner size=\"lg\" />\n </div>\n } @else if (status() === 'error') {\n <p\n data-failed\n class=\"text-body text-text-secondary absolute inset-0 grid place-items-center p-4 text-center\"\n >\n {{ labels.imageLoadFailed }}\n </p>\n }\n </div>\n </div>\n @if (count() > 1) {\n <bf-icon-button\n data-chrome\n data-previous\n [class]=\"previousClasses\"\n [label]=\"labels.imageViewerPrevious\"\n (clicked)=\"ref.previous()\"\n >\n <bf-icon class=\"rtl:-scale-x-100\" [icon]=\"previousIcon\" />\n </bf-icon-button>\n <bf-icon-button\n data-chrome\n data-next\n [class]=\"nextClasses\"\n [label]=\"labels.imageViewerNext\"\n (clicked)=\"ref.next()\"\n >\n <bf-icon class=\"rtl:-scale-x-100\" [icon]=\"nextIcon\" />\n </bf-icon-button>\n }\n </div>\n <div\n #bottom\n data-chrome\n class=\"relative flex shrink-0 flex-wrap items-center gap-x-4 gap-y-2 px-5 pt-2 pb-4 empty:hidden\"\n >\n @if (image().caption; as caption) {\n <p data-caption class=\"text-body min-w-0 flex-1 wrap-anywhere\">{{ caption }}</p>\n }\n @if (context.actions; as actions) {\n <div data-actions class=\"ms-auto flex flex-wrap items-center gap-2\">\n <ng-container\n [ngTemplateOutlet]=\"actions\"\n [ngTemplateOutletContext]=\"actionsContext()\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n }\n </div>\n <div data-announcement aria-live=\"polite\" class=\"sr-only\">{{ announcement() }}</div>\n `,\n})\nexport class BfImageViewerComponent implements BfImageViewerMotion {\n protected readonly labels = inject(BF_LABELS);\n protected readonly ref = inject(BfImageViewerRef);\n protected readonly context = inject(BF_IMAGE_VIEWER_CONTEXT);\n protected readonly injector = inject(Injector);\n private readonly document = inject(DOCUMENT);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n protected readonly closeIcon = X;\n protected readonly previousIcon = ChevronLeft;\n protected readonly nextIcon = ChevronRight;\n protected readonly previousClasses = `${NAV} start-3`;\n protected readonly nextClasses = `${NAV} end-3`;\n\n private readonly frame = viewChild.required<ElementRef<HTMLElement>>('frame');\n private readonly scrim = viewChild.required<ElementRef<HTMLElement>>('scrim');\n private readonly top = viewChild.required<ElementRef<HTMLElement>>('top');\n private readonly bottom = viewChild.required<ElementRef<HTMLElement>>('bottom');\n\n /** The progress of every image shown so far, by index. */\n private readonly statuses = signal<ReadonlyMap<number, ImageStatus>>(new Map());\n /** The aspect ratio (width / height) of every image that has loaded, by index. */\n private readonly ratios = signal<ReadonlyMap<number, number>>(new Map());\n\n protected readonly count = computed(() => this.ref.images.length);\n protected readonly index = this.ref.index;\n protected readonly image = computed<BfImageViewerImage>(\n () => this.ref.images[this.index()] ?? { src: '', label: '' },\n );\n protected readonly status = computed<ImageStatus>(\n () => this.statuses().get(this.index()) ?? 'pending',\n );\n /** The shown image, keyed by index so a step replaces the element (and cross-fades); none\n * once it failed, so the failure message is not drawn over a broken-image box. */\n protected readonly shown = computed(() =>\n this.status() === 'error' ? [] : [{ index: this.index(), image: this.image() }],\n );\n protected readonly counter = computed(() =>\n this.labels.imageViewerPosition(this.index() + 1, this.count()),\n );\n\n /** Announced politely after each step (never on open, where the dialog itself is read). */\n private readonly stepped = linkedSignal<number, boolean>({\n source: this.index,\n computation: (_, previous) => previous !== undefined,\n });\n protected readonly announcement = computed(() => {\n if (!this.stepped()) {\n return '';\n }\n const alt = this.image().label;\n return alt ? `${this.counter()}, ${alt}` : this.counter();\n });\n\n /** The thumbnail of the shown image, under it until the large one arrives. */\n protected readonly placeholder = computed(() => {\n if (this.status() === 'loaded') {\n return null;\n }\n const img = thumbnailImage(this.originFor(this.index()));\n if (!img) {\n return null;\n }\n const src = img.currentSrc ? img.currentSrc : img.getAttribute('src');\n return src === '' ? null : src;\n });\n\n /** Width / height of the shown image: once loaded its own, before that its thumbnail's. */\n protected readonly ratio = computed<number | null>(() => {\n const own = this.ratios().get(this.index());\n if (own) {\n return own;\n }\n const img = thumbnailImage(this.originFor(this.index()));\n return img && img.naturalWidth > 0 && img.naturalHeight > 0\n ? img.naturalWidth / img.naturalHeight\n : null;\n });\n protected readonly frameClasses = computed(() =>\n this.ratio() ? `${FRAME} ${FRAME_SIZED}` : `${FRAME} size-full`,\n );\n\n protected readonly actionsContext = computed<BfImageViewerActionsContext>(() => ({\n $implicit: this.image(),\n index: this.index(),\n ref: this.ref,\n }));\n\n constructor() {\n this.context.register(this);\n }\n\n /** @internal Plays the open motion; called by `BfImageViewerService` as the overlay's enter. */\n enter(): Animation {\n return playViewerMotion(this.parts(), this.originFor(this.index()), true, this.reduced());\n }\n\n /** @internal Plays the close motion; called by `BfImageViewerService` as the overlay's exit. */\n exit(): Animation {\n return playViewerMotion(this.parts(), this.originFor(this.index()), false, this.reduced());\n }\n\n /** @internal An image loaded: it shows, and the frame takes its aspect ratio. */\n imageLoaded(event: Event, index: number): void {\n const img = event.target;\n if (img instanceof HTMLImageElement && img.naturalWidth > 0 && img.naturalHeight > 0) {\n const ratio = img.naturalWidth / img.naturalHeight;\n this.ratios.update((map) => new Map(map).set(index, ratio));\n }\n this.statuses.update((map) => new Map(map).set(index, 'loaded'));\n }\n\n /** @internal An image failed: the frame shows the failure message. */\n imageFailed(index: number): void {\n this.statuses.update((map) => new Map(map).set(index, 'error'));\n }\n\n /** @internal Arrow keys step (mirrored under rtl), Home and End jump to the ends. */\n keydown(event: KeyboardEvent): void {\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) {\n return;\n }\n const target = event.target;\n if (\n target instanceof HTMLElement &&\n (target.isContentEditable || target.matches('input, textarea, select'))\n ) {\n return;\n }\n const rtl =\n this.document.defaultView?.getComputedStyle(this.host.nativeElement).direction === 'rtl';\n const forward = rtl ? 'ArrowLeft' : 'ArrowRight';\n const backward = rtl ? 'ArrowRight' : 'ArrowLeft';\n switch (event.key) {\n case forward:\n this.ref.next();\n break;\n case backward:\n this.ref.previous();\n break;\n case 'Home':\n this.ref.goTo(0);\n break;\n case 'End':\n this.ref.goTo(this.count() - 1);\n break;\n default:\n return;\n }\n event.preventDefault();\n }\n\n /** @internal A click on the scrim or around the image closes the viewer. */\n clicked(event: MouseEvent): void {\n const target = event.target;\n if (target instanceof Element && !target.closest(KEEP_OPEN)) {\n this.ref.close();\n }\n }\n\n /** The thumbnail of image `index`, when the opener gave one. */\n private originFor(index: number): HTMLElement | null {\n const origin = this.context.origin;\n if (typeof origin === 'function') {\n return origin(index) ?? null;\n }\n return index === this.context.start ? origin : null;\n }\n\n private parts(): { host: HTMLElement; frame: HTMLElement; chrome: HTMLElement[] } {\n const host = this.host.nativeElement;\n const navigation = Array.from(\n host.querySelectorAll<HTMLElement>('bf-icon-button[data-chrome]'),\n );\n return {\n host,\n frame: this.frame().nativeElement,\n chrome: [\n this.scrim().nativeElement,\n this.top().nativeElement,\n this.bottom().nativeElement,\n ...navigation,\n ],\n };\n }\n\n private reduced(): boolean {\n return prefersReducedMotion(this.document.defaultView);\n }\n}\n\n/** The `img` of a thumbnail: the element itself, or the first image inside it. */\nfunction thumbnailImage(origin: HTMLElement | null): HTMLImageElement | null {\n if (!origin) {\n return null;\n }\n return origin instanceof HTMLImageElement ? origin : origin.querySelector('img');\n}\n","import { Injectable, Injector, type StaticProvider, type TemplateRef, inject } from '@angular/core';\nimport { BF_LABELS } from '@bitforgehq/ui';\nimport { fadeIn, fadeOut } from '../core/overlay-animations';\nimport { type BfOverlayRef } from '../core/overlay-ref';\nimport { BfOverlayService } from '../core/overlay.service';\nimport { BfImageViewerComponent } from './image-viewer.component';\nimport {\n BF_IMAGE_VIEWER_CONTEXT,\n type BfImageViewerActionsContext,\n type BfImageViewerContext,\n type BfImageViewerImage,\n type BfImageViewerMotion,\n type BfImageViewerOrigin,\n BfImageViewerRef,\n} from './image-viewer-ref';\n\n/**\n * Options of `BfImageViewerService.open()`.\n *\n * @summary Options of an image viewer: its images, the first one, its thumbnail and actions\n * @since 0.5.0\n */\nexport interface BfImageViewerOptions {\n /** The images to step through, in order; at least one. */\n images: readonly BfImageViewerImage[];\n /**\n * Index of the image shown first, wrapped into the set.\n * @default 0\n */\n index?: number;\n /**\n * The thumbnail the viewer zooms out of and back into (or a function returning the thumbnail\n * of an image by index); none fades the viewer in and out.\n */\n origin?: BfImageViewerOrigin;\n /**\n * Actions under the image, beside its caption (a download link, a \"Use this one\" button); its\n * context is `{ $implicit: image, index, ref }`.\n */\n actions?: TemplateRef<BfImageViewerActionsContext>;\n /** Accessible name of the viewer; empty uses `provideBfLabels()`'s `imageViewer`. */\n ariaLabel?: string;\n /**\n * A navigation to another URL path closes the viewer (default true).\n * @default true\n */\n closeOnNavigation?: boolean;\n /**\n * Parent of the viewer's injector and source of its labels (default the root injector). Pass\n * the opener's `inject(Injector)` so a feature-level `provideBfLabels()` reaches the viewer.\n */\n injector?: Injector;\n}\n\n/**\n * Opens a full-screen image viewer (a lightbox) on the overlay core: one image large over a dark\n * scrim, previous and next buttons, the arrow keys, Home and End to step through the set\n * (wrapping at both ends), a counter, the caption and optional actions. It zooms out of the\n * clicked thumbnail (`origin`) and back into it, cross-fades between images, and fades when there\n * is no thumbnail on screen; reduced motion only fades. It is a modal dialog: focus moves to its\n * close button and is trapped, `Escape`, the close button and a click on the scrim close it, the\n * page behind it is `inert` and does not scroll, and focus returns to the opener.\n *\n * @example\n * const ref = inject(BfImageViewerService).open({\n * images: shots.map((s) => ({ src: s.full, label: s.alt, caption: s.title })),\n * index: 2,\n * origin: (i) => thumbnails[i],\n * });\n * await ref.afterClosed;\n * @summary Opens a full-screen image viewer that zooms from a thumbnail and steps through a set\n * @since 0.5.0\n */\n@Injectable({ providedIn: 'root' })\nexport class BfImageViewerService {\n private readonly overlays = inject(BfOverlayService);\n private readonly injector = inject(Injector);\n\n /**\n * Opens the viewer on `options.images`, showing `options.index` first.\n * @param options The images, the first index, the thumbnail, the actions and the injector.\n * @returns The viewer's ref.\n */\n open(options: BfImageViewerOptions): BfImageViewerRef {\n const images = [...options.images];\n if (images.length === 0) {\n throw new Error('BfImageViewerService: open() needs at least one image');\n }\n const requested = Math.trunc(options.index ?? 0);\n const start = Number.isFinite(requested)\n ? ((requested % images.length) + images.length) % images.length\n : 0;\n const injector = options.injector ?? this.injector;\n const label = options.ariaLabel?.length\n ? options.ariaLabel\n : injector.get(BF_LABELS).imageViewer;\n let viewerRef: BfImageViewerRef | null = null;\n let motion: BfImageViewerMotion | null = null;\n const context: BfImageViewerContext = {\n start,\n label,\n origin: options.origin ?? null,\n actions: options.actions ?? null,\n register: (viewer) => {\n motion = viewer;\n },\n };\n\n const providers = (ref: BfOverlayRef<unknown>): StaticProvider[] => {\n viewerRef = new BfImageViewerRef(ref, images, start);\n return [\n { provide: BfImageViewerRef, useValue: viewerRef },\n { provide: BF_IMAGE_VIEWER_CONTEXT, useValue: context },\n ];\n };\n\n this.overlays.open(BfImageViewerComponent, {\n position: 'fullscreen',\n // The viewer draws its own scrim (the pane covers the viewport) and closes on its clicks.\n backdrop: false,\n role: 'dialog',\n ariaLabel: label,\n closeOnNavigation: options.closeOnNavigation,\n panelClass: ['bf-image-viewer-panel'],\n injector,\n providers,\n // The viewer registers its motion as it is created, before the core runs the enter.\n enter: (panel) => (motion ? motion.enter() : fadeIn(panel)),\n exit: (panel) => (motion ? motion.exit() : fadeOut(panel)),\n });\n if (!viewerRef) {\n throw new Error('BfImageViewerService: the overlay core did not build the viewer providers');\n }\n return viewerRef;\n }\n}\n"],"mappings":"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"}