@skra/ui 0.4.0 → 0.5.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.
Files changed (60) hide show
  1. package/fesm2022/skra-ui-accordion.mjs +2 -2
  2. package/fesm2022/skra-ui-accordion.mjs.map +1 -1
  3. package/fesm2022/skra-ui-alert.mjs +2 -2
  4. package/fesm2022/skra-ui-alert.mjs.map +1 -1
  5. package/fesm2022/skra-ui-avatar.mjs.map +1 -1
  6. package/fesm2022/skra-ui-badge.mjs.map +1 -1
  7. package/fesm2022/skra-ui-button.mjs +2 -2
  8. package/fesm2022/skra-ui-button.mjs.map +1 -1
  9. package/fesm2022/skra-ui-checkbox.mjs +2 -2
  10. package/fesm2022/skra-ui-checkbox.mjs.map +1 -1
  11. package/fesm2022/skra-ui-chip.mjs +2 -2
  12. package/fesm2022/skra-ui-chip.mjs.map +1 -1
  13. package/fesm2022/skra-ui-combobox.mjs +120 -120
  14. package/fesm2022/skra-ui-combobox.mjs.map +1 -1
  15. package/fesm2022/skra-ui-core.mjs +36 -36
  16. package/fesm2022/skra-ui-core.mjs.map +1 -1
  17. package/fesm2022/skra-ui-counter.mjs.map +1 -1
  18. package/fesm2022/skra-ui-datepicker.mjs +605 -190
  19. package/fesm2022/skra-ui-datepicker.mjs.map +1 -1
  20. package/fesm2022/skra-ui-dialog.mjs.map +1 -1
  21. package/fesm2022/skra-ui-field.mjs.map +1 -1
  22. package/fesm2022/skra-ui-icon.mjs.map +1 -1
  23. package/fesm2022/skra-ui-input.mjs +2 -2
  24. package/fesm2022/skra-ui-input.mjs.map +1 -1
  25. package/fesm2022/skra-ui-kbd.mjs.map +1 -1
  26. package/fesm2022/skra-ui-layout.mjs.map +1 -1
  27. package/fesm2022/skra-ui-link.mjs +2 -2
  28. package/fesm2022/skra-ui-link.mjs.map +1 -1
  29. package/fesm2022/skra-ui-loading-indicator.mjs.map +1 -1
  30. package/fesm2022/skra-ui-menu.mjs +2 -2
  31. package/fesm2022/skra-ui-menu.mjs.map +1 -1
  32. package/fesm2022/skra-ui-multi-select.mjs +94 -94
  33. package/fesm2022/skra-ui-multi-select.mjs.map +1 -1
  34. package/fesm2022/skra-ui-native-select.mjs +2 -2
  35. package/fesm2022/skra-ui-native-select.mjs.map +1 -1
  36. package/fesm2022/skra-ui-popover.mjs.map +1 -1
  37. package/fesm2022/skra-ui-progress.mjs.map +1 -1
  38. package/fesm2022/skra-ui-radio.mjs +2 -2
  39. package/fesm2022/skra-ui-radio.mjs.map +1 -1
  40. package/fesm2022/skra-ui-rating-display.mjs.map +1 -1
  41. package/fesm2022/skra-ui-select.mjs +92 -92
  42. package/fesm2022/skra-ui-select.mjs.map +1 -1
  43. package/fesm2022/skra-ui-skeleton.mjs +8 -8
  44. package/fesm2022/skra-ui-skeleton.mjs.map +1 -1
  45. package/fesm2022/skra-ui-star-rating.mjs +2 -2
  46. package/fesm2022/skra-ui-star-rating.mjs.map +1 -1
  47. package/fesm2022/skra-ui-status-dot.mjs.map +1 -1
  48. package/fesm2022/skra-ui-switch.mjs +2 -2
  49. package/fesm2022/skra-ui-switch.mjs.map +1 -1
  50. package/fesm2022/skra-ui-tabs.mjs +2 -2
  51. package/fesm2022/skra-ui-tabs.mjs.map +1 -1
  52. package/fesm2022/skra-ui-textarea.mjs +2 -2
  53. package/fesm2022/skra-ui-textarea.mjs.map +1 -1
  54. package/fesm2022/skra-ui-toast.mjs +2 -2
  55. package/fesm2022/skra-ui-toast.mjs.map +1 -1
  56. package/fesm2022/skra-ui-tooltip.mjs.map +1 -1
  57. package/fesm2022/skra-ui-typography.mjs.map +1 -1
  58. package/package.json +3 -3
  59. package/types/skra-ui-datepicker.d.ts +146 -46
  60. package/types/skra-ui-datepicker.d.ts.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-tabs.mjs","sources":["../../../../libs/ui/tabs/src/lib/tabs/tabs-context.ts","../../../../libs/ui/tabs/src/lib/tabs/tab.ts","../../../../libs/ui/tabs/src/lib/tabs/tab-panel.ts","../../../../libs/ui/tabs/src/lib/tabs/tabs-keyboard.ts","../../../../libs/ui/tabs/src/lib/tabs/tabs.ts","../../../../libs/ui/tabs/src/lib/tabs/tablist.ts","../../../../libs/ui/tabs/src/skra-ui-tabs.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\r\n\r\n/** Module-global counter → a deterministic, unique id base per `[skraTabs]` instance.\r\n * Equivalent to the forms `IdGeneratorService` (ADR 013) but lib-local, so `@skra/navigation`\r\n * takes no dependency on `@skra/forms` just for id generation. Stable across SSR↔hydration\r\n * (same instantiation order yields the same ids — the standard counter technique). */\r\nlet tabsInstanceCounter = 0;\r\n\r\n/** Sanitize a consumer `value` into an id-safe fragment (no spaces / special chars). */\r\nfunction idSafe(value: string): string {\r\n return value.replace(/[^a-zA-Z0-9_-]/g, '-');\r\n}\r\n\r\n/**\r\n * DI Context provided per `[skraTabs]` instance — the ADR 013 §3.6 **non-form** Contextual-ID-Sync\r\n * bus wiring `tab` ↔ `tabpanel`. It carries **IDs + derived, read-only interaction state only**\r\n * (`selected` mirrors the consumer's `[selected]`; `activeValue` is the roving-focus position). It\r\n * **never owns value** — selection stays consumer-owned (ADR 037); a tab requests a change through\r\n * `select()`, which the coordinator implements and from which it emits `(selectedChange)`.\r\n */\r\n@Injectable()\r\nexport class SkraTabsContext {\r\n /** Unique per `[skraTabs]` — the prefix for every tab/panel id in this group. */\r\n private readonly baseId = `skra-tabs-${++tabsInstanceCounter}`;\r\n\r\n /** Mirror of the consumer's `[selected]` — drives `aria-selected` + panel visibility (read-only to children). */\r\n readonly selected = signal<string>('');\r\n /** Roving-focus position — the value of the tab that currently carries `tabindex=\"0\"` (read-only to children). */\r\n readonly activeValue = signal<string>('');\r\n /** Activation model (read-only to children). */\r\n readonly activation = signal<'automatic' | 'manual'>('automatic');\r\n\r\n tabId(value: string): string {\r\n return `${this.baseId}-tab-${idSafe(value)}`;\r\n }\r\n panelId(value: string): string {\r\n return `${this.baseId}-panel-${idSafe(value)}`;\r\n }\r\n isSelected(value: string): boolean {\r\n return this.selected() === value;\r\n }\r\n\r\n /** Coordinator-assigned: a tab/keyboard requests selection (the coordinator emits `(selectedChange)`). */\r\n select: (value: string) => void = () => undefined;\r\n /** Coordinator-assigned: the tablist forwards its `keydown` here (routed to the keyboard controller). */\r\n handleKeydown: (event: KeyboardEvent) => void = () => undefined;\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n ViewEncapsulation,\r\n computed,\r\n inject,\r\n input,\r\n} from '@angular/core';\r\n\r\nimport { SkraTabsContext } from './tabs-context';\r\nimport type { SkraTabKeyItem } from './tabs-types';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/**\r\n * SkraTab — a single tab, a Component on the native command host `button[skraTab]` (ADR 012/040:\r\n * a `<button>` gives Enter/Space→click + focusability for free; its implicit role is overridden to\r\n * `role=\"tab\"`, the precedent set by `button[skraMenuItem]`).\r\n *\r\n * Roving tabindex: `tabindex=\"0\"` only when this tab is the roving stop (`SkraTabsContext.activeValue`),\r\n * else `-1` — the controller (`SkraTabsKeyboard`) moves real focus. `aria-selected` reflects the\r\n * consumer-owned selection (`[selected]`), NOT the roving focus — and is the source of truth for the\r\n * selected STYLE too (CSS keys off `:host([aria-selected=\"true\"])`; no `data-skra-*`). On activation it\r\n * REQUESTS selection from the coordinator (`ctx.select`) — it never mutates selection itself (ADR 037).\r\n *\r\n * **Disabled is native-attr-first (boundary #9): the consumer sets the native `disabled` attribute** —\r\n * Forge OBSERVES it (no `disabled` input). A disabled tab is SKIPPED in the roving order (APG).\r\n */\r\n@Component({\r\n selector: 'button[skraTab]',\r\n standalone: true,\r\n exportAs: 'skraTab',\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './tab.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n role: 'tab',\r\n type: 'button', // never an implicit submit if the tablist sits inside a <form>\r\n '[attr.id]': 'tabId()',\r\n '[attr.aria-controls]': 'panelId()',\r\n '[attr.aria-selected]': 'ariaSelected()',\r\n '[attr.tabindex]': 'tabindex()',\r\n '(click)': 'onClick()',\r\n },\r\n})\r\nexport class SkraTab implements SkraTabKeyItem {\r\n /** Selection key — matched against `skraTabs [selected]` and the owning panel's `value`. */\r\n readonly value = input.required<string>();\r\n\r\n private readonly host = inject<ElementRef<HTMLButtonElement>>(ElementRef);\r\n private readonly ctx = inject(SkraTabsContext, { optional: true });\r\n\r\n protected readonly tabId = computed(\r\n () => this.ctx?.tabId(this.value()) ?? null,\r\n );\r\n protected readonly panelId = computed(\r\n () => this.ctx?.panelId(this.value()) ?? null,\r\n );\r\n protected readonly ariaSelected = computed(() =>\r\n this.ctx?.isSelected(this.value()) ? 'true' : 'false',\r\n );\r\n protected readonly tabindex = computed(() => {\r\n if (!this.ctx) return null; // standalone misuse — leave the native button focusable\r\n return this.ctx.activeValue() === this.value() ? '0' : '-1';\r\n });\r\n\r\n constructor() {\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n if (!this.ctx) {\r\n console.warn(\r\n '[skraTab] has no [skraTabs] ancestor — it is not wired to a tablist (no aria-controls / ' +\r\n 'roving / selection). Project it inside <div skraTablist> within <element skraTabs>.',\r\n );\r\n }\r\n }\r\n }\r\n\r\n // ── SkraTabKeyItem (driven by SkraTabsKeyboard / CDK FocusKeyManager) ──\r\n focus(): void {\r\n this.host.nativeElement.focus();\r\n }\r\n /** Disabled tabs are skipped in the roving order — read live off the native attribute (no input). */\r\n isDisabled(): boolean {\r\n return this.host.nativeElement.disabled;\r\n }\r\n getValue(): string {\r\n return this.value();\r\n }\r\n\r\n protected onClick(): void {\r\n if (this.host.nativeElement.disabled) return; // belt-and-suspenders (native disabled won't fire click)\r\n this.ctx?.select(this.value());\r\n }\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n computed,\r\n inject,\r\n input,\r\n} from '@angular/core';\r\n\r\nimport { SkraTabsContext } from './tabs-context';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/**\r\n * SkraTabPanel — the `role=\"tabpanel\"` for one tab, a Component on the consumer's `<div skraTabPanel>`\r\n * (ADR 040, `template: '<ng-content>'` so the panel body renders). It is focusable (`tabindex=\"0\"`, APG —\r\n * keyboard users Tab from the active tab into its content), auto-named by `aria-labelledby`→its tab, and\r\n * `hidden` when its `value` is not the selected one (removed from the a11y tree; stays in the DOM — lazy\r\n * mounting is the consumer's own `@if` on the content).\r\n */\r\n@Component({\r\n selector: '[skraTabPanel]',\r\n standalone: true,\r\n exportAs: 'skraTabPanel',\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './tab-panel.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n role: 'tabpanel',\r\n tabindex: '0',\r\n '[attr.id]': 'panelId()',\r\n '[attr.aria-labelledby]': 'tabId()',\r\n '[attr.hidden]': 'hidden()',\r\n },\r\n})\r\nexport class SkraTabPanel {\r\n /** Selection key — matched against the owning `button[skraTab]`'s `value`. */\r\n readonly value = input.required<string>();\r\n\r\n private readonly ctx = inject(SkraTabsContext, { optional: true });\r\n\r\n protected readonly panelId = computed(\r\n () => this.ctx?.panelId(this.value()) ?? null,\r\n );\r\n protected readonly tabId = computed(\r\n () => this.ctx?.tabId(this.value()) ?? null,\r\n );\r\n /** `''` (attribute present) when not selected → hidden; `null` (absent) when selected → shown. */\r\n protected readonly hidden = computed(() =>\r\n this.ctx?.isSelected(this.value()) ? null : '',\r\n );\r\n\r\n constructor() {\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n if (!this.ctx) {\r\n console.warn(\r\n '[skraTabPanel] has no [skraTabs] ancestor — it cannot be linked to a tab or shown/hidden. ' +\r\n 'Project it inside <element skraTabs>.',\r\n );\r\n }\r\n }\r\n }\r\n}\r\n","import { FocusKeyManager } from '@angular/cdk/a11y';\r\n\r\nimport type { SkraTabKeyItem } from './tabs-types';\r\n\r\n/**\r\n * SkraTabsKeyboard — the WAI-ARIA APG **Tabs** roving-tabindex keyboard model, confined to ONE file.\r\n *\r\n * This is the **only** module in `@skra/navigation` that imports `@angular/cdk` (ADR 0044 §7,\r\n * generalized library-wide 2026-06-19). It wraps CDK `FocusKeyManager` (roving REAL focus) so the\r\n * engine is swappable in one file — exactly as `SkraMenuKeyboard` does for the menu. Unlike the menu,\r\n * tabs use **horizontal** orientation (Left/Right) and **skip** disabled tabs.\r\n *\r\n * Owns: Left/Right roving (wrap), Home/End. Enter/Space (native button activation) and selection are\r\n * the coordinator's job — the controller only moves focus and reports the active tab's value.\r\n */\r\nexport class SkraTabsKeyboard {\r\n private manager?: FocusKeyManager<SkraTabKeyItem>;\r\n private items: SkraTabKeyItem[] = [];\r\n\r\n /**\r\n * (Re)build the manager from the current projected tab set. Called from an `effect` on the signal\r\n * `contentChildren` — a passed array is a static snapshot, so the manager is rebuilt whenever the\r\n * tab set changes (the documented signal↔CDK seam, mirroring `menu-keyboard.ts`).\r\n */\r\n setItems(items: readonly SkraTabKeyItem[]): void {\r\n this.items = [...items];\r\n this.manager?.destroy();\r\n this.manager = new FocusKeyManager<SkraTabKeyItem>(this.items)\r\n .withHorizontalOrientation('ltr') // Left/Right; RTL handled by the manager via the page dir\r\n .withWrap()\r\n .withHomeAndEnd()\r\n // Tabs SKIP disabled (APG): a disabled tab is not a roving stop. (Menu keeps them focusable.)\r\n .skipPredicate((tab) => tab.isDisabled());\r\n }\r\n\r\n /** Delegate Left/Right/Home/End. Enter/Space/Tab are intentionally left to the platform/coordinator. */\r\n onKeydown(event: KeyboardEvent): void {\r\n this.manager?.onKeydown(event);\r\n }\r\n\r\n /** The value of the tab the manager currently considers active (focused after `onKeydown`). */\r\n activeValue(): string | undefined {\r\n return this.manager?.activeItem?.getValue();\r\n }\r\n\r\n /** Sync the manager's active index to a value WITHOUT moving focus (after a click / on init). */\r\n setActive(value: string): void {\r\n const index = this.items.findIndex((tab) => tab.getValue() === value);\r\n if (index >= 0) this.manager?.updateActiveItem(index);\r\n }\r\n\r\n /** The first non-disabled tab's value (the roving stop when nothing is selected) — APG. */\r\n firstEnabledValue(): string | undefined {\r\n return this.items.find((tab) => !tab.isDisabled())?.getValue();\r\n }\r\n\r\n hasValue(value: string): boolean {\r\n return this.items.some((tab) => tab.getValue() === value);\r\n }\r\n\r\n destroy(): void {\r\n this.manager?.destroy();\r\n this.manager = undefined;\r\n }\r\n}\r\n","import {\r\n DestroyRef,\r\n Directive,\r\n contentChildren,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n} from '@angular/core';\r\n\r\nimport { SkraTab } from './tab';\r\nimport { SkraTabPanel } from './tab-panel';\r\nimport { SkraTabsContext } from './tabs-context';\r\nimport { SkraTabsKeyboard } from './tabs-keyboard';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/**\r\n * SkraTabs — the WAI-ARIA APG **Tabs** coordinator. A directive on a wrapping element that holds a\r\n * `[skraTablist]` (the `role=\"tablist\"` with its `button[skraTab]` children) and the\r\n * `[skraTabPanel]` panels as DI descendants. It provides `SkraTabsContext` (the ADR 013 §3.6 non-form\r\n * Contextual-ID-Sync bus), owns the consumer-facing `[selected]` / `(selectedChange)` (controlled,\r\n * ADR 037 — NO internal selection state) and `[activation]`, and drives the roving-tabindex keyboard\r\n * (`SkraTabsKeyboard` → CDK `FocusKeyManager`).\r\n *\r\n * <div skraTabs [selected]=\"tab()\" (selectedChange)=\"tab.set($event)\">\r\n * <div skraTablist aria-label=\"Account\">\r\n * <button skraTab value=\"profile\">Profile</button>\r\n * <button skraTab value=\"security\">Security</button>\r\n * </div>\r\n * <div skraTabPanel value=\"profile\">…</div>\r\n * <div skraTabPanel value=\"security\">…</div>\r\n * </div>\r\n *\r\n * Selection is consumer-owned: a click / Enter / Space / (automatic) arrow emits `(selectedChange)`;\r\n * the visible selection updates when the consumer round-trips `[selected]`. The roving focus position\r\n * (`tabindex=\"0\"`) is component-owned UI state — it moves immediately, independent of `[selected]`.\r\n *\r\n * Full contract: adr/specs/component-tabs-spec.md.\r\n */\r\n@Directive({\r\n selector: '[skraTabs]',\r\n standalone: true,\r\n exportAs: 'skraTabs',\r\n providers: [SkraTabsContext],\r\n})\r\nexport class SkraTabs {\r\n /** Consumer-owned selection key (matches a tab's `value`); '' / no-match → nothing selected (ADR 037). */\r\n readonly selected = input<string>('');\r\n /** Automatic (selection follows roving focus) | manual (Enter/Space selects). */\r\n readonly activation = input<'automatic' | 'manual'>('automatic');\r\n /** Fires ONLY on user activation — never on a programmatic `[selected]` change. */\r\n readonly selectedChange = output<string>();\r\n\r\n private readonly ctx = inject(SkraTabsContext);\r\n private readonly tabs = contentChildren(SkraTab, { descendants: true });\r\n private readonly panels = contentChildren(SkraTabPanel, {\r\n descendants: true,\r\n });\r\n private readonly keyboard = new SkraTabsKeyboard();\r\n\r\n constructor() {\r\n // Wire the context bus (a tab requests selection; the tablist forwards keydown).\r\n this.ctx.select = (value) => this.selectTab(value);\r\n this.ctx.handleKeydown = (event) => this.onTablistKeydown(event);\r\n\r\n // Mirror inputs → context (read-only to children).\r\n effect(() => this.ctx.selected.set(this.selected()));\r\n effect(() => this.ctx.activation.set(this.activation()));\r\n\r\n // (Re)build the keyboard from the projected tab set and (re)seat the roving stop whenever the tab\r\n // set or the selection changes. Rebuilding the manager for a handful of tabs is trivial.\r\n effect(() => {\r\n this.keyboard.setItems(this.tabs());\r\n this.reseat();\r\n });\r\n\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n effect(() => this.warnMismatches());\r\n }\r\n\r\n inject(DestroyRef).onDestroy(() => this.keyboard.destroy());\r\n }\r\n\r\n /** Seat the roving stop (`tabindex=\"0\"`) on a real, enabled tab: the selected one if valid, else the\r\n * first enabled tab (APG — the tablist must always have exactly one tab stop). */\r\n private reseat(): void {\r\n const sel = this.selected();\r\n const next = this.keyboard.hasValue(sel)\r\n ? sel\r\n : (this.keyboard.firstEnabledValue() ?? '');\r\n this.ctx.activeValue.set(next);\r\n if (next) this.keyboard.setActive(next);\r\n }\r\n\r\n /** A tab was activated (click / Enter / Space / automatic arrow). Move the roving stop immediately\r\n * (UI state), then REQUEST selection from the consumer — never mutate selection internally (ADR 037). */\r\n private selectTab(value: string): void {\r\n this.ctx.activeValue.set(value);\r\n this.keyboard.setActive(value);\r\n if (this.selected() === value) return; // idempotent — no redundant output\r\n this.selectedChange.emit(value);\r\n }\r\n\r\n private onTablistKeydown(event: KeyboardEvent): void {\r\n const before = this.keyboard.activeValue();\r\n this.keyboard.onKeydown(event);\r\n const after = this.keyboard.activeValue();\r\n if (after && after !== before) {\r\n this.ctx.activeValue.set(after); // roving moved (focus already on the new tab)\r\n if (this.ctx.activation() === 'automatic') this.selectTab(after);\r\n }\r\n }\r\n\r\n /** Dev-only nudge: every tab needs a panel of the same `value`, and vice-versa (aria-controls / -labelledby). */\r\n private warnMismatches(): void {\r\n const tabValues = new Set(this.tabs().map((t) => t.value()));\r\n const panelValues = new Set(this.panels().map((p) => p.value()));\r\n for (const v of tabValues) {\r\n if (!panelValues.has(v))\r\n console.warn(\r\n `[skraTabs] tab value=\"${v}\" has no matching [skraTabPanel] — its aria-controls points to a missing panel.`,\r\n );\r\n }\r\n for (const v of panelValues) {\r\n if (!tabValues.has(v))\r\n console.warn(\r\n `[skraTabs] panel value=\"${v}\" has no matching button[skraTab] — it will never be revealed.`,\r\n );\r\n }\r\n }\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n inject,\r\n} from '@angular/core';\r\n\r\nimport { SkraTabsContext } from './tabs-context';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/**\r\n * SkraTablist — the `role=\"tablist\"` container, a Component on the consumer's `<div skraTablist>`\r\n * (ADR 040, `template: '<ng-content>'` so the projected `button[skraTab]` children render). It carries\r\n * the rail styling and forwards its `keydown` to the coordinator's roving keyboard (`SkraTabsKeyboard`)\r\n * via the `SkraTabsContext` bus. Name it for AT with consumer `aria-label`/`aria-labelledby` (ADR 033).\r\n */\r\n@Component({\r\n selector: '[skraTablist]',\r\n standalone: true,\r\n exportAs: 'skraTablist',\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './tablist.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n role: 'tablist',\r\n 'aria-orientation': 'horizontal',\r\n '(keydown)': 'onKeydown($event)',\r\n },\r\n})\r\nexport class SkraTablist {\r\n private readonly ctx = inject(SkraTabsContext, { optional: true });\r\n\r\n constructor() {\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n if (!this.ctx) {\r\n console.warn(\r\n '[skraTablist] has no [skraTabs] ancestor — its tabs cannot be keyboard-navigated. ' +\r\n 'Wrap the tablist + panels in <element skraTabs>.',\r\n );\r\n }\r\n }\r\n }\r\n\r\n protected onKeydown(event: KeyboardEvent): void {\r\n this.ctx?.handleKeydown(event);\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skra-ui-tabs.mjs","sources":["../../../../libs/ui/tabs/src/lib/tabs/tabs-context.ts","../../../../libs/ui/tabs/src/lib/tabs/tab.ts","../../../../libs/ui/tabs/src/lib/tabs/tab-panel.ts","../../../../libs/ui/tabs/src/lib/tabs/tabs-keyboard.ts","../../../../libs/ui/tabs/src/lib/tabs/tabs.ts","../../../../libs/ui/tabs/src/lib/tabs/tablist.ts","../../../../libs/ui/tabs/src/skra-ui-tabs.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\n\n/** Module-global counter → a deterministic, unique id base per `[skraTabs]` instance.\n * Equivalent to the forms `IdGeneratorService` (ADR 013) but lib-local, so `@skra/navigation`\n * takes no dependency on `@skra/forms` just for id generation. Stable across SSR↔hydration\n * (same instantiation order yields the same ids — the standard counter technique). */\nlet tabsInstanceCounter = 0;\n\n/** Sanitize a consumer `value` into an id-safe fragment (no spaces / special chars). */\nfunction idSafe(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, '-');\n}\n\n/**\n * DI Context provided per `[skraTabs]` instance — the ADR 013 §3.6 **non-form** Contextual-ID-Sync\n * bus wiring `tab` ↔ `tabpanel`. It carries **IDs + derived, read-only interaction state only**\n * (`selected` mirrors the consumer's `[selected]`; `activeValue` is the roving-focus position). It\n * **never owns value** — selection stays consumer-owned (ADR 037); a tab requests a change through\n * `select()`, which the coordinator implements and from which it emits `(selectedChange)`.\n */\n@Injectable()\nexport class SkraTabsContext {\n /** Unique per `[skraTabs]` — the prefix for every tab/panel id in this group. */\n private readonly baseId = `skra-tabs-${++tabsInstanceCounter}`;\n\n /** Mirror of the consumer's `[selected]` — drives `aria-selected` + panel visibility (read-only to children). */\n readonly selected = signal<string>('');\n /** Roving-focus position — the value of the tab that currently carries `tabindex=\"0\"` (read-only to children). */\n readonly activeValue = signal<string>('');\n /** Activation model (read-only to children). */\n readonly activation = signal<'automatic' | 'manual'>('automatic');\n\n tabId(value: string): string {\n return `${this.baseId}-tab-${idSafe(value)}`;\n }\n panelId(value: string): string {\n return `${this.baseId}-panel-${idSafe(value)}`;\n }\n isSelected(value: string): boolean {\n return this.selected() === value;\n }\n\n /** Coordinator-assigned: a tab/keyboard requests selection (the coordinator emits `(selectedChange)`). */\n select: (value: string) => void = () => undefined;\n /** Coordinator-assigned: the tablist forwards its `keydown` here (routed to the keyboard controller). */\n handleKeydown: (event: KeyboardEvent) => void = () => undefined;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n} from '@angular/core';\n\nimport { SkraTabsContext } from './tabs-context';\nimport type { SkraTabKeyItem } from './tabs-types';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/**\n * SkraTab — a single tab, a Component on the native command host `button[skraTab]` (ADR 012/040:\n * a `<button>` gives Enter/Space→click + focusability for free; its implicit role is overridden to\n * `role=\"tab\"`, the precedent set by `button[skraMenuItem]`).\n *\n * Roving tabindex: `tabindex=\"0\"` only when this tab is the roving stop (`SkraTabsContext.activeValue`),\n * else `-1` — the controller (`SkraTabsKeyboard`) moves real focus. `aria-selected` reflects the\n * consumer-owned selection (`[selected]`), NOT the roving focus — and is the source of truth for the\n * selected STYLE too (CSS keys off `:host([aria-selected=\"true\"])`; no `data-skra-*`). On activation it\n * REQUESTS selection from the coordinator (`ctx.select`) — it never mutates selection itself (ADR 037).\n *\n * **Disabled is native-attr-first (boundary #9): the consumer sets the native `disabled` attribute** —\n * Forge OBSERVES it (no `disabled` input). A disabled tab is SKIPPED in the roving order (APG).\n */\n@Component({\n selector: 'button[skraTab]',\n standalone: true,\n exportAs: 'skraTab',\n template: '<ng-content></ng-content>',\n styleUrl: './tab.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n role: 'tab',\n type: 'button', // never an implicit submit if the tablist sits inside a <form>\n '[attr.id]': 'tabId()',\n '[attr.aria-controls]': 'panelId()',\n '[attr.aria-selected]': 'ariaSelected()',\n '[attr.tabindex]': 'tabindex()',\n '(click)': 'onClick()',\n },\n})\nexport class SkraTab implements SkraTabKeyItem {\n /** Selection key — matched against `skraTabs [selected]` and the owning panel's `value`. */\n readonly value = input.required<string>();\n\n private readonly host = inject<ElementRef<HTMLButtonElement>>(ElementRef);\n private readonly ctx = inject(SkraTabsContext, { optional: true });\n\n protected readonly tabId = computed(\n () => this.ctx?.tabId(this.value()) ?? null,\n );\n protected readonly panelId = computed(\n () => this.ctx?.panelId(this.value()) ?? null,\n );\n protected readonly ariaSelected = computed(() =>\n this.ctx?.isSelected(this.value()) ? 'true' : 'false',\n );\n protected readonly tabindex = computed(() => {\n if (!this.ctx) return null; // standalone misuse — leave the native button focusable\n return this.ctx.activeValue() === this.value() ? '0' : '-1';\n });\n\n constructor() {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this.ctx) {\n console.warn(\n '[skraTab] has no [skraTabs] ancestor — it is not wired to a tablist (no aria-controls / ' +\n 'roving / selection). Project it inside <div skraTablist> within <element skraTabs>.',\n );\n }\n }\n }\n\n // ── SkraTabKeyItem (driven by SkraTabsKeyboard / CDK FocusKeyManager) ──\n focus(): void {\n this.host.nativeElement.focus();\n }\n /** Disabled tabs are skipped in the roving order — read live off the native attribute (no input). */\n isDisabled(): boolean {\n return this.host.nativeElement.disabled;\n }\n getValue(): string {\n return this.value();\n }\n\n protected onClick(): void {\n if (this.host.nativeElement.disabled) return; // belt-and-suspenders (native disabled won't fire click)\n this.ctx?.select(this.value());\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n inject,\n input,\n} from '@angular/core';\n\nimport { SkraTabsContext } from './tabs-context';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/**\n * SkraTabPanel — the `role=\"tabpanel\"` for one tab, a Component on the consumer's `<div skraTabPanel>`\n * (ADR 040, `template: '<ng-content>'` so the panel body renders). It is focusable (`tabindex=\"0\"`, APG —\n * keyboard users Tab from the active tab into its content), auto-named by `aria-labelledby`→its tab, and\n * `hidden` when its `value` is not the selected one (removed from the a11y tree; stays in the DOM — lazy\n * mounting is the consumer's own `@if` on the content).\n */\n@Component({\n selector: '[skraTabPanel]',\n standalone: true,\n exportAs: 'skraTabPanel',\n template: '<ng-content></ng-content>',\n styleUrl: './tab-panel.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n role: 'tabpanel',\n tabindex: '0',\n '[attr.id]': 'panelId()',\n '[attr.aria-labelledby]': 'tabId()',\n '[attr.hidden]': 'hidden()',\n },\n})\nexport class SkraTabPanel {\n /** Selection key — matched against the owning `button[skraTab]`'s `value`. */\n readonly value = input.required<string>();\n\n private readonly ctx = inject(SkraTabsContext, { optional: true });\n\n protected readonly panelId = computed(\n () => this.ctx?.panelId(this.value()) ?? null,\n );\n protected readonly tabId = computed(\n () => this.ctx?.tabId(this.value()) ?? null,\n );\n /** `''` (attribute present) when not selected → hidden; `null` (absent) when selected → shown. */\n protected readonly hidden = computed(() =>\n this.ctx?.isSelected(this.value()) ? null : '',\n );\n\n constructor() {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this.ctx) {\n console.warn(\n '[skraTabPanel] has no [skraTabs] ancestor — it cannot be linked to a tab or shown/hidden. ' +\n 'Project it inside <element skraTabs>.',\n );\n }\n }\n }\n}\n","import { FocusKeyManager } from '@angular/cdk/a11y';\n\nimport type { SkraTabKeyItem } from './tabs-types';\n\n/**\n * SkraTabsKeyboard — the WAI-ARIA APG **Tabs** roving-tabindex keyboard model, confined to ONE file.\n *\n * This is the **only** module in `@skra/navigation` that imports `@angular/cdk` (ADR 0044 §7,\n * generalized library-wide 2026-06-19). It wraps CDK `FocusKeyManager` (roving REAL focus) so the\n * engine is swappable in one file — exactly as `SkraMenuKeyboard` does for the menu. Unlike the menu,\n * tabs use **horizontal** orientation (Left/Right) and **skip** disabled tabs.\n *\n * Owns: Left/Right roving (wrap), Home/End. Enter/Space (native button activation) and selection are\n * the coordinator's job — the controller only moves focus and reports the active tab's value.\n */\nexport class SkraTabsKeyboard {\n private manager?: FocusKeyManager<SkraTabKeyItem>;\n private items: SkraTabKeyItem[] = [];\n\n /**\n * (Re)build the manager from the current projected tab set. Called from an `effect` on the signal\n * `contentChildren` — a passed array is a static snapshot, so the manager is rebuilt whenever the\n * tab set changes (the documented signal↔CDK seam, mirroring `menu-keyboard.ts`).\n */\n setItems(items: readonly SkraTabKeyItem[]): void {\n this.items = [...items];\n this.manager?.destroy();\n this.manager = new FocusKeyManager<SkraTabKeyItem>(this.items)\n .withHorizontalOrientation('ltr') // Left/Right; RTL handled by the manager via the page dir\n .withWrap()\n .withHomeAndEnd()\n // Tabs SKIP disabled (APG): a disabled tab is not a roving stop. (Menu keeps them focusable.)\n .skipPredicate((tab) => tab.isDisabled());\n }\n\n /** Delegate Left/Right/Home/End. Enter/Space/Tab are intentionally left to the platform/coordinator. */\n onKeydown(event: KeyboardEvent): void {\n this.manager?.onKeydown(event);\n }\n\n /** The value of the tab the manager currently considers active (focused after `onKeydown`). */\n activeValue(): string | undefined {\n return this.manager?.activeItem?.getValue();\n }\n\n /** Sync the manager's active index to a value WITHOUT moving focus (after a click / on init). */\n setActive(value: string): void {\n const index = this.items.findIndex((tab) => tab.getValue() === value);\n if (index >= 0) this.manager?.updateActiveItem(index);\n }\n\n /** The first non-disabled tab's value (the roving stop when nothing is selected) — APG. */\n firstEnabledValue(): string | undefined {\n return this.items.find((tab) => !tab.isDisabled())?.getValue();\n }\n\n hasValue(value: string): boolean {\n return this.items.some((tab) => tab.getValue() === value);\n }\n\n destroy(): void {\n this.manager?.destroy();\n this.manager = undefined;\n }\n}\n","import {\n DestroyRef,\n Directive,\n contentChildren,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\n\nimport { SkraTab } from './tab';\nimport { SkraTabPanel } from './tab-panel';\nimport { SkraTabsContext } from './tabs-context';\nimport { SkraTabsKeyboard } from './tabs-keyboard';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/**\n * SkraTabs — the WAI-ARIA APG **Tabs** coordinator. A directive on a wrapping element that holds a\n * `[skraTablist]` (the `role=\"tablist\"` with its `button[skraTab]` children) and the\n * `[skraTabPanel]` panels as DI descendants. It provides `SkraTabsContext` (the ADR 013 §3.6 non-form\n * Contextual-ID-Sync bus), owns the consumer-facing `[selected]` / `(selectedChange)` (controlled,\n * ADR 037 — NO internal selection state) and `[activation]`, and drives the roving-tabindex keyboard\n * (`SkraTabsKeyboard` → CDK `FocusKeyManager`).\n *\n * <div skraTabs [selected]=\"tab()\" (selectedChange)=\"tab.set($event)\">\n * <div skraTablist aria-label=\"Account\">\n * <button skraTab value=\"profile\">Profile</button>\n * <button skraTab value=\"security\">Security</button>\n * </div>\n * <div skraTabPanel value=\"profile\">…</div>\n * <div skraTabPanel value=\"security\">…</div>\n * </div>\n *\n * Selection is consumer-owned: a click / Enter / Space / (automatic) arrow emits `(selectedChange)`;\n * the visible selection updates when the consumer round-trips `[selected]`. The roving focus position\n * (`tabindex=\"0\"`) is component-owned UI state — it moves immediately, independent of `[selected]`.\n *\n * Full contract: adr/specs/component-tabs-spec.md.\n */\n@Directive({\n selector: '[skraTabs]',\n standalone: true,\n exportAs: 'skraTabs',\n providers: [SkraTabsContext],\n})\nexport class SkraTabs {\n /** Consumer-owned selection key (matches a tab's `value`); '' / no-match → nothing selected (ADR 037). */\n readonly selected = input<string>('');\n /** Automatic (selection follows roving focus) | manual (Enter/Space selects). */\n readonly activation = input<'automatic' | 'manual'>('automatic');\n /** Fires ONLY on user activation — never on a programmatic `[selected]` change. */\n readonly selectedChange = output<string>();\n\n private readonly ctx = inject(SkraTabsContext);\n private readonly tabs = contentChildren(SkraTab, { descendants: true });\n private readonly panels = contentChildren(SkraTabPanel, {\n descendants: true,\n });\n private readonly keyboard = new SkraTabsKeyboard();\n\n constructor() {\n // Wire the context bus (a tab requests selection; the tablist forwards keydown).\n this.ctx.select = (value) => this.selectTab(value);\n this.ctx.handleKeydown = (event) => this.onTablistKeydown(event);\n\n // Mirror inputs → context (read-only to children).\n effect(() => this.ctx.selected.set(this.selected()));\n effect(() => this.ctx.activation.set(this.activation()));\n\n // (Re)build the keyboard from the projected tab set and (re)seat the roving stop whenever the tab\n // set or the selection changes. Rebuilding the manager for a handful of tabs is trivial.\n effect(() => {\n this.keyboard.setItems(this.tabs());\n this.reseat();\n });\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n effect(() => this.warnMismatches());\n }\n\n inject(DestroyRef).onDestroy(() => this.keyboard.destroy());\n }\n\n /** Seat the roving stop (`tabindex=\"0\"`) on a real, enabled tab: the selected one if valid, else the\n * first enabled tab (APG — the tablist must always have exactly one tab stop). */\n private reseat(): void {\n const sel = this.selected();\n const next = this.keyboard.hasValue(sel)\n ? sel\n : (this.keyboard.firstEnabledValue() ?? '');\n this.ctx.activeValue.set(next);\n if (next) this.keyboard.setActive(next);\n }\n\n /** A tab was activated (click / Enter / Space / automatic arrow). Move the roving stop immediately\n * (UI state), then REQUEST selection from the consumer — never mutate selection internally (ADR 037). */\n private selectTab(value: string): void {\n this.ctx.activeValue.set(value);\n this.keyboard.setActive(value);\n if (this.selected() === value) return; // idempotent — no redundant output\n this.selectedChange.emit(value);\n }\n\n private onTablistKeydown(event: KeyboardEvent): void {\n const before = this.keyboard.activeValue();\n this.keyboard.onKeydown(event);\n const after = this.keyboard.activeValue();\n if (after && after !== before) {\n this.ctx.activeValue.set(after); // roving moved (focus already on the new tab)\n if (this.ctx.activation() === 'automatic') this.selectTab(after);\n }\n }\n\n /** Dev-only nudge: every tab needs a panel of the same `value`, and vice-versa (aria-controls / -labelledby). */\n private warnMismatches(): void {\n const tabValues = new Set(this.tabs().map((t) => t.value()));\n const panelValues = new Set(this.panels().map((p) => p.value()));\n for (const v of tabValues) {\n if (!panelValues.has(v))\n console.warn(\n `[skraTabs] tab value=\"${v}\" has no matching [skraTabPanel] — its aria-controls points to a missing panel.`,\n );\n }\n for (const v of panelValues) {\n if (!tabValues.has(v))\n console.warn(\n `[skraTabs] panel value=\"${v}\" has no matching button[skraTab] — it will never be revealed.`,\n );\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n inject,\n} from '@angular/core';\n\nimport { SkraTabsContext } from './tabs-context';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/**\n * SkraTablist — the `role=\"tablist\"` container, a Component on the consumer's `<div skraTablist>`\n * (ADR 040, `template: '<ng-content>'` so the projected `button[skraTab]` children render). It carries\n * the rail styling and forwards its `keydown` to the coordinator's roving keyboard (`SkraTabsKeyboard`)\n * via the `SkraTabsContext` bus. Name it for AT with consumer `aria-label`/`aria-labelledby` (ADR 033).\n */\n@Component({\n selector: '[skraTablist]',\n standalone: true,\n exportAs: 'skraTablist',\n template: '<ng-content></ng-content>',\n styleUrl: './tablist.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n role: 'tablist',\n 'aria-orientation': 'horizontal',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class SkraTablist {\n private readonly ctx = inject(SkraTabsContext, { optional: true });\n\n constructor() {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this.ctx) {\n console.warn(\n '[skraTablist] has no [skraTabs] ancestor — its tabs cannot be keyboard-navigated. ' +\n 'Wrap the tablist + panels in <element skraTabs>.',\n );\n }\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n this.ctx?.handleKeydown(event);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -53,7 +53,7 @@ class SkraTextarea {
53
53
  }
54
54
  }
55
55
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTextarea, deps: [], target: i0.ɵɵFactoryTarget.Component });
56
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.1", type: SkraTextarea, isStandalone: true, selector: "textarea[skraTextarea]", host: { properties: { "attr.aria-describedby": "context?.describedByIds() ?? null", "attr.aria-invalid": "context?.hasError() ? \"true\" : null", "attr.aria-required": "context?.isRequired() ? \"true\" : null" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{background:var(--skra-comp-field-background);color:var(--skra-comp-field-foreground);border-color:var(--skra-comp-field-border-color);border-width:var(--skra-comp-field-border-width);border-style:var(--skra-comp-field-border-style);border-radius:var(--skra-comp-field-radius);padding-block:var(--skra-comp-field-padding-block);padding-inline:var(--skra-comp-field-padding-inline);box-shadow:var(--skra-comp-field-shadow);font:inherit;outline:none;transition:background-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),border-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),box-shadow var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing)}:host(:hover:not(:disabled):not([readonly])){background:var(--skra-comp-field-background-hover);border-color:var(--skra-comp-field-border-color-hover)}:host(:focus-visible){border-color:var(--skra-comp-field-focus-ring-color);box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-focus-ring-color)}:host(:disabled){cursor:not-allowed;opacity:var(--skra-sys-opacity-disabled)}:host([readonly]){cursor:default}:host([aria-invalid=true]){border-color:var(--skra-comp-field-error-color)}:host([aria-invalid=true]:focus-visible){box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-error-color)}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
56
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.1", type: SkraTextarea, isStandalone: true, selector: "textarea[skraTextarea]", host: { properties: { "attr.aria-describedby": "context?.describedByIds() ?? null", "attr.aria-invalid": "context?.hasError() ? \"true\" : null", "attr.aria-required": "context?.isRequired() ? \"true\" : null" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{background:var(--skra-comp-field-background);color:var(--skra-comp-field-foreground);border-color:var(--skra-comp-field-border-color);border-width:var(--skra-comp-field-border-width);border-style:var(--skra-comp-field-border-style);border-radius:var(--skra-comp-field-radius);padding-block:var(--skra-comp-field-padding-block);padding-inline:var(--skra-comp-field-padding-inline);box-shadow:var(--skra-comp-field-shadow);font:inherit;outline:none;transition:background-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),border-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),box-shadow var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing)}@media(hover:hover)and (pointer:fine){:host(:hover:not(:disabled):not([readonly])){background:var(--skra-comp-field-background-hover);border-color:var(--skra-comp-field-border-color-hover)}}:host(:focus-visible){border-color:var(--skra-comp-field-focus-ring-color);box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-focus-ring-color)}:host(:disabled){cursor:not-allowed;opacity:var(--skra-sys-opacity-disabled)}:host([readonly]){cursor:default}:host([aria-invalid=true]){border-color:var(--skra-comp-field-error-color)}:host([aria-invalid=true]:focus-visible){box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-error-color)}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
57
57
  }
58
58
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTextarea, decorators: [{
59
59
  type: Component,
@@ -67,7 +67,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImpor
67
67
  // `aria-disabled` duplicate. Readonly styling keys off `:read-only`.
68
68
  // Driven imperatively below, NOT as host bindings — see the constructor
69
69
  // note on standalone attribute ownership.
70
- }, styles: [":host{background:var(--skra-comp-field-background);color:var(--skra-comp-field-foreground);border-color:var(--skra-comp-field-border-color);border-width:var(--skra-comp-field-border-width);border-style:var(--skra-comp-field-border-style);border-radius:var(--skra-comp-field-radius);padding-block:var(--skra-comp-field-padding-block);padding-inline:var(--skra-comp-field-padding-inline);box-shadow:var(--skra-comp-field-shadow);font:inherit;outline:none;transition:background-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),border-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),box-shadow var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing)}:host(:hover:not(:disabled):not([readonly])){background:var(--skra-comp-field-background-hover);border-color:var(--skra-comp-field-border-color-hover)}:host(:focus-visible){border-color:var(--skra-comp-field-focus-ring-color);box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-focus-ring-color)}:host(:disabled){cursor:not-allowed;opacity:var(--skra-sys-opacity-disabled)}:host([readonly]){cursor:default}:host([aria-invalid=true]){border-color:var(--skra-comp-field-error-color)}:host([aria-invalid=true]:focus-visible){box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-error-color)}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"] }]
70
+ }, styles: [":host{background:var(--skra-comp-field-background);color:var(--skra-comp-field-foreground);border-color:var(--skra-comp-field-border-color);border-width:var(--skra-comp-field-border-width);border-style:var(--skra-comp-field-border-style);border-radius:var(--skra-comp-field-radius);padding-block:var(--skra-comp-field-padding-block);padding-inline:var(--skra-comp-field-padding-inline);box-shadow:var(--skra-comp-field-shadow);font:inherit;outline:none;transition:background-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),border-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),box-shadow var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing)}@media(hover:hover)and (pointer:fine){:host(:hover:not(:disabled):not([readonly])){background:var(--skra-comp-field-background-hover);border-color:var(--skra-comp-field-border-color-hover)}}:host(:focus-visible){border-color:var(--skra-comp-field-focus-ring-color);box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-focus-ring-color)}:host(:disabled){cursor:not-allowed;opacity:var(--skra-sys-opacity-disabled)}:host([readonly]){cursor:default}:host([aria-invalid=true]){border-color:var(--skra-comp-field-error-color)}:host([aria-invalid=true]:focus-visible){box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-error-color)}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"] }]
71
71
  }], ctorParameters: () => [] });
72
72
 
73
73
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-textarea.mjs","sources":["../../../../libs/ui/textarea/src/lib/textarea/textarea.ts","../../../../libs/ui/textarea/src/lib/auto-resize/auto-resize.directive.ts","../../../../libs/ui/textarea/src/skra-ui-textarea.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n effect,\n inject,\n} from '@angular/core';\nimport { SkraFieldContext } from '@skra/ui/field';\n\n/**\n * `textarea[skraTextarea]` — multiline text atom. Per ADR 040 this is a\n * Component-on-a-native-host carrying its own host-scoped CSS (`textarea.scss`)\n * via Emulated encapsulation, replacing the ADR 038 slice branch.\n *\n * `<textarea>` is a content-bearing host (its value is its text content), so the\n * template MUST be `<ng-content>` — `template: ''` would discard the consumer's\n * initial text. See ADR 040 §2.\n *\n * Sibling atom to SkraInput — split per atom-granularity rule (memory\n * `feedback_atom_granularity.md`): textarea has capabilities `<input>` does not\n * (multi-line content, native `rows` / `cols`, autosize composition via the\n * sibling `[skraAutoResize]` directive).\n *\n * <skra-field>\n * <label skraLabelFor>Bio</label>\n * <textarea skraTextarea skraAutoResize rows=\"3\"></textarea>\n * </skra-field>\n *\n * <!-- standalone: native implicit label (wrapping) — no id/for needed -->\n * <label>Notes <textarea skraTextarea></textarea></label>\n *\n * Native `rows` / `cols` remain the consumer-facing sizing primitives — Forge\n * does not duplicate them as Angular inputs (boundary #9 native-attr-first).\n *\n * `SkraFieldContext` is injected `{ optional: true }` (ADR 013 §3.7) — same\n * posture as SkraInput / SkraCheckbox. Standalone, the atom renders the skin\n * only and the consumer owns every attribute, including the accessible name.\n */\n@Component({\n selector: 'textarea[skraTextarea]',\n standalone: true,\n // Content-bearing host — see ADR 040 §2.\n template: '<ng-content></ng-content>',\n styleUrl: './textarea.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n // ARIA relationships — Skra-owned, present only while a field cascades them.\n '[attr.aria-describedby]': 'context?.describedByIds() ?? null',\n '[attr.aria-invalid]': 'context?.hasError() ? \"true\" : null',\n '[attr.aria-required]': 'context?.isRequired() ? \"true\" : null',\n // Availability — native attrs only (native-attr-first, boundary #9).\n // <textarea> supports native `readonly`/`disabled`; NO `aria-readonly`/\n // `aria-disabled` duplicate. Readonly styling keys off `:read-only`.\n // Driven imperatively below, NOT as host bindings — see the constructor\n // note on standalone attribute ownership.\n },\n})\nexport class SkraTextarea {\n private readonly el = inject<ElementRef<HTMLTextAreaElement>>(ElementRef);\n readonly context = inject(SkraFieldContext, { optional: true });\n\n constructor() {\n const el = this.el.nativeElement;\n\n // Field-cascaded native properties — only bind when context is present so\n // standalone consumers retain full control of their static attributes.\n // Mirrors SkraInput / SkraCheckbox.\n if (this.context) {\n const ctx = this.context;\n effect(() => {\n el.id = ctx.fieldId();\n });\n effect(() => {\n el.disabled = ctx.isDisabled();\n });\n effect(() => {\n el.readOnly = ctx.isReadonly();\n });\n }\n }\n}\n","import { Directive } from '@angular/core';\r\n\r\n/**\r\n * Marker directive enabling content-driven sizing on a native form control via\r\n * the modern CSS `field-sizing: content` declaration shipped from the skin's\r\n * global utilities layer (`tokens/skins/skra/utilities.scss`).\r\n *\r\n * <textarea skraTextarea skraAutoResize rows=\"2\"></textarea>\r\n * <input skraInput skraAutoResize type=\"text\" />\r\n *\r\n * Composition-over-configuration: the host opts in by adding the attribute,\r\n * not by toggling a boolean Angular input. The directive has no host bindings,\r\n * no DI, and no template — its sole job is to make the selector available at\r\n * Angular's compilation stage; CSS does the rest.\r\n *\r\n * Wide selector (textarea + input) reflects that `field-sizing: content` is a\r\n * native CSS capability for both: textarea grows in block-size with rows,\r\n * input grows in inline-size with content width.\r\n */\r\n@Directive({\r\n selector: 'textarea[skraAutoResize], input[skraAutoResize]',\r\n standalone: true,\r\n})\r\nexport class SkraAutoResizeDirective {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;MAqBU,YAAY,CAAA;AACN,IAAA,EAAE,GAAG,MAAM,CAAkC,UAAU,CAAC;IAChE,OAAO,GAAG,MAAM,CAAC,gBAAgB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAE/D,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa;;;;AAKhC,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO;YACxB,MAAM,CAAC,MAAK;AACV,gBAAA,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE;AACvB,YAAA,CAAC,CAAC;YACF,MAAM,CAAC,MAAK;AACV,gBAAA,EAAE,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,EAAE;AAChC,YAAA,CAAC,CAAC;YACF,MAAM,CAAC,MAAK;AACV,gBAAA,EAAE,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,EAAE;AAChC,YAAA,CAAC,CAAC;QACJ;IACF;uGAtBW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAY,ySAhBb,2BAA2B,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,i/CAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAgB1B,YAAY,EAAA,UAAA,EAAA,CAAA;kBApBxB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wBAAwB,EAAA,UAAA,EACtB,IAAI,EAAA,QAAA,EAEN,2BAA2B,EAAA,eAAA,EAEpB,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;AAEJ,wBAAA,yBAAyB,EAAE,mCAAmC;AAC9D,wBAAA,qBAAqB,EAAE,qCAAqC;AAC5D,wBAAA,sBAAsB,EAAE,uCAAuC;;;;;;AAMhE,qBAAA,EAAA,MAAA,EAAA,CAAA,i/CAAA,CAAA,EAAA;;;ACvDH;;;;;;;;;;;;;;;;AAgBG;MAKU,uBAAuB,CAAA;uGAAvB,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAvB,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iDAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAvB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAJnC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iDAAiD;AAC3D,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA;;;ACtBD;;AAEG;;;;"}
1
+ {"version":3,"file":"skra-ui-textarea.mjs","sources":["../../../../libs/ui/textarea/src/lib/textarea/textarea.ts","../../../../libs/ui/textarea/src/lib/auto-resize/auto-resize.directive.ts","../../../../libs/ui/textarea/src/skra-ui-textarea.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n effect,\n inject,\n} from '@angular/core';\nimport { SkraFieldContext } from '@skra/ui/field';\n\n/**\n * `textarea[skraTextarea]` — multiline text atom. Per ADR 040 this is a\n * Component-on-a-native-host carrying its own host-scoped CSS (`textarea.scss`)\n * via Emulated encapsulation, replacing the ADR 038 slice branch.\n *\n * `<textarea>` is a content-bearing host (its value is its text content), so the\n * template MUST be `<ng-content>` — `template: ''` would discard the consumer's\n * initial text. See ADR 040 §2.\n *\n * Sibling atom to SkraInput — split per atom-granularity rule (memory\n * `feedback_atom_granularity.md`): textarea has capabilities `<input>` does not\n * (multi-line content, native `rows` / `cols`, autosize composition via the\n * sibling `[skraAutoResize]` directive).\n *\n * <skra-field>\n * <label skraLabelFor>Bio</label>\n * <textarea skraTextarea skraAutoResize rows=\"3\"></textarea>\n * </skra-field>\n *\n * <!-- standalone: native implicit label (wrapping) — no id/for needed -->\n * <label>Notes <textarea skraTextarea></textarea></label>\n *\n * Native `rows` / `cols` remain the consumer-facing sizing primitives — Forge\n * does not duplicate them as Angular inputs (boundary #9 native-attr-first).\n *\n * `SkraFieldContext` is injected `{ optional: true }` (ADR 013 §3.7) — same\n * posture as SkraInput / SkraCheckbox. Standalone, the atom renders the skin\n * only and the consumer owns every attribute, including the accessible name.\n */\n@Component({\n selector: 'textarea[skraTextarea]',\n standalone: true,\n // Content-bearing host — see ADR 040 §2.\n template: '<ng-content></ng-content>',\n styleUrl: './textarea.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n // ARIA relationships — Skra-owned, present only while a field cascades them.\n '[attr.aria-describedby]': 'context?.describedByIds() ?? null',\n '[attr.aria-invalid]': 'context?.hasError() ? \"true\" : null',\n '[attr.aria-required]': 'context?.isRequired() ? \"true\" : null',\n // Availability — native attrs only (native-attr-first, boundary #9).\n // <textarea> supports native `readonly`/`disabled`; NO `aria-readonly`/\n // `aria-disabled` duplicate. Readonly styling keys off `:read-only`.\n // Driven imperatively below, NOT as host bindings — see the constructor\n // note on standalone attribute ownership.\n },\n})\nexport class SkraTextarea {\n private readonly el = inject<ElementRef<HTMLTextAreaElement>>(ElementRef);\n readonly context = inject(SkraFieldContext, { optional: true });\n\n constructor() {\n const el = this.el.nativeElement;\n\n // Field-cascaded native properties — only bind when context is present so\n // standalone consumers retain full control of their static attributes.\n // Mirrors SkraInput / SkraCheckbox.\n if (this.context) {\n const ctx = this.context;\n effect(() => {\n el.id = ctx.fieldId();\n });\n effect(() => {\n el.disabled = ctx.isDisabled();\n });\n effect(() => {\n el.readOnly = ctx.isReadonly();\n });\n }\n }\n}\n","import { Directive } from '@angular/core';\n\n/**\n * Marker directive enabling content-driven sizing on a native form control via\n * the modern CSS `field-sizing: content` declaration shipped from the skin's\n * global utilities layer (`tokens/skins/skra/utilities.scss`).\n *\n * <textarea skraTextarea skraAutoResize rows=\"2\"></textarea>\n * <input skraInput skraAutoResize type=\"text\" />\n *\n * Composition-over-configuration: the host opts in by adding the attribute,\n * not by toggling a boolean Angular input. The directive has no host bindings,\n * no DI, and no template — its sole job is to make the selector available at\n * Angular's compilation stage; CSS does the rest.\n *\n * Wide selector (textarea + input) reflects that `field-sizing: content` is a\n * native CSS capability for both: textarea grows in block-size with rows,\n * input grows in inline-size with content width.\n */\n@Directive({\n selector: 'textarea[skraAutoResize], input[skraAutoResize]',\n standalone: true,\n})\nexport class SkraAutoResizeDirective {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;MAqBU,YAAY,CAAA;AACN,IAAA,EAAE,GAAG,MAAM,CAAkC,UAAU,CAAC;IAChE,OAAO,GAAG,MAAM,CAAC,gBAAgB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAE/D,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa;;;;AAKhC,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO;YACxB,MAAM,CAAC,MAAK;AACV,gBAAA,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE;AACvB,YAAA,CAAC,CAAC;YACF,MAAM,CAAC,MAAK;AACV,gBAAA,EAAE,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,EAAE;AAChC,YAAA,CAAC,CAAC;YACF,MAAM,CAAC,MAAK;AACV,gBAAA,EAAE,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,EAAE;AAChC,YAAA,CAAC,CAAC;QACJ;IACF;uGAtBW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAY,ySAhBb,2BAA2B,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,whDAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAgB1B,YAAY,EAAA,UAAA,EAAA,CAAA;kBApBxB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wBAAwB,EAAA,UAAA,EACtB,IAAI,EAAA,QAAA,EAEN,2BAA2B,EAAA,eAAA,EAEpB,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;AAEJ,wBAAA,yBAAyB,EAAE,mCAAmC;AAC9D,wBAAA,qBAAqB,EAAE,qCAAqC;AAC5D,wBAAA,sBAAsB,EAAE,uCAAuC;;;;;;AAMhE,qBAAA,EAAA,MAAA,EAAA,CAAA,whDAAA,CAAA,EAAA;;;ACvDH;;;;;;;;;;;;;;;;AAgBG;MAKU,uBAAuB,CAAA;uGAAvB,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAvB,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iDAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAvB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAJnC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iDAAiD;AAC3D,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA;;;ACtBD;;AAEG;;;;"}
@@ -114,7 +114,7 @@ class SkraToast {
114
114
  }
115
115
  }
116
116
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraToast, deps: [], target: i0.ɵɵFactoryTarget.Component });
117
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: SkraToast, isStandalone: true, selector: "skra-toast", inputs: { intent: { classPropertyName: "intent", publicName: "intent", isSignal: true, isRequired: false, transformFunction: null }, emphasis: { classPropertyName: "emphasis", publicName: "emphasis", isSignal: true, isRequired: false, transformFunction: null }, live: { classPropertyName: "live", publicName: "live", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismissed: "dismissed" }, host: { listeners: { "mouseenter": "pause()", "mouseleave": "resume()", "focusin": "pause()", "focusout": "resume()" }, properties: { "attr.data-skra-intent": "intent()", "attr.data-skra-emphasis": "emphasis()", "attr.data-skra-has-icon": "hasIcon() ? \"\" : null" } }, queries: [{ propertyName: "iconSlot", first: true, predicate: SkraToastIcon, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (hasIcon()) {\r\n<span class=\"skra-toast-icon\">\r\n <ng-content select=\"[skra-toast-icon]\"></ng-content>\r\n</span>\r\n}\r\n\r\n<div class=\"skra-toast-content\" #content>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n@if (dismissible()) {\r\n<button type=\"button\" class=\"skra-toast-dismiss\" (click)=\"onDismiss()\">\r\n <span class=\"skra-toast-dismiss-glyph\" aria-hidden=\"true\">&times;</span>\r\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\r\n</button>\r\n}\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:flex-start;box-sizing:border-box;margin:0;gap:var(--skra-comp-toast-icon-gap);font-family:var(--skra-sys-typography-role-body-medium-font-family);font-size:var(--skra-sys-typography-role-body-medium-font-size);font-weight:var(--skra-sys-typography-role-body-medium-font-weight);line-height:var(--skra-sys-typography-role-body-medium-line-height);letter-spacing:var(--skra-sys-typography-role-body-medium-letter-spacing);background:var(--skra-comp-toast-background);color:var(--skra-comp-toast-foreground);border-color:var(--skra-comp-toast-border-color);border-width:var(--skra-comp-toast-border-width);border-style:var(--skra-comp-toast-border-style);border-radius:var(--skra-comp-toast-radius);padding-block:var(--skra-comp-toast-padding-block);padding-inline:var(--skra-comp-toast-padding-inline);box-shadow:var(--skra-comp-toast-shadow);opacity:1;transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}@starting-style{:host{opacity:0}}:host([data-skra-emphasis=high]){--skra-comp-toast-border-width: 0}:host([data-skra-intent=neutral][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-high, var(--skra-sys-color-neutral-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-high, var(--skra-sys-color-neutral-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-high, transparent )}:host([data-skra-intent=neutral][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-medium, var(--skra-sys-color-neutral-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-medium, var(--skra-sys-color-neutral-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-medium, var(--skra-sys-color-neutral-border) )}:host([data-skra-intent=info][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-high, var(--skra-sys-color-info-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-high, var(--skra-sys-color-info-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-high, transparent )}:host([data-skra-intent=info][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-medium, var(--skra-sys-color-info-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-medium, var(--skra-sys-color-info-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-medium, var(--skra-sys-color-info-border) )}:host([data-skra-intent=success][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-high, var(--skra-sys-color-success-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-high, var(--skra-sys-color-success-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-high, transparent )}:host([data-skra-intent=success][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-medium, var(--skra-sys-color-success-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-medium, var(--skra-sys-color-success-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-medium, var(--skra-sys-color-success-border) )}:host([data-skra-intent=warning][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-high, var(--skra-sys-color-warning-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-high, var(--skra-sys-color-warning-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-high, transparent )}:host([data-skra-intent=warning][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-medium, var(--skra-sys-color-warning-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-medium, var(--skra-sys-color-warning-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-medium, var(--skra-sys-color-warning-border) )}:host([data-skra-intent=danger][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-high, var(--skra-sys-color-danger-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-high, var(--skra-sys-color-danger-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-high, transparent )}:host([data-skra-intent=danger][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-medium, var(--skra-sys-color-danger-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-medium, var(--skra-sys-color-danger-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-medium, var(--skra-sys-color-danger-border) )}.skra-toast-icon{display:inline-flex;flex-shrink:0;align-items:center;block-size:1lh;--skra-comp-icon-size: var(--skra-comp-toast-icon-size)}.skra-toast-content{flex:1 1 auto;min-inline-size:0}.skra-toast-dismiss{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--skra-comp-toast-dismiss-size);block-size:var(--skra-comp-toast-dismiss-size);margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;border-radius:var(--skra-comp-toast-radius);transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}.skra-toast-dismiss:hover{opacity:.7}.skra-toast-dismiss:focus-visible{outline-style:solid;outline-color:var(--skra-comp-toast-focus-ring-color);outline-width:var(--skra-comp-toast-focus-ring-width);outline-offset:2px}.skra-toast-dismiss-glyph{font-size:1.25em;line-height:1}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}.skra-toast-dismiss{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
117
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: SkraToast, isStandalone: true, selector: "skra-toast", inputs: { intent: { classPropertyName: "intent", publicName: "intent", isSignal: true, isRequired: false, transformFunction: null }, emphasis: { classPropertyName: "emphasis", publicName: "emphasis", isSignal: true, isRequired: false, transformFunction: null }, live: { classPropertyName: "live", publicName: "live", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismissed: "dismissed" }, host: { listeners: { "mouseenter": "pause()", "mouseleave": "resume()", "focusin": "pause()", "focusout": "resume()" }, properties: { "attr.data-skra-intent": "intent()", "attr.data-skra-emphasis": "emphasis()", "attr.data-skra-has-icon": "hasIcon() ? \"\" : null" } }, queries: [{ propertyName: "iconSlot", first: true, predicate: SkraToastIcon, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (hasIcon()) {\r\n<span class=\"skra-toast-icon\">\r\n <ng-content select=\"[skra-toast-icon]\"></ng-content>\r\n</span>\r\n}\r\n\r\n<div class=\"skra-toast-content\" #content>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n@if (dismissible()) {\r\n<button type=\"button\" class=\"skra-toast-dismiss\" (click)=\"onDismiss()\">\r\n <span class=\"skra-toast-dismiss-glyph\" aria-hidden=\"true\">&times;</span>\r\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\r\n</button>\r\n}\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:flex-start;box-sizing:border-box;margin:0;gap:var(--skra-comp-toast-icon-gap);font-family:var(--skra-sys-typography-role-body-medium-font-family);font-size:var(--skra-sys-typography-role-body-medium-font-size);font-weight:var(--skra-sys-typography-role-body-medium-font-weight);line-height:var(--skra-sys-typography-role-body-medium-line-height);letter-spacing:var(--skra-sys-typography-role-body-medium-letter-spacing);background:var(--skra-comp-toast-background);color:var(--skra-comp-toast-foreground);border-color:var(--skra-comp-toast-border-color);border-width:var(--skra-comp-toast-border-width);border-style:var(--skra-comp-toast-border-style);border-radius:var(--skra-comp-toast-radius);padding-block:var(--skra-comp-toast-padding-block);padding-inline:var(--skra-comp-toast-padding-inline);box-shadow:var(--skra-comp-toast-shadow);opacity:1;transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}@starting-style{:host{opacity:0}}:host([data-skra-emphasis=high]){--skra-comp-toast-border-width: 0}:host([data-skra-intent=neutral][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-high, var(--skra-sys-color-neutral-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-high, var(--skra-sys-color-neutral-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-high, transparent )}:host([data-skra-intent=neutral][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-medium, var(--skra-sys-color-neutral-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-medium, var(--skra-sys-color-neutral-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-medium, var(--skra-sys-color-neutral-border) )}:host([data-skra-intent=info][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-high, var(--skra-sys-color-info-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-high, var(--skra-sys-color-info-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-high, transparent )}:host([data-skra-intent=info][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-medium, var(--skra-sys-color-info-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-medium, var(--skra-sys-color-info-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-medium, var(--skra-sys-color-info-border) )}:host([data-skra-intent=success][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-high, var(--skra-sys-color-success-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-high, var(--skra-sys-color-success-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-high, transparent )}:host([data-skra-intent=success][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-medium, var(--skra-sys-color-success-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-medium, var(--skra-sys-color-success-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-medium, var(--skra-sys-color-success-border) )}:host([data-skra-intent=warning][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-high, var(--skra-sys-color-warning-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-high, var(--skra-sys-color-warning-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-high, transparent )}:host([data-skra-intent=warning][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-medium, var(--skra-sys-color-warning-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-medium, var(--skra-sys-color-warning-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-medium, var(--skra-sys-color-warning-border) )}:host([data-skra-intent=danger][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-high, var(--skra-sys-color-danger-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-high, var(--skra-sys-color-danger-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-high, transparent )}:host([data-skra-intent=danger][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-medium, var(--skra-sys-color-danger-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-medium, var(--skra-sys-color-danger-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-medium, var(--skra-sys-color-danger-border) )}.skra-toast-icon{display:inline-flex;flex-shrink:0;align-items:center;block-size:1lh;--skra-comp-icon-size: var(--skra-comp-toast-icon-size)}.skra-toast-content{flex:1 1 auto;min-inline-size:0}.skra-toast-dismiss{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--skra-comp-toast-dismiss-size);block-size:var(--skra-comp-toast-dismiss-size);margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;border-radius:var(--skra-comp-toast-radius);transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}@media(hover:hover)and (pointer:fine){.skra-toast-dismiss:hover{opacity:.7}}.skra-toast-dismiss:focus-visible{outline-style:solid;outline-color:var(--skra-comp-toast-focus-ring-color);outline-width:var(--skra-comp-toast-focus-ring-width);outline-offset:2px}.skra-toast-dismiss-glyph{font-size:1.25em;line-height:1}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}.skra-toast-dismiss{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
118
118
  }
119
119
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraToast, decorators: [{
120
120
  type: Component,
@@ -130,7 +130,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImpor
130
130
  '(mouseleave)': 'resume()',
131
131
  '(focusin)': 'pause()',
132
132
  '(focusout)': 'resume()',
133
- }, template: "@if (hasIcon()) {\r\n<span class=\"skra-toast-icon\">\r\n <ng-content select=\"[skra-toast-icon]\"></ng-content>\r\n</span>\r\n}\r\n\r\n<div class=\"skra-toast-content\" #content>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n@if (dismissible()) {\r\n<button type=\"button\" class=\"skra-toast-dismiss\" (click)=\"onDismiss()\">\r\n <span class=\"skra-toast-dismiss-glyph\" aria-hidden=\"true\">&times;</span>\r\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\r\n</button>\r\n}\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:flex-start;box-sizing:border-box;margin:0;gap:var(--skra-comp-toast-icon-gap);font-family:var(--skra-sys-typography-role-body-medium-font-family);font-size:var(--skra-sys-typography-role-body-medium-font-size);font-weight:var(--skra-sys-typography-role-body-medium-font-weight);line-height:var(--skra-sys-typography-role-body-medium-line-height);letter-spacing:var(--skra-sys-typography-role-body-medium-letter-spacing);background:var(--skra-comp-toast-background);color:var(--skra-comp-toast-foreground);border-color:var(--skra-comp-toast-border-color);border-width:var(--skra-comp-toast-border-width);border-style:var(--skra-comp-toast-border-style);border-radius:var(--skra-comp-toast-radius);padding-block:var(--skra-comp-toast-padding-block);padding-inline:var(--skra-comp-toast-padding-inline);box-shadow:var(--skra-comp-toast-shadow);opacity:1;transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}@starting-style{:host{opacity:0}}:host([data-skra-emphasis=high]){--skra-comp-toast-border-width: 0}:host([data-skra-intent=neutral][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-high, var(--skra-sys-color-neutral-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-high, var(--skra-sys-color-neutral-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-high, transparent )}:host([data-skra-intent=neutral][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-medium, var(--skra-sys-color-neutral-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-medium, var(--skra-sys-color-neutral-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-medium, var(--skra-sys-color-neutral-border) )}:host([data-skra-intent=info][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-high, var(--skra-sys-color-info-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-high, var(--skra-sys-color-info-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-high, transparent )}:host([data-skra-intent=info][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-medium, var(--skra-sys-color-info-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-medium, var(--skra-sys-color-info-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-medium, var(--skra-sys-color-info-border) )}:host([data-skra-intent=success][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-high, var(--skra-sys-color-success-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-high, var(--skra-sys-color-success-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-high, transparent )}:host([data-skra-intent=success][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-medium, var(--skra-sys-color-success-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-medium, var(--skra-sys-color-success-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-medium, var(--skra-sys-color-success-border) )}:host([data-skra-intent=warning][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-high, var(--skra-sys-color-warning-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-high, var(--skra-sys-color-warning-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-high, transparent )}:host([data-skra-intent=warning][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-medium, var(--skra-sys-color-warning-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-medium, var(--skra-sys-color-warning-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-medium, var(--skra-sys-color-warning-border) )}:host([data-skra-intent=danger][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-high, var(--skra-sys-color-danger-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-high, var(--skra-sys-color-danger-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-high, transparent )}:host([data-skra-intent=danger][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-medium, var(--skra-sys-color-danger-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-medium, var(--skra-sys-color-danger-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-medium, var(--skra-sys-color-danger-border) )}.skra-toast-icon{display:inline-flex;flex-shrink:0;align-items:center;block-size:1lh;--skra-comp-icon-size: var(--skra-comp-toast-icon-size)}.skra-toast-content{flex:1 1 auto;min-inline-size:0}.skra-toast-dismiss{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--skra-comp-toast-dismiss-size);block-size:var(--skra-comp-toast-dismiss-size);margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;border-radius:var(--skra-comp-toast-radius);transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}.skra-toast-dismiss:hover{opacity:.7}.skra-toast-dismiss:focus-visible{outline-style:solid;outline-color:var(--skra-comp-toast-focus-ring-color);outline-width:var(--skra-comp-toast-focus-ring-width);outline-offset:2px}.skra-toast-dismiss-glyph{font-size:1.25em;line-height:1}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}.skra-toast-dismiss{transition:none}}\n"] }]
133
+ }, template: "@if (hasIcon()) {\r\n<span class=\"skra-toast-icon\">\r\n <ng-content select=\"[skra-toast-icon]\"></ng-content>\r\n</span>\r\n}\r\n\r\n<div class=\"skra-toast-content\" #content>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n@if (dismissible()) {\r\n<button type=\"button\" class=\"skra-toast-dismiss\" (click)=\"onDismiss()\">\r\n <span class=\"skra-toast-dismiss-glyph\" aria-hidden=\"true\">&times;</span>\r\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\r\n</button>\r\n}\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:flex-start;box-sizing:border-box;margin:0;gap:var(--skra-comp-toast-icon-gap);font-family:var(--skra-sys-typography-role-body-medium-font-family);font-size:var(--skra-sys-typography-role-body-medium-font-size);font-weight:var(--skra-sys-typography-role-body-medium-font-weight);line-height:var(--skra-sys-typography-role-body-medium-line-height);letter-spacing:var(--skra-sys-typography-role-body-medium-letter-spacing);background:var(--skra-comp-toast-background);color:var(--skra-comp-toast-foreground);border-color:var(--skra-comp-toast-border-color);border-width:var(--skra-comp-toast-border-width);border-style:var(--skra-comp-toast-border-style);border-radius:var(--skra-comp-toast-radius);padding-block:var(--skra-comp-toast-padding-block);padding-inline:var(--skra-comp-toast-padding-inline);box-shadow:var(--skra-comp-toast-shadow);opacity:1;transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}@starting-style{:host{opacity:0}}:host([data-skra-emphasis=high]){--skra-comp-toast-border-width: 0}:host([data-skra-intent=neutral][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-high, var(--skra-sys-color-neutral-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-high, var(--skra-sys-color-neutral-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-high, transparent )}:host([data-skra-intent=neutral][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-medium, var(--skra-sys-color-neutral-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-medium, var(--skra-sys-color-neutral-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-medium, var(--skra-sys-color-neutral-border) )}:host([data-skra-intent=info][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-high, var(--skra-sys-color-info-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-high, var(--skra-sys-color-info-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-high, transparent )}:host([data-skra-intent=info][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-medium, var(--skra-sys-color-info-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-medium, var(--skra-sys-color-info-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-medium, var(--skra-sys-color-info-border) )}:host([data-skra-intent=success][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-high, var(--skra-sys-color-success-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-high, var(--skra-sys-color-success-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-high, transparent )}:host([data-skra-intent=success][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-medium, var(--skra-sys-color-success-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-medium, var(--skra-sys-color-success-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-medium, var(--skra-sys-color-success-border) )}:host([data-skra-intent=warning][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-high, var(--skra-sys-color-warning-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-high, var(--skra-sys-color-warning-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-high, transparent )}:host([data-skra-intent=warning][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-medium, var(--skra-sys-color-warning-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-medium, var(--skra-sys-color-warning-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-medium, var(--skra-sys-color-warning-border) )}:host([data-skra-intent=danger][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-high, var(--skra-sys-color-danger-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-high, var(--skra-sys-color-danger-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-high, transparent )}:host([data-skra-intent=danger][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-medium, var(--skra-sys-color-danger-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-medium, var(--skra-sys-color-danger-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-medium, var(--skra-sys-color-danger-border) )}.skra-toast-icon{display:inline-flex;flex-shrink:0;align-items:center;block-size:1lh;--skra-comp-icon-size: var(--skra-comp-toast-icon-size)}.skra-toast-content{flex:1 1 auto;min-inline-size:0}.skra-toast-dismiss{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--skra-comp-toast-dismiss-size);block-size:var(--skra-comp-toast-dismiss-size);margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;border-radius:var(--skra-comp-toast-radius);transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}@media(hover:hover)and (pointer:fine){.skra-toast-dismiss:hover{opacity:.7}}.skra-toast-dismiss:focus-visible{outline-style:solid;outline-color:var(--skra-comp-toast-focus-ring-color);outline-width:var(--skra-comp-toast-focus-ring-width);outline-offset:2px}.skra-toast-dismiss-glyph{font-size:1.25em;line-height:1}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}.skra-toast-dismiss{transition:none}}\n"] }]
134
134
  }], ctorParameters: () => [], propDecorators: { intent: [{ type: i0.Input, args: [{ isSignal: true, alias: "intent", required: false }] }], emphasis: [{ type: i0.Input, args: [{ isSignal: true, alias: "emphasis", required: false }] }], live: [{ type: i0.Input, args: [{ isSignal: true, alias: "live", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], dismissed: [{ type: i0.Output, args: ["dismissed"] }], iconSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SkraToastIcon), { isSignal: true }] }], contentRef: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }] } });
135
135
 
136
136
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-toast.mjs","sources":["../../../../libs/ui/toast/src/lib/toast.directives.ts","../../../../libs/ui/toast/src/lib/toast/toast-announcer.ts","../../../../libs/ui/toast/src/lib/toast/toast.ts","../../../../libs/ui/toast/src/lib/toast/toast.html","../../../../libs/ui/toast/src/lib/toast/toast-region.ts","../../../../libs/ui/toast/src/lib/toast/toast-region.html","../../../../libs/ui/toast/src/skra-ui-toast.ts"],"sourcesContent":["import { Directive } from '@angular/core';\r\n\r\n/**\r\n * Marker directive for the leading icon slot of `<skra-toast>`.\r\n * Detected via `contentChild` (ADR 020 Smart Slots v2.0) to toggle the icon\r\n * wrapper without emitting an empty DOM node. Feedback-local (not the button\r\n * lib's `[skra-start]`) to avoid a cross-lib marker dependency — mirrors\r\n * `[skra-alert-icon]` / `[skra-badge-icon]`.\r\n */\r\n@Directive({\r\n selector: '[skra-toast-icon]',\r\n standalone: true,\r\n})\r\nexport class SkraToastIcon {}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\n/**\r\n * Politeness routed to the toast region's role-only announcer (ADR 0052 §7).\r\n * `off` never reaches the announcer (no announcement), so the seam only carries\r\n * the two announced levels.\r\n */\r\nexport type SkraToastPoliteness = 'polite' | 'assertive';\r\n\r\n/**\r\n * The ADR 0052 §7 announcement seam. Provided by `<skra-toast-region>` and injected\r\n * (optionally) by each projected `<skra-toast>`. The toast pushes its message text on\r\n * appearance; the region writes it into the matching PERSISTENT, role-only announcer\r\n * (`role=\"status\"` for polite / `role=\"alert\"` for assertive) — never a role/`aria-live`\r\n * on the ephemeral toast host. This is why a live region pre-exists the content it\r\n * announces (WCAG 4.1.3): the announcers are rendered from the region's first render.\r\n *\r\n * Narrow seam (like `SkraSelectPanel` / `SkraFieldContext`): the toast depends on the\r\n * interface, not the concrete region. Content-projected toasts inject from their DECLARED\r\n * parent element (= the region), the same DI mechanism as `SkraFieldContext` (ADR 013).\r\n */\r\nexport interface SkraToastAnnouncer {\r\n /** Announce `text` at the given politeness by writing it into the matching live region. */\r\n announce(text: string, politeness: SkraToastPoliteness): void;\r\n}\r\n\r\nexport const SKRA_TOAST_ANNOUNCER = new InjectionToken<SkraToastAnnouncer>(\r\n 'SKRA_TOAST_ANNOUNCER',\r\n);\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n DestroyRef,\r\n ElementRef,\r\n ViewEncapsulation,\r\n afterNextRender,\r\n booleanAttribute,\r\n computed,\r\n contentChild,\r\n inject,\r\n input,\r\n output,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { SkraToastIcon } from '../toast.directives';\r\nimport {\r\n SKRA_TOAST_ANNOUNCER,\r\n type SkraToastPoliteness,\r\n} from './toast-announcer';\r\n\r\n/**\r\n * ToastIntent — semantic feedback meaning (ADR 035 §3.1, downward subset). Excludes the\r\n * action intents `primary`/`secondary`. Same enum as Alert/Badge.\r\n */\r\nexport type ToastIntent = 'neutral' | 'info' | 'success' | 'warning' | 'danger';\r\n\r\n/** ToastEmphasis — `high` = filled, `medium` = soft. `low` deferred (ADR 035 §3.1). */\r\nexport type ToastEmphasis = 'high' | 'medium';\r\n\r\n/**\r\n * ToastLive — screen-reader announcement politeness (ADR 0052). For Toast the politeness\r\n * is routed to the REGION's announcer (ADR 0052 §7); it does NOT set a role on this host.\r\n * Default `polite` (toasts are always dynamically presented — ADR 0052 §4). `assertive`\r\n * for error toasts, set explicitly by the consumer — NEVER auto-derived from `intent`.\r\n */\r\nexport type ToastLive = 'off' | 'polite' | 'assertive';\r\n\r\n/**\r\n * `<skra-toast>` — an ephemeral, auto-dismissing feedback message rendered inside a\r\n * `<skra-toast-region>` top-layer stack (Feedback/Status family, ADR 0052; Tier 2 overlay,\r\n * ADR 0044). Visually an Alert (intent×emphasis seam, 4th consumer) with a timer.\r\n *\r\n * Announcement (ADR 0052 §7): this host carries NO `role`/`aria-live`. On appearance the\r\n * toast pushes its message text into the region's persistent role-only announcer via the\r\n * injected `SkraToastAnnouncer`, at the politeness of `live` (`off` → no announcement).\r\n *\r\n * Auto-dismiss (WCAG 2.2.1): after `duration` ms the toast emits `(dismissed)`. The timer\r\n * PAUSES on hover and on focus-within and resumes with the remaining time; `duration=0`\r\n * disables it (persistent — pair with `dismissible`). Forge does NOT self-remove — the\r\n * consumer removes the model from its array on `(dismissed)` (agnostic doctrine; the Alert\r\n * precedent). `(dismissed)` is the single removal channel (timer elapse OR close control).\r\n */\r\n@Component({\r\n selector: 'skra-toast',\r\n standalone: true,\r\n imports: [SkraToastIcon],\r\n templateUrl: './toast.html',\r\n styleUrl: './toast.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // Variant Surface reflection (ADR 035 §3.5; ADR 021 — never [style.--var])\r\n '[attr.data-skra-intent]': 'intent()',\r\n '[attr.data-skra-emphasis]': 'emphasis()',\r\n // Smart Slot layout reflection (ADR 020 v2.0 — slot-presence, State-Surface-exempt §3.6)\r\n '[attr.data-skra-has-icon]': 'hasIcon() ? \"\" : null',\r\n // NO `role` / NO `aria-live` here — the region announces (ADR 0052 §7).\r\n // Pause/resume the auto-dismiss timer on hover + focus (WCAG 2.2.1 Timing Adjustable).\r\n '(mouseenter)': 'pause()',\r\n '(mouseleave)': 'resume()',\r\n '(focusin)': 'pause()',\r\n '(focusout)': 'resume()',\r\n },\r\n})\r\nexport class SkraToast {\r\n // --- Variant Surface (ADR 035) ---\r\n readonly intent = input<ToastIntent>('neutral');\r\n readonly emphasis = input<ToastEmphasis>('medium');\r\n\r\n // --- Announcement (ADR 0052 §7) ---\r\n readonly live = input<ToastLive>('polite');\r\n\r\n // --- Auto-dismiss + dismissal ---\r\n readonly duration = input<number>(5000);\r\n readonly dismissible = input(false, { transform: booleanAttribute });\r\n readonly dismissed = output<void>();\r\n\r\n // --- Smart Slots v2.0 (ADR 020) ---\r\n readonly iconSlot = contentChild(SkraToastIcon);\r\n readonly hasIcon = computed(() => !!this.iconSlot());\r\n\r\n /** The message column — its text is the announcement (excludes the icon + sr-only close label). */\r\n private readonly contentRef =\r\n viewChild.required<ElementRef<HTMLElement>>('content');\r\n\r\n private readonly announcer = inject(SKRA_TOAST_ANNOUNCER, {\r\n optional: true,\r\n });\r\n\r\n private timerId: ReturnType<typeof setTimeout> | null = null;\r\n private remaining = 0;\r\n private startedAt = 0;\r\n\r\n constructor() {\r\n afterNextRender(() => {\r\n // Announce on appearance (browser-only; projected content is present post-render).\r\n const live = this.live();\r\n if (live !== 'off' && this.announcer) {\r\n const text = this.contentRef().nativeElement.textContent?.trim() ?? '';\r\n if (text) this.announcer.announce(text, live as SkraToastPoliteness);\r\n }\r\n // Start the auto-dismiss countdown (timers are browser-only — SSR-safe by construction).\r\n this.remaining = this.duration();\r\n this.start();\r\n });\r\n inject(DestroyRef).onDestroy(() => this.clear());\r\n }\r\n\r\n protected onDismiss(): void {\r\n this.clear();\r\n this.dismissed.emit();\r\n }\r\n\r\n /** Pause the countdown, banking the remaining time (WCAG 2.2.1). */\r\n protected pause(): void {\r\n if (this.timerId === null) return;\r\n clearTimeout(this.timerId);\r\n this.timerId = null;\r\n this.remaining -= Date.now() - this.startedAt;\r\n }\r\n\r\n /** Resume the countdown with the banked remaining time. */\r\n protected resume(): void {\r\n if (this.timerId !== null) return;\r\n this.start();\r\n }\r\n\r\n private start(): void {\r\n if (this.remaining <= 0) return; // duration=0 (or fully elapsed) → persistent\r\n this.startedAt = Date.now();\r\n this.timerId = setTimeout(() => {\r\n this.timerId = null;\r\n this.dismissed.emit();\r\n }, this.remaining);\r\n }\r\n\r\n private clear(): void {\r\n if (this.timerId !== null) {\r\n clearTimeout(this.timerId);\r\n this.timerId = null;\r\n }\r\n }\r\n}\r\n","@if (hasIcon()) {\r\n<span class=\"skra-toast-icon\">\r\n <ng-content select=\"[skra-toast-icon]\"></ng-content>\r\n</span>\r\n}\r\n\r\n<div class=\"skra-toast-content\" #content>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n@if (dismissible()) {\r\n<button type=\"button\" class=\"skra-toast-dismiss\" (click)=\"onDismiss()\">\r\n <span class=\"skra-toast-dismiss-glyph\" aria-hidden=\"true\">&times;</span>\r\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\r\n</button>\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n ViewEncapsulation,\r\n afterRenderEffect,\r\n contentChildren,\r\n input,\r\n signal,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { SkraToast } from './toast';\r\nimport {\r\n SKRA_TOAST_ANNOUNCER,\r\n type SkraToastAnnouncer,\r\n type SkraToastPoliteness,\r\n} from './toast-announcer';\r\n\r\n/**\r\n * ToastPlacement — viewport corner, logical (RTL-correct). `block-start`/`block-end` = the\r\n * top/bottom edge; `inline-start`/`center`/`inline-end` = the horizontal position.\r\n */\r\nexport type ToastPlacement =\r\n | 'block-start inline-start'\r\n | 'block-start center'\r\n | 'block-start inline-end'\r\n | 'block-end inline-start'\r\n | 'block-end center'\r\n | 'block-end inline-end';\r\n\r\n/**\r\n * `<skra-toast-region>` — the persistent, app-root manager for `<skra-toast>` (ADR 0044 §7\r\n * non-anchored top-layer; ADR 0052 §7 announcer). Place ONCE near the app root; the consumer\r\n * projects its own `@for` of toast models into it and owns the array (agnostic doctrine —\r\n * a `ToastService` push/remove helper is a consumer recipe, NOT shipped here).\r\n *\r\n * Two mechanisms:\r\n * - Announcement (ADR 0052 §7): provides `SkraToastAnnouncer` + renders TWO persistent,\r\n * visually-hidden, role-only announcers (`role=\"status\"` polite / `role=\"alert\"` assertive).\r\n * A toast pushes its text on appearance; identical repeated messages re-announce via a\r\n * clear-then-set across two frames (forces a live-region mutation).\r\n * - Top layer (ADR 0044 §7): a SINGLE `popover=\"manual\"` stack (not `auto` — no light-dismiss /\r\n * Escape collapse; not N popovers). Shown when non-empty; RE-ASSERTS top-layer order on each\r\n * addition (`hidePopover()`+`showPopover()`) so a toast raised over an open modal `<dialog>`\r\n * paints above it. Paint-only — never moves focus, never disturbs the dialog. Zero z-index.\r\n */\r\n@Component({\r\n selector: 'skra-toast-region',\r\n standalone: true,\r\n templateUrl: './toast-region.html',\r\n styleUrl: './toast-region.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n '[attr.data-skra-placement]': 'placement()',\r\n },\r\n providers: [{ provide: SKRA_TOAST_ANNOUNCER, useExisting: SkraToastRegion }],\r\n})\r\nexport class SkraToastRegion implements SkraToastAnnouncer {\r\n readonly placement = input<ToastPlacement>('block-end inline-end');\r\n\r\n /** The two persistent role-only announcer buffers (ADR 0052 §7). */\r\n protected readonly politeMsg = signal('');\r\n protected readonly assertiveMsg = signal('');\r\n\r\n private readonly toasts = contentChildren(SkraToast);\r\n private readonly stackEl =\r\n viewChild.required<ElementRef<HTMLElement>>('stack');\r\n\r\n /** Tracked locally — jsdom/SSR have no `:popover-open`; never read it back. */\r\n private shown = false;\r\n private prevCount = 0;\r\n\r\n constructor() {\r\n // Browser-only (afterRender family never runs on the server — SSR-safe, O-18). Reads the\r\n // contentChildren signal so it re-runs whenever the visible toast set changes.\r\n afterRenderEffect(() => {\r\n // Re-assert keys on the COUNT, not toast identity: a remove+add in the SAME change-detection\r\n // tick keeps `n` unchanged and skips the re-assert, so the new toast would not be raised above\r\n // an already-open modal. Accepted for the auto-dismiss MVP (paint-only; announcement is\r\n // unaffected); the cross-browser top-layer pass folds into O-9 (spec Open Question 3).\r\n const n = this.toasts().length;\r\n const stack = this.stackEl().nativeElement;\r\n if (n > 0) {\r\n if (n > this.prevCount && this.shown) {\r\n // Re-assert top-layer order on additions (ADR 0044 §7) — drop then re-add to the top.\r\n stack.hidePopover?.();\r\n this.shown = false;\r\n }\r\n if (!this.shown) {\r\n stack.showPopover?.();\r\n this.shown = true;\r\n }\r\n } else if (this.shown) {\r\n stack.hidePopover?.();\r\n this.shown = false;\r\n }\r\n this.prevCount = n;\r\n });\r\n }\r\n\r\n /**\r\n * ADR 0052 §7 — write `text` into the matching persistent announcer. Clear-then-set across two\r\n * animation frames so a repeated IDENTICAL message still mutates the live region and re-announces\r\n * (the \"repeated action\" case). `off` toasts never call this.\r\n */\r\n announce(text: string, politeness: SkraToastPoliteness): void {\r\n const target =\r\n politeness === 'assertive' ? this.assertiveMsg : this.politeMsg;\r\n target.set('');\r\n requestAnimationFrame(() => requestAnimationFrame(() => target.set(text)));\r\n }\r\n}\r\n","<div class=\"skra-toast-stack\" popover=\"manual\" #stack>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n<!--\r\n ADR 0052 §7 — two PERSISTENT, role-only live announcers, held in normal flow (NOT inside the\r\n popover, so they are pre-armed and announce regardless of the stack's shown/paint state).\r\n role=\"status\" carries aria-live=polite + aria-atomic; role=\"alert\" carries assertive + atomic\r\n (implicitly — no explicit aria-live, ADR 0052 rule 2). Each holds one message at a time.\r\n-->\r\n<div class=\"skra-sr-only\" role=\"status\">{{ politeMsg() }}</div>\r\n<div class=\"skra-sr-only\" role=\"alert\">{{ assertiveMsg() }}</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skra-ui-toast.mjs","sources":["../../../../libs/ui/toast/src/lib/toast.directives.ts","../../../../libs/ui/toast/src/lib/toast/toast-announcer.ts","../../../../libs/ui/toast/src/lib/toast/toast.ts","../../../../libs/ui/toast/src/lib/toast/toast.html","../../../../libs/ui/toast/src/lib/toast/toast-region.ts","../../../../libs/ui/toast/src/lib/toast/toast-region.html","../../../../libs/ui/toast/src/skra-ui-toast.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n/**\n * Marker directive for the leading icon slot of `<skra-toast>`.\n * Detected via `contentChild` (ADR 020 Smart Slots v2.0) to toggle the icon\n * wrapper without emitting an empty DOM node. Feedback-local (not the button\n * lib's `[skra-start]`) to avoid a cross-lib marker dependency — mirrors\n * `[skra-alert-icon]` / `[skra-badge-icon]`.\n */\n@Directive({\n selector: '[skra-toast-icon]',\n standalone: true,\n})\nexport class SkraToastIcon {}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Politeness routed to the toast region's role-only announcer (ADR 0052 §7).\n * `off` never reaches the announcer (no announcement), so the seam only carries\n * the two announced levels.\n */\nexport type SkraToastPoliteness = 'polite' | 'assertive';\n\n/**\n * The ADR 0052 §7 announcement seam. Provided by `<skra-toast-region>` and injected\n * (optionally) by each projected `<skra-toast>`. The toast pushes its message text on\n * appearance; the region writes it into the matching PERSISTENT, role-only announcer\n * (`role=\"status\"` for polite / `role=\"alert\"` for assertive) — never a role/`aria-live`\n * on the ephemeral toast host. This is why a live region pre-exists the content it\n * announces (WCAG 4.1.3): the announcers are rendered from the region's first render.\n *\n * Narrow seam (like `SkraSelectPanel` / `SkraFieldContext`): the toast depends on the\n * interface, not the concrete region. Content-projected toasts inject from their DECLARED\n * parent element (= the region), the same DI mechanism as `SkraFieldContext` (ADR 013).\n */\nexport interface SkraToastAnnouncer {\n /** Announce `text` at the given politeness by writing it into the matching live region. */\n announce(text: string, politeness: SkraToastPoliteness): void;\n}\n\nexport const SKRA_TOAST_ANNOUNCER = new InjectionToken<SkraToastAnnouncer>(\n 'SKRA_TOAST_ANNOUNCER',\n);\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n ViewEncapsulation,\n afterNextRender,\n booleanAttribute,\n computed,\n contentChild,\n inject,\n input,\n output,\n viewChild,\n} from '@angular/core';\nimport { SkraToastIcon } from '../toast.directives';\nimport {\n SKRA_TOAST_ANNOUNCER,\n type SkraToastPoliteness,\n} from './toast-announcer';\n\n/**\n * ToastIntent — semantic feedback meaning (ADR 035 §3.1, downward subset). Excludes the\n * action intents `primary`/`secondary`. Same enum as Alert/Badge.\n */\nexport type ToastIntent = 'neutral' | 'info' | 'success' | 'warning' | 'danger';\n\n/** ToastEmphasis — `high` = filled, `medium` = soft. `low` deferred (ADR 035 §3.1). */\nexport type ToastEmphasis = 'high' | 'medium';\n\n/**\n * ToastLive — screen-reader announcement politeness (ADR 0052). For Toast the politeness\n * is routed to the REGION's announcer (ADR 0052 §7); it does NOT set a role on this host.\n * Default `polite` (toasts are always dynamically presented — ADR 0052 §4). `assertive`\n * for error toasts, set explicitly by the consumer — NEVER auto-derived from `intent`.\n */\nexport type ToastLive = 'off' | 'polite' | 'assertive';\n\n/**\n * `<skra-toast>` — an ephemeral, auto-dismissing feedback message rendered inside a\n * `<skra-toast-region>` top-layer stack (Feedback/Status family, ADR 0052; Tier 2 overlay,\n * ADR 0044). Visually an Alert (intent×emphasis seam, 4th consumer) with a timer.\n *\n * Announcement (ADR 0052 §7): this host carries NO `role`/`aria-live`. On appearance the\n * toast pushes its message text into the region's persistent role-only announcer via the\n * injected `SkraToastAnnouncer`, at the politeness of `live` (`off` → no announcement).\n *\n * Auto-dismiss (WCAG 2.2.1): after `duration` ms the toast emits `(dismissed)`. The timer\n * PAUSES on hover and on focus-within and resumes with the remaining time; `duration=0`\n * disables it (persistent — pair with `dismissible`). Forge does NOT self-remove — the\n * consumer removes the model from its array on `(dismissed)` (agnostic doctrine; the Alert\n * precedent). `(dismissed)` is the single removal channel (timer elapse OR close control).\n */\n@Component({\n selector: 'skra-toast',\n standalone: true,\n imports: [SkraToastIcon],\n templateUrl: './toast.html',\n styleUrl: './toast.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n // Variant Surface reflection (ADR 035 §3.5; ADR 021 — never [style.--var])\n '[attr.data-skra-intent]': 'intent()',\n '[attr.data-skra-emphasis]': 'emphasis()',\n // Smart Slot layout reflection (ADR 020 v2.0 — slot-presence, State-Surface-exempt §3.6)\n '[attr.data-skra-has-icon]': 'hasIcon() ? \"\" : null',\n // NO `role` / NO `aria-live` here — the region announces (ADR 0052 §7).\n // Pause/resume the auto-dismiss timer on hover + focus (WCAG 2.2.1 Timing Adjustable).\n '(mouseenter)': 'pause()',\n '(mouseleave)': 'resume()',\n '(focusin)': 'pause()',\n '(focusout)': 'resume()',\n },\n})\nexport class SkraToast {\n // --- Variant Surface (ADR 035) ---\n readonly intent = input<ToastIntent>('neutral');\n readonly emphasis = input<ToastEmphasis>('medium');\n\n // --- Announcement (ADR 0052 §7) ---\n readonly live = input<ToastLive>('polite');\n\n // --- Auto-dismiss + dismissal ---\n readonly duration = input<number>(5000);\n readonly dismissible = input(false, { transform: booleanAttribute });\n readonly dismissed = output<void>();\n\n // --- Smart Slots v2.0 (ADR 020) ---\n readonly iconSlot = contentChild(SkraToastIcon);\n readonly hasIcon = computed(() => !!this.iconSlot());\n\n /** The message column — its text is the announcement (excludes the icon + sr-only close label). */\n private readonly contentRef =\n viewChild.required<ElementRef<HTMLElement>>('content');\n\n private readonly announcer = inject(SKRA_TOAST_ANNOUNCER, {\n optional: true,\n });\n\n private timerId: ReturnType<typeof setTimeout> | null = null;\n private remaining = 0;\n private startedAt = 0;\n\n constructor() {\n afterNextRender(() => {\n // Announce on appearance (browser-only; projected content is present post-render).\n const live = this.live();\n if (live !== 'off' && this.announcer) {\n const text = this.contentRef().nativeElement.textContent?.trim() ?? '';\n if (text) this.announcer.announce(text, live as SkraToastPoliteness);\n }\n // Start the auto-dismiss countdown (timers are browser-only — SSR-safe by construction).\n this.remaining = this.duration();\n this.start();\n });\n inject(DestroyRef).onDestroy(() => this.clear());\n }\n\n protected onDismiss(): void {\n this.clear();\n this.dismissed.emit();\n }\n\n /** Pause the countdown, banking the remaining time (WCAG 2.2.1). */\n protected pause(): void {\n if (this.timerId === null) return;\n clearTimeout(this.timerId);\n this.timerId = null;\n this.remaining -= Date.now() - this.startedAt;\n }\n\n /** Resume the countdown with the banked remaining time. */\n protected resume(): void {\n if (this.timerId !== null) return;\n this.start();\n }\n\n private start(): void {\n if (this.remaining <= 0) return; // duration=0 (or fully elapsed) → persistent\n this.startedAt = Date.now();\n this.timerId = setTimeout(() => {\n this.timerId = null;\n this.dismissed.emit();\n }, this.remaining);\n }\n\n private clear(): void {\n if (this.timerId !== null) {\n clearTimeout(this.timerId);\n this.timerId = null;\n }\n }\n}\n","@if (hasIcon()) {\r\n<span class=\"skra-toast-icon\">\r\n <ng-content select=\"[skra-toast-icon]\"></ng-content>\r\n</span>\r\n}\r\n\r\n<div class=\"skra-toast-content\" #content>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n@if (dismissible()) {\r\n<button type=\"button\" class=\"skra-toast-dismiss\" (click)=\"onDismiss()\">\r\n <span class=\"skra-toast-dismiss-glyph\" aria-hidden=\"true\">&times;</span>\r\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\r\n</button>\r\n}\r\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n afterRenderEffect,\n contentChildren,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { SkraToast } from './toast';\nimport {\n SKRA_TOAST_ANNOUNCER,\n type SkraToastAnnouncer,\n type SkraToastPoliteness,\n} from './toast-announcer';\n\n/**\n * ToastPlacement — viewport corner, logical (RTL-correct). `block-start`/`block-end` = the\n * top/bottom edge; `inline-start`/`center`/`inline-end` = the horizontal position.\n */\nexport type ToastPlacement =\n | 'block-start inline-start'\n | 'block-start center'\n | 'block-start inline-end'\n | 'block-end inline-start'\n | 'block-end center'\n | 'block-end inline-end';\n\n/**\n * `<skra-toast-region>` — the persistent, app-root manager for `<skra-toast>` (ADR 0044 §7\n * non-anchored top-layer; ADR 0052 §7 announcer). Place ONCE near the app root; the consumer\n * projects its own `@for` of toast models into it and owns the array (agnostic doctrine —\n * a `ToastService` push/remove helper is a consumer recipe, NOT shipped here).\n *\n * Two mechanisms:\n * - Announcement (ADR 0052 §7): provides `SkraToastAnnouncer` + renders TWO persistent,\n * visually-hidden, role-only announcers (`role=\"status\"` polite / `role=\"alert\"` assertive).\n * A toast pushes its text on appearance; identical repeated messages re-announce via a\n * clear-then-set across two frames (forces a live-region mutation).\n * - Top layer (ADR 0044 §7): a SINGLE `popover=\"manual\"` stack (not `auto` — no light-dismiss /\n * Escape collapse; not N popovers). Shown when non-empty; RE-ASSERTS top-layer order on each\n * addition (`hidePopover()`+`showPopover()`) so a toast raised over an open modal `<dialog>`\n * paints above it. Paint-only — never moves focus, never disturbs the dialog. Zero z-index.\n */\n@Component({\n selector: 'skra-toast-region',\n standalone: true,\n templateUrl: './toast-region.html',\n styleUrl: './toast-region.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n '[attr.data-skra-placement]': 'placement()',\n },\n providers: [{ provide: SKRA_TOAST_ANNOUNCER, useExisting: SkraToastRegion }],\n})\nexport class SkraToastRegion implements SkraToastAnnouncer {\n readonly placement = input<ToastPlacement>('block-end inline-end');\n\n /** The two persistent role-only announcer buffers (ADR 0052 §7). */\n protected readonly politeMsg = signal('');\n protected readonly assertiveMsg = signal('');\n\n private readonly toasts = contentChildren(SkraToast);\n private readonly stackEl =\n viewChild.required<ElementRef<HTMLElement>>('stack');\n\n /** Tracked locally — jsdom/SSR have no `:popover-open`; never read it back. */\n private shown = false;\n private prevCount = 0;\n\n constructor() {\n // Browser-only (afterRender family never runs on the server — SSR-safe, O-18). Reads the\n // contentChildren signal so it re-runs whenever the visible toast set changes.\n afterRenderEffect(() => {\n // Re-assert keys on the COUNT, not toast identity: a remove+add in the SAME change-detection\n // tick keeps `n` unchanged and skips the re-assert, so the new toast would not be raised above\n // an already-open modal. Accepted for the auto-dismiss MVP (paint-only; announcement is\n // unaffected); the cross-browser top-layer pass folds into O-9 (spec Open Question 3).\n const n = this.toasts().length;\n const stack = this.stackEl().nativeElement;\n if (n > 0) {\n if (n > this.prevCount && this.shown) {\n // Re-assert top-layer order on additions (ADR 0044 §7) — drop then re-add to the top.\n stack.hidePopover?.();\n this.shown = false;\n }\n if (!this.shown) {\n stack.showPopover?.();\n this.shown = true;\n }\n } else if (this.shown) {\n stack.hidePopover?.();\n this.shown = false;\n }\n this.prevCount = n;\n });\n }\n\n /**\n * ADR 0052 §7 — write `text` into the matching persistent announcer. Clear-then-set across two\n * animation frames so a repeated IDENTICAL message still mutates the live region and re-announces\n * (the \"repeated action\" case). `off` toasts never call this.\n */\n announce(text: string, politeness: SkraToastPoliteness): void {\n const target =\n politeness === 'assertive' ? this.assertiveMsg : this.politeMsg;\n target.set('');\n requestAnimationFrame(() => requestAnimationFrame(() => target.set(text)));\n }\n}\n","<div class=\"skra-toast-stack\" popover=\"manual\" #stack>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n<!--\r\n ADR 0052 §7 — two PERSISTENT, role-only live announcers, held in normal flow (NOT inside the\r\n popover, so they are pre-armed and announce regardless of the stack's shown/paint state).\r\n role=\"status\" carries aria-live=polite + aria-atomic; role=\"alert\" carries assertive + atomic\r\n (implicitly — no explicit aria-live, ADR 0052 rule 2). Each holds one message at a time.\r\n-->\r\n<div class=\"skra-sr-only\" role=\"status\">{{ politeMsg() }}</div>\r\n<div class=\"skra-sr-only\" role=\"alert\">{{ assertiveMsg() }}</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-tooltip.mjs","sources":["../../../../libs/ui/tooltip/src/lib/tooltip/tooltip-panel.ts","../../../../libs/ui/tooltip/src/lib/tooltip/tooltip.ts","../../../../libs/ui/tooltip/src/skra-ui-tooltip.ts"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n input,\r\n} from '@angular/core';\r\n\r\nlet nextId = 0;\r\n\r\n/**\r\n * SkraTooltipPanel — the floating tooltip surface (ADR 0044 native top layer via the Popover API).\r\n *\r\n * INTERNAL: never placed by consumers in a template. `SkraTooltip` creates it programmatically with\r\n * `ViewContainerRef.createComponent` (Angular-idiomatic, in-tree → inherits the design-context cascade\r\n * + the O-8 Shadow-DOM bridge per ADR 0044 §3 rule 3) and drives `showPopover()`/`hidePopover()` on the\r\n * host element.\r\n *\r\n * `popover=\"manual\"` (NOT `auto`): a hover/focus tooltip's show/hide is Forge-owned, not click-toggle\r\n * light-dismiss. `role=\"tooltip\"` is the AT semantics; the trigger references this panel's `id` via\r\n * `aria-describedby` (wired by the directive). The 13-axis Universal Surface (ADR 025) + motion live in\r\n * `tooltip.scss`; geometry (`left`/`top` + `data-skra-placement`) is written by `SkraPositioner`.\r\n *\r\n * Full contract: adr/specs/component-tooltip-spec.md.\r\n */\r\n@Component({\r\n selector: 'skra-tooltip-panel',\r\n standalone: true,\r\n template: '{{ text() }}',\r\n styleUrl: './tooltip.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n role: 'tooltip',\r\n popover: 'manual',\r\n '[id]': 'panelId',\r\n },\r\n})\r\nexport class SkraTooltipPanel {\r\n /** Tooltip text; set by the directive and kept in sync. */\r\n readonly text = input<string>('');\r\n\r\n /** Stable unique id — target of the trigger's `aria-describedby`. */\r\n readonly panelId = `skra-tooltip-${nextId++}`;\r\n}\r\n","import {\r\n ComponentRef,\r\n DestroyRef,\r\n Directive,\r\n ElementRef,\r\n Renderer2,\r\n ViewContainerRef,\r\n effect,\r\n inject,\r\n input,\r\n} from '@angular/core';\r\n\r\nimport {\r\n _attachPositioner,\r\n type SkraPlacement,\r\n type _PositionerHandle,\r\n} from '@skra/ui/core';\r\nimport { SkraTooltipPanel } from './tooltip-panel';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/** A focusable trigger is required (WCAG 2.1.1); used only for the dev-mode nudge. */\r\nconst FOCUSABLE_SELECTOR =\r\n 'a[href],area[href],button,input,select,textarea,[tabindex],summary,' +\r\n '[contenteditable]:not([contenteditable=\"false\"])';\r\n\r\n/**\r\n * SkraTooltip — a supplementary, non-interactive text description on a focusable trigger, shown on\r\n * hover AND keyboard focus (ADR 0044 native top layer via the Popover API). Applied to the consumer's\r\n * own trigger: `<button skraButton [skraTooltip]=\"'Settings'\">`.\r\n *\r\n * The bulk of this directive is the WCAG 1.4.13 (Content on Hover or Focus) state machine — the\r\n * platform's `popover=\"manual\"` gives top-layer rendering but no dismiss/Escape, so Forge wires it:\r\n * - Dismissible: Escape hides WITHOUT moving focus.\r\n * - Hoverable: a hide grace-delay lets the pointer travel trigger→panel; hovering the panel keeps it.\r\n * - Persistent: no auto-timeout.\r\n * - Keyboard: focus shows immediately (no delay).\r\n *\r\n * Accessible-name contract (ADR 033, describedby-only): the tooltip is a DESCRIPTION, never the name —\r\n * it MERGES its panel id into the trigger's `aria-describedby` (preserving any existing value) and\r\n * removes only its own token on destroy. The trigger owns its own accessible name (an icon-only button\r\n * still needs its own `aria-label`). No `ariaLabel` input, no `aria-labelledby` wiring.\r\n *\r\n * The panel is created EAGERLY (hidden) so `aria-describedby` resolves and a screen reader announces\r\n * the description on first focus. Positioning is delegated to `SkraPositioner` (single JS path,\r\n * geometry-only inline; ADR 0044 §3 rules 4–5). Full contract: adr/specs/component-tooltip-spec.md.\r\n */\r\n@Directive({\r\n selector: '[skraTooltip]',\r\n standalone: true,\r\n exportAs: 'skraTooltip',\r\n host: {\r\n '(pointerenter)': 'onPointerEnter()',\r\n '(pointerleave)': 'onPointerLeave()',\r\n '(focusin)': 'onFocusIn()',\r\n '(focusout)': 'onFocusOut()',\r\n },\r\n})\r\nexport class SkraTooltip {\r\n /** The tooltip text (bound as `[skraTooltip]=\"...\"`). */\r\n readonly skraTooltip = input.required<string>();\r\n /** Placement intent; `flip`/`shift` adjust at runtime. */\r\n readonly placement = input<SkraPlacement>('top');\r\n\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n private readonly vcr = inject(ViewContainerRef);\r\n private readonly renderer = inject(Renderer2);\r\n\r\n private readonly panelRef: ComponentRef<SkraTooltipPanel>;\r\n private readonly panelEl: HTMLElement;\r\n private readonly panelId: string;\r\n\r\n private positioner?: _PositionerHandle;\r\n private showTimer?: ReturnType<typeof setTimeout>;\r\n private hideTimer?: ReturnType<typeof setTimeout>;\r\n private docEscapeUnlisten?: () => void;\r\n\r\n private open = false;\r\n private hovered = false;\r\n private focused = false;\r\n private panelHovered = false;\r\n\r\n constructor() {\r\n // Eager, in-tree panel (ADR 0044 §3 rule 3): inherits the design-context cascade + O-8 bridge.\r\n this.panelRef = this.vcr.createComponent(SkraTooltipPanel);\r\n this.panelEl = this.panelRef.location.nativeElement as HTMLElement;\r\n this.panelId = this.panelRef.instance.panelId;\r\n\r\n // Describedby-only (ADR 033) — merge, never overwrite.\r\n this.wireDescribedBy();\r\n\r\n // Keep the panel text in sync with the input (effect runs after inputs are set).\r\n effect(() => this.panelRef.setInput('text', this.skraTooltip()));\r\n\r\n // Hoverable (WCAG 1.4.13): hovering the panel itself keeps the tooltip open.\r\n this.renderer.listen(this.panelEl, 'pointerenter', () => {\r\n this.panelHovered = true;\r\n clearTimeout(this.hideTimer);\r\n });\r\n this.renderer.listen(this.panelEl, 'pointerleave', () => {\r\n this.panelHovered = false;\r\n this.scheduleHide();\r\n });\r\n\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n this.warnIfTriggerNotFocusable();\r\n }\r\n\r\n inject(DestroyRef).onDestroy(() => this.teardown());\r\n }\r\n\r\n // ── Trigger events ──────────────────────────────────────────────────────────\r\n protected onPointerEnter(): void {\r\n this.hovered = true;\r\n this.scheduleShow();\r\n }\r\n\r\n protected onPointerLeave(): void {\r\n this.hovered = false;\r\n this.scheduleHide();\r\n }\r\n\r\n protected onFocusIn(): void {\r\n this.focused = true;\r\n // Keyboard users get it immediately (WCAG 2.1.1) — no show-delay.\r\n clearTimeout(this.showTimer);\r\n clearTimeout(this.hideTimer);\r\n this.show();\r\n }\r\n\r\n protected onFocusOut(): void {\r\n this.focused = false;\r\n this.scheduleHide();\r\n }\r\n\r\n // ── Show / hide state machine ─────────────────────────────────────────────────\r\n private scheduleShow(): void {\r\n clearTimeout(this.hideTimer);\r\n if (this.open) return;\r\n clearTimeout(this.showTimer);\r\n this.showTimer = setTimeout(\r\n () => this.show(),\r\n this.cssTimeMs('--skra-comp-tooltip-show-delay'),\r\n );\r\n }\r\n\r\n private scheduleHide(): void {\r\n clearTimeout(this.showTimer);\r\n clearTimeout(this.hideTimer);\r\n this.hideTimer = setTimeout(() => {\r\n // Only hide once nothing keeps it engaged (hoverable + focus coordination).\r\n if (!this.hovered && !this.focused && !this.panelHovered) this.hide();\r\n }, this.cssTimeMs('--skra-comp-tooltip-hide-delay'));\r\n }\r\n\r\n private show(): void {\r\n clearTimeout(this.showTimer);\r\n if (this.open) return;\r\n this.open = true;\r\n\r\n this.panelEl.showPopover?.();\r\n\r\n this.positioner?.destroy();\r\n this.positioner = _attachPositioner(\r\n this.host.nativeElement,\r\n this.panelEl,\r\n () => ({\r\n placement: this.placement(),\r\n offset: this.cssLenPx('--skra-comp-tooltip-offset'),\r\n viewportPadding: this.cssLenPx('--skra-comp-tooltip-viewport-padding'),\r\n }),\r\n );\r\n\r\n // Dismissible (WCAG 1.4.13): Escape hides without moving focus. Transient document listener\r\n // (active only while open) so Escape works even for a hover-triggered tooltip whose trigger is\r\n // not focused — `popover=\"manual\"` does not provide platform Escape.\r\n this.docEscapeUnlisten = this.renderer.listen(\r\n 'document',\r\n 'keydown',\r\n (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') this.hide();\r\n },\r\n );\r\n }\r\n\r\n private hide(): void {\r\n clearTimeout(this.showTimer);\r\n clearTimeout(this.hideTimer);\r\n if (!this.open) return;\r\n this.open = false;\r\n\r\n this.panelEl.hidePopover?.();\r\n this.positioner?.destroy();\r\n this.positioner = undefined;\r\n this.docEscapeUnlisten?.();\r\n this.docEscapeUnlisten = undefined;\r\n }\r\n\r\n // ── aria-describedby merge (ADR 033 / ADR 013-style wiring) ───────────────────\r\n private wireDescribedBy(): void {\r\n const tokens = this.describedByTokens();\r\n if (!tokens.includes(this.panelId)) tokens.push(this.panelId);\r\n this.renderer.setAttribute(\r\n this.host.nativeElement,\r\n 'aria-describedby',\r\n tokens.join(' '),\r\n );\r\n }\r\n\r\n private unwireDescribedBy(): void {\r\n const remaining = this.describedByTokens().filter(\r\n (t) => t !== this.panelId,\r\n );\r\n if (remaining.length) {\r\n this.renderer.setAttribute(\r\n this.host.nativeElement,\r\n 'aria-describedby',\r\n remaining.join(' '),\r\n );\r\n } else {\r\n this.renderer.removeAttribute(\r\n this.host.nativeElement,\r\n 'aria-describedby',\r\n );\r\n }\r\n }\r\n\r\n private describedByTokens(): string[] {\r\n return (this.host.nativeElement.getAttribute('aria-describedby') ?? '')\r\n .split(/\\s+/)\r\n .filter(Boolean);\r\n }\r\n\r\n // ── token resolution helpers (read computed comp tokens at runtime) ───────────\r\n private cssTimeMs(prop: string): number {\r\n const raw = getComputedStyle(this.panelEl).getPropertyValue(prop).trim();\r\n if (raw.endsWith('ms')) return parseFloat(raw);\r\n if (raw.endsWith('s')) return parseFloat(raw) * 1000;\r\n return parseFloat(raw) || 0;\r\n }\r\n\r\n private cssLenPx(prop: string): number {\r\n const raw = getComputedStyle(this.panelEl).getPropertyValue(prop).trim();\r\n if (raw.endsWith('px')) return parseFloat(raw);\r\n if (raw.endsWith('rem')) {\r\n const rootFontSize =\r\n parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\r\n return parseFloat(raw) * rootFontSize;\r\n }\r\n return parseFloat(raw) || 0;\r\n }\r\n\r\n private warnIfTriggerNotFocusable(): void {\r\n const el = this.host.nativeElement;\r\n if (!el.matches(FOCUSABLE_SELECTOR)) {\r\n console.warn(\r\n '[skraTooltip] host is not focusable — the tooltip is unreachable by keyboard ' +\r\n '(WCAG 2.1.1) and never shows on focus. Apply it to a button/link/form control, ' +\r\n 'or add tabindex to the trigger.',\r\n );\r\n }\r\n }\r\n\r\n private teardown(): void {\r\n clearTimeout(this.showTimer);\r\n clearTimeout(this.hideTimer);\r\n this.docEscapeUnlisten?.();\r\n this.positioner?.destroy();\r\n this.unwireDescribedBy();\r\n this.panelRef.destroy();\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skra-ui-tooltip.mjs","sources":["../../../../libs/ui/tooltip/src/lib/tooltip/tooltip-panel.ts","../../../../libs/ui/tooltip/src/lib/tooltip/tooltip.ts","../../../../libs/ui/tooltip/src/skra-ui-tooltip.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n input,\n} from '@angular/core';\n\nlet nextId = 0;\n\n/**\n * SkraTooltipPanel — the floating tooltip surface (ADR 0044 native top layer via the Popover API).\n *\n * INTERNAL: never placed by consumers in a template. `SkraTooltip` creates it programmatically with\n * `ViewContainerRef.createComponent` (Angular-idiomatic, in-tree → inherits the design-context cascade\n * + the O-8 Shadow-DOM bridge per ADR 0044 §3 rule 3) and drives `showPopover()`/`hidePopover()` on the\n * host element.\n *\n * `popover=\"manual\"` (NOT `auto`): a hover/focus tooltip's show/hide is Forge-owned, not click-toggle\n * light-dismiss. `role=\"tooltip\"` is the AT semantics; the trigger references this panel's `id` via\n * `aria-describedby` (wired by the directive). The 13-axis Universal Surface (ADR 025) + motion live in\n * `tooltip.scss`; geometry (`left`/`top` + `data-skra-placement`) is written by `SkraPositioner`.\n *\n * Full contract: adr/specs/component-tooltip-spec.md.\n */\n@Component({\n selector: 'skra-tooltip-panel',\n standalone: true,\n template: '{{ text() }}',\n styleUrl: './tooltip.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n role: 'tooltip',\n popover: 'manual',\n '[id]': 'panelId',\n },\n})\nexport class SkraTooltipPanel {\n /** Tooltip text; set by the directive and kept in sync. */\n readonly text = input<string>('');\n\n /** Stable unique id — target of the trigger's `aria-describedby`. */\n readonly panelId = `skra-tooltip-${nextId++}`;\n}\n","import {\n ComponentRef,\n DestroyRef,\n Directive,\n ElementRef,\n Renderer2,\n ViewContainerRef,\n effect,\n inject,\n input,\n} from '@angular/core';\n\nimport {\n _attachPositioner,\n type SkraPlacement,\n type _PositionerHandle,\n} from '@skra/ui/core';\nimport { SkraTooltipPanel } from './tooltip-panel';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/** A focusable trigger is required (WCAG 2.1.1); used only for the dev-mode nudge. */\nconst FOCUSABLE_SELECTOR =\n 'a[href],area[href],button,input,select,textarea,[tabindex],summary,' +\n '[contenteditable]:not([contenteditable=\"false\"])';\n\n/**\n * SkraTooltip — a supplementary, non-interactive text description on a focusable trigger, shown on\n * hover AND keyboard focus (ADR 0044 native top layer via the Popover API). Applied to the consumer's\n * own trigger: `<button skraButton [skraTooltip]=\"'Settings'\">`.\n *\n * The bulk of this directive is the WCAG 1.4.13 (Content on Hover or Focus) state machine — the\n * platform's `popover=\"manual\"` gives top-layer rendering but no dismiss/Escape, so Forge wires it:\n * - Dismissible: Escape hides WITHOUT moving focus.\n * - Hoverable: a hide grace-delay lets the pointer travel trigger→panel; hovering the panel keeps it.\n * - Persistent: no auto-timeout.\n * - Keyboard: focus shows immediately (no delay).\n *\n * Accessible-name contract (ADR 033, describedby-only): the tooltip is a DESCRIPTION, never the name —\n * it MERGES its panel id into the trigger's `aria-describedby` (preserving any existing value) and\n * removes only its own token on destroy. The trigger owns its own accessible name (an icon-only button\n * still needs its own `aria-label`). No `ariaLabel` input, no `aria-labelledby` wiring.\n *\n * The panel is created EAGERLY (hidden) so `aria-describedby` resolves and a screen reader announces\n * the description on first focus. Positioning is delegated to `SkraPositioner` (single JS path,\n * geometry-only inline; ADR 0044 §3 rules 4–5). Full contract: adr/specs/component-tooltip-spec.md.\n */\n@Directive({\n selector: '[skraTooltip]',\n standalone: true,\n exportAs: 'skraTooltip',\n host: {\n '(pointerenter)': 'onPointerEnter()',\n '(pointerleave)': 'onPointerLeave()',\n '(focusin)': 'onFocusIn()',\n '(focusout)': 'onFocusOut()',\n },\n})\nexport class SkraTooltip {\n /** The tooltip text (bound as `[skraTooltip]=\"...\"`). */\n readonly skraTooltip = input.required<string>();\n /** Placement intent; `flip`/`shift` adjust at runtime. */\n readonly placement = input<SkraPlacement>('top');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly vcr = inject(ViewContainerRef);\n private readonly renderer = inject(Renderer2);\n\n private readonly panelRef: ComponentRef<SkraTooltipPanel>;\n private readonly panelEl: HTMLElement;\n private readonly panelId: string;\n\n private positioner?: _PositionerHandle;\n private showTimer?: ReturnType<typeof setTimeout>;\n private hideTimer?: ReturnType<typeof setTimeout>;\n private docEscapeUnlisten?: () => void;\n\n private open = false;\n private hovered = false;\n private focused = false;\n private panelHovered = false;\n\n constructor() {\n // Eager, in-tree panel (ADR 0044 §3 rule 3): inherits the design-context cascade + O-8 bridge.\n this.panelRef = this.vcr.createComponent(SkraTooltipPanel);\n this.panelEl = this.panelRef.location.nativeElement as HTMLElement;\n this.panelId = this.panelRef.instance.panelId;\n\n // Describedby-only (ADR 033) — merge, never overwrite.\n this.wireDescribedBy();\n\n // Keep the panel text in sync with the input (effect runs after inputs are set).\n effect(() => this.panelRef.setInput('text', this.skraTooltip()));\n\n // Hoverable (WCAG 1.4.13): hovering the panel itself keeps the tooltip open.\n this.renderer.listen(this.panelEl, 'pointerenter', () => {\n this.panelHovered = true;\n clearTimeout(this.hideTimer);\n });\n this.renderer.listen(this.panelEl, 'pointerleave', () => {\n this.panelHovered = false;\n this.scheduleHide();\n });\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n this.warnIfTriggerNotFocusable();\n }\n\n inject(DestroyRef).onDestroy(() => this.teardown());\n }\n\n // ── Trigger events ──────────────────────────────────────────────────────────\n protected onPointerEnter(): void {\n this.hovered = true;\n this.scheduleShow();\n }\n\n protected onPointerLeave(): void {\n this.hovered = false;\n this.scheduleHide();\n }\n\n protected onFocusIn(): void {\n this.focused = true;\n // Keyboard users get it immediately (WCAG 2.1.1) — no show-delay.\n clearTimeout(this.showTimer);\n clearTimeout(this.hideTimer);\n this.show();\n }\n\n protected onFocusOut(): void {\n this.focused = false;\n this.scheduleHide();\n }\n\n // ── Show / hide state machine ─────────────────────────────────────────────────\n private scheduleShow(): void {\n clearTimeout(this.hideTimer);\n if (this.open) return;\n clearTimeout(this.showTimer);\n this.showTimer = setTimeout(\n () => this.show(),\n this.cssTimeMs('--skra-comp-tooltip-show-delay'),\n );\n }\n\n private scheduleHide(): void {\n clearTimeout(this.showTimer);\n clearTimeout(this.hideTimer);\n this.hideTimer = setTimeout(() => {\n // Only hide once nothing keeps it engaged (hoverable + focus coordination).\n if (!this.hovered && !this.focused && !this.panelHovered) this.hide();\n }, this.cssTimeMs('--skra-comp-tooltip-hide-delay'));\n }\n\n private show(): void {\n clearTimeout(this.showTimer);\n if (this.open) return;\n this.open = true;\n\n this.panelEl.showPopover?.();\n\n this.positioner?.destroy();\n this.positioner = _attachPositioner(\n this.host.nativeElement,\n this.panelEl,\n () => ({\n placement: this.placement(),\n offset: this.cssLenPx('--skra-comp-tooltip-offset'),\n viewportPadding: this.cssLenPx('--skra-comp-tooltip-viewport-padding'),\n }),\n );\n\n // Dismissible (WCAG 1.4.13): Escape hides without moving focus. Transient document listener\n // (active only while open) so Escape works even for a hover-triggered tooltip whose trigger is\n // not focused — `popover=\"manual\"` does not provide platform Escape.\n this.docEscapeUnlisten = this.renderer.listen(\n 'document',\n 'keydown',\n (event: KeyboardEvent) => {\n if (event.key === 'Escape') this.hide();\n },\n );\n }\n\n private hide(): void {\n clearTimeout(this.showTimer);\n clearTimeout(this.hideTimer);\n if (!this.open) return;\n this.open = false;\n\n this.panelEl.hidePopover?.();\n this.positioner?.destroy();\n this.positioner = undefined;\n this.docEscapeUnlisten?.();\n this.docEscapeUnlisten = undefined;\n }\n\n // ── aria-describedby merge (ADR 033 / ADR 013-style wiring) ───────────────────\n private wireDescribedBy(): void {\n const tokens = this.describedByTokens();\n if (!tokens.includes(this.panelId)) tokens.push(this.panelId);\n this.renderer.setAttribute(\n this.host.nativeElement,\n 'aria-describedby',\n tokens.join(' '),\n );\n }\n\n private unwireDescribedBy(): void {\n const remaining = this.describedByTokens().filter(\n (t) => t !== this.panelId,\n );\n if (remaining.length) {\n this.renderer.setAttribute(\n this.host.nativeElement,\n 'aria-describedby',\n remaining.join(' '),\n );\n } else {\n this.renderer.removeAttribute(\n this.host.nativeElement,\n 'aria-describedby',\n );\n }\n }\n\n private describedByTokens(): string[] {\n return (this.host.nativeElement.getAttribute('aria-describedby') ?? '')\n .split(/\\s+/)\n .filter(Boolean);\n }\n\n // ── token resolution helpers (read computed comp tokens at runtime) ───────────\n private cssTimeMs(prop: string): number {\n const raw = getComputedStyle(this.panelEl).getPropertyValue(prop).trim();\n if (raw.endsWith('ms')) return parseFloat(raw);\n if (raw.endsWith('s')) return parseFloat(raw) * 1000;\n return parseFloat(raw) || 0;\n }\n\n private cssLenPx(prop: string): number {\n const raw = getComputedStyle(this.panelEl).getPropertyValue(prop).trim();\n if (raw.endsWith('px')) return parseFloat(raw);\n if (raw.endsWith('rem')) {\n const rootFontSize =\n parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\n return parseFloat(raw) * rootFontSize;\n }\n return parseFloat(raw) || 0;\n }\n\n private warnIfTriggerNotFocusable(): void {\n const el = this.host.nativeElement;\n if (!el.matches(FOCUSABLE_SELECTOR)) {\n console.warn(\n '[skraTooltip] host is not focusable — the tooltip is unreachable by keyboard ' +\n '(WCAG 2.1.1) and never shows on focus. Apply it to a button/link/form control, ' +\n 'or add tabindex to the trigger.',\n );\n }\n }\n\n private teardown(): void {\n clearTimeout(this.showTimer);\n clearTimeout(this.hideTimer);\n this.docEscapeUnlisten?.();\n this.positioner?.destroy();\n this.unwireDescribedBy();\n this.panelRef.destroy();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-typography.mjs","sources":["../../../../libs/ui/typography/src/lib/typography/typography.ts","../../../../libs/ui/typography/src/skra-ui-typography.ts"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n input,\r\n} from '@angular/core';\r\n\r\nexport type TypographyRole =\r\n | 'display-large'\r\n | 'display-medium'\r\n | 'display-small'\r\n | 'headline-large'\r\n | 'headline-medium'\r\n | 'headline-small'\r\n | 'title-large'\r\n | 'title-medium'\r\n | 'title-small'\r\n | 'body-large'\r\n | 'body-medium'\r\n | 'body-small'\r\n | 'label-large'\r\n | 'label-medium'\r\n | 'label-small';\r\n\r\nexport type TypographySeverity = 'error' | 'warning' | 'success';\r\nexport type TypographyTruncate = 'single' | 'multi';\r\n\r\n@Component({\r\n selector: '[skraTypography]',\r\n standalone: true,\r\n imports: [],\r\n template: '<ng-content />',\r\n styleUrl: './typography.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // ADR 021 — CSP-safe state reflection. The zero-margin reset (ADR 022)\r\n // lives in typography.scss `:host` — host-metadata bare keys would render\r\n // as junk attributes, not styles.\r\n '[attr.data-skra-typo-role]': 'role()',\r\n '[attr.data-skra-severity]': 'severity()',\r\n '[attr.data-skra-truncate]': 'truncate()',\r\n // Line-clamp count — reflected as an enumerated data-attribute, consumed by\r\n // static `-webkit-line-clamp` rules in typography.scss (buckets 2–6). NOT a\r\n // `[style.--var]` binding (ADR 021 iron boundary) — same enumerated-bucket\r\n // approach Grid/Stack use to keep CSP-safe. Values outside 2–6 fall back to\r\n // the base 2-line rule.\r\n '[attr.data-skra-line-clamp]':\r\n 'truncate() === \"multi\" ? lineClamp() : null',\r\n },\r\n})\r\nexport class SkraTypography {\r\n readonly role = input<TypographyRole>('body-medium', {\r\n alias: 'skraTypography',\r\n });\r\n readonly severity = input<TypographySeverity | null>(null);\r\n readonly truncate = input<TypographyTruncate | null>(null);\r\n readonly lineClamp = input<number>(2);\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;MAmDa,cAAc,CAAA;IAChB,IAAI,GAAG,KAAK,CAAiB,aAAa,4EACjD,KAAK,EAAE,gBAAgB,EAAA,CACvB;IACO,QAAQ,GAAG,KAAK,CAA4B,IAAI;iFAAC;IACjD,QAAQ,GAAG,KAAK,CAA4B,IAAI;iFAAC;IACjD,SAAS,GAAG,KAAK,CAAS,CAAC;kFAAC;uGAN1B,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAd,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,cAAc,6zBApBf,gBAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,23TAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAoBf,cAAc,EAAA,UAAA,EAAA,CAAA;kBAxB1B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,kBAAkB,EAAA,UAAA,EAChB,IAAI,EAAA,OAAA,EACP,EAAE,YACD,gBAAgB,EAAA,eAAA,EAET,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;;;AAIJ,wBAAA,4BAA4B,EAAE,QAAQ;AACtC,wBAAA,2BAA2B,EAAE,YAAY;AACzC,wBAAA,2BAA2B,EAAE,YAAY;;;;;;AAMzC,wBAAA,6BAA6B,EAC3B,6CAA6C;AAChD,qBAAA,EAAA,MAAA,EAAA,CAAA,23TAAA,CAAA,EAAA;;;ACjDH;;AAEG;;;;"}
1
+ {"version":3,"file":"skra-ui-typography.mjs","sources":["../../../../libs/ui/typography/src/lib/typography/typography.ts","../../../../libs/ui/typography/src/skra-ui-typography.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n input,\n} from '@angular/core';\n\nexport type TypographyRole =\n | 'display-large'\n | 'display-medium'\n | 'display-small'\n | 'headline-large'\n | 'headline-medium'\n | 'headline-small'\n | 'title-large'\n | 'title-medium'\n | 'title-small'\n | 'body-large'\n | 'body-medium'\n | 'body-small'\n | 'label-large'\n | 'label-medium'\n | 'label-small';\n\nexport type TypographySeverity = 'error' | 'warning' | 'success';\nexport type TypographyTruncate = 'single' | 'multi';\n\n@Component({\n selector: '[skraTypography]',\n standalone: true,\n imports: [],\n template: '<ng-content />',\n styleUrl: './typography.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n // ADR 021 — CSP-safe state reflection. The zero-margin reset (ADR 022)\n // lives in typography.scss `:host` — host-metadata bare keys would render\n // as junk attributes, not styles.\n '[attr.data-skra-typo-role]': 'role()',\n '[attr.data-skra-severity]': 'severity()',\n '[attr.data-skra-truncate]': 'truncate()',\n // Line-clamp count — reflected as an enumerated data-attribute, consumed by\n // static `-webkit-line-clamp` rules in typography.scss (buckets 2–6). NOT a\n // `[style.--var]` binding (ADR 021 iron boundary) — same enumerated-bucket\n // approach Grid/Stack use to keep CSP-safe. Values outside 2–6 fall back to\n // the base 2-line rule.\n '[attr.data-skra-line-clamp]':\n 'truncate() === \"multi\" ? lineClamp() : null',\n },\n})\nexport class SkraTypography {\n readonly role = input<TypographyRole>('body-medium', {\n alias: 'skraTypography',\n });\n readonly severity = input<TypographySeverity | null>(null);\n readonly truncate = input<TypographyTruncate | null>(null);\n readonly lineClamp = input<number>(2);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;MAmDa,cAAc,CAAA;IAChB,IAAI,GAAG,KAAK,CAAiB,aAAa,4EACjD,KAAK,EAAE,gBAAgB,EAAA,CACvB;IACO,QAAQ,GAAG,KAAK,CAA4B,IAAI;iFAAC;IACjD,QAAQ,GAAG,KAAK,CAA4B,IAAI;iFAAC;IACjD,SAAS,GAAG,KAAK,CAAS,CAAC;kFAAC;uGAN1B,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAd,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,cAAc,6zBApBf,gBAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,23TAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAoBf,cAAc,EAAA,UAAA,EAAA,CAAA;kBAxB1B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,kBAAkB,EAAA,UAAA,EAChB,IAAI,EAAA,OAAA,EACP,EAAE,YACD,gBAAgB,EAAA,eAAA,EAET,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;;;AAIJ,wBAAA,4BAA4B,EAAE,QAAQ;AACtC,wBAAA,2BAA2B,EAAE,YAAY;AACzC,wBAAA,2BAA2B,EAAE,YAAY;;;;;;AAMzC,wBAAA,6BAA6B,EAC3B,6CAA6C;AAChD,qBAAA,EAAA,MAAA,EAAA,CAAA,23TAAA,CAAA,EAAA;;;ACjDH;;AAEG;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skra/ui",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "license": "Apache-2.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -10,7 +10,7 @@
10
10
  "@angular/core": ">=22.0.0 <23.0.0",
11
11
  "@angular/common": ">=22.0.0 <23.0.0",
12
12
  "@angular/cdk": ">=22.0.0 <23.0.0",
13
- "@skra/tokens": "^0.4.0"
13
+ "@skra/tokens": "^0.5.0"
14
14
  },
15
15
  "dependencies": {
16
16
  "@floating-ui/dom": "^1.7.6",
@@ -172,4 +172,4 @@
172
172
  }
173
173
  },
174
174
  "type": "module"
175
- }
175
+ }