forty-cdk 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/accordion/README.md +122 -0
- package/aspect-ratio/README.md +76 -0
- package/avatar/README.md +100 -0
- package/breadcrumbs/README.md +49 -0
- package/breakpoints/README.md +81 -0
- package/button/README.md +49 -0
- package/calendar/README.md +458 -0
- package/carousel/README.md +358 -0
- package/checkbox/README.md +146 -0
- package/combobox/README.md +535 -0
- package/context-menu/README.md +139 -0
- package/date-field/README.md +184 -0
- package/date-picker/README.md +338 -0
- package/dialog/README.md +388 -0
- package/disclosure/README.md +114 -0
- package/drag-drop/README.md +359 -0
- package/drawer/README.md +560 -0
- package/dropdown-menu/README.md +176 -0
- package/fesm2022/forty-cdk-accordion.mjs +348 -0
- package/fesm2022/forty-cdk-accordion.mjs.map +1 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs +74 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs.map +1 -0
- package/fesm2022/forty-cdk-avatar.mjs +308 -0
- package/fesm2022/forty-cdk-avatar.mjs.map +1 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs +125 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs.map +1 -0
- package/fesm2022/forty-cdk-breakpoints.mjs +117 -0
- package/fesm2022/forty-cdk-breakpoints.mjs.map +1 -0
- package/fesm2022/forty-cdk-button.mjs +134 -0
- package/fesm2022/forty-cdk-button.mjs.map +1 -0
- package/fesm2022/forty-cdk-calendar.mjs +2034 -0
- package/fesm2022/forty-cdk-calendar.mjs.map +1 -0
- package/fesm2022/forty-cdk-carousel.mjs +968 -0
- package/fesm2022/forty-cdk-carousel.mjs.map +1 -0
- package/fesm2022/forty-cdk-checkbox.mjs +226 -0
- package/fesm2022/forty-cdk-checkbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-combobox.mjs +2596 -0
- package/fesm2022/forty-cdk-combobox.mjs.map +1 -0
- package/fesm2022/forty-cdk-context-menu.mjs +413 -0
- package/fesm2022/forty-cdk-context-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-core.mjs +9022 -0
- package/fesm2022/forty-cdk-core.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-field.mjs +744 -0
- package/fesm2022/forty-cdk-date-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-picker.mjs +1011 -0
- package/fesm2022/forty-cdk-date-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-dialog.mjs +707 -0
- package/fesm2022/forty-cdk-dialog.mjs.map +1 -0
- package/fesm2022/forty-cdk-disclosure.mjs +190 -0
- package/fesm2022/forty-cdk-disclosure.mjs.map +1 -0
- package/fesm2022/forty-cdk-drag-drop.mjs +1180 -0
- package/fesm2022/forty-cdk-drag-drop.mjs.map +1 -0
- package/fesm2022/forty-cdk-drawer.mjs +1641 -0
- package/fesm2022/forty-cdk-drawer.mjs.map +1 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs +350 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-field.mjs +425 -0
- package/fesm2022/forty-cdk-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-fieldset.mjs +164 -0
- package/fesm2022/forty-cdk-fieldset.mjs.map +1 -0
- package/fesm2022/forty-cdk-file-upload.mjs +221 -0
- package/fesm2022/forty-cdk-file-upload.mjs.map +1 -0
- package/fesm2022/forty-cdk-hover-card.mjs +496 -0
- package/fesm2022/forty-cdk-hover-card.mjs.map +1 -0
- package/fesm2022/forty-cdk-input.mjs +274 -0
- package/fesm2022/forty-cdk-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-internationalized-date.mjs +1 -1
- package/fesm2022/forty-cdk-internationalized-date.mjs.map +1 -1
- package/fesm2022/forty-cdk-listbox.mjs +1279 -0
- package/fesm2022/forty-cdk-listbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-menu.mjs +1439 -0
- package/fesm2022/forty-cdk-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-menubar.mjs +787 -0
- package/fesm2022/forty-cdk-menubar.mjs.map +1 -0
- package/fesm2022/forty-cdk-meter.mjs +211 -0
- package/fesm2022/forty-cdk-meter.mjs.map +1 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs +1145 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-number-input.mjs +559 -0
- package/fesm2022/forty-cdk-number-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-otp-input.mjs +527 -0
- package/fesm2022/forty-cdk-otp-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-pagination.mjs +323 -0
- package/fesm2022/forty-cdk-pagination.mjs.map +1 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs +297 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs.map +1 -0
- package/fesm2022/forty-cdk-popover.mjs +698 -0
- package/fesm2022/forty-cdk-popover.mjs.map +1 -0
- package/fesm2022/forty-cdk-progress.mjs +226 -0
- package/fesm2022/forty-cdk-progress.mjs.map +1 -0
- package/fesm2022/forty-cdk-radio-group.mjs +378 -0
- package/fesm2022/forty-cdk-radio-group.mjs.map +1 -0
- package/fesm2022/forty-cdk-scroll-area.mjs +640 -0
- package/fesm2022/forty-cdk-scroll-area.mjs.map +1 -0
- package/fesm2022/forty-cdk-search.mjs +205 -0
- package/fesm2022/forty-cdk-search.mjs.map +1 -0
- package/fesm2022/forty-cdk-select.mjs +1661 -0
- package/fesm2022/forty-cdk-select.mjs.map +1 -0
- package/fesm2022/forty-cdk-separator.mjs +82 -0
- package/fesm2022/forty-cdk-separator.mjs.map +1 -0
- package/fesm2022/forty-cdk-signal-forms.mjs +97 -0
- package/fesm2022/forty-cdk-signal-forms.mjs.map +1 -0
- package/fesm2022/forty-cdk-slider.mjs +803 -0
- package/fesm2022/forty-cdk-slider.mjs.map +1 -0
- package/fesm2022/forty-cdk-stepper.mjs +886 -0
- package/fesm2022/forty-cdk-stepper.mjs.map +1 -0
- package/fesm2022/forty-cdk-switch.mjs +137 -0
- package/fesm2022/forty-cdk-switch.mjs.map +1 -0
- package/fesm2022/forty-cdk-table.mjs +1518 -0
- package/fesm2022/forty-cdk-table.mjs.map +1 -0
- package/fesm2022/forty-cdk-tabs.mjs +400 -0
- package/fesm2022/forty-cdk-tabs.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-field.mjs +593 -0
- package/fesm2022/forty-cdk-time-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-picker.mjs +1013 -0
- package/fesm2022/forty-cdk-time-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-toast.mjs +1153 -0
- package/fesm2022/forty-cdk-toast.mjs.map +1 -0
- package/fesm2022/forty-cdk-toggle.mjs +516 -0
- package/fesm2022/forty-cdk-toggle.mjs.map +1 -0
- package/fesm2022/forty-cdk-toolbar.mjs +374 -0
- package/fesm2022/forty-cdk-toolbar.mjs.map +1 -0
- package/fesm2022/forty-cdk-tooltip.mjs +672 -0
- package/fesm2022/forty-cdk-tooltip.mjs.map +1 -0
- package/fesm2022/forty-cdk-tree.mjs +2007 -0
- package/fesm2022/forty-cdk-tree.mjs.map +1 -0
- package/fesm2022/forty-cdk-virtualization.mjs +1 -1
- package/fesm2022/forty-cdk-virtualization.mjs.map +1 -1
- package/fesm2022/forty-cdk.mjs +0 -43310
- package/fesm2022/forty-cdk.mjs.map +1 -1
- package/field/README.md +97 -0
- package/fieldset/README.md +86 -0
- package/file-upload/README.md +73 -0
- package/hover-card/README.md +171 -0
- package/input/README.md +156 -0
- package/listbox/README.md +424 -0
- package/menu/README.md +181 -0
- package/menubar/README.md +140 -0
- package/meter/README.md +128 -0
- package/navigation-menu/README.md +253 -0
- package/number-input/README.md +171 -0
- package/otp-input/README.md +198 -0
- package/package.json +213 -1
- package/pagination/README.md +61 -0
- package/pane-resizer/README.md +136 -0
- package/popover/README.md +262 -0
- package/progress/README.md +115 -0
- package/radio-group/README.md +129 -0
- package/scroll-area/README.md +184 -0
- package/search/README.md +42 -0
- package/select/README.md +488 -0
- package/separator/README.md +84 -0
- package/signal-forms/README.md +72 -0
- package/slider/README.md +152 -0
- package/stepper/README.md +292 -0
- package/switch/README.md +116 -0
- package/table/README.md +769 -0
- package/tabs/README.md +130 -0
- package/time-field/README.md +157 -0
- package/time-picker/README.md +172 -0
- package/toast/README.md +398 -0
- package/toggle/README.md +224 -0
- package/toolbar/README.md +109 -0
- package/tooltip/README.md +274 -0
- package/tree/README.md +708 -0
- package/types/forty-cdk-accordion.d.ts +242 -0
- package/types/forty-cdk-aspect-ratio.d.ts +59 -0
- package/types/forty-cdk-avatar.d.ts +133 -0
- package/types/forty-cdk-breadcrumbs.d.ts +92 -0
- package/types/forty-cdk-breakpoints.d.ts +141 -0
- package/types/forty-cdk-button.d.ts +80 -0
- package/types/forty-cdk-calendar.d.ts +914 -0
- package/types/forty-cdk-carousel.d.ts +530 -0
- package/types/forty-cdk-checkbox.d.ts +141 -0
- package/types/forty-cdk-combobox.d.ts +1259 -0
- package/types/forty-cdk-context-menu.d.ts +313 -0
- package/types/forty-cdk-core.d.ts +5774 -0
- package/types/forty-cdk-date-field.d.ts +307 -0
- package/types/forty-cdk-date-picker.d.ts +622 -0
- package/types/forty-cdk-dialog.d.ts +546 -0
- package/types/forty-cdk-disclosure.d.ts +127 -0
- package/types/forty-cdk-drag-drop.d.ts +456 -0
- package/types/forty-cdk-drawer.d.ts +871 -0
- package/types/forty-cdk-dropdown-menu.d.ts +242 -0
- package/types/forty-cdk-field.d.ts +236 -0
- package/types/forty-cdk-fieldset.d.ts +119 -0
- package/types/forty-cdk-file-upload.d.ts +124 -0
- package/types/forty-cdk-hover-card.d.ts +320 -0
- package/types/forty-cdk-input.d.ts +169 -0
- package/types/forty-cdk-internationalized-date.d.ts +1 -1
- package/types/forty-cdk-listbox.d.ts +513 -0
- package/types/forty-cdk-menu.d.ts +629 -0
- package/types/forty-cdk-menubar.d.ts +451 -0
- package/types/forty-cdk-meter.d.ts +122 -0
- package/types/forty-cdk-navigation-menu.d.ts +514 -0
- package/types/forty-cdk-number-input.d.ts +319 -0
- package/types/forty-cdk-otp-input.d.ts +248 -0
- package/types/forty-cdk-pagination.d.ts +214 -0
- package/types/forty-cdk-pane-resizer.d.ts +145 -0
- package/types/forty-cdk-popover.d.ts +509 -0
- package/types/forty-cdk-progress.d.ts +143 -0
- package/types/forty-cdk-radio-group.d.ts +222 -0
- package/types/forty-cdk-scroll-area.d.ts +258 -0
- package/types/forty-cdk-search.d.ts +142 -0
- package/types/forty-cdk-select.d.ts +899 -0
- package/types/forty-cdk-separator.d.ts +59 -0
- package/types/forty-cdk-signal-forms.d.ts +58 -0
- package/types/forty-cdk-slider.d.ts +379 -0
- package/types/forty-cdk-stepper.d.ts +650 -0
- package/types/forty-cdk-switch.d.ts +87 -0
- package/types/forty-cdk-table.d.ts +723 -0
- package/types/forty-cdk-tabs.d.ts +235 -0
- package/types/forty-cdk-time-field.d.ts +307 -0
- package/types/forty-cdk-time-picker.d.ts +578 -0
- package/types/forty-cdk-toast.d.ts +598 -0
- package/types/forty-cdk-toggle.d.ts +310 -0
- package/types/forty-cdk-toolbar.d.ts +217 -0
- package/types/forty-cdk-tooltip.d.ts +436 -0
- package/types/forty-cdk-tree.d.ts +688 -0
- package/types/forty-cdk.d.ts +1 -19743
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forty-cdk-menubar.mjs","sources":["../../../projects/forty-cdk/menubar/src/menubar-menu-context.ts","../../../projects/forty-cdk/menubar/src/menubar-context.ts","../../../projects/forty-cdk/menubar/src/menubar-defaults.ts","../../../projects/forty-cdk/menubar/src/menubar.ts","../../../projects/forty-cdk/menubar/src/menubar-trigger.ts","../../../projects/forty-cdk/menubar/src/forty-cdk-menubar.ts"],"sourcesContent":["import { computed, type ModelSignal, type Signal, signal } from '@angular/core';\nimport type { ReferenceElement } from '@floating-ui/dom';\n\nimport {\n CloseReasonState,\n InitialFocusState,\n createMenuItemList,\n MENU_POSITIONING_DEFAULTS,\n type MenuActivationModality,\n type ListNavigationAction,\n type ForMenuCloseReason,\n type ForMenuContext,\n type ForMenuItemHandle,\n type MenuSiblingNavigator,\n} from 'forty-cdk/core';\nimport type { ForMenubarTriggerHandle } from './menubar-context';\n\n/**\n * The slice of `[forMenubar]` the multiplexed `ForMenuContext` reads. Passed to\n * {@link MenubarMenuContext} so the context implementation stays a plain class\n * (testable, no `inject()`) while still reading the bar's reactive state.\n */\nexport interface MenubarMenuHost extends MenuSiblingNavigator {\n readonly value: ModelSignal<string>;\n readonly disabled: Signal<boolean>;\n readonly dismissible: Signal<boolean>;\n readonly dir: ForMenuContext['dir'];\n readonly loop: Signal<boolean>;\n /** Currently-open trigger handle, or `null` when no menu is open. */\n readonly activeTrigger: Signal<ForMenubarTriggerHandle | null>;\n /** All registered triggers in DOM order; their hosts are the dismissable exemptions. */\n readonly triggers: Signal<readonly ForMenubarTriggerHandle[]>;\n /**\n * The most-recently-active trigger host — survives past close so the\n * content's destroy hook can still return focus to the trigger.\n */\n readonly lastTriggerHost: Signal<HTMLElement | null>;\n /** Close the currently-open menu (clears `value`, snapshots the last trigger). */\n closeOpen(): void;\n /** Attach the bar's hover-keepalive listeners to a mounted content element. */\n attachContentPointer(el: HTMLElement): void;\n /** Detach the bar's hover-keepalive listeners from the content element. */\n detachContentPointer(): void;\n}\n\n/**\n * Single concrete `ForMenuContext` the `[forMenubar]` root provides to its\n * descendant `[forMenuContent]` and items. It is the one place the bar's\n * \"which trigger's menu is open\" multiplexing lives: open / anchor / side /\n * ids / placement are all derived from the host's `activeTrigger`, so the same\n * context shape transparently covers whichever trigger's menu is mounted.\n *\n * Item navigation reuses the shared `MenuItemList` (the same item-collection /\n * typeahead / navigate / focus mechanics that back `MenuOverlay`), and the\n * initial-focus / highlight-consume protocol and the close-reason record reuse\n * the shared `InitialFocusState` / `CloseReasonState` micro-helpers (also\n * composed by `MenuOverlay`), so this only has to cover the parts the\n * single-owner overlay can't — the `activeTrigger`-derived multiplexing.\n *\n * A bar-level menu has no per-trigger dismiss / auto-focus outputs and no\n * per-context trigger registration (triggers register with the bar directly),\n * so the corresponding `ForMenuContext` members are deliberately inert here:\n * the outside-interaction emit forwarders have nowhere to surface (the implicit\n * close runs through {@link requestClose}), the auto-focus emitters never veto\n * (bar menus follow APG-prescribed focus movement), and trigger\n * register/unregister are owned by the bar. They stay as documented members of\n * this one implementation rather than scattered no-op literals.\n */\nexport class MenubarMenuContext implements ForMenuContext {\n readonly #host: MenubarMenuHost;\n readonly #itemList = createMenuItemList<ForMenuItemHandle>(() => this.#host.loop());\n readonly #contentEl = signal<HTMLElement | null>(null);\n readonly #initialFocusState = new InitialFocusState();\n readonly #closeReasonState = new CloseReasonState<ForMenuCloseReason>();\n\n readonly open = computed(() => this.#host.value() !== '');\n readonly disabled: Signal<boolean>;\n readonly dismissible: Signal<boolean>;\n readonly returnFocus = signal(true).asReadonly();\n readonly dir: ForMenuContext['dir'];\n readonly side = computed(() => this.#host.activeTrigger()?.side());\n readonly align = computed(() => this.#host.activeTrigger()?.align());\n readonly sideOffset = computed(() => this.#host.activeTrigger()?.sideOffset() ?? 4);\n readonly alignOffset = computed(\n () => this.#host.activeTrigger()?.alignOffset() ?? MENU_POSITIONING_DEFAULTS.alignOffset,\n );\n readonly avoidCollisions = computed(\n () =>\n this.#host.activeTrigger()?.avoidCollisions() ?? MENU_POSITIONING_DEFAULTS.avoidCollisions,\n );\n readonly collisionPadding = computed(() => this.#host.activeTrigger()?.collisionPadding() ?? 8);\n readonly arrowPadding = computed(\n () => this.#host.activeTrigger()?.arrowPadding() ?? MENU_POSITIONING_DEFAULTS.arrowPadding,\n );\n readonly sticky = computed(\n () => this.#host.activeTrigger()?.sticky() ?? MENU_POSITIONING_DEFAULTS.sticky,\n );\n readonly hideWhenDetached = computed(\n () =>\n this.#host.activeTrigger()?.hideWhenDetached() ?? MENU_POSITIONING_DEFAULTS.hideWhenDetached,\n );\n readonly clipUntilPositioned = computed(\n () =>\n this.#host.activeTrigger()?.clipUntilPositioned() ??\n MENU_POSITIONING_DEFAULTS.clipUntilPositioned,\n );\n readonly loop: Signal<boolean>;\n readonly initialFocus = this.#initialFocusState.target;\n readonly lastCloseReason = this.#closeReasonState.reason;\n readonly triggerId = computed(() => this.#host.activeTrigger()?.triggerId() ?? '');\n readonly contentId = computed(() => this.#host.activeTrigger()?.contentId() ?? '');\n readonly ariaLabel = computed(() => this.#host.activeTrigger()?.ariaLabel() ?? null);\n readonly anchor = computed<ReferenceElement | null>(\n () => this.#host.activeTrigger()?.host ?? null,\n );\n readonly trigger: Signal<HTMLElement | null>;\n readonly content = this.#contentEl.asReadonly();\n readonly parentMenu = null;\n readonly menubar: MenuSiblingNavigator;\n\n /**\n * Exempt every menubar trigger element so clicking another trigger doesn't\n * fire `pointerDownOutside` (the trigger's own click handler routes the\n * close + open).\n */\n readonly dismissableExemptions = computed<readonly HTMLElement[]>(() =>\n this.#host.triggers().map((t) => t.host),\n );\n\n constructor(host: MenubarMenuHost) {\n this.#host = host;\n this.disabled = host.disabled;\n this.dismissible = host.dismissible;\n this.dir = host.dir;\n this.loop = host.loop;\n this.trigger = host.lastTriggerHost;\n this.menubar = host;\n }\n\n setInitialFocus(target: 'first' | 'last'): void {\n this.#initialFocusState.setTarget(target);\n }\n\n /**\n * Read by the bar's `openTrigger` so the next open seeds the resolved\n * initial-focus target and clears the prior close reason. A `'pointer'`\n * `modality` keeps the upcoming programmatic initial focus from reflecting\n * `data-highlighted` on the focused item.\n */\n prepareOpen(initialFocus: 'first' | 'last', modality: MenuActivationModality = 'keyboard'): void {\n this.#initialFocusState.prepareOpen(initialFocus, modality === 'keyboard');\n this.#closeReasonState.reset();\n }\n\n /** Read by the bar's pointer-driven close so the content skips its return-focus. */\n setLastCloseReason(reason: ForMenuCloseReason): void {\n this.#closeReasonState.set(reason);\n }\n\n registerTrigger(): void {\n // Triggers register with the menubar itself, not with this menu context.\n }\n unregisterTrigger(): void {}\n\n registerContent(el: HTMLElement): void {\n this.#contentEl.set(el);\n this.#host.attachContentPointer(el);\n }\n unregisterContent(el: HTMLElement): void {\n if (this.#contentEl() === el) {\n this.#contentEl.set(null);\n }\n this.#host.detachContentPointer();\n }\n\n registerItem(handle: ForMenuItemHandle): void {\n this.#itemList.registerItem(handle);\n }\n unregisterItem(handle: ForMenuItemHandle): void {\n this.#itemList.unregisterItem(handle);\n }\n\n navigate(currentItem: HTMLElement, action: ListNavigationAction): void {\n this.#itemList.navigate(currentItem, action);\n }\n handleTypeahead(event: KeyboardEvent): void {\n this.#itemList.handleTypeahead(event);\n }\n clearItemHighlights(): void {\n this.#itemList.clearHighlights();\n }\n focusFirstEnabledItem(): boolean {\n return this.#itemList.focusFirstEnabledItem(this.#initialFocusState.consumeHighlight());\n }\n focusLastEnabledItem(): boolean {\n return this.#itemList.focusLastEnabledItem(this.#initialFocusState.consumeHighlight());\n }\n\n toggle(): void {\n // Without a specific trigger value, toggle from the bar context can only\n // close. Triggers themselves drive the open path via the bar's openTrigger.\n if (this.#host.value() !== '') {\n this.#host.closeOpen();\n }\n }\n\n openMenu(): void {\n // Open requires a trigger value — see the bar's openTrigger.\n }\n\n closeMenu(reason: ForMenuCloseReason): void {\n this.#closeReasonState.set(reason);\n this.#host.closeOpen();\n }\n\n emitEscapeKeyDown(event: KeyboardEvent): void {\n if (!event.defaultPrevented && this.#host.dismissible()) {\n event.stopPropagation();\n this.#closeReasonState.set('escape');\n this.#host.closeOpen();\n }\n }\n\n // The menubar has no per-trigger `(pointerDownOutside)` / `(focusOutside)` /\n // `(interactOutside)` outputs, so these emit forwarders have nowhere to\n // surface; the implicit close runs through `requestClose` below.\n emitPointerDownOutside(): void {}\n emitFocusOutside(): void {}\n emitInteractOutside(): void {}\n\n requestClose(reason: 'pointerDownOutside' | 'focusOutside'): void {\n if (this.#host.value() === '') {\n return;\n }\n this.#closeReasonState.set(reason);\n this.#host.closeOpen();\n }\n\n // Bar-level menus follow APG-prescribed focus movement and expose no\n // `(autoFocusOnOpen)` / `(autoFocusOnClose)` outputs, so the vetoes never\n // fire — the content's focus moves always run.\n emitAutoFocusOnOpen(): boolean {\n return false;\n }\n emitAutoFocusOnClose(): boolean {\n return false;\n }\n}\n","import { inject, InjectionToken, type ModelSignal, type Signal } from '@angular/core';\n\nimport {\n type CollectionHandle,\n type FloatingAlign,\n type FloatingSide,\n type ListNavigationAction,\n type WritingDirection,\n type MenuActivationModality,\n type MenuSiblingNavigator,\n} from 'forty-cdk/core';\n\n/**\n * Per-trigger configuration that the menubar root reads when its menu is the\n * one currently open. Each `[forMenubarTrigger]` registers one of these so\n * the menubar's multiplexed `ForMenuContext` (which `[forMenuContent]`\n * injects) can pull side / align, ids, anchor, and per-menu inputs from\n * the matching trigger.\n */\nexport interface ForMenubarTriggerHandle extends CollectionHandle {\n readonly value: Signal<string>;\n readonly disabled: Signal<boolean>;\n readonly triggerId: Signal<string>;\n readonly contentId: Signal<string>;\n readonly side: Signal<FloatingSide | undefined>;\n readonly align: Signal<FloatingAlign | undefined>;\n readonly sideOffset: Signal<number>;\n readonly alignOffset: Signal<number>;\n readonly avoidCollisions: Signal<boolean>;\n readonly collisionPadding: Signal<number>;\n readonly arrowPadding: Signal<number>;\n readonly sticky: Signal<'partial' | 'always' | false>;\n readonly hideWhenDetached: Signal<boolean>;\n readonly clipUntilPositioned: Signal<boolean>;\n readonly ariaLabel: Signal<string | null>;\n}\n\n/**\n * Coordination contract owned by `[forMenubar]`. Sibling triggers register\n * here so the bar can run cross-trigger navigation, roving tabindex,\n * typeahead, and the \"first open is intentional, subsequent are hover\"\n * (skip-delay) model — and so the multiplexed `ForMenuContext` can route\n * `[forMenuContent]` to whichever trigger is currently active.\n */\nexport interface ForMenubarContext extends MenuSiblingNavigator {\n /**\n * Two-way bindable. The value of the open trigger, or `''` for none.\n * The `model()` change emitter (`(valueChange)`) fires only on internal\n * transitions (trigger interaction, Escape, outside dismissal, item\n * select, cross-menu nav), never on consumer writes via `[(value)]`.\n */\n readonly value: ModelSignal<string>;\n readonly orientation: Signal<'horizontal' | 'vertical'>;\n readonly dir: Signal<WritingDirection>;\n readonly loop: Signal<boolean>;\n readonly disabled: Signal<boolean>;\n readonly ariaLabel: Signal<string | null>;\n\n registerTrigger(handle: ForMenubarTriggerHandle): void;\n unregisterTrigger(handle: ForMenubarTriggerHandle): void;\n\n /** All registered triggers in DOM order. */\n readonly triggers: Signal<readonly ForMenubarTriggerHandle[]>;\n\n /** Returns the trigger handle for `value`, or `null` if none matches. */\n triggerFor(value: string): ForMenubarTriggerHandle | null;\n\n /** Currently-open trigger handle, or `null` when no menu is open. */\n readonly activeTrigger: Signal<ForMenubarTriggerHandle | null>;\n\n /**\n * Returns `0` for the trigger element that should be in the tab sequence\n * and `-1` for the rest. The active stop is the open trigger, or the\n * most-recently-focused trigger, or the first enabled trigger when\n * nothing has been focused yet. Wire into a host binding on each trigger.\n */\n tabindexFor(el: HTMLElement): 0 | -1;\n\n /**\n * Promote `el` to the focused trigger so the roving tab stop follows\n * keyboard navigation. Called from each trigger's `(focus)` handler.\n */\n setFocusedTrigger(el: HTMLElement | null): void;\n\n /** Cross-trigger navigation. Used by triggers when no menu is open. */\n navigateTriggers(currentTrigger: HTMLElement, action: ListNavigationAction): void;\n\n /**\n * Open the trigger identified by `value`, focus its first or last item.\n * Called by the trigger itself (Enter/Space/click/ArrowDown/ArrowUp).\n * `modality` (default `'keyboard'`) records how the open was activated: a\n * `'pointer'` open (click, hover-after-open) keeps the programmatic\n * initial focus from reflecting `data-highlighted`, while a `'keyboard'`\n * open highlights the focused item.\n */\n openTrigger(\n value: string,\n initialFocus: 'first' | 'last',\n modality?: MenuActivationModality,\n ): void;\n\n /** Close the currently-open menu, if any. Returns focus to the trigger. */\n closeOpen(): void;\n\n /**\n * Hover-after-open. When some menu is open and pointer enters a sibling\n * trigger, that sibling's menu opens immediately. No-op while no menu\n * is open (first open requires keyboard / click).\n */\n pointerEnterTrigger(value: string): void;\n\n /** Typeahead at the trigger row matches sibling trigger labels. */\n handleTriggerTypeahead(event: KeyboardEvent): void;\n}\n\nexport const FOR_MENUBAR_CONTEXT = new InjectionToken<ForMenubarContext>('FOR_MENUBAR_CONTEXT');\n\nexport function injectMenubarContext(piece: string): ForMenubarContext {\n const ctx = inject(FOR_MENUBAR_CONTEXT, { optional: true });\n if (!ctx) {\n throw new Error(\n `[forty-cdk/menubar] ${piece} must be used inside a [forMenubar] element. ` +\n \"If it is declared inside an ng-template, DI resolves at the template's declaration site — \" +\n 'not where it is stamped (e.g. via ngTemplateOutlet) — so declare the template inside the ' +\n '[forMenubar] root.',\n );\n }\n return ctx;\n}\n","import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * Defaults inherited by descendant menubars in the surrounding injector\n * scope. Configure with `provideForMenubarDefaults` either at the\n * application root or in any component's `providers` array; partial\n * overrides merge with the parent scope.\n */\nexport interface ForMenubarDefaults {\n /** ms before the open menu closes after the pointer leaves the bar. */\n closeDelay: number;\n}\n\n/**\n * Library fallback for menubar defaults, read at the root injector when no\n * consumer has called `provideForMenubarDefaults`. Exported for the shared\n * defaults contract spec; not re-exported from the primitive's public entry.\n */\nexport const FOR_MENUBAR_FALLBACK_DEFAULTS: ForMenubarDefaults = {\n closeDelay: 150,\n};\n\nconst { token, provideDefaults } = createDefaults<ForMenubarDefaults>(\n 'FOR_MENUBAR_DEFAULTS',\n FOR_MENUBAR_FALLBACK_DEFAULTS,\n);\n\n/** Token holding the resolved menubar defaults for the current scope. */\nexport const FOR_MENUBAR_DEFAULTS = token;\n\n/**\n * Configures forty-cdk menubar defaults for this injector scope. Partial\n * overrides inherit unspecified keys from the parent scope (or library\n * defaults at the root).\n */\nexport function provideForMenubarDefaults(defaults: Partial<ForMenubarDefaults> = {}): Provider[] {\n return provideDefaults(defaults);\n}\n","import {\n booleanAttribute,\n computed,\n DestroyRef,\n Directive,\n inject,\n input,\n model,\n numberAttribute,\n signal,\n} from '@angular/core';\n\nimport {\n Collection,\n firstEnabledHost,\n createDebouncedAction,\n type ListNavigationAction,\n type WritingDirection,\n nextEnabledHandle,\n type MenuActivationModality,\n reconcileRovingActive,\n RovingTabindex,\n injectTextDirection,\n injectTypeahead,\n FOR_MENU_CONTEXT,\n} from 'forty-cdk/core';\nimport { MenubarMenuContext } from './menubar-menu-context';\nimport {\n FOR_MENUBAR_CONTEXT,\n type ForMenubarContext,\n type ForMenubarTriggerHandle,\n} from './menubar-context';\nimport { FOR_MENUBAR_DEFAULTS } from './menubar-defaults';\n\n/**\n * Headless implementation of the\n * [WAI-ARIA Menubar pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/).\n *\n * A horizontal (or vertical) bar of triggers, each opening a dropdown menu.\n * The bar owns \"which child menu is open\" — opening another implicitly\n * closes the previous. Cross-menu ArrowLeft / ArrowRight navigation,\n * hover-after-first-open (switch siblings instantly, dismiss on hover-leave\n * after `closeDelay`), and roving tabindex among triggers are wired\n * automatically.\n *\n * Surface composition:\n *\n * ```html\n * <div forMenubar [(value)]=\"open\">\n * <button forMenubarTrigger value=\"file\">File</button>\n * @if (open() === 'file') {\n * <div forMenuContent>\n * <button forMenuItem (activate)=\"newDoc()\">New</button>\n * </div>\n * }\n *\n * <button forMenubarTrigger value=\"edit\">Edit</button>\n * @if (open() === 'edit') {\n * <div forMenuContent>…</div>\n * }\n * </div>\n * ```\n *\n * `[forMenuContent]` is the same directive used by `[forDropdownMenu]` /\n * `[forContextMenu]`. The bar provides a multiplexed `ForMenuContext`\n * whose anchor / placement / ids are pulled from whichever trigger is\n * currently active, so the content directive needs no menubar-specific\n * code path.\n */\n@Directive({\n selector: '[forMenubar]',\n exportAs: 'forMenubar',\n host: {\n role: 'menubar',\n '[attr.aria-orientation]': 'orientation()',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\n '[attr.data-state]': 'value() === \"\" ? \"closed\" : \"open\"',\n '[attr.data-orientation]': 'orientation()',\n '[attr.data-disabled]': 'disabled() ? \"\" : null',\n '[attr.dir]': 'dir()',\n '(pointerenter)': 'cancelPendingClose()',\n '(pointermove)': 'cancelPendingClose()',\n '(pointerleave)': 'onBarPointerLeave($event)',\n },\n providers: [\n { provide: FOR_MENUBAR_CONTEXT, useExisting: ForMenubar },\n {\n provide: FOR_MENU_CONTEXT,\n useFactory: (m: ForMenubar) => m.menuCtx,\n deps: [ForMenubar],\n },\n ],\n})\nexport class ForMenubar implements ForMenubarContext {\n readonly #defaults = inject(FOR_MENUBAR_DEFAULTS);\n\n /**\n * Two-way bindable. The value of the open trigger, or `''` when none.\n * The `model()` change emitter (`(valueChange)`) fires only on internal\n * transitions (trigger interaction, item activation, Escape, outside\n * dismissal, cross-menu nav), never on consumer writes via `[(value)]`.\n */\n readonly value = model<string>('');\n\n readonly orientation = input<'horizontal' | 'vertical'>('horizontal');\n\n /**\n * Writing direction. When unset (default `null`), the inherited ambient\n * direction is resolved from the nearest ancestor carrying a `dir` attribute\n * (or `<html dir>`), defaulting to `'ltr'`. An explicit `[dir]` always wins.\n * The resolved value is reflected to the host `dir` attribute, swaps\n * cross-menu ArrowLeft / ArrowRight, and is inherited by descendant menus.\n */\n readonly _dirInput = input<WritingDirection | null>(null, { alias: 'dir' });\n readonly dir = injectTextDirection(this._dirInput);\n readonly loop = input(true, { transform: booleanAttribute });\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /**\n * Whether the open menu closes on Escape, an outside interaction, or the\n * pointer leaving the bar. When `false`, the menu stays open until the\n * consumer flips `value` (or a trigger / item interaction switches it).\n * Matches the dismiss contract of `[forDropdownMenu]` / `[forContextMenu]`.\n * Default `true`.\n */\n readonly dismissible = input(true, { transform: booleanAttribute });\n\n /** Optional accessible name for the menubar. */\n readonly ariaLabel = input<string | null>(null);\n\n /**\n * ms before the open menu closes after the pointer leaves the bar (and any\n * open menu). Default `150`. The default is read from\n * `provideForMenubarDefaults` for the surrounding scope.\n */\n readonly closeDelay = input<number>(this.#defaults.closeDelay, { transform: numberAttribute });\n\n readonly #triggerCollection = new Collection<ForMenubarTriggerHandle>();\n readonly triggers = this.#triggerCollection.items;\n\n readonly activeTrigger = computed<ForMenubarTriggerHandle | null>(() => {\n const v = this.value();\n if (v === '') {\n return null;\n }\n return this.#triggerCollection.items().find((t) => t.value() === v) ?? null;\n });\n\n /**\n * The most-recently-active trigger value. Persists past close so the\n * `[forMenuContent]` destroy hook can still target the trigger (by then\n * `value()` is already `''`). Updated synchronously by `openTrigger`\n * and snapshotted in `closeOpen` before clearing `value` — that covers\n * every internal close path (Escape, item activation, outside dismiss).\n */\n readonly #lastValue = signal<string>('');\n\n /**\n * The most-recently-active trigger host. Persists past close so the\n * multiplexed `[forMenuContent]` destroy hook can still target the trigger\n * (by then `value()` is already `''`). Consumed by {@link MenubarMenuContext}\n * as its return-focus `trigger`.\n */\n readonly lastTriggerHost = computed<HTMLElement | null>(() => {\n const v = this.value() || this.#lastValue();\n if (v === '') {\n return null;\n }\n return this.#triggerCollection.items().find((t) => t.value() === v)?.host ?? null;\n });\n\n readonly #firstEnabledTriggerHost = computed(() =>\n firstEnabledHost(this.#triggerCollection.items()),\n );\n\n /**\n * Roving-tabindex tracker shared by every menubar trigger, mirroring\n * `ForToolbar` / `ForTabs`. Triggers promote themselves to active on\n * `(focus)` (via {@link setFocusedTrigger}) and read `active()` through\n * {@link tabindexFor}, so re-entry restores the last focused trigger. Before\n * any focus — and on every close — `active()` is `null`/stale and the tab\n * stop falls back to the first enabled trigger. The active pointer is\n * self-healing (a detached / disabled trigger no longer owns the stop).\n */\n readonly roving = new RovingTabindex();\n\n readonly #triggerTypeahead = injectTypeahead();\n\n readonly #closeAction = createDebouncedAction(() => this.#closeByPointer());\n #detachContentPointerFn: (() => void) | null = null;\n\n constructor() {\n reconcileRovingActive(this.roving, this.#triggerCollection.items);\n inject(DestroyRef).onDestroy(() => {\n this.#closeAction.cancel();\n this.detachContentPointer();\n });\n }\n\n // -- Multiplexed ForMenuContext for the currently-active menu -------------\n\n /**\n * Single `ForMenuContext` provided to descendant `[forMenuContent]` and\n * items, implemented by the dedicated {@link MenubarMenuContext} class. Its\n * open / anchor / side / ids fields are derived from `activeTrigger`, so the\n * same context shape transparently covers whichever trigger's menu is\n * mounted. The bar's menu-item navigation reuses the shared `MenuItemList`\n * (the same mechanics that back `MenuOverlay`), so the multiplexing only\n * covers the parts the single-owner overlay can't.\n */\n readonly menuCtx: MenubarMenuContext = new MenubarMenuContext(this);\n\n // -- ForMenubarContext ----------------------------------------------------\n\n registerTrigger(handle: ForMenubarTriggerHandle): void {\n this.#triggerCollection.register(handle);\n }\n unregisterTrigger(handle: ForMenubarTriggerHandle): void {\n this.#triggerCollection.unregister(handle);\n this.roving.unregister(handle.host);\n }\n\n triggerFor(value: string): ForMenubarTriggerHandle | null {\n if (value === '') {\n return null;\n }\n return this.#triggerCollection.items().find((t) => t.value() === value) ?? null;\n }\n\n tabindexFor(el: HTMLElement): 0 | -1 {\n const v = this.value();\n if (v !== '') {\n // While a menu is open, only its trigger is tabbable.\n return this.activeTrigger()?.host === el ? 0 : -1;\n }\n // Otherwise the roving tracker (promoted by trigger `(focus)`) holds the\n // tab stop, falling back to the first enabled trigger when nothing has\n // been focused yet or the active trigger went stale.\n if (this.roving.hasActive()) {\n return this.roving.tabindexFor(el);\n }\n return this.#firstEnabledTriggerHost() === el ? 0 : -1;\n }\n\n setFocusedTrigger(el: HTMLElement | null): void {\n this.roving.setActive(el);\n }\n\n navigateTriggers(currentTrigger: HTMLElement, action: ListNavigationAction): void {\n if (this.disabled()) {\n return;\n }\n const target = nextEnabledHandle(this.#triggerCollection.items(), currentTrigger, action, {\n loop: this.loop(),\n });\n target?.host.focus();\n }\n\n openTrigger(\n value: string,\n initialFocus: 'first' | 'last',\n modality: MenuActivationModality = 'keyboard',\n ): void {\n if (this.disabled()) {\n return;\n }\n const handle = this.triggerFor(value);\n if (!handle || handle.disabled()) {\n return;\n }\n this.menuCtx.prepareOpen(initialFocus, modality);\n this.#lastValue.set(value);\n if (this.value() !== value) {\n this.value.set(value);\n }\n }\n\n closeOpen(): void {\n const current = this.value();\n if (current === '') {\n return;\n }\n // Snapshot so [forMenuContent]'s destroy hook can return focus to the\n // just-closed trigger via menuCtx.trigger (which falls back to #lastValue\n // once value() is '').\n this.#lastValue.set(current);\n this.value.set('');\n }\n\n switchToSibling(direction: 'next' | 'prev'): void {\n if (this.disabled()) {\n return;\n }\n const items = this.#triggerCollection.items();\n if (items.length === 0) {\n return;\n }\n const currentValue = this.value();\n const currentIndex = items.findIndex((t) => t.value() === currentValue);\n const target = nextEnabledHandle(items, currentIndex < 0 ? 0 : currentIndex, direction, {\n loop: this.loop(),\n });\n if (target === null) {\n return;\n }\n this.openTrigger(target.value(), 'first');\n }\n\n pointerEnterTrigger(value: string): void {\n if (this.disabled()) {\n return;\n }\n // Entering any trigger aborts a pending hover-leave close — the pointer\n // is still travelling across the bar, so keep the open menu alive.\n this.#closeAction.cancel();\n // Hover-after-open opens siblings instantly; while no menu is\n // open, hover does nothing (first open requires keyboard / click).\n if (this.value() === '' || this.value() === value) {\n return;\n }\n this.openTrigger(value, 'first', 'pointer');\n }\n\n /**\n * Abort a scheduled hover-leave close, if any. Bound to the bar's\n * `pointerenter` / `pointermove` so re-entering the bar (or its open menu)\n * keeps the menu open. Also called by the multiplexed content's\n * `pointerenter` so travelling from a trigger into its portaled menu does\n * not trip the close timer.\n */\n cancelPendingClose(): void {\n this.#closeAction.cancel();\n }\n\n /**\n * The pointer left the bar. Schedule a close after `closeDelay`; entering\n * the bar, a trigger, or the open menu again cancels it. No-op while no\n * menu is open or for non-mouse pointers (touch / pen drive open/close via\n * tap, not hover).\n */\n protected onBarPointerLeave(event: PointerEvent): void {\n if (event.pointerType !== '' && event.pointerType !== 'mouse') {\n return;\n }\n this.#scheduleCloseByPointer();\n }\n\n #scheduleCloseByPointer(): void {\n this.#closeAction.cancel();\n // A non-dismissible menu stays pinned open: hover-leave is held to the\n // same contract as Escape / outside interaction.\n if (this.value() === '' || !this.dismissible()) {\n return;\n }\n this.#closeAction.schedule(this.closeDelay());\n }\n\n #closeByPointer(): void {\n if (this.value() === '') {\n return;\n }\n this.menuCtx.setLastCloseReason('pointerDownOutside');\n this.closeOpen();\n }\n\n /**\n * Attach the bar's hover-keepalive listeners to the mounted multiplexed\n * content element so travelling from a trigger into its portaled menu keeps\n * the open chain alive. Called by {@link MenubarMenuContext} on content\n * registration.\n */\n attachContentPointer(el: HTMLElement): void {\n this.detachContentPointer();\n const onEnter = (event: PointerEvent): void => {\n if (event.pointerType !== '' && event.pointerType !== 'mouse') {\n return;\n }\n this.#closeAction.cancel();\n };\n const onLeave = (event: PointerEvent): void => {\n if (event.pointerType !== '' && event.pointerType !== 'mouse') {\n return;\n }\n this.#scheduleCloseByPointer();\n };\n el.addEventListener('pointerenter', onEnter);\n el.addEventListener('pointerleave', onLeave);\n this.#detachContentPointerFn = () => {\n el.removeEventListener('pointerenter', onEnter);\n el.removeEventListener('pointerleave', onLeave);\n };\n }\n\n /** Detach the bar's hover-keepalive listeners. Called by {@link MenubarMenuContext}. */\n detachContentPointer(): void {\n this.#detachContentPointerFn?.();\n this.#detachContentPointerFn = null;\n }\n\n handleTriggerTypeahead(event: KeyboardEvent): void {\n if (!this.#triggerTypeahead.handle(event)) {\n return;\n }\n const buffer = this.#triggerTypeahead.buffer().toLowerCase();\n if (!buffer) {\n return;\n }\n const items = this.#triggerCollection.items();\n const match = items.find((t) => {\n if (t.disabled()) {\n return false;\n }\n const text = t.host.textContent ?? '';\n return text.trim().toLowerCase().startsWith(buffer);\n });\n match?.host.focus();\n }\n}\n","import {\n booleanAttribute,\n computed,\n Directive,\n ElementRef,\n inject,\n input,\n numberAttribute,\n signal,\n} from '@angular/core';\n\nimport {\n registerHandle,\n type FloatingAlign,\n type FloatingSide,\n hostId,\n IdGenerator,\n resolveListNavigation,\n type MenuActivationModality,\n} from 'forty-cdk/core';\nimport { injectMenubarContext } from './menubar-context';\n\n/**\n * One trigger inside `[forMenubar]`. Apply on a `<button>` so Space / Enter\n * dispatch native click events that route through `(click)`.\n *\n * Wires `role=\"menuitem\"`, `aria-haspopup=\"menu\"`, `aria-expanded`, and\n * `aria-controls`. Participates in the menubar's roving tabindex (only the\n * active trigger is tabbable; the rest are `tabindex=\"-1\"`).\n *\n * Each trigger registers its per-menu floating-ui inputs (side, align,\n * sideOffset, …) with the menubar so the multiplexed `[forMenuContent]`\n * reads the right values when this trigger's menu is the one currently\n * open.\n *\n * Keyboard:\n * - **Click / Enter / Space** — toggle this trigger's menu (focus first item on open).\n * - **ArrowDown** — open and focus first item.\n * - **ArrowUp** — open and focus last item.\n * - **ArrowLeft / ArrowRight** — move focus across sibling triggers (RTL inverts).\n * - **Home / End** — jump to first / last enabled trigger.\n * - **Typeahead** — printable keys focus the first sibling trigger whose label\n * starts with the buffered string.\n *\n * While some other trigger's menu is open, hovering this trigger opens it\n * immediately (no delay) — \"first open is intentional, subsequent\n * are hover\". Keyboard focus alone never opens a menu.\n *\n * Pointer-driven opens (click — detected by the `pointerdown` preceding it —\n * and hover-after-open) move focus to the menu's first item without\n * highlighting it; keyboard activation (Enter / Space / ArrowDown / ArrowUp)\n * highlights the focused item.\n */\n@Directive({\n selector: '[forMenubarTrigger]',\n exportAs: 'forMenubarTrigger',\n host: {\n role: 'menuitem',\n type: 'button',\n '[id]': 'triggerId()',\n '[attr.tabindex]': 'tabindex()',\n '[attr.aria-haspopup]': '\"menu\"',\n '[attr.aria-expanded]': 'isOpen() ? \"true\" : \"false\"',\n '[attr.aria-controls]': 'isOpen() ? contentId() : null',\n '[attr.aria-disabled]': 'effectiveDisabled() ? \"true\" : null',\n '[attr.data-state]': 'isOpen() ? \"open\" : \"closed\"',\n '[attr.data-disabled]': 'effectiveDisabled() ? \"\" : null',\n '[attr.data-orientation]': 'menubar.orientation()',\n '(pointerdown)': 'onPointerDown()',\n '(click)': 'onClick()',\n '(keydown)': 'onKeyDown($event)',\n '(focus)': 'onFocus()',\n '(pointerenter)': 'onPointerEnter()',\n },\n})\nexport class ForMenubarTrigger {\n protected readonly menubar = injectMenubarContext('ForMenubarTrigger');\n readonly #host = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly #idGen = inject(IdGenerator);\n #pointerActivation = false;\n\n /** Identifies this trigger in the menubar's `value` model. */\n readonly value = input.required<string>();\n\n /** Per-trigger disabled, in addition to the menubar's `disabled`. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n // -- Floating-ui inputs (forwarded to the multiplexed [forMenuContent]) --\n\n /** Anchor side. Default `'bottom'`. */\n readonly side = input<FloatingSide | undefined>('bottom');\n /** Alignment along `side`. Default `'start'`. */\n readonly align = input<FloatingAlign | undefined>('start');\n /** Gap (px) along the main axis. Default `4`. */\n readonly sideOffset = input(4, { transform: numberAttribute });\n /** Gap (px) along the cross axis. Default `0`. */\n readonly alignOffset = input(0, { transform: numberAttribute });\n readonly avoidCollisions = input(true, { transform: booleanAttribute });\n readonly collisionPadding = input(8, { transform: numberAttribute });\n readonly arrowPadding = input(0, { transform: numberAttribute });\n readonly sticky = input<'partial' | 'always' | false>('partial');\n readonly hideWhenDetached = input(false, { transform: booleanAttribute });\n\n /**\n * When `true` (default), the content is clipped until floating-ui resolves\n * its first position, preventing a flash at the viewport corner. Set to\n * `false` so a dramatic `animate.enter` plays from its first frame (the\n * surface may flash briefly at the unresolved position while positioning\n * computes).\n */\n readonly clipUntilPositioned = input(true, { transform: booleanAttribute });\n\n /** Manual `aria-label` on `[forMenuContent]` when the trigger isn't a meaningful name. */\n readonly ariaLabel = input<string | null>(null);\n\n readonly triggerId = hostId('for-menubar-trigger');\n readonly contentId = signal(this.#idGen.next('for-menubar-content'));\n\n readonly effectiveDisabled = computed(() => this.disabled() || this.menubar.disabled());\n\n protected readonly isOpen = computed(() => this.menubar.value() === this.value());\n\n protected readonly tabindex = computed<0 | -1>(() => {\n if (this.effectiveDisabled()) {\n return -1;\n }\n return this.menubar.tabindexFor(this.#host.nativeElement);\n });\n\n constructor() {\n const handle = {\n host: this.#host.nativeElement,\n value: this.value,\n disabled: this.effectiveDisabled,\n triggerId: this.triggerId,\n contentId: this.contentId,\n side: this.side,\n align: this.align,\n sideOffset: this.sideOffset,\n alignOffset: this.alignOffset,\n avoidCollisions: this.avoidCollisions,\n collisionPadding: this.collisionPadding,\n arrowPadding: this.arrowPadding,\n sticky: this.sticky,\n hideWhenDetached: this.hideWhenDetached,\n clipUntilPositioned: this.clipUntilPositioned,\n ariaLabel: this.ariaLabel,\n };\n registerHandle(\n handle,\n (h) => this.menubar.registerTrigger(h),\n (h) => this.menubar.unregisterTrigger(h),\n );\n }\n\n protected onPointerDown(): void {\n this.#pointerActivation = true;\n }\n\n protected onClick(): void {\n const modality: MenuActivationModality = this.#pointerActivation ? 'pointer' : 'keyboard';\n this.#pointerActivation = false;\n if (this.effectiveDisabled()) {\n return;\n }\n if (this.isOpen()) {\n this.menubar.closeOpen();\n } else {\n this.menubar.openTrigger(this.value(), 'first', modality);\n }\n }\n\n protected onKeyDown(event: KeyboardEvent): void {\n this.#pointerActivation = false;\n if (this.effectiveDisabled()) {\n return;\n }\n // Open / focus-on-open first.\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.menubar.openTrigger(this.value(), 'first');\n return;\n }\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n this.menubar.openTrigger(this.value(), 'last');\n return;\n }\n\n // Trigger-row navigation (cross-axis to the open key, per APG).\n const action = resolveListNavigation(event, {\n orientation: this.menubar.orientation(),\n dir: this.menubar.dir(),\n });\n if (action) {\n event.preventDefault();\n this.menubar.navigateTriggers(this.#host.nativeElement, action);\n return;\n }\n\n // Typeahead among sibling triggers.\n this.menubar.handleTriggerTypeahead(event);\n }\n\n protected onFocus(): void {\n if (this.effectiveDisabled()) {\n return;\n }\n // Roving tab stop follows focus — but focus alone never opens a menu.\n // Keyboard traversal across triggers (ArrowLeft / ArrowRight, typeahead)\n // only moves focus; opening is reserved for hover (pointerenter),\n // click, and the open keys. Cross-menu nav while a menu is open is driven\n // by the items, not by trigger focus.\n this.menubar.setFocusedTrigger(this.#host.nativeElement);\n }\n\n protected onPointerEnter(): void {\n if (this.effectiveDisabled()) {\n return;\n }\n this.menubar.pointerEnterTrigger(this.value());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, model, input, computed, Directive } from '@angular/core';
|
|
3
|
+
import { clamp, createDefaults } from 'forty-cdk/core';
|
|
4
|
+
|
|
5
|
+
const FOR_METER_CONTEXT = new InjectionToken('FOR_METER_CONTEXT');
|
|
6
|
+
/**
|
|
7
|
+
* Injects the nearest {@link ForMeterContext}, throwing a descriptive error
|
|
8
|
+
* when used outside a `[forMeter]` element.
|
|
9
|
+
*
|
|
10
|
+
* @param piece Name of the calling directive, used in the error message.
|
|
11
|
+
*/
|
|
12
|
+
function injectMeterContext(piece) {
|
|
13
|
+
const ctx = inject(FOR_METER_CONTEXT, { optional: true });
|
|
14
|
+
if (!ctx) {
|
|
15
|
+
throw new Error(`[forty-cdk/meter] ${piece} must be used inside a [forMeter] element.`);
|
|
16
|
+
}
|
|
17
|
+
return ctx;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Headless implementation of the
|
|
22
|
+
* [WAI-ARIA Meter pattern](https://www.w3.org/WAI/ARIA/apg/patterns/meter/),
|
|
23
|
+
* mirroring the HTML5 `<meter>` element semantics.
|
|
24
|
+
*
|
|
25
|
+
* A meter represents a known scalar measurement within a range — disk usage,
|
|
26
|
+
* battery level, score, queue depth — **not** a task in progress. Use
|
|
27
|
+
* `[forProgress]` for the latter.
|
|
28
|
+
*
|
|
29
|
+
* The optional `low`, `high`, and `optimum` inputs let you shape the "quality
|
|
30
|
+
* bucket" reflected on `data-quality` (`optimum` / `sub-optimum` /
|
|
31
|
+
* `even-less-good`) for CSS styling.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```html
|
|
35
|
+
* <div forMeter [value]="diskUsed()" min="0" max="100" [low]="20" [high]="80" [optimum]="40">
|
|
36
|
+
* <div forMeterIndicator></div>
|
|
37
|
+
* </div>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
class ForMeter {
|
|
41
|
+
/**
|
|
42
|
+
* Two-way bindable. Current measurement, clamped to `[min, max]` for
|
|
43
|
+
* everything reflected on the host. The model retains what the consumer
|
|
44
|
+
* wrote so external bindings are not surprised.
|
|
45
|
+
*/
|
|
46
|
+
value = model(0, /* @ts-ignore */
|
|
47
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
48
|
+
/** Lower bound. Defaults to `0`. */
|
|
49
|
+
min = input(0, /* @ts-ignore */
|
|
50
|
+
...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
|
|
51
|
+
/** Upper bound. Defaults to `100`. */
|
|
52
|
+
max = input(100, /* @ts-ignore */
|
|
53
|
+
...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
54
|
+
/**
|
|
55
|
+
* Optional lower boundary of the "OK" range. Values below `low` are
|
|
56
|
+
* treated as below the comfortable region. `null` means no lower band.
|
|
57
|
+
*/
|
|
58
|
+
low = input(null, /* @ts-ignore */
|
|
59
|
+
...(ngDevMode ? [{ debugName: "low" }] : /* istanbul ignore next */ []));
|
|
60
|
+
/**
|
|
61
|
+
* Optional upper boundary of the "OK" range. Values above `high` are
|
|
62
|
+
* treated as above the comfortable region. `null` means no upper band.
|
|
63
|
+
*/
|
|
64
|
+
high = input(null, /* @ts-ignore */
|
|
65
|
+
...(ngDevMode ? [{ debugName: "high" }] : /* istanbul ignore next */ []));
|
|
66
|
+
/**
|
|
67
|
+
* Optional point at which the value is considered ideal. Falls back to
|
|
68
|
+
* the midpoint of `[min, max]`. Determines which region is `optimum`,
|
|
69
|
+
* which is `sub-optimum`, and which is `even-less-good` (see HTML5 spec).
|
|
70
|
+
*/
|
|
71
|
+
optimum = input(null, /* @ts-ignore */
|
|
72
|
+
...(ngDevMode ? [{ debugName: "optimum" }] : /* istanbul ignore next */ []));
|
|
73
|
+
/**
|
|
74
|
+
* Optional override for `aria-valuetext`. Receives the clamped value,
|
|
75
|
+
* `min`, and `max`.
|
|
76
|
+
*/
|
|
77
|
+
getValueLabel = input(null, /* @ts-ignore */
|
|
78
|
+
...(ngDevMode ? [{ debugName: "getValueLabel" }] : /* istanbul ignore next */ []));
|
|
79
|
+
#range = computed(() => {
|
|
80
|
+
const min = this.min();
|
|
81
|
+
const max = Math.max(this.max(), min);
|
|
82
|
+
return { min, max };
|
|
83
|
+
}, /* @ts-ignore */
|
|
84
|
+
...(ngDevMode ? [{ debugName: "#range" }] : /* istanbul ignore next */ []));
|
|
85
|
+
clampedValue = computed(() => {
|
|
86
|
+
const { min, max } = this.#range();
|
|
87
|
+
return clamp(this.value(), min, max);
|
|
88
|
+
}, /* @ts-ignore */
|
|
89
|
+
...(ngDevMode ? [{ debugName: "clampedValue" }] : /* istanbul ignore next */ []));
|
|
90
|
+
percentage = computed(() => {
|
|
91
|
+
const { min, max } = this.#range();
|
|
92
|
+
if (max === min)
|
|
93
|
+
return 0;
|
|
94
|
+
return ((this.clampedValue() - min) / (max - min)) * 100;
|
|
95
|
+
}, /* @ts-ignore */
|
|
96
|
+
...(ngDevMode ? [{ debugName: "percentage" }] : /* istanbul ignore next */ []));
|
|
97
|
+
quality = computed(() => {
|
|
98
|
+
const { min, max } = this.#range();
|
|
99
|
+
let low = this.low() ?? min;
|
|
100
|
+
let high = this.high() ?? max;
|
|
101
|
+
if (low < min)
|
|
102
|
+
low = min;
|
|
103
|
+
if (high > max)
|
|
104
|
+
high = max;
|
|
105
|
+
if (low > high)
|
|
106
|
+
low = high;
|
|
107
|
+
let optimum = this.optimum() ?? (min + max) / 2;
|
|
108
|
+
if (optimum < min)
|
|
109
|
+
optimum = min;
|
|
110
|
+
if (optimum > max)
|
|
111
|
+
optimum = max;
|
|
112
|
+
const v = this.clampedValue();
|
|
113
|
+
if (optimum < low) {
|
|
114
|
+
if (v < low)
|
|
115
|
+
return 'optimum';
|
|
116
|
+
if (v <= high)
|
|
117
|
+
return 'sub-optimum';
|
|
118
|
+
return 'even-less-good';
|
|
119
|
+
}
|
|
120
|
+
if (optimum > high) {
|
|
121
|
+
if (v > high)
|
|
122
|
+
return 'optimum';
|
|
123
|
+
if (v >= low)
|
|
124
|
+
return 'sub-optimum';
|
|
125
|
+
return 'even-less-good';
|
|
126
|
+
}
|
|
127
|
+
return v >= low && v <= high ? 'optimum' : 'sub-optimum';
|
|
128
|
+
}, /* @ts-ignore */
|
|
129
|
+
...(ngDevMode ? [{ debugName: "quality" }] : /* istanbul ignore next */ []));
|
|
130
|
+
ariaValueText = computed(() => {
|
|
131
|
+
const label = this.getValueLabel();
|
|
132
|
+
if (!label)
|
|
133
|
+
return null;
|
|
134
|
+
const { min, max } = this.#range();
|
|
135
|
+
return label(this.clampedValue(), min, max);
|
|
136
|
+
}, /* @ts-ignore */
|
|
137
|
+
...(ngDevMode ? [{ debugName: "ariaValueText" }] : /* istanbul ignore next */ []));
|
|
138
|
+
percentageAttr = computed(() => Math.round(this.percentage() * 100) / 100, /* @ts-ignore */
|
|
139
|
+
...(ngDevMode ? [{ debugName: "percentageAttr" }] : /* istanbul ignore next */ []));
|
|
140
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForMeter, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
141
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForMeter, isStandalone: true, selector: "[forMeter]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, low: { classPropertyName: "low", publicName: "low", isSignal: true, isRequired: false, transformFunction: null }, high: { classPropertyName: "high", publicName: "high", isSignal: true, isRequired: false, transformFunction: null }, optimum: { classPropertyName: "optimum", publicName: "optimum", isSignal: true, isRequired: false, transformFunction: null }, getValueLabel: { classPropertyName: "getValueLabel", publicName: "getValueLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { attributes: { "role": "meter" }, properties: { "attr.aria-valuemin": "min()", "attr.aria-valuemax": "max()", "attr.aria-valuenow": "clampedValue()", "attr.aria-valuetext": "ariaValueText()", "attr.data-quality": "quality()", "attr.data-value": "clampedValue()", "attr.data-min": "min()", "attr.data-max": "max()", "attr.data-percentage": "percentageAttr()" } }, providers: [{ provide: FOR_METER_CONTEXT, useExisting: ForMeter }], exportAs: ["forMeter"], ngImport: i0 });
|
|
142
|
+
}
|
|
143
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForMeter, decorators: [{
|
|
144
|
+
type: Directive,
|
|
145
|
+
args: [{
|
|
146
|
+
selector: '[forMeter]',
|
|
147
|
+
exportAs: 'forMeter',
|
|
148
|
+
host: {
|
|
149
|
+
role: 'meter',
|
|
150
|
+
'[attr.aria-valuemin]': 'min()',
|
|
151
|
+
'[attr.aria-valuemax]': 'max()',
|
|
152
|
+
'[attr.aria-valuenow]': 'clampedValue()',
|
|
153
|
+
'[attr.aria-valuetext]': 'ariaValueText()',
|
|
154
|
+
'[attr.data-quality]': 'quality()',
|
|
155
|
+
'[attr.data-value]': 'clampedValue()',
|
|
156
|
+
'[attr.data-min]': 'min()',
|
|
157
|
+
'[attr.data-max]': 'max()',
|
|
158
|
+
'[attr.data-percentage]': 'percentageAttr()',
|
|
159
|
+
},
|
|
160
|
+
providers: [{ provide: FOR_METER_CONTEXT, useExisting: ForMeter }],
|
|
161
|
+
}]
|
|
162
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], low: [{ type: i0.Input, args: [{ isSignal: true, alias: "low", required: false }] }], high: [{ type: i0.Input, args: [{ isSignal: true, alias: "high", required: false }] }], optimum: [{ type: i0.Input, args: [{ isSignal: true, alias: "optimum", required: false }] }], getValueLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "getValueLabel", required: false }] }] } });
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Visual fill paired with `[forMeter]`. Reflects `data-quality`,
|
|
166
|
+
* `data-percentage`, and the CSS custom property `--for-meter-percentage`
|
|
167
|
+
* so the consumer can drive width / transform from CSS.
|
|
168
|
+
*/
|
|
169
|
+
class ForMeterIndicator {
|
|
170
|
+
context = injectMeterContext('ForMeterIndicator');
|
|
171
|
+
percentageStyle() {
|
|
172
|
+
return `${this.context.percentageAttr()}%`;
|
|
173
|
+
}
|
|
174
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForMeterIndicator, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
175
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: ForMeterIndicator, isStandalone: true, selector: "[forMeterIndicator]", host: { properties: { "attr.data-quality": "context.quality()", "attr.data-value": "context.clampedValue()", "attr.data-min": "context.min()", "attr.data-max": "context.max()", "attr.data-percentage": "context.percentageAttr()", "style.--for-meter-percentage": "percentageStyle()" } }, exportAs: ["forMeterIndicator"], ngImport: i0 });
|
|
176
|
+
}
|
|
177
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForMeterIndicator, decorators: [{
|
|
178
|
+
type: Directive,
|
|
179
|
+
args: [{
|
|
180
|
+
selector: '[forMeterIndicator]',
|
|
181
|
+
exportAs: 'forMeterIndicator',
|
|
182
|
+
host: {
|
|
183
|
+
'[attr.data-quality]': 'context.quality()',
|
|
184
|
+
'[attr.data-value]': 'context.clampedValue()',
|
|
185
|
+
'[attr.data-min]': 'context.min()',
|
|
186
|
+
'[attr.data-max]': 'context.max()',
|
|
187
|
+
'[attr.data-percentage]': 'context.percentageAttr()',
|
|
188
|
+
'[style.--for-meter-percentage]': 'percentageStyle()',
|
|
189
|
+
},
|
|
190
|
+
}]
|
|
191
|
+
}] });
|
|
192
|
+
|
|
193
|
+
const FALLBACK = {};
|
|
194
|
+
const { token, provideDefaults } = createDefaults('FOR_METER_DEFAULTS', FALLBACK);
|
|
195
|
+
/** Token holding the resolved meter defaults for the current scope. */
|
|
196
|
+
const FOR_METER_DEFAULTS = token;
|
|
197
|
+
/**
|
|
198
|
+
* Configures forty-cdk meter defaults for this injector scope. Partial
|
|
199
|
+
* overrides inherit unspecified keys from the parent scope (or library
|
|
200
|
+
* defaults at the root).
|
|
201
|
+
*/
|
|
202
|
+
function provideForMeterDefaults(defaults = {}) {
|
|
203
|
+
return provideDefaults(defaults);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Generated bundle index. Do not edit.
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
export { FOR_METER_CONTEXT, FOR_METER_DEFAULTS, ForMeter, ForMeterIndicator, provideForMeterDefaults };
|
|
211
|
+
//# sourceMappingURL=forty-cdk-meter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forty-cdk-meter.mjs","sources":["../../../projects/forty-cdk/meter/src/meter-context.ts","../../../projects/forty-cdk/meter/src/meter.ts","../../../projects/forty-cdk/meter/src/meter-indicator.ts","../../../projects/forty-cdk/meter/src/meter-defaults.ts","../../../projects/forty-cdk/meter/src/forty-cdk-meter.ts"],"sourcesContent":["import { inject, InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Quality bucket reflected on `data-quality`. Mirrors the HTML5 `<meter>`\n * algorithm:\n * - `optimum`: the value sits in the optimal region.\n * - `sub-optimum`: less than ideal but still acceptable.\n * - `even-less-good`: opposite side of optimum, the worst region.\n */\nexport type ForMeterQuality = 'optimum' | 'sub-optimum' | 'even-less-good';\n\nexport interface ForMeterContext {\n /** Clamped to `[min, max]`. Use this for any visual / ARIA reflection. */\n readonly clampedValue: Signal<number>;\n readonly min: Signal<number>;\n readonly max: Signal<number>;\n /** `0..100`. */\n readonly percentage: Signal<number>;\n /**\n * {@link percentage} rounded to two decimals for the `data-percentage`\n * reflection. Owned by the root so the indicator mirrors it instead of\n * re-implementing the rounding.\n */\n readonly percentageAttr: Signal<number>;\n readonly quality: Signal<ForMeterQuality>;\n}\n\nexport const FOR_METER_CONTEXT = new InjectionToken<ForMeterContext>('FOR_METER_CONTEXT');\n\n/**\n * Injects the nearest {@link ForMeterContext}, throwing a descriptive error\n * when used outside a `[forMeter]` element.\n *\n * @param piece Name of the calling directive, used in the error message.\n */\nexport function injectMeterContext(piece: string): ForMeterContext {\n const ctx = inject(FOR_METER_CONTEXT, { optional: true });\n if (!ctx) {\n throw new Error(`[forty-cdk/meter] ${piece} must be used inside a [forMeter] element.`);\n }\n return ctx;\n}\n","import { computed, Directive, input, model } from '@angular/core';\n\nimport { clamp } from 'forty-cdk/core';\nimport { FOR_METER_CONTEXT, type ForMeterContext, type ForMeterQuality } from './meter-context';\n\n/**\n * Headless implementation of the\n * [WAI-ARIA Meter pattern](https://www.w3.org/WAI/ARIA/apg/patterns/meter/),\n * mirroring the HTML5 `<meter>` element semantics.\n *\n * A meter represents a known scalar measurement within a range — disk usage,\n * battery level, score, queue depth — **not** a task in progress. Use\n * `[forProgress]` for the latter.\n *\n * The optional `low`, `high`, and `optimum` inputs let you shape the \"quality\n * bucket\" reflected on `data-quality` (`optimum` / `sub-optimum` /\n * `even-less-good`) for CSS styling.\n *\n * @example\n * ```html\n * <div forMeter [value]=\"diskUsed()\" min=\"0\" max=\"100\" [low]=\"20\" [high]=\"80\" [optimum]=\"40\">\n * <div forMeterIndicator></div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[forMeter]',\n exportAs: 'forMeter',\n host: {\n role: 'meter',\n '[attr.aria-valuemin]': 'min()',\n '[attr.aria-valuemax]': 'max()',\n '[attr.aria-valuenow]': 'clampedValue()',\n '[attr.aria-valuetext]': 'ariaValueText()',\n '[attr.data-quality]': 'quality()',\n '[attr.data-value]': 'clampedValue()',\n '[attr.data-min]': 'min()',\n '[attr.data-max]': 'max()',\n '[attr.data-percentage]': 'percentageAttr()',\n },\n providers: [{ provide: FOR_METER_CONTEXT, useExisting: ForMeter }],\n})\nexport class ForMeter implements ForMeterContext {\n /**\n * Two-way bindable. Current measurement, clamped to `[min, max]` for\n * everything reflected on the host. The model retains what the consumer\n * wrote so external bindings are not surprised.\n */\n readonly value = model<number>(0);\n\n /** Lower bound. Defaults to `0`. */\n readonly min = input<number>(0);\n\n /** Upper bound. Defaults to `100`. */\n readonly max = input<number>(100);\n\n /**\n * Optional lower boundary of the \"OK\" range. Values below `low` are\n * treated as below the comfortable region. `null` means no lower band.\n */\n readonly low = input<number | null>(null);\n\n /**\n * Optional upper boundary of the \"OK\" range. Values above `high` are\n * treated as above the comfortable region. `null` means no upper band.\n */\n readonly high = input<number | null>(null);\n\n /**\n * Optional point at which the value is considered ideal. Falls back to\n * the midpoint of `[min, max]`. Determines which region is `optimum`,\n * which is `sub-optimum`, and which is `even-less-good` (see HTML5 spec).\n */\n readonly optimum = input<number | null>(null);\n\n /**\n * Optional override for `aria-valuetext`. Receives the clamped value,\n * `min`, and `max`.\n */\n readonly getValueLabel = input<((value: number, min: number, max: number) => string) | null>(\n null,\n );\n\n readonly #range = computed(() => {\n const min = this.min();\n const max = Math.max(this.max(), min);\n return { min, max };\n });\n\n readonly clampedValue = computed<number>(() => {\n const { min, max } = this.#range();\n return clamp(this.value(), min, max);\n });\n\n readonly percentage = computed<number>(() => {\n const { min, max } = this.#range();\n if (max === min) return 0;\n return ((this.clampedValue() - min) / (max - min)) * 100;\n });\n\n readonly quality = computed<ForMeterQuality>(() => {\n const { min, max } = this.#range();\n let low = this.low() ?? min;\n let high = this.high() ?? max;\n if (low < min) low = min;\n if (high > max) high = max;\n if (low > high) low = high;\n let optimum = this.optimum() ?? (min + max) / 2;\n if (optimum < min) optimum = min;\n if (optimum > max) optimum = max;\n const v = this.clampedValue();\n\n if (optimum < low) {\n if (v < low) return 'optimum';\n if (v <= high) return 'sub-optimum';\n return 'even-less-good';\n }\n if (optimum > high) {\n if (v > high) return 'optimum';\n if (v >= low) return 'sub-optimum';\n return 'even-less-good';\n }\n return v >= low && v <= high ? 'optimum' : 'sub-optimum';\n });\n\n readonly ariaValueText = computed<string | null>(() => {\n const label = this.getValueLabel();\n if (!label) return null;\n const { min, max } = this.#range();\n return label(this.clampedValue(), min, max);\n });\n\n readonly percentageAttr = computed<number>(() => Math.round(this.percentage() * 100) / 100);\n}\n","import { Directive } from '@angular/core';\n\nimport { injectMeterContext } from './meter-context';\n\n/**\n * Visual fill paired with `[forMeter]`. Reflects `data-quality`,\n * `data-percentage`, and the CSS custom property `--for-meter-percentage`\n * so the consumer can drive width / transform from CSS.\n */\n@Directive({\n selector: '[forMeterIndicator]',\n exportAs: 'forMeterIndicator',\n host: {\n '[attr.data-quality]': 'context.quality()',\n '[attr.data-value]': 'context.clampedValue()',\n '[attr.data-min]': 'context.min()',\n '[attr.data-max]': 'context.max()',\n '[attr.data-percentage]': 'context.percentageAttr()',\n '[style.--for-meter-percentage]': 'percentageStyle()',\n },\n})\nexport class ForMeterIndicator {\n protected readonly context = injectMeterContext('ForMeterIndicator');\n\n protected percentageStyle(): string {\n return `${this.context.percentageAttr()}%`;\n }\n}\n","import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * Defaults inherited by descendant meters in the surrounding injector\n * scope. Configure with `provideForMeterDefaults`. The shape is a stub\n * today — present so future per-scope tuning can land without churning the\n * public surface.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface ForMeterDefaults {}\n\nconst FALLBACK: ForMeterDefaults = {};\n\nconst { token, provideDefaults } = createDefaults<ForMeterDefaults>('FOR_METER_DEFAULTS', FALLBACK);\n\n/** Token holding the resolved meter defaults for the current scope. */\nexport const FOR_METER_DEFAULTS = token;\n\n/**\n * Configures forty-cdk meter defaults for this injector scope. Partial\n * overrides inherit unspecified keys from the parent scope (or library\n * defaults at the root).\n */\nexport function provideForMeterDefaults(defaults: Partial<ForMeterDefaults> = {}): Provider[] {\n return provideDefaults(defaults);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|