ngwr 13.0.1 → 14.0.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/README.md +13 -6
- package/color-picker/styles/_index.scss +43 -5
- package/fesm2022/ngwr-alert.mjs +5 -5
- package/fesm2022/ngwr-alert.mjs.map +1 -1
- package/fesm2022/ngwr-back-top.mjs +11 -1
- package/fesm2022/ngwr-back-top.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text.mjs +13 -2
- package/fesm2022/ngwr-blur-text.mjs.map +1 -1
- package/fesm2022/ngwr-button.mjs +4 -4
- package/fesm2022/ngwr-button.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-testing.mjs +15 -0
- package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-calendar.mjs +51 -5
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text.mjs +20 -1
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-collapse.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker-testing.mjs +23 -7
- package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +89 -10
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette.mjs +27 -3
- package/fesm2022/ngwr-command-palette.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu.mjs +7 -1
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapters-fns.mjs +101 -33
- package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker-testing.mjs +10 -2
- package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +103 -13
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-date.mjs +480 -79
- package/fesm2022/ngwr-date.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +30 -2
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +2 -1
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar.mjs +1 -1
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload.mjs +52 -12
- package/fesm2022/ngwr-file-upload.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +63 -1
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +28 -1
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n.mjs +150 -22
- package/fesm2022/ngwr-i18n.mjs.map +1 -1
- package/fesm2022/ngwr-input-number.mjs +3 -3
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp.mjs +21 -3
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-input.mjs +14 -7
- package/fesm2022/ngwr-input.mjs.map +1 -1
- package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
- package/fesm2022/ngwr-knob.mjs +20 -2
- package/fesm2022/ngwr-knob.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar-router.mjs +73 -0
- package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -0
- package/fesm2022/ngwr-loading-bar.mjs +21 -32
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-mention.mjs +104 -14
- package/fesm2022/ngwr-mention.mjs.map +1 -1
- package/fesm2022/ngwr-pagination-testing.mjs +11 -10
- package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +65 -30
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm.mjs +3 -2
- package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
- package/fesm2022/ngwr-popover.mjs +2 -1
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +93 -34
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
- package/fesm2022/ngwr-squircle.mjs +2 -1
- package/fesm2022/ngwr-squircle.mjs.map +1 -1
- package/fesm2022/ngwr-statistic.mjs +35 -4
- package/fesm2022/ngwr-statistic.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +35 -12
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-router.mjs +158 -0
- package/fesm2022/ngwr-tabs-router.mjs.map +1 -0
- package/fesm2022/ngwr-tabs-testing.mjs +13 -11
- package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +98 -10
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +20 -1
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-tour.mjs +1 -1
- package/fesm2022/ngwr-tour.mjs.map +1 -1
- package/fesm2022/ngwr-transfer.mjs +2 -2
- package/fesm2022/ngwr-transfer.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +18 -2
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-utils.mjs +37 -1
- package/fesm2022/ngwr-utils.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-window-testing.mjs +10 -2
- package/fesm2022/ngwr-window-testing.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +4 -4
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/i18n/en.json +33 -6
- package/i18n/ru.json +33 -6
- package/llms-full.txt +20 -11
- package/llms.txt +47 -16
- package/mcp/catalog.js +3 -3
- package/mcp/providers.js +11 -0
- package/package.json +9 -1
- package/schematics/migrations/v13/index.js +101 -0
- package/schematics/migrations/v14/index.js +422 -0
- package/schematics/migrations.json +10 -0
- package/schematics/page/templates.js +1 -1
- package/schematics/use/symbol-map.json +1 -0
- package/skills/ngwr/SKILL.md +4 -1
- package/skills/ngwr/references/catalog.md +2 -0
- package/skills/ngwr/references/setup.md +4 -0
- package/stepper/styles/_index.scss +19 -1
- package/textarea/styles/_index.scss +14 -6
- package/toast/styles/_index.scss +12 -4
- package/types/ngwr-alert.d.ts +3 -3
- package/types/ngwr-blur-text.d.ts +8 -0
- package/types/ngwr-button.d.ts +2 -2
- package/types/ngwr-calendar-testing.d.ts +21 -4
- package/types/ngwr-calendar.d.ts +37 -0
- package/types/ngwr-circular-text.d.ts +9 -0
- package/types/ngwr-collapse.d.ts +19 -15
- package/types/ngwr-color-picker-testing.d.ts +10 -4
- package/types/ngwr-color-picker.d.ts +70 -2
- package/types/ngwr-command-palette.d.ts +14 -0
- package/types/ngwr-context-menu.d.ts +1 -1
- package/types/ngwr-date-adapters-fns.d.ts +71 -29
- package/types/ngwr-date-picker-testing.d.ts +206 -185
- package/types/ngwr-date-picker.d.ts +7 -0
- package/types/ngwr-date.d.ts +143 -13
- package/types/ngwr-drag-drop.d.ts +19 -0
- package/types/ngwr-dropdown.d.ts +1 -1
- package/types/ngwr-event-calendar-testing.d.ts +12 -9
- package/types/ngwr-file-upload.d.ts +31 -3
- package/types/ngwr-i18n.d.ts +89 -7
- package/types/ngwr-input-number.d.ts +1 -1
- package/types/ngwr-input-otp.d.ts +3 -0
- package/types/ngwr-input.d.ts +11 -4
- package/types/ngwr-knob-testing.d.ts +8 -4
- package/types/ngwr-knob.d.ts +18 -0
- package/types/ngwr-loading-bar-router.d.ts +35 -0
- package/types/ngwr-loading-bar.d.ts +19 -9
- package/types/ngwr-mention.d.ts +13 -0
- package/types/ngwr-pagination-testing.d.ts +11 -10
- package/types/ngwr-pagination.d.ts +39 -10
- package/types/ngwr-popconfirm.d.ts +1 -1
- package/types/ngwr-popover.d.ts +1 -1
- package/types/ngwr-select.d.ts +65 -10
- package/types/ngwr-splitter-testing.d.ts +9 -4
- package/types/ngwr-squircle.d.ts +1 -1
- package/types/ngwr-statistic.d.ts +22 -2
- package/types/ngwr-table.d.ts +24 -5
- package/types/ngwr-tabs-router.d.ts +67 -0
- package/types/ngwr-tabs-testing.d.ts +12 -10
- package/types/ngwr-tabs.d.ts +103 -6
- package/types/ngwr-textarea.d.ts +9 -0
- package/types/ngwr-tree.d.ts +7 -0
- package/types/ngwr-utils.d.ts +33 -1
- package/types/ngwr-version.d.ts +1 -1
- package/types/ngwr-window-testing.d.ts +11 -3
- package/types/ngwr-window.d.ts +11 -4
- package/window/styles/_index.scss +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-date.mjs","sources":["../../../projects/lib/date/wr-date-adapter.ts","../../../projects/lib/date/tokens/wr-date-locale.token.ts","../../../projects/lib/date/wr-native-date-adapter.ts","../../../projects/lib/date/provide-wr-date-adapter.ts","../../../projects/lib/date/ngwr-date.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { WrDateFormat } from './interfaces';\n\n/**\n * Abstraction over a date object so the calendar, date picker and time picker\n * can work with `Date`, `date-fns`, `luxon`, or any other library a consumer\n * prefers — without changing component code.\n *\n * Default implementation: {@link WrNativeDateAdapter} (native `Date`,\n * `Intl.DateTimeFormat`). Register a different adapter via\n * `provideWrDateAdapter({ adapter: MyAdapter })`.\n *\n * Used as both the type and the DI token — `inject(WrDateAdapter)` works\n * directly thanks to Angular's class-as-token resolution.\n *\n * Every \"mutating\" method (`addX`, `setTime`) returns a **new** value;\n * adapters never mutate in place so consumers can pass dates around safely.\n */\nexport abstract class WrDateAdapter<TDate = Date> {\n // Construction & identity\n\n /** Current moment. */\n abstract today(): TDate;\n\n /** Defensive clone — must return an independent value, never the same reference. */\n abstract clone(date: TDate): TDate;\n\n /** Build a date from year / month (0-based) / day. */\n abstract createDate(year: number, month: number, day: number): TDate;\n\n /** `false` for `NaN` / invalid input. */\n abstract isValid(date: TDate): boolean;\n\n // Accessors\n\n abstract getYear(date: TDate): number;\n /** `0` (January) – `11` (December). */\n abstract getMonth(date: TDate): number;\n /** Day of the month, `1`-`31`. */\n abstract getDate(date: TDate): number;\n /** `0` (Sunday) – `6` (Saturday). */\n abstract getDayOfWeek(date: TDate): number;\n abstract getDaysInMonth(date: TDate): number;\n abstract getHours(date: TDate): number;\n abstract getMinutes(date: TDate): number;\n abstract getSeconds(date: TDate): number;\n\n // Immutable math\n\n abstract addYears(date: TDate, amount: number): TDate;\n abstract addMonths(date: TDate, amount: number): TDate;\n abstract addDays(date: TDate, amount: number): TDate;\n /** Returns a new date with the time portion replaced. */\n abstract setTime(date: TDate, hours: number, minutes: number, seconds: number): TDate;\n\n // Comparison\n\n abstract isSameDay(a: TDate, b: TDate): boolean;\n abstract isSameMonth(a: TDate, b: TDate): boolean;\n /** Negative if `a < b`, positive if `a > b`, zero if equal (compared at day precision). */\n abstract compareDate(a: TDate, b: TDate): number;\n\n /**\n * Convenience used by the calendar's range UI. Inclusive on both ends.\n * Implementation can stay on the base class because it delegates to\n * `compareDate`.\n */\n isWithinRange(date: TDate, start: TDate, end: TDate): boolean {\n return this.compareDate(date, start) >= 0 && this.compareDate(date, end) <= 0;\n }\n\n // Formatting / parsing\n\n /**\n * Format a date. Accepts either a named {@link WrDateFormat} key (which the\n * adapter resolves locale-aware) or a raw format string (`'dd.MM.yyyy'`).\n *\n * Supported tokens for raw strings: `yyyy`, `yy`, `MMMM`, `MMM`, `MM`, `M`,\n * `dd`, `d`, `HH`, `H`, `hh`, `h`, `mm`, `ss`, `a` (am / pm).\n */\n abstract format(date: TDate, formatKeyOrString: WrDateFormat | (string & {})): string;\n\n /**\n * Parse a string into a date. Returns `null` when parsing fails. Accepts\n * the same `formatKeyOrString` set as {@link format}.\n */\n abstract parse(value: string, formatKeyOrString: WrDateFormat | (string & {})): TDate | null;\n\n // Locale info\n\n /** `0` Sunday, `1` Monday — locale-dependent. */\n abstract getFirstDayOfWeek(): number;\n\n /** Names ordered from `getFirstDayOfWeek()` onwards. Length 7. */\n abstract getDayOfWeekNames(style: 'narrow' | 'short' | 'long'): readonly string[];\n\n /** Names from January (index `0`) to December (`11`). Length 12. */\n abstract getMonthNames(style: 'narrow' | 'short' | 'long'): readonly string[];\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport { InjectionToken, PLATFORM_ID, inject } from '@angular/core';\n\n/**\n * BCP 47 locale tag the {@link WrDateAdapter} implementations read. Defaults to\n * `navigator.language` in the browser and `'en-US'` on the server; override via\n * {@link provideWrDateAdapter}'s `locale` option.\n *\n * **How far it reaches depends on the adapter, and the difference matters.**\n * The luxon adapter threads it through everything — every `DateTime` is\n * constructed with it, and `format` / `parse` call `setLocale`. The date-fns\n * adapter reads it only for locale-DERIVED defaults (first day of week); its\n * `format` and `parse` pass no locale to date-fns, so they stay on that\n * library's module default. Setting this token and expecting French month names\n * out of `WrDateFnsAdapter` gets English ones, and the parse side of that\n * mismatch is silent rather than loud — see the adapter's own class docs for the\n * lever (`setDefaultOptions`).\n */\nexport const WR_DATE_LOCALE = new InjectionToken<string>('WR_DATE_LOCALE', {\n providedIn: 'root',\n factory: () => {\n // Node 21+ also defines `navigator`, and reports the *build machine's*\n // locale — so a `typeof` probe silently bakes that locale into\n // prerendered output (wrong month names, wrong first day of week).\n // Ask the platform instead.\n if (isPlatformBrowser(inject(PLATFORM_ID)) && navigator.language) {\n return navigator.language;\n }\n return 'en-US';\n },\n});\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Service, inject } from '@angular/core';\n\nimport type { WrDateFormat } from './interfaces';\nimport { WR_DATE_LOCALE } from './tokens';\nimport { WrDateAdapter } from './wr-date-adapter';\n\nconst NAMED_KEYS = new Set<WrDateFormat>([\n 'shortDate',\n 'mediumDate',\n 'longDate',\n 'time',\n 'shortDateTime',\n 'mediumDateTime',\n]);\n\nconst INTL_OPTIONS: Readonly<Record<WrDateFormat, Intl.DateTimeFormatOptions>> = {\n shortDate: { year: 'numeric', month: 'numeric', day: 'numeric' },\n mediumDate: { year: 'numeric', month: 'short', day: 'numeric' },\n longDate: { year: 'numeric', month: 'long', day: 'numeric' },\n time: { hour: '2-digit', minute: '2-digit' },\n shortDateTime: { year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit' },\n mediumDateTime: { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' },\n};\n\n/** Recognised tokens, longest first so `MMMM` matches before `MMM`. */\n/**\n * Every token, with single-quoted runs taken FIRST so they win.\n *\n * Without that, the one-letter tokens match letters inside literal text: `'yyyy [year]'`\n * came out as `2025 [yeamr]`, because the `a` in \"year\" was read as the meridiem token.\n * Quote literals the way `DatePipe` and LDML do — `'at'` — and `''` for a real quote.\n */\nconst PART_RE = /'([^']*)'|yyyy|yy|MMMM|MMM|MM|M|dd|d|HH|H|hh|h|mm|ss|a/g;\n\nfunction pad(n: number, width = 2): string {\n return String(Math.abs(n)).padStart(width, '0');\n}\n\n/** Whether `value` is one of the shared named format keys. */\nfunction isNamedFormat(value: string): value is WrDateFormat {\n return NAMED_KEYS.has(value as WrDateFormat);\n}\n\nfunction tokenToRegex(token: string): string {\n switch (token) {\n case 'yyyy':\n return '(\\\\d{4})';\n case 'yy':\n return '(\\\\d{2})';\n case 'MM':\n case 'dd':\n case 'HH':\n case 'hh':\n case 'mm':\n case 'ss':\n return '(\\\\d{2})';\n case 'M':\n case 'd':\n case 'H':\n case 'h':\n return '(\\\\d{1,2})';\n case 'a':\n return '(am|pm|AM|PM)';\n default:\n return '(.+)';\n }\n}\n\n/**\n * Reference {@link WrDateAdapter} implementation backed by the native `Date`\n * object and `Intl.DateTimeFormat`. Zero external dependencies. Suitable for\n * most apps — swap to a `date-fns` / `luxon` adapter only when you need\n * timezone-aware math or richer parsing.\n */\n@Service()\nexport class WrNativeDateAdapter extends WrDateAdapter<Date> {\n private readonly locale = inject(WR_DATE_LOCALE);\n\n // Construction & identity\n\n today(): Date {\n return new Date();\n }\n\n clone(date: Date): Date {\n return new Date(date.getTime());\n }\n\n createDate(year: number, month: number, day: number): Date {\n // Native Date constructor with year < 100 maps to 1900 + year unless we explicitly setFullYear.\n const d = new Date(year, month, day);\n if (year >= 0 && year < 100) d.setFullYear(year);\n return d;\n }\n\n isValid(date: Date): boolean {\n return date instanceof Date && !Number.isNaN(date.getTime());\n }\n\n // Accessors\n\n getYear(date: Date): number {\n return date.getFullYear();\n }\n\n getMonth(date: Date): number {\n return date.getMonth();\n }\n\n getDate(date: Date): number {\n return date.getDate();\n }\n\n getDayOfWeek(date: Date): number {\n return date.getDay();\n }\n\n getDaysInMonth(date: Date): number {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();\n }\n\n getHours(date: Date): number {\n return date.getHours();\n }\n\n getMinutes(date: Date): number {\n return date.getMinutes();\n }\n\n getSeconds(date: Date): number {\n return date.getSeconds();\n }\n\n // Immutable math\n\n addYears(date: Date, amount: number): Date {\n const d = this.clone(date);\n d.setFullYear(d.getFullYear() + amount);\n return d;\n }\n\n addMonths(date: Date, amount: number): Date {\n const d = this.clone(date);\n const desiredDay = d.getDate();\n d.setDate(1);\n d.setMonth(d.getMonth() + amount);\n // Clamp day to the new month's length (Jan 31 + 1 month → Feb 28/29).\n d.setDate(Math.min(desiredDay, this.getDaysInMonth(d)));\n return d;\n }\n\n addDays(date: Date, amount: number): Date {\n // A calendar day, not 86 400 000 ms. Where daylight saving applies a day can be 23 or\n // 25 hours long, so millisecond arithmetic drifts the wall clock and — across an\n // autumn change — lands back on the same calendar date, which makes a month grid\n // repeat a day and lose one. Not observable in a fixed-offset timezone, which is why\n // the reason lives here rather than only in a test.\n const d = this.clone(date);\n d.setDate(d.getDate() + amount);\n return d;\n }\n\n setTime(date: Date, hours: number, minutes: number, seconds: number): Date {\n const d = this.clone(date);\n d.setHours(hours, minutes, seconds, 0);\n return d;\n }\n\n // Comparison\n\n isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n }\n\n isSameMonth(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();\n }\n\n compareDate(a: Date, b: Date): number {\n const ay = a.getFullYear();\n const by = b.getFullYear();\n if (ay !== by) return ay - by;\n const am = a.getMonth();\n const bm = b.getMonth();\n if (am !== bm) return am - bm;\n return a.getDate() - b.getDate();\n }\n\n // Formatting / parsing\n\n // `(string & {})` keeps autocomplete for the WrDateFormat literals\n // while still accepting any other string as a raw token pattern.\n format(date: Date, formatKeyOrString: WrDateFormat | (string & {})): string {\n if (isNamedFormat(formatKeyOrString)) {\n return this.intl(formatKeyOrString).format(date);\n }\n return this.formatWithTokens(date, formatKeyOrString);\n }\n\n parse(value: string, formatKeyOrString: WrDateFormat | (string & {})): Date | null {\n const raw = value?.trim();\n if (!raw) return null;\n\n // Named formats fall back to `new Date()` parsing — best-effort, locale-fragile.\n if (isNamedFormat(formatKeyOrString)) {\n const d = new Date(raw);\n return this.isValid(d) ? d : null;\n }\n\n return this.parseWithTokens(raw, formatKeyOrString);\n }\n\n // Locale info\n\n getFirstDayOfWeek(): number {\n // `Intl.Locale.prototype.getWeekInfo` is Stage 3 — not in TS lib types yet,\n // so we probe at runtime through an unknown cast.\n try {\n const locale = new Intl.Locale(this.locale) as unknown as { getWeekInfo?: () => { firstDay: number } };\n const info = locale.getWeekInfo?.();\n if (info && typeof info.firstDay === 'number') {\n // Intl uses 1 (Mon) – 7 (Sun); we use 0 (Sun) – 6 (Sat).\n return info.firstDay % 7;\n }\n } catch {\n // Browser doesn't support Intl.Locale or getWeekInfo — fall through.\n }\n return this.locale.toLowerCase().startsWith('en-us') ? 0 : 1;\n }\n\n /**\n * One `Intl.DateTimeFormat` per named format, built once.\n *\n * Constructing one is the expensive part of `format()`, and this adapter is\n * called per CELL: `wr-event-calendar` builds an `aria-label` for every time\n * slot on every day, so a week view asked for hundreds of identical\n * formatters. `locale` is injected once and never changes for the life of the\n * adapter, so the cache needs no invalidation — that is the whole reason it\n * can be this simple.\n */\n private readonly formatters = new Map<string, Intl.DateTimeFormat>();\n\n private intl(key: WrDateFormat): Intl.DateTimeFormat {\n let found = this.formatters.get(key);\n if (!found) {\n found = new Intl.DateTimeFormat(this.locale, INTL_OPTIONS[key]);\n this.formatters.set(key, found);\n }\n return found;\n }\n\n getDayOfWeekNames(style: 'narrow' | 'short' | 'long'): readonly string[] {\n const formatter = new Intl.DateTimeFormat(this.locale, { weekday: style });\n const first = this.getFirstDayOfWeek();\n // Pick a reference Sunday and walk seven days.\n const base = new Date(2024, 0, 7); // Sunday 7 Jan 2024\n const out: string[] = [];\n for (let i = 0; i < 7; i++) {\n const d = new Date(base);\n d.setDate(base.getDate() + ((first + i) % 7));\n out.push(formatter.format(d));\n }\n return out;\n }\n\n getMonthNames(style: 'narrow' | 'short' | 'long'): readonly string[] {\n const formatter = new Intl.DateTimeFormat(this.locale, { month: style });\n const out: string[] = [];\n for (let i = 0; i < 12; i++) {\n out.push(formatter.format(new Date(2024, i, 15)));\n }\n return out;\n }\n\n // Internals: token-based format / parse\n\n private formatWithTokens(date: Date, pattern: string): string {\n const year = date.getFullYear();\n const month = date.getMonth();\n const day = date.getDate();\n const hours24 = date.getHours();\n const hours12 = hours24 % 12 === 0 ? 12 : hours24 % 12;\n const minutes = date.getMinutes();\n const seconds = date.getSeconds();\n const monthNames = this.getMonthNames('long');\n const monthShort = this.getMonthNames('short');\n\n return pattern.replace(PART_RE, (part, quoted?: string) => {\n // A quoted run is emitted as-is; `''` is how a single quote is written.\n if (quoted !== undefined) return quoted === '' ? \"'\" : quoted;\n const token = part;\n switch (token) {\n case 'yyyy':\n return pad(year, 4);\n case 'yy':\n return pad(year % 100, 2);\n case 'MMMM':\n return monthNames[month] ?? '';\n case 'MMM':\n return monthShort[month] ?? '';\n case 'MM':\n return pad(month + 1);\n case 'M':\n return String(month + 1);\n case 'dd':\n return pad(day);\n case 'd':\n return String(day);\n case 'HH':\n return pad(hours24);\n case 'H':\n return String(hours24);\n case 'hh':\n return pad(hours12);\n case 'h':\n return String(hours12);\n case 'mm':\n return pad(minutes);\n case 'ss':\n return pad(seconds);\n case 'a':\n return hours24 < 12 ? 'am' : 'pm';\n }\n return token;\n });\n }\n\n private parseWithTokens(value: string, pattern: string): Date | null {\n const tokens: string[] = [];\n const monthLong = this.getMonthNames('long');\n const monthShort = this.getMonthNames('short');\n const escaped = pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = escaped.replace(PART_RE, (part, quoted?: string) => {\n if (quoted !== undefined) {\n // Literal text matches itself and captures nothing, so the token indices stay\n // aligned with the groups below.\n return quoted === '' ? \"'\" : quoted;\n }\n tokens.push(part);\n return tokenToRegex(part);\n });\n\n const match = new RegExp(`^${regex}$`).exec(value);\n if (!match) return null;\n\n let year = new Date().getFullYear();\n let month = 0;\n let day = 1;\n let hours = 0;\n let minutes = 0;\n let seconds = 0;\n let isPm = false;\n let hadHour12 = false;\n let hour12 = 0;\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n const raw = match[i + 1];\n const n = Number(raw);\n switch (token) {\n case 'yyyy':\n year = n;\n break;\n case 'yy':\n year = 2000 + n;\n break;\n case 'MM':\n case 'M':\n month = n - 1;\n break;\n case 'MMM':\n case 'MMMM': {\n const names = token === 'MMM' ? monthShort : monthLong;\n const found = names.findIndex(name => name.toLowerCase() === raw.toLowerCase());\n if (found < 0) return null;\n month = found;\n break;\n }\n case 'dd':\n case 'd':\n day = n;\n break;\n case 'HH':\n case 'H':\n hours = n;\n break;\n case 'hh':\n case 'h':\n hadHour12 = true;\n hour12 = n;\n break;\n case 'mm':\n minutes = n;\n break;\n case 'ss':\n seconds = n;\n break;\n case 'a':\n isPm = raw.toLowerCase() === 'pm';\n break;\n }\n }\n\n if (hadHour12) {\n hours = (hour12 % 12) + (isPm ? 12 : 0);\n }\n\n // `new Date(2025, 12, 45)` does not fail — it rolls forward into the next year — and\n // `isValid` is happy with the result, so a text field turned nonsense into a confident\n // wrong answer. The clock parts are range-checked directly; the month and the day are\n // checked by comparing what came back, which catches every rollover including a month\n // of 12 or -1.\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59) return null;\n\n const out = new Date(year, month, day, hours, minutes, seconds);\n if (!this.isValid(out)) return null;\n // The day is range-checked by construction: anything the calendar rolled over comes\n // back as a different month or a different day.\n if (out.getMonth() !== month || out.getDate() !== day) return null;\n return out;\n }\n}\n\nexport { isNamedFormat };\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport type { WrDateAdapterOptions } from './interfaces';\nimport { WR_DATE_LOCALE } from './tokens';\nimport { WrDateAdapter } from './wr-date-adapter';\nimport { WrNativeDateAdapter } from './wr-native-date-adapter';\n\n/**\n * Register the date adapter and locale used by the calendar / date picker /\n * time picker. Call once at bootstrap.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideWrDateAdapter(), // native, browser locale\n * // provideWrDateAdapter({ locale: 'ru-RU' }),\n * // provideWrDateAdapter({ adapter: MyDateFnsAdapter, locale: 'fr' }),\n * ],\n * });\n * ```\n */\nexport function provideWrDateAdapter(options: WrDateAdapterOptions = {}): EnvironmentProviders {\n const providers: Parameters<typeof makeEnvironmentProviders>[0] = [\n { provide: WrDateAdapter, useClass: options.adapter ?? WrNativeDateAdapter },\n ];\n\n if (options.locale) {\n providers.push({ provide: WR_DATE_LOCALE, useValue: options.locale });\n }\n\n return makeEnvironmentProviders(providers);\n}\n\nexport type { WrDateAdapterOptions } from './interfaces';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAAA;;;;;AAKG;AAIH;;;;;;;;;;;;;;AAcG;MACmB,aAAa,CAAA;AA4CjC;;;;AAIG;AACH,IAAA,aAAa,CAAC,IAAW,EAAE,KAAY,EAAE,GAAU,EAAA;QACjD,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC;IAC/E;AA6BD;;ACxGD;;;;;AAKG;AAKH;;;;;;;;;;;;;;AAcG;MACU,cAAc,GAAG,IAAI,cAAc,CAAS,gBAAgB,EAAE;AACzE,IAAA,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,MAAK;;;;;AAKZ,QAAA,IAAI,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,SAAS,CAAC,QAAQ,EAAE;YAChE,OAAO,SAAS,CAAC,QAAQ;QAC3B;AACA,QAAA,OAAO,OAAO;IAChB,CAAC;AACF,CAAA;;ACrCD;;;;;AAKG;AAQH,MAAM,UAAU,GAAG,IAAI,GAAG,CAAe;IACvC,WAAW;IACX,YAAY;IACZ,UAAU;IACV,MAAM;IACN,eAAe;IACf,gBAAgB;AACjB,CAAA,CAAC;AAEF,MAAM,YAAY,GAA+D;AAC/E,IAAA,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE;AAChE,IAAA,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE;AAC/D,IAAA,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE;IAC5D,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC5C,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IACxG,cAAc,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;CACxG;AAED;AACA;;;;;;AAMG;AACH,MAAM,OAAO,GAAG,yDAAyD;AAEzE,SAAS,GAAG,CAAC,CAAS,EAAE,KAAK,GAAG,CAAC,EAAA;AAC/B,IAAA,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;AACjD;AAEA;AACA,SAAS,aAAa,CAAC,KAAa,EAAA;AAClC,IAAA,OAAO,UAAU,CAAC,GAAG,CAAC,KAAqB,CAAC;AAC9C;AAEA,SAAS,YAAY,CAAC,KAAa,EAAA;IACjC,QAAQ,KAAK;AACX,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,UAAU;AACnB,QAAA,KAAK,IAAI;AACP,YAAA,OAAO,UAAU;AACnB,QAAA,KAAK,IAAI;AACT,QAAA,KAAK,IAAI;AACT,QAAA,KAAK,IAAI;AACT,QAAA,KAAK,IAAI;AACT,QAAA,KAAK,IAAI;AACT,QAAA,KAAK,IAAI;AACP,YAAA,OAAO,UAAU;AACnB,QAAA,KAAK,GAAG;AACR,QAAA,KAAK,GAAG;AACR,QAAA,KAAK,GAAG;AACR,QAAA,KAAK,GAAG;AACN,YAAA,OAAO,YAAY;AACrB,QAAA,KAAK,GAAG;AACN,YAAA,OAAO,eAAe;AACxB,QAAA;AACE,YAAA,OAAO,MAAM;;AAEnB;AAEA;;;;;AAKG;AAEG,MAAO,mBAAoB,SAAQ,aAAmB,CAAA;AACzC,IAAA,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC;;IAIhD,KAAK,GAAA;QACH,OAAO,IAAI,IAAI,EAAE;IACnB;AAEA,IAAA,KAAK,CAAC,IAAU,EAAA;QACd,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACjC;AAEA,IAAA,UAAU,CAAC,IAAY,EAAE,KAAa,EAAE,GAAW,EAAA;;QAEjD,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC;AACpC,QAAA,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,GAAG;AAAE,YAAA,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC;AAChD,QAAA,OAAO,CAAC;IACV;AAEA,IAAA,OAAO,CAAC,IAAU,EAAA;AAChB,QAAA,OAAO,IAAI,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC9D;;AAIA,IAAA,OAAO,CAAC,IAAU,EAAA;AAChB,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE;IAC3B;AAEA,IAAA,QAAQ,CAAC,IAAU,EAAA;AACjB,QAAA,OAAO,IAAI,CAAC,QAAQ,EAAE;IACxB;AAEA,IAAA,OAAO,CAAC,IAAU,EAAA;AAChB,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE;IACvB;AAEA,IAAA,YAAY,CAAC,IAAU,EAAA;AACrB,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE;IACtB;AAEA,IAAA,cAAc,CAAC,IAAU,EAAA;QACvB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE;IACvE;AAEA,IAAA,QAAQ,CAAC,IAAU,EAAA;AACjB,QAAA,OAAO,IAAI,CAAC,QAAQ,EAAE;IACxB;AAEA,IAAA,UAAU,CAAC,IAAU,EAAA;AACnB,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE;IAC1B;AAEA,IAAA,UAAU,CAAC,IAAU,EAAA;AACnB,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE;IAC1B;;IAIA,QAAQ,CAAC,IAAU,EAAE,MAAc,EAAA;QACjC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAC1B,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC;AACvC,QAAA,OAAO,CAAC;IACV;IAEA,SAAS,CAAC,IAAU,EAAE,MAAc,EAAA;QAClC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;AAC1B,QAAA,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,EAAE;AAC9B,QAAA,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC;;AAEjC,QAAA,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,QAAA,OAAO,CAAC;IACV;IAEA,OAAO,CAAC,IAAU,EAAE,MAAc,EAAA;;;;;;QAMhC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAC1B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC;AAC/B,QAAA,OAAO,CAAC;IACV;AAEA,IAAA,OAAO,CAAC,IAAU,EAAE,KAAa,EAAE,OAAe,EAAE,OAAe,EAAA;QACjE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAC1B,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AACtC,QAAA,OAAO,CAAC;IACV;;IAIA,SAAS,CAAC,CAAO,EAAE,CAAO,EAAA;AACxB,QAAA,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE;IAC5G;IAEA,WAAW,CAAC,CAAO,EAAE,CAAO,EAAA;AAC1B,QAAA,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE;IAC7E;IAEA,WAAW,CAAC,CAAO,EAAE,CAAO,EAAA;AAC1B,QAAA,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;AAC1B,QAAA,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;QAC1B,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,GAAG,EAAE;AAC7B,QAAA,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE;AACvB,QAAA,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE;QACvB,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,GAAG,EAAE;QAC7B,OAAO,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE;IAClC;;;;IAMA,MAAM,CAAC,IAAU,EAAE,iBAA+C,EAAA;AAChE,QAAA,IAAI,aAAa,CAAC,iBAAiB,CAAC,EAAE;YACpC,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;QAClD;QACA,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACvD;IAEA,KAAK,CAAC,KAAa,EAAE,iBAA+C,EAAA;AAClE,QAAA,MAAM,GAAG,GAAG,KAAK,EAAE,IAAI,EAAE;AACzB,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,IAAI;;AAGrB,QAAA,IAAI,aAAa,CAAC,iBAAiB,CAAC,EAAE;AACpC,YAAA,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;AACvB,YAAA,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI;QACnC;QAEA,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,iBAAiB,CAAC;IACrD;;IAIA,iBAAiB,GAAA;;;AAGf,QAAA,IAAI;YACF,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAA4D;AACtG,YAAA,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,IAAI;YACnC,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE;;AAE7C,gBAAA,OAAO,IAAI,CAAC,QAAQ,GAAG,CAAC;YAC1B;QACF;AAAE,QAAA,MAAM;;QAER;AACA,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IAC9D;AAEA;;;;;;;;;AASG;AACc,IAAA,UAAU,GAAG,IAAI,GAAG,EAA+B;AAE5D,IAAA,IAAI,CAAC,GAAiB,EAAA;QAC5B,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,KAAK,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC;YAC/D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;QACjC;AACA,QAAA,OAAO,KAAK;IACd;AAEA,IAAA,iBAAiB,CAAC,KAAkC,EAAA;AAClD,QAAA,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC1E,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE;;AAEtC,QAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,GAAG,GAAa,EAAE;AACxB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;AAC1B,YAAA,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC;AACxB,YAAA,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7C,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/B;AACA,QAAA,OAAO,GAAG;IACZ;AAEA,IAAA,aAAa,CAAC,KAAkC,EAAA;AAC9C,QAAA,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACxE,MAAM,GAAG,GAAa,EAAE;AACxB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;AAC3B,YAAA,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACnD;AACA,QAAA,OAAO,GAAG;IACZ;;IAIQ,gBAAgB,CAAC,IAAU,EAAE,OAAe,EAAA;AAClD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;AAC/B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC7B,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE;AAC1B,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC/B,QAAA,MAAM,OAAO,GAAG,OAAO,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,EAAE;AACtD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;AACjC,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;QACjC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;QAE9C,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAe,KAAI;;YAExD,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO,MAAM,KAAK,EAAE,GAAG,GAAG,GAAG,MAAM;YAC7D,MAAM,KAAK,GAAG,IAAI;YAClB,QAAQ,KAAK;AACX,gBAAA,KAAK,MAAM;AACT,oBAAA,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AACrB,gBAAA,KAAK,IAAI;oBACP,OAAO,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC;AAC3B,gBAAA,KAAK,MAAM;AACT,oBAAA,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE;AAChC,gBAAA,KAAK,KAAK;AACR,oBAAA,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE;AAChC,gBAAA,KAAK,IAAI;AACP,oBAAA,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;AACvB,gBAAA,KAAK,GAAG;AACN,oBAAA,OAAO,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;AAC1B,gBAAA,KAAK,IAAI;AACP,oBAAA,OAAO,GAAG,CAAC,GAAG,CAAC;AACjB,gBAAA,KAAK,GAAG;AACN,oBAAA,OAAO,MAAM,CAAC,GAAG,CAAC;AACpB,gBAAA,KAAK,IAAI;AACP,oBAAA,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,gBAAA,KAAK,GAAG;AACN,oBAAA,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,gBAAA,KAAK,IAAI;AACP,oBAAA,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,gBAAA,KAAK,GAAG;AACN,oBAAA,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,gBAAA,KAAK,IAAI;AACP,oBAAA,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,gBAAA,KAAK,IAAI;AACP,oBAAA,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,gBAAA,KAAK,GAAG;oBACN,OAAO,OAAO,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;;AAErC,YAAA,OAAO,KAAK;AACd,QAAA,CAAC,CAAC;IACJ;IAEQ,eAAe,CAAC,KAAa,EAAE,OAAe,EAAA;QACpD,MAAM,MAAM,GAAa,EAAE;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;QAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;AAC9D,QAAA,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAe,KAAI;AAC/D,YAAA,IAAI,MAAM,KAAK,SAAS,EAAE;;;gBAGxB,OAAO,MAAM,KAAK,EAAE,GAAG,GAAG,GAAG,MAAM;YACrC;AACA,YAAA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AACjB,YAAA,OAAO,YAAY,CAAC,IAAI,CAAC;AAC3B,QAAA,CAAC,CAAC;AAEF,QAAA,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,CAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;AAClD,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,IAAI;QAEvB,IAAI,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,IAAI,KAAK,GAAG,CAAC;QACb,IAAI,GAAG,GAAG,CAAC;QACX,IAAI,KAAK,GAAG,CAAC;QACb,IAAI,OAAO,GAAG,CAAC;QACf,IAAI,OAAO,GAAG,CAAC;QACf,IAAI,IAAI,GAAG,KAAK;QAChB,IAAI,SAAS,GAAG,KAAK;QACrB,IAAI,MAAM,GAAG,CAAC;AAEd,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,YAAA,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC;YACvB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;AACxB,YAAA,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC;YACrB,QAAQ,KAAK;AACX,gBAAA,KAAK,MAAM;oBACT,IAAI,GAAG,CAAC;oBACR;AACF,gBAAA,KAAK,IAAI;AACP,oBAAA,IAAI,GAAG,IAAI,GAAG,CAAC;oBACf;AACF,gBAAA,KAAK,IAAI;AACT,gBAAA,KAAK,GAAG;AACN,oBAAA,KAAK,GAAG,CAAC,GAAG,CAAC;oBACb;AACF,gBAAA,KAAK,KAAK;gBACV,KAAK,MAAM,EAAE;AACX,oBAAA,MAAM,KAAK,GAAG,KAAK,KAAK,KAAK,GAAG,UAAU,GAAG,SAAS;oBACtD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC;oBAC/E,IAAI,KAAK,GAAG,CAAC;AAAE,wBAAA,OAAO,IAAI;oBAC1B,KAAK,GAAG,KAAK;oBACb;gBACF;AACA,gBAAA,KAAK,IAAI;AACT,gBAAA,KAAK,GAAG;oBACN,GAAG,GAAG,CAAC;oBACP;AACF,gBAAA,KAAK,IAAI;AACT,gBAAA,KAAK,GAAG;oBACN,KAAK,GAAG,CAAC;oBACT;AACF,gBAAA,KAAK,IAAI;AACT,gBAAA,KAAK,GAAG;oBACN,SAAS,GAAG,IAAI;oBAChB,MAAM,GAAG,CAAC;oBACV;AACF,gBAAA,KAAK,IAAI;oBACP,OAAO,GAAG,CAAC;oBACX;AACF,gBAAA,KAAK,IAAI;oBACP,OAAO,GAAG,CAAC;oBACX;AACF,gBAAA,KAAK,GAAG;AACN,oBAAA,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,KAAK,IAAI;oBACjC;;QAEN;QAEA,IAAI,SAAS,EAAE;AACb,YAAA,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;QACzC;;;;;;QAOA,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,EAAE;AAAE,YAAA,OAAO,IAAI;AAEtG,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC;AAC/D,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;AAAE,YAAA,OAAO,IAAI;;;AAGnC,QAAA,IAAI,GAAG,CAAC,QAAQ,EAAE,KAAK,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE,KAAK,GAAG;AAAE,YAAA,OAAO,IAAI;AAClE,QAAA,OAAO,GAAG;IACZ;uGAzVW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,OAAA,EAAA,CAAA;wGAAnB,mBAAmB,EAAA,CAAA;;2FAAnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAD/B;;;ACjFD;;;;;AAKG;AASH;;;;;;;;;;;;;;AAcG;AACG,SAAU,oBAAoB,CAAC,OAAA,GAAgC,EAAE,EAAA;AACrE,IAAA,MAAM,SAAS,GAAmD;QAChE,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,IAAI,mBAAmB,EAAE;KAC7E;AAED,IAAA,IAAI,OAAO,CAAC,MAAM,EAAE;AAClB,QAAA,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;IACvE;AAEA,IAAA,OAAO,wBAAwB,CAAC,SAAS,CAAC;AAC5C;;ACvCA;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ngwr-date.mjs","sources":["../../../projects/lib/date/wr-date-adapter.ts","../../../projects/lib/date/tokens/wr-date-locale.token.ts","../../../projects/lib/date/wr-native-date-adapter.ts","../../../projects/lib/date/provide-wr-date-adapter.ts","../../../projects/lib/date/ngwr-date.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { WrDateFormat } from './interfaces';\n\n/**\n * Abstraction over a date object so the calendar, date picker and time picker\n * can work with `Date`, `date-fns`, `luxon`, or any other library a consumer\n * prefers — without changing component code.\n *\n * Default implementation: {@link WrNativeDateAdapter} (native `Date`,\n * `Intl.DateTimeFormat`). Register a different adapter via\n * `provideWrDateAdapter({ adapter: MyAdapter })`.\n *\n * Used as both the type and the DI token — `inject(WrDateAdapter)` works\n * directly thanks to Angular's class-as-token resolution.\n *\n * Every \"mutating\" method (`addX`, `setTime`) returns a **new** value;\n * adapters never mutate in place so consumers can pass dates around safely.\n */\nexport abstract class WrDateAdapter<TDate = Date> {\n // Construction & identity\n\n /** Current moment. */\n abstract today(): TDate;\n\n /** Defensive clone — must return an independent value, never the same reference. */\n abstract clone(date: TDate): TDate;\n\n /** Build a date from year / month (0-based) / day. */\n abstract createDate(year: number, month: number, day: number): TDate;\n\n /** `false` for `NaN` / invalid input. */\n abstract isValid(date: TDate): boolean;\n\n // Accessors\n\n abstract getYear(date: TDate): number;\n /** `0` (January) – `11` (December). */\n abstract getMonth(date: TDate): number;\n /** Day of the month, `1`-`31`. */\n abstract getDate(date: TDate): number;\n /** `0` (Sunday) – `6` (Saturday). */\n abstract getDayOfWeek(date: TDate): number;\n abstract getDaysInMonth(date: TDate): number;\n abstract getHours(date: TDate): number;\n abstract getMinutes(date: TDate): number;\n abstract getSeconds(date: TDate): number;\n\n // Immutable math\n\n abstract addYears(date: TDate, amount: number): TDate;\n abstract addMonths(date: TDate, amount: number): TDate;\n abstract addDays(date: TDate, amount: number): TDate;\n /** Returns a new date with the time portion replaced. */\n abstract setTime(date: TDate, hours: number, minutes: number, seconds: number): TDate;\n\n // Comparison\n\n abstract isSameDay(a: TDate, b: TDate): boolean;\n abstract isSameMonth(a: TDate, b: TDate): boolean;\n /** Negative if `a < b`, positive if `a > b`, zero if equal (compared at day precision). */\n abstract compareDate(a: TDate, b: TDate): number;\n\n /**\n * Convenience used by the calendar's range UI. Inclusive on both ends.\n * Implementation can stay on the base class because it delegates to\n * `compareDate`.\n */\n isWithinRange(date: TDate, start: TDate, end: TDate): boolean {\n return this.compareDate(date, start) >= 0 && this.compareDate(date, end) <= 0;\n }\n\n // Formatting / parsing\n\n /**\n * Format a date. Accepts either a named {@link WrDateFormat} key (which the\n * adapter resolves locale-aware) or a raw format string (`'dd.MM.yyyy'`).\n *\n * Supported tokens for raw strings: `yyyy`, `yy`, `MMMM`, `MMM`, `MM`, `M`,\n * `dd`, `d`, `HH`, `H`, `hh`, `h`, `mm`, `ss`, `a` (the locale's day-period\n * marker — `PM`, `م`, `午後`).\n *\n * `MMMM` / `MMM` take the form the language uses in the position the pattern\n * puts them: beside a day token a case language declines the month (ru writes\n * `15 марта`, not `15 март`), and on their own they stay nominative, which is\n * what a calendar heading wants.\n */\n abstract format(date: TDate, formatKeyOrString: WrDateFormat | (string & {})): string;\n\n /**\n * Parse a string into a date. Returns `null` when parsing fails. Accepts\n * the same `formatKeyOrString` set as {@link format}.\n *\n * **The round trip is a contract, not an aspiration**: whatever {@link format}\n * writes for a given key, `parse` reads back to the same date. A caller relies\n * on it every keystroke — the picker re-parses what it printed — and returning\n * `null` is how an adapter refuses, which leaves the caller's committed value\n * exactly as it was.\n */\n abstract parse(value: string, formatKeyOrString: WrDateFormat | (string & {})): TDate | null;\n\n // Locale info\n\n /** `0` Sunday, `1` Monday — locale-dependent. */\n abstract getFirstDayOfWeek(): number;\n\n /** Names ordered from `getFirstDayOfWeek()` onwards. Length 7. */\n abstract getDayOfWeekNames(style: 'narrow' | 'short' | 'long'): readonly string[];\n\n /** Names from January (index `0`) to December (`11`). Length 12. */\n abstract getMonthNames(style: 'narrow' | 'short' | 'long'): readonly string[];\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken, LOCALE_ID, inject } from '@angular/core';\n\n/**\n * BCP 47 locale tag the {@link WrDateAdapter} implementations read. Defaults to\n * Angular's `LOCALE_ID`; override via {@link provideWrDateAdapter}'s `locale`\n * option.\n *\n * **It used to default to `navigator.language`, and that was wrong in the\n * documented case.** The provider's own first example is the no-argument call,\n * so the path a reader copies was the broken one: an app that set\n * `LOCALE_ID: 'ru-RU'` and translated every string still rendered `March 2026`,\n * `SUN MON TUE …` and a week starting on Sunday, because the calendar was\n * asking the browser rather than the application. `navigator.language` is the\n * user's browser preference; `LOCALE_ID` is what the app says it is, and only\n * the app can be right about that. Reading the browser also made a prerendered\n * page and its hydrated self disagree — the server has no `navigator.language`\n * to match. An app that genuinely wants the browser's tag can still say so:\n * `provideWrDateAdapter({ locale: navigator.language })`.\n *\n * The token is a plain string, resolved once. It is therefore the *pinned* date\n * locale, not a live one — `WrI18n.use()` moves catalog text and cannot move\n * this. `WrI18n`'s class docs carry the full precedence and `use()` warns about\n * the gap in dev mode.\n *\n * **How far it reaches depends on the adapter, and the difference matters.**\n * The native and luxon adapters thread it through everything. The date-fns\n * adapter cannot: date-fns resolves its patterns against a `Locale` OBJECT, not\n * a tag, so this token drives only the parts that go through `Intl` (the month\n * and weekday names) and the OBJECT drives `format` / `parse`. Pass it as\n * `provideWrDateFnsAdapter({ dateFnsLocale: ru })` — with only a tag the calendar\n * headings localize and the field does not, which the adapter warns about once\n * in dev mode.\n */\nexport const WR_DATE_LOCALE = new InjectionToken<string>('WR_DATE_LOCALE', {\n providedIn: 'root',\n factory: () => inject(LOCALE_ID),\n});\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Service, inject } from '@angular/core';\n\nimport type { WrDateFormat } from './interfaces';\nimport { WR_DATE_LOCALE } from './tokens';\nimport { WrDateAdapter } from './wr-date-adapter';\n\nconst NAMED_KEYS = new Set<WrDateFormat>([\n 'shortDate',\n 'mediumDate',\n 'longDate',\n 'time',\n 'shortDateTime',\n 'mediumDateTime',\n]);\n\n/**\n * Bidi control marks ICU embeds in a right-to-left date pattern — ar-SA writes its\n * separator as U+200F followed by a slash. No keyboard produces one, so both the\n * pattern and the typed string drop them before they are compared.\n */\nconst BIDI_RE = /[\\u200e\\u200f\\u061c\\u2066-\\u2069]/g;\n\nconst REGEX_META_RE = /[.*+?^${}()|[\\]\\\\]/g;\n\nfunction stripBidi(value: string): string {\n return value.replace(BIDI_RE, '');\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(REGEX_META_RE, '\\\\$&');\n}\n\n/**\n * One literal run of an `Intl` pattern, as a regex fragment.\n *\n * Whitespace inside a literal is advisory, not exact: ICU separates `02:30` from `PM`\n * with a NARROW NO-BREAK SPACE (U+202F) and no keyboard emits one, so every whitespace\n * run matches `\\s*`. A literal that is nothing BUT whitespace keeps `\\s+` — relaxing it\n * there would let `15 2026` also read as `152026`, which is how a lenient parser invents\n * a date nobody typed.\n */\nfunction literalToRegex(literal: string): string {\n const text = stripBidi(literal);\n if (!text) return '';\n if (!text.trim()) return '\\\\s+';\n return text.split(/\\s+/).map(escapeRegex).join('\\\\s*');\n}\n\n/** Longest first, so `March` is never consumed as `Mar` with `ch` left over. */\nfunction alternation(names: readonly string[]): string {\n return [...new Set(names)]\n .sort((a, b) => b.length - a.length)\n .map(name => escapeRegex(stripBidi(name)))\n .join('|');\n}\n\n/**\n * The ten digits a locale's numbering system writes, index 0 to 9 — `null` when the\n * system is algorithmic (roman, hebrew) and there is no digit-by-digit reading to do.\n */\nfunction numeralsFor(locale: string, numberingSystem: string): readonly string[] | null {\n let formatter: Intl.NumberFormat;\n try {\n formatter = new Intl.NumberFormat(locale, { numberingSystem, useGrouping: false });\n } catch {\n return null;\n }\n const digits: string[] = [];\n for (let i = 0; i < 10; i++) {\n const digit = formatter.format(i);\n if ([...digit].length !== 1 || digits.includes(digit)) return null;\n digits.push(digit);\n }\n return digits;\n}\n\n/** A character class accepting the locale's own digits AND ASCII ones. */\nfunction digitClass(numerals: readonly string[]): string {\n const extra = numerals\n .filter(digit => digit < '0' || digit > '9')\n .map(digit => `\\\\u${digit.codePointAt(0)!.toString(16).padStart(4, '0')}`)\n .join('');\n return `[0-9${extra}]`;\n}\n\n/** `١٥` to `15`, and ASCII through unchanged. `NaN` for anything else. */\nfunction digitsToNumber(text: string, numerals: readonly string[]): number {\n let out = '';\n for (const ch of text) {\n if (ch >= '0' && ch <= '9') {\n out += ch;\n continue;\n }\n const index = numerals.indexOf(ch);\n if (index < 0) return Number.NaN;\n out += String(index);\n }\n return out ? Number(out) : Number.NaN;\n}\n\nfunction isAllDigits(text: string, numerals: readonly string[]): boolean {\n return text.length > 0 && !Number.isNaN(digitsToNumber(text, numerals));\n}\n\n/** What one capture group of a named-format parser holds. */\ninterface NamedField {\n readonly kind: 'year' | 'month' | 'monthName' | 'day' | 'hour' | 'minute' | 'second' | 'dayPeriod';\n /** Month names (12) or day-period names (`[am, pm]`), matched case-insensitively. */\n readonly names?: readonly string[];\n}\n\ninterface NamedParser {\n readonly regex: RegExp;\n readonly fields: readonly NamedField[];\n readonly numerals: readonly string[];\n readonly hourCycle: string | undefined;\n}\n\n/** The parts assembled into a `Date`, whatever route read them. */\ninterface DateParts {\n year?: number;\n month?: number;\n day?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n hour12?: number;\n isPm?: boolean;\n}\n\nconst INTL_OPTIONS: Readonly<Record<WrDateFormat, Intl.DateTimeFormatOptions>> = {\n shortDate: { year: 'numeric', month: 'numeric', day: 'numeric' },\n mediumDate: { year: 'numeric', month: 'short', day: 'numeric' },\n longDate: { year: 'numeric', month: 'long', day: 'numeric' },\n time: { hour: '2-digit', minute: '2-digit' },\n shortDateTime: { year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit' },\n mediumDateTime: { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' },\n};\n\n/** Recognised tokens, longest first so `MMMM` matches before `MMM`. */\n/**\n * Every token, with single-quoted runs taken FIRST so they win.\n *\n * Without that, the one-letter tokens match letters inside literal text: `'yyyy [year]'`\n * came out as `2025 [yeamr]`, because the `a` in \"year\" was read as the meridiem token.\n * Quote literals the way `DatePipe` and LDML do — `'at'` — and `''` for a real quote.\n */\nconst PART_RE = /'([^']*)'|yyyy|yy|MMMM|MMM|MM|M|dd|d|HH|H|hh|h|mm|ss|a/g;\n\nfunction pad(n: number, width = 2): string {\n return String(Math.abs(n)).padStart(width, '0');\n}\n\n/** Whether `value` is one of the shared named format keys. */\nfunction isNamedFormat(value: string): value is WrDateFormat {\n return NAMED_KEYS.has(value as WrDateFormat);\n}\n\n/**\n * `digits` is a character class rather than `\\d`, and it always accepts ASCII as well as\n * the locale's own numerals. The token formatter WRITES ASCII, so the round trip never\n * needed more — but a reader on an Arabic keyboard types `١٥` into the same field, and\n * `\\d` made that silently unparseable with no feedback anywhere.\n */\nfunction tokenToRegex(token: string, digits: string): string {\n switch (token) {\n case 'yyyy':\n return `(${digits}{4})`;\n case 'yy':\n return `(${digits}{2})`;\n case 'MM':\n case 'dd':\n case 'HH':\n case 'hh':\n case 'mm':\n case 'ss':\n return `(${digits}{2})`;\n case 'M':\n case 'd':\n case 'H':\n case 'h':\n return `(${digits}{1,2})`;\n case 'a':\n return '(am|pm|AM|PM)';\n default:\n return '(.+)';\n }\n}\n\n/**\n * Reference {@link WrDateAdapter} implementation backed by the native `Date`\n * object and `Intl.DateTimeFormat`. Zero external dependencies. Suitable for\n * most apps — swap to a `date-fns` / `luxon` adapter only when you need\n * timezone-aware math or richer parsing.\n */\n@Service()\nexport class WrNativeDateAdapter extends WrDateAdapter<Date> {\n private readonly locale = inject(WR_DATE_LOCALE);\n\n // Construction & identity\n\n today(): Date {\n return new Date();\n }\n\n clone(date: Date): Date {\n return new Date(date.getTime());\n }\n\n createDate(year: number, month: number, day: number): Date {\n // Native Date constructor with year < 100 maps to 1900 + year unless we explicitly setFullYear.\n const d = new Date(year, month, day);\n if (year >= 0 && year < 100) d.setFullYear(year);\n return d;\n }\n\n isValid(date: Date): boolean {\n return date instanceof Date && !Number.isNaN(date.getTime());\n }\n\n // Accessors\n\n getYear(date: Date): number {\n return date.getFullYear();\n }\n\n getMonth(date: Date): number {\n return date.getMonth();\n }\n\n getDate(date: Date): number {\n return date.getDate();\n }\n\n getDayOfWeek(date: Date): number {\n return date.getDay();\n }\n\n getDaysInMonth(date: Date): number {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();\n }\n\n getHours(date: Date): number {\n return date.getHours();\n }\n\n getMinutes(date: Date): number {\n return date.getMinutes();\n }\n\n getSeconds(date: Date): number {\n return date.getSeconds();\n }\n\n // Immutable math\n\n addYears(date: Date, amount: number): Date {\n const d = this.clone(date);\n d.setFullYear(d.getFullYear() + amount);\n return d;\n }\n\n addMonths(date: Date, amount: number): Date {\n const d = this.clone(date);\n const desiredDay = d.getDate();\n d.setDate(1);\n d.setMonth(d.getMonth() + amount);\n // Clamp day to the new month's length (Jan 31 + 1 month → Feb 28/29).\n d.setDate(Math.min(desiredDay, this.getDaysInMonth(d)));\n return d;\n }\n\n addDays(date: Date, amount: number): Date {\n // A calendar day, not 86 400 000 ms. Where daylight saving applies a day can be 23 or\n // 25 hours long, so millisecond arithmetic drifts the wall clock and — across an\n // autumn change — lands back on the same calendar date, which makes a month grid\n // repeat a day and lose one. Not observable in a fixed-offset timezone, which is why\n // the reason lives here rather than only in a test.\n const d = this.clone(date);\n d.setDate(d.getDate() + amount);\n return d;\n }\n\n setTime(date: Date, hours: number, minutes: number, seconds: number): Date {\n const d = this.clone(date);\n d.setHours(hours, minutes, seconds, 0);\n return d;\n }\n\n // Comparison\n\n isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n }\n\n isSameMonth(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();\n }\n\n compareDate(a: Date, b: Date): number {\n const ay = a.getFullYear();\n const by = b.getFullYear();\n if (ay !== by) return ay - by;\n const am = a.getMonth();\n const bm = b.getMonth();\n if (am !== bm) return am - bm;\n return a.getDate() - b.getDate();\n }\n\n // Formatting / parsing\n\n // `(string & {})` keeps autocomplete for the WrDateFormat literals\n // while still accepting any other string as a raw token pattern.\n format(date: Date, formatKeyOrString: WrDateFormat | (string & {})): string {\n if (isNamedFormat(formatKeyOrString)) {\n return this.intl(formatKeyOrString).format(date);\n }\n return this.formatWithTokens(date, formatKeyOrString);\n }\n\n /**\n * Read back what {@link format} wrote.\n *\n * A named format used to delegate to `new Date(raw)`, which understands only\n * Anglo-American forms — so the field could not read its own output anywhere else.\n * `new Date('15.3.2026')` and `new Date('14:30')` are both `Invalid Date`, while\n * `new Date('1')` is 1 January 2001: retyping a de-DE date committed the year 2001 on\n * the first keystroke and then refused every one after it, and `mode=\"time\"` collapsed\n * to midnight in EVERY locale, en-US included. The named branch now builds its parser\n * from the SAME `Intl.DateTimeFormat` that printed the string, so the round trip holds\n * by construction rather than by luck.\n *\n * Returns `null` rather than a guess whenever the string does not match — the caller's\n * committed value is then left exactly as it was, which is the contract\n * `wr-input-number` follows for unparseable text.\n */\n parse(value: string, formatKeyOrString: WrDateFormat | (string & {})): Date | null {\n const raw = value?.trim();\n if (!raw) return null;\n\n if (isNamedFormat(formatKeyOrString)) {\n return this.parseNamed(raw, formatKeyOrString);\n }\n\n return this.parseWithTokens(raw, formatKeyOrString);\n }\n\n // Locale info\n\n getFirstDayOfWeek(): number {\n // `Intl.Locale.prototype.getWeekInfo` is Stage 3 — not in TS lib types yet,\n // so we probe at runtime through an unknown cast.\n try {\n const locale = new Intl.Locale(this.locale) as unknown as { getWeekInfo?: () => { firstDay: number } };\n const info = locale.getWeekInfo?.();\n if (info && typeof info.firstDay === 'number') {\n // Intl uses 1 (Mon) – 7 (Sun); we use 0 (Sun) – 6 (Sat).\n return info.firstDay % 7;\n }\n } catch {\n // Browser doesn't support Intl.Locale or getWeekInfo — fall through.\n }\n return this.locale.toLowerCase().startsWith('en-us') ? 0 : 1;\n }\n\n /**\n * One `Intl.DateTimeFormat` per named format, built once.\n *\n * Constructing one is the expensive part of `format()`, and this adapter is\n * called per CELL: `wr-event-calendar` builds an `aria-label` for every time\n * slot on every day, so a week view asked for hundreds of identical\n * formatters. `locale` is injected once and never changes for the life of the\n * adapter, so the cache needs no invalidation — that is the whole reason it\n * can be this simple.\n */\n private readonly formatters = new Map<string, Intl.DateTimeFormat>();\n\n /**\n * Every `Intl` call this adapter makes pins `calendar: 'gregory'`, and that is a\n * correctness fix rather than a preference.\n *\n * The value type is a JS `Date`, every accessor on this class (`getYear`,\n * `getMonth`, `getDate`) is Gregorian, `createDate` builds a Gregorian date and the\n * calendar grid draws Gregorian months. A locale whose DEFAULT calendar is something\n * else — `fa-IR` resolves to `persian`, `th-TH` to `buddhist`, `ar-SA` to\n * `islamic-umalqura` in several engines — printed a field the grid beside it could\n * never agree with (`۱۴۰۴/۱۲/۲۴` over a grid headed 2026), and no parser can turn\n * that back into the `Date` it came from. Pinning the calendar makes format and parse\n * describe the same one.\n */\n private intlOptions(options: Intl.DateTimeFormatOptions): Intl.DateTimeFormatOptions {\n return { ...options, calendar: 'gregory' };\n }\n\n private intl(key: WrDateFormat): Intl.DateTimeFormat {\n let found = this.formatters.get(key);\n if (!found) {\n found = new Intl.DateTimeFormat(this.locale, this.intlOptions(INTL_OPTIONS[key]));\n this.formatters.set(key, found);\n }\n return found;\n }\n\n getDayOfWeekNames(style: 'narrow' | 'short' | 'long'): readonly string[] {\n const formatter = new Intl.DateTimeFormat(this.locale, this.intlOptions({ weekday: style }));\n const first = this.getFirstDayOfWeek();\n // Pick a reference Sunday and walk seven days.\n const base = new Date(2024, 0, 7); // Sunday 7 Jan 2024\n const out: string[] = [];\n for (let i = 0; i < 7; i++) {\n const d = new Date(base);\n d.setDate(base.getDate() + ((first + i) % 7));\n out.push(formatter.format(d));\n }\n return out;\n }\n\n /**\n * Month names in the STANDALONE (nominative) form — what a calendar heading wants.\n * Inside a date the same name often declines; {@link monthNames} serves that form to\n * the token formatter, and this method deliberately keeps the heading one.\n */\n getMonthNames(style: 'narrow' | 'short' | 'long'): readonly string[] {\n return this.monthNames(style, 'standalone');\n }\n\n private numeralsCache: readonly string[] | null = null;\n\n /** The locale's own ten digits, cached — empty when its system is algorithmic. */\n private localeNumerals(): readonly string[] {\n this.numeralsCache ??=\n numeralsFor(this.locale, new Intl.NumberFormat(this.locale).resolvedOptions().numberingSystem) ?? [];\n return this.numeralsCache;\n }\n\n private dayPeriodCache: readonly [string, string] | null = null;\n\n /**\n * `[am, pm]` as the LOCALE writes them — `PM`, `م`, `午後`.\n *\n * The `a` token used to return a hard-coded lowercase `pm`, byte for byte identical in\n * every locale, which made it the one token in the pattern language that could not be\n * localised at all. `Intl` is the source rather than the i18n catalog because\n * `ngwr/date` deliberately depends on nothing: the panel next to it reads\n * `datePicker.am` / `datePicker.pm`, so an app that wants its own wording overrides it\n * there and passes a 24-hour pattern here.\n */\n private dayPeriods(): readonly [string, string] {\n if (this.dayPeriodCache) return this.dayPeriodCache;\n let periods: [string, string] = ['AM', 'PM'];\n try {\n const formatter = new Intl.DateTimeFormat(this.locale, this.intlOptions({ hour: 'numeric', hour12: true }));\n const read = (hour: number): string =>\n formatter.formatToParts(new Date(2024, 0, 15, hour)).find(p => p.type === 'dayPeriod')?.value ?? '';\n const [am, pm] = [read(9), read(21)];\n if (am && pm && am !== pm) periods = [am, pm];\n } catch {\n // No `Intl` day period for this locale — the English pair stays.\n }\n this.dayPeriodCache = periods;\n return periods;\n }\n\n private readonly monthNameCache = new Map<string, readonly string[]>();\n\n /**\n * `context: 'format'` asks `Intl` for the month name as it appears BESIDE A DAY, which\n * is where a case language stops using the nominative: ru writes `15 марта`, not\n * `15 март`, and fi writes `maaliskuuta`, not `maaliskuu`. The name comes out of a\n * `{ day, month }` formatter's parts, because a `{ month }` formatter alone can only\n * ever answer with the standalone form.\n *\n * Some locales write the month NUMERICALLY in that position — fi abbreviates `15.3.`,\n * ja writes `3` with `月` as a separate literal — and there the standalone name is the\n * only name there is, so a purely numeric answer falls back to it. Without that guard\n * `dd MMMM yyyy` would render `15 3 2026` in Japanese.\n */\n private monthNames(style: 'narrow' | 'short' | 'long', context: 'standalone' | 'format'): readonly string[] {\n const cacheKey = `${style}:${context}`;\n const cached = this.monthNameCache.get(cacheKey);\n if (cached) return cached;\n\n const standaloneFormatter = new Intl.DateTimeFormat(this.locale, this.intlOptions({ month: style }));\n const standalone: string[] = [];\n for (let i = 0; i < 12; i++) standalone.push(standaloneFormatter.format(new Date(2024, i, 15)));\n\n let out: readonly string[] = standalone;\n if (context === 'format') {\n const numerals = numeralsFor(this.locale, standaloneFormatter.resolvedOptions().numberingSystem) ?? [];\n const inDate = new Intl.DateTimeFormat(this.locale, this.intlOptions({ day: 'numeric', month: style }));\n out = standalone.map((name, i) => {\n const part = inDate.formatToParts(new Date(2024, i, 15)).find(p => p.type === 'month')?.value;\n if (!part || isAllDigits(part, numerals)) return name;\n return part;\n });\n }\n\n this.monthNameCache.set(cacheKey, out);\n return out;\n }\n\n // Internals: token-based format / parse\n\n /** Whether a token pattern also writes the day, which decides the month's form. */\n private hasDayToken(pattern: string): boolean {\n let found = false;\n pattern.replace(PART_RE, (part: string, quoted?: string) => {\n if (quoted === undefined && (part === 'd' || part === 'dd')) found = true;\n return part;\n });\n return found;\n }\n\n private formatWithTokens(date: Date, pattern: string): string {\n const year = date.getFullYear();\n const month = date.getMonth();\n const day = date.getDate();\n const hours24 = date.getHours();\n const hours12 = hours24 % 12 === 0 ? 12 : hours24 % 12;\n const minutes = date.getMinutes();\n const seconds = date.getSeconds();\n // A pattern that writes the day wants the month declined for that position — `MMMM`\n // used to hand `15 март 2026` to a Russian field, which reads as machine output.\n const context = this.hasDayToken(pattern) ? 'format' : 'standalone';\n const monthNames = this.monthNames('long', context);\n const monthShort = this.monthNames('short', context);\n\n return pattern.replace(PART_RE, (part, quoted?: string) => {\n // A quoted run is emitted as-is; `''` is how a single quote is written.\n if (quoted !== undefined) return quoted === '' ? \"'\" : quoted;\n const token = part;\n switch (token) {\n case 'yyyy':\n return pad(year, 4);\n case 'yy':\n return pad(year % 100, 2);\n case 'MMMM':\n return monthNames[month] ?? '';\n case 'MMM':\n return monthShort[month] ?? '';\n case 'MM':\n return pad(month + 1);\n case 'M':\n return String(month + 1);\n case 'dd':\n return pad(day);\n case 'd':\n return String(day);\n case 'HH':\n return pad(hours24);\n case 'H':\n return String(hours24);\n case 'hh':\n return pad(hours12);\n case 'h':\n return String(hours12);\n case 'mm':\n return pad(minutes);\n case 'ss':\n return pad(seconds);\n case 'a':\n return this.dayPeriods()[hours24 < 12 ? 0 : 1];\n }\n return token;\n });\n }\n\n private parseWithTokens(value: string, pattern: string): Date | null {\n const tokens: string[] = [];\n // Both forms are accepted on the way IN: the formatter writes the declined one beside\n // a day (`15 марта`), and a heading or an older stored string carries the nominative.\n const monthLong = [this.monthNames('long', 'format'), this.monthNames('long', 'standalone')];\n const monthShort = [this.monthNames('short', 'format'), this.monthNames('short', 'standalone')];\n const numerals = this.localeNumerals();\n const digits = digitClass(numerals);\n const escaped = pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = escaped.replace(PART_RE, (part, quoted?: string) => {\n if (quoted !== undefined) {\n // Literal text matches itself and captures nothing, so the token indices stay\n // aligned with the groups below.\n return quoted === '' ? \"'\" : quoted;\n }\n tokens.push(part);\n // `a` is the one token whose text is locale-dependent, so its alternation is built\n // here rather than in the pure `tokenToRegex`: the marker this adapter now PRINTS\n // has to be one the same adapter can read.\n if (part === 'a') return `(${alternation([...this.dayPeriods(), 'am', 'pm'])})`;\n return tokenToRegex(part, digits);\n });\n\n const match = new RegExp(`^${regex}$`, 'i').exec(value);\n if (!match) return null;\n\n const parts: DateParts = {};\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n const raw = match[i + 1];\n const n = digitsToNumber(raw, numerals);\n switch (token) {\n case 'yyyy':\n parts.year = n;\n break;\n case 'yy':\n parts.year = 2000 + n;\n break;\n case 'MM':\n case 'M':\n parts.month = n - 1;\n break;\n case 'MMM':\n case 'MMMM': {\n const sets = token === 'MMM' ? monthShort : monthLong;\n const wanted = raw.toLowerCase();\n const found = sets\n .map(names => names.findIndex(name => name.toLowerCase() === wanted))\n .find(index => index >= 0);\n if (found === undefined) return null;\n parts.month = found;\n break;\n }\n case 'dd':\n case 'd':\n parts.day = n;\n break;\n case 'HH':\n case 'H':\n parts.hours = n;\n break;\n case 'hh':\n case 'h':\n parts.hour12 = n;\n break;\n case 'mm':\n parts.minutes = n;\n break;\n case 'ss':\n parts.seconds = n;\n break;\n case 'a': {\n const marker = raw.toLowerCase();\n parts.isPm = marker === 'pm' || marker === this.dayPeriods()[1].toLowerCase();\n break;\n }\n }\n }\n\n return this.compose(parts);\n }\n\n /**\n * Build the parser for one named format out of the very formatter that prints it.\n *\n * `formatToParts` is the only honest source for a locale's field ORDER and its\n * literals — ru writes `dd.MM.y` with a two-digit month while its own\n * `{ month: 'numeric' }` request says one digit, ja puts the year first, and ar-SA\n * separates fields with U+200F. Names (a month, AM/PM) become an alternation of the\n * real strings; numbers accept the locale's digits AND ASCII, because a physical\n * keyboard produces the latter whatever the display shows.\n *\n * Returns `null` — meaning \"this format cannot be read back\" — rather than guessing,\n * for a field type nothing here asks for (an era, a weekday) or a numbering system\n * with no digit-by-digit reading (roman numerals). `parse` then refuses, which leaves\n * the caller's committed value untouched.\n */\n private buildNamedParser(key: WrDateFormat): NamedParser | null {\n const formatter = this.intl(key);\n const resolved = formatter.resolvedOptions();\n const numerals = numeralsFor(this.locale, resolved.numberingSystem);\n if (!numerals) return null;\n const digits = digitClass(numerals);\n\n // Distinct values in every field, so nothing below can read one field's reference\n // value out of another's position.\n const reference = new Date(2024, 0, 15, 13, 45, 56);\n const fields: NamedField[] = [];\n const fragments: { readonly source: string; readonly literal: boolean }[] = [];\n\n for (const part of formatter.formatToParts(reference)) {\n switch (part.type) {\n case 'literal':\n fragments.push({ source: literalToRegex(part.value), literal: true });\n break;\n case 'year':\n fields.push({ kind: 'year' });\n // Exactly two digits or exactly four — the shapes a year is actually written\n // in. `{1,4}` would let the third keystroke of `15.3.2026` read as the year 2\n // and commit it, which is a smaller version of the defect this replaces.\n fragments.push({ source: `(${digits}{2}|${digits}{4})`, literal: false });\n break;\n case 'month': {\n const names = this.namedMonthNames(formatter);\n if (names.every(name => isAllDigits(name, numerals))) {\n fields.push({ kind: 'month' });\n fragments.push({ source: `(${digits}{1,2})`, literal: false });\n } else {\n fields.push({ kind: 'monthName', names });\n fragments.push({ source: `(${alternation(names)})`, literal: false });\n }\n break;\n }\n case 'day':\n fields.push({ kind: 'day' });\n fragments.push({ source: `(${digits}{1,2})`, literal: false });\n break;\n case 'hour':\n fields.push({ kind: 'hour' });\n fragments.push({ source: `(${digits}{1,2})`, literal: false });\n break;\n case 'minute':\n fields.push({ kind: 'minute' });\n fragments.push({ source: `(${digits}{1,2})`, literal: false });\n break;\n case 'second':\n fields.push({ kind: 'second' });\n fragments.push({ source: `(${digits}{1,2})`, literal: false });\n break;\n case 'dayPeriod': {\n const names = this.dayPeriodNames(formatter);\n fields.push({ kind: 'dayPeriod', names });\n fragments.push({ source: `(${alternation(names)})`, literal: false });\n break;\n }\n default:\n return null;\n }\n }\n\n if (!fields.length) return null;\n\n // A trailing literal is optional. ru's medium date ends ` г.` and fi's short date\n // ends with a bare `.`; someone retyping the field types the fields and stops, and\n // refusing that would reintroduce the very \"cannot read its own output\" defect for\n // the one part of the string that carries no information.\n const source = fragments\n .map((fragment, i) =>\n i === fragments.length - 1 && fragment.literal && fragment.source ? `(?:${fragment.source})?` : fragment.source\n )\n .join('');\n\n return { regex: new RegExp(`^${source}$`, 'iu'), fields, numerals, hourCycle: resolved.hourCycle };\n }\n\n /** The twelve month strings THIS formatter writes, in its own style and context. */\n private namedMonthNames(formatter: Intl.DateTimeFormat): readonly string[] {\n const out: string[] = [];\n for (let i = 0; i < 12; i++) {\n out.push(formatter.formatToParts(new Date(2024, i, 15)).find(p => p.type === 'month')?.value ?? '');\n }\n return out;\n }\n\n /** `[am, pm]` as THIS formatter writes them — `ص` / `م` in Arabic, not AM / PM. */\n private dayPeriodNames(formatter: Intl.DateTimeFormat): readonly string[] {\n const read = (hour: number): string =>\n formatter.formatToParts(new Date(2024, 0, 15, hour, 30)).find(p => p.type === 'dayPeriod')?.value ?? '';\n return [read(9), read(21)];\n }\n\n private readonly namedParsers = new Map<WrDateFormat, NamedParser | null>();\n\n private parseNamed(raw: string, key: WrDateFormat): Date | null {\n let parser = this.namedParsers.get(key);\n if (parser === undefined) {\n parser = this.buildNamedParser(key);\n this.namedParsers.set(key, parser);\n }\n if (!parser) return null;\n\n const match = parser.regex.exec(stripBidi(raw));\n if (!match) return null;\n\n const parts: DateParts = {};\n const twelveHour = parser.fields.some(field => field.kind === 'dayPeriod');\n\n for (let i = 0; i < parser.fields.length; i++) {\n const field = parser.fields[i];\n const captured = match[i + 1] ?? '';\n if (field.kind === 'monthName' || field.kind === 'dayPeriod') {\n const wanted = stripBidi(captured).toLowerCase();\n const index = (field.names ?? []).findIndex(name => stripBidi(name).toLowerCase() === wanted);\n if (index < 0) return null;\n if (field.kind === 'monthName') parts.month = index;\n else parts.isPm = index === 1;\n continue;\n }\n\n const n = digitsToNumber(captured, parser.numerals);\n if (Number.isNaN(n)) return null;\n switch (field.kind) {\n case 'year':\n // Two digits mean this century, the same reading the `yy` token gives — the\n // picker's own doc promises `1/5/25` cleans up to 2025.\n parts.year = captured.length <= 2 ? 2000 + n : n;\n break;\n case 'month':\n parts.month = n - 1;\n break;\n case 'day':\n parts.day = n;\n break;\n case 'hour':\n if (twelveHour) parts.hour12 = n;\n // `hourCycle: 'h24'` numbers midnight 24 rather than 0.\n else parts.hours = n === 24 && parser.hourCycle === 'h24' ? 0 : n;\n break;\n case 'minute':\n parts.minutes = n;\n break;\n case 'second':\n parts.seconds = n;\n break;\n }\n }\n\n return this.compose(parts);\n }\n\n /**\n * Assemble whatever was read into a `Date`, or refuse.\n *\n * `new Date(2025, 12, 45)` does not fail — it rolls forward into the next year — and\n * `isValid` is happy with the result, so a text field used to turn nonsense into a\n * confident wrong answer. The clock parts are range-checked directly; the month and the\n * day are checked by comparing what came back, which catches every rollover including a\n * month of 12 or -1.\n */\n private compose(parts: DateParts): Date | null {\n const now = new Date();\n const year = parts.year ?? now.getFullYear();\n const month = parts.month ?? now.getMonth();\n\n let hours = parts.hours ?? 0;\n if (parts.hour12 !== undefined) hours = (parts.hour12 % 12) + (parts.isPm ? 12 : 0);\n const minutes = parts.minutes ?? 0;\n const seconds = parts.seconds ?? 0;\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59) return null;\n\n // A time-only format carries no date, and the date it should imply is TODAY — the\n // previous default was 1 January, so a picker in `mode=\"time\"` moved the model back\n // to New Year's Day as a side effect of reading a clock. The default is clamped to\n // the month it lands in, because an unclamped 31st would roll a February string\n // forward and the rollover check below would then refuse a well-formed string.\n const monthLength = new Date(year, month + 1, 0).getDate();\n const day = parts.day ?? Math.min(now.getDate(), monthLength);\n\n const out = new Date(year, month, day, hours, minutes, seconds);\n // Same trap `createDate` documents: a year under 100 maps onto 1900 + year unless it\n // is written back explicitly, so `0025-08-11` used to parse as 1925.\n if (year >= 0 && year < 100) out.setFullYear(year);\n if (!this.isValid(out)) return null;\n if (out.getMonth() !== month || out.getDate() !== day) return null;\n return out;\n }\n}\n\nexport { isNamedFormat };\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport type { WrDateAdapterOptions } from './interfaces';\nimport { WR_DATE_LOCALE } from './tokens';\nimport { WrDateAdapter } from './wr-date-adapter';\nimport { WrNativeDateAdapter } from './wr-native-date-adapter';\n\n/**\n * Register the date adapter and locale used by the calendar / date picker /\n * time picker. Call once at bootstrap.\n *\n * Omit `locale` and dates follow Angular's `LOCALE_ID`, which is what the app\n * already says it is. Pass one only to pin dates to something else — see\n * {@link WR_DATE_LOCALE}, and `WrI18n` for how the three locale inputs rank.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideWrDateAdapter(), // native adapter, LOCALE_ID\n * // provideWrDateAdapter({ locale: 'ru-RU' }), // pin the dates\n * // provideWrDateAdapter({ adapter: MyDateFnsAdapter, locale: 'fr' }),\n * ],\n * });\n * ```\n */\nexport function provideWrDateAdapter(options: WrDateAdapterOptions = {}): EnvironmentProviders {\n const providers: Parameters<typeof makeEnvironmentProviders>[0] = [\n { provide: WrDateAdapter, useClass: options.adapter ?? WrNativeDateAdapter },\n ];\n\n if (options.locale) {\n providers.push({ provide: WR_DATE_LOCALE, useValue: options.locale });\n }\n\n return makeEnvironmentProviders(providers);\n}\n\nexport type { WrDateAdapterOptions } from './interfaces';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Directionality } from '@angular/cdk/bidi';
|
|
1
2
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
2
3
|
import * as i1 from '@angular/cdk/drag-drop';
|
|
3
4
|
import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop';
|
|
@@ -29,6 +30,10 @@ let sortableListUid = 0;
|
|
|
29
30
|
* handling of its own, so without this the component's only function was
|
|
30
31
|
* unreachable from a keyboard.
|
|
31
32
|
*
|
|
33
|
+
* Reading direction: a `horizontal` list follows the VISUAL order, so under
|
|
34
|
+
* `dir="rtl"` ArrowLeft moves the held row toward the higher index — the same
|
|
35
|
+
* rule `wr-slider` applies to its track. A vertical list never mirrors.
|
|
36
|
+
*
|
|
32
37
|
* What that does NOT answer is WCAG 2.5.7, which asks for a POINTER alternative
|
|
33
38
|
* to the drag. Click-to-pick-up is the obvious candidate and is not safe here:
|
|
34
39
|
* the CDK's drag-drop bundle installs no click suppressor of any kind, so the
|
|
@@ -80,6 +85,21 @@ class WrSortableList {
|
|
|
80
85
|
rowTemplate = contentChild.required((TemplateRef), /* @ts-ignore */
|
|
81
86
|
...(ngDevMode ? [{ debugName: "rowTemplate" }] : /* istanbul ignore next */ []));
|
|
82
87
|
injector = inject(Injector);
|
|
88
|
+
/**
|
|
89
|
+
* Ambient reading direction, for the horizontal keyboard path only.
|
|
90
|
+
*
|
|
91
|
+
* Optional so a bare `TestBed` — or any consumer that never set a direction —
|
|
92
|
+
* needs no provider; `Directionality` is root-provided, so `null` only ever
|
|
93
|
+
* means "nobody asked", which is LTR. Nothing caches a direction-derived
|
|
94
|
+
* value: `isRtl()` is read inside the key handler, so a runtime flip needs no
|
|
95
|
+
* subscription to `Directionality.change`.
|
|
96
|
+
*
|
|
97
|
+
* The POINTER path already mirrors without this — `cdkDropList` injects
|
|
98
|
+
* `Directionality` itself and feeds it to `DropListRef.withDirection`, so a
|
|
99
|
+
* horizontal drag has always followed the visual order. The keyboard path was
|
|
100
|
+
* the half that did not, which is why the two disagreed.
|
|
101
|
+
*/
|
|
102
|
+
dir = inject(Directionality, { optional: true });
|
|
83
103
|
rowEls = viewChildren('row', /* @ts-ignore */
|
|
84
104
|
...(ngDevMode ? [{ debugName: "rowEls" }] : /* istanbul ignore next */ []));
|
|
85
105
|
/** Index of the row the keyboard is holding, or `null` when nothing is held. */
|
|
@@ -127,8 +147,16 @@ class WrSortableList {
|
|
|
127
147
|
return;
|
|
128
148
|
const grabbed = this.grabbedIndex();
|
|
129
149
|
const horizontal = this.orientation() === 'horizontal';
|
|
130
|
-
|
|
131
|
-
|
|
150
|
+
// The horizontal arrows name a SIDE of the row, so they follow the reading
|
|
151
|
+
// direction: a horizontal list under `dir="rtl"` paints index 0 at the right,
|
|
152
|
+
// so the key that raises the index is ArrowLeft. Raising it on ArrowRight
|
|
153
|
+
// regardless moved the held item away from the arrow the user pressed — the
|
|
154
|
+
// one failure in this set a user cannot rationalise, because it inverts their
|
|
155
|
+
// model of the list silently. The block arrows name a value's direction in a
|
|
156
|
+
// column and never mirror, which is why only the horizontal pair is swapped.
|
|
157
|
+
const rtl = horizontal && this.dir?.value === 'rtl';
|
|
158
|
+
const forward = horizontal ? (rtl ? 'ArrowLeft' : 'ArrowRight') : 'ArrowDown';
|
|
159
|
+
const back = horizontal ? (rtl ? 'ArrowRight' : 'ArrowLeft') : 'ArrowUp';
|
|
132
160
|
if (event.key === ' ' || event.key === 'Enter') {
|
|
133
161
|
event.preventDefault();
|
|
134
162
|
if (grabbed === null)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-drag-drop.mjs","sources":["../../../projects/lib/drag-drop/sortable-list.ts","../../../projects/lib/drag-drop/sortable-list.html","../../../projects/lib/drag-drop/drag-handle.ts","../../../projects/lib/drag-drop/ngwr-drag-drop.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CdkDrag, type CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { NgTemplateOutlet } from '@angular/common';\nimport type { ElementRef } from '@angular/core';\nimport {\n Component,\n Injector,\n TemplateRef,\n ViewEncapsulation,\n afterNextRender,\n contentChild,\n inject,\n input,\n model,\n output,\n signal,\n viewChildren,\n} from '@angular/core';\n\nimport { readI18nText, useI18nFormatter } from 'ngwr/i18n';\n\nimport type { WrSortableReorderEvent } from './interfaces';\n\n/** Counted, not random: the list prerenders, so the id has to match on rehydration. */\nlet sortableListUid = 0;\n\n/**\n * Drag-to-reorder list. Wraps CDK's `cdkDropList` + `cdkDrag` with a\n * signal-based items binding — the source array is updated in place and\n * emitted via 2-way `[(items)]`.\n *\n * Drop a single template — it's rendered per item with `let-item\n * let-index=\"index\"`. Put `wrDragHandle` on an element inside that\n * template to restrict drag start to a handle; there is no input for\n * it, the directive's presence is the switch.\n *\n * Every row is a tab stop: Space or Enter picks it up, the arrow keys move it,\n * Space or Enter drops it and Escape puts it back. CDK's `cdkDrag` ships no key\n * handling of its own, so without this the component's only function was\n * unreachable from a keyboard.\n *\n * What that does NOT answer is WCAG 2.5.7, which asks for a POINTER alternative\n * to the drag. Click-to-pick-up is the obvious candidate and is not safe here:\n * the CDK's drag-drop bundle installs no click suppressor of any kind, so the\n * mouseup ending a drag still produces a click, and a row that grabbed itself on\n * click would be picking itself straight back up. A visible move-up /\n * move-down affordance is the remaining answer, and that is a design change.\n *\n * @example\n * ```html\n * <wr-sortable-list [(items)]=\"rows\" (reorder)=\"onReorder($event)\">\n * <ng-template let-row let-i=\"index\">\n * <div class=\"row\">\n * <span wrDragHandle>≡</span>\n * {{ i + 1 }}. {{ row.label }}\n * </div>\n * </ng-template>\n * </wr-sortable-list>\n * ```\n *\n * @see https://ngwr.dev/reference/components/drag-drop\n */\n@Component({\n selector: 'wr-sortable-list',\n templateUrl: './sortable-list.html',\n styleUrl: './sortable-list.scss',\n encapsulation: ViewEncapsulation.None,\n imports: [CdkDropList, CdkDrag, NgTemplateOutlet],\n host: { class: 'wr-sortable-list' },\n})\nexport class WrSortableList<T = unknown> {\n /** Items to render. Two-way — emits the reordered array on drop. */\n readonly items = model.required<T[]>();\n\n /** Layout direction. Drives CDK's `cdkDropListOrientation`. @default 'vertical' */\n readonly orientation = input<'vertical' | 'horizontal'>('vertical');\n\n /** Disable all dragging. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /** Locked axis — restrict drag movement to one axis even diagonally. */\n readonly lockAxis = input<'x' | 'y' | undefined>(undefined);\n\n /**\n * Delay (ms) before a drag begins after the pointer goes down. The touch\n * delay is the fix for the classic CDK touch snag: without it, the\n * `touch-action: none` CDK puts on each item blocks scrolling the list on a\n * phone. With a small touch delay, a quick swipe scrolls and a brief hold\n * starts the drag; mouse stays instant. Pass a single number to apply one\n * delay to both pointers. @default { touch: 150, mouse: 0 }\n */\n readonly dragStartDelay = input<number | { touch: number; mouse: number }>({ touch: 150, mouse: 0 });\n\n /** `trackBy` for the inner `@for`. Defaults to identity. */\n readonly trackBy = input<(index: number, item: T) => unknown>((_, item) => item);\n\n /** Fired after a successful reorder with the new array + indices. */\n readonly reorder = output<WrSortableReorderEvent<T>>();\n\n protected readonly rowTemplate = contentChild.required(TemplateRef<{ $implicit: T; index: number }>);\n\n private readonly injector = inject(Injector);\n\n private readonly rowEls = viewChildren<ElementRef<HTMLElement>>('row');\n\n /** Index of the row the keyboard is holding, or `null` when nothing is held. */\n protected readonly grabbedIndex = signal<number | null>(null);\n\n /** Live-region text. Written by the keyboard path only. */\n protected readonly announcement = signal('');\n\n /** Links every row to the key model via `aria-describedby`. */\n protected readonly keyHelpId = `wr-sortable-list-help-${++sortableListUid}`;\n\n protected readonly resolvedKeyHelp = readI18nText(\n 'sortableList.keyHelp',\n 'Press Space to pick this item up, then use the arrow keys to move it. ' +\n 'Press Space again to drop it, or Escape to put it back.'\n );\n\n private readonly grabbedText = useI18nFormatter('sortableList.grabbed', 'Grabbed. {{index}} of {{total}}.');\n private readonly movedText = useI18nFormatter('sortableList.moved', '{{index}} of {{total}}.');\n private readonly droppedText = useI18nFormatter('sortableList.dropped', 'Dropped. {{index}} of {{total}}.');\n private readonly cancelledText = readI18nText('sortableList.cancelled', 'Move cancelled.');\n\n /** Where the held row started. Escape puts it back there. */\n private grabOrigin = -1;\n\n /** True while a keyboard move is handing focus back — see `onRowFocusout`. */\n private restoringFocus = false;\n\n protected onDrop(event: CdkDragDrop<T[]>): void {\n if (event.previousIndex === event.currentIndex) return;\n const next = this.items().slice();\n moveItemInArray(next, event.previousIndex, event.currentIndex);\n this.items.set(next);\n this.reorder.emit({\n items: next,\n previousIndex: event.previousIndex,\n currentIndex: event.currentIndex,\n item: next[event.currentIndex],\n });\n }\n\n /**\n * The keyboard reorder path: pick up, move, drop — deliberately a two-step\n * grab rather than \"an arrow moves the focused row\", so that arrowing through\n * a list a user is only reading can never rearrange it.\n *\n * Keys are handled only when the ROW itself is the event target; a button or\n * an input projected into the row template keeps every key it would normally\n * get.\n */\n protected onRowKeydown(event: KeyboardEvent, index: number): void {\n if (this.disabled() || event.target !== event.currentTarget) return;\n\n const grabbed = this.grabbedIndex();\n const horizontal = this.orientation() === 'horizontal';\n const forward = horizontal ? 'ArrowRight' : 'ArrowDown';\n const back = horizontal ? 'ArrowLeft' : 'ArrowUp';\n\n if (event.key === ' ' || event.key === 'Enter') {\n event.preventDefault();\n if (grabbed === null) this.grab(index);\n else this.drop();\n return;\n }\n\n if (grabbed === null) return;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n // Held only while a row is grabbed — an Escape typed anywhere else has to\n // keep reaching whatever dialog or overlay the list is sitting in.\n event.stopPropagation();\n this.cancelGrab();\n return;\n }\n\n if (event.key === forward || event.key === back) {\n event.preventDefault();\n this.moveGrabbed(event.key === forward ? 1 : -1);\n }\n }\n\n /**\n * Focus leaving a held row ends the gesture as a drop rather than dropping the\n * change on the floor — `[(items)]` has already been written by then, so a\n * silent release would leave `reorder` never reporting a move that happened.\n * The guard is what makes it safe: moving a focused node in the DOM blurs it,\n * so every keyboard move fires this too.\n */\n protected onRowFocusout(): void {\n if (this.restoringFocus || this.grabbedIndex() === null) return;\n this.drop();\n }\n\n private grab(index: number): void {\n this.grabOrigin = index;\n this.grabbedIndex.set(index);\n this.announcement.set(this.grabbedText(this.position(index)));\n }\n\n private moveGrabbed(delta: number): void {\n const from = this.grabbedIndex();\n if (from === null) return;\n const to = from + delta;\n if (to < 0 || to >= this.items().length) return;\n\n this.relocate(from, to);\n this.grabbedIndex.set(to);\n this.announcement.set(this.movedText(this.position(to)));\n }\n\n private drop(): void {\n const to = this.grabbedIndex();\n const from = this.grabOrigin;\n this.grabbedIndex.set(null);\n this.grabOrigin = -1;\n if (to === null) return;\n\n this.announcement.set(this.droppedText(this.position(to)));\n if (from === to) return;\n // One event per gesture, the way a drag emits one on drop — not one per\n // arrow press, which would put a host that persists on `reorder` through a\n // write per keystroke. `[(items)]` still updates on every press, because\n // the rendered order has to follow the row the user is moving.\n this.reorder.emit({ items: this.items(), previousIndex: from, currentIndex: to, item: this.items()[to] });\n }\n\n private cancelGrab(): void {\n const from = this.grabbedIndex();\n if (from === null) return;\n if (from !== this.grabOrigin) this.relocate(from, this.grabOrigin);\n this.grabbedIndex.set(null);\n this.grabOrigin = -1;\n this.announcement.set(this.cancelledText());\n }\n\n private relocate(from: number, to: number): void {\n const next = this.items().slice();\n moveItemInArray(next, from, to);\n this.items.set(next);\n\n // The row is the same DOM node moved to another slot, and moving a focused\n // node hands focus back to `<body>` — so it has to be taken again once the\n // move has rendered. `afterNextRender`, never a microtask: zoneless change\n // detection runs in a macrotask, so a microtask would fire while the row is\n // still at its old index and focus the wrong one. (jsdom keeps focus across\n // a node move, so no spec here can express that half.)\n this.restoringFocus = true;\n afterNextRender(\n () => {\n this.rowEls()[to]?.nativeElement.focus();\n this.restoringFocus = false;\n },\n { injector: this.injector }\n );\n }\n\n private position(index: number): { index: number; total: number } {\n return { index: index + 1, total: this.items().length };\n }\n}\n\nexport type { WrSortableReorderEvent } from './interfaces';\n","<!--\n `role=\"list\"` / `role=\"listitem\"` rather than the bare divs this used to be:\n every row is a tab stop now, and a focusable element with no role at all is\n announced as loose text. The list role is also what gives the reader the\n position of the row focus lands on.\n-->\n<div\n cdkDropList\n role=\"list\"\n class=\"wr-sortable-list__list\"\n [cdkDropListOrientation]=\"orientation()\"\n [cdkDropListDisabled]=\"disabled()\"\n (cdkDropListDropped)=\"onDrop($event)\"\n>\n @for (item of items(); track trackBy()($index, item)) {\n <div\n #row\n cdkDrag\n role=\"listitem\"\n class=\"wr-sortable-list__item\"\n [class.wr-sortable-list__item--grabbed]=\"grabbedIndex() === $index\"\n [attr.tabindex]=\"disabled() ? null : 0\"\n [attr.aria-describedby]=\"disabled() ? null : keyHelpId\"\n [cdkDragDisabled]=\"disabled()\"\n [cdkDragLockAxis]=\"lockAxis() ?? null\"\n [cdkDragStartDelay]=\"dragStartDelay()\"\n (keydown)=\"onRowKeydown($event, $index)\"\n (focusout)=\"onRowFocusout()\"\n >\n <ng-container *ngTemplateOutlet=\"rowTemplate(); context: { $implicit: item, index: $index }\" />\n </div>\n }\n</div>\n\n<!--\n The key model, on every row rather than once on the container: focus lands on\n a row and never on the list itself, so a description hung on the list would\n never be read out.\n-->\n<p class=\"wr-sortable-list__sr-only\" [id]=\"keyHelpId\">{{ resolvedKeyHelp() }}</p>\n\n<!--\n Position announcements, written by the keyboard path only — a drag already\n gives sighted feedback, and announcing every pointer move would flood the\n region.\n-->\n<p class=\"wr-sortable-list__sr-only\" role=\"status\">{{ announcement() }}</p>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { CdkDragHandle } from '@angular/cdk/drag-drop';\nimport { Directive } from '@angular/core';\n\n/**\n * Drag handle for {@link WrSortableList} (and any nested `cdkDrag`).\n * Composes CDK's `cdkDragHandle` via `hostDirectives` so consumers don't\n * need to import the CDK selector directly.\n *\n * @example\n * ```html\n * <wr-sortable-list [(items)]=\"rows\">\n * <ng-template let-row>\n * <div class=\"row\">\n * <span wrDragHandle class=\"grip\">≡</span>\n * <span>{{ row.label }}</span>\n * </div>\n * </ng-template>\n * </wr-sortable-list>\n * ```\n */\n@Directive({\n selector: '[wrDragHandle]',\n hostDirectives: [CdkDragHandle],\n host: { class: 'wr-drag-handle' },\n})\nexport class WrDragHandle {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngwr-drag-drop.mjs","sources":["../../../projects/lib/drag-drop/sortable-list.ts","../../../projects/lib/drag-drop/sortable-list.html","../../../projects/lib/drag-drop/drag-handle.ts","../../../projects/lib/drag-drop/ngwr-drag-drop.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CdkDrag, type CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { NgTemplateOutlet } from '@angular/common';\nimport type { ElementRef } from '@angular/core';\nimport {\n Component,\n Injector,\n TemplateRef,\n ViewEncapsulation,\n afterNextRender,\n contentChild,\n inject,\n input,\n model,\n output,\n signal,\n viewChildren,\n} from '@angular/core';\n\nimport { readI18nText, useI18nFormatter } from 'ngwr/i18n';\n\nimport type { WrSortableReorderEvent } from './interfaces';\n\n/** Counted, not random: the list prerenders, so the id has to match on rehydration. */\nlet sortableListUid = 0;\n\n/**\n * Drag-to-reorder list. Wraps CDK's `cdkDropList` + `cdkDrag` with a\n * signal-based items binding — the source array is updated in place and\n * emitted via 2-way `[(items)]`.\n *\n * Drop a single template — it's rendered per item with `let-item\n * let-index=\"index\"`. Put `wrDragHandle` on an element inside that\n * template to restrict drag start to a handle; there is no input for\n * it, the directive's presence is the switch.\n *\n * Every row is a tab stop: Space or Enter picks it up, the arrow keys move it,\n * Space or Enter drops it and Escape puts it back. CDK's `cdkDrag` ships no key\n * handling of its own, so without this the component's only function was\n * unreachable from a keyboard.\n *\n * Reading direction: a `horizontal` list follows the VISUAL order, so under\n * `dir=\"rtl\"` ArrowLeft moves the held row toward the higher index — the same\n * rule `wr-slider` applies to its track. A vertical list never mirrors.\n *\n * What that does NOT answer is WCAG 2.5.7, which asks for a POINTER alternative\n * to the drag. Click-to-pick-up is the obvious candidate and is not safe here:\n * the CDK's drag-drop bundle installs no click suppressor of any kind, so the\n * mouseup ending a drag still produces a click, and a row that grabbed itself on\n * click would be picking itself straight back up. A visible move-up /\n * move-down affordance is the remaining answer, and that is a design change.\n *\n * @example\n * ```html\n * <wr-sortable-list [(items)]=\"rows\" (reorder)=\"onReorder($event)\">\n * <ng-template let-row let-i=\"index\">\n * <div class=\"row\">\n * <span wrDragHandle>≡</span>\n * {{ i + 1 }}. {{ row.label }}\n * </div>\n * </ng-template>\n * </wr-sortable-list>\n * ```\n *\n * @see https://ngwr.dev/reference/components/drag-drop\n */\n@Component({\n selector: 'wr-sortable-list',\n templateUrl: './sortable-list.html',\n styleUrl: './sortable-list.scss',\n encapsulation: ViewEncapsulation.None,\n imports: [CdkDropList, CdkDrag, NgTemplateOutlet],\n host: { class: 'wr-sortable-list' },\n})\nexport class WrSortableList<T = unknown> {\n /** Items to render. Two-way — emits the reordered array on drop. */\n readonly items = model.required<T[]>();\n\n /** Layout direction. Drives CDK's `cdkDropListOrientation`. @default 'vertical' */\n readonly orientation = input<'vertical' | 'horizontal'>('vertical');\n\n /** Disable all dragging. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /** Locked axis — restrict drag movement to one axis even diagonally. */\n readonly lockAxis = input<'x' | 'y' | undefined>(undefined);\n\n /**\n * Delay (ms) before a drag begins after the pointer goes down. The touch\n * delay is the fix for the classic CDK touch snag: without it, the\n * `touch-action: none` CDK puts on each item blocks scrolling the list on a\n * phone. With a small touch delay, a quick swipe scrolls and a brief hold\n * starts the drag; mouse stays instant. Pass a single number to apply one\n * delay to both pointers. @default { touch: 150, mouse: 0 }\n */\n readonly dragStartDelay = input<number | { touch: number; mouse: number }>({ touch: 150, mouse: 0 });\n\n /** `trackBy` for the inner `@for`. Defaults to identity. */\n readonly trackBy = input<(index: number, item: T) => unknown>((_, item) => item);\n\n /** Fired after a successful reorder with the new array + indices. */\n readonly reorder = output<WrSortableReorderEvent<T>>();\n\n protected readonly rowTemplate = contentChild.required(TemplateRef<{ $implicit: T; index: number }>);\n\n private readonly injector = inject(Injector);\n\n /**\n * Ambient reading direction, for the horizontal keyboard path only.\n *\n * Optional so a bare `TestBed` — or any consumer that never set a direction —\n * needs no provider; `Directionality` is root-provided, so `null` only ever\n * means \"nobody asked\", which is LTR. Nothing caches a direction-derived\n * value: `isRtl()` is read inside the key handler, so a runtime flip needs no\n * subscription to `Directionality.change`.\n *\n * The POINTER path already mirrors without this — `cdkDropList` injects\n * `Directionality` itself and feeds it to `DropListRef.withDirection`, so a\n * horizontal drag has always followed the visual order. The keyboard path was\n * the half that did not, which is why the two disagreed.\n */\n private readonly dir = inject(Directionality, { optional: true });\n\n private readonly rowEls = viewChildren<ElementRef<HTMLElement>>('row');\n\n /** Index of the row the keyboard is holding, or `null` when nothing is held. */\n protected readonly grabbedIndex = signal<number | null>(null);\n\n /** Live-region text. Written by the keyboard path only. */\n protected readonly announcement = signal('');\n\n /** Links every row to the key model via `aria-describedby`. */\n protected readonly keyHelpId = `wr-sortable-list-help-${++sortableListUid}`;\n\n protected readonly resolvedKeyHelp = readI18nText(\n 'sortableList.keyHelp',\n 'Press Space to pick this item up, then use the arrow keys to move it. ' +\n 'Press Space again to drop it, or Escape to put it back.'\n );\n\n private readonly grabbedText = useI18nFormatter('sortableList.grabbed', 'Grabbed. {{index}} of {{total}}.');\n private readonly movedText = useI18nFormatter('sortableList.moved', '{{index}} of {{total}}.');\n private readonly droppedText = useI18nFormatter('sortableList.dropped', 'Dropped. {{index}} of {{total}}.');\n private readonly cancelledText = readI18nText('sortableList.cancelled', 'Move cancelled.');\n\n /** Where the held row started. Escape puts it back there. */\n private grabOrigin = -1;\n\n /** True while a keyboard move is handing focus back — see `onRowFocusout`. */\n private restoringFocus = false;\n\n protected onDrop(event: CdkDragDrop<T[]>): void {\n if (event.previousIndex === event.currentIndex) return;\n const next = this.items().slice();\n moveItemInArray(next, event.previousIndex, event.currentIndex);\n this.items.set(next);\n this.reorder.emit({\n items: next,\n previousIndex: event.previousIndex,\n currentIndex: event.currentIndex,\n item: next[event.currentIndex],\n });\n }\n\n /**\n * The keyboard reorder path: pick up, move, drop — deliberately a two-step\n * grab rather than \"an arrow moves the focused row\", so that arrowing through\n * a list a user is only reading can never rearrange it.\n *\n * Keys are handled only when the ROW itself is the event target; a button or\n * an input projected into the row template keeps every key it would normally\n * get.\n */\n protected onRowKeydown(event: KeyboardEvent, index: number): void {\n if (this.disabled() || event.target !== event.currentTarget) return;\n\n const grabbed = this.grabbedIndex();\n const horizontal = this.orientation() === 'horizontal';\n // The horizontal arrows name a SIDE of the row, so they follow the reading\n // direction: a horizontal list under `dir=\"rtl\"` paints index 0 at the right,\n // so the key that raises the index is ArrowLeft. Raising it on ArrowRight\n // regardless moved the held item away from the arrow the user pressed — the\n // one failure in this set a user cannot rationalise, because it inverts their\n // model of the list silently. The block arrows name a value's direction in a\n // column and never mirror, which is why only the horizontal pair is swapped.\n const rtl = horizontal && this.dir?.value === 'rtl';\n const forward = horizontal ? (rtl ? 'ArrowLeft' : 'ArrowRight') : 'ArrowDown';\n const back = horizontal ? (rtl ? 'ArrowRight' : 'ArrowLeft') : 'ArrowUp';\n\n if (event.key === ' ' || event.key === 'Enter') {\n event.preventDefault();\n if (grabbed === null) this.grab(index);\n else this.drop();\n return;\n }\n\n if (grabbed === null) return;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n // Held only while a row is grabbed — an Escape typed anywhere else has to\n // keep reaching whatever dialog or overlay the list is sitting in.\n event.stopPropagation();\n this.cancelGrab();\n return;\n }\n\n if (event.key === forward || event.key === back) {\n event.preventDefault();\n this.moveGrabbed(event.key === forward ? 1 : -1);\n }\n }\n\n /**\n * Focus leaving a held row ends the gesture as a drop rather than dropping the\n * change on the floor — `[(items)]` has already been written by then, so a\n * silent release would leave `reorder` never reporting a move that happened.\n * The guard is what makes it safe: moving a focused node in the DOM blurs it,\n * so every keyboard move fires this too.\n */\n protected onRowFocusout(): void {\n if (this.restoringFocus || this.grabbedIndex() === null) return;\n this.drop();\n }\n\n private grab(index: number): void {\n this.grabOrigin = index;\n this.grabbedIndex.set(index);\n this.announcement.set(this.grabbedText(this.position(index)));\n }\n\n private moveGrabbed(delta: number): void {\n const from = this.grabbedIndex();\n if (from === null) return;\n const to = from + delta;\n if (to < 0 || to >= this.items().length) return;\n\n this.relocate(from, to);\n this.grabbedIndex.set(to);\n this.announcement.set(this.movedText(this.position(to)));\n }\n\n private drop(): void {\n const to = this.grabbedIndex();\n const from = this.grabOrigin;\n this.grabbedIndex.set(null);\n this.grabOrigin = -1;\n if (to === null) return;\n\n this.announcement.set(this.droppedText(this.position(to)));\n if (from === to) return;\n // One event per gesture, the way a drag emits one on drop — not one per\n // arrow press, which would put a host that persists on `reorder` through a\n // write per keystroke. `[(items)]` still updates on every press, because\n // the rendered order has to follow the row the user is moving.\n this.reorder.emit({ items: this.items(), previousIndex: from, currentIndex: to, item: this.items()[to] });\n }\n\n private cancelGrab(): void {\n const from = this.grabbedIndex();\n if (from === null) return;\n if (from !== this.grabOrigin) this.relocate(from, this.grabOrigin);\n this.grabbedIndex.set(null);\n this.grabOrigin = -1;\n this.announcement.set(this.cancelledText());\n }\n\n private relocate(from: number, to: number): void {\n const next = this.items().slice();\n moveItemInArray(next, from, to);\n this.items.set(next);\n\n // The row is the same DOM node moved to another slot, and moving a focused\n // node hands focus back to `<body>` — so it has to be taken again once the\n // move has rendered. `afterNextRender`, never a microtask: zoneless change\n // detection runs in a macrotask, so a microtask would fire while the row is\n // still at its old index and focus the wrong one. (jsdom keeps focus across\n // a node move, so no spec here can express that half.)\n this.restoringFocus = true;\n afterNextRender(\n () => {\n this.rowEls()[to]?.nativeElement.focus();\n this.restoringFocus = false;\n },\n { injector: this.injector }\n );\n }\n\n private position(index: number): { index: number; total: number } {\n return { index: index + 1, total: this.items().length };\n }\n}\n\nexport type { WrSortableReorderEvent } from './interfaces';\n","<!--\n `role=\"list\"` / `role=\"listitem\"` rather than the bare divs this used to be:\n every row is a tab stop now, and a focusable element with no role at all is\n announced as loose text. The list role is also what gives the reader the\n position of the row focus lands on.\n-->\n<div\n cdkDropList\n role=\"list\"\n class=\"wr-sortable-list__list\"\n [cdkDropListOrientation]=\"orientation()\"\n [cdkDropListDisabled]=\"disabled()\"\n (cdkDropListDropped)=\"onDrop($event)\"\n>\n @for (item of items(); track trackBy()($index, item)) {\n <div\n #row\n cdkDrag\n role=\"listitem\"\n class=\"wr-sortable-list__item\"\n [class.wr-sortable-list__item--grabbed]=\"grabbedIndex() === $index\"\n [attr.tabindex]=\"disabled() ? null : 0\"\n [attr.aria-describedby]=\"disabled() ? null : keyHelpId\"\n [cdkDragDisabled]=\"disabled()\"\n [cdkDragLockAxis]=\"lockAxis() ?? null\"\n [cdkDragStartDelay]=\"dragStartDelay()\"\n (keydown)=\"onRowKeydown($event, $index)\"\n (focusout)=\"onRowFocusout()\"\n >\n <ng-container *ngTemplateOutlet=\"rowTemplate(); context: { $implicit: item, index: $index }\" />\n </div>\n }\n</div>\n\n<!--\n The key model, on every row rather than once on the container: focus lands on\n a row and never on the list itself, so a description hung on the list would\n never be read out.\n-->\n<p class=\"wr-sortable-list__sr-only\" [id]=\"keyHelpId\">{{ resolvedKeyHelp() }}</p>\n\n<!--\n Position announcements, written by the keyboard path only — a drag already\n gives sighted feedback, and announcing every pointer move would flood the\n region.\n-->\n<p class=\"wr-sortable-list__sr-only\" role=\"status\">{{ announcement() }}</p>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { CdkDragHandle } from '@angular/cdk/drag-drop';\nimport { Directive } from '@angular/core';\n\n/**\n * Drag handle for {@link WrSortableList} (and any nested `cdkDrag`).\n * Composes CDK's `cdkDragHandle` via `hostDirectives` so consumers don't\n * need to import the CDK selector directly.\n *\n * @example\n * ```html\n * <wr-sortable-list [(items)]=\"rows\">\n * <ng-template let-row>\n * <div class=\"row\">\n * <span wrDragHandle class=\"grip\">≡</span>\n * <span>{{ row.label }}</span>\n * </div>\n * </ng-template>\n * </wr-sortable-list>\n * ```\n */\n@Directive({\n selector: '[wrDragHandle]',\n hostDirectives: [CdkDragHandle],\n host: { class: 'wr-drag-handle' },\n})\nexport class WrDragHandle {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -319,12 +319,13 @@ class WrDropdown {
|
|
|
319
319
|
this.isOpen.set(false);
|
|
320
320
|
};
|
|
321
321
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrDropdown, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
322
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.4", type: WrDropdown, isStandalone: true, selector: "[wrDropdown]", inputs: { menu: { classPropertyName: "menu", publicName: "wrDropdown", isSignal: true, isRequired: true, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, host: { listeners: { "click": "onClick($event)", "keydown": "onKeydown($event)", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave($event)" }, properties: { "attr.id": "triggerId", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "isOpen()", "attr.aria-controls": "isOpen() ? menu().menuId() : null" }, classAttribute: "wr-dropdown-trigger" }, ngImport: i0 });
|
|
322
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.4", type: WrDropdown, isStandalone: true, selector: "[wrDropdown]", inputs: { menu: { classPropertyName: "menu", publicName: "wrDropdown", isSignal: true, isRequired: true, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, host: { listeners: { "click": "onClick($event)", "keydown": "onKeydown($event)", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave($event)" }, properties: { "attr.id": "triggerId", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "isOpen()", "attr.aria-controls": "isOpen() ? menu().menuId() : null" }, classAttribute: "wr-dropdown-trigger" }, exportAs: ["wrDropdown"], ngImport: i0 });
|
|
323
323
|
}
|
|
324
324
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrDropdown, decorators: [{
|
|
325
325
|
type: Directive,
|
|
326
326
|
args: [{
|
|
327
327
|
selector: '[wrDropdown]',
|
|
328
|
+
exportAs: 'wrDropdown',
|
|
328
329
|
host: {
|
|
329
330
|
class: 'wr-dropdown-trigger',
|
|
330
331
|
'[attr.id]': 'triggerId',
|