@skra/ui 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE +201 -201
  2. package/NOTICE +7 -7
  3. package/README.md +39 -39
  4. package/consumer-guide/README.md +84 -84
  5. package/consumer-guide/forms-and-binding.md +19 -3
  6. package/consumer-guide/layout.md +19 -0
  7. package/consumer-guide/overlays.md +100 -100
  8. package/consumer-guide/setup-and-gotchas.md +165 -103
  9. package/consumer-guide/theming-and-encapsulation.md +129 -115
  10. package/fesm2022/skra-ui-accordion.mjs +61 -43
  11. package/fesm2022/skra-ui-accordion.mjs.map +1 -1
  12. package/fesm2022/skra-ui-alert.mjs +26 -18
  13. package/fesm2022/skra-ui-alert.mjs.map +1 -1
  14. package/fesm2022/skra-ui-avatar.mjs +12 -8
  15. package/fesm2022/skra-ui-avatar.mjs.map +1 -1
  16. package/fesm2022/skra-ui-badge.mjs +19 -13
  17. package/fesm2022/skra-ui-badge.mjs.map +1 -1
  18. package/fesm2022/skra-ui-button.mjs +28 -19
  19. package/fesm2022/skra-ui-button.mjs.map +1 -1
  20. package/fesm2022/skra-ui-checkbox.mjs +3 -3
  21. package/fesm2022/skra-ui-checkbox.mjs.map +1 -1
  22. package/fesm2022/skra-ui-chip.mjs +15 -11
  23. package/fesm2022/skra-ui-chip.mjs.map +1 -1
  24. package/fesm2022/skra-ui-combobox.mjs +135 -130
  25. package/fesm2022/skra-ui-combobox.mjs.map +1 -1
  26. package/fesm2022/skra-ui-core.mjs +95 -73
  27. package/fesm2022/skra-ui-core.mjs.map +1 -1
  28. package/fesm2022/skra-ui-counter.mjs +9 -6
  29. package/fesm2022/skra-ui-counter.mjs.map +1 -1
  30. package/fesm2022/skra-ui-datepicker.mjs +334 -307
  31. package/fesm2022/skra-ui-datepicker.mjs.map +1 -1
  32. package/fesm2022/skra-ui-dialog.mjs +5 -4
  33. package/fesm2022/skra-ui-dialog.mjs.map +1 -1
  34. package/fesm2022/skra-ui-field.mjs +65 -43
  35. package/fesm2022/skra-ui-field.mjs.map +1 -1
  36. package/fesm2022/skra-ui-icon.mjs +5 -4
  37. package/fesm2022/skra-ui-icon.mjs.map +1 -1
  38. package/fesm2022/skra-ui-input.mjs +53 -12
  39. package/fesm2022/skra-ui-input.mjs.map +1 -1
  40. package/fesm2022/skra-ui-kbd.mjs +3 -3
  41. package/fesm2022/skra-ui-kbd.mjs.map +1 -1
  42. package/fesm2022/skra-ui-layout.mjs +33 -21
  43. package/fesm2022/skra-ui-layout.mjs.map +1 -1
  44. package/fesm2022/skra-ui-link.mjs +3 -3
  45. package/fesm2022/skra-ui-link.mjs.map +1 -1
  46. package/fesm2022/skra-ui-loading-indicator.mjs +3 -3
  47. package/fesm2022/skra-ui-loading-indicator.mjs.map +1 -1
  48. package/fesm2022/skra-ui-menu.mjs +8 -7
  49. package/fesm2022/skra-ui-menu.mjs.map +1 -1
  50. package/fesm2022/skra-ui-multi-select.mjs +102 -98
  51. package/fesm2022/skra-ui-multi-select.mjs.map +1 -1
  52. package/fesm2022/skra-ui-native-select.mjs +35 -17
  53. package/fesm2022/skra-ui-native-select.mjs.map +1 -1
  54. package/fesm2022/skra-ui-popover.mjs +5 -4
  55. package/fesm2022/skra-ui-popover.mjs.map +1 -1
  56. package/fesm2022/skra-ui-progress.mjs +7 -5
  57. package/fesm2022/skra-ui-progress.mjs.map +1 -1
  58. package/fesm2022/skra-ui-radio.mjs +3 -3
  59. package/fesm2022/skra-ui-radio.mjs.map +1 -1
  60. package/fesm2022/skra-ui-rating-display.mjs +14 -9
  61. package/fesm2022/skra-ui-rating-display.mjs.map +1 -1
  62. package/fesm2022/skra-ui-select.mjs +98 -95
  63. package/fesm2022/skra-ui-select.mjs.map +1 -1
  64. package/fesm2022/skra-ui-skeleton.mjs +16 -13
  65. package/fesm2022/skra-ui-skeleton.mjs.map +1 -1
  66. package/fesm2022/skra-ui-star-rating.mjs +18 -11
  67. package/fesm2022/skra-ui-star-rating.mjs.map +1 -1
  68. package/fesm2022/skra-ui-status-dot.mjs +7 -5
  69. package/fesm2022/skra-ui-status-dot.mjs.map +1 -1
  70. package/fesm2022/skra-ui-switch.mjs +3 -3
  71. package/fesm2022/skra-ui-switch.mjs.map +1 -1
  72. package/fesm2022/skra-ui-tabs.mjs +43 -29
  73. package/fesm2022/skra-ui-tabs.mjs.map +1 -1
  74. package/fesm2022/skra-ui-textarea.mjs +41 -15
  75. package/fesm2022/skra-ui-textarea.mjs.map +1 -1
  76. package/fesm2022/skra-ui-toast.mjs +35 -23
  77. package/fesm2022/skra-ui-toast.mjs.map +1 -1
  78. package/fesm2022/skra-ui-tooltip.mjs +12 -9
  79. package/fesm2022/skra-ui-tooltip.mjs.map +1 -1
  80. package/fesm2022/skra-ui-typography.mjs +9 -6
  81. package/fesm2022/skra-ui-typography.mjs.map +1 -1
  82. package/package.json +6 -6
  83. package/types/skra-ui-field.d.ts +3 -3
  84. package/types/skra-ui-field.d.ts.map +1 -1
  85. package/types/skra-ui-input.d.ts +24 -1
  86. package/types/skra-ui-input.d.ts.map +1 -1
  87. package/types/skra-ui-native-select.d.ts +9 -1
  88. package/types/skra-ui-native-select.d.ts.map +1 -1
  89. package/types/skra-ui-textarea.d.ts +10 -1
  90. package/types/skra-ui-textarea.d.ts.map +1 -1
@@ -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';\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()) {\n<span class=\"skra-toast-icon\">\n <ng-content select=\"[skra-toast-icon]\"></ng-content>\n</span>\n}\n\n<div class=\"skra-toast-content\" #content>\n <ng-content></ng-content>\n</div>\n\n@if (dismissible()) {\n<button type=\"button\" class=\"skra-toast-dismiss\" (click)=\"onDismiss()\">\n <span class=\"skra-toast-dismiss-glyph\" aria-hidden=\"true\">&times;</span>\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\n</button>\n}\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>\n <ng-content></ng-content>\n</div>\n\n<!--\n ADR 0052 §7 — two PERSISTENT, role-only live announcers, held in normal flow (NOT inside the\n popover, so they are pre-armed and announce regardless of the stack's shown/paint state).\n role=\"status\" carries aria-live=polite + aria-atomic; role=\"alert\" carries assertive + atomic\n (implicitly — no explicit aria-live, ADR 0052 rule 2). Each holds one message at a time.\n-->\n<div class=\"skra-sr-only\" role=\"status\">{{ politeMsg() }}</div>\n<div class=\"skra-sr-only\" role=\"alert\">{{ assertiveMsg() }}</div>\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';\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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"}
@@ -20,13 +20,14 @@ let nextId = 0;
20
20
  */
21
21
  class SkraTooltipPanel {
22
22
  /** Tooltip text; set by the directive and kept in sync. */
23
- text = input('', ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
23
+ text = input('', /* @ts-ignore */
24
+ ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
24
25
  /** Stable unique id — target of the trigger's `aria-describedby`. */
25
26
  panelId = `skra-tooltip-${nextId++}`;
26
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTooltipPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
27
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.7", type: SkraTooltipPanel, isStandalone: true, selector: "skra-tooltip-panel", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tooltip", "popover": "manual" }, properties: { "id": "panelId" } }, ngImport: i0, template: '{{ text() }}', isInline: true, styles: ["@charset \"UTF-8\";:host{position:fixed;margin:0;inset:auto;box-sizing:border-box;background:var(--skra-comp-tooltip-background);color:var(--skra-comp-tooltip-foreground);border-color:var(--skra-comp-tooltip-border-color);border-width:var(--skra-comp-tooltip-border-width);border-style:var(--skra-comp-tooltip-border-style);border-radius:var(--skra-comp-tooltip-radius);padding-block:var(--skra-comp-tooltip-padding-block);padding-inline:var(--skra-comp-tooltip-padding-inline);box-shadow:var(--skra-comp-tooltip-shadow);inline-size:max-content;max-inline-size:var(--skra-comp-tooltip-max-inline-size);font-family:var(--skra-sys-typography-role-body-small-font-family);font-size:var(--skra-sys-typography-role-body-small-font-size);font-weight:var(--skra-sys-typography-role-body-small-font-weight);line-height:var(--skra-sys-typography-role-body-small-line-height);letter-spacing:var(--skra-sys-typography-role-body-small-letter-spacing);opacity:0;transition:opacity var(--skra-comp-tooltip-motion-duration) var(--skra-comp-tooltip-motion-easing),display var(--skra-comp-tooltip-motion-duration) allow-discrete,overlay var(--skra-comp-tooltip-motion-duration) allow-discrete}:host(:popover-open){display:block;opacity:1}@starting-style{:host(:popover-open){opacity:0}}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
27
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTooltipPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
28
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.1", type: SkraTooltipPanel, isStandalone: true, selector: "skra-tooltip-panel", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tooltip", "popover": "manual" }, properties: { "id": "panelId" } }, ngImport: i0, template: '{{ text() }}', isInline: true, styles: ["@charset \"UTF-8\";:host{position:fixed;margin:0;inset:auto;box-sizing:border-box;background:var(--skra-comp-tooltip-background);color:var(--skra-comp-tooltip-foreground);border-color:var(--skra-comp-tooltip-border-color);border-width:var(--skra-comp-tooltip-border-width);border-style:var(--skra-comp-tooltip-border-style);border-radius:var(--skra-comp-tooltip-radius);padding-block:var(--skra-comp-tooltip-padding-block);padding-inline:var(--skra-comp-tooltip-padding-inline);box-shadow:var(--skra-comp-tooltip-shadow);inline-size:max-content;max-inline-size:var(--skra-comp-tooltip-max-inline-size);font-family:var(--skra-sys-typography-role-body-small-font-family);font-size:var(--skra-sys-typography-role-body-small-font-size);font-weight:var(--skra-sys-typography-role-body-small-font-weight);line-height:var(--skra-sys-typography-role-body-small-line-height);letter-spacing:var(--skra-sys-typography-role-body-small-letter-spacing);opacity:0;transition:opacity var(--skra-comp-tooltip-motion-duration) var(--skra-comp-tooltip-motion-easing),display var(--skra-comp-tooltip-motion-duration) allow-discrete,overlay var(--skra-comp-tooltip-motion-duration) allow-discrete}:host(:popover-open){display:block;opacity:1}@starting-style{:host(:popover-open){opacity:0}}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
28
29
  }
29
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTooltipPanel, decorators: [{
30
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTooltipPanel, decorators: [{
30
31
  type: Component,
31
32
  args: [{ selector: 'skra-tooltip-panel', standalone: true, template: '{{ text() }}', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
32
33
  role: 'tooltip',
@@ -61,9 +62,11 @@ const FOCUSABLE_SELECTOR = 'a[href],area[href],button,input,select,textarea,[tab
61
62
  */
62
63
  class SkraTooltip {
63
64
  /** The tooltip text (bound as `[skraTooltip]="..."`). */
64
- skraTooltip = input.required(...(ngDevMode ? [{ debugName: "skraTooltip" }] : /* istanbul ignore next */ []));
65
+ skraTooltip = input.required(/* @ts-ignore */
66
+ ...(ngDevMode ? [{ debugName: "skraTooltip" }] : /* istanbul ignore next */ []));
65
67
  /** Placement intent; `flip`/`shift` adjust at runtime. */
66
- placement = input('top', ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
68
+ placement = input('top', /* @ts-ignore */
69
+ ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
67
70
  host = inject(ElementRef);
68
71
  vcr = inject(ViewContainerRef);
69
72
  renderer = inject(Renderer2);
@@ -226,10 +229,10 @@ class SkraTooltip {
226
229
  this.unwireDescribedBy();
227
230
  this.panelRef.destroy();
228
231
  }
229
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive });
230
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.7", type: SkraTooltip, isStandalone: true, selector: "[skraTooltip]", inputs: { skraTooltip: { classPropertyName: "skraTooltip", publicName: "skraTooltip", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointerenter": "onPointerEnter()", "pointerleave": "onPointerLeave()", "focusin": "onFocusIn()", "focusout": "onFocusOut()" } }, exportAs: ["skraTooltip"], ngImport: i0 });
232
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive });
233
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.1", type: SkraTooltip, isStandalone: true, selector: "[skraTooltip]", inputs: { skraTooltip: { classPropertyName: "skraTooltip", publicName: "skraTooltip", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointerenter": "onPointerEnter()", "pointerleave": "onPointerLeave()", "focusin": "onFocusIn()", "focusout": "onFocusOut()" } }, exportAs: ["skraTooltip"], ngImport: i0 });
231
234
  }
232
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTooltip, decorators: [{
235
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTooltip, decorators: [{
233
236
  type: Directive,
234
237
  args: [{
235
238
  selector: '[skraTooltip]',
@@ -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 {\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
+ {"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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"}
@@ -3,13 +3,16 @@ import { input, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@a
3
3
 
4
4
  class SkraTypography {
5
5
  role = input('body-medium', { ...(ngDevMode ? { debugName: "role" } : /* istanbul ignore next */ {}), alias: 'skraTypography' });
6
- severity = input(null, ...(ngDevMode ? [{ debugName: "severity" }] : /* istanbul ignore next */ []));
7
- truncate = input(null, ...(ngDevMode ? [{ debugName: "truncate" }] : /* istanbul ignore next */ []));
8
- lineClamp = input(2, ...(ngDevMode ? [{ debugName: "lineClamp" }] : /* istanbul ignore next */ []));
9
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTypography, deps: [], target: i0.ɵɵFactoryTarget.Component });
10
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.7", type: SkraTypography, isStandalone: true, selector: "[skraTypography]", inputs: { role: { classPropertyName: "role", publicName: "skraTypography", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, truncate: { classPropertyName: "truncate", publicName: "truncate", isSignal: true, isRequired: false, transformFunction: null }, lineClamp: { classPropertyName: "lineClamp", publicName: "lineClamp", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-skra-typo-role": "role()", "attr.data-skra-severity": "severity()", "attr.data-skra-truncate": "truncate()", "attr.data-skra-line-clamp": "truncate() === \"multi\" ? lineClamp() : null" } }, ngImport: i0, template: '<ng-content />', isInline: true, styles: ["@charset \"UTF-8\";:host{display:block;margin:0;font-family:var(--skra-comp-typography-font-family);font-size:var(--skra-comp-typography-font-size);font-weight:var(--skra-comp-typography-font-weight);line-height:var(--skra-comp-typography-line-height);letter-spacing:var(--skra-comp-typography-letter-spacing);color:var(--skra-comp-typography-foreground)}:host([data-skra-typo-role=display-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-large-foreground )}:host([data-skra-typo-role=display-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-medium-foreground )}:host([data-skra-typo-role=display-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-small-foreground )}:host([data-skra-typo-role=headline-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-large-foreground )}:host([data-skra-typo-role=headline-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-medium-foreground )}:host([data-skra-typo-role=headline-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-small-foreground )}:host([data-skra-typo-role=title-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-large-foreground )}:host([data-skra-typo-role=title-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-medium-foreground )}:host([data-skra-typo-role=title-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-small-foreground )}:host([data-skra-typo-role=body-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-large-foreground )}:host([data-skra-typo-role=body-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-medium-foreground )}:host([data-skra-typo-role=body-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-small-foreground )}:host([data-skra-typo-role=label-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-large-foreground )}:host([data-skra-typo-role=label-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-medium-foreground )}:host([data-skra-typo-role=label-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-small-foreground )}:host([data-skra-severity=error]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-error )}:host([data-skra-severity=warning]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-warning )}:host([data-skra-severity=success]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-success )}:host([data-skra-truncate=single]){display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host([data-skra-truncate=multi]){display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}:host([data-skra-truncate=multi][data-skra-line-clamp=\"3\"]){-webkit-line-clamp:3}:host([data-skra-truncate=multi][data-skra-line-clamp=\"4\"]){-webkit-line-clamp:4}:host([data-skra-truncate=multi][data-skra-line-clamp=\"5\"]){-webkit-line-clamp:5}:host([data-skra-truncate=multi][data-skra-line-clamp=\"6\"]){-webkit-line-clamp:6}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6
+ severity = input(null, /* @ts-ignore */
7
+ ...(ngDevMode ? [{ debugName: "severity" }] : /* istanbul ignore next */ []));
8
+ truncate = input(null, /* @ts-ignore */
9
+ ...(ngDevMode ? [{ debugName: "truncate" }] : /* istanbul ignore next */ []));
10
+ lineClamp = input(2, /* @ts-ignore */
11
+ ...(ngDevMode ? [{ debugName: "lineClamp" }] : /* istanbul ignore next */ []));
12
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTypography, deps: [], target: i0.ɵɵFactoryTarget.Component });
13
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.1", type: SkraTypography, isStandalone: true, selector: "[skraTypography]", inputs: { role: { classPropertyName: "role", publicName: "skraTypography", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, truncate: { classPropertyName: "truncate", publicName: "truncate", isSignal: true, isRequired: false, transformFunction: null }, lineClamp: { classPropertyName: "lineClamp", publicName: "lineClamp", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-skra-typo-role": "role()", "attr.data-skra-severity": "severity()", "attr.data-skra-truncate": "truncate()", "attr.data-skra-line-clamp": "truncate() === \"multi\" ? lineClamp() : null" } }, ngImport: i0, template: '<ng-content />', isInline: true, styles: ["@charset \"UTF-8\";:host{display:block;margin:0;font-family:var(--skra-comp-typography-font-family);font-size:var(--skra-comp-typography-font-size);font-weight:var(--skra-comp-typography-font-weight);line-height:var(--skra-comp-typography-line-height);letter-spacing:var(--skra-comp-typography-letter-spacing);color:var(--skra-comp-typography-foreground)}:host([data-skra-typo-role=display-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-large-foreground )}:host([data-skra-typo-role=display-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-medium-foreground )}:host([data-skra-typo-role=display-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-small-foreground )}:host([data-skra-typo-role=headline-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-large-foreground )}:host([data-skra-typo-role=headline-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-medium-foreground )}:host([data-skra-typo-role=headline-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-small-foreground )}:host([data-skra-typo-role=title-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-large-foreground )}:host([data-skra-typo-role=title-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-medium-foreground )}:host([data-skra-typo-role=title-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-small-foreground )}:host([data-skra-typo-role=body-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-large-foreground )}:host([data-skra-typo-role=body-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-medium-foreground )}:host([data-skra-typo-role=body-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-small-foreground )}:host([data-skra-typo-role=label-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-large-foreground )}:host([data-skra-typo-role=label-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-medium-foreground )}:host([data-skra-typo-role=label-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-small-foreground )}:host([data-skra-severity=error]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-error )}:host([data-skra-severity=warning]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-warning )}:host([data-skra-severity=success]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-success )}:host([data-skra-truncate=single]){display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host([data-skra-truncate=multi]){display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}:host([data-skra-truncate=multi][data-skra-line-clamp=\"3\"]){-webkit-line-clamp:3}:host([data-skra-truncate=multi][data-skra-line-clamp=\"4\"]){-webkit-line-clamp:4}:host([data-skra-truncate=multi][data-skra-line-clamp=\"5\"]){-webkit-line-clamp:5}:host([data-skra-truncate=multi][data-skra-line-clamp=\"6\"]){-webkit-line-clamp:6}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11
14
  }
12
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTypography, decorators: [{
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTypography, decorators: [{
13
16
  type: Component,
14
17
  args: [{ selector: '[skraTypography]', standalone: true, imports: [], template: '<ng-content />', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
15
18
  // ADR 021 — CSP-safe state reflection. The zero-margin reset (ADR 022)
@@ -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 {\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;AACO,IAAA,QAAQ,GAAG,KAAK,CAA4B,IAAI,+EAAC;AACjD,IAAA,QAAQ,GAAG,KAAK,CAA4B,IAAI,+EAAC;AACjD,IAAA,SAAS,GAAG,KAAK,CAAS,CAAC,gFAAC;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 {\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;;;;"}
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@skra/ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "license": "Apache-2.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
8
  "sideEffects": false,
9
9
  "peerDependencies": {
10
- "@angular/core": "~21.2.0",
11
- "@angular/common": "~21.2.0",
12
- "@angular/cdk": "~21.2.0",
13
- "@skra/tokens": "^0.2.0"
10
+ "@angular/core": ">=22.0.0 <23.0.0",
11
+ "@angular/common": ">=22.0.0 <23.0.0",
12
+ "@angular/cdk": ">=22.0.0 <23.0.0",
13
+ "@skra/tokens": "^0.3.1"
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
+ }
@@ -61,7 +61,7 @@ declare class SkraField implements OnInit {
61
61
  * moved here from the slice).
62
62
  */
63
63
  declare class SkraLabel {
64
- readonly context: SkraFieldContext;
64
+ readonly context: SkraFieldContext | null;
65
65
  static ɵfac: i0.ɵɵFactoryDeclaration<SkraLabel, never>;
66
66
  static ɵcmp: i0.ɵɵComponentDeclaration<SkraLabel, "label[skraLabelFor]", never, {}, {}, never, ["*"], true, never>;
67
67
  }
@@ -71,7 +71,7 @@ declare class SkraLabel {
71
71
  * Auto-receives ID from SkraFieldContext so aria-describedby on input works automatically.
72
72
  */
73
73
  declare class SkraHint {
74
- readonly context: SkraFieldContext;
74
+ readonly context: SkraFieldContext | null;
75
75
  static ɵfac: i0.ɵɵFactoryDeclaration<SkraHint, never>;
76
76
  static ɵcmp: i0.ɵɵComponentDeclaration<SkraHint, "skra-hint", never, {}, {}, never, ["*"], true, never>;
77
77
  }
@@ -108,7 +108,7 @@ declare class SkraHint {
108
108
  * loaded two responsibilities into a single primitive.
109
109
  */
110
110
  declare class SkraError {
111
- readonly context: SkraFieldContext;
111
+ readonly context: SkraFieldContext | null;
112
112
  static ɵfac: i0.ɵɵFactoryDeclaration<SkraError, never>;
113
113
  static ɵcmp: i0.ɵɵComponentDeclaration<SkraError, "skra-error", never, {}, {}, never, ["*"], true, never>;
114
114
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-field.d.ts","sources":["../../../../libs/ui/field/src/lib/id-generator/id-generator.service.ts","../../../../libs/ui/field/src/lib/field-context/field-context.ts","../../../../libs/ui/field/src/lib/field/field.component.ts","../../../../libs/ui/field/src/lib/label/label.ts","../../../../libs/ui/field/src/lib/hint/hint.component.ts","../../../../libs/ui/field/src/lib/error/error.component.ts","../../../../libs/ui/field/src/lib/fieldset/fieldset.ts","../../../../libs/ui/field/src/lib/fieldset/legend.ts"],"mappings":";;;AAEA;;;AAGG;AACH,cACa,kBAAkB;;AAG7B;yCAHW,kBAAkB;6CAAlB,kBAAkB;AAM9B;;ACXD;;;;AAIG;AACH,cACa,gBAAgB;sBACXA,EAAA,CAAA,cAAA;uBACCA,EAAA,CAAA,cAAA;yBACEA,EAAA,CAAA,cAAA;yBACAA,EAAA,CAAA,cAAA;yBACAA,EAAA,CAAA,cAAA;qBAGJA,EAAA,CAAA,MAAA;sBACCA,EAAA,CAAA,MAAA;sBAQAA,EAAA,CAAA,MAAA;6BAOOA,EAAA,CAAA,MAAA;yCAxBZ,gBAAgB;6CAAhB,gBAAgB;AA2B5B;;ACtBD,cA0Ba,SAAU,YAAW,MAAM;AACtC;sBACgB,gBAAA;sBAEAA,EAAA,CAAA,WAAA;uBACCA,EAAA,CAAA,wBAAA;uBACAA,EAAA,CAAA,wBAAA;uBACAA,EAAA,CAAA,wBAAA;uBACAA,EAAA,CAAA,wBAAA;;AAkBjB;yCA1BW,SAAS;2CAAT,SAAS;AA6BrB;;AC5DD;;;;;;;;;;;;;;AAcG;AACH,cAwBa,SAAS;sBACJ,gBAAA;yCADL,SAAS;2CAAT,SAAS;AAErB;;ACzCD;;;AAGG;AACH,cAca,QAAQ;sBACH,gBAAA;yCADL,QAAQ;2CAAR,QAAQ;AAEpB;;ACpBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BG;AACH,cAiBa,SAAS;sBACJ,gBAAA;yCADL,SAAS;2CAAT,SAAS;AAErB;;AClDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCG;AACH,cAca,YAAY;uBACNA,EAAA,CAAA,wBAAA;yCADN,YAAY;2CAAZ,YAAY;AAExB;;ACpDD;;;;;;;;;;;;;;;;;;AAkBG;AACH,cASa,UAAU;yCAAV,UAAU;2CAAV,UAAU;AAAG;;;;","names":["_angular_core"]}
1
+ {"version":3,"file":"skra-ui-field.d.ts","sources":["../../../../libs/ui/field/src/lib/id-generator/id-generator.service.ts","../../../../libs/ui/field/src/lib/field-context/field-context.ts","../../../../libs/ui/field/src/lib/field/field.component.ts","../../../../libs/ui/field/src/lib/label/label.ts","../../../../libs/ui/field/src/lib/hint/hint.component.ts","../../../../libs/ui/field/src/lib/error/error.component.ts","../../../../libs/ui/field/src/lib/fieldset/fieldset.ts","../../../../libs/ui/field/src/lib/fieldset/legend.ts"],"mappings":";;;AAEA;;;AAGG;AACH,cACa,kBAAkB;;AAG7B;yCAHW,kBAAkB;6CAAlB,kBAAkB;AAM9B;;ACXD;;;;AAIG;AACH,cACa,gBAAgB;sBACXA,EAAA,CAAA,cAAA;uBACCA,EAAA,CAAA,cAAA;yBACEA,EAAA,CAAA,cAAA;yBACAA,EAAA,CAAA,cAAA;yBACAA,EAAA,CAAA,cAAA;qBAGJA,EAAA,CAAA,MAAA;sBACCA,EAAA,CAAA,MAAA;sBAQAA,EAAA,CAAA,MAAA;6BAOOA,EAAA,CAAA,MAAA;yCAxBZ,gBAAgB;6CAAhB,gBAAgB;AA2B5B;;ACtBD,cA0Ba,SAAU,YAAW,MAAM;AACtC;sBACgB,gBAAA;sBAEAA,EAAA,CAAA,WAAA;uBACCA,EAAA,CAAA,wBAAA;uBACAA,EAAA,CAAA,wBAAA;uBACAA,EAAA,CAAA,wBAAA;uBACAA,EAAA,CAAA,wBAAA;;AAkBjB;yCA1BW,SAAS;2CAAT,SAAS;AA6BrB;;AC5DD;;;;;;;;;;;;;;AAcG;AACH,cA0Ba,SAAS;sBAIJ,gBAAA;yCAJL,SAAS;2CAAT,SAAS;AAKrB;;AC9CD;;;AAGG;AACH,cAca,QAAQ;sBAGH,gBAAA;yCAHL,QAAQ;2CAAR,QAAQ;AAIpB;;ACtBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BG;AACH,cAiBa,SAAS;sBAMJ,gBAAA;yCANL,SAAS;2CAAT,SAAS;AAOrB;;ACvDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCG;AACH,cAca,YAAY;uBACNA,EAAA,CAAA,wBAAA;yCADN,YAAY;2CAAZ,YAAY;AAExB;;ACpDD;;;;;;;;;;;;;;;;;;AAkBG;AACH,cASa,UAAU;yCAAV,UAAU;2CAAV,UAAU;AAAG;;;;","names":["_angular_core"]}
@@ -11,9 +11,32 @@ import * as i0 from '@angular/core';
11
11
  * DI wiring (ADR 013), host a11y bindings (ADR 021/027), and the agnostic
12
12
  * value posture (ADR 037 — no value channel, no @angular/forms) are unchanged
13
13
  * from the prior directive form.
14
+ *
15
+ * `SkraFieldContext` is injected `{ optional: true }` (ADR 013 §3.7) — the same
16
+ * posture as `skraCheckbox` / `skraRadio` / `skraSwitch`. Inside `<skra-field>`
17
+ * the atom takes the field's id + describedby + availability cascade; standalone
18
+ * it renders the skin only and the consumer owns every attribute, including the
19
+ * accessible name:
20
+ *
21
+ * <!-- inside Field — label association via the DI-generated id/for pair -->
22
+ * <skra-field>
23
+ * <label skraLabelFor>Email</label>
24
+ * <input skraInput type="email" />
25
+ * </skra-field>
26
+ *
27
+ * <!-- standalone: native implicit label (wrapping) — no id/for needed -->
28
+ * <label>Search <input skraInput type="search" /></label>
29
+ *
30
+ * Standalone use does NOT relax the ADR 033 accessible-name contract; it moves
31
+ * the name onto the consumer's own native markup. An input with no name is an
32
+ * a11y defect wherever it appears — including inside a `<skra-field>` that
33
+ * carries no `label[skraLabelFor]` — so the check belongs to the a11y gate, not
34
+ * to this injection site (ADR 013 §3.7).
14
35
  */
15
36
  declare class SkraInput {
16
- readonly context: SkraFieldContext;
37
+ private readonly el;
38
+ readonly context: SkraFieldContext | null;
39
+ constructor();
17
40
  static ɵfac: i0.ɵɵFactoryDeclaration<SkraInput, never>;
18
41
  static ɵcmp: i0.ɵɵComponentDeclaration<SkraInput, "input[skraInput]", never, {}, {}, never, never, true, never>;
19
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-input.d.ts","sources":["../../../../libs/ui/input/src/lib/input/input.ts"],"mappings":";;;AAQA;;;;;;;;;;AAUG;AACH,cAqBa,SAAS;sBACJ,gBAAA;yCADL,SAAS;2CAAT,SAAS;AAErB;;;;","names":[]}
1
+ {"version":3,"file":"skra-ui-input.d.ts","sources":["../../../../libs/ui/input/src/lib/input/input.ts"],"mappings":";;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BG;AACH,cAqBa,SAAS;AACpB;sBACgB,gBAAA;;yCAFL,SAAS;2CAAT,SAAS;AAwBrB;;;;","names":[]}
@@ -24,6 +24,14 @@ import * as i0 from '@angular/core';
24
24
  * </select>
25
25
  * </skra-field>
26
26
  *
27
+ * <!-- standalone: native implicit label (wrapping) — no id/for needed -->
28
+ * <label>Country <select skraSelect><option value="pl">Poland</option></select></label>
29
+ *
30
+ * `SkraFieldContext` is injected `{ optional: true }` (ADR 013 §3.7) — same
31
+ * posture as SkraInput / SkraCheckbox. Standalone, the atom renders the skin
32
+ * only, the readonly guards are inert, and the consumer owns every attribute
33
+ * including the accessible name.
34
+ *
27
35
  * Native `<select>` is the only web-platform widget whose dropdown renders in
28
36
  * the OS / browser top-layer, above modal `<dialog>`, above Shadow DOM
29
37
  * boundaries, above z-index stacking contexts. By staying native at Tier 1 we
@@ -49,7 +57,7 @@ import * as i0 from '@angular/core';
49
57
  */
50
58
  declare class SkraNativeSelect {
51
59
  private readonly el;
52
- readonly context: SkraFieldContext;
60
+ readonly context: SkraFieldContext | null;
53
61
  constructor();
54
62
  /**
55
63
  * Readonly: suppress the pointer affordance that opens the native listbox.
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-native-select.d.ts","sources":["../../../../libs/ui/native-select/src/lib/select/select.ts"],"mappings":";;;AAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CG;AACH,cAwBa,gBAAgB;AAC3B;sBACgB,gBAAA;;AA2BhB;;;;;AAKG;AACH,uCAAmC,KAAK;AAIxC;;;;;;AAMG;AACH,0CAAsC,aAAa;yCA9CxC,gBAAgB;2CAAhB,gBAAgB;AAmD5B;;;;","names":[]}
1
+ {"version":3,"file":"skra-ui-native-select.d.ts","sources":["../../../../libs/ui/native-select/src/lib/select/select.ts"],"mappings":";;;AAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDG;AACH,cAuBa,gBAAgB;AAC3B;sBACgB,gBAAA;;AAsChB;;;;;AAKG;AACH,uCAAmC,KAAK;AAIxC;;;;;;AAMG;AACH,0CAAsC,aAAa;yCAzDxC,gBAAgB;2CAAhB,gBAAgB;AA8D5B;;;;","names":[]}
@@ -20,11 +20,20 @@ import * as i0 from '@angular/core';
20
20
  * <textarea skraTextarea skraAutoResize rows="3"></textarea>
21
21
  * </skra-field>
22
22
  *
23
+ * <!-- standalone: native implicit label (wrapping) — no id/for needed -->
24
+ * <label>Notes <textarea skraTextarea></textarea></label>
25
+ *
23
26
  * Native `rows` / `cols` remain the consumer-facing sizing primitives — Forge
24
27
  * does not duplicate them as Angular inputs (boundary #9 native-attr-first).
28
+ *
29
+ * `SkraFieldContext` is injected `{ optional: true }` (ADR 013 §3.7) — same
30
+ * posture as SkraInput / SkraCheckbox. Standalone, the atom renders the skin
31
+ * only and the consumer owns every attribute, including the accessible name.
25
32
  */
26
33
  declare class SkraTextarea {
27
- readonly context: SkraFieldContext;
34
+ private readonly el;
35
+ readonly context: SkraFieldContext | null;
36
+ constructor();
28
37
  static ɵfac: i0.ɵɵFactoryDeclaration<SkraTextarea, never>;
29
38
  static ɵcmp: i0.ɵɵComponentDeclaration<SkraTextarea, "textarea[skraTextarea]", never, {}, {}, never, ["*"], true, never>;
30
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-textarea.d.ts","sources":["../../../../libs/ui/textarea/src/lib/textarea/textarea.ts","../../../../libs/ui/textarea/src/lib/auto-resize/auto-resize.directive.ts"],"mappings":";;;AAQA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACH,cAoBa,YAAY;sBACP,gBAAA;yCADL,YAAY;2CAAZ,YAAY;AAExB;;AClDD;;;;;;;;;;;;;;;;AAgBG;AACH,cAIa,uBAAuB;yCAAvB,uBAAuB;2CAAvB,uBAAuB;AAAG;;;;","names":[]}
1
+ {"version":3,"file":"skra-ui-textarea.d.ts","sources":["../../../../libs/ui/textarea/src/lib/textarea/textarea.ts","../../../../libs/ui/textarea/src/lib/auto-resize/auto-resize.directive.ts"],"mappings":";;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;AACH,cAoBa,YAAY;AACvB;sBACgB,gBAAA;;yCAFL,YAAY;2CAAZ,YAAY;AAuBxB;;AChFD;;;;;;;;;;;;;;;;AAgBG;AACH,cAIa,uBAAuB;yCAAvB,uBAAuB;2CAAvB,uBAAuB;AAAG;;;;","names":[]}