@skra/ui 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +44 -34
- 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 +5 -5
- 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-datepicker.mjs","sources":["../../../../libs/ui/datepicker/src/lib/datepicker/calendar-math.ts","../../../../libs/ui/datepicker/src/lib/datepicker/calendar-keyboard.ts","../../../../libs/ui/datepicker/src/lib/datepicker/calendar-intl.ts","../../../../libs/ui/datepicker/src/lib/datepicker/datepicker.ts","../../../../libs/ui/datepicker/src/skra-ui-datepicker.ts"],"sourcesContent":["/**\r\n * calendar-math — the ONE sanctioned site for DatePicker date arithmetic (ADR 0050 §3/§6).\r\n *\r\n * Zoneless calendar-date discipline (the timezone off-by-one is the bug class this exists to prevent):\r\n * - The value is an ISO 8601 date-only string (`YYYY-MM-DD`) — NEVER materialized as a `Date`.\r\n * - `Date` is used ONLY as a UTC calendar calculator — built via `Date.UTC(...)`, read via `getUTC*`.\r\n * - `new Date(isoString)` is FORBIDDEN (date-only parses as UTC midnight → local accessors shift it).\r\n * - \"today\" uses LOCAL accessors — \"today\" is inherently local-civil.\r\n * - Month length + leap years are delegated to the platform engine, NEVER a hand-written leap rule.\r\n *\r\n * Months are **1-based** here (1=Jan … 12=Dec) to mirror the ISO string; the single 0-based conversion\r\n * happens at the `Date.UTC` call sites. Weekdays are **ISO** (1=Mon … 7=Sun) to match `firstDayOfWeek`.\r\n *\r\n * This module is the ADR 0050 §6 swap-point: a future `Temporal.PlainDate` migration touches only here.\r\n */\r\n\r\n/** A zoneless calendar date. `m` is 1-based (1=Jan … 12=Dec). */\r\nexport interface CalendarDate {\r\n readonly y: number;\r\n readonly m: number;\r\n readonly d: number;\r\n}\r\n\r\nconst ISO_DATE = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\r\n\r\n/** Zero-pad to a fixed width (no locale, no `Intl` — pure formatting). */\r\nfunction pad(n: number, width: number): string {\r\n return String(n).padStart(width, '0');\r\n}\r\n\r\n/** Days in month `m` (1-based) of year `y` — delegated to the engine (leap years handled for free). */\r\nexport function daysInMonth(y: number, m: number): number {\r\n // Date.UTC month is 0-based; passing the 1-based `m` selects the NEXT month, day 0 = last of `m`.\r\n return new Date(Date.UTC(y, m, 0)).getUTCDate();\r\n}\r\n\r\n/** ISO weekday (1=Mon … 7=Sun) of an arbitrary {y,m,d}, via the UTC calculator. */\r\nexport function isoWeekday(y: number, m: number, d: number): number {\r\n const jsDay = new Date(Date.UTC(y, m - 1, d)).getUTCDay(); // 0=Sun … 6=Sat\r\n return ((jsDay + 6) % 7) + 1; // → 1=Mon … 7=Sun\r\n}\r\n\r\n/** Strict `YYYY-MM-DD` parse with real calendar validation. Returns `null` for anything invalid. */\r\nexport function parseIso(iso: string): CalendarDate | null {\r\n const match = ISO_DATE.exec(iso);\r\n if (!match) return null;\r\n const y = Number(match[1]);\r\n const m = Number(match[2]);\r\n const d = Number(match[3]);\r\n if (m < 1 || m > 12) return null;\r\n if (d < 1 || d > daysInMonth(y, m)) return null; // rejects 2026-02-30, 2026-04-31, etc.\r\n return { y, m, d };\r\n}\r\n\r\n/** `true` iff `iso` is a strictly valid `YYYY-MM-DD` calendar date. */\r\nexport function isValidIso(iso: string): boolean {\r\n return parseIso(iso) !== null;\r\n}\r\n\r\n/** Serialize a calendar date to `YYYY-MM-DD`. */\r\nexport function toIso({ y, m, d }: CalendarDate): string {\r\n return `${pad(y, 4)}-${pad(m, 2)}-${pad(d, 2)}`;\r\n}\r\n\r\n/**\r\n * Build a UTC `Date` from an ISO string — the ONLY sanctioned `Date`-from-value site (used by\r\n * `calendar-intl` to feed `Intl.DateTimeFormat`, which MUST also pass `timeZone:'UTC'`). Returns the\r\n * value as a UTC instant; callers MUST read it back via UTC accessors / a UTC-zoned formatter ONLY.\r\n */\r\nexport function toUtcDate(iso: string): Date | null {\r\n const date = parseIso(iso);\r\n if (!date) return null;\r\n return new Date(Date.UTC(date.y, date.m - 1, date.d));\r\n}\r\n\r\n/** Today's LOCAL calendar date as ISO (local accessors — \"today\" is local-civil, ADR 0050 §3). */\r\nexport function today(): string {\r\n const now = new Date();\r\n return toIso({\r\n y: now.getFullYear(),\r\n m: now.getMonth() + 1,\r\n d: now.getDate(),\r\n });\r\n}\r\n\r\n/** Add `n` days (may be negative); crosses month/year boundaries via the UTC engine. */\r\nexport function addDays(iso: string, n: number): string {\r\n const date = parseIso(iso);\r\n if (!date) return iso;\r\n const dt = new Date(Date.UTC(date.y, date.m - 1, date.d));\r\n dt.setUTCDate(dt.getUTCDate() + n);\r\n return toIso({\r\n y: dt.getUTCFullYear(),\r\n m: dt.getUTCMonth() + 1,\r\n d: dt.getUTCDate(),\r\n });\r\n}\r\n\r\n/**\r\n * Add `n` months (may be negative), preserving day-of-month CLAMPED to the target month length\r\n * (ADR 0050 §4): Jan 31 + 1 month → Feb 28/29, never Mar 3.\r\n */\r\nexport function addMonthsClamped(iso: string, n: number): string {\r\n const date = parseIso(iso);\r\n if (!date) return iso;\r\n const total = date.y * 12 + (date.m - 1) + n;\r\n const y = Math.floor(total / 12);\r\n const m = (((total % 12) + 12) % 12) + 1; // 1-based, safe for negative totals\r\n const d = Math.min(date.d, daysInMonth(y, m));\r\n return toIso({ y, m, d });\r\n}\r\n\r\n/** Add `n` years, clamped (Feb 29 + 1 year → Feb 28). Delegates to month arithmetic. */\r\nexport function addYearsClamped(iso: string, n: number): string {\r\n return addMonthsClamped(iso, n * 12);\r\n}\r\n\r\n/** Lexicographic comparison — valid because same-format ISO 8601 date-only strings are byte-sortable. */\r\nexport function compareIso(a: string, b: string): number {\r\n return a < b ? -1 : a > b ? 1 : 0;\r\n}\r\n\r\n/** Inclusive range test. `''` bound = unbounded on that side (ADR 0050 §2, lexicographic). */\r\nexport function isInRange(iso: string, min: string, max: string): boolean {\r\n if (min !== '' && compareIso(iso, min) < 0) return false;\r\n if (max !== '' && compareIso(iso, max) > 0) return false;\r\n return true;\r\n}\r\n\r\n/** Clamp `iso` into `[min,max]` (each `''` = unbounded). Used to seed the displayed month / focus. */\r\nexport function clampIso(iso: string, min: string, max: string): string {\r\n if (min !== '' && compareIso(iso, min) < 0) return min;\r\n if (max !== '' && compareIso(iso, max) > 0) return max;\r\n return iso;\r\n}\r\n\r\n/**\r\n * Build a month grid: weeks of 7 cells, each a day ISO string or `null` (leading/trailing padding —\r\n * adjacent-month days are NOT rendered in MVP). `firstDayOfWeek` is ISO (1=Mon … 7=Sun).\r\n * Pure + deterministic; the component decorates cells with selected/today/disabled/focused state.\r\n */\r\nexport function monthGrid(\r\n y: number,\r\n m: number,\r\n firstDayOfWeek: number,\r\n): (string | null)[][] {\r\n const firstWeekday = isoWeekday(y, m, 1); // ISO weekday of the 1st\r\n const leadingBlanks = (firstWeekday - firstDayOfWeek + 7) % 7;\r\n const dim = daysInMonth(y, m);\r\n\r\n const cells: (string | null)[] = [];\r\n for (let i = 0; i < leadingBlanks; i++) cells.push(null);\r\n for (let d = 1; d <= dim; d++) cells.push(toIso({ y, m, d }));\r\n while (cells.length % 7 !== 0) cells.push(null); // trailing padding\r\n\r\n const weeks: (string | null)[][] = [];\r\n for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));\r\n return weeks;\r\n}\r\n","import {\n addDays,\n addMonthsClamped,\n addYearsClamped,\n isoWeekday,\n parseIso,\n} from './calendar-math';\n\n/**\n * The intent a key produces in the calendar grid. The controller is PURE (no DOM, no focus, no signals);\n * the `skra-datepicker` component applies the intent — sets `focusedIso`/`displayedMonth` and moves REAL\n * DOM focus (roving). `monthChanged` tells the component the grid will re-stamp so it must re-`focus()`.\n */\nexport type CalendarKeyIntent =\n | {\n readonly type: 'focus';\n readonly iso: string;\n readonly monthChanged: boolean;\n }\n | { readonly type: 'select' }\n | { readonly type: 'close' }\n | { readonly type: 'none' };\n\nexport interface CalendarKeyContext {\n /** The currently focused day (ISO). */\n readonly focusedIso: string;\n /** First day of week, ISO 1=Mon … 7=Sun (already resolved by `calendar-intl`). */\n readonly firstDayOfWeek: number;\n}\n\nconst NONE: CalendarKeyIntent = { type: 'none' };\n\n/**\n * SkraCalendarKeyboard — the WAI-ARIA APG **Date Picker Dialog** grid keyboard model (2-D), confined to\n * ONE file. The THIRD per-pattern keyboard controller and the FIRST that does NOT wrap a CDK key manager:\n * neither `FocusKeyManager` (Menu) nor `ActiveDescendantKeyManager` (Select/Combobox) models a 2-D grid\n * whose focusable cell set is recomputed on month change (ADR 0044 §7 note, 2026-06-14). Date arithmetic\n * is delegated to `calendar-math` (the ADR 0050 single math site); this controller only maps keys to\n * intents. Roving REAL focus (NOT `aria-activedescendant`) — the divergence from Select/Combobox.\n *\n * Navigation is unclamped (a user may move onto a disabled out-of-range day — APG-discoverable); only\n * SELECTION is range-guarded, and that guard lives in the component (one place, shared with pointer click).\n */\nexport class SkraCalendarKeyboard {\n resolve(\n event: { key: string; shiftKey: boolean },\n ctx: CalendarKeyContext,\n ): CalendarKeyIntent {\n const { focusedIso, firstDayOfWeek } = ctx;\n switch (event.key) {\n case 'ArrowLeft':\n return this.toFocus(focusedIso, addDays(focusedIso, -1));\n case 'ArrowRight':\n return this.toFocus(focusedIso, addDays(focusedIso, 1));\n case 'ArrowUp':\n return this.toFocus(focusedIso, addDays(focusedIso, -7));\n case 'ArrowDown':\n return this.toFocus(focusedIso, addDays(focusedIso, 7));\n case 'Home':\n return this.toFocus(\n focusedIso,\n this.weekStart(focusedIso, firstDayOfWeek),\n );\n case 'End':\n return this.toFocus(\n focusedIso,\n addDays(this.weekStart(focusedIso, firstDayOfWeek), 6),\n );\n case 'PageUp':\n return this.toFocus(\n focusedIso,\n event.shiftKey\n ? addYearsClamped(focusedIso, -1)\n : addMonthsClamped(focusedIso, -1),\n );\n case 'PageDown':\n return this.toFocus(\n focusedIso,\n event.shiftKey\n ? addYearsClamped(focusedIso, 1)\n : addMonthsClamped(focusedIso, 1),\n );\n case 'Enter':\n case ' ':\n case 'Spacebar': // legacy key name\n return { type: 'select' };\n case 'Escape':\n return { type: 'close' };\n default:\n return NONE;\n }\n }\n\n private toFocus(fromIso: string, toIso: string): CalendarKeyIntent {\n return {\n type: 'focus',\n iso: toIso,\n monthChanged: this.monthChanged(fromIso, toIso),\n };\n }\n\n private monthChanged(a: string, b: string): boolean {\n const pa = parseIso(a);\n const pb = parseIso(b);\n return !pa || !pb || pa.y !== pb.y || pa.m !== pb.m;\n }\n\n private weekStart(iso: string, firstDayOfWeek: number): string {\n const p = parseIso(iso);\n if (!p) return iso;\n const offset = (isoWeekday(p.y, p.m, p.d) - firstDayOfWeek + 7) % 7;\n return addDays(iso, -offset);\n }\n}\n","import { toUtcDate } from './calendar-math';\n\n/**\n * calendar-intl — DatePicker localization via the platform `Intl` (ADR 0050 §5). NO locale string\n * catalog is bundled (atoms-agnostic); everything language/digit-related is derived from `Intl`, keyed\n * by the consumer `locale`. Every `Date` fed to a formatter comes from `calendar-math.toUtcDate` AND the\n * formatter MUST set `timeZone: 'UTC'` (else the displayed date shifts off the zoneless value).\n */\n\nconst UTC = 'UTC';\n\n/** A localized weekday column header (short label + full name for the `<abbr title>`). */\nexport interface WeekdayHeader {\n /** ISO weekday 1=Mon … 7=Sun — a stable `@for` track key. */\n readonly key: number;\n readonly short: string;\n readonly long: string;\n}\n\n/** Resolve the host's default BCP-47 locale tag, SSR-safe (no `navigator` in Node). */\nfunction hostLocale(): string | undefined {\n return typeof navigator !== 'undefined' ? navigator.language : undefined;\n}\n\n/** Trigger display of the selected date (`dateStyle: 'medium'`). `''`/invalid → `''`. */\nexport function formatValue(iso: string, locale: string | undefined): string {\n const dt = toUtcDate(iso);\n if (!dt) return '';\n return new Intl.DateTimeFormat(locale, {\n dateStyle: 'medium',\n timeZone: UTC,\n }).format(dt);\n}\n\n/** Header / nav-button label for a month: localized `month long + year` (e.g. \"czerwiec 2026\"). */\nexport function formatMonthYear(\n y: number,\n m: number,\n locale: string | undefined,\n): string {\n const dt = toUtcDate(\n `${String(y).padStart(4, '0')}-${String(m).padStart(2, '0')}-01`,\n );\n if (!dt) return '';\n return new Intl.DateTimeFormat(locale, {\n month: 'long',\n year: 'numeric',\n timeZone: UTC,\n }).format(dt);\n}\n\n/** Full localized date for a day cell's `[skra-sr-only]` accessible-name extension (ADR 033 Path 2). */\nexport function formatDayName(iso: string, locale: string | undefined): string {\n const dt = toUtcDate(iso);\n if (!dt) return '';\n return new Intl.DateTimeFormat(locale, {\n dateStyle: 'long',\n timeZone: UTC,\n }).format(dt);\n}\n\n/** Visible day number, localized digits (e.g. Arabic-Indic `٥`) — never a raw `toString()`. */\nexport function formatDayNumber(\n day: number,\n locale: string | undefined,\n): string {\n return new Intl.NumberFormat(locale).format(day);\n}\n\n/**\n * Localized weekday column headers, 7 entries starting at `firstDayOfWeek` (ISO 1=Mon … 7=Sun).\n * Reference week: 2024-01-01 is a Monday, so day-of-month `d` (1–7) maps directly to ISO weekday `d`.\n */\nexport function weekdayHeaders(\n firstDayOfWeek: number,\n locale: string | undefined,\n): WeekdayHeader[] {\n const shortFmt = new Intl.DateTimeFormat(locale, {\n weekday: 'short',\n timeZone: UTC,\n });\n const longFmt = new Intl.DateTimeFormat(locale, {\n weekday: 'long',\n timeZone: UTC,\n });\n const headers: WeekdayHeader[] = [];\n for (let i = 0; i < 7; i++) {\n const dow = ((firstDayOfWeek - 1 + i) % 7) + 1; // 1 … 7\n const dt = toUtcDate(`2024-01-0${dow}`)!; // dow 1–7 → '2024-01-01' … '2024-01-07'\n headers.push({\n key: dow,\n short: shortFmt.format(dt),\n long: longFmt.format(dt),\n });\n }\n return headers;\n}\n\n/**\n * Resolve the first day of the week (ISO 1=Mon … 7=Sun): explicit `override` → `Intl` `getWeekInfo` →\n * **Monday fallback**. The override is the MVP safety valve — `Intl.Locale.getWeekInfo()` support is\n * spotty (older Firefox/Safari), so the detection path genuinely fails in mainstream browsers and the\n * Monday fallback is wrong for en-US (Sun) / much of the Middle East (Sat) (ADR 0050 §5).\n */\nexport function resolveFirstDayOfWeek(\n override: number | undefined,\n locale: string | undefined,\n): number {\n if (typeof override === 'number' && override >= 1 && override <= 7)\n return override;\n try {\n const loc = new Intl.Locale(\n locale ?? hostLocale() ?? 'en',\n ) as Intl.Locale & {\n getWeekInfo?: () => { firstDay?: number };\n weekInfo?: { firstDay?: number };\n };\n const info = loc.getWeekInfo?.() ?? loc.weekInfo; // method (modern) or property (older engines)\n const firstDay = info?.firstDay;\n if (typeof firstDay === 'number' && firstDay >= 1 && firstDay <= 7)\n return firstDay;\n } catch {\n /* unsupported / malformed locale → fall through to the documented fallback */\n }\n return 1; // Monday (ISO-8601 week start)\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { SkraFieldContext } from '@skra/ui/field';\n\nimport {\n _attachPositioner,\n type SkraPlacement,\n type _PositionerHandle,\n} from '@skra/ui/core';\nimport { SkraCalendarKeyboard } from './calendar-keyboard';\nimport {\n addMonthsClamped,\n clampIso,\n compareIso,\n isInRange,\n isValidIso,\n monthGrid,\n parseIso,\n toIso,\n today,\n} from './calendar-math';\nimport {\n formatDayName,\n formatDayNumber,\n formatMonthYear,\n formatValue,\n resolveFirstDayOfWeek,\n weekdayHeaders,\n} from './calendar-intl';\n\ninterface DayCell {\n readonly key: string;\n readonly iso: string | null;\n readonly dayNum: string;\n readonly srName: string;\n readonly today: boolean;\n readonly selected: boolean;\n readonly disabled: boolean;\n readonly focused: boolean;\n}\n\ninterface WeekRow {\n readonly key: number;\n readonly days: DayCell[];\n}\n\nlet nextDatePickerId = 0;\n\n/**\n * SkraDatePicker — pick a single **calendar date** from an APG Date Picker grid in the native top layer.\n * Second Tier-3 component. A value-display **trigger** (`<button>`) opens a non-modal top-layer **calendar\n * panel** (Popover API, `popover=\"auto\"`, ADR 0044). The value is an **ISO 8601 date-only string**\n * (`YYYY-MM-DD`), consumer-owned (ADR 0050/037 — NO `@angular/forms`); all date math is the zoneless\n * UTC-calculator discipline in `calendar-math` (no date library). Localization (month/weekday names,\n * first-day-of-week, digits) is `Intl`-derived in `calendar-intl`; the 2-D grid keyboard is the\n * hand-rolled `SkraCalendarKeyboard` (ADR 0044 §7 — roving REAL focus, not aria-activedescendant).\n *\n * No projected content: the calendar days are GENERATED (the structural divergence from select/combobox —\n * there is no `skra-option` reuse). The only focusable element in the open panel is the roving day cell;\n * the month-nav buttons are pointer affordances (`tabindex=\"-1\"`, driven by PageUp/PageDown on keyboard),\n * and Tab dismisses — so no focus-containment machinery is needed (spec Q-1).\n *\n * Full contract: adr/specs/component-datepicker-spec.md.\n */\n@Component({\n selector: 'skra-datepicker',\n standalone: true,\n exportAs: 'skraDatePicker',\n template: `\n <button\n #trigger\n class=\"skra-datepicker-trigger\"\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n [attr.id]=\"triggerId()\"\n [attr.popovertarget]=\"panelId\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"hasError() ? 'true' : null\"\n [attr.aria-required]=\"isRequired() ? 'true' : null\"\n [attr.aria-readonly]=\"isReadonly() ? 'true' : null\"\n [disabled]=\"isDisabled()\"\n (click)=\"onTriggerClick($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (formattedValue(); as label) {\n <span class=\"skra-datepicker-value\">{{ label }}</span>\n } @else {\n <span class=\"skra-datepicker-placeholder\">{{ placeholder() }}</span>\n }\n <svg\n class=\"skra-datepicker-icon\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"17\" rx=\"2\" />\n <path d=\"M3 9h18M8 2v4M16 2v4\" />\n </svg>\n </button>\n\n <div\n #panel\n class=\"skra-datepicker-panel\"\n [id]=\"panelId\"\n popover=\"auto\"\n role=\"dialog\"\n aria-modal=\"false\"\n [attr.aria-labelledby]=\"monthYearId\"\n (toggle)=\"onPanelToggle($event)\"\n >\n <div class=\"skra-datepicker-header\">\n <button\n type=\"button\"\n class=\"skra-datepicker-nav\"\n tabindex=\"-1\"\n [attr.aria-label]=\"prevMonthLabel()\"\n (click)=\"goToPreviousMonth()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M15 6l-6 6 6 6\" />\n </svg>\n </button>\n <span\n class=\"skra-datepicker-monthyear\"\n [id]=\"monthYearId\"\n aria-live=\"polite\"\n >{{ monthYearLabel() }}</span\n >\n <button\n type=\"button\"\n class=\"skra-datepicker-nav\"\n tabindex=\"-1\"\n [attr.aria-label]=\"nextMonthLabel()\"\n (click)=\"goToNextMonth()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 6l6 6-6 6\" />\n </svg>\n </button>\n </div>\n\n <table\n class=\"skra-datepicker-grid\"\n role=\"grid\"\n [attr.aria-labelledby]=\"monthYearId\"\n >\n <thead>\n <tr>\n @for (wd of weekdayHeadersView(); track wd.key) {\n <th scope=\"col\" class=\"skra-datepicker-weekday\">\n <abbr [title]=\"wd.long\">{{ wd.short }}</abbr>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (week of weeks(); track week.key) {\n <tr>\n @for (cell of week.days; track cell.key) {\n @if (cell.iso) {\n <td\n role=\"gridcell\"\n [attr.aria-selected]=\"cell.selected ? 'true' : null\"\n >\n <button\n type=\"button\"\n class=\"skra-datepicker-day\"\n [attr.tabindex]=\"cell.focused ? 0 : -1\"\n [attr.aria-current]=\"cell.today ? 'date' : null\"\n [attr.aria-disabled]=\"cell.disabled ? 'true' : null\"\n [attr.data-skra-selected]=\"cell.selected ? '' : null\"\n [attr.data-skra-today]=\"cell.today ? '' : null\"\n (click)=\"selectDate(cell.iso)\"\n (keydown)=\"onGridKeydown($event)\"\n >\n {{ cell.dayNum\n }}<span class=\"skra-datepicker-day-sr\" skra-sr-only>{{\n cell.srName\n }}</span>\n </button>\n </td>\n } @else {\n <td class=\"skra-datepicker-day-empty\" aria-hidden=\"true\"></td>\n }\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n `,\n styleUrl: './datepicker.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n '[attr.data-skra-disabled]': 'isDisabled() ? \"\" : null',\n '[attr.data-skra-readonly]': 'isReadonly() ? \"\" : null',\n '[attr.data-skra-validation]': 'hasError() ? \"invalid\" : null',\n },\n})\nexport class SkraDatePicker {\n /** Consumer-owned value: ISO 8601 date-only (`YYYY-MM-DD`); `''` = unset. NEVER a Date (ADR 0050/037). */\n readonly value = input<string>('');\n /** Inclusive lower bound (ISO); `''` = unbounded (ADR 0050 §2). */\n readonly min = input<string>('');\n /** Inclusive upper bound (ISO); `''` = unbounded. */\n readonly max = input<string>('');\n /** `Intl` locale (BCP-47); `undefined` → host default (ADR 0050 §5). */\n readonly locale = input<string | undefined>(undefined);\n /** First day of week, ISO 1=Mon … 7=Sun; overrides `Intl.getWeekInfo` (the MVP safety valve, ADR 0050 §5). */\n readonly firstDayOfWeek = input<number | undefined>(undefined);\n /** Value-empty hint in the trigger (NOT the accessible name — ADR 033). */\n readonly placeholder = input<string>('');\n /** Placement intent; flip/shift adjust at runtime. */\n readonly placement = input<SkraPlacement>('bottom');\n /** Standalone availability source — `SkraFieldContext` wins when present. */\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly readonly = input(false, { transform: booleanAttribute });\n\n /** Fires ONLY on user date selection — never on a programmatic `value()` change (ADR 037/0050). */\n readonly valueChange = output<string>();\n\n private readonly triggerRef =\n viewChild<ElementRef<HTMLButtonElement>>('trigger');\n private readonly panelRef = viewChild<ElementRef<HTMLElement>>('panel');\n\n private readonly context = inject(SkraFieldContext, { optional: true });\n private readonly injector = inject(Injector);\n private readonly keyboard = new SkraCalendarKeyboard();\n\n readonly panelId = `skra-datepicker-${nextDatePickerId}`;\n readonly monthYearId = `skra-datepicker-monthyear-${nextDatePickerId++}`;\n protected readonly isOpen = signal(false);\n\n /** Today's LOCAL date (ADR 0050 §3) — stable for the session. */\n private readonly todayIso = today();\n /** The roving-focus day; SINGLE source of truth for what the grid shows AND which cell is focusable. */\n private readonly focusedIso = signal(this.todayIso);\n\n private positioner?: _PositionerHandle;\n /** Set when a close should return focus to the trigger (keyboard/select), not on outside-click. */\n private returnFocus = false;\n\n // ── Availability / validation (SkraFieldContext, ADR 013, with standalone fallbacks) ──\n protected readonly isDisabled = computed(\n () => this.context?.isDisabled() ?? this.disabled(),\n );\n protected readonly isReadonly = computed(\n () => this.context?.isReadonly() ?? this.readonly(),\n );\n protected readonly hasError = computed(\n () => this.context?.hasError() ?? false,\n );\n protected readonly isRequired = computed(\n () => this.context?.isRequired() ?? false,\n );\n protected readonly triggerId = computed(\n () => this.context?.fieldId() || null,\n );\n protected readonly describedBy = computed(\n () => this.context?.describedByIds() ?? null,\n );\n\n // ── Derived calendar state ──\n /** The committed value, defensively normalized: invalid/out-of-range → `''` for display (ADR 0050 §1). */\n protected readonly selectedIso = computed(() => {\n const v = this.value();\n return isValidIso(v) && isInRange(v, this.min(), this.max()) ? v : '';\n });\n protected readonly formattedValue = computed(() =>\n formatValue(this.selectedIso(), this.locale()),\n );\n private readonly firstDow = computed(() =>\n resolveFirstDayOfWeek(this.firstDayOfWeek(), this.locale()),\n );\n /** The month being shown — always the focused day's month (keeps the roving tabindex valid). */\n private readonly displayedMonth = computed(() => {\n const p = parseIso(this.focusedIso()) ?? parseIso(this.todayIso)!;\n return { y: p.y, m: p.m };\n });\n protected readonly monthYearLabel = computed(() =>\n formatMonthYear(\n this.displayedMonth().y,\n this.displayedMonth().m,\n this.locale(),\n ),\n );\n protected readonly prevMonthLabel = computed(() => this.monthOffsetLabel(-1));\n protected readonly nextMonthLabel = computed(() => this.monthOffsetLabel(1));\n protected readonly weekdayHeadersView = computed(() =>\n weekdayHeaders(this.firstDow(), this.locale()),\n );\n protected readonly weeks = computed<WeekRow[]>(() => {\n const { y, m } = this.displayedMonth();\n const loc = this.locale();\n const sel = this.selectedIso();\n const foc = this.focusedIso();\n const min = this.min();\n const max = this.max();\n return monthGrid(y, m, this.firstDow()).map((week, wi) => ({\n key: wi,\n days: week.map((iso, di) =>\n iso === null\n ? this.emptyCell(`${wi}-${di}`)\n : {\n key: iso,\n iso,\n dayNum: formatDayNumber(parseIso(iso)!.d, loc),\n srName: formatDayName(iso, loc),\n today: iso === this.todayIso,\n selected: iso === sel,\n disabled: !isInRange(iso, min, max),\n focused: iso === foc,\n },\n ),\n }));\n });\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.positioner?.destroy());\n if (typeof ngDevMode !== 'undefined' && ngDevMode) {\n // Dev-only sanity warnings (stripped in prod) — never thrown (ADR 0050 §1).\n const warn = computed(() => {\n const v = this.value();\n if (v !== '' && !isValidIso(v))\n return `skra-datepicker: value \"${v}\" is not a valid YYYY-MM-DD date; shown as unset.`;\n if (\n this.min() !== '' &&\n this.max() !== '' &&\n compareIso(this.min(), this.max()) > 0\n )\n return `skra-datepicker: min \"${this.min()}\" is after max \"${this.max()}\" — every day is disabled.`;\n return null;\n });\n afterNextRender(\n () => {\n const message = warn();\n if (message) console.warn(message);\n },\n { injector: this.injector },\n );\n }\n }\n\n // ── Trigger interaction ──\n protected onTriggerClick(event: MouseEvent): void {\n if (this.isReadonly()) event.preventDefault(); // block the native popovertarget open\n }\n\n protected onTriggerKeydown(event: KeyboardEvent): void {\n if (this.isDisabled() || this.isReadonly() || this.isOpen()) return;\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n this.open(); // Enter/Space/click open via the native popovertarget\n }\n }\n\n // ── Grid keyboard (APG Date Picker, 2-D) ──\n protected onGridKeydown(event: KeyboardEvent): void {\n if (event.key === 'Tab') {\n // APG: Tab dismisses the calendar; focus returns to the trigger (deterministic, no containment).\n event.preventDefault();\n this.returnFocus = true;\n this.close();\n return;\n }\n const intent = this.keyboard.resolve(event, {\n focusedIso: this.focusedIso(),\n firstDayOfWeek: this.firstDow(),\n });\n switch (intent.type) {\n case 'focus':\n event.preventDefault();\n this.focusedIso.set(intent.iso);\n this.scheduleFocus(); // re-focus after the grid re-stamps\n break;\n case 'select':\n event.preventDefault();\n this.selectDate(this.focusedIso());\n break;\n case 'close':\n this.returnFocus = true;\n this.close();\n break;\n case 'none':\n break;\n }\n }\n\n // ── Month navigation (pointer; focus stays on the nav button) ──\n protected goToPreviousMonth(): void {\n this.focusedIso.set(addMonthsClamped(this.focusedIso(), -1));\n }\n protected goToNextMonth(): void {\n this.focusedIso.set(addMonthsClamped(this.focusedIso(), 1));\n }\n\n // ── Selection ──\n protected selectDate(iso: string): void {\n if (!isInRange(iso, this.min(), this.max())) return; // guard out-of-range (one place: keyboard + pointer)\n this.returnFocus = true;\n this.valueChange.emit(iso);\n this.close();\n }\n\n // ── Panel open / close (native toggle from the Popover API) ──\n protected onPanelToggle(event: Event): void {\n const open = (event as ToggleEvent).newState === 'open';\n this.isOpen.set(open);\n if (open) this.onOpen();\n else this.onClose();\n }\n\n private onOpen(): void {\n this.focusedIso.set(this.seedFocus());\n const anchor = this.triggerRef()?.nativeElement;\n const panel = this.panelRef()?.nativeElement;\n if (anchor && panel) {\n this.positioner?.destroy();\n this.positioner = _attachPositioner(anchor, panel, () => ({\n placement: this.placement(),\n offset: this.cssLenPx('--skra-comp-datepicker-panel-offset'),\n viewportPadding: this.cssLenPx(\n '--skra-comp-datepicker-panel-viewport-padding',\n ),\n }));\n }\n this.scheduleFocus();\n }\n\n private onClose(): void {\n this.positioner?.destroy();\n this.positioner = undefined;\n if (this.returnFocus) {\n this.returnFocus = false;\n this.triggerRef()?.nativeElement.focus();\n }\n }\n\n private open(): void {\n this.panelRef()?.nativeElement.showPopover?.();\n }\n private close(): void {\n this.panelRef()?.nativeElement.hidePopover?.();\n }\n\n /** Seed the focused day on open: the valid current value, else today, clamped into `[min,max]`. */\n private seedFocus(): string {\n const v = this.value();\n const base = isValidIso(v) ? v : this.todayIso;\n return clampIso(base, this.min(), this.max());\n }\n\n private monthOffsetLabel(n: number): string {\n const { y, m } = this.displayedMonth();\n const ref = parseIso(addMonthsClamped(toIso({ y, m, d: 1 }), n))!;\n return formatMonthYear(ref.y, ref.m, this.locale());\n }\n\n private emptyCell(key: string): DayCell {\n return {\n key,\n iso: null,\n dayNum: '',\n srName: '',\n today: false,\n selected: false,\n disabled: true,\n focused: false,\n };\n }\n\n private scheduleFocus(): void {\n afterNextRender(() => this.focusActiveDay(), { injector: this.injector });\n }\n\n private focusActiveDay(): void {\n this.panelRef()\n ?.nativeElement.querySelector<HTMLElement>(\n '.skra-datepicker-day[tabindex=\"0\"]',\n )\n ?.focus();\n }\n\n /** Read a length comp token (px/rem) off the panel computed style for the positioner. */\n private cssLenPx(prop: string): number {\n const el = this.panelRef()?.nativeElement;\n if (!el) return 0;\n const raw = getComputedStyle(el).getPropertyValue(prop).trim();\n if (raw.endsWith('px')) return parseFloat(raw);\n if (raw.endsWith('rem')) {\n const rootFontSize =\n parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\n return parseFloat(raw) * rootFontSize;\n }\n return parseFloat(raw) || 0;\n }\n}\n","/**\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-datepicker.mjs","sources":["../../../../libs/ui/datepicker/src/lib/datepicker/calendar-math.ts","../../../../libs/ui/datepicker/src/lib/datepicker/calendar-keyboard.ts","../../../../libs/ui/datepicker/src/lib/datepicker/calendar-intl.ts","../../../../libs/ui/datepicker/src/lib/datepicker/datepicker.ts","../../../../libs/ui/datepicker/src/skra-ui-datepicker.ts"],"sourcesContent":["/**\r\n * calendar-math — the ONE sanctioned site for DatePicker date arithmetic (ADR 0050 §3/§6).\r\n *\r\n * Zoneless calendar-date discipline (the timezone off-by-one is the bug class this exists to prevent):\r\n * - The value is an ISO 8601 date-only string (`YYYY-MM-DD`) — NEVER materialized as a `Date`.\r\n * - `Date` is used ONLY as a UTC calendar calculator — built via `Date.UTC(...)`, read via `getUTC*`.\r\n * - `new Date(isoString)` is FORBIDDEN (date-only parses as UTC midnight → local accessors shift it).\r\n * - \"today\" uses LOCAL accessors — \"today\" is inherently local-civil.\r\n * - Month length + leap years are delegated to the platform engine, NEVER a hand-written leap rule.\r\n *\r\n * Months are **1-based** here (1=Jan … 12=Dec) to mirror the ISO string; the single 0-based conversion\r\n * happens at the `Date.UTC` call sites. Weekdays are **ISO** (1=Mon … 7=Sun) to match `firstDayOfWeek`.\r\n *\r\n * This module is the ADR 0050 §6 swap-point: a future `Temporal.PlainDate` migration touches only here.\r\n */\r\n\r\n/** A zoneless calendar date. `m` is 1-based (1=Jan … 12=Dec). */\r\nexport interface CalendarDate {\r\n readonly y: number;\r\n readonly m: number;\r\n readonly d: number;\r\n}\r\n\r\nconst ISO_DATE = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\r\n\r\n/** Zero-pad to a fixed width (no locale, no `Intl` — pure formatting). */\r\nfunction pad(n: number, width: number): string {\r\n return String(n).padStart(width, '0');\r\n}\r\n\r\n/** Days in month `m` (1-based) of year `y` — delegated to the engine (leap years handled for free). */\r\nexport function daysInMonth(y: number, m: number): number {\r\n // Date.UTC month is 0-based; passing the 1-based `m` selects the NEXT month, day 0 = last of `m`.\r\n return new Date(Date.UTC(y, m, 0)).getUTCDate();\r\n}\r\n\r\n/** ISO weekday (1=Mon … 7=Sun) of an arbitrary {y,m,d}, via the UTC calculator. */\r\nexport function isoWeekday(y: number, m: number, d: number): number {\r\n const jsDay = new Date(Date.UTC(y, m - 1, d)).getUTCDay(); // 0=Sun … 6=Sat\r\n return ((jsDay + 6) % 7) + 1; // → 1=Mon … 7=Sun\r\n}\r\n\r\n/** Strict `YYYY-MM-DD` parse with real calendar validation. Returns `null` for anything invalid. */\r\nexport function parseIso(iso: string): CalendarDate | null {\r\n const match = ISO_DATE.exec(iso);\r\n if (!match) return null;\r\n const y = Number(match[1]);\r\n const m = Number(match[2]);\r\n const d = Number(match[3]);\r\n if (m < 1 || m > 12) return null;\r\n if (d < 1 || d > daysInMonth(y, m)) return null; // rejects 2026-02-30, 2026-04-31, etc.\r\n return { y, m, d };\r\n}\r\n\r\n/** `true` iff `iso` is a strictly valid `YYYY-MM-DD` calendar date. */\r\nexport function isValidIso(iso: string): boolean {\r\n return parseIso(iso) !== null;\r\n}\r\n\r\n/** Serialize a calendar date to `YYYY-MM-DD`. */\r\nexport function toIso({ y, m, d }: CalendarDate): string {\r\n return `${pad(y, 4)}-${pad(m, 2)}-${pad(d, 2)}`;\r\n}\r\n\r\n/**\r\n * Build a UTC `Date` from an ISO string — the ONLY sanctioned `Date`-from-value site (used by\r\n * `calendar-intl` to feed `Intl.DateTimeFormat`, which MUST also pass `timeZone:'UTC'`). Returns the\r\n * value as a UTC instant; callers MUST read it back via UTC accessors / a UTC-zoned formatter ONLY.\r\n */\r\nexport function toUtcDate(iso: string): Date | null {\r\n const date = parseIso(iso);\r\n if (!date) return null;\r\n return new Date(Date.UTC(date.y, date.m - 1, date.d));\r\n}\r\n\r\n/** Today's LOCAL calendar date as ISO (local accessors — \"today\" is local-civil, ADR 0050 §3). */\r\nexport function today(): string {\r\n const now = new Date();\r\n return toIso({\r\n y: now.getFullYear(),\r\n m: now.getMonth() + 1,\r\n d: now.getDate(),\r\n });\r\n}\r\n\r\n/** Add `n` days (may be negative); crosses month/year boundaries via the UTC engine. */\r\nexport function addDays(iso: string, n: number): string {\r\n const date = parseIso(iso);\r\n if (!date) return iso;\r\n const dt = new Date(Date.UTC(date.y, date.m - 1, date.d));\r\n dt.setUTCDate(dt.getUTCDate() + n);\r\n return toIso({\r\n y: dt.getUTCFullYear(),\r\n m: dt.getUTCMonth() + 1,\r\n d: dt.getUTCDate(),\r\n });\r\n}\r\n\r\n/**\r\n * Add `n` months (may be negative), preserving day-of-month CLAMPED to the target month length\r\n * (ADR 0050 §4): Jan 31 + 1 month → Feb 28/29, never Mar 3.\r\n */\r\nexport function addMonthsClamped(iso: string, n: number): string {\r\n const date = parseIso(iso);\r\n if (!date) return iso;\r\n const total = date.y * 12 + (date.m - 1) + n;\r\n const y = Math.floor(total / 12);\r\n const m = (((total % 12) + 12) % 12) + 1; // 1-based, safe for negative totals\r\n const d = Math.min(date.d, daysInMonth(y, m));\r\n return toIso({ y, m, d });\r\n}\r\n\r\n/** Add `n` years, clamped (Feb 29 + 1 year → Feb 28). Delegates to month arithmetic. */\r\nexport function addYearsClamped(iso: string, n: number): string {\r\n return addMonthsClamped(iso, n * 12);\r\n}\r\n\r\n/** Lexicographic comparison — valid because same-format ISO 8601 date-only strings are byte-sortable. */\r\nexport function compareIso(a: string, b: string): number {\r\n return a < b ? -1 : a > b ? 1 : 0;\r\n}\r\n\r\n/** Inclusive range test. `''` bound = unbounded on that side (ADR 0050 §2, lexicographic). */\r\nexport function isInRange(iso: string, min: string, max: string): boolean {\r\n if (min !== '' && compareIso(iso, min) < 0) return false;\r\n if (max !== '' && compareIso(iso, max) > 0) return false;\r\n return true;\r\n}\r\n\r\n/** Clamp `iso` into `[min,max]` (each `''` = unbounded). Used to seed the displayed month / focus. */\r\nexport function clampIso(iso: string, min: string, max: string): string {\r\n if (min !== '' && compareIso(iso, min) < 0) return min;\r\n if (max !== '' && compareIso(iso, max) > 0) return max;\r\n return iso;\r\n}\r\n\r\n/**\r\n * Build a month grid: weeks of 7 cells, each a day ISO string or `null` (leading/trailing padding —\r\n * adjacent-month days are NOT rendered in MVP). `firstDayOfWeek` is ISO (1=Mon … 7=Sun).\r\n * Pure + deterministic; the component decorates cells with selected/today/disabled/focused state.\r\n */\r\nexport function monthGrid(\r\n y: number,\r\n m: number,\r\n firstDayOfWeek: number,\r\n): (string | null)[][] {\r\n const firstWeekday = isoWeekday(y, m, 1); // ISO weekday of the 1st\r\n const leadingBlanks = (firstWeekday - firstDayOfWeek + 7) % 7;\r\n const dim = daysInMonth(y, m);\r\n\r\n const cells: (string | null)[] = [];\r\n for (let i = 0; i < leadingBlanks; i++) cells.push(null);\r\n for (let d = 1; d <= dim; d++) cells.push(toIso({ y, m, d }));\r\n while (cells.length % 7 !== 0) cells.push(null); // trailing padding\r\n\r\n const weeks: (string | null)[][] = [];\r\n for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));\r\n return weeks;\r\n}\r\n","import {\r\n addDays,\r\n addMonthsClamped,\r\n addYearsClamped,\r\n isoWeekday,\r\n parseIso,\r\n} from './calendar-math';\r\n\r\n/**\r\n * The intent a key produces in the calendar grid. The controller is PURE (no DOM, no focus, no signals);\r\n * the `skra-datepicker` component applies the intent — sets `focusedIso`/`displayedMonth` and moves REAL\r\n * DOM focus (roving). `monthChanged` tells the component the grid will re-stamp so it must re-`focus()`.\r\n */\r\nexport type CalendarKeyIntent =\r\n | {\r\n readonly type: 'focus';\r\n readonly iso: string;\r\n readonly monthChanged: boolean;\r\n }\r\n | { readonly type: 'select' }\r\n | { readonly type: 'close' }\r\n | { readonly type: 'none' };\r\n\r\nexport interface CalendarKeyContext {\r\n /** The currently focused day (ISO). */\r\n readonly focusedIso: string;\r\n /** First day of week, ISO 1=Mon … 7=Sun (already resolved by `calendar-intl`). */\r\n readonly firstDayOfWeek: number;\r\n}\r\n\r\nconst NONE: CalendarKeyIntent = { type: 'none' };\r\n\r\n/**\r\n * SkraCalendarKeyboard — the WAI-ARIA APG **Date Picker Dialog** grid keyboard model (2-D), confined to\r\n * ONE file. The THIRD per-pattern keyboard controller and the FIRST that does NOT wrap a CDK key manager:\r\n * neither `FocusKeyManager` (Menu) nor `ActiveDescendantKeyManager` (Select/Combobox) models a 2-D grid\r\n * whose focusable cell set is recomputed on month change (ADR 0044 §7 note, 2026-06-14). Date arithmetic\r\n * is delegated to `calendar-math` (the ADR 0050 single math site); this controller only maps keys to\r\n * intents. Roving REAL focus (NOT `aria-activedescendant`) — the divergence from Select/Combobox.\r\n *\r\n * Navigation is unclamped (a user may move onto a disabled out-of-range day — APG-discoverable); only\r\n * SELECTION is range-guarded, and that guard lives in the component (one place, shared with pointer click).\r\n */\r\nexport class SkraCalendarKeyboard {\r\n resolve(\r\n event: { key: string; shiftKey: boolean },\r\n ctx: CalendarKeyContext,\r\n ): CalendarKeyIntent {\r\n const { focusedIso, firstDayOfWeek } = ctx;\r\n switch (event.key) {\r\n case 'ArrowLeft':\r\n return this.toFocus(focusedIso, addDays(focusedIso, -1));\r\n case 'ArrowRight':\r\n return this.toFocus(focusedIso, addDays(focusedIso, 1));\r\n case 'ArrowUp':\r\n return this.toFocus(focusedIso, addDays(focusedIso, -7));\r\n case 'ArrowDown':\r\n return this.toFocus(focusedIso, addDays(focusedIso, 7));\r\n case 'Home':\r\n return this.toFocus(\r\n focusedIso,\r\n this.weekStart(focusedIso, firstDayOfWeek),\r\n );\r\n case 'End':\r\n return this.toFocus(\r\n focusedIso,\r\n addDays(this.weekStart(focusedIso, firstDayOfWeek), 6),\r\n );\r\n case 'PageUp':\r\n return this.toFocus(\r\n focusedIso,\r\n event.shiftKey\r\n ? addYearsClamped(focusedIso, -1)\r\n : addMonthsClamped(focusedIso, -1),\r\n );\r\n case 'PageDown':\r\n return this.toFocus(\r\n focusedIso,\r\n event.shiftKey\r\n ? addYearsClamped(focusedIso, 1)\r\n : addMonthsClamped(focusedIso, 1),\r\n );\r\n case 'Enter':\r\n case ' ':\r\n case 'Spacebar': // legacy key name\r\n return { type: 'select' };\r\n case 'Escape':\r\n return { type: 'close' };\r\n default:\r\n return NONE;\r\n }\r\n }\r\n\r\n private toFocus(fromIso: string, toIso: string): CalendarKeyIntent {\r\n return {\r\n type: 'focus',\r\n iso: toIso,\r\n monthChanged: this.monthChanged(fromIso, toIso),\r\n };\r\n }\r\n\r\n private monthChanged(a: string, b: string): boolean {\r\n const pa = parseIso(a);\r\n const pb = parseIso(b);\r\n return !pa || !pb || pa.y !== pb.y || pa.m !== pb.m;\r\n }\r\n\r\n private weekStart(iso: string, firstDayOfWeek: number): string {\r\n const p = parseIso(iso);\r\n if (!p) return iso;\r\n const offset = (isoWeekday(p.y, p.m, p.d) - firstDayOfWeek + 7) % 7;\r\n return addDays(iso, -offset);\r\n }\r\n}\r\n","import { toUtcDate } from './calendar-math';\r\n\r\n/**\r\n * calendar-intl — DatePicker localization via the platform `Intl` (ADR 0050 §5). NO locale string\r\n * catalog is bundled (atoms-agnostic); everything language/digit-related is derived from `Intl`, keyed\r\n * by the consumer `locale`. Every `Date` fed to a formatter comes from `calendar-math.toUtcDate` AND the\r\n * formatter MUST set `timeZone: 'UTC'` (else the displayed date shifts off the zoneless value).\r\n */\r\n\r\nconst UTC = 'UTC';\r\n\r\n/** A localized weekday column header (short label + full name for the `<abbr title>`). */\r\nexport interface WeekdayHeader {\r\n /** ISO weekday 1=Mon … 7=Sun — a stable `@for` track key. */\r\n readonly key: number;\r\n readonly short: string;\r\n readonly long: string;\r\n}\r\n\r\n/** Resolve the host's default BCP-47 locale tag, SSR-safe (no `navigator` in Node). */\r\nfunction hostLocale(): string | undefined {\r\n return typeof navigator !== 'undefined' ? navigator.language : undefined;\r\n}\r\n\r\n/** Trigger display of the selected date (`dateStyle: 'medium'`). `''`/invalid → `''`. */\r\nexport function formatValue(iso: string, locale: string | undefined): string {\r\n const dt = toUtcDate(iso);\r\n if (!dt) return '';\r\n return new Intl.DateTimeFormat(locale, {\r\n dateStyle: 'medium',\r\n timeZone: UTC,\r\n }).format(dt);\r\n}\r\n\r\n/** Header / nav-button label for a month: localized `month long + year` (e.g. \"czerwiec 2026\"). */\r\nexport function formatMonthYear(\r\n y: number,\r\n m: number,\r\n locale: string | undefined,\r\n): string {\r\n const dt = toUtcDate(\r\n `${String(y).padStart(4, '0')}-${String(m).padStart(2, '0')}-01`,\r\n );\r\n if (!dt) return '';\r\n return new Intl.DateTimeFormat(locale, {\r\n month: 'long',\r\n year: 'numeric',\r\n timeZone: UTC,\r\n }).format(dt);\r\n}\r\n\r\n/** Full localized date for a day cell's `[skra-sr-only]` accessible-name extension (ADR 033 Path 2). */\r\nexport function formatDayName(iso: string, locale: string | undefined): string {\r\n const dt = toUtcDate(iso);\r\n if (!dt) return '';\r\n return new Intl.DateTimeFormat(locale, {\r\n dateStyle: 'long',\r\n timeZone: UTC,\r\n }).format(dt);\r\n}\r\n\r\n/** Visible day number, localized digits (e.g. Arabic-Indic `٥`) — never a raw `toString()`. */\r\nexport function formatDayNumber(\r\n day: number,\r\n locale: string | undefined,\r\n): string {\r\n return new Intl.NumberFormat(locale).format(day);\r\n}\r\n\r\n/**\r\n * Localized weekday column headers, 7 entries starting at `firstDayOfWeek` (ISO 1=Mon … 7=Sun).\r\n * Reference week: 2024-01-01 is a Monday, so day-of-month `d` (1–7) maps directly to ISO weekday `d`.\r\n */\r\nexport function weekdayHeaders(\r\n firstDayOfWeek: number,\r\n locale: string | undefined,\r\n): WeekdayHeader[] {\r\n const shortFmt = new Intl.DateTimeFormat(locale, {\r\n weekday: 'short',\r\n timeZone: UTC,\r\n });\r\n const longFmt = new Intl.DateTimeFormat(locale, {\r\n weekday: 'long',\r\n timeZone: UTC,\r\n });\r\n const headers: WeekdayHeader[] = [];\r\n for (let i = 0; i < 7; i++) {\r\n const dow = ((firstDayOfWeek - 1 + i) % 7) + 1; // 1 … 7\r\n const dt = toUtcDate(`2024-01-0${dow}`)!; // dow 1–7 → '2024-01-01' … '2024-01-07'\r\n headers.push({\r\n key: dow,\r\n short: shortFmt.format(dt),\r\n long: longFmt.format(dt),\r\n });\r\n }\r\n return headers;\r\n}\r\n\r\n/**\r\n * Resolve the first day of the week (ISO 1=Mon … 7=Sun): explicit `override` → `Intl` `getWeekInfo` →\r\n * **Monday fallback**. The override is the MVP safety valve — `Intl.Locale.getWeekInfo()` support is\r\n * spotty (older Firefox/Safari), so the detection path genuinely fails in mainstream browsers and the\r\n * Monday fallback is wrong for en-US (Sun) / much of the Middle East (Sat) (ADR 0050 §5).\r\n */\r\nexport function resolveFirstDayOfWeek(\r\n override: number | undefined,\r\n locale: string | undefined,\r\n): number {\r\n if (typeof override === 'number' && override >= 1 && override <= 7)\r\n return override;\r\n try {\r\n const loc = new Intl.Locale(\r\n locale ?? hostLocale() ?? 'en',\r\n ) as Intl.Locale & {\r\n getWeekInfo?: () => { firstDay?: number };\r\n weekInfo?: { firstDay?: number };\r\n };\r\n const info = loc.getWeekInfo?.() ?? loc.weekInfo; // method (modern) or property (older engines)\r\n const firstDay = info?.firstDay;\r\n if (typeof firstDay === 'number' && firstDay >= 1 && firstDay <= 7)\r\n return firstDay;\r\n } catch {\r\n /* unsupported / malformed locale → fall through to the documented fallback */\r\n }\r\n return 1; // Monday (ISO-8601 week start)\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n DestroyRef,\r\n ElementRef,\r\n Injector,\r\n ViewEncapsulation,\r\n afterNextRender,\r\n booleanAttribute,\r\n computed,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { SkraFieldContext } from '@skra/ui/field';\r\n\r\nimport {\r\n _attachPositioner,\r\n type SkraPlacement,\r\n type _PositionerHandle,\r\n} from '@skra/ui/core';\r\nimport { SkraCalendarKeyboard } from './calendar-keyboard';\r\nimport {\r\n addMonthsClamped,\r\n clampIso,\r\n compareIso,\r\n isInRange,\r\n isValidIso,\r\n monthGrid,\r\n parseIso,\r\n toIso,\r\n today,\r\n} from './calendar-math';\r\nimport {\r\n formatDayName,\r\n formatDayNumber,\r\n formatMonthYear,\r\n formatValue,\r\n resolveFirstDayOfWeek,\r\n weekdayHeaders,\r\n} from './calendar-intl';\r\n\r\ninterface DayCell {\r\n readonly key: string;\r\n readonly iso: string | null;\r\n readonly dayNum: string;\r\n readonly srName: string;\r\n readonly today: boolean;\r\n readonly selected: boolean;\r\n readonly disabled: boolean;\r\n readonly focused: boolean;\r\n}\r\n\r\ninterface WeekRow {\r\n readonly key: number;\r\n readonly days: DayCell[];\r\n}\r\n\r\nlet nextDatePickerId = 0;\r\n\r\n/**\r\n * SkraDatePicker — pick a single **calendar date** from an APG Date Picker grid in the native top layer.\r\n * Second Tier-3 component. A value-display **trigger** (`<button>`) opens a non-modal top-layer **calendar\r\n * panel** (Popover API, `popover=\"auto\"`, ADR 0044). The value is an **ISO 8601 date-only string**\r\n * (`YYYY-MM-DD`), consumer-owned (ADR 0050/037 — NO `@angular/forms`); all date math is the zoneless\r\n * UTC-calculator discipline in `calendar-math` (no date library). Localization (month/weekday names,\r\n * first-day-of-week, digits) is `Intl`-derived in `calendar-intl`; the 2-D grid keyboard is the\r\n * hand-rolled `SkraCalendarKeyboard` (ADR 0044 §7 — roving REAL focus, not aria-activedescendant).\r\n *\r\n * No projected content: the calendar days are GENERATED (the structural divergence from select/combobox —\r\n * there is no `skra-option` reuse). The only focusable element in the open panel is the roving day cell;\r\n * the month-nav buttons are pointer affordances (`tabindex=\"-1\"`, driven by PageUp/PageDown on keyboard),\r\n * and Tab dismisses — so no focus-containment machinery is needed (spec Q-1).\r\n *\r\n * Full contract: adr/specs/component-datepicker-spec.md.\r\n */\r\n@Component({\r\n selector: 'skra-datepicker',\r\n standalone: true,\r\n exportAs: 'skraDatePicker',\r\n template: `\r\n <button\r\n #trigger\r\n class=\"skra-datepicker-trigger\"\r\n type=\"button\"\r\n role=\"combobox\"\r\n aria-haspopup=\"dialog\"\r\n [attr.id]=\"triggerId()\"\r\n [attr.popovertarget]=\"panelId\"\r\n [attr.aria-controls]=\"panelId\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n [attr.aria-describedby]=\"describedBy()\"\r\n [attr.aria-invalid]=\"hasError() ? 'true' : null\"\r\n [attr.aria-required]=\"isRequired() ? 'true' : null\"\r\n [attr.aria-readonly]=\"isReadonly() ? 'true' : null\"\r\n [disabled]=\"isDisabled()\"\r\n (click)=\"onTriggerClick($event)\"\r\n (keydown)=\"onTriggerKeydown($event)\"\r\n >\r\n @if (formattedValue(); as label) {\r\n <span class=\"skra-datepicker-value\">{{ label }}</span>\r\n } @else {\r\n <span class=\"skra-datepicker-placeholder\">{{ placeholder() }}</span>\r\n }\r\n <svg\r\n class=\"skra-datepicker-icon\"\r\n aria-hidden=\"true\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n >\r\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"17\" rx=\"2\" />\r\n <path d=\"M3 9h18M8 2v4M16 2v4\" />\r\n </svg>\r\n </button>\r\n\r\n <div\r\n #panel\r\n class=\"skra-datepicker-panel\"\r\n [id]=\"panelId\"\r\n popover=\"auto\"\r\n role=\"dialog\"\r\n aria-modal=\"false\"\r\n [attr.aria-labelledby]=\"monthYearId\"\r\n (toggle)=\"onPanelToggle($event)\"\r\n >\r\n <div class=\"skra-datepicker-header\">\r\n <button\r\n type=\"button\"\r\n class=\"skra-datepicker-nav\"\r\n tabindex=\"-1\"\r\n [attr.aria-label]=\"prevMonthLabel()\"\r\n (click)=\"goToPreviousMonth()\"\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n aria-hidden=\"true\"\r\n >\r\n <path d=\"M15 6l-6 6 6 6\" />\r\n </svg>\r\n </button>\r\n <span\r\n class=\"skra-datepicker-monthyear\"\r\n [id]=\"monthYearId\"\r\n aria-live=\"polite\"\r\n >{{ monthYearLabel() }}</span\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"skra-datepicker-nav\"\r\n tabindex=\"-1\"\r\n [attr.aria-label]=\"nextMonthLabel()\"\r\n (click)=\"goToNextMonth()\"\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n aria-hidden=\"true\"\r\n >\r\n <path d=\"M9 6l6 6-6 6\" />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <table\r\n class=\"skra-datepicker-grid\"\r\n role=\"grid\"\r\n [attr.aria-labelledby]=\"monthYearId\"\r\n >\r\n <thead>\r\n <tr>\r\n @for (wd of weekdayHeadersView(); track wd.key) {\r\n <th scope=\"col\" class=\"skra-datepicker-weekday\">\r\n <abbr [title]=\"wd.long\">{{ wd.short }}</abbr>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (week of weeks(); track week.key) {\r\n <tr>\r\n @for (cell of week.days; track cell.key) {\r\n @if (cell.iso) {\r\n <td\r\n role=\"gridcell\"\r\n [attr.aria-selected]=\"cell.selected ? 'true' : null\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"skra-datepicker-day\"\r\n [attr.tabindex]=\"cell.focused ? 0 : -1\"\r\n [attr.aria-current]=\"cell.today ? 'date' : null\"\r\n [attr.aria-disabled]=\"cell.disabled ? 'true' : null\"\r\n [attr.data-skra-selected]=\"cell.selected ? '' : null\"\r\n [attr.data-skra-today]=\"cell.today ? '' : null\"\r\n (click)=\"selectDate(cell.iso)\"\r\n (keydown)=\"onGridKeydown($event)\"\r\n >\r\n {{ cell.dayNum\r\n }}<span class=\"skra-datepicker-day-sr\" skra-sr-only>{{\r\n cell.srName\r\n }}</span>\r\n </button>\r\n </td>\r\n } @else {\r\n <td class=\"skra-datepicker-day-empty\" aria-hidden=\"true\"></td>\r\n }\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n `,\r\n styleUrl: './datepicker.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n '[attr.data-skra-disabled]': 'isDisabled() ? \"\" : null',\r\n '[attr.data-skra-readonly]': 'isReadonly() ? \"\" : null',\r\n '[attr.data-skra-validation]': 'hasError() ? \"invalid\" : null',\r\n },\r\n})\r\nexport class SkraDatePicker {\r\n /** Consumer-owned value: ISO 8601 date-only (`YYYY-MM-DD`); `''` = unset. NEVER a Date (ADR 0050/037). */\r\n readonly value = input<string>('');\r\n /** Inclusive lower bound (ISO); `''` = unbounded (ADR 0050 §2). */\r\n readonly min = input<string>('');\r\n /** Inclusive upper bound (ISO); `''` = unbounded. */\r\n readonly max = input<string>('');\r\n /** `Intl` locale (BCP-47); `undefined` → host default (ADR 0050 §5). */\r\n readonly locale = input<string | undefined>(undefined);\r\n /** First day of week, ISO 1=Mon … 7=Sun; overrides `Intl.getWeekInfo` (the MVP safety valve, ADR 0050 §5). */\r\n readonly firstDayOfWeek = input<number | undefined>(undefined);\r\n /** Value-empty hint in the trigger (NOT the accessible name — ADR 033). */\r\n readonly placeholder = input<string>('');\r\n /** Placement intent; flip/shift adjust at runtime. */\r\n readonly placement = input<SkraPlacement>('bottom');\r\n /** Standalone availability source — `SkraFieldContext` wins when present. */\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n readonly readonly = input(false, { transform: booleanAttribute });\r\n\r\n /** Fires ONLY on user date selection — never on a programmatic `value()` change (ADR 037/0050). */\r\n readonly valueChange = output<string>();\r\n\r\n private readonly triggerRef =\r\n viewChild<ElementRef<HTMLButtonElement>>('trigger');\r\n private readonly panelRef = viewChild<ElementRef<HTMLElement>>('panel');\r\n\r\n private readonly context = inject(SkraFieldContext, { optional: true });\r\n private readonly injector = inject(Injector);\r\n private readonly keyboard = new SkraCalendarKeyboard();\r\n\r\n readonly panelId = `skra-datepicker-${nextDatePickerId}`;\r\n readonly monthYearId = `skra-datepicker-monthyear-${nextDatePickerId++}`;\r\n protected readonly isOpen = signal(false);\r\n\r\n /** Today's LOCAL date (ADR 0050 §3) — stable for the session. */\r\n private readonly todayIso = today();\r\n /** The roving-focus day; SINGLE source of truth for what the grid shows AND which cell is focusable. */\r\n private readonly focusedIso = signal(this.todayIso);\r\n\r\n private positioner?: _PositionerHandle;\r\n /** Set when a close should return focus to the trigger (keyboard/select), not on outside-click. */\r\n private returnFocus = false;\r\n\r\n // ── Availability / validation (SkraFieldContext, ADR 013, with standalone fallbacks) ──\r\n protected readonly isDisabled = computed(\r\n () => this.context?.isDisabled() ?? this.disabled(),\r\n );\r\n protected readonly isReadonly = computed(\r\n () => this.context?.isReadonly() ?? this.readonly(),\r\n );\r\n protected readonly hasError = computed(\r\n () => this.context?.hasError() ?? false,\r\n );\r\n protected readonly isRequired = computed(\r\n () => this.context?.isRequired() ?? false,\r\n );\r\n protected readonly triggerId = computed(\r\n () => this.context?.fieldId() || null,\r\n );\r\n protected readonly describedBy = computed(\r\n () => this.context?.describedByIds() ?? null,\r\n );\r\n\r\n // ── Derived calendar state ──\r\n /** The committed value, defensively normalized: invalid/out-of-range → `''` for display (ADR 0050 §1). */\r\n protected readonly selectedIso = computed(() => {\r\n const v = this.value();\r\n return isValidIso(v) && isInRange(v, this.min(), this.max()) ? v : '';\r\n });\r\n protected readonly formattedValue = computed(() =>\r\n formatValue(this.selectedIso(), this.locale()),\r\n );\r\n private readonly firstDow = computed(() =>\r\n resolveFirstDayOfWeek(this.firstDayOfWeek(), this.locale()),\r\n );\r\n /** The month being shown — always the focused day's month (keeps the roving tabindex valid). */\r\n private readonly displayedMonth = computed(() => {\r\n const p = parseIso(this.focusedIso()) ?? parseIso(this.todayIso)!;\r\n return { y: p.y, m: p.m };\r\n });\r\n protected readonly monthYearLabel = computed(() =>\r\n formatMonthYear(\r\n this.displayedMonth().y,\r\n this.displayedMonth().m,\r\n this.locale(),\r\n ),\r\n );\r\n protected readonly prevMonthLabel = computed(() => this.monthOffsetLabel(-1));\r\n protected readonly nextMonthLabel = computed(() => this.monthOffsetLabel(1));\r\n protected readonly weekdayHeadersView = computed(() =>\r\n weekdayHeaders(this.firstDow(), this.locale()),\r\n );\r\n protected readonly weeks = computed<WeekRow[]>(() => {\r\n const { y, m } = this.displayedMonth();\r\n const loc = this.locale();\r\n const sel = this.selectedIso();\r\n const foc = this.focusedIso();\r\n const min = this.min();\r\n const max = this.max();\r\n return monthGrid(y, m, this.firstDow()).map((week, wi) => ({\r\n key: wi,\r\n days: week.map((iso, di) =>\r\n iso === null\r\n ? this.emptyCell(`${wi}-${di}`)\r\n : {\r\n key: iso,\r\n iso,\r\n dayNum: formatDayNumber(parseIso(iso)!.d, loc),\r\n srName: formatDayName(iso, loc),\r\n today: iso === this.todayIso,\r\n selected: iso === sel,\r\n disabled: !isInRange(iso, min, max),\r\n focused: iso === foc,\r\n },\r\n ),\r\n }));\r\n });\r\n\r\n constructor() {\r\n inject(DestroyRef).onDestroy(() => this.positioner?.destroy());\r\n if (typeof ngDevMode !== 'undefined' && ngDevMode) {\r\n // Dev-only sanity warnings (stripped in prod) — never thrown (ADR 0050 §1).\r\n const warn = computed(() => {\r\n const v = this.value();\r\n if (v !== '' && !isValidIso(v))\r\n return `skra-datepicker: value \"${v}\" is not a valid YYYY-MM-DD date; shown as unset.`;\r\n if (\r\n this.min() !== '' &&\r\n this.max() !== '' &&\r\n compareIso(this.min(), this.max()) > 0\r\n )\r\n return `skra-datepicker: min \"${this.min()}\" is after max \"${this.max()}\" — every day is disabled.`;\r\n return null;\r\n });\r\n afterNextRender(\r\n () => {\r\n const message = warn();\r\n if (message) console.warn(message);\r\n },\r\n { injector: this.injector },\r\n );\r\n }\r\n }\r\n\r\n // ── Trigger interaction ──\r\n protected onTriggerClick(event: MouseEvent): void {\r\n if (this.isReadonly()) event.preventDefault(); // block the native popovertarget open\r\n }\r\n\r\n protected onTriggerKeydown(event: KeyboardEvent): void {\r\n if (this.isDisabled() || this.isReadonly() || this.isOpen()) return;\r\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\r\n event.preventDefault();\r\n this.open(); // Enter/Space/click open via the native popovertarget\r\n }\r\n }\r\n\r\n // ── Grid keyboard (APG Date Picker, 2-D) ──\r\n protected onGridKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Tab') {\r\n // APG: Tab dismisses the calendar; focus returns to the trigger (deterministic, no containment).\r\n event.preventDefault();\r\n this.returnFocus = true;\r\n this.close();\r\n return;\r\n }\r\n const intent = this.keyboard.resolve(event, {\r\n focusedIso: this.focusedIso(),\r\n firstDayOfWeek: this.firstDow(),\r\n });\r\n switch (intent.type) {\r\n case 'focus':\r\n event.preventDefault();\r\n this.focusedIso.set(intent.iso);\r\n this.scheduleFocus(); // re-focus after the grid re-stamps\r\n break;\r\n case 'select':\r\n event.preventDefault();\r\n this.selectDate(this.focusedIso());\r\n break;\r\n case 'close':\r\n this.returnFocus = true;\r\n this.close();\r\n break;\r\n case 'none':\r\n break;\r\n }\r\n }\r\n\r\n // ── Month navigation (pointer; focus stays on the nav button) ──\r\n protected goToPreviousMonth(): void {\r\n this.focusedIso.set(addMonthsClamped(this.focusedIso(), -1));\r\n }\r\n protected goToNextMonth(): void {\r\n this.focusedIso.set(addMonthsClamped(this.focusedIso(), 1));\r\n }\r\n\r\n // ── Selection ──\r\n protected selectDate(iso: string): void {\r\n if (!isInRange(iso, this.min(), this.max())) return; // guard out-of-range (one place: keyboard + pointer)\r\n this.returnFocus = true;\r\n this.valueChange.emit(iso);\r\n this.close();\r\n }\r\n\r\n // ── Panel open / close (native toggle from the Popover API) ──\r\n protected onPanelToggle(event: Event): void {\r\n const open = (event as ToggleEvent).newState === 'open';\r\n this.isOpen.set(open);\r\n if (open) this.onOpen();\r\n else this.onClose();\r\n }\r\n\r\n private onOpen(): void {\r\n this.focusedIso.set(this.seedFocus());\r\n const anchor = this.triggerRef()?.nativeElement;\r\n const panel = this.panelRef()?.nativeElement;\r\n if (anchor && panel) {\r\n this.positioner?.destroy();\r\n this.positioner = _attachPositioner(anchor, panel, () => ({\r\n placement: this.placement(),\r\n offset: this.cssLenPx('--skra-comp-datepicker-panel-offset'),\r\n viewportPadding: this.cssLenPx(\r\n '--skra-comp-datepicker-panel-viewport-padding',\r\n ),\r\n }));\r\n }\r\n this.scheduleFocus();\r\n }\r\n\r\n private onClose(): void {\r\n this.positioner?.destroy();\r\n this.positioner = undefined;\r\n if (this.returnFocus) {\r\n this.returnFocus = false;\r\n this.triggerRef()?.nativeElement.focus();\r\n }\r\n }\r\n\r\n private open(): void {\r\n this.panelRef()?.nativeElement.showPopover?.();\r\n }\r\n private close(): void {\r\n this.panelRef()?.nativeElement.hidePopover?.();\r\n }\r\n\r\n /** Seed the focused day on open: the valid current value, else today, clamped into `[min,max]`. */\r\n private seedFocus(): string {\r\n const v = this.value();\r\n const base = isValidIso(v) ? v : this.todayIso;\r\n return clampIso(base, this.min(), this.max());\r\n }\r\n\r\n private monthOffsetLabel(n: number): string {\r\n const { y, m } = this.displayedMonth();\r\n const ref = parseIso(addMonthsClamped(toIso({ y, m, d: 1 }), n))!;\r\n return formatMonthYear(ref.y, ref.m, this.locale());\r\n }\r\n\r\n private emptyCell(key: string): DayCell {\r\n return {\r\n key,\r\n iso: null,\r\n dayNum: '',\r\n srName: '',\r\n today: false,\r\n selected: false,\r\n disabled: true,\r\n focused: false,\r\n };\r\n }\r\n\r\n private scheduleFocus(): void {\r\n afterNextRender(() => this.focusActiveDay(), { injector: this.injector });\r\n }\r\n\r\n private focusActiveDay(): void {\r\n this.panelRef()\r\n ?.nativeElement.querySelector<HTMLElement>(\r\n '.skra-datepicker-day[tabindex=\"0\"]',\r\n )\r\n ?.focus();\r\n }\r\n\r\n /** Read a length comp token (px/rem) off the panel computed style for the positioner. */\r\n private cssLenPx(prop: string): number {\r\n const el = this.panelRef()?.nativeElement;\r\n if (!el) return 0;\r\n const raw = getComputedStyle(el).getPropertyValue(prop).trim();\r\n if (raw.endsWith('px')) return parseFloat(raw);\r\n if (raw.endsWith('rem')) {\r\n const rootFontSize =\r\n parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\r\n return parseFloat(raw) * rootFontSize;\r\n }\r\n return parseFloat(raw) || 0;\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -31,7 +31,8 @@ function deepActiveElement() {
|
|
|
31
31
|
*/
|
|
32
32
|
class SkraDialog {
|
|
33
33
|
/** Width bucket (ADR 035). No look inputs (ADR 025); no `ariaLabel` (ADR 033). */
|
|
34
|
-
size = input('md',
|
|
34
|
+
size = input('md', /* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
35
36
|
/**
|
|
36
37
|
* Emitted from `showModal()` once the dialog has entered the top layer. Fills a genuine
|
|
37
38
|
* NATIVE GAP — `<dialog>` fires no "open" event, so the dialog's owner otherwise cannot
|
|
@@ -108,10 +109,10 @@ class SkraDialog {
|
|
|
108
109
|
'browser default initial focus is inconsistent.');
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
112
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
112
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
113
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.1", type: SkraDialog, isStandalone: true, selector: "dialog[skraDialog]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened" }, host: { listeners: { "close": "onClose()", "keydown": "onKeydown($event)" }, properties: { "attr.data-skra-size": "size()" } }, exportAs: ["skraDialog"], ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["@charset \"UTF-8\";:host{box-sizing:border-box;background:var(--skra-comp-dialog-background);color:var(--skra-comp-dialog-foreground);border-color:var(--skra-comp-dialog-border-color);border-width:var(--skra-comp-dialog-border-width);border-style:var(--skra-comp-dialog-border-style);border-radius:var(--skra-comp-dialog-radius);padding-block:var(--skra-comp-dialog-padding-block);padding-inline:var(--skra-comp-dialog-padding-inline);box-shadow:var(--skra-comp-dialog-shadow);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);inline-size:100%;max-inline-size:var(--skra-comp-dialog-size-md-max-inline-size);max-block-size:calc(100dvh - 2 * var(--skra-sys-spacing-4));overflow:auto;opacity:1;transition:opacity var(--skra-comp-dialog-motion-duration) var(--skra-comp-dialog-motion-easing),display var(--skra-comp-dialog-motion-duration) allow-discrete,overlay var(--skra-comp-dialog-motion-duration) allow-discrete}@starting-style{:host{opacity:0}}:host:focus-visible{outline-style:solid;outline-color:var(--skra-comp-dialog-focus-ring-color);outline-width:var(--skra-comp-dialog-focus-ring-width);outline-offset:2px}:host([data-skra-size=sm]){max-inline-size:var(--skra-comp-dialog-size-sm-max-inline-size)}:host([data-skra-size=lg]){max-inline-size:var(--skra-comp-dialog-size-lg-max-inline-size)}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
113
114
|
}
|
|
114
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraDialog, decorators: [{
|
|
115
116
|
type: Component,
|
|
116
117
|
args: [{ selector: 'dialog[skraDialog]', standalone: true, exportAs: 'skraDialog', template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
|
|
117
118
|
// Variant Surface reflection (ADR 035 Size axis)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skra-ui-dialog.mjs","sources":["../../../../libs/ui/dialog/src/lib/dialog/dialog.ts","../../../../libs/ui/dialog/src/skra-ui-dialog.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n inject,\n input,\n output,\n} from '@angular/core';\n\n/**\n * DialogSize — width bucket (Variant Surface, ADR 035 Size axis).\n * Closed enum; extension requires an ADR 035 amendment.\n */\nexport type DialogSize = 'sm' | 'md' | 'lg';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/** Tab-focusable elements — for the dev-mode \"no focus target\" nudge only. */\nconst FOCUSABLE_SELECTOR =\n 'a[href],area[href],button:not([disabled]),input:not([disabled]),' +\n 'select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"]),' +\n 'details,summary,[contenteditable]:not([contenteditable=\"false\"])';\n\n/**\n * Composed active element across open shadow roots — the real focused control when the\n * trigger lives inside a Shadow DOM subtree (microfrontend isolation).\n */\nfunction deepActiveElement(): HTMLElement | null {\n let active = document.activeElement as HTMLElement | null;\n while (active?.shadowRoot?.activeElement) {\n active = active.shadowRoot.activeElement as HTMLElement;\n }\n return active;\n}\n\n/**\n * SkraDialog — a Component on the native `<dialog>` host (ADR 012/040/041), rendered in the\n * browser TOP LAYER via `showModal()` (ADR 0044 — no portal, no z-index, dependency-free).\n *\n * Forge owns the token-driven surface + size + enter/leave motion (see `dialog.scss`) and the\n * focus contract (ADR 0044 §3 rule 8): deterministic INITIAL focus via the native `autofocus`\n * attribute (consumer-placed), plus a focus-RETURN safety net. Open/closed state, `role=\"dialog\"`,\n * `aria-modal`, Escape, the `::backdrop` scrim, scroll-lock and focus containment are NATIVE\n * (the scrim + scroll-lock live in the global `_overlay.scss` slice). Accessible name is consumer\n * `aria-labelledby` → projected heading (ADR 033 container carve-out — no `ariaLabel` input).\n *\n * Full contract: adr/specs/component-dialog-spec.md.\n */\n@Component({\n selector: 'dialog[skraDialog]',\n standalone: true,\n exportAs: 'skraDialog',\n template: '<ng-content></ng-content>',\n styleUrl: './dialog.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n // Variant Surface reflection (ADR 035 Size axis)\n '[attr.data-skra-size]': 'size()',\n // Focus-return safety net — fires on EVERY close path (Escape / form submit / close())\n '(close)': 'onClose()',\n // Focus TRAP (ADR 0044 §3 rule 8 — minimal scoped JS where native is insufficient):\n // native `showModal()` makes the background inert, but does NOT cycle Tab last<->first and\n // lets focus escape an enclosing iframe / micro-frontend boundary. This wraps focus in.\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class SkraDialog {\n /** Width bucket (ADR 035). No look inputs (ADR 025); no `ariaLabel` (ADR 033). */\n readonly size = input<DialogSize>('md');\n\n /**\n * Emitted from `showModal()` once the dialog has entered the top layer. Fills a genuine\n * NATIVE GAP — `<dialog>` fires no \"open\" event, so the dialog's owner otherwise cannot\n * observe opening decoupled from whoever called `showModal()` (lazy content, analytics, …).\n *\n * There is deliberately NO `closed`/`cancel` output (native-first, boundary #9): the native\n * `<dialog>` `(close)`/`(cancel)` events already serve the owner directly on the element\n * (with `returnValue`). A Forge output would duplicate a native event.\n */\n readonly opened = output<void>();\n\n private readonly host = inject<ElementRef<HTMLDialogElement>>(ElementRef);\n private previouslyFocused: HTMLElement | null = null;\n\n /** Native `.open` state (read-only proxy; open/closed stays native — ADR 0044). */\n get open(): boolean {\n return this.host.nativeElement.open;\n }\n\n /** Open as a modal: store the trigger for focus-return, then native `showModal()`. */\n showModal(): void {\n this.previouslyFocused = deepActiveElement();\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n this.warnIfNoFocusTarget();\n }\n this.host.nativeElement.showModal();\n this.opened.emit();\n }\n\n /** Close the dialog. The native `close` event drives focus-return (see `onClose`). */\n close(returnValue?: string): void {\n this.host.nativeElement.close(returnValue);\n }\n\n /** Restore focus to the trigger on any close path (Escape / form submit / `close()`). */\n protected onClose(): void {\n // Restore only if the trigger is still in the document (it may have been removed while\n // the dialog was open). Focusing a detached node is a no-op; guard keeps intent explicit.\n if (this.previouslyFocused?.isConnected) this.previouslyFocused.focus();\n this.previouslyFocused = null;\n }\n\n /**\n * Wrap Tab focus within the modal (ADR 0044 §3 rule 8). Native `showModal()` makes the\n * background `inert` but does NOT cycle Tab last<->first and lets focus leave an enclosing\n * iframe / micro-frontend boundary — the WCAG-over-native gap this minimal JS closes. Modal\n * only (`:modal`); non-modal open dialogs are not trapped. Host-scoped DOM access only.\n */\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab') return;\n const el = this.host.nativeElement;\n if (!el.matches(':modal')) return;\n const focusables = Array.from(\n el.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n );\n if (focusables.length === 0) {\n event.preventDefault();\n return;\n }\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = deepActiveElement();\n if (event.shiftKey && (active === first || active === el)) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n }\n\n /** Dev-only a11y nudge: native default initial focus is inconsistent without `autofocus`. */\n private warnIfNoFocusTarget(): void {\n const el = this.host.nativeElement;\n if (\n !el.querySelector('[autofocus]') &&\n !el.querySelector(FOCUSABLE_SELECTOR)\n ) {\n console.warn(\n '[skraDialog] opened with no focusable element or [autofocus] target. ' +\n 'Place `autofocus` on the intended initial control (WAI-ARIA APG) — ' +\n 'browser default initial focus is inconsistent.',\n );\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;AAkBA;AACA,MAAM,kBAAkB,GACtB,kEAAkE;IAClE,kFAAkF;AAClF,IAAA,kEAAkE;AAEpE;;;AAGG;AACH,SAAS,iBAAiB,GAAA;AACxB,IAAA,IAAI,MAAM,GAAG,QAAQ,CAAC,aAAmC;AACzD,IAAA,OAAO,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE;AACxC,QAAA,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,aAA4B;IACzD;AACA,IAAA,OAAO,MAAM;AACf;AAEA;;;;;;;;;;;;AAYG;MAoBU,UAAU,CAAA;;
|
|
1
|
+
{"version":3,"file":"skra-ui-dialog.mjs","sources":["../../../../libs/ui/dialog/src/lib/dialog/dialog.ts","../../../../libs/ui/dialog/src/skra-ui-dialog.ts"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n ViewEncapsulation,\r\n inject,\r\n input,\r\n output,\r\n} from '@angular/core';\r\n\r\n/**\r\n * DialogSize — width bucket (Variant Surface, ADR 035 Size axis).\r\n * Closed enum; extension requires an ADR 035 amendment.\r\n */\r\nexport type DialogSize = 'sm' | 'md' | 'lg';\r\n\r\ndeclare const ngDevMode: boolean | undefined;\r\n\r\n/** Tab-focusable elements — for the dev-mode \"no focus target\" nudge only. */\r\nconst FOCUSABLE_SELECTOR =\r\n 'a[href],area[href],button:not([disabled]),input:not([disabled]),' +\r\n 'select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"]),' +\r\n 'details,summary,[contenteditable]:not([contenteditable=\"false\"])';\r\n\r\n/**\r\n * Composed active element across open shadow roots — the real focused control when the\r\n * trigger lives inside a Shadow DOM subtree (microfrontend isolation).\r\n */\r\nfunction deepActiveElement(): HTMLElement | null {\r\n let active = document.activeElement as HTMLElement | null;\r\n while (active?.shadowRoot?.activeElement) {\r\n active = active.shadowRoot.activeElement as HTMLElement;\r\n }\r\n return active;\r\n}\r\n\r\n/**\r\n * SkraDialog — a Component on the native `<dialog>` host (ADR 012/040/041), rendered in the\r\n * browser TOP LAYER via `showModal()` (ADR 0044 — no portal, no z-index, dependency-free).\r\n *\r\n * Forge owns the token-driven surface + size + enter/leave motion (see `dialog.scss`) and the\r\n * focus contract (ADR 0044 §3 rule 8): deterministic INITIAL focus via the native `autofocus`\r\n * attribute (consumer-placed), plus a focus-RETURN safety net. Open/closed state, `role=\"dialog\"`,\r\n * `aria-modal`, Escape, the `::backdrop` scrim, scroll-lock and focus containment are NATIVE\r\n * (the scrim + scroll-lock live in the global `_overlay.scss` slice). Accessible name is consumer\r\n * `aria-labelledby` → projected heading (ADR 033 container carve-out — no `ariaLabel` input).\r\n *\r\n * Full contract: adr/specs/component-dialog-spec.md.\r\n */\r\n@Component({\r\n selector: 'dialog[skraDialog]',\r\n standalone: true,\r\n exportAs: 'skraDialog',\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './dialog.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // Variant Surface reflection (ADR 035 Size axis)\r\n '[attr.data-skra-size]': 'size()',\r\n // Focus-return safety net — fires on EVERY close path (Escape / form submit / close())\r\n '(close)': 'onClose()',\r\n // Focus TRAP (ADR 0044 §3 rule 8 — minimal scoped JS where native is insufficient):\r\n // native `showModal()` makes the background inert, but does NOT cycle Tab last<->first and\r\n // lets focus escape an enclosing iframe / micro-frontend boundary. This wraps focus in.\r\n '(keydown)': 'onKeydown($event)',\r\n },\r\n})\r\nexport class SkraDialog {\r\n /** Width bucket (ADR 035). No look inputs (ADR 025); no `ariaLabel` (ADR 033). */\r\n readonly size = input<DialogSize>('md');\r\n\r\n /**\r\n * Emitted from `showModal()` once the dialog has entered the top layer. Fills a genuine\r\n * NATIVE GAP — `<dialog>` fires no \"open\" event, so the dialog's owner otherwise cannot\r\n * observe opening decoupled from whoever called `showModal()` (lazy content, analytics, …).\r\n *\r\n * There is deliberately NO `closed`/`cancel` output (native-first, boundary #9): the native\r\n * `<dialog>` `(close)`/`(cancel)` events already serve the owner directly on the element\r\n * (with `returnValue`). A Forge output would duplicate a native event.\r\n */\r\n readonly opened = output<void>();\r\n\r\n private readonly host = inject<ElementRef<HTMLDialogElement>>(ElementRef);\r\n private previouslyFocused: HTMLElement | null = null;\r\n\r\n /** Native `.open` state (read-only proxy; open/closed stays native — ADR 0044). */\r\n get open(): boolean {\r\n return this.host.nativeElement.open;\r\n }\r\n\r\n /** Open as a modal: store the trigger for focus-return, then native `showModal()`. */\r\n showModal(): void {\r\n this.previouslyFocused = deepActiveElement();\r\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\r\n this.warnIfNoFocusTarget();\r\n }\r\n this.host.nativeElement.showModal();\r\n this.opened.emit();\r\n }\r\n\r\n /** Close the dialog. The native `close` event drives focus-return (see `onClose`). */\r\n close(returnValue?: string): void {\r\n this.host.nativeElement.close(returnValue);\r\n }\r\n\r\n /** Restore focus to the trigger on any close path (Escape / form submit / `close()`). */\r\n protected onClose(): void {\r\n // Restore only if the trigger is still in the document (it may have been removed while\r\n // the dialog was open). Focusing a detached node is a no-op; guard keeps intent explicit.\r\n if (this.previouslyFocused?.isConnected) this.previouslyFocused.focus();\r\n this.previouslyFocused = null;\r\n }\r\n\r\n /**\r\n * Wrap Tab focus within the modal (ADR 0044 §3 rule 8). Native `showModal()` makes the\r\n * background `inert` but does NOT cycle Tab last<->first and lets focus leave an enclosing\r\n * iframe / micro-frontend boundary — the WCAG-over-native gap this minimal JS closes. Modal\r\n * only (`:modal`); non-modal open dialogs are not trapped. Host-scoped DOM access only.\r\n */\r\n protected onKeydown(event: KeyboardEvent): void {\r\n if (event.key !== 'Tab') return;\r\n const el = this.host.nativeElement;\r\n if (!el.matches(':modal')) return;\r\n const focusables = Array.from(\r\n el.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\r\n );\r\n if (focusables.length === 0) {\r\n event.preventDefault();\r\n return;\r\n }\r\n const first = focusables[0];\r\n const last = focusables[focusables.length - 1];\r\n const active = deepActiveElement();\r\n if (event.shiftKey && (active === first || active === el)) {\r\n event.preventDefault();\r\n last.focus();\r\n } else if (!event.shiftKey && active === last) {\r\n event.preventDefault();\r\n first.focus();\r\n }\r\n }\r\n\r\n /** Dev-only a11y nudge: native default initial focus is inconsistent without `autofocus`. */\r\n private warnIfNoFocusTarget(): void {\r\n const el = this.host.nativeElement;\r\n if (\r\n !el.querySelector('[autofocus]') &&\r\n !el.querySelector(FOCUSABLE_SELECTOR)\r\n ) {\r\n console.warn(\r\n '[skraDialog] opened with no focusable element or [autofocus] target. ' +\r\n 'Place `autofocus` on the intended initial control (WAI-ARIA APG) — ' +\r\n 'browser default initial focus is inconsistent.',\r\n );\r\n }\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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"}
|
|
@@ -10,10 +10,10 @@ class IdGeneratorService {
|
|
|
10
10
|
nextId(prefix = 'fg') {
|
|
11
11
|
return `${prefix}-${++this.counter}`;
|
|
12
12
|
}
|
|
13
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
14
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
13
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: IdGeneratorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
14
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: IdGeneratorService, providedIn: 'root' });
|
|
15
15
|
}
|
|
16
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
16
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: IdGeneratorService, decorators: [{
|
|
17
17
|
type: Injectable,
|
|
18
18
|
args: [{ providedIn: 'root' }]
|
|
19
19
|
}] });
|
|
@@ -24,38 +24,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
24
24
|
* Implements ADR 013: Signal-based Contextual Interaction.
|
|
25
25
|
*/
|
|
26
26
|
class SkraFieldContext {
|
|
27
|
-
fieldId = signal('',
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
fieldId = signal('', /* @ts-ignore */
|
|
28
|
+
...(ngDevMode ? [{ debugName: "fieldId" }] : /* istanbul ignore next */ []));
|
|
29
|
+
hasError = signal(false, /* @ts-ignore */
|
|
30
|
+
...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
|
|
31
|
+
isDisabled = signal(false, /* @ts-ignore */
|
|
32
|
+
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
33
|
+
isRequired = signal(false, /* @ts-ignore */
|
|
34
|
+
...(ngDevMode ? [{ debugName: "isRequired" }] : /* istanbul ignore next */ []));
|
|
35
|
+
isReadonly = signal(false, /* @ts-ignore */
|
|
36
|
+
...(ngDevMode ? [{ debugName: "isReadonly" }] : /* istanbul ignore next */ []));
|
|
32
37
|
// Derived IDs for aria-describedby linkage
|
|
33
|
-
hintId = computed(() => `${this.fieldId()}-hint`,
|
|
34
|
-
|
|
38
|
+
hintId = computed(() => `${this.fieldId()}-hint`, /* @ts-ignore */
|
|
39
|
+
...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
|
|
40
|
+
errorId = computed(() => `${this.fieldId()}-error`, /* @ts-ignore */
|
|
41
|
+
...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
|
|
35
42
|
// Derived label ID. Labelable controls (input/checkbox/radio) associate via the
|
|
36
43
|
// native `for`/`id` pair, so they never needed a referenceable label id. A
|
|
37
44
|
// `role="radiogroup"` host (<skra-star-rating>) is NOT labelable by `for`, so it
|
|
38
45
|
// must name itself via `aria-labelledby` → the label needs an id. This is the third
|
|
39
46
|
// derived id alongside hintId/errorId — an id, never a value (ADR 013 §3.6; the
|
|
40
47
|
// context carries id + derived state only). Set on `label[skraLabelFor]`.
|
|
41
|
-
labelId = computed(() => `${this.fieldId()}-label`,
|
|
48
|
+
labelId = computed(() => `${this.fieldId()}-label`, /* @ts-ignore */
|
|
49
|
+
...(ngDevMode ? [{ debugName: "labelId" }] : /* istanbul ignore next */ []));
|
|
42
50
|
// Combined aria-describedby tokens for the input/textarea host.
|
|
43
51
|
// Both ids are always emitted — when <skra-hint> or <skra-error> is not
|
|
44
52
|
// rendered, the matching DOM node is absent and browsers / screen readers
|
|
45
53
|
// gracefully ignore the dangling reference. Simpler than tracking presence
|
|
46
54
|
// via contentChild queries from the directive (which has no template).
|
|
47
|
-
describedByIds = computed(() => `${this.hintId()} ${this.errorId()}`,
|
|
48
|
-
|
|
49
|
-
static
|
|
55
|
+
describedByIds = computed(() => `${this.hintId()} ${this.errorId()}`, /* @ts-ignore */
|
|
56
|
+
...(ngDevMode ? [{ debugName: "describedByIds" }] : /* istanbul ignore next */ []));
|
|
57
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraFieldContext, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
58
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraFieldContext });
|
|
50
59
|
}
|
|
51
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
60
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraFieldContext, decorators: [{
|
|
52
61
|
type: Injectable
|
|
53
62
|
}] });
|
|
54
63
|
|
|
55
64
|
class SkraField {
|
|
56
65
|
idGen = inject(IdGeneratorService);
|
|
57
66
|
context = inject(SkraFieldContext);
|
|
58
|
-
fieldId = input(null,
|
|
67
|
+
fieldId = input(null, /* @ts-ignore */
|
|
68
|
+
...(ngDevMode ? [{ debugName: "fieldId" }] : /* istanbul ignore next */ []));
|
|
59
69
|
readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
60
70
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
61
71
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
@@ -78,10 +88,10 @@ class SkraField {
|
|
|
78
88
|
ngOnInit() {
|
|
79
89
|
this.context.fieldId.set(this.fieldId() ?? this.idGen.nextId('fg'));
|
|
80
90
|
}
|
|
81
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
82
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
91
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
92
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.1", type: SkraField, isStandalone: true, selector: "skra-field", inputs: { fieldId: { classPropertyName: "fieldId", publicName: "fieldId", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group" }, properties: { "attr.data-skra-validation": "context.hasError() ? \"invalid\" : null", "attr.data-skra-disabled": "context.isDisabled() ? \"\" : null", "attr.data-skra-required": "context.isRequired() ? \"\" : null", "attr.data-skra-readonly": "context.isReadonly() ? \"\" : null" } }, providers: [SkraFieldContext], ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{margin:0;display:flex;flex-direction:column;gap:var(--skra-comp-field-gap)}:host[data-skra-validation=invalid]{--skra-comp-field-border-color: var( --skra-comp-field-border-color-validation-invalid )}:host[data-skra-disabled],:host:has(:disabled){pointer-events:none;cursor:not-allowed}:host[data-skra-readonly]{cursor:default;--skra-comp-field-background: var(--skra-comp-field-background-readonly);--skra-comp-field-border-color: var( --skra-comp-field-border-color-readonly );--skra-comp-field-label-cursor: default;--skra-comp-field-hint-color: var(--skra-comp-field-label-color)}:host:has(input[type=checkbox][skraCheckbox]),:host:has(input[type=checkbox][skraSwitch]),:host:has(input[type=radio][skraRadio]){display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;column-gap:var(--skra-comp-field-checkbox-gap);row-gap:var(--skra-comp-field-gap)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
83
93
|
}
|
|
84
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
94
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraField, decorators: [{
|
|
85
95
|
type: Component,
|
|
86
96
|
args: [{ selector: 'skra-field', standalone: true, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, providers: [SkraFieldContext], host: {
|
|
87
97
|
// CSP-Safe State Reflection (ADR 021). The layout reset (margin) +
|
|
@@ -117,10 +127,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
117
127
|
*/
|
|
118
128
|
class SkraLabel {
|
|
119
129
|
context = inject(SkraFieldContext);
|
|
120
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
121
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
130
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraLabel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
131
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.1", type: SkraLabel, isStandalone: true, selector: "label[skraLabelFor]", host: { properties: { "htmlFor": "context.fieldId()", "id": "context.labelId()", "attr.data-skra-required": "context.isRequired() ? \"\" : null" }, classAttribute: "skra-label" }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{color:var(--skra-comp-field-label-color);font-family:var(--skra-sys-typography-role-label-medium-font-family);font-size:var(--skra-sys-typography-role-label-medium-font-size);font-weight:var(--skra-sys-typography-role-label-medium-font-weight);line-height:var(--skra-sys-typography-role-label-medium-line-height);letter-spacing:var(--skra-sys-typography-role-label-medium-letter-spacing);cursor:var(--skra-comp-field-label-cursor, pointer);transition:color var(--skra-comp-field-motion-duration) var(--skra-comp-field-motion-easing)}:host([data-skra-required]):after{content:\"*\"/\"\";margin-inline-start:var(--skra-sys-spacing-1);color:var(--skra-comp-field-required-color)}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
122
132
|
}
|
|
123
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraLabel, decorators: [{
|
|
124
134
|
type: Component,
|
|
125
135
|
args: [{ selector: 'label[skraLabelFor]', standalone: true, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
|
|
126
136
|
// The magic: auto-linking label to input via shared Context ID
|
|
@@ -145,10 +155,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
145
155
|
*/
|
|
146
156
|
class SkraHint {
|
|
147
157
|
context = inject(SkraFieldContext);
|
|
148
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
149
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
158
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraHint, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
159
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.1", type: SkraHint, isStandalone: true, selector: "skra-hint", host: { attributes: { "role": "note" }, properties: { "id": "context.hintId()" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{margin:0;display:block;font-family:var(--skra-sys-typography-role-body-small-font-family);font-size:var(--skra-sys-typography-role-body-small-font-size);font-weight:var(--skra-sys-typography-role-body-small-font-weight);line-height:var(--skra-sys-typography-role-body-small-line-height);letter-spacing:var(--skra-sys-typography-role-body-small-letter-spacing);color:var(--skra-comp-field-hint-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
150
160
|
}
|
|
151
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
161
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraHint, decorators: [{
|
|
152
162
|
type: Component,
|
|
153
163
|
args: [{ selector: 'skra-hint', standalone: true, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
|
|
154
164
|
// Zero-margin reset (ADR 022) lives in hint.component.scss `:host`.
|
|
@@ -191,10 +201,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
191
201
|
*/
|
|
192
202
|
class SkraError {
|
|
193
203
|
context = inject(SkraFieldContext);
|
|
194
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
195
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
204
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraError, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
205
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.1", type: SkraError, isStandalone: true, selector: "skra-error", host: { attributes: { "role": "alert" }, properties: { "id": "context.errorId()" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{margin:0;display:block;font-family:var(--skra-sys-typography-role-body-small-font-family);font-size:var(--skra-sys-typography-role-body-small-font-size);font-weight:var(--skra-sys-typography-role-body-small-font-weight);line-height:var(--skra-sys-typography-role-body-small-line-height);letter-spacing:var(--skra-sys-typography-role-body-small-letter-spacing);color:var(--skra-comp-field-error-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
196
206
|
}
|
|
197
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
207
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraError, decorators: [{
|
|
198
208
|
type: Component,
|
|
199
209
|
args: [{ selector: 'skra-error', standalone: true, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
|
|
200
210
|
// Zero-margin reset (ADR 022) lives in error.component.scss `:host`.
|
|
@@ -243,10 +253,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
243
253
|
*/
|
|
244
254
|
class SkraFieldset {
|
|
245
255
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
246
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
247
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
256
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraFieldset, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
257
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.1", type: SkraFieldset, isStandalone: true, selector: "fieldset[skraFieldset]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group" }, properties: { "attr.disabled": "disabled() ? \"\" : null", "attr.data-skra-disabled": "disabled() ? \"\" : null" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{border:0;padding:0;margin:0;min-inline-size:0;display:flex;flex-direction:column;gap:var(--skra-comp-field-group-gap)}:host(:disabled),:host([data-skra-disabled]){cursor:not-allowed}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
248
258
|
}
|
|
249
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
259
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraFieldset, decorators: [{
|
|
250
260
|
type: Component,
|
|
251
261
|
args: [{ selector: 'fieldset[skraFieldset]', standalone: true, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
|
|
252
262
|
role: 'group',
|
|
@@ -275,10 +285,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
275
285
|
* legends (re-parents to fieldset), but Forge documents the canonical form.
|
|
276
286
|
*/
|
|
277
287
|
class SkraLegend {
|
|
278
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
279
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
288
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraLegend, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
289
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.1", type: SkraLegend, isStandalone: true, selector: "legend[skraLegend]", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{padding:0;margin:0;margin-block-end:var(--skra-comp-field-group-legend-spacing-block-end);display:block;inline-size:100%;font-family:var(--skra-sys-typography-role-label-large-font-family);font-size:var(--skra-sys-typography-role-label-large-font-size);font-weight:var(--skra-sys-typography-role-label-large-font-weight);line-height:var(--skra-sys-typography-role-label-large-line-height);letter-spacing:var(--skra-sys-typography-role-label-large-letter-spacing);color:var(--skra-comp-field-group-legend-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
280
290
|
}
|
|
281
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
291
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraLegend, decorators: [{
|
|
282
292
|
type: Component,
|
|
283
293
|
args: [{ selector: 'legend[skraLegend]', standalone: true, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, styles: [":host{padding:0;margin:0;margin-block-end:var(--skra-comp-field-group-legend-spacing-block-end);display:block;inline-size:100%;font-family:var(--skra-sys-typography-role-label-large-font-family);font-size:var(--skra-sys-typography-role-label-large-font-size);font-weight:var(--skra-sys-typography-role-label-large-font-weight);line-height:var(--skra-sys-typography-role-label-large-line-height);letter-spacing:var(--skra-sys-typography-role-label-large-letter-spacing);color:var(--skra-comp-field-group-legend-color)}\n"] }]
|
|
284
294
|
}] });
|