@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.
- package/LICENSE +201 -201
- package/NOTICE +7 -7
- package/README.md +39 -39
- package/consumer-guide/README.md +84 -84
- package/consumer-guide/forms-and-binding.md +19 -3
- package/consumer-guide/layout.md +19 -0
- package/consumer-guide/overlays.md +100 -100
- package/consumer-guide/setup-and-gotchas.md +165 -103
- package/consumer-guide/theming-and-encapsulation.md +129 -115
- package/fesm2022/skra-ui-accordion.mjs +61 -43
- package/fesm2022/skra-ui-accordion.mjs.map +1 -1
- package/fesm2022/skra-ui-alert.mjs +26 -18
- package/fesm2022/skra-ui-alert.mjs.map +1 -1
- package/fesm2022/skra-ui-avatar.mjs +12 -8
- package/fesm2022/skra-ui-avatar.mjs.map +1 -1
- package/fesm2022/skra-ui-badge.mjs +19 -13
- package/fesm2022/skra-ui-badge.mjs.map +1 -1
- package/fesm2022/skra-ui-button.mjs +28 -19
- package/fesm2022/skra-ui-button.mjs.map +1 -1
- package/fesm2022/skra-ui-checkbox.mjs +3 -3
- package/fesm2022/skra-ui-checkbox.mjs.map +1 -1
- package/fesm2022/skra-ui-chip.mjs +15 -11
- package/fesm2022/skra-ui-chip.mjs.map +1 -1
- package/fesm2022/skra-ui-combobox.mjs +135 -130
- package/fesm2022/skra-ui-combobox.mjs.map +1 -1
- package/fesm2022/skra-ui-core.mjs +95 -73
- package/fesm2022/skra-ui-core.mjs.map +1 -1
- package/fesm2022/skra-ui-counter.mjs +9 -6
- package/fesm2022/skra-ui-counter.mjs.map +1 -1
- package/fesm2022/skra-ui-datepicker.mjs +334 -307
- package/fesm2022/skra-ui-datepicker.mjs.map +1 -1
- package/fesm2022/skra-ui-dialog.mjs +5 -4
- package/fesm2022/skra-ui-dialog.mjs.map +1 -1
- package/fesm2022/skra-ui-field.mjs +65 -43
- package/fesm2022/skra-ui-field.mjs.map +1 -1
- package/fesm2022/skra-ui-icon.mjs +5 -4
- package/fesm2022/skra-ui-icon.mjs.map +1 -1
- package/fesm2022/skra-ui-input.mjs +53 -12
- package/fesm2022/skra-ui-input.mjs.map +1 -1
- package/fesm2022/skra-ui-kbd.mjs +3 -3
- package/fesm2022/skra-ui-kbd.mjs.map +1 -1
- package/fesm2022/skra-ui-layout.mjs +33 -21
- package/fesm2022/skra-ui-layout.mjs.map +1 -1
- package/fesm2022/skra-ui-link.mjs +3 -3
- package/fesm2022/skra-ui-link.mjs.map +1 -1
- package/fesm2022/skra-ui-loading-indicator.mjs +3 -3
- package/fesm2022/skra-ui-loading-indicator.mjs.map +1 -1
- package/fesm2022/skra-ui-menu.mjs +8 -7
- package/fesm2022/skra-ui-menu.mjs.map +1 -1
- package/fesm2022/skra-ui-multi-select.mjs +102 -98
- package/fesm2022/skra-ui-multi-select.mjs.map +1 -1
- package/fesm2022/skra-ui-native-select.mjs +35 -17
- package/fesm2022/skra-ui-native-select.mjs.map +1 -1
- package/fesm2022/skra-ui-popover.mjs +5 -4
- package/fesm2022/skra-ui-popover.mjs.map +1 -1
- package/fesm2022/skra-ui-progress.mjs +7 -5
- package/fesm2022/skra-ui-progress.mjs.map +1 -1
- package/fesm2022/skra-ui-radio.mjs +3 -3
- package/fesm2022/skra-ui-radio.mjs.map +1 -1
- package/fesm2022/skra-ui-rating-display.mjs +14 -9
- package/fesm2022/skra-ui-rating-display.mjs.map +1 -1
- package/fesm2022/skra-ui-select.mjs +98 -95
- package/fesm2022/skra-ui-select.mjs.map +1 -1
- package/fesm2022/skra-ui-skeleton.mjs +16 -13
- package/fesm2022/skra-ui-skeleton.mjs.map +1 -1
- package/fesm2022/skra-ui-star-rating.mjs +18 -11
- package/fesm2022/skra-ui-star-rating.mjs.map +1 -1
- package/fesm2022/skra-ui-status-dot.mjs +7 -5
- package/fesm2022/skra-ui-status-dot.mjs.map +1 -1
- package/fesm2022/skra-ui-switch.mjs +3 -3
- package/fesm2022/skra-ui-switch.mjs.map +1 -1
- package/fesm2022/skra-ui-tabs.mjs +43 -29
- package/fesm2022/skra-ui-tabs.mjs.map +1 -1
- package/fesm2022/skra-ui-textarea.mjs +41 -15
- package/fesm2022/skra-ui-textarea.mjs.map +1 -1
- package/fesm2022/skra-ui-toast.mjs +35 -23
- package/fesm2022/skra-ui-toast.mjs.map +1 -1
- package/fesm2022/skra-ui-tooltip.mjs +12 -9
- package/fesm2022/skra-ui-tooltip.mjs.map +1 -1
- package/fesm2022/skra-ui-typography.mjs +9 -6
- package/fesm2022/skra-ui-typography.mjs.map +1 -1
- package/package.json +6 -6
- package/types/skra-ui-field.d.ts +3 -3
- package/types/skra-ui-field.d.ts.map +1 -1
- package/types/skra-ui-input.d.ts +24 -1
- package/types/skra-ui-input.d.ts.map +1 -1
- package/types/skra-ui-native-select.d.ts +9 -1
- package/types/skra-ui-native-select.d.ts.map +1 -1
- package/types/skra-ui-textarea.d.ts +10 -1
- package/types/skra-ui-textarea.d.ts.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skra-ui-tabs.mjs","sources":["../../../../libs/ui/tabs/src/lib/tabs/tabs-context.ts","../../../../libs/ui/tabs/src/lib/tabs/tab.ts","../../../../libs/ui/tabs/src/lib/tabs/tab-panel.ts","../../../../libs/ui/tabs/src/lib/tabs/tabs-keyboard.ts","../../../../libs/ui/tabs/src/lib/tabs/tabs.ts","../../../../libs/ui/tabs/src/lib/tabs/tablist.ts","../../../../libs/ui/tabs/src/skra-ui-tabs.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\n\n/** Module-global counter → a deterministic, unique id base per `[skraTabs]` instance.\n * Equivalent to the forms `IdGeneratorService` (ADR 013) but lib-local, so `@skra/navigation`\n * takes no dependency on `@skra/forms` just for id generation. Stable across SSR↔hydration\n * (same instantiation order yields the same ids — the standard counter technique). */\nlet tabsInstanceCounter = 0;\n\n/** Sanitize a consumer `value` into an id-safe fragment (no spaces / special chars). */\nfunction idSafe(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, '-');\n}\n\n/**\n * DI Context provided per `[skraTabs]` instance — the ADR 013 §3.6 **non-form** Contextual-ID-Sync\n * bus wiring `tab` ↔ `tabpanel`. It carries **IDs + derived, read-only interaction state only**\n * (`selected` mirrors the consumer's `[selected]`; `activeValue` is the roving-focus position). It\n * **never owns value** — selection stays consumer-owned (ADR 037); a tab requests a change through\n * `select()`, which the coordinator implements and from which it emits `(selectedChange)`.\n */\n@Injectable()\nexport class SkraTabsContext {\n /** Unique per `[skraTabs]` — the prefix for every tab/panel id in this group. */\n private readonly baseId = `skra-tabs-${++tabsInstanceCounter}`;\n\n /** Mirror of the consumer's `[selected]` — drives `aria-selected` + panel visibility (read-only to children). */\n readonly selected = signal<string>('');\n /** Roving-focus position — the value of the tab that currently carries `tabindex=\"0\"` (read-only to children). */\n readonly activeValue = signal<string>('');\n /** Activation model (read-only to children). */\n readonly activation = signal<'automatic' | 'manual'>('automatic');\n\n tabId(value: string): string {\n return `${this.baseId}-tab-${idSafe(value)}`;\n }\n panelId(value: string): string {\n return `${this.baseId}-panel-${idSafe(value)}`;\n }\n isSelected(value: string): boolean {\n return this.selected() === value;\n }\n\n /** Coordinator-assigned: a tab/keyboard requests selection (the coordinator emits `(selectedChange)`). */\n select: (value: string) => void = () => undefined;\n /** Coordinator-assigned: the tablist forwards its `keydown` here (routed to the keyboard controller). */\n handleKeydown: (event: KeyboardEvent) => void = () => undefined;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n} from '@angular/core';\n\nimport { SkraTabsContext } from './tabs-context';\nimport type { SkraTabKeyItem } from './tabs-types';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/**\n * SkraTab — a single tab, a Component on the native command host `button[skraTab]` (ADR 012/040:\n * a `<button>` gives Enter/Space→click + focusability for free; its implicit role is overridden to\n * `role=\"tab\"`, the precedent set by `button[skraMenuItem]`).\n *\n * Roving tabindex: `tabindex=\"0\"` only when this tab is the roving stop (`SkraTabsContext.activeValue`),\n * else `-1` — the controller (`SkraTabsKeyboard`) moves real focus. `aria-selected` reflects the\n * consumer-owned selection (`[selected]`), NOT the roving focus — and is the source of truth for the\n * selected STYLE too (CSS keys off `:host([aria-selected=\"true\"])`; no `data-skra-*`). On activation it\n * REQUESTS selection from the coordinator (`ctx.select`) — it never mutates selection itself (ADR 037).\n *\n * **Disabled is native-attr-first (boundary #9): the consumer sets the native `disabled` attribute** —\n * Forge OBSERVES it (no `disabled` input). A disabled tab is SKIPPED in the roving order (APG).\n */\n@Component({\n selector: 'button[skraTab]',\n standalone: true,\n exportAs: 'skraTab',\n template: '<ng-content></ng-content>',\n styleUrl: './tab.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n role: 'tab',\n type: 'button', // never an implicit submit if the tablist sits inside a <form>\n '[attr.id]': 'tabId()',\n '[attr.aria-controls]': 'panelId()',\n '[attr.aria-selected]': 'ariaSelected()',\n '[attr.tabindex]': 'tabindex()',\n '(click)': 'onClick()',\n },\n})\nexport class SkraTab implements SkraTabKeyItem {\n /** Selection key — matched against `skraTabs [selected]` and the owning panel's `value`. */\n readonly value = input.required<string>();\n\n private readonly host = inject<ElementRef<HTMLButtonElement>>(ElementRef);\n private readonly ctx = inject(SkraTabsContext, { optional: true });\n\n protected readonly tabId = computed(\n () => this.ctx?.tabId(this.value()) ?? null,\n );\n protected readonly panelId = computed(\n () => this.ctx?.panelId(this.value()) ?? null,\n );\n protected readonly ariaSelected = computed(() =>\n this.ctx?.isSelected(this.value()) ? 'true' : 'false',\n );\n protected readonly tabindex = computed(() => {\n if (!this.ctx) return null; // standalone misuse — leave the native button focusable\n return this.ctx.activeValue() === this.value() ? '0' : '-1';\n });\n\n constructor() {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this.ctx) {\n console.warn(\n '[skraTab] has no [skraTabs] ancestor — it is not wired to a tablist (no aria-controls / ' +\n 'roving / selection). Project it inside <div skraTablist> within <element skraTabs>.',\n );\n }\n }\n }\n\n // ── SkraTabKeyItem (driven by SkraTabsKeyboard / CDK FocusKeyManager) ──\n focus(): void {\n this.host.nativeElement.focus();\n }\n /** Disabled tabs are skipped in the roving order — read live off the native attribute (no input). */\n isDisabled(): boolean {\n return this.host.nativeElement.disabled;\n }\n getValue(): string {\n return this.value();\n }\n\n protected onClick(): void {\n if (this.host.nativeElement.disabled) return; // belt-and-suspenders (native disabled won't fire click)\n this.ctx?.select(this.value());\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n inject,\n input,\n} from '@angular/core';\n\nimport { SkraTabsContext } from './tabs-context';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/**\n * SkraTabPanel — the `role=\"tabpanel\"` for one tab, a Component on the consumer's `<div skraTabPanel>`\n * (ADR 040, `template: '<ng-content>'` so the panel body renders). It is focusable (`tabindex=\"0\"`, APG —\n * keyboard users Tab from the active tab into its content), auto-named by `aria-labelledby`→its tab, and\n * `hidden` when its `value` is not the selected one (removed from the a11y tree; stays in the DOM — lazy\n * mounting is the consumer's own `@if` on the content).\n */\n@Component({\n selector: '[skraTabPanel]',\n standalone: true,\n exportAs: 'skraTabPanel',\n template: '<ng-content></ng-content>',\n styleUrl: './tab-panel.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n role: 'tabpanel',\n tabindex: '0',\n '[attr.id]': 'panelId()',\n '[attr.aria-labelledby]': 'tabId()',\n '[attr.hidden]': 'hidden()',\n },\n})\nexport class SkraTabPanel {\n /** Selection key — matched against the owning `button[skraTab]`'s `value`. */\n readonly value = input.required<string>();\n\n private readonly ctx = inject(SkraTabsContext, { optional: true });\n\n protected readonly panelId = computed(\n () => this.ctx?.panelId(this.value()) ?? null,\n );\n protected readonly tabId = computed(\n () => this.ctx?.tabId(this.value()) ?? null,\n );\n /** `''` (attribute present) when not selected → hidden; `null` (absent) when selected → shown. */\n protected readonly hidden = computed(() =>\n this.ctx?.isSelected(this.value()) ? null : '',\n );\n\n constructor() {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this.ctx) {\n console.warn(\n '[skraTabPanel] has no [skraTabs] ancestor — it cannot be linked to a tab or shown/hidden. ' +\n 'Project it inside <element skraTabs>.',\n );\n }\n }\n }\n}\n","import { FocusKeyManager } from '@angular/cdk/a11y';\n\nimport type { SkraTabKeyItem } from './tabs-types';\n\n/**\n * SkraTabsKeyboard — the WAI-ARIA APG **Tabs** roving-tabindex keyboard model, confined to ONE file.\n *\n * This is the **only** module in `@skra/navigation` that imports `@angular/cdk` (ADR 0044 §7,\n * generalized library-wide 2026-06-19). It wraps CDK `FocusKeyManager` (roving REAL focus) so the\n * engine is swappable in one file — exactly as `SkraMenuKeyboard` does for the menu. Unlike the menu,\n * tabs use **horizontal** orientation (Left/Right) and **skip** disabled tabs.\n *\n * Owns: Left/Right roving (wrap), Home/End. Enter/Space (native button activation) and selection are\n * the coordinator's job — the controller only moves focus and reports the active tab's value.\n */\nexport class SkraTabsKeyboard {\n private manager?: FocusKeyManager<SkraTabKeyItem>;\n private items: SkraTabKeyItem[] = [];\n\n /**\n * (Re)build the manager from the current projected tab set. Called from an `effect` on the signal\n * `contentChildren` — a passed array is a static snapshot, so the manager is rebuilt whenever the\n * tab set changes (the documented signal↔CDK seam, mirroring `menu-keyboard.ts`).\n */\n setItems(items: readonly SkraTabKeyItem[]): void {\n this.items = [...items];\n this.manager?.destroy();\n this.manager = new FocusKeyManager<SkraTabKeyItem>(this.items)\n .withHorizontalOrientation('ltr') // Left/Right; RTL handled by the manager via the page dir\n .withWrap()\n .withHomeAndEnd()\n // Tabs SKIP disabled (APG): a disabled tab is not a roving stop. (Menu keeps them focusable.)\n .skipPredicate((tab) => tab.isDisabled());\n }\n\n /** Delegate Left/Right/Home/End. Enter/Space/Tab are intentionally left to the platform/coordinator. */\n onKeydown(event: KeyboardEvent): void {\n this.manager?.onKeydown(event);\n }\n\n /** The value of the tab the manager currently considers active (focused after `onKeydown`). */\n activeValue(): string | undefined {\n return this.manager?.activeItem?.getValue();\n }\n\n /** Sync the manager's active index to a value WITHOUT moving focus (after a click / on init). */\n setActive(value: string): void {\n const index = this.items.findIndex((tab) => tab.getValue() === value);\n if (index >= 0) this.manager?.updateActiveItem(index);\n }\n\n /** The first non-disabled tab's value (the roving stop when nothing is selected) — APG. */\n firstEnabledValue(): string | undefined {\n return this.items.find((tab) => !tab.isDisabled())?.getValue();\n }\n\n hasValue(value: string): boolean {\n return this.items.some((tab) => tab.getValue() === value);\n }\n\n destroy(): void {\n this.manager?.destroy();\n this.manager = undefined;\n }\n}\n","import {\n DestroyRef,\n Directive,\n contentChildren,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\n\nimport { SkraTab } from './tab';\nimport { SkraTabPanel } from './tab-panel';\nimport { SkraTabsContext } from './tabs-context';\nimport { SkraTabsKeyboard } from './tabs-keyboard';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/**\n * SkraTabs — the WAI-ARIA APG **Tabs** coordinator. A directive on a wrapping element that holds a\n * `[skraTablist]` (the `role=\"tablist\"` with its `button[skraTab]` children) and the\n * `[skraTabPanel]` panels as DI descendants. It provides `SkraTabsContext` (the ADR 013 §3.6 non-form\n * Contextual-ID-Sync bus), owns the consumer-facing `[selected]` / `(selectedChange)` (controlled,\n * ADR 037 — NO internal selection state) and `[activation]`, and drives the roving-tabindex keyboard\n * (`SkraTabsKeyboard` → CDK `FocusKeyManager`).\n *\n * <div skraTabs [selected]=\"tab()\" (selectedChange)=\"tab.set($event)\">\n * <div skraTablist aria-label=\"Account\">\n * <button skraTab value=\"profile\">Profile</button>\n * <button skraTab value=\"security\">Security</button>\n * </div>\n * <div skraTabPanel value=\"profile\">…</div>\n * <div skraTabPanel value=\"security\">…</div>\n * </div>\n *\n * Selection is consumer-owned: a click / Enter / Space / (automatic) arrow emits `(selectedChange)`;\n * the visible selection updates when the consumer round-trips `[selected]`. The roving focus position\n * (`tabindex=\"0\"`) is component-owned UI state — it moves immediately, independent of `[selected]`.\n *\n * Full contract: adr/specs/component-tabs-spec.md.\n */\n@Directive({\n selector: '[skraTabs]',\n standalone: true,\n exportAs: 'skraTabs',\n providers: [SkraTabsContext],\n})\nexport class SkraTabs {\n /** Consumer-owned selection key (matches a tab's `value`); '' / no-match → nothing selected (ADR 037). */\n readonly selected = input<string>('');\n /** Automatic (selection follows roving focus) | manual (Enter/Space selects). */\n readonly activation = input<'automatic' | 'manual'>('automatic');\n /** Fires ONLY on user activation — never on a programmatic `[selected]` change. */\n readonly selectedChange = output<string>();\n\n private readonly ctx = inject(SkraTabsContext);\n private readonly tabs = contentChildren(SkraTab, { descendants: true });\n private readonly panels = contentChildren(SkraTabPanel, {\n descendants: true,\n });\n private readonly keyboard = new SkraTabsKeyboard();\n\n constructor() {\n // Wire the context bus (a tab requests selection; the tablist forwards keydown).\n this.ctx.select = (value) => this.selectTab(value);\n this.ctx.handleKeydown = (event) => this.onTablistKeydown(event);\n\n // Mirror inputs → context (read-only to children).\n effect(() => this.ctx.selected.set(this.selected()));\n effect(() => this.ctx.activation.set(this.activation()));\n\n // (Re)build the keyboard from the projected tab set and (re)seat the roving stop whenever the tab\n // set or the selection changes. Rebuilding the manager for a handful of tabs is trivial.\n effect(() => {\n this.keyboard.setItems(this.tabs());\n this.reseat();\n });\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n effect(() => this.warnMismatches());\n }\n\n inject(DestroyRef).onDestroy(() => this.keyboard.destroy());\n }\n\n /** Seat the roving stop (`tabindex=\"0\"`) on a real, enabled tab: the selected one if valid, else the\n * first enabled tab (APG — the tablist must always have exactly one tab stop). */\n private reseat(): void {\n const sel = this.selected();\n const next = this.keyboard.hasValue(sel)\n ? sel\n : (this.keyboard.firstEnabledValue() ?? '');\n this.ctx.activeValue.set(next);\n if (next) this.keyboard.setActive(next);\n }\n\n /** A tab was activated (click / Enter / Space / automatic arrow). Move the roving stop immediately\n * (UI state), then REQUEST selection from the consumer — never mutate selection internally (ADR 037). */\n private selectTab(value: string): void {\n this.ctx.activeValue.set(value);\n this.keyboard.setActive(value);\n if (this.selected() === value) return; // idempotent — no redundant output\n this.selectedChange.emit(value);\n }\n\n private onTablistKeydown(event: KeyboardEvent): void {\n const before = this.keyboard.activeValue();\n this.keyboard.onKeydown(event);\n const after = this.keyboard.activeValue();\n if (after && after !== before) {\n this.ctx.activeValue.set(after); // roving moved (focus already on the new tab)\n if (this.ctx.activation() === 'automatic') this.selectTab(after);\n }\n }\n\n /** Dev-only nudge: every tab needs a panel of the same `value`, and vice-versa (aria-controls / -labelledby). */\n private warnMismatches(): void {\n const tabValues = new Set(this.tabs().map((t) => t.value()));\n const panelValues = new Set(this.panels().map((p) => p.value()));\n for (const v of tabValues) {\n if (!panelValues.has(v))\n console.warn(\n `[skraTabs] tab value=\"${v}\" has no matching [skraTabPanel] — its aria-controls points to a missing panel.`,\n );\n }\n for (const v of panelValues) {\n if (!tabValues.has(v))\n console.warn(\n `[skraTabs] panel value=\"${v}\" has no matching button[skraTab] — it will never be revealed.`,\n );\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n inject,\n} from '@angular/core';\n\nimport { SkraTabsContext } from './tabs-context';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/**\n * SkraTablist — the `role=\"tablist\"` container, a Component on the consumer's `<div skraTablist>`\n * (ADR 040, `template: '<ng-content>'` so the projected `button[skraTab]` children render). It carries\n * the rail styling and forwards its `keydown` to the coordinator's roving keyboard (`SkraTabsKeyboard`)\n * via the `SkraTabsContext` bus. Name it for AT with consumer `aria-label`/`aria-labelledby` (ADR 033).\n */\n@Component({\n selector: '[skraTablist]',\n standalone: true,\n exportAs: 'skraTablist',\n template: '<ng-content></ng-content>',\n styleUrl: './tablist.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n role: 'tablist',\n 'aria-orientation': 'horizontal',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class SkraTablist {\n private readonly ctx = inject(SkraTabsContext, { optional: true });\n\n constructor() {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this.ctx) {\n console.warn(\n '[skraTablist] has no [skraTabs] ancestor — its tabs cannot be keyboard-navigated. ' +\n 'Wrap the tablist + panels in <element skraTabs>.',\n );\n }\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n this.ctx?.handleKeydown(event);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"skra-ui-tabs.mjs","sources":["../../../../libs/ui/tabs/src/lib/tabs/tabs-context.ts","../../../../libs/ui/tabs/src/lib/tabs/tab.ts","../../../../libs/ui/tabs/src/lib/tabs/tab-panel.ts","../../../../libs/ui/tabs/src/lib/tabs/tabs-keyboard.ts","../../../../libs/ui/tabs/src/lib/tabs/tabs.ts","../../../../libs/ui/tabs/src/lib/tabs/tablist.ts","../../../../libs/ui/tabs/src/skra-ui-tabs.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\r\n\r\n/** Module-global counter → a deterministic, unique id base per `[skraTabs]` instance.\r\n * Equivalent to the forms `IdGeneratorService` (ADR 013) but lib-local, so `@skra/navigation`\r\n * takes no dependency on `@skra/forms` just for id generation. Stable across SSR↔hydration\r\n * (same instantiation order yields the same ids — the standard counter technique). */\r\nlet tabsInstanceCounter = 0;\r\n\r\n/** Sanitize a consumer `value` into an id-safe fragment (no spaces / special chars). */\r\nfunction idSafe(value: string): string {\r\n return value.replace(/[^a-zA-Z0-9_-]/g, '-');\r\n}\r\n\r\n/**\r\n * DI Context provided per `[skraTabs]` instance — the ADR 013 §3.6 **non-form** Contextual-ID-Sync\r\n * bus wiring `tab` ↔ `tabpanel`. It carries **IDs + derived, read-only interaction state only**\r\n * (`selected` mirrors the consumer's `[selected]`; `activeValue` is the roving-focus position). It\r\n * **never owns value** — selection stays consumer-owned (ADR 037); a tab requests a change through\r\n * `select()`, which the coordinator implements and from which it emits `(selectedChange)`.\r\n */\r\n@Injectable()\r\nexport class SkraTabsContext {\r\n /** Unique per `[skraTabs]` — the prefix for every tab/panel id in this group. */\r\n private readonly baseId = `skra-tabs-${++tabsInstanceCounter}`;\r\n\r\n /** Mirror of the consumer's `[selected]` — drives `aria-selected` + panel visibility (read-only to children). */\r\n readonly selected = signal<string>('');\r\n /** Roving-focus position — the value of the tab that currently carries `tabindex=\"0\"` (read-only to children). */\r\n readonly activeValue = signal<string>('');\r\n /** Activation model (read-only to children). */\r\n readonly activation = signal<'automatic' | 'manual'>('automatic');\r\n\r\n tabId(value: string): string {\r\n return `${this.baseId}-tab-${idSafe(value)}`;\r\n }\r\n panelId(value: string): string {\r\n return `${this.baseId}-panel-${idSafe(value)}`;\r\n }\r\n isSelected(value: string): boolean {\r\n return this.selected() === value;\r\n }\r\n\r\n /** Coordinator-assigned: a tab/keyboard requests selection (the coordinator emits `(selectedChange)`). */\r\n select: (value: string) => void = () => undefined;\r\n /** Coordinator-assigned: the tablist forwards its `keydown` here (routed to the keyboard controller). */\r\n handleKeydown: (event: KeyboardEvent) => void = () => undefined;\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n ViewEncapsulation,\r\n computed,\r\n inject,\r\n input,\r\n} from '@angular/core';\r\n\r\nimport { SkraTabsContext } from './tabs-context';\r\nimport type { SkraTabKeyItem } from './tabs-types';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/**\r\n * SkraTab — a single tab, a Component on the native command host `button[skraTab]` (ADR 012/040:\r\n * a `<button>` gives Enter/Space→click + focusability for free; its implicit role is overridden to\r\n * `role=\"tab\"`, the precedent set by `button[skraMenuItem]`).\r\n *\r\n * Roving tabindex: `tabindex=\"0\"` only when this tab is the roving stop (`SkraTabsContext.activeValue`),\r\n * else `-1` — the controller (`SkraTabsKeyboard`) moves real focus. `aria-selected` reflects the\r\n * consumer-owned selection (`[selected]`), NOT the roving focus — and is the source of truth for the\r\n * selected STYLE too (CSS keys off `:host([aria-selected=\"true\"])`; no `data-skra-*`). On activation it\r\n * REQUESTS selection from the coordinator (`ctx.select`) — it never mutates selection itself (ADR 037).\r\n *\r\n * **Disabled is native-attr-first (boundary #9): the consumer sets the native `disabled` attribute** —\r\n * Forge OBSERVES it (no `disabled` input). A disabled tab is SKIPPED in the roving order (APG).\r\n */\r\n@Component({\r\n selector: 'button[skraTab]',\r\n standalone: true,\r\n exportAs: 'skraTab',\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './tab.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n role: 'tab',\r\n type: 'button', // never an implicit submit if the tablist sits inside a <form>\r\n '[attr.id]': 'tabId()',\r\n '[attr.aria-controls]': 'panelId()',\r\n '[attr.aria-selected]': 'ariaSelected()',\r\n '[attr.tabindex]': 'tabindex()',\r\n '(click)': 'onClick()',\r\n },\r\n})\r\nexport class SkraTab implements SkraTabKeyItem {\r\n /** Selection key — matched against `skraTabs [selected]` and the owning panel's `value`. */\r\n readonly value = input.required<string>();\r\n\r\n private readonly host = inject<ElementRef<HTMLButtonElement>>(ElementRef);\r\n private readonly ctx = inject(SkraTabsContext, { optional: true });\r\n\r\n protected readonly tabId = computed(\r\n () => this.ctx?.tabId(this.value()) ?? null,\r\n );\r\n protected readonly panelId = computed(\r\n () => this.ctx?.panelId(this.value()) ?? null,\r\n );\r\n protected readonly ariaSelected = computed(() =>\r\n this.ctx?.isSelected(this.value()) ? 'true' : 'false',\r\n );\r\n protected readonly tabindex = computed(() => {\r\n if (!this.ctx) return null; // standalone misuse — leave the native button focusable\r\n return this.ctx.activeValue() === this.value() ? '0' : '-1';\r\n });\r\n\r\n constructor() {\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n if (!this.ctx) {\r\n console.warn(\r\n '[skraTab] has no [skraTabs] ancestor — it is not wired to a tablist (no aria-controls / ' +\r\n 'roving / selection). Project it inside <div skraTablist> within <element skraTabs>.',\r\n );\r\n }\r\n }\r\n }\r\n\r\n // ── SkraTabKeyItem (driven by SkraTabsKeyboard / CDK FocusKeyManager) ──\r\n focus(): void {\r\n this.host.nativeElement.focus();\r\n }\r\n /** Disabled tabs are skipped in the roving order — read live off the native attribute (no input). */\r\n isDisabled(): boolean {\r\n return this.host.nativeElement.disabled;\r\n }\r\n getValue(): string {\r\n return this.value();\r\n }\r\n\r\n protected onClick(): void {\r\n if (this.host.nativeElement.disabled) return; // belt-and-suspenders (native disabled won't fire click)\r\n this.ctx?.select(this.value());\r\n }\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n computed,\r\n inject,\r\n input,\r\n} from '@angular/core';\r\n\r\nimport { SkraTabsContext } from './tabs-context';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/**\r\n * SkraTabPanel — the `role=\"tabpanel\"` for one tab, a Component on the consumer's `<div skraTabPanel>`\r\n * (ADR 040, `template: '<ng-content>'` so the panel body renders). It is focusable (`tabindex=\"0\"`, APG —\r\n * keyboard users Tab from the active tab into its content), auto-named by `aria-labelledby`→its tab, and\r\n * `hidden` when its `value` is not the selected one (removed from the a11y tree; stays in the DOM — lazy\r\n * mounting is the consumer's own `@if` on the content).\r\n */\r\n@Component({\r\n selector: '[skraTabPanel]',\r\n standalone: true,\r\n exportAs: 'skraTabPanel',\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './tab-panel.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n role: 'tabpanel',\r\n tabindex: '0',\r\n '[attr.id]': 'panelId()',\r\n '[attr.aria-labelledby]': 'tabId()',\r\n '[attr.hidden]': 'hidden()',\r\n },\r\n})\r\nexport class SkraTabPanel {\r\n /** Selection key — matched against the owning `button[skraTab]`'s `value`. */\r\n readonly value = input.required<string>();\r\n\r\n private readonly ctx = inject(SkraTabsContext, { optional: true });\r\n\r\n protected readonly panelId = computed(\r\n () => this.ctx?.panelId(this.value()) ?? null,\r\n );\r\n protected readonly tabId = computed(\r\n () => this.ctx?.tabId(this.value()) ?? null,\r\n );\r\n /** `''` (attribute present) when not selected → hidden; `null` (absent) when selected → shown. */\r\n protected readonly hidden = computed(() =>\r\n this.ctx?.isSelected(this.value()) ? null : '',\r\n );\r\n\r\n constructor() {\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n if (!this.ctx) {\r\n console.warn(\r\n '[skraTabPanel] has no [skraTabs] ancestor — it cannot be linked to a tab or shown/hidden. ' +\r\n 'Project it inside <element skraTabs>.',\r\n );\r\n }\r\n }\r\n }\r\n}\r\n","import { FocusKeyManager } from '@angular/cdk/a11y';\r\n\r\nimport type { SkraTabKeyItem } from './tabs-types';\r\n\r\n/**\r\n * SkraTabsKeyboard — the WAI-ARIA APG **Tabs** roving-tabindex keyboard model, confined to ONE file.\r\n *\r\n * This is the **only** module in `@skra/navigation` that imports `@angular/cdk` (ADR 0044 §7,\r\n * generalized library-wide 2026-06-19). It wraps CDK `FocusKeyManager` (roving REAL focus) so the\r\n * engine is swappable in one file — exactly as `SkraMenuKeyboard` does for the menu. Unlike the menu,\r\n * tabs use **horizontal** orientation (Left/Right) and **skip** disabled tabs.\r\n *\r\n * Owns: Left/Right roving (wrap), Home/End. Enter/Space (native button activation) and selection are\r\n * the coordinator's job — the controller only moves focus and reports the active tab's value.\r\n */\r\nexport class SkraTabsKeyboard {\r\n private manager?: FocusKeyManager<SkraTabKeyItem>;\r\n private items: SkraTabKeyItem[] = [];\r\n\r\n /**\r\n * (Re)build the manager from the current projected tab set. Called from an `effect` on the signal\r\n * `contentChildren` — a passed array is a static snapshot, so the manager is rebuilt whenever the\r\n * tab set changes (the documented signal↔CDK seam, mirroring `menu-keyboard.ts`).\r\n */\r\n setItems(items: readonly SkraTabKeyItem[]): void {\r\n this.items = [...items];\r\n this.manager?.destroy();\r\n this.manager = new FocusKeyManager<SkraTabKeyItem>(this.items)\r\n .withHorizontalOrientation('ltr') // Left/Right; RTL handled by the manager via the page dir\r\n .withWrap()\r\n .withHomeAndEnd()\r\n // Tabs SKIP disabled (APG): a disabled tab is not a roving stop. (Menu keeps them focusable.)\r\n .skipPredicate((tab) => tab.isDisabled());\r\n }\r\n\r\n /** Delegate Left/Right/Home/End. Enter/Space/Tab are intentionally left to the platform/coordinator. */\r\n onKeydown(event: KeyboardEvent): void {\r\n this.manager?.onKeydown(event);\r\n }\r\n\r\n /** The value of the tab the manager currently considers active (focused after `onKeydown`). */\r\n activeValue(): string | undefined {\r\n return this.manager?.activeItem?.getValue();\r\n }\r\n\r\n /** Sync the manager's active index to a value WITHOUT moving focus (after a click / on init). */\r\n setActive(value: string): void {\r\n const index = this.items.findIndex((tab) => tab.getValue() === value);\r\n if (index >= 0) this.manager?.updateActiveItem(index);\r\n }\r\n\r\n /** The first non-disabled tab's value (the roving stop when nothing is selected) — APG. */\r\n firstEnabledValue(): string | undefined {\r\n return this.items.find((tab) => !tab.isDisabled())?.getValue();\r\n }\r\n\r\n hasValue(value: string): boolean {\r\n return this.items.some((tab) => tab.getValue() === value);\r\n }\r\n\r\n destroy(): void {\r\n this.manager?.destroy();\r\n this.manager = undefined;\r\n }\r\n}\r\n","import {\r\n DestroyRef,\r\n Directive,\r\n contentChildren,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n} from '@angular/core';\r\n\r\nimport { SkraTab } from './tab';\r\nimport { SkraTabPanel } from './tab-panel';\r\nimport { SkraTabsContext } from './tabs-context';\r\nimport { SkraTabsKeyboard } from './tabs-keyboard';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/**\r\n * SkraTabs — the WAI-ARIA APG **Tabs** coordinator. A directive on a wrapping element that holds a\r\n * `[skraTablist]` (the `role=\"tablist\"` with its `button[skraTab]` children) and the\r\n * `[skraTabPanel]` panels as DI descendants. It provides `SkraTabsContext` (the ADR 013 §3.6 non-form\r\n * Contextual-ID-Sync bus), owns the consumer-facing `[selected]` / `(selectedChange)` (controlled,\r\n * ADR 037 — NO internal selection state) and `[activation]`, and drives the roving-tabindex keyboard\r\n * (`SkraTabsKeyboard` → CDK `FocusKeyManager`).\r\n *\r\n * <div skraTabs [selected]=\"tab()\" (selectedChange)=\"tab.set($event)\">\r\n * <div skraTablist aria-label=\"Account\">\r\n * <button skraTab value=\"profile\">Profile</button>\r\n * <button skraTab value=\"security\">Security</button>\r\n * </div>\r\n * <div skraTabPanel value=\"profile\">…</div>\r\n * <div skraTabPanel value=\"security\">…</div>\r\n * </div>\r\n *\r\n * Selection is consumer-owned: a click / Enter / Space / (automatic) arrow emits `(selectedChange)`;\r\n * the visible selection updates when the consumer round-trips `[selected]`. The roving focus position\r\n * (`tabindex=\"0\"`) is component-owned UI state — it moves immediately, independent of `[selected]`.\r\n *\r\n * Full contract: adr/specs/component-tabs-spec.md.\r\n */\r\n@Directive({\r\n selector: '[skraTabs]',\r\n standalone: true,\r\n exportAs: 'skraTabs',\r\n providers: [SkraTabsContext],\r\n})\r\nexport class SkraTabs {\r\n /** Consumer-owned selection key (matches a tab's `value`); '' / no-match → nothing selected (ADR 037). */\r\n readonly selected = input<string>('');\r\n /** Automatic (selection follows roving focus) | manual (Enter/Space selects). */\r\n readonly activation = input<'automatic' | 'manual'>('automatic');\r\n /** Fires ONLY on user activation — never on a programmatic `[selected]` change. */\r\n readonly selectedChange = output<string>();\r\n\r\n private readonly ctx = inject(SkraTabsContext);\r\n private readonly tabs = contentChildren(SkraTab, { descendants: true });\r\n private readonly panels = contentChildren(SkraTabPanel, {\r\n descendants: true,\r\n });\r\n private readonly keyboard = new SkraTabsKeyboard();\r\n\r\n constructor() {\r\n // Wire the context bus (a tab requests selection; the tablist forwards keydown).\r\n this.ctx.select = (value) => this.selectTab(value);\r\n this.ctx.handleKeydown = (event) => this.onTablistKeydown(event);\r\n\r\n // Mirror inputs → context (read-only to children).\r\n effect(() => this.ctx.selected.set(this.selected()));\r\n effect(() => this.ctx.activation.set(this.activation()));\r\n\r\n // (Re)build the keyboard from the projected tab set and (re)seat the roving stop whenever the tab\r\n // set or the selection changes. Rebuilding the manager for a handful of tabs is trivial.\r\n effect(() => {\r\n this.keyboard.setItems(this.tabs());\r\n this.reseat();\r\n });\r\n\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n effect(() => this.warnMismatches());\r\n }\r\n\r\n inject(DestroyRef).onDestroy(() => this.keyboard.destroy());\r\n }\r\n\r\n /** Seat the roving stop (`tabindex=\"0\"`) on a real, enabled tab: the selected one if valid, else the\r\n * first enabled tab (APG — the tablist must always have exactly one tab stop). */\r\n private reseat(): void {\r\n const sel = this.selected();\r\n const next = this.keyboard.hasValue(sel)\r\n ? sel\r\n : (this.keyboard.firstEnabledValue() ?? '');\r\n this.ctx.activeValue.set(next);\r\n if (next) this.keyboard.setActive(next);\r\n }\r\n\r\n /** A tab was activated (click / Enter / Space / automatic arrow). Move the roving stop immediately\r\n * (UI state), then REQUEST selection from the consumer — never mutate selection internally (ADR 037). */\r\n private selectTab(value: string): void {\r\n this.ctx.activeValue.set(value);\r\n this.keyboard.setActive(value);\r\n if (this.selected() === value) return; // idempotent — no redundant output\r\n this.selectedChange.emit(value);\r\n }\r\n\r\n private onTablistKeydown(event: KeyboardEvent): void {\r\n const before = this.keyboard.activeValue();\r\n this.keyboard.onKeydown(event);\r\n const after = this.keyboard.activeValue();\r\n if (after && after !== before) {\r\n this.ctx.activeValue.set(after); // roving moved (focus already on the new tab)\r\n if (this.ctx.activation() === 'automatic') this.selectTab(after);\r\n }\r\n }\r\n\r\n /** Dev-only nudge: every tab needs a panel of the same `value`, and vice-versa (aria-controls / -labelledby). */\r\n private warnMismatches(): void {\r\n const tabValues = new Set(this.tabs().map((t) => t.value()));\r\n const panelValues = new Set(this.panels().map((p) => p.value()));\r\n for (const v of tabValues) {\r\n if (!panelValues.has(v))\r\n console.warn(\r\n `[skraTabs] tab value=\"${v}\" has no matching [skraTabPanel] — its aria-controls points to a missing panel.`,\r\n );\r\n }\r\n for (const v of panelValues) {\r\n if (!tabValues.has(v))\r\n console.warn(\r\n `[skraTabs] panel value=\"${v}\" has no matching button[skraTab] — it will never be revealed.`,\r\n );\r\n }\r\n }\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n inject,\r\n} from '@angular/core';\r\n\r\nimport { SkraTabsContext } from './tabs-context';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/**\r\n * SkraTablist — the `role=\"tablist\"` container, a Component on the consumer's `<div skraTablist>`\r\n * (ADR 040, `template: '<ng-content>'` so the projected `button[skraTab]` children render). It carries\r\n * the rail styling and forwards its `keydown` to the coordinator's roving keyboard (`SkraTabsKeyboard`)\r\n * via the `SkraTabsContext` bus. Name it for AT with consumer `aria-label`/`aria-labelledby` (ADR 033).\r\n */\r\n@Component({\r\n selector: '[skraTablist]',\r\n standalone: true,\r\n exportAs: 'skraTablist',\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './tablist.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n role: 'tablist',\r\n 'aria-orientation': 'horizontal',\r\n '(keydown)': 'onKeydown($event)',\r\n },\r\n})\r\nexport class SkraTablist {\r\n private readonly ctx = inject(SkraTabsContext, { optional: true });\r\n\r\n constructor() {\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n if (!this.ctx) {\r\n console.warn(\r\n '[skraTablist] has no [skraTabs] ancestor — its tabs cannot be keyboard-navigated. ' +\r\n 'Wrap the tablist + panels in <element skraTabs>.',\r\n );\r\n }\r\n }\r\n }\r\n\r\n protected onKeydown(event: KeyboardEvent): void {\r\n this.ctx?.handleKeydown(event);\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ViewEncapsulation, ChangeDetectionStrategy, Component, Directive } from '@angular/core';
|
|
2
|
+
import { inject, ElementRef, effect, ViewEncapsulation, ChangeDetectionStrategy, Component, Directive } from '@angular/core';
|
|
3
3
|
import { SkraFieldContext } from '@skra/ui/field';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -21,28 +21,54 @@ import { SkraFieldContext } from '@skra/ui/field';
|
|
|
21
21
|
* <textarea skraTextarea skraAutoResize rows="3"></textarea>
|
|
22
22
|
* </skra-field>
|
|
23
23
|
*
|
|
24
|
+
* <!-- standalone: native implicit label (wrapping) — no id/for needed -->
|
|
25
|
+
* <label>Notes <textarea skraTextarea></textarea></label>
|
|
26
|
+
*
|
|
24
27
|
* Native `rows` / `cols` remain the consumer-facing sizing primitives — Forge
|
|
25
28
|
* does not duplicate them as Angular inputs (boundary #9 native-attr-first).
|
|
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 and the consumer owns every attribute, including the accessible name.
|
|
26
33
|
*/
|
|
27
34
|
class SkraTextarea {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
el = inject(ElementRef);
|
|
36
|
+
context = inject(SkraFieldContext, { optional: true });
|
|
37
|
+
constructor() {
|
|
38
|
+
const el = this.el.nativeElement;
|
|
39
|
+
// Field-cascaded native properties — only bind when context is present so
|
|
40
|
+
// standalone consumers retain full control of their static attributes.
|
|
41
|
+
// Mirrors SkraInput / SkraCheckbox.
|
|
42
|
+
if (this.context) {
|
|
43
|
+
const ctx = this.context;
|
|
44
|
+
effect(() => {
|
|
45
|
+
el.id = ctx.fieldId();
|
|
46
|
+
});
|
|
47
|
+
effect(() => {
|
|
48
|
+
el.disabled = ctx.isDisabled();
|
|
49
|
+
});
|
|
50
|
+
effect(() => {
|
|
51
|
+
el.readOnly = ctx.isReadonly();
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTextarea, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
56
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.1", type: SkraTextarea, isStandalone: true, selector: "textarea[skraTextarea]", host: { properties: { "attr.aria-describedby": "context?.describedByIds() ?? null", "attr.aria-invalid": "context?.hasError() ? \"true\" : null", "attr.aria-required": "context?.isRequired() ? \"true\" : null" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{background:var(--skra-comp-field-background);color:var(--skra-comp-field-foreground);border-color:var(--skra-comp-field-border-color);border-width:var(--skra-comp-field-border-width);border-style:var(--skra-comp-field-border-style);border-radius:var(--skra-comp-field-radius);padding-block:var(--skra-comp-field-padding-block);padding-inline:var(--skra-comp-field-padding-inline);box-shadow:var(--skra-comp-field-shadow);font:inherit;outline:none;transition:background-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),border-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),box-shadow var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing)}:host(:hover:not(:disabled):not([readonly])){background:var(--skra-comp-field-background-hover);border-color:var(--skra-comp-field-border-color-hover)}:host(:focus-visible){border-color:var(--skra-comp-field-focus-ring-color);box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-focus-ring-color)}:host(:disabled){cursor:not-allowed;opacity:var(--skra-sys-opacity-disabled)}:host([readonly]){cursor:default}:host([aria-invalid=true]){border-color:var(--skra-comp-field-error-color)}:host([aria-invalid=true]:focus-visible){box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-error-color)}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
31
57
|
}
|
|
32
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
58
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraTextarea, decorators: [{
|
|
33
59
|
type: Component,
|
|
34
60
|
args: [{ selector: 'textarea[skraTextarea]', standalone: true, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
|
|
35
|
-
|
|
36
|
-
'[attr.aria-describedby]': 'context
|
|
37
|
-
'[attr.aria-invalid]': 'context
|
|
38
|
-
'[attr.aria-required]': 'context
|
|
61
|
+
// ARIA relationships — Skra-owned, present only while a field cascades them.
|
|
62
|
+
'[attr.aria-describedby]': 'context?.describedByIds() ?? null',
|
|
63
|
+
'[attr.aria-invalid]': 'context?.hasError() ? "true" : null',
|
|
64
|
+
'[attr.aria-required]': 'context?.isRequired() ? "true" : null',
|
|
39
65
|
// Availability — native attrs only (native-attr-first, boundary #9).
|
|
40
66
|
// <textarea> supports native `readonly`/`disabled`; NO `aria-readonly`/
|
|
41
67
|
// `aria-disabled` duplicate. Readonly styling keys off `:read-only`.
|
|
42
|
-
|
|
43
|
-
|
|
68
|
+
// Driven imperatively below, NOT as host bindings — see the constructor
|
|
69
|
+
// note on standalone attribute ownership.
|
|
44
70
|
}, styles: [":host{background:var(--skra-comp-field-background);color:var(--skra-comp-field-foreground);border-color:var(--skra-comp-field-border-color);border-width:var(--skra-comp-field-border-width);border-style:var(--skra-comp-field-border-style);border-radius:var(--skra-comp-field-radius);padding-block:var(--skra-comp-field-padding-block);padding-inline:var(--skra-comp-field-padding-inline);box-shadow:var(--skra-comp-field-shadow);font:inherit;outline:none;transition:background-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),border-color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing),box-shadow var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing)}:host(:hover:not(:disabled):not([readonly])){background:var(--skra-comp-field-background-hover);border-color:var(--skra-comp-field-border-color-hover)}:host(:focus-visible){border-color:var(--skra-comp-field-focus-ring-color);box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-focus-ring-color)}:host(:disabled){cursor:not-allowed;opacity:var(--skra-sys-opacity-disabled)}:host([readonly]){cursor:default}:host([aria-invalid=true]){border-color:var(--skra-comp-field-error-color)}:host([aria-invalid=true]:focus-visible){box-shadow:0 0 0 var(--skra-comp-field-focus-ring-width) var(--skra-comp-field-error-color)}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"] }]
|
|
45
|
-
}] });
|
|
71
|
+
}], ctorParameters: () => [] });
|
|
46
72
|
|
|
47
73
|
/**
|
|
48
74
|
* Marker directive enabling content-driven sizing on a native form control via
|
|
@@ -62,10 +88,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
62
88
|
* input grows in inline-size with content width.
|
|
63
89
|
*/
|
|
64
90
|
class SkraAutoResizeDirective {
|
|
65
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
66
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
91
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraAutoResizeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
92
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.1", type: SkraAutoResizeDirective, isStandalone: true, selector: "textarea[skraAutoResize], input[skraAutoResize]", ngImport: i0 });
|
|
67
93
|
}
|
|
68
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
94
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraAutoResizeDirective, decorators: [{
|
|
69
95
|
type: Directive,
|
|
70
96
|
args: [{
|
|
71
97
|
selector: 'textarea[skraAutoResize], input[skraAutoResize]',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skra-ui-textarea.mjs","sources":["../../../../libs/ui/textarea/src/lib/textarea/textarea.ts","../../../../libs/ui/textarea/src/lib/auto-resize/auto-resize.directive.ts","../../../../libs/ui/textarea/src/skra-ui-textarea.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n inject,\n} from '@angular/core';\nimport { SkraFieldContext } from '@skra/ui/field';\n\n/**\n * `textarea[skraTextarea]` — multiline text atom. Per ADR 040 this is a\n * Component-on-a-native-host carrying its own host-scoped CSS (`textarea.scss`)\n * via Emulated encapsulation, replacing the ADR 038 slice branch.\n *\n * `<textarea>` is a content-bearing host (its value is its text content), so the\n * template MUST be `<ng-content>` — `template: ''` would discard the consumer's\n * initial text. See ADR 040 §2.\n *\n * Sibling atom to SkraInput — split per atom-granularity rule (memory\n * `feedback_atom_granularity.md`): textarea has capabilities `<input>` does not\n * (multi-line content, native `rows` / `cols`, autosize composition via the\n * sibling `[skraAutoResize]` directive).\n *\n * <skra-field>\n * <label skraLabelFor>Bio</label>\n * <textarea skraTextarea skraAutoResize rows=\"3\"></textarea>\n * </skra-field>\n *\n * Native `rows` / `cols` remain the consumer-facing sizing primitives — Forge\n * does not duplicate them as Angular inputs (boundary #9 native-attr-first).\n */\n@Component({\n selector: 'textarea[skraTextarea]',\n standalone: true,\n // Content-bearing host — see ADR 040 §2.\n template: '<ng-content></ng-content>',\n styleUrl: './textarea.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n
|
|
1
|
+
{"version":3,"file":"skra-ui-textarea.mjs","sources":["../../../../libs/ui/textarea/src/lib/textarea/textarea.ts","../../../../libs/ui/textarea/src/lib/auto-resize/auto-resize.directive.ts","../../../../libs/ui/textarea/src/skra-ui-textarea.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n effect,\n inject,\n} from '@angular/core';\nimport { SkraFieldContext } from '@skra/ui/field';\n\n/**\n * `textarea[skraTextarea]` — multiline text atom. Per ADR 040 this is a\n * Component-on-a-native-host carrying its own host-scoped CSS (`textarea.scss`)\n * via Emulated encapsulation, replacing the ADR 038 slice branch.\n *\n * `<textarea>` is a content-bearing host (its value is its text content), so the\n * template MUST be `<ng-content>` — `template: ''` would discard the consumer's\n * initial text. See ADR 040 §2.\n *\n * Sibling atom to SkraInput — split per atom-granularity rule (memory\n * `feedback_atom_granularity.md`): textarea has capabilities `<input>` does not\n * (multi-line content, native `rows` / `cols`, autosize composition via the\n * sibling `[skraAutoResize]` directive).\n *\n * <skra-field>\n * <label skraLabelFor>Bio</label>\n * <textarea skraTextarea skraAutoResize rows=\"3\"></textarea>\n * </skra-field>\n *\n * <!-- standalone: native implicit label (wrapping) — no id/for needed -->\n * <label>Notes <textarea skraTextarea></textarea></label>\n *\n * Native `rows` / `cols` remain the consumer-facing sizing primitives — Forge\n * does not duplicate them as Angular inputs (boundary #9 native-attr-first).\n *\n * `SkraFieldContext` is injected `{ optional: true }` (ADR 013 §3.7) — same\n * posture as SkraInput / SkraCheckbox. Standalone, the atom renders the skin\n * only and the consumer owns every attribute, including the accessible name.\n */\n@Component({\n selector: 'textarea[skraTextarea]',\n standalone: true,\n // Content-bearing host — see ADR 040 §2.\n template: '<ng-content></ng-content>',\n styleUrl: './textarea.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n // ARIA relationships — Skra-owned, present only while a field cascades them.\n '[attr.aria-describedby]': 'context?.describedByIds() ?? null',\n '[attr.aria-invalid]': 'context?.hasError() ? \"true\" : null',\n '[attr.aria-required]': 'context?.isRequired() ? \"true\" : null',\n // Availability — native attrs only (native-attr-first, boundary #9).\n // <textarea> supports native `readonly`/`disabled`; NO `aria-readonly`/\n // `aria-disabled` duplicate. Readonly styling keys off `:read-only`.\n // Driven imperatively below, NOT as host bindings — see the constructor\n // note on standalone attribute ownership.\n },\n})\nexport class SkraTextarea {\n private readonly el = inject<ElementRef<HTMLTextAreaElement>>(ElementRef);\n readonly context = inject(SkraFieldContext, { optional: true });\n\n constructor() {\n const el = this.el.nativeElement;\n\n // Field-cascaded native properties — only bind when context is present so\n // standalone consumers retain full control of their static attributes.\n // Mirrors SkraInput / SkraCheckbox.\n if (this.context) {\n const ctx = this.context;\n effect(() => {\n el.id = ctx.fieldId();\n });\n effect(() => {\n el.disabled = ctx.isDisabled();\n });\n effect(() => {\n el.readOnly = ctx.isReadonly();\n });\n }\n }\n}\n","import { Directive } from '@angular/core';\r\n\r\n/**\r\n * Marker directive enabling content-driven sizing on a native form control via\r\n * the modern CSS `field-sizing: content` declaration shipped from the skin's\r\n * global utilities layer (`tokens/skins/skra/utilities.scss`).\r\n *\r\n * <textarea skraTextarea skraAutoResize rows=\"2\"></textarea>\r\n * <input skraInput skraAutoResize type=\"text\" />\r\n *\r\n * Composition-over-configuration: the host opts in by adding the attribute,\r\n * not by toggling a boolean Angular input. The directive has no host bindings,\r\n * no DI, and no template — its sole job is to make the selector available at\r\n * Angular's compilation stage; CSS does the rest.\r\n *\r\n * Wide selector (textarea + input) reflects that `field-sizing: content` is a\r\n * native CSS capability for both: textarea grows in block-size with rows,\r\n * input grows in inline-size with content width.\r\n */\r\n@Directive({\r\n selector: 'textarea[skraAutoResize], input[skraAutoResize]',\r\n standalone: true,\r\n})\r\nexport class SkraAutoResizeDirective {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;MAqBU,YAAY,CAAA;AACN,IAAA,EAAE,GAAG,MAAM,CAAkC,UAAU,CAAC;IAChE,OAAO,GAAG,MAAM,CAAC,gBAAgB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAE/D,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa;;;;AAKhC,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO;YACxB,MAAM,CAAC,MAAK;AACV,gBAAA,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE;AACvB,YAAA,CAAC,CAAC;YACF,MAAM,CAAC,MAAK;AACV,gBAAA,EAAE,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,EAAE;AAChC,YAAA,CAAC,CAAC;YACF,MAAM,CAAC,MAAK;AACV,gBAAA,EAAE,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,EAAE;AAChC,YAAA,CAAC,CAAC;QACJ;IACF;uGAtBW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAY,ySAhBb,2BAA2B,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,i/CAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAgB1B,YAAY,EAAA,UAAA,EAAA,CAAA;kBApBxB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wBAAwB,EAAA,UAAA,EACtB,IAAI,EAAA,QAAA,EAEN,2BAA2B,EAAA,eAAA,EAEpB,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;AAEJ,wBAAA,yBAAyB,EAAE,mCAAmC;AAC9D,wBAAA,qBAAqB,EAAE,qCAAqC;AAC5D,wBAAA,sBAAsB,EAAE,uCAAuC;;;;;;AAMhE,qBAAA,EAAA,MAAA,EAAA,CAAA,i/CAAA,CAAA,EAAA;;;ACvDH;;;;;;;;;;;;;;;;AAgBG;MAKU,uBAAuB,CAAA;uGAAvB,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAvB,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iDAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAvB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAJnC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iDAAiD;AAC3D,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA;;;ACtBD;;AAEG;;;;"}
|
|
@@ -9,10 +9,10 @@ import { Directive, InjectionToken, input, booleanAttribute, output, contentChil
|
|
|
9
9
|
* `[skra-alert-icon]` / `[skra-badge-icon]`.
|
|
10
10
|
*/
|
|
11
11
|
class SkraToastIcon {
|
|
12
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
13
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
12
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraToastIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
13
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.1", type: SkraToastIcon, isStandalone: true, selector: "[skra-toast-icon]", ngImport: i0 });
|
|
14
14
|
}
|
|
15
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
15
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraToastIcon, decorators: [{
|
|
16
16
|
type: Directive,
|
|
17
17
|
args: [{
|
|
18
18
|
selector: '[skra-toast-icon]',
|
|
@@ -39,19 +39,26 @@ const SKRA_TOAST_ANNOUNCER = new InjectionToken('SKRA_TOAST_ANNOUNCER');
|
|
|
39
39
|
*/
|
|
40
40
|
class SkraToast {
|
|
41
41
|
// --- Variant Surface (ADR 035) ---
|
|
42
|
-
intent = input('neutral',
|
|
43
|
-
|
|
42
|
+
intent = input('neutral', /* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [{ debugName: "intent" }] : /* istanbul ignore next */ []));
|
|
44
|
+
emphasis = input('medium', /* @ts-ignore */
|
|
45
|
+
...(ngDevMode ? [{ debugName: "emphasis" }] : /* istanbul ignore next */ []));
|
|
44
46
|
// --- Announcement (ADR 0052 §7) ---
|
|
45
|
-
live = input('polite',
|
|
47
|
+
live = input('polite', /* @ts-ignore */
|
|
48
|
+
...(ngDevMode ? [{ debugName: "live" }] : /* istanbul ignore next */ []));
|
|
46
49
|
// --- Auto-dismiss + dismissal ---
|
|
47
|
-
duration = input(5000,
|
|
50
|
+
duration = input(5000, /* @ts-ignore */
|
|
51
|
+
...(ngDevMode ? [{ debugName: "duration" }] : /* istanbul ignore next */ []));
|
|
48
52
|
dismissible = input(false, { ...(ngDevMode ? { debugName: "dismissible" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
49
53
|
dismissed = output();
|
|
50
54
|
// --- Smart Slots v2.0 (ADR 020) ---
|
|
51
|
-
iconSlot = contentChild(SkraToastIcon,
|
|
52
|
-
|
|
55
|
+
iconSlot = contentChild(SkraToastIcon, /* @ts-ignore */
|
|
56
|
+
...(ngDevMode ? [{ debugName: "iconSlot" }] : /* istanbul ignore next */ []));
|
|
57
|
+
hasIcon = computed(() => !!this.iconSlot(), /* @ts-ignore */
|
|
58
|
+
...(ngDevMode ? [{ debugName: "hasIcon" }] : /* istanbul ignore next */ []));
|
|
53
59
|
/** The message column — its text is the announcement (excludes the icon + sr-only close label). */
|
|
54
|
-
contentRef = viewChild.required('content'
|
|
60
|
+
contentRef = viewChild.required('content', /* @ts-ignore */
|
|
61
|
+
...(ngDevMode ? [{ debugName: "contentRef" }] : /* istanbul ignore next */ []));
|
|
55
62
|
announcer = inject(SKRA_TOAST_ANNOUNCER, {
|
|
56
63
|
optional: true,
|
|
57
64
|
});
|
|
@@ -106,10 +113,10 @@ class SkraToast {
|
|
|
106
113
|
this.timerId = null;
|
|
107
114
|
}
|
|
108
115
|
}
|
|
109
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
110
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
116
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraToast, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
117
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: SkraToast, isStandalone: true, selector: "skra-toast", inputs: { intent: { classPropertyName: "intent", publicName: "intent", isSignal: true, isRequired: false, transformFunction: null }, emphasis: { classPropertyName: "emphasis", publicName: "emphasis", isSignal: true, isRequired: false, transformFunction: null }, live: { classPropertyName: "live", publicName: "live", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismissed: "dismissed" }, host: { listeners: { "mouseenter": "pause()", "mouseleave": "resume()", "focusin": "pause()", "focusout": "resume()" }, properties: { "attr.data-skra-intent": "intent()", "attr.data-skra-emphasis": "emphasis()", "attr.data-skra-has-icon": "hasIcon() ? \"\" : null" } }, queries: [{ propertyName: "iconSlot", first: true, predicate: SkraToastIcon, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (hasIcon()) {\r\n<span class=\"skra-toast-icon\">\r\n <ng-content select=\"[skra-toast-icon]\"></ng-content>\r\n</span>\r\n}\r\n\r\n<div class=\"skra-toast-content\" #content>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n@if (dismissible()) {\r\n<button type=\"button\" class=\"skra-toast-dismiss\" (click)=\"onDismiss()\">\r\n <span class=\"skra-toast-dismiss-glyph\" aria-hidden=\"true\">×</span>\r\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\r\n</button>\r\n}\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:flex-start;box-sizing:border-box;margin:0;gap:var(--skra-comp-toast-icon-gap);font-family:var(--skra-sys-typography-role-body-medium-font-family);font-size:var(--skra-sys-typography-role-body-medium-font-size);font-weight:var(--skra-sys-typography-role-body-medium-font-weight);line-height:var(--skra-sys-typography-role-body-medium-line-height);letter-spacing:var(--skra-sys-typography-role-body-medium-letter-spacing);background:var(--skra-comp-toast-background);color:var(--skra-comp-toast-foreground);border-color:var(--skra-comp-toast-border-color);border-width:var(--skra-comp-toast-border-width);border-style:var(--skra-comp-toast-border-style);border-radius:var(--skra-comp-toast-radius);padding-block:var(--skra-comp-toast-padding-block);padding-inline:var(--skra-comp-toast-padding-inline);box-shadow:var(--skra-comp-toast-shadow);opacity:1;transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}@starting-style{:host{opacity:0}}:host([data-skra-emphasis=high]){--skra-comp-toast-border-width: 0}:host([data-skra-intent=neutral][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-high, var(--skra-sys-color-neutral-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-high, var(--skra-sys-color-neutral-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-high, transparent )}:host([data-skra-intent=neutral][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-medium, var(--skra-sys-color-neutral-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-medium, var(--skra-sys-color-neutral-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-medium, var(--skra-sys-color-neutral-border) )}:host([data-skra-intent=info][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-high, var(--skra-sys-color-info-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-high, var(--skra-sys-color-info-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-high, transparent )}:host([data-skra-intent=info][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-medium, var(--skra-sys-color-info-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-medium, var(--skra-sys-color-info-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-medium, var(--skra-sys-color-info-border) )}:host([data-skra-intent=success][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-high, var(--skra-sys-color-success-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-high, var(--skra-sys-color-success-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-high, transparent )}:host([data-skra-intent=success][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-medium, var(--skra-sys-color-success-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-medium, var(--skra-sys-color-success-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-medium, var(--skra-sys-color-success-border) )}:host([data-skra-intent=warning][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-high, var(--skra-sys-color-warning-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-high, var(--skra-sys-color-warning-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-high, transparent )}:host([data-skra-intent=warning][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-medium, var(--skra-sys-color-warning-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-medium, var(--skra-sys-color-warning-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-medium, var(--skra-sys-color-warning-border) )}:host([data-skra-intent=danger][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-high, var(--skra-sys-color-danger-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-high, var(--skra-sys-color-danger-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-high, transparent )}:host([data-skra-intent=danger][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-medium, var(--skra-sys-color-danger-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-medium, var(--skra-sys-color-danger-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-medium, var(--skra-sys-color-danger-border) )}.skra-toast-icon{display:inline-flex;flex-shrink:0;align-items:center;block-size:1lh;--skra-comp-icon-size: var(--skra-comp-toast-icon-size)}.skra-toast-content{flex:1 1 auto;min-inline-size:0}.skra-toast-dismiss{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--skra-comp-toast-dismiss-size);block-size:var(--skra-comp-toast-dismiss-size);margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;border-radius:var(--skra-comp-toast-radius);transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}.skra-toast-dismiss:hover{opacity:.7}.skra-toast-dismiss:focus-visible{outline-style:solid;outline-color:var(--skra-comp-toast-focus-ring-color);outline-width:var(--skra-comp-toast-focus-ring-width);outline-offset:2px}.skra-toast-dismiss-glyph{font-size:1.25em;line-height:1}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}.skra-toast-dismiss{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
111
118
|
}
|
|
112
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
119
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraToast, decorators: [{
|
|
113
120
|
type: Component,
|
|
114
121
|
args: [{ selector: 'skra-toast', standalone: true, imports: [SkraToastIcon], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
|
|
115
122
|
// Variant Surface reflection (ADR 035 §3.5; ADR 021 — never [style.--var])
|
|
@@ -123,7 +130,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
123
130
|
'(mouseleave)': 'resume()',
|
|
124
131
|
'(focusin)': 'pause()',
|
|
125
132
|
'(focusout)': 'resume()',
|
|
126
|
-
}, template: "@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\">×</span>\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\n</button>\n}\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:flex-start;box-sizing:border-box;margin:0;gap:var(--skra-comp-toast-icon-gap);font-family:var(--skra-sys-typography-role-body-medium-font-family);font-size:var(--skra-sys-typography-role-body-medium-font-size);font-weight:var(--skra-sys-typography-role-body-medium-font-weight);line-height:var(--skra-sys-typography-role-body-medium-line-height);letter-spacing:var(--skra-sys-typography-role-body-medium-letter-spacing);background:var(--skra-comp-toast-background);color:var(--skra-comp-toast-foreground);border-color:var(--skra-comp-toast-border-color);border-width:var(--skra-comp-toast-border-width);border-style:var(--skra-comp-toast-border-style);border-radius:var(--skra-comp-toast-radius);padding-block:var(--skra-comp-toast-padding-block);padding-inline:var(--skra-comp-toast-padding-inline);box-shadow:var(--skra-comp-toast-shadow);opacity:1;transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}@starting-style{:host{opacity:0}}:host([data-skra-emphasis=high]){--skra-comp-toast-border-width: 0}:host([data-skra-intent=neutral][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-high, var(--skra-sys-color-neutral-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-high, var(--skra-sys-color-neutral-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-high, transparent )}:host([data-skra-intent=neutral][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-medium, var(--skra-sys-color-neutral-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-medium, var(--skra-sys-color-neutral-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-medium, var(--skra-sys-color-neutral-border) )}:host([data-skra-intent=info][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-high, var(--skra-sys-color-info-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-high, var(--skra-sys-color-info-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-high, transparent )}:host([data-skra-intent=info][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-medium, var(--skra-sys-color-info-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-medium, var(--skra-sys-color-info-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-medium, var(--skra-sys-color-info-border) )}:host([data-skra-intent=success][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-high, var(--skra-sys-color-success-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-high, var(--skra-sys-color-success-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-high, transparent )}:host([data-skra-intent=success][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-medium, var(--skra-sys-color-success-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-medium, var(--skra-sys-color-success-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-medium, var(--skra-sys-color-success-border) )}:host([data-skra-intent=warning][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-high, var(--skra-sys-color-warning-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-high, var(--skra-sys-color-warning-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-high, transparent )}:host([data-skra-intent=warning][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-medium, var(--skra-sys-color-warning-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-medium, var(--skra-sys-color-warning-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-medium, var(--skra-sys-color-warning-border) )}:host([data-skra-intent=danger][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-high, var(--skra-sys-color-danger-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-high, var(--skra-sys-color-danger-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-high, transparent )}:host([data-skra-intent=danger][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-medium, var(--skra-sys-color-danger-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-medium, var(--skra-sys-color-danger-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-medium, var(--skra-sys-color-danger-border) )}.skra-toast-icon{display:inline-flex;flex-shrink:0;align-items:center;block-size:1lh;--skra-comp-icon-size: var(--skra-comp-toast-icon-size)}.skra-toast-content{flex:1 1 auto;min-inline-size:0}.skra-toast-dismiss{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--skra-comp-toast-dismiss-size);block-size:var(--skra-comp-toast-dismiss-size);margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;border-radius:var(--skra-comp-toast-radius);transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}.skra-toast-dismiss:hover{opacity:.7}.skra-toast-dismiss:focus-visible{outline-style:solid;outline-color:var(--skra-comp-toast-focus-ring-color);outline-width:var(--skra-comp-toast-focus-ring-width);outline-offset:2px}.skra-toast-dismiss-glyph{font-size:1.25em;line-height:1}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}.skra-toast-dismiss{transition:none}}\n"] }]
|
|
133
|
+
}, template: "@if (hasIcon()) {\r\n<span class=\"skra-toast-icon\">\r\n <ng-content select=\"[skra-toast-icon]\"></ng-content>\r\n</span>\r\n}\r\n\r\n<div class=\"skra-toast-content\" #content>\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n@if (dismissible()) {\r\n<button type=\"button\" class=\"skra-toast-dismiss\" (click)=\"onDismiss()\">\r\n <span class=\"skra-toast-dismiss-glyph\" aria-hidden=\"true\">×</span>\r\n <ng-content select=\"[skra-toast-close-label]\"></ng-content>\r\n</button>\r\n}\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:flex-start;box-sizing:border-box;margin:0;gap:var(--skra-comp-toast-icon-gap);font-family:var(--skra-sys-typography-role-body-medium-font-family);font-size:var(--skra-sys-typography-role-body-medium-font-size);font-weight:var(--skra-sys-typography-role-body-medium-font-weight);line-height:var(--skra-sys-typography-role-body-medium-line-height);letter-spacing:var(--skra-sys-typography-role-body-medium-letter-spacing);background:var(--skra-comp-toast-background);color:var(--skra-comp-toast-foreground);border-color:var(--skra-comp-toast-border-color);border-width:var(--skra-comp-toast-border-width);border-style:var(--skra-comp-toast-border-style);border-radius:var(--skra-comp-toast-radius);padding-block:var(--skra-comp-toast-padding-block);padding-inline:var(--skra-comp-toast-padding-inline);box-shadow:var(--skra-comp-toast-shadow);opacity:1;transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}@starting-style{:host{opacity:0}}:host([data-skra-emphasis=high]){--skra-comp-toast-border-width: 0}:host([data-skra-intent=neutral][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-high, var(--skra-sys-color-neutral-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-high, var(--skra-sys-color-neutral-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-high, transparent )}:host([data-skra-intent=neutral][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-neutral-medium, var(--skra-sys-color-neutral-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-neutral-medium, var(--skra-sys-color-neutral-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-neutral-medium, var(--skra-sys-color-neutral-border) )}:host([data-skra-intent=info][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-high, var(--skra-sys-color-info-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-high, var(--skra-sys-color-info-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-high, transparent )}:host([data-skra-intent=info][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-info-medium, var(--skra-sys-color-info-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-info-medium, var(--skra-sys-color-info-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-info-medium, var(--skra-sys-color-info-border) )}:host([data-skra-intent=success][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-high, var(--skra-sys-color-success-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-high, var(--skra-sys-color-success-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-high, transparent )}:host([data-skra-intent=success][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-success-medium, var(--skra-sys-color-success-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-success-medium, var(--skra-sys-color-success-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-success-medium, var(--skra-sys-color-success-border) )}:host([data-skra-intent=warning][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-high, var(--skra-sys-color-warning-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-high, var(--skra-sys-color-warning-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-high, transparent )}:host([data-skra-intent=warning][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-warning-medium, var(--skra-sys-color-warning-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-warning-medium, var(--skra-sys-color-warning-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-warning-medium, var(--skra-sys-color-warning-border) )}:host([data-skra-intent=danger][data-skra-emphasis=high]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-high, var(--skra-sys-color-danger-base) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-high, var(--skra-sys-color-danger-contrast) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-high, transparent )}:host([data-skra-intent=danger][data-skra-emphasis=medium]){--skra-comp-toast-background: var( --skra-comp-toast-background-danger-medium, var(--skra-sys-color-danger-soft) );--skra-comp-toast-foreground: var( --skra-comp-toast-foreground-danger-medium, var(--skra-sys-color-danger-strong) );--skra-comp-toast-border-color: var( --skra-comp-toast-border-color-danger-medium, var(--skra-sys-color-danger-border) )}.skra-toast-icon{display:inline-flex;flex-shrink:0;align-items:center;block-size:1lh;--skra-comp-icon-size: var(--skra-comp-toast-icon-size)}.skra-toast-content{flex:1 1 auto;min-inline-size:0}.skra-toast-dismiss{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--skra-comp-toast-dismiss-size);block-size:var(--skra-comp-toast-dismiss-size);margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;border-radius:var(--skra-comp-toast-radius);transition:opacity var(--skra-comp-toast-motion-duration) var(--skra-comp-toast-motion-easing)}.skra-toast-dismiss:hover{opacity:.7}.skra-toast-dismiss:focus-visible{outline-style:solid;outline-color:var(--skra-comp-toast-focus-ring-color);outline-width:var(--skra-comp-toast-focus-ring-width);outline-offset:2px}.skra-toast-dismiss-glyph{font-size:1.25em;line-height:1}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}.skra-toast-dismiss{transition:none}}\n"] }]
|
|
127
134
|
}], ctorParameters: () => [], propDecorators: { intent: [{ type: i0.Input, args: [{ isSignal: true, alias: "intent", required: false }] }], emphasis: [{ type: i0.Input, args: [{ isSignal: true, alias: "emphasis", required: false }] }], live: [{ type: i0.Input, args: [{ isSignal: true, alias: "live", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], dismissed: [{ type: i0.Output, args: ["dismissed"] }], iconSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SkraToastIcon), { isSignal: true }] }], contentRef: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }] } });
|
|
128
135
|
|
|
129
136
|
/**
|
|
@@ -143,12 +150,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
143
150
|
* paints above it. Paint-only — never moves focus, never disturbs the dialog. Zero z-index.
|
|
144
151
|
*/
|
|
145
152
|
class SkraToastRegion {
|
|
146
|
-
placement = input('block-end inline-end',
|
|
153
|
+
placement = input('block-end inline-end', /* @ts-ignore */
|
|
154
|
+
...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
|
|
147
155
|
/** The two persistent role-only announcer buffers (ADR 0052 §7). */
|
|
148
|
-
politeMsg = signal('',
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
156
|
+
politeMsg = signal('', /* @ts-ignore */
|
|
157
|
+
...(ngDevMode ? [{ debugName: "politeMsg" }] : /* istanbul ignore next */ []));
|
|
158
|
+
assertiveMsg = signal('', /* @ts-ignore */
|
|
159
|
+
...(ngDevMode ? [{ debugName: "assertiveMsg" }] : /* istanbul ignore next */ []));
|
|
160
|
+
toasts = contentChildren(SkraToast, /* @ts-ignore */
|
|
161
|
+
...(ngDevMode ? [{ debugName: "toasts" }] : /* istanbul ignore next */ []));
|
|
162
|
+
stackEl = viewChild.required('stack', /* @ts-ignore */
|
|
163
|
+
...(ngDevMode ? [{ debugName: "stackEl" }] : /* istanbul ignore next */ []));
|
|
152
164
|
/** Tracked locally — jsdom/SSR have no `:popover-open`; never read it back. */
|
|
153
165
|
shown = false;
|
|
154
166
|
prevCount = 0;
|
|
@@ -190,14 +202,14 @@ class SkraToastRegion {
|
|
|
190
202
|
target.set('');
|
|
191
203
|
requestAnimationFrame(() => requestAnimationFrame(() => target.set(text)));
|
|
192
204
|
}
|
|
193
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
194
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "
|
|
205
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraToastRegion, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
206
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.1", type: SkraToastRegion, isStandalone: true, selector: "skra-toast-region", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-skra-placement": "placement()" } }, providers: [{ provide: SKRA_TOAST_ANNOUNCER, useExisting: SkraToastRegion }], queries: [{ propertyName: "toasts", predicate: SkraToast, isSignal: true }], viewQueries: [{ propertyName: "stackEl", first: true, predicate: ["stack"], descendants: true, isSignal: true }], ngImport: i0, template: "<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 \u00A77 \u2014 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 \u2014 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", styles: ["@charset \"UTF-8\";:host{display:contents}.skra-toast-stack{position:fixed;margin:0;inset:auto;box-sizing:border-box;flex-direction:column;gap:var(--skra-comp-toast-region-gap);inline-size:max-content;max-inline-size:var(--skra-comp-toast-region-max-inline-size);border:0;padding:0;background:transparent}.skra-toast-stack:popover-open{display:flex}:host([data-skra-placement=\"block-end inline-end\"]) .skra-toast-stack{inset-block-end:var(--skra-comp-toast-region-inset-block);inset-inline-end:var(--skra-comp-toast-region-inset-inline);flex-direction:column}:host([data-skra-placement=\"block-end inline-start\"]) .skra-toast-stack{inset-block-end:var(--skra-comp-toast-region-inset-block);inset-inline-start:var(--skra-comp-toast-region-inset-inline);flex-direction:column}:host([data-skra-placement=\"block-end center\"]) .skra-toast-stack{inset-block-end:var(--skra-comp-toast-region-inset-block);inset-inline:0;margin-inline:auto;flex-direction:column}:host([data-skra-placement=\"block-start inline-end\"]) .skra-toast-stack{inset-block-start:var(--skra-comp-toast-region-inset-block);inset-inline-end:var(--skra-comp-toast-region-inset-inline);flex-direction:column-reverse}:host([data-skra-placement=\"block-start inline-start\"]) .skra-toast-stack{inset-block-start:var(--skra-comp-toast-region-inset-block);inset-inline-start:var(--skra-comp-toast-region-inset-inline);flex-direction:column-reverse}:host([data-skra-placement=\"block-start center\"]) .skra-toast-stack{inset-block-start:var(--skra-comp-toast-region-inset-block);inset-inline:0;margin-inline:auto;flex-direction:column-reverse}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
195
207
|
}
|
|
196
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
208
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraToastRegion, decorators: [{
|
|
197
209
|
type: Component,
|
|
198
210
|
args: [{ selector: 'skra-toast-region', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
|
|
199
211
|
'[attr.data-skra-placement]': 'placement()',
|
|
200
|
-
}, providers: [{ provide: SKRA_TOAST_ANNOUNCER, useExisting: SkraToastRegion }], template: "<div class=\"skra-toast-stack\" popover=\"manual\" #stack>\n <ng-content></ng-content>\n</div>\n\n<!--\n ADR 0052 \u00A77 \u2014 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 \u2014 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", styles: ["@charset \"UTF-8\";:host{display:contents}.skra-toast-stack{position:fixed;margin:0;inset:auto;box-sizing:border-box;flex-direction:column;gap:var(--skra-comp-toast-region-gap);inline-size:max-content;max-inline-size:var(--skra-comp-toast-region-max-inline-size);border:0;padding:0;background:transparent}.skra-toast-stack:popover-open{display:flex}:host([data-skra-placement=\"block-end inline-end\"]) .skra-toast-stack{inset-block-end:var(--skra-comp-toast-region-inset-block);inset-inline-end:var(--skra-comp-toast-region-inset-inline);flex-direction:column}:host([data-skra-placement=\"block-end inline-start\"]) .skra-toast-stack{inset-block-end:var(--skra-comp-toast-region-inset-block);inset-inline-start:var(--skra-comp-toast-region-inset-inline);flex-direction:column}:host([data-skra-placement=\"block-end center\"]) .skra-toast-stack{inset-block-end:var(--skra-comp-toast-region-inset-block);inset-inline:0;margin-inline:auto;flex-direction:column}:host([data-skra-placement=\"block-start inline-end\"]) .skra-toast-stack{inset-block-start:var(--skra-comp-toast-region-inset-block);inset-inline-end:var(--skra-comp-toast-region-inset-inline);flex-direction:column-reverse}:host([data-skra-placement=\"block-start inline-start\"]) .skra-toast-stack{inset-block-start:var(--skra-comp-toast-region-inset-block);inset-inline-start:var(--skra-comp-toast-region-inset-inline);flex-direction:column-reverse}:host([data-skra-placement=\"block-start center\"]) .skra-toast-stack{inset-block-start:var(--skra-comp-toast-region-inset-block);inset-inline:0;margin-inline:auto;flex-direction:column-reverse}\n"] }]
|
|
212
|
+
}, providers: [{ provide: SKRA_TOAST_ANNOUNCER, useExisting: SkraToastRegion }], template: "<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 \u00A77 \u2014 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 \u2014 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", styles: ["@charset \"UTF-8\";:host{display:contents}.skra-toast-stack{position:fixed;margin:0;inset:auto;box-sizing:border-box;flex-direction:column;gap:var(--skra-comp-toast-region-gap);inline-size:max-content;max-inline-size:var(--skra-comp-toast-region-max-inline-size);border:0;padding:0;background:transparent}.skra-toast-stack:popover-open{display:flex}:host([data-skra-placement=\"block-end inline-end\"]) .skra-toast-stack{inset-block-end:var(--skra-comp-toast-region-inset-block);inset-inline-end:var(--skra-comp-toast-region-inset-inline);flex-direction:column}:host([data-skra-placement=\"block-end inline-start\"]) .skra-toast-stack{inset-block-end:var(--skra-comp-toast-region-inset-block);inset-inline-start:var(--skra-comp-toast-region-inset-inline);flex-direction:column}:host([data-skra-placement=\"block-end center\"]) .skra-toast-stack{inset-block-end:var(--skra-comp-toast-region-inset-block);inset-inline:0;margin-inline:auto;flex-direction:column}:host([data-skra-placement=\"block-start inline-end\"]) .skra-toast-stack{inset-block-start:var(--skra-comp-toast-region-inset-block);inset-inline-end:var(--skra-comp-toast-region-inset-inline);flex-direction:column-reverse}:host([data-skra-placement=\"block-start inline-start\"]) .skra-toast-stack{inset-block-start:var(--skra-comp-toast-region-inset-block);inset-inline-start:var(--skra-comp-toast-region-inset-inline);flex-direction:column-reverse}:host([data-skra-placement=\"block-start center\"]) .skra-toast-stack{inset-block-start:var(--skra-comp-toast-region-inset-block);inset-inline:0;margin-inline:auto;flex-direction:column-reverse}\n"] }]
|
|
201
213
|
}], ctorParameters: () => [], propDecorators: { placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], toasts: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SkraToast), { isSignal: true }] }], stackEl: [{ type: i0.ViewChild, args: ['stack', { isSignal: true }] }] } });
|
|
202
214
|
|
|
203
215
|
/**
|