ngwr 14.12.0 → 14.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cascader/styles/_rules.scss +9 -4
- package/fesm2022/ngwr-affix.mjs +10 -0
- package/fesm2022/ngwr-affix.mjs.map +1 -1
- package/fesm2022/ngwr-calendar.mjs +11 -0
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +6 -4
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +5 -1
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +14 -6
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-counter.mjs +5 -4
- package/fesm2022/ngwr-counter.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +4 -2
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ar.mjs +2 -2
- package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-cs.mjs +2 -2
- package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-de.mjs +2 -2
- package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +2 -2
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-es.mjs +2 -2
- package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-fr.mjs +2 -2
- package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-he.mjs +2 -2
- package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-hi.mjs +2 -2
- package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-id.mjs +2 -2
- package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-it.mjs +2 -2
- package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ja.mjs +2 -2
- package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ko.mjs +2 -2
- package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-nl.mjs +2 -2
- package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pl.mjs +2 -2
- package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pt.mjs +2 -2
- package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +2 -2
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-sv.mjs +2 -2
- package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-tr.mjs +2 -2
- package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-uk.mjs +2 -2
- package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-vi.mjs +2 -2
- package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh-TW.mjs +2 -2
- package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh.mjs +2 -2
- package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
- package/fesm2022/ngwr-icon.mjs.map +1 -1
- package/fesm2022/ngwr-list.mjs +4 -10
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-marquee.mjs +2 -2
- package/fesm2022/ngwr-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-pipes.mjs +1 -1
- package/fesm2022/ngwr-pipes.mjs.map +1 -1
- package/fesm2022/ngwr-radio.mjs +5 -1
- package/fesm2022/ngwr-radio.mjs.map +1 -1
- package/fesm2022/ngwr-segmented.mjs +5 -1
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +4 -2
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-slider.mjs +4 -2
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +26 -5
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +2 -2
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +4 -2
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-toast.mjs +1 -1
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-tour.mjs +2 -0
- package/fesm2022/ngwr-tour.mjs.map +1 -1
- package/fesm2022/ngwr-transfer.mjs +5 -1
- package/fesm2022/ngwr-transfer.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +2 -2
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/i18n/ar.json +2 -2
- package/i18n/cs.json +2 -2
- package/i18n/de.json +2 -2
- package/i18n/en.json +2 -2
- package/i18n/es.json +2 -2
- package/i18n/fr.json +2 -2
- package/i18n/he.json +2 -2
- package/i18n/hi.json +2 -2
- package/i18n/id.json +2 -2
- package/i18n/it.json +2 -2
- package/i18n/ja.json +2 -2
- package/i18n/ko.json +2 -2
- package/i18n/nl.json +2 -2
- package/i18n/pl.json +2 -2
- package/i18n/pt.json +2 -2
- package/i18n/ru.json +2 -2
- package/i18n/sv.json +2 -2
- package/i18n/tr.json +2 -2
- package/i18n/uk.json +2 -2
- package/i18n/vi.json +2 -2
- package/i18n/zh-TW.json +2 -2
- package/i18n/zh.json +2 -2
- package/package.json +1 -1
- package/types/ngwr-affix.d.ts +5 -2
- package/types/ngwr-calendar.d.ts +18 -0
- package/types/ngwr-cascader.d.ts +15 -0
- package/types/ngwr-checkbox.d.ts +14 -0
- package/types/ngwr-color-picker.d.ts +14 -0
- package/types/ngwr-counter.d.ts +7 -4
- package/types/ngwr-date-picker.d.ts +19 -0
- package/types/ngwr-icon.d.ts +12 -9
- package/types/ngwr-radio.d.ts +9 -0
- package/types/ngwr-segmented.d.ts +14 -0
- package/types/ngwr-select.d.ts +14 -0
- package/types/ngwr-slider.d.ts +19 -0
- package/types/ngwr-table.d.ts +27 -1
- package/types/ngwr-textarea.d.ts +14 -0
- package/types/ngwr-tour.d.ts +3 -2
- package/types/ngwr-transfer.d.ts +14 -0
- package/types/ngwr-version.d.ts +1 -1
|
@@ -21,8 +21,6 @@
|
|
|
21
21
|
--wr-cascader-padding-x: var(--wr-control-padding-x-md);
|
|
22
22
|
--wr-cascader-font-size: var(--wr-control-font-size-md);
|
|
23
23
|
--wr-cascader-line-height: var(--wr-control-line-height-md);
|
|
24
|
-
--wr-cascader-col-width: 12rem;
|
|
25
|
-
--wr-cascader-max-height: 16rem;
|
|
26
24
|
// Trigger width floor, the same contract as `--wr-select-min-width`. Despite
|
|
27
25
|
// the name it is a DEFAULT width rather than a minimum: an explicit `width`,
|
|
28
26
|
// `width: 100%` in a narrow parent, a `minmax(0, 1fr)` cell and a shrinking
|
|
@@ -230,6 +228,13 @@
|
|
|
230
228
|
// can't inherit the host size class). Default md.
|
|
231
229
|
--wr-cascader-opt-font: var(--wr-control-font-size-md);
|
|
232
230
|
--wr-cascader-opt-py: 0.5rem;
|
|
231
|
+
// Column geometry, declared HERE for the same reason. Both used to sit on
|
|
232
|
+
// `.wr-cascader` and be read inside this panel, which the overlay appends to
|
|
233
|
+
// the CDK container — so the host is not an ancestor of the thing reading
|
|
234
|
+
// them, and a consumer setting either on `<wr-cascader>` got the `var()`
|
|
235
|
+
// fallback and no change. Reach them through `panelClass`.
|
|
236
|
+
--wr-cascader-col-width: 12rem;
|
|
237
|
+
--wr-cascader-max-height: 16rem;
|
|
233
238
|
|
|
234
239
|
display: flex;
|
|
235
240
|
background: var(--wr-color-surface);
|
|
@@ -255,8 +260,8 @@
|
|
|
255
260
|
margin: 0;
|
|
256
261
|
// Inset padding so options read as rounded pills, matching the select panel.
|
|
257
262
|
padding: 0.25rem;
|
|
258
|
-
width: var(--wr-cascader-col-width
|
|
259
|
-
max-height: var(--wr-cascader-max-height
|
|
263
|
+
width: var(--wr-cascader-col-width);
|
|
264
|
+
max-height: var(--wr-cascader-max-height);
|
|
260
265
|
overflow-y: auto;
|
|
261
266
|
display: flex;
|
|
262
267
|
flex-direction: column;
|
package/fesm2022/ngwr-affix.mjs
CHANGED
|
@@ -8,6 +8,14 @@ import { DestroyRef, Directive, ElementRef, Injector, PLATFORM_ID, afterNextRend
|
|
|
8
8
|
* Use of this source code is governed by an MIT-style license that can be
|
|
9
9
|
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
10
10
|
*/
|
|
11
|
+
function scrollParent(el) {
|
|
12
|
+
for (let node = el.parentElement; node !== null; node = node.parentElement) {
|
|
13
|
+
if (node === document.body || node === document.documentElement) break;
|
|
14
|
+
const style = getComputedStyle(node);
|
|
15
|
+
if (/auto|scroll|overlay|hidden/.test(`${style.overflowY} ${style.overflowX}`) && node.scrollHeight > node.clientHeight) return node;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
11
19
|
var WrAffix = class WrAffix {
|
|
12
20
|
offsetTop = input(0, {
|
|
13
21
|
...ngDevMode ? { debugName: "offsetTop" } : /* istanbul ignore next */ {},
|
|
@@ -34,6 +42,7 @@ var WrAffix = class WrAffix {
|
|
|
34
42
|
let observer = null;
|
|
35
43
|
effect((onCleanup) => {
|
|
36
44
|
const offset = this.offsetTop();
|
|
45
|
+
const root = scrollParent(el);
|
|
37
46
|
observer = new IntersectionObserver(([entry]) => {
|
|
38
47
|
const rootTop = entry.rootBounds?.top ?? offset;
|
|
39
48
|
const next = !entry.isIntersecting && entry.boundingClientRect.top < rootTop;
|
|
@@ -42,6 +51,7 @@ var WrAffix = class WrAffix {
|
|
|
42
51
|
el.classList.toggle("wr-affix--active", next);
|
|
43
52
|
this.affixChange.emit(next);
|
|
44
53
|
}, {
|
|
54
|
+
root,
|
|
45
55
|
rootMargin: `-${offset}px 0px 0px 0px`,
|
|
46
56
|
threshold: [0]
|
|
47
57
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-affix.mjs","names":[],"sources":["../../../projects/lib/affix/affix.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 { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n PLATFORM_ID,\n afterNextRender,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\n\n/**\n * Stick-on-scroll directive. Combines native CSS `position: sticky` with\n * an `IntersectionObserver`-driven `wr-affix--active` state class, so consumers\n * can style the element differently while it's pinned (e.g. add a\n * shadow, change the background, shrink the height).\n *\n * The host gets `position: sticky; top: ${offsetTop}px;` inline. A tiny\n * sentinel `<div>` is inserted just before the host — when the sentinel\n * scrolls out of view, the host is \"stuck\" and gets `wr-affix--active`\n * + an `(wrAffixChange)` emission.\n *\n * Works inside any scroll container without configuration — CSS sticky\n * picks the nearest scrollable ancestor automatically.\n *\n * @example\n * ```html\n * <header wrAffix [wrAffixOffsetTop]=\"0\">\n * <!-- adds a shadow once stuck -->\n * </header>\n * ```\n *\n * ```scss\n * header.wr-affix.wr-affix--active {\n * box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n * }\n * ```\n */\n@Directive({\n selector: '[wrAffix]',\n host: {\n class: 'wr-affix',\n '[style.position]': '\"sticky\"',\n '[style.top.px]': 'offsetTop()',\n },\n})\nexport class WrAffix {\n /** Pixels from the top of the scroll container when stuck. @default 0 */\n readonly offsetTop = input(0, {\n alias: 'wrAffixOffsetTop',\n transform: (v: unknown): number => coerceNumberProperty(v, 0),\n });\n\n /** Emits `true` when the element becomes affixed, `false` when it unsticks. */\n // eslint-disable-next-line @angular-eslint/no-output-rename -- keep wr-prefixed binding to match `[wrAffix]`\n readonly affixChange = output<boolean>({ alias: 'wrAffixChange' });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n /**\n * `afterNextRender`'s callback is not an injection context, and the observer\n * cannot exist before the sentinel it watches — so the effect that rebuilds it\n * is handed the injector explicitly.\n */\n private readonly injector = inject(Injector);\n\n constructor() {\n if (!this.isBrowser) return;\n\n afterNextRender(() => {\n const el = this.host.nativeElement;\n const parent = el.parentElement;\n if (!parent) return;\n\n // Sentinel: an empty zero-height block placed immediately before\n // the host. When the sentinel scrolls out of view, the host is\n // necessarily \"stuck\" at the configured offset.\n const sentinel = el.ownerDocument.createElement('div');\n sentinel.className = 'wr-affix__sentinel';\n sentinel.setAttribute('aria-hidden', 'true');\n sentinel.style.cssText = 'height:0;width:100%;margin:0;padding:0;pointer-events:none;';\n parent.insertBefore(sentinel, el);\n\n // The observer reports STATE, not transitions: it delivers an entry for the\n // sentinel as soon as it starts watching it — before anything has scrolled —\n // and can repeat a state the host is already in (a resize, another crossing of\n // the same threshold). `affixChange` is documented as the transition, so it\n // only fires on one. The starting state is \"not affixed\", which is what the\n // element already renders as, so that first entry is silent.\n let affixed = false;\n\n let observer: IntersectionObserver | null = null;\n\n // `rootMargin` is fixed for an observer's lifetime, so a changed offset means\n // a NEW observer. Without this the two halves of the offset drifted apart:\n // `[style.top.px]` is a live binding, so a header that animates its offset\n // pinned at the new line while still flipping state at the old one.\n // Re-observing re-delivers the current state, which the transition guard\n // above absorbs when nothing has actually changed.\n effect(\n onCleanup => {\n const offset = this.offsetTop();\n\n observer = new IntersectionObserver(\n ([entry]) => {\n // NOT `!entry.isIntersecting` on its own. A sentinel is outside\n // the root in TWO directions, and only one of them means the\n // header has stuck: above the line because the page scrolled past\n // it, or below it because the host simply starts further down the\n // page than the first screen. The bare negation called both\n // \"affixed\", so any sticky element below the fold reported\n // `affixed = true` and painted `.wr-affix--active` on its very\n // first observer callback — before a pixel had scrolled — and\n // emitted a transition that never happened.\n //\n // `rootBounds.top` is the offset line (the negative `rootMargin`\n // above moves it), so a sentinel above it has genuinely gone by.\n const rootTop = entry.rootBounds?.top ?? offset;\n const next = !entry.isIntersecting && entry.boundingClientRect.top < rootTop;\n if (next === affixed) return;\n\n affixed = next;\n el.classList.toggle('wr-affix--active', next);\n this.affixChange.emit(next);\n },\n {\n // Trigger when the sentinel's top crosses the offset line.\n rootMargin: `-${offset}px 0px 0px 0px`,\n threshold: [0],\n }\n );\n observer.observe(sentinel);\n\n onCleanup(() => observer?.disconnect());\n },\n { injector: this.injector }\n );\n\n this.destroyRef.onDestroy(() => {\n observer?.disconnect();\n sentinel.remove();\n el.classList.remove('wr-affix--active');\n });\n });\n }\n}\n"],"mappings":";;;;;;;;;;AAyDA,IAAa,UAAb,MAAa,QAAO;CAET,YAAY,MAAM,GAAC;EAAA,GAAA,YAAA,EAAA,WAAA,YAAA,+BAAA,CAAA;EAC1B,OAAO;EACP,YAAY,MAAuB,qBAAqB,GAAG,CAAC;CAAC,CAAA;CAKtD,cAAc,OAAgB,EAAE,OAAO,gBAAe,CAAE;CAEhD,OAAO,OAAgC,UAAU;CACjD,aAAa,OAAO,UAAU;CAC9B,YAAY,kBAAkB,OAAO,WAAW,CAAC;CAMjD,WAAW,OAAO,QAAQ;CAE3C,cAAA;EACE,IAAI,CAAC,KAAK,WAAW;EAErB,sBAAqB;GACnB,MAAM,KAAK,KAAK,KAAK;GACrB,MAAM,SAAS,GAAG;GAClB,IAAI,CAAC,QAAQ;GAKb,MAAM,WAAW,GAAG,cAAc,cAAc,KAAK;GACrD,SAAS,YAAY;GACrB,SAAS,aAAa,eAAe,MAAM;GAC3C,SAAS,MAAM,UAAU;GACzB,OAAO,aAAa,UAAU,EAAE;GAQhC,IAAI,UAAU;GAEd,IAAI,WAAwC;GAQ5C,QACE,cAAY;IACV,MAAM,SAAS,KAAK,UAAS;IAE7B,WAAW,IAAI,sBACZ,CAAC,WAAU;KAaV,MAAM,UAAU,MAAM,YAAY,OAAO;KACzC,MAAM,OAAO,CAAC,MAAM,kBAAkB,MAAM,mBAAmB,MAAM;KACrE,IAAI,SAAS,SAAS;KAEtB,UAAU;KACV,GAAG,UAAU,OAAO,oBAAoB,IAAI;KAC5C,KAAK,YAAY,KAAK,IAAI;IAC5B,GACA;KAEE,YAAY,IAAI,OAAM;KACtB,WAAW,CAAC,CAAC;IACd,CAAA;IAEH,SAAS,QAAQ,QAAQ;IAEzB,gBAAgB,UAAU,WAAU,CAAE;GACxC,GACA,EAAE,UAAU,KAAK,SAAQ,CAAE;GAG7B,KAAK,WAAW,gBAAe;IAC7B,UAAU,WAAU;IACpB,SAAS,OAAM;IACf,GAAG,UAAU,OAAO,kBAAkB;GACxC,CAAC;EACH,CAAC;CACH;CAnGW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAO,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAP,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAO,cAAA;EAAA,UAAA;EAAA,QAAA,EAAA,WAAA;GAAA,mBAAA;GAAA,YAAA;GAAA,UAAA;GAAA,YAAA;GAAA,mBAAA;EAAA,EAAA;EAAA,SAAA,EAAA,aAAA,gBAAA;EAAA,MAAA;GAAA,YAAA;IAAA,kBAAA;IAAA,gBAAA;GAAA;GAAA,gBAAA;EAAA;EAAA,UAAA;CAAA,CAAA;;AAAP,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAO,YAAA,CAAA;EARnB,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,MAAM;IACJ,OAAO;IACP,oBAAoB;IACpB,kBAAkB;GACnB;EACF,CAAA"}
|
|
1
|
+
{"version":3,"file":"ngwr-affix.mjs","names":[],"sources":["../../../projects/lib/affix/affix.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 { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n PLATFORM_ID,\n afterNextRender,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\n\n/**\n * The element a `position: sticky` host actually pins against.\n *\n * Walks up looking for an ancestor that scrolls — `overflow` anything but\n * `visible` on an axis, and a box that can actually be scrolled. `null` means\n * the document scroller, which is both what the browser uses and what\n * `IntersectionObserver` takes for \"the viewport\".\n *\n * A `getComputedStyle` read per ancestor, once per observer construction —\n * cheap, and the only way to answer the question: CSS resolves it internally\n * and exposes nothing.\n */\nfunction scrollParent(el: HTMLElement): HTMLElement | null {\n for (let node = el.parentElement; node !== null; node = node.parentElement) {\n if (node === document.body || node === document.documentElement) break;\n const style = getComputedStyle(node);\n const scrolls = /auto|scroll|overlay|hidden/.test(`${style.overflowY} ${style.overflowX}`);\n if (scrolls && node.scrollHeight > node.clientHeight) return node;\n }\n return null;\n}\n\n/**\n * Stick-on-scroll directive. Combines native CSS `position: sticky` with\n * an `IntersectionObserver`-driven `wr-affix--active` state class, so consumers\n * can style the element differently while it's pinned (e.g. add a\n * shadow, change the background, shrink the height).\n *\n * The host gets `position: sticky; top: ${offsetTop}px;` inline. A tiny\n * sentinel `<div>` is inserted just before the host — when the sentinel\n * scrolls out of view, the host is \"stuck\" and gets `wr-affix--active`\n * + an `(wrAffixChange)` emission.\n *\n * Works inside any scroll container without configuration: CSS sticky picks\n * the nearest scrollable ancestor, and the observer watching for the pinned\n * state is given that same element as its root — see `scrollParent`. Without\n * that second half the two measured different lines, and the state never\n * flipped inside a nested scroller.\n *\n * @example\n * ```html\n * <header wrAffix [wrAffixOffsetTop]=\"0\">\n * <!-- adds a shadow once stuck -->\n * </header>\n * ```\n *\n * ```scss\n * header.wr-affix.wr-affix--active {\n * box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n * }\n * ```\n */\n@Directive({\n selector: '[wrAffix]',\n host: {\n class: 'wr-affix',\n '[style.position]': '\"sticky\"',\n '[style.top.px]': 'offsetTop()',\n },\n})\nexport class WrAffix {\n /** Pixels from the top of the scroll container when stuck. @default 0 */\n readonly offsetTop = input(0, {\n alias: 'wrAffixOffsetTop',\n transform: (v: unknown): number => coerceNumberProperty(v, 0),\n });\n\n /** Emits `true` when the element becomes affixed, `false` when it unsticks. */\n // eslint-disable-next-line @angular-eslint/no-output-rename -- keep wr-prefixed binding to match `[wrAffix]`\n readonly affixChange = output<boolean>({ alias: 'wrAffixChange' });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n /**\n * `afterNextRender`'s callback is not an injection context, and the observer\n * cannot exist before the sentinel it watches — so the effect that rebuilds it\n * is handed the injector explicitly.\n */\n private readonly injector = inject(Injector);\n\n constructor() {\n if (!this.isBrowser) return;\n\n afterNextRender(() => {\n const el = this.host.nativeElement;\n const parent = el.parentElement;\n if (!parent) return;\n\n // Sentinel: an empty zero-height block placed immediately before\n // the host. When the sentinel scrolls out of view, the host is\n // necessarily \"stuck\" at the configured offset.\n const sentinel = el.ownerDocument.createElement('div');\n sentinel.className = 'wr-affix__sentinel';\n sentinel.setAttribute('aria-hidden', 'true');\n sentinel.style.cssText = 'height:0;width:100%;margin:0;padding:0;pointer-events:none;';\n parent.insertBefore(sentinel, el);\n\n // The observer reports STATE, not transitions: it delivers an entry for the\n // sentinel as soon as it starts watching it — before anything has scrolled —\n // and can repeat a state the host is already in (a resize, another crossing of\n // the same threshold). `affixChange` is documented as the transition, so it\n // only fires on one. The starting state is \"not affixed\", which is what the\n // element already renders as, so that first entry is silent.\n let affixed = false;\n\n let observer: IntersectionObserver | null = null;\n\n // `rootMargin` is fixed for an observer's lifetime, so a changed offset means\n // a NEW observer. Without this the two halves of the offset drifted apart:\n // `[style.top.px]` is a live binding, so a header that animates its offset\n // pinned at the new line while still flipping state at the old one.\n // Re-observing re-delivers the current state, which the transition guard\n // above absorbs when nothing has actually changed.\n effect(\n onCleanup => {\n const offset = this.offsetTop();\n\n // The observer's ROOT has to be the element the host sticks to, not\n // the viewport. `position: sticky` pins against the nearest\n // SCROLLING ancestor, and an observer with no root measures against\n // the viewport — so inside any nested scroller whose top sits below\n // the viewport's, `rootBounds.top` was 0 while the host pinned at\n // the container's own top. The direction guard below then computed\n // `false` at the one crossing it was ever handed, and because\n // `isIntersecting` stays false afterwards no further callback came:\n // `wr-affix--active` was never added and `(wrAffixChange)` never\n // emitted, for the whole scroll. The JSDoc promised the opposite —\n // \"works inside any scroll container without configuration\" — and\n // the docs page's own demo is exactly that shape.\n const root = scrollParent(el);\n\n observer = new IntersectionObserver(\n ([entry]) => {\n // NOT `!entry.isIntersecting` on its own. A sentinel is outside\n // the root in TWO directions, and only one of them means the\n // header has stuck: above the line because the page scrolled past\n // it, or below it because the host simply starts further down the\n // page than the first screen. The bare negation called both\n // \"affixed\", so any sticky element below the fold reported\n // `affixed = true` and painted `.wr-affix--active` on its very\n // first observer callback — before a pixel had scrolled — and\n // emitted a transition that never happened.\n //\n // `rootBounds.top` is the offset line (the negative `rootMargin`\n // above moves it), so a sentinel above it has genuinely gone by.\n const rootTop = entry.rootBounds?.top ?? offset;\n const next = !entry.isIntersecting && entry.boundingClientRect.top < rootTop;\n if (next === affixed) return;\n\n affixed = next;\n el.classList.toggle('wr-affix--active', next);\n this.affixChange.emit(next);\n },\n {\n // `null` is the document scroller, which is what the browser\n // uses for a host with no scrolling ancestor.\n root,\n // Trigger when the sentinel's top crosses the offset line.\n rootMargin: `-${offset}px 0px 0px 0px`,\n threshold: [0],\n }\n );\n observer.observe(sentinel);\n\n onCleanup(() => observer?.disconnect());\n },\n { injector: this.injector }\n );\n\n this.destroyRef.onDestroy(() => {\n observer?.disconnect();\n sentinel.remove();\n el.classList.remove('wr-affix--active');\n });\n });\n }\n}\n"],"mappings":";;;;;;;;;;AAkCA,SAAS,aAAa,IAAe;CACnC,KAAK,IAAI,OAAO,GAAG,eAAe,SAAS,MAAM,OAAO,KAAK,eAAe;EAC1E,IAAI,SAAS,SAAS,QAAQ,SAAS,SAAS,iBAAiB;EACjE,MAAM,QAAQ,iBAAiB,IAAI;EAEnC,IADgB,6BAA6B,KAAK,GAAG,MAAM,UAAS,GAAI,MAAM,WAC1E,KAAW,KAAK,eAAe,KAAK,cAAc,OAAO;CAC/D;CACA,OAAO;AACT;AAwCA,IAAa,UAAb,MAAa,QAAO;CAET,YAAY,MAAM,GAAC;EAAA,GAAA,YAAA,EAAA,WAAA,YAAA,+BAAA,CAAA;EAC1B,OAAO;EACP,YAAY,MAAuB,qBAAqB,GAAG,CAAC;CAAC,CAAA;CAKtD,cAAc,OAAgB,EAAE,OAAO,gBAAe,CAAE;CAEhD,OAAO,OAAgC,UAAU;CACjD,aAAa,OAAO,UAAU;CAC9B,YAAY,kBAAkB,OAAO,WAAW,CAAC;CAMjD,WAAW,OAAO,QAAQ;CAE3C,cAAA;EACE,IAAI,CAAC,KAAK,WAAW;EAErB,sBAAqB;GACnB,MAAM,KAAK,KAAK,KAAK;GACrB,MAAM,SAAS,GAAG;GAClB,IAAI,CAAC,QAAQ;GAKb,MAAM,WAAW,GAAG,cAAc,cAAc,KAAK;GACrD,SAAS,YAAY;GACrB,SAAS,aAAa,eAAe,MAAM;GAC3C,SAAS,MAAM,UAAU;GACzB,OAAO,aAAa,UAAU,EAAE;GAQhC,IAAI,UAAU;GAEd,IAAI,WAAwC;GAQ5C,QACE,cAAY;IACV,MAAM,SAAS,KAAK,UAAS;IAc7B,MAAM,OAAO,aAAa,EAAE;IAE5B,WAAW,IAAI,sBACZ,CAAC,WAAU;KAaV,MAAM,UAAU,MAAM,YAAY,OAAO;KACzC,MAAM,OAAO,CAAC,MAAM,kBAAkB,MAAM,mBAAmB,MAAM;KACrE,IAAI,SAAS,SAAS;KAEtB,UAAU;KACV,GAAG,UAAU,OAAO,oBAAoB,IAAI;KAC5C,KAAK,YAAY,KAAK,IAAI;IAC5B,GACA;KAGE;KAEA,YAAY,IAAI,OAAM;KACtB,WAAW,CAAC,CAAC;IACd,CAAA;IAEH,SAAS,QAAQ,QAAQ;IAEzB,gBAAgB,UAAU,WAAU,CAAE;GACxC,GACA,EAAE,UAAU,KAAK,SAAQ,CAAE;GAG7B,KAAK,WAAW,gBAAe;IAC7B,UAAU,WAAU;IACpB,SAAS,OAAM;IACf,GAAG,UAAU,OAAO,kBAAkB;GACxC,CAAC;EACH,CAAC;CACH;CApHW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAO,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAP,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAO,cAAA;EAAA,UAAA;EAAA,QAAA,EAAA,WAAA;GAAA,mBAAA;GAAA,YAAA;GAAA,UAAA;GAAA,YAAA;GAAA,mBAAA;EAAA,EAAA;EAAA,SAAA,EAAA,aAAA,gBAAA;EAAA,MAAA;GAAA,YAAA;IAAA,kBAAA;IAAA,gBAAA;GAAA;GAAA,gBAAA;EAAA;EAAA,UAAA;CAAA,CAAA;;AAAP,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAO,YAAA,CAAA;EARnB,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,MAAM;IACJ,OAAO;IACP,oBAAoB;IACpB,kBAAkB;GACnB;EACF,CAAA"}
|
|
@@ -140,9 +140,20 @@ var WrCalendar = class WrCalendar {
|
|
|
140
140
|
}
|
|
141
141
|
prev() {
|
|
142
142
|
this.viewDate.set(this.stepViewDate(-1));
|
|
143
|
+
this.carryCursorIntoView();
|
|
143
144
|
}
|
|
144
145
|
next() {
|
|
145
146
|
this.viewDate.set(this.stepViewDate(1));
|
|
147
|
+
this.carryCursorIntoView();
|
|
148
|
+
}
|
|
149
|
+
carryCursorIntoView() {
|
|
150
|
+
if (this.viewMode() !== "day") return;
|
|
151
|
+
const view = this.viewDate();
|
|
152
|
+
const focused = this.focusedDate();
|
|
153
|
+
if (this.adapter.isSameMonth(focused, view)) return;
|
|
154
|
+
const day = Math.min(this.adapter.getDate(focused), this.adapter.getDaysInMonth(view));
|
|
155
|
+
const landing = this.adapter.createDate(this.adapter.getYear(view), this.adapter.getMonth(view), day);
|
|
156
|
+
this.focusedDate.set(this.nearestEnabled(landing));
|
|
146
157
|
}
|
|
147
158
|
onLabelClick() {
|
|
148
159
|
if (this.disabled()) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-calendar.mjs","names":[],"sources":["../../../projects/lib/calendar/calendar.ts","../../../projects/lib/calendar/calendar.html"],"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 {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { WrDateAdapter } from 'ngwr/date';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport type { WrCalendarMode, WrCalendarRange } from './interfaces';\n\n/**\n * Stands in for the consumer input `useI18nText` expects, for labels the calendar\n * exposes no input for. Constant and read-only, so one instance is safe to share.\n */\nconst NO_OVERRIDE = signal<string | null>(null).asReadonly();\n\nconst ROWS = 6;\nconst COLS = 7;\n\n/**\n * Chips per row in the month and year views — the vertical arrows step by one\n * of these, so they have to agree with `grid-template-columns` in\n * `styles/_index.scss`. Two numbers because the two grids differ: twelve months\n * read as four rows of three, twelve years as three rows of four.\n */\nconst MONTH_COLS = 3;\nconst YEAR_COLS = 4;\n\n/**\n * Month-view calendar. Supports single-date selection (`mode=\"single\"`) or\n * date-range selection (`mode=\"range\"`). Reusable on its own; consumed by\n * `<wr-date-picker>` inside an overlay.\n *\n * Uses {@link WrDateAdapter} for all date math and formatting — register\n * one via {@link provideWrDateAdapter} at bootstrap.\n *\n * @example\n * ```html\n * <wr-calendar [(date)]=\"picked\" [min]=\"minDate\" />\n *\n * <wr-calendar mode=\"range\" [(range)]=\"[start, end]\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar\n */\n@Component({\n selector: 'wr-calendar',\n templateUrl: './calendar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n // No `role=\"grid\"` here: the host also wraps the nav header, and a grid may\n // only own rows. The role sits on `.wr-calendar__body`, which is the day\n // matrix and nothing else.\n '(keydown)': 'onKeyDown($event)',\n },\n})\nexport class WrCalendar {\n /** Selection mode. @default 'single' */\n readonly mode = input<WrCalendarMode>('single');\n\n /** Two-way bindable single value (used when `mode === 'single'`). */\n readonly date = model<Date | null>(null);\n\n /** Two-way bindable `[start, end]` (used when `mode === 'range'`). */\n readonly range = model<WrCalendarRange>([null, null]);\n\n /** Min selectable date (inclusive). */\n readonly min = input<Date | null>(null);\n\n /** Max selectable date (inclusive). */\n readonly max = input<Date | null>(null);\n\n /** Predicate — return `false` to disable specific dates (e.g. weekends only). */\n readonly dateFilter = input<((date: Date) => boolean) | null>(null);\n\n /**\n * Move real focus onto the roving cell as soon as the grid is on screen.\n *\n * Off by default: a standalone `<wr-calendar>` sitting in a page must not\n * steal focus on load. `wr-date-picker` turns it on for the popup it opens\n * from its trigger, where the user asked to be taken to the calendar.\n * @default false\n */\n readonly autoFocus = input(false, { transform: coerceBooleanProperty });\n\n /** Disable interaction entirely. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n private readonly adapter = inject<WrDateAdapter<Date>>(WrDateAdapter);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n\n /** Currently displayed month (any date inside it). */\n protected readonly viewDate = signal(this.adapter.today());\n\n /** Date currently focused by keyboard (single roving tabindex). */\n protected readonly focusedDate = signal(this.adapter.today());\n\n /** Hovered date during range-mode end-pick — drives the preview highlight. */\n protected readonly hoverDate = signal<Date | null>(null);\n\n /** Which sub-view is currently shown. Cycles `day → month → year` on header click. */\n protected readonly viewMode = signal<'day' | 'month' | 'year'>('day');\n\n /**\n * Chip the month / year listbox has moved its ring to, as an index into\n * `monthsView()` / `yearsView()`. `null` means \"nobody has pressed an arrow\n * yet\", which resolves to the month or year on screen — see {@link activeChip}.\n *\n * Reset on every view change rather than remembered: coming back to the month\n * list should ring the month you are looking at, not the one an earlier visit\n * happened to leave the ring on.\n */\n private readonly rovedChip = signal<number | null>(null);\n\n // The four month/year strings have been in both catalogs since they were written\n // and nothing read them: the template hard-coded the same English beside them, so a\n // localized app announced its calendar's arrows in English. `nullSignal()` is the\n // shim for exactly this — a label with no consumer input to forward.\n private readonly prevMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.prevMonth', 'Previous month');\n private readonly nextMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.nextMonth', 'Next month');\n protected readonly monthListLabel = useI18nText(NO_OVERRIDE, 'calendar.monthList', 'Months');\n protected readonly yearListLabel = useI18nText(NO_OVERRIDE, 'calendar.yearList', 'Years');\n private readonly prevYearLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYear', 'Previous year');\n private readonly nextYearLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYear', 'Next year');\n private readonly prevYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYears', 'Previous 12 years');\n private readonly nextYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYears', 'Next 12 years');\n\n /** What the ← button does from here — a month, a year, or a 12-year page. */\n protected readonly prevLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.prevYearsLabel();\n case 'month':\n return this.prevYearLabel();\n default:\n return this.prevMonthLabel();\n }\n });\n\n /** What the → button does from here. */\n protected readonly nextLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.nextYearsLabel();\n case 'month':\n return this.nextYearLabel();\n default:\n return this.nextMonthLabel();\n }\n });\n\n protected readonly today = computed(() => this.adapter.today());\n\n protected readonly weekdayNames = computed(() => this.adapter.getDayOfWeekNames('short'));\n\n protected readonly monthsView = computed(() => this.adapter.getMonthNames('short'));\n\n /** 12-year window centered on the floor-aligned decade containing `viewDate`. */\n protected readonly yearsView = computed<readonly number[]>(() => {\n const y = this.adapter.getYear(this.viewDate());\n const start = Math.floor(y / 12) * 12;\n return Array.from({ length: 12 }, (_, i) => start + i);\n });\n\n /**\n * The header above the grid.\n *\n * Both templated strings used to be assembled here: `${month} ${year}` and\n * `${first} – ${last}`. That is English word order with an English separator\n * baked into TypeScript, and no catalog could move either — ja-JP writes\n * 2026年3月, which is not a translation of any word in `March 2026` but a\n * different arrangement of the same two values. So the arrangement is the\n * translatable unit, and `calendar.header` / `calendar.yearRange` are it.\n */\n protected readonly headerLabel = computed(() => {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day': {\n const monthNames = this.adapter.getMonthNames('long');\n return this.headerText({\n month: monthNames[this.adapter.getMonth(v)],\n year: this.adapter.getYear(v),\n });\n }\n case 'month':\n return `${this.adapter.getYear(v)}`;\n case 'year': {\n const years = this.yearsView();\n return this.yearRangeText({ from: years[0], to: years[years.length - 1] });\n }\n }\n });\n\n private readonly headerText = useI18nFormatter('calendar.header', '{{month}} {{year}}');\n private readonly yearRangeText = useI18nFormatter('calendar.yearRange', '{{from}} – {{to}}');\n private readonly dayLabelText = useI18nFormatter('calendar.dayLabel', '{{weekday}}, {{date}}');\n\n /**\n * Long weekday names for the cell names.\n *\n * `getDayOfWeekNames` returns them in COLUMN order — index 0 is\n * `getFirstDayOfWeek()`, not Sunday — which is what the header strip wants and\n * what a `getDayOfWeek()` result (0 = Sunday) must be rotated into. Indexing\n * it directly reads Monday's name for a Sunday in every locale that starts its\n * week on Monday, which is most of them.\n */\n private readonly longWeekdays = computed(() => this.adapter.getDayOfWeekNames('long'));\n\n /**\n * A day cell's accessible name — \"Sunday, March 15, 2026\".\n *\n * The cell had none. Its only content is the day NUMBER, and `role=\"gridcell\"`\n * does not inherit a name from the grid's header or from the column header\n * above it, so every date in the month announced as a bare number: the month,\n * the year and the weekday were all on screen and none of them reachable.\n *\n * `{{date}}` is the adapter's `longDate`, so its field order, its separators\n * and its digits are `Intl`'s — the catalog decides only where the weekday\n * goes. Building it from `getMonthNames('long')` instead would have hard-coded\n * the nominative month, which Russian and Finnish inflect inside a date.\n */\n protected dayLabel(date: Date): string {\n return this.dayLabelText({\n weekday: this.longWeekdays()[(this.adapter.getDayOfWeek(date) - this.adapter.getFirstDayOfWeek() + 7) % 7],\n date: this.adapter.format(date, 'longDate'),\n });\n }\n\n /** 6×7 day grid covering the current month plus spillover. */\n protected readonly weeks = computed<readonly (readonly Date[])[]>(() => {\n const view = this.viewDate();\n const year = this.adapter.getYear(view);\n const month = this.adapter.getMonth(view);\n const firstOfMonth = this.adapter.createDate(year, month, 1);\n const firstWeekday = this.adapter.getDayOfWeek(firstOfMonth);\n const firstDayOfWeek = this.adapter.getFirstDayOfWeek();\n const lead = (firstWeekday - firstDayOfWeek + 7) % 7;\n const gridStart = this.adapter.addDays(firstOfMonth, -lead);\n\n const out: Date[][] = [];\n for (let w = 0; w < ROWS; w++) {\n const row: Date[] = [];\n for (let d = 0; d < COLS; d++) {\n row.push(this.adapter.addDays(gridStart, w * COLS + d));\n }\n out.push(row);\n }\n return out;\n });\n\n /**\n * The chip carrying the listbox's only `tabindex=\"0\"` — where the ring is, and\n * where Tab lands.\n *\n * A listbox owns its arrows, and these two did not: twelve months were twelve\n * tab stops, so the role promised an interaction model the component never\n * implemented. One tab stop plus arrow keys is the roving-tabindex half of the\n * pattern the day grid already uses.\n *\n * Routed through {@link nearestEnabledChip} on BOTH paths — the seed and every\n * arrow — for the reason the grid learned first: `.focus()` on a\n * `<button disabled>` is a no-op, so parking the sole tab stop on a month a\n * `[min]` has closed off leaves the whole view unreachable by keyboard.\n * `-1` on the day view, where there are no chips at all.\n */\n protected readonly activeChip = computed(() => {\n if (this.viewMode() === 'day') return -1;\n return this.nearestEnabledChip(this.rovedChip() ?? this.currentChip());\n });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-calendar', `wr-calendar--${this.mode()}`];\n if (this.disabled()) parts.push('wr-calendar--disabled');\n return parts.join(' ');\n });\n\n constructor() {\n // Initial focus: selected date if any, else today. Also snap viewDate to\n // that month.\n //\n // Stepped onto an ENABLED day, because the roving tabindex puts the grid's\n // only `tabindex=\"0\"` on this cell: seed it on a disabled one — which is\n // exactly what a `min` in the future does to \"today\" — and the sole tab\n // stop is an unfocusable button, leaving the grid unreachable by keyboard.\n afterNextRender(() => {\n const initial = this.nearestEnabled(this.date() ?? this.range()[0] ?? this.adapter.today());\n this.focusedDate.set(initial);\n this.viewDate.set(initial);\n\n // A second, NESTED hook: the lines above only SET the signals, which\n // schedules another change-detection pass — the `--focused` class and the\n // `tabindex` are not in the DOM until that one has run.\n if (this.autoFocus()) {\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n });\n\n // Keep viewDate in sync when date / range changes externally to a\n // different month. The viewDate read must stay untracked — otherwise\n // the effect re-runs on every internal navigation (month stepping,\n // year picking) and snaps the view back to the selected month.\n effect(() => {\n const candidate = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!candidate) return;\n untracked(() => {\n if (!this.adapter.isSameMonth(candidate, this.viewDate())) {\n this.viewDate.set(candidate);\n }\n });\n });\n }\n\n // Navigation\n\n /** Header `‹` button — steps by month / year / decade based on the active view. */\n protected prev(): void {\n this.viewDate.set(this.stepViewDate(-1));\n }\n\n /** Header `›` button — steps by month / year / decade based on the active view. */\n protected next(): void {\n this.viewDate.set(this.stepViewDate(1));\n }\n\n /** Header label click — zooms out (`day → month → year`). No-op at year view. */\n protected onLabelClick(): void {\n if (this.disabled()) return;\n if (this.viewMode() === 'day') {\n this.setViewMode('month');\n } else if (this.viewMode() === 'month') {\n this.setViewMode('year');\n }\n }\n\n /**\n * Picking a month drops to the day grid — and takes real focus with it.\n *\n * The `@switch (viewMode())` in the template destroys the chip that holds DOM\n * focus, so without the two lines below `document.activeElement` became\n * `<body>`: the ring appeared on the new view and focus did not, the arrow\n * keys went dead (the keydown handler is a HOST binding, so nothing reaches\n * the component from `<body>`), and the next Tab restarted from the top of the\n * document — out of the calendar entirely. It is the same trap the two\n * keyboard paths in this file already fix, and for the same reason\n * `afterNextRender` rather than `queueMicrotask`: under zoneless CD the\n * microtask runs before the new view is in the DOM.\n *\n * `focusedDate` has to move too, and that half is easy to miss. The grid marks\n * its focusable cell by comparing against `focusedDate`, not `viewDate`, so\n * choosing a DIFFERENT month rendered a grid with no `--focused` cell and no\n * `tabindex=\"0\"` at all — unreachable by keyboard from either direction. The\n * day is preserved when the month already holds it and otherwise falls to the\n * first, which is where `viewDate` lands anyway.\n */\n protected onMonthSelect(monthIdx: number): void {\n if (this.isMonthDisabled(monthIdx)) return;\n const v = this.viewDate();\n const year = this.adapter.getYear(v);\n this.viewDate.set(this.adapter.createDate(year, monthIdx, 1));\n\n const focused = this.focusedDate();\n const alreadyThere = this.adapter.getYear(focused) === year && this.adapter.getMonth(focused) === monthIdx;\n if (!alreadyThere) this.focusedDate.set(this.adapter.createDate(year, monthIdx, 1));\n\n this.setViewMode('day');\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /** Year → month view, with the same focus restoration; the landing view is chips. */\n protected onYearSelect(year: number): void {\n if (this.isYearDisabled(year)) return;\n const v = this.viewDate();\n this.viewDate.set(this.adapter.createDate(year, this.adapter.getMonth(v), 1));\n this.setViewMode('month');\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /**\n * Switch views and drop the chip ring with them.\n *\n * Every view change is the only thing that changes what the chips MEAN, so it\n * is the one place the ring has to forget where it was — otherwise a year\n * picked at index 7 rings the eighth MONTH on the way back down.\n */\n private setViewMode(view: 'day' | 'month' | 'year'): void {\n this.rovedChip.set(null);\n this.viewMode.set(view);\n }\n\n private stepViewDate(direction: -1 | 1): Date {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day':\n return this.adapter.addMonths(v, direction);\n case 'month':\n return this.adapter.addYears(v, direction);\n case 'year':\n return this.adapter.addYears(v, direction * 12);\n }\n }\n\n // Cell state predicates (used by template)\n\n protected isToday(date: Date): boolean {\n return this.adapter.isSameDay(date, this.today());\n }\n\n protected isOutOfMonth(date: Date): boolean {\n return !this.adapter.isSameMonth(date, this.viewDate());\n }\n\n protected isSelected(date: Date): boolean {\n if (this.mode() === 'single') {\n const v = this.date();\n return v ? this.adapter.isSameDay(date, v) : false;\n }\n const [start, end] = this.range();\n if (start && this.adapter.isSameDay(date, start)) return true;\n if (end && this.adapter.isSameDay(date, end)) return true;\n return false;\n }\n\n protected isInRange(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n if (!start || !end) return false;\n return this.adapter.compareDate(date, start) > 0 && this.adapter.compareDate(date, end) < 0;\n }\n\n protected isInRangePreview(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n const hover = this.hoverDate();\n if (!start || end || !hover) return false;\n const before = this.adapter.compareDate(start, hover) <= 0;\n const lo = before ? start : hover;\n const hi = before ? hover : start;\n return this.adapter.compareDate(date, lo) > 0 && this.adapter.compareDate(date, hi) < 0;\n }\n\n protected isFocused(date: Date): boolean {\n return this.adapter.isSameDay(date, this.focusedDate());\n }\n\n protected isDisabled(date: Date): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && this.adapter.compareDate(date, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(date, max) > 0) return true;\n const filter = this.dateFilter();\n if (filter && !filter(date)) return true;\n return false;\n }\n\n // Month / year view predicates\n\n protected isMonthCurrent(monthIdx: number): boolean {\n return this.adapter.getMonth(this.viewDate()) === monthIdx;\n }\n\n protected isMonthSelected(monthIdx: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!v) return false;\n return this.adapter.getYear(v) === this.adapter.getYear(this.viewDate()) && this.adapter.getMonth(v) === monthIdx;\n }\n\n protected isMonthDisabled(monthIdx: number): boolean {\n if (this.disabled()) return true;\n const year = this.adapter.getYear(this.viewDate());\n const monthStart = this.adapter.createDate(year, monthIdx, 1);\n const monthEnd = this.adapter.createDate(year, monthIdx, this.adapter.getDaysInMonth(monthStart));\n const min = this.min();\n if (min && this.adapter.compareDate(monthEnd, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(monthStart, max) > 0) return true;\n return false;\n }\n\n protected isYearCurrent(year: number): boolean {\n return this.adapter.getYear(this.viewDate()) === year;\n }\n\n protected isYearSelected(year: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n return v ? this.adapter.getYear(v) === year : false;\n }\n\n protected isYearDisabled(year: number): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && year < this.adapter.getYear(min)) return true;\n const max = this.max();\n if (max && year > this.adapter.getYear(max)) return true;\n return false;\n }\n\n // Interaction\n\n protected onCellClick(date: Date): void {\n if (this.isDisabled(date)) return;\n if (this.mode() === 'single') {\n this.date.set(this.adapter.clone(date));\n } else {\n this.applyRangeClick(date);\n }\n this.focusedDate.set(date);\n if (!this.adapter.isSameMonth(date, this.viewDate())) {\n this.viewDate.set(date);\n }\n }\n\n protected onCellEnter(date: Date): void {\n if (this.mode() === 'range') this.hoverDate.set(date);\n }\n\n protected onCellLeave(): void {\n if (this.mode() === 'range') this.hoverDate.set(null);\n }\n\n private applyRangeClick(date: Date): void {\n const [start, end] = this.range();\n if (!start || (start && end)) {\n this.range.set([this.adapter.clone(date), null]);\n return;\n }\n if (this.adapter.compareDate(date, start) < 0) {\n this.range.set([this.adapter.clone(date), start]);\n } else {\n this.range.set([start, this.adapter.clone(date)]);\n }\n this.hoverDate.set(null);\n }\n\n // Keyboard\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n\n // The listener sits on the HOST, which also wraps the nav header — so\n // without this every key aimed at a `‹` button drove the day grid instead,\n // and the `preventDefault()` below cancelled the button's own activation:\n // Enter on `‹` picked a day the user never touched, ArrowDown on the header\n // yanked real focus into the grid. The host element itself is deliberately\n // let through: `WrCalendarHarness` sends its keys to `<wr-calendar>` rather\n // than to a cell, because the calendar moves focus in an `afterNextRender`\n // and jsdom often has focus nowhere at all.\n const target = event.target as Element | null;\n if (target !== this.host.nativeElement && target?.closest('.wr-calendar__header')) return;\n\n // The month and year views are listboxes, and the arrows belong to them\n // while they are up — there is no day grid on screen to drive. Their chips\n // are real `<button>`s, so Enter and Space fall through to the browser's own\n // activation and must not be swallowed here.\n if (this.viewMode() !== 'day') {\n this.onChipKeyDown(event);\n return;\n }\n\n const current = this.focusedDate();\n let next: Date | null = null;\n // Which way the key travels, so a landing on a closed-off day can keep\n // going instead of stopping on it. See `nearestEnabledToward`.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = this.adapter.addDays(current, -1);\n dir = -1;\n break;\n case 'ArrowRight':\n next = this.adapter.addDays(current, 1);\n break;\n case 'ArrowUp':\n next = this.adapter.addDays(current, -7);\n dir = -1;\n break;\n case 'ArrowDown':\n next = this.adapter.addDays(current, 7);\n break;\n case 'Home': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, -((dow - first + 7) % 7));\n dir = -1;\n break;\n }\n case 'End': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, 6 - ((dow - first + 7) % 7));\n break;\n }\n case 'PageUp':\n next = event.shiftKey ? this.adapter.addYears(current, -1) : this.adapter.addMonths(current, -1);\n dir = -1;\n break;\n case 'PageDown':\n next = event.shiftKey ? this.adapter.addYears(current, 1) : this.adapter.addMonths(current, 1);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.onCellClick(current);\n return;\n }\n\n if (!next) return;\n event.preventDefault();\n\n // The seed is routed through `nearestEnabled` for a reason, and navigation\n // needs the same care: a cell renders `disabled` AND carries the grid's only\n // `tabindex=\"0\"`, so parking the ring on a closed-off day leaves zero\n // tabbable cells — the user tabs out of the calendar and can never tab back\n // in. Real focus splits from the ring too, because `.focus()` on a disabled\n // button is a no-op. Reached by nothing more exotic than `[minDate]`.\n const landing = this.nearestEnabledToward(next, dir);\n if (!landing) return;\n next = landing;\n\n this.focusedDate.set(next);\n if (!this.adapter.isSameMonth(next, this.viewDate())) {\n this.viewDate.set(next);\n }\n // `afterNextRender`, NOT `queueMicrotask`. Under zoneless CD the scheduler\n // runs change detection in a macrotask, so a microtask fires FIRST — the\n // `--focused` class is still on the cell we just left, and this focuses\n // that one. The ring moved and real focus did not, permanently: a screen\n // reader kept announcing the previous day.\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /**\n * Arrow / Home / End inside the month or year listbox — the roving half of the\n * pattern their `role` has always claimed.\n *\n * Steps by one along the row and by a full row vertically, and the inline pair\n * mirrors under `dir=\"rtl\"` for the same reason the grid's does: those two keys\n * name a side of the screen. The page does NOT wrap or spill into the next\n * one — a month list is twelve fixed cells, and the header's `‹` / `›` are what\n * change which twelve. Anything else (Enter, Space, Tab, Escape) is left to the\n * button and to whatever owns the calendar.\n */\n private onChipKeyDown(event: KeyboardEvent): void {\n const cols = this.viewMode() === 'month' ? MONTH_COLS : YEAR_COLS;\n const count = this.chipCount();\n const current = this.activeChip();\n // Assigned on every branch that does not return, so it needs no placeholder.\n let next: number;\n // Which way to keep looking when the landing chip is closed off, exactly as\n // `nearestEnabledToward` does for days.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = current - 1;\n dir = -1;\n break;\n case 'ArrowRight':\n next = current + 1;\n break;\n case 'ArrowUp':\n next = current - cols;\n dir = -1;\n break;\n case 'ArrowDown':\n next = current + cols;\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = count - 1;\n dir = -1;\n break;\n default:\n return;\n }\n\n const landing = this.enabledChipToward(next, dir);\n if (landing === null) return;\n\n event.preventDefault();\n this.rovedChip.set(landing);\n // `afterNextRender`, not `queueMicrotask` — same trap as the grid: under\n // zoneless CD the microtask runs before the new `tabindex` is in the DOM, so\n // the focus call would land on the chip the ring just left.\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /** How many chips the current view renders — twelve either way, read rather than assumed. */\n private chipCount(): number {\n return this.viewMode() === 'month' ? this.monthsView().length : this.yearsView().length;\n }\n\n /** Whether the chip at `index` refuses selection in the current view. */\n private isChipDisabled(index: number): boolean {\n if (this.viewMode() === 'month') return this.isMonthDisabled(index);\n const year = this.yearsView()[index];\n return year === undefined || this.isYearDisabled(year);\n }\n\n /** The chip the view itself points at: the month or year currently on screen. */\n private currentChip(): number {\n if (this.viewMode() === 'month') return this.adapter.getMonth(this.viewDate());\n const index = this.yearsView().indexOf(this.adapter.getYear(this.viewDate()));\n return index === -1 ? 0 : index;\n }\n\n /**\n * The first selectable chip at or after `from`, else the first before it, else\n * `from` unchanged when the whole page is closed off — the chip version of\n * {@link nearestEnabled}, and it exists for the same reason: the ring carries\n * the only `tabindex=\"0\"`, and a disabled button cannot hold it.\n */\n private nearestEnabledChip(from: number): number {\n const count = this.chipCount();\n const start = Math.min(Math.max(from, 0), count - 1);\n if (!this.isChipDisabled(start)) return start;\n\n for (const step of [1, -1] as const) {\n const found = this.enabledChipToward(start + step, step);\n if (found !== null) return found;\n }\n return start;\n }\n\n /**\n * The first selectable chip at `from` or beyond it in `step`'s direction, else\n * null when that whole direction is closed off — which is the answer for an\n * ArrowLeft on the first chip: stay put.\n */\n private enabledChipToward(from: number, step: 1 | -1): number | null {\n for (let i = from; i >= 0 && i < this.chipCount(); i += step) {\n if (!this.isChipDisabled(i)) return i;\n }\n return null;\n }\n\n private focusActiveChip(): void {\n // By the tab stop, not by index: it is the same element the ring is on, and\n // asking for it this way cannot drift out of step with the template.\n this.host.nativeElement.querySelector<HTMLElement>('.wr-calendar__chip[tabindex=\"0\"]')?.focus();\n }\n\n /**\n * The first selectable day at or after `candidate`, else the first before it,\n * else `candidate` unchanged when everything nearby is closed off. Bounded at\n * a year each way so a pathological `dateFilter` cannot spin.\n */\n private nearestEnabled(candidate: Date): Date {\n if (!this.isDisabled(candidate)) return candidate;\n\n for (const step of [1, -1] as const) {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n probe = this.adapter.addDays(probe, step);\n if (!this.isDisabled(probe)) return probe;\n }\n }\n return candidate;\n }\n\n /**\n * The first selectable day at `candidate` or beyond it in `step`'s direction,\n * else null when that whole direction is closed off — which is the answer for\n * an ArrowLeft that would cross `min`: stay put.\n *\n * Direction matters. Reusing `nearestEnabled`, which probes forward first,\n * would send an ArrowLeft over a disabled weekend straight back to the day it\n * started from, so the ring could never cross the hole.\n */\n private nearestEnabledToward(candidate: Date, step: 1 | -1): Date | null {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n if (!this.isDisabled(probe)) return probe;\n probe = this.adapter.addDays(probe, step);\n }\n return null;\n }\n\n private focusActiveCell(): void {\n const el = this.host.nativeElement.querySelector('.wr-calendar__day--focused');\n (el as HTMLElement | null)?.focus();\n }\n\n /** Used by the template's `track` expression. */\n protected trackByTime(_: number, date: Date): number {\n return date.getTime();\n }\n\n /**\n * The key as the GRID sees it.\n *\n * Arrow keys follow visual order, and a calendar grid mirrors under\n * `dir=\"rtl\"`: the day to the visual right of today is yesterday. Only the\n * inline pair swaps — Up/Down step a week either way, and PageUp/PageDown and\n * Home/End are semantic rather than physical.\n */\n private inlineKey(key: string): string {\n if (this.dir?.value !== 'rtl') return key;\n if (key === 'ArrowRight') return 'ArrowLeft';\n if (key === 'ArrowLeft') return 'ArrowRight';\n return key;\n }\n}\n","<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-label]=\"dayLabel(day)\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model — arrow to a month, Tab\n out of the list — that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\" [attr.aria-label]=\"monthListLabel()\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\" [attr.aria-label]=\"yearListLabel()\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngwr-calendar.mjs","names":[],"sources":["../../../projects/lib/calendar/calendar.ts","../../../projects/lib/calendar/calendar.html"],"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 {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { WrDateAdapter } from 'ngwr/date';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport type { WrCalendarMode, WrCalendarRange } from './interfaces';\n\n/**\n * Stands in for the consumer input `useI18nText` expects, for labels the calendar\n * exposes no input for. Constant and read-only, so one instance is safe to share.\n */\nconst NO_OVERRIDE = signal<string | null>(null).asReadonly();\n\nconst ROWS = 6;\nconst COLS = 7;\n\n/**\n * Chips per row in the month and year views — the vertical arrows step by one\n * of these, so they have to agree with `grid-template-columns` in\n * `styles/_index.scss`. Two numbers because the two grids differ: twelve months\n * read as four rows of three, twelve years as three rows of four.\n */\nconst MONTH_COLS = 3;\nconst YEAR_COLS = 4;\n\n/**\n * Month-view calendar. Supports single-date selection (`mode=\"single\"`) or\n * date-range selection (`mode=\"range\"`). Reusable on its own; consumed by\n * `<wr-date-picker>` inside an overlay.\n *\n * Uses {@link WrDateAdapter} for all date math and formatting — register\n * one via {@link provideWrDateAdapter} at bootstrap.\n *\n * @example\n * ```html\n * <wr-calendar [(date)]=\"picked\" [min]=\"minDate\" />\n *\n * <wr-calendar mode=\"range\" [(range)]=\"[start, end]\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar\n */\n@Component({\n selector: 'wr-calendar',\n templateUrl: './calendar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n // No `role=\"grid\"` here: the host also wraps the nav header, and a grid may\n // only own rows. The role sits on `.wr-calendar__body`, which is the day\n // matrix and nothing else.\n '(keydown)': 'onKeyDown($event)',\n },\n})\nexport class WrCalendar {\n /** Selection mode. @default 'single' */\n readonly mode = input<WrCalendarMode>('single');\n\n /** Two-way bindable single value (used when `mode === 'single'`). */\n readonly date = model<Date | null>(null);\n\n /** Two-way bindable `[start, end]` (used when `mode === 'range'`). */\n readonly range = model<WrCalendarRange>([null, null]);\n\n /** Min selectable date (inclusive). */\n readonly min = input<Date | null>(null);\n\n /** Max selectable date (inclusive). */\n readonly max = input<Date | null>(null);\n\n /** Predicate — return `false` to disable specific dates (e.g. weekends only). */\n readonly dateFilter = input<((date: Date) => boolean) | null>(null);\n\n /**\n * Move real focus onto the roving cell as soon as the grid is on screen.\n *\n * Off by default: a standalone `<wr-calendar>` sitting in a page must not\n * steal focus on load. `wr-date-picker` turns it on for the popup it opens\n * from its trigger, where the user asked to be taken to the calendar.\n * @default false\n */\n readonly autoFocus = input(false, { transform: coerceBooleanProperty });\n\n /** Disable interaction entirely. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n private readonly adapter = inject<WrDateAdapter<Date>>(WrDateAdapter);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n\n /** Currently displayed month (any date inside it). */\n protected readonly viewDate = signal(this.adapter.today());\n\n /** Date currently focused by keyboard (single roving tabindex). */\n protected readonly focusedDate = signal(this.adapter.today());\n\n /** Hovered date during range-mode end-pick — drives the preview highlight. */\n protected readonly hoverDate = signal<Date | null>(null);\n\n /** Which sub-view is currently shown. Cycles `day → month → year` on header click. */\n protected readonly viewMode = signal<'day' | 'month' | 'year'>('day');\n\n /**\n * Chip the month / year listbox has moved its ring to, as an index into\n * `monthsView()` / `yearsView()`. `null` means \"nobody has pressed an arrow\n * yet\", which resolves to the month or year on screen — see {@link activeChip}.\n *\n * Reset on every view change rather than remembered: coming back to the month\n * list should ring the month you are looking at, not the one an earlier visit\n * happened to leave the ring on.\n */\n private readonly rovedChip = signal<number | null>(null);\n\n // The four month/year strings have been in both catalogs since they were written\n // and nothing read them: the template hard-coded the same English beside them, so a\n // localized app announced its calendar's arrows in English. `nullSignal()` is the\n // shim for exactly this — a label with no consumer input to forward.\n private readonly prevMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.prevMonth', 'Previous month');\n private readonly nextMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.nextMonth', 'Next month');\n protected readonly monthListLabel = useI18nText(NO_OVERRIDE, 'calendar.monthList', 'Months');\n protected readonly yearListLabel = useI18nText(NO_OVERRIDE, 'calendar.yearList', 'Years');\n private readonly prevYearLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYear', 'Previous year');\n private readonly nextYearLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYear', 'Next year');\n private readonly prevYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYears', 'Previous 12 years');\n private readonly nextYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYears', 'Next 12 years');\n\n /** What the ← button does from here — a month, a year, or a 12-year page. */\n protected readonly prevLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.prevYearsLabel();\n case 'month':\n return this.prevYearLabel();\n default:\n return this.prevMonthLabel();\n }\n });\n\n /** What the → button does from here. */\n protected readonly nextLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.nextYearsLabel();\n case 'month':\n return this.nextYearLabel();\n default:\n return this.nextMonthLabel();\n }\n });\n\n protected readonly today = computed(() => this.adapter.today());\n\n protected readonly weekdayNames = computed(() => this.adapter.getDayOfWeekNames('short'));\n\n protected readonly monthsView = computed(() => this.adapter.getMonthNames('short'));\n\n /** 12-year window centered on the floor-aligned decade containing `viewDate`. */\n protected readonly yearsView = computed<readonly number[]>(() => {\n const y = this.adapter.getYear(this.viewDate());\n const start = Math.floor(y / 12) * 12;\n return Array.from({ length: 12 }, (_, i) => start + i);\n });\n\n /**\n * The header above the grid.\n *\n * Both templated strings used to be assembled here: `${month} ${year}` and\n * `${first} – ${last}`. That is English word order with an English separator\n * baked into TypeScript, and no catalog could move either — ja-JP writes\n * 2026年3月, which is not a translation of any word in `March 2026` but a\n * different arrangement of the same two values. So the arrangement is the\n * translatable unit, and `calendar.header` / `calendar.yearRange` are it.\n */\n protected readonly headerLabel = computed(() => {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day': {\n const monthNames = this.adapter.getMonthNames('long');\n return this.headerText({\n month: monthNames[this.adapter.getMonth(v)],\n year: this.adapter.getYear(v),\n });\n }\n case 'month':\n return `${this.adapter.getYear(v)}`;\n case 'year': {\n const years = this.yearsView();\n return this.yearRangeText({ from: years[0], to: years[years.length - 1] });\n }\n }\n });\n\n private readonly headerText = useI18nFormatter('calendar.header', '{{month}} {{year}}');\n private readonly yearRangeText = useI18nFormatter('calendar.yearRange', '{{from}} – {{to}}');\n private readonly dayLabelText = useI18nFormatter('calendar.dayLabel', '{{weekday}}, {{date}}');\n\n /**\n * Long weekday names for the cell names.\n *\n * `getDayOfWeekNames` returns them in COLUMN order — index 0 is\n * `getFirstDayOfWeek()`, not Sunday — which is what the header strip wants and\n * what a `getDayOfWeek()` result (0 = Sunday) must be rotated into. Indexing\n * it directly reads Monday's name for a Sunday in every locale that starts its\n * week on Monday, which is most of them.\n */\n private readonly longWeekdays = computed(() => this.adapter.getDayOfWeekNames('long'));\n\n /**\n * A day cell's accessible name — \"Sunday, March 15, 2026\".\n *\n * The cell had none. Its only content is the day NUMBER, and `role=\"gridcell\"`\n * does not inherit a name from the grid's header or from the column header\n * above it, so every date in the month announced as a bare number: the month,\n * the year and the weekday were all on screen and none of them reachable.\n *\n * `{{date}}` is the adapter's `longDate`, so its field order, its separators\n * and its digits are `Intl`'s — the catalog decides only where the weekday\n * goes. Building it from `getMonthNames('long')` instead would have hard-coded\n * the nominative month, which Russian and Finnish inflect inside a date.\n */\n protected dayLabel(date: Date): string {\n return this.dayLabelText({\n weekday: this.longWeekdays()[(this.adapter.getDayOfWeek(date) - this.adapter.getFirstDayOfWeek() + 7) % 7],\n date: this.adapter.format(date, 'longDate'),\n });\n }\n\n /** 6×7 day grid covering the current month plus spillover. */\n protected readonly weeks = computed<readonly (readonly Date[])[]>(() => {\n const view = this.viewDate();\n const year = this.adapter.getYear(view);\n const month = this.adapter.getMonth(view);\n const firstOfMonth = this.adapter.createDate(year, month, 1);\n const firstWeekday = this.adapter.getDayOfWeek(firstOfMonth);\n const firstDayOfWeek = this.adapter.getFirstDayOfWeek();\n const lead = (firstWeekday - firstDayOfWeek + 7) % 7;\n const gridStart = this.adapter.addDays(firstOfMonth, -lead);\n\n const out: Date[][] = [];\n for (let w = 0; w < ROWS; w++) {\n const row: Date[] = [];\n for (let d = 0; d < COLS; d++) {\n row.push(this.adapter.addDays(gridStart, w * COLS + d));\n }\n out.push(row);\n }\n return out;\n });\n\n /**\n * The chip carrying the listbox's only `tabindex=\"0\"` — where the ring is, and\n * where Tab lands.\n *\n * A listbox owns its arrows, and these two did not: twelve months were twelve\n * tab stops, so the role promised an interaction model the component never\n * implemented. One tab stop plus arrow keys is the roving-tabindex half of the\n * pattern the day grid already uses.\n *\n * Routed through {@link nearestEnabledChip} on BOTH paths — the seed and every\n * arrow — for the reason the grid learned first: `.focus()` on a\n * `<button disabled>` is a no-op, so parking the sole tab stop on a month a\n * `[min]` has closed off leaves the whole view unreachable by keyboard.\n * `-1` on the day view, where there are no chips at all.\n */\n protected readonly activeChip = computed(() => {\n if (this.viewMode() === 'day') return -1;\n return this.nearestEnabledChip(this.rovedChip() ?? this.currentChip());\n });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-calendar', `wr-calendar--${this.mode()}`];\n if (this.disabled()) parts.push('wr-calendar--disabled');\n return parts.join(' ');\n });\n\n constructor() {\n // Initial focus: selected date if any, else today. Also snap viewDate to\n // that month.\n //\n // Stepped onto an ENABLED day, because the roving tabindex puts the grid's\n // only `tabindex=\"0\"` on this cell: seed it on a disabled one — which is\n // exactly what a `min` in the future does to \"today\" — and the sole tab\n // stop is an unfocusable button, leaving the grid unreachable by keyboard.\n afterNextRender(() => {\n const initial = this.nearestEnabled(this.date() ?? this.range()[0] ?? this.adapter.today());\n this.focusedDate.set(initial);\n this.viewDate.set(initial);\n\n // A second, NESTED hook: the lines above only SET the signals, which\n // schedules another change-detection pass — the `--focused` class and the\n // `tabindex` are not in the DOM until that one has run.\n if (this.autoFocus()) {\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n });\n\n // Keep viewDate in sync when date / range changes externally to a\n // different month. The viewDate read must stay untracked — otherwise\n // the effect re-runs on every internal navigation (month stepping,\n // year picking) and snaps the view back to the selected month.\n effect(() => {\n const candidate = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!candidate) return;\n untracked(() => {\n if (!this.adapter.isSameMonth(candidate, this.viewDate())) {\n this.viewDate.set(candidate);\n }\n });\n });\n }\n\n // Navigation\n\n /** Header `‹` button — steps by month / year / decade based on the active view. */\n protected prev(): void {\n this.viewDate.set(this.stepViewDate(-1));\n this.carryCursorIntoView();\n }\n\n /** Header `›` button — steps by month / year / decade based on the active view. */\n protected next(): void {\n this.viewDate.set(this.stepViewDate(1));\n this.carryCursorIntoView();\n }\n\n /**\n * Keeps the roving cursor inside the month the grid is showing.\n *\n * The day grid marks its one tab stop by comparing each cell against\n * `focusedDate` — `[attr.tabindex]=\"isFocused(day) ? 0 : -1\"` — and `weeks()`\n * renders a fixed 42-day window around `viewDate`. Stepping the header moved\n * the window and left the cursor behind, so after two clicks no rendered cell\n * matched and all 42 buttons were `tabindex=\"-1\"`: the grid dropped out of\n * the tab order entirely and could not be reached by keyboard again without\n * navigating back. `onMonthSelect` already did this for its own path and says\n * why at the line; this is the same move for the header arrows.\n *\n * The day-of-month is kept where the new month is long enough for it, so\n * paging through March from the 31st does not silently walk the cursor back\n * to the 1st, and the landing is routed through `nearestEnabled` like every\n * other cursor write.\n */\n private carryCursorIntoView(): void {\n if (this.viewMode() !== 'day') return;\n\n const view = this.viewDate();\n const focused = this.focusedDate();\n if (this.adapter.isSameMonth(focused, view)) return;\n\n const day = Math.min(this.adapter.getDate(focused), this.adapter.getDaysInMonth(view));\n const landing = this.adapter.createDate(this.adapter.getYear(view), this.adapter.getMonth(view), day);\n this.focusedDate.set(this.nearestEnabled(landing));\n }\n\n /** Header label click — zooms out (`day → month → year`). No-op at year view. */\n protected onLabelClick(): void {\n if (this.disabled()) return;\n if (this.viewMode() === 'day') {\n this.setViewMode('month');\n } else if (this.viewMode() === 'month') {\n this.setViewMode('year');\n }\n }\n\n /**\n * Picking a month drops to the day grid — and takes real focus with it.\n *\n * The `@switch (viewMode())` in the template destroys the chip that holds DOM\n * focus, so without the two lines below `document.activeElement` became\n * `<body>`: the ring appeared on the new view and focus did not, the arrow\n * keys went dead (the keydown handler is a HOST binding, so nothing reaches\n * the component from `<body>`), and the next Tab restarted from the top of the\n * document — out of the calendar entirely. It is the same trap the two\n * keyboard paths in this file already fix, and for the same reason\n * `afterNextRender` rather than `queueMicrotask`: under zoneless CD the\n * microtask runs before the new view is in the DOM.\n *\n * `focusedDate` has to move too, and that half is easy to miss. The grid marks\n * its focusable cell by comparing against `focusedDate`, not `viewDate`, so\n * choosing a DIFFERENT month rendered a grid with no `--focused` cell and no\n * `tabindex=\"0\"` at all — unreachable by keyboard from either direction. The\n * day is preserved when the month already holds it and otherwise falls to the\n * first, which is where `viewDate` lands anyway.\n */\n protected onMonthSelect(monthIdx: number): void {\n if (this.isMonthDisabled(monthIdx)) return;\n const v = this.viewDate();\n const year = this.adapter.getYear(v);\n this.viewDate.set(this.adapter.createDate(year, monthIdx, 1));\n\n const focused = this.focusedDate();\n const alreadyThere = this.adapter.getYear(focused) === year && this.adapter.getMonth(focused) === monthIdx;\n if (!alreadyThere) this.focusedDate.set(this.adapter.createDate(year, monthIdx, 1));\n\n this.setViewMode('day');\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /** Year → month view, with the same focus restoration; the landing view is chips. */\n protected onYearSelect(year: number): void {\n if (this.isYearDisabled(year)) return;\n const v = this.viewDate();\n this.viewDate.set(this.adapter.createDate(year, this.adapter.getMonth(v), 1));\n this.setViewMode('month');\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /**\n * Switch views and drop the chip ring with them.\n *\n * Every view change is the only thing that changes what the chips MEAN, so it\n * is the one place the ring has to forget where it was — otherwise a year\n * picked at index 7 rings the eighth MONTH on the way back down.\n */\n private setViewMode(view: 'day' | 'month' | 'year'): void {\n this.rovedChip.set(null);\n this.viewMode.set(view);\n }\n\n private stepViewDate(direction: -1 | 1): Date {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day':\n return this.adapter.addMonths(v, direction);\n case 'month':\n return this.adapter.addYears(v, direction);\n case 'year':\n return this.adapter.addYears(v, direction * 12);\n }\n }\n\n // Cell state predicates (used by template)\n\n protected isToday(date: Date): boolean {\n return this.adapter.isSameDay(date, this.today());\n }\n\n protected isOutOfMonth(date: Date): boolean {\n return !this.adapter.isSameMonth(date, this.viewDate());\n }\n\n protected isSelected(date: Date): boolean {\n if (this.mode() === 'single') {\n const v = this.date();\n return v ? this.adapter.isSameDay(date, v) : false;\n }\n const [start, end] = this.range();\n if (start && this.adapter.isSameDay(date, start)) return true;\n if (end && this.adapter.isSameDay(date, end)) return true;\n return false;\n }\n\n protected isInRange(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n if (!start || !end) return false;\n return this.adapter.compareDate(date, start) > 0 && this.adapter.compareDate(date, end) < 0;\n }\n\n protected isInRangePreview(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n const hover = this.hoverDate();\n if (!start || end || !hover) return false;\n const before = this.adapter.compareDate(start, hover) <= 0;\n const lo = before ? start : hover;\n const hi = before ? hover : start;\n return this.adapter.compareDate(date, lo) > 0 && this.adapter.compareDate(date, hi) < 0;\n }\n\n protected isFocused(date: Date): boolean {\n return this.adapter.isSameDay(date, this.focusedDate());\n }\n\n protected isDisabled(date: Date): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && this.adapter.compareDate(date, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(date, max) > 0) return true;\n const filter = this.dateFilter();\n if (filter && !filter(date)) return true;\n return false;\n }\n\n // Month / year view predicates\n\n protected isMonthCurrent(monthIdx: number): boolean {\n return this.adapter.getMonth(this.viewDate()) === monthIdx;\n }\n\n protected isMonthSelected(monthIdx: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!v) return false;\n return this.adapter.getYear(v) === this.adapter.getYear(this.viewDate()) && this.adapter.getMonth(v) === monthIdx;\n }\n\n protected isMonthDisabled(monthIdx: number): boolean {\n if (this.disabled()) return true;\n const year = this.adapter.getYear(this.viewDate());\n const monthStart = this.adapter.createDate(year, monthIdx, 1);\n const monthEnd = this.adapter.createDate(year, monthIdx, this.adapter.getDaysInMonth(monthStart));\n const min = this.min();\n if (min && this.adapter.compareDate(monthEnd, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(monthStart, max) > 0) return true;\n return false;\n }\n\n protected isYearCurrent(year: number): boolean {\n return this.adapter.getYear(this.viewDate()) === year;\n }\n\n protected isYearSelected(year: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n return v ? this.adapter.getYear(v) === year : false;\n }\n\n protected isYearDisabled(year: number): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && year < this.adapter.getYear(min)) return true;\n const max = this.max();\n if (max && year > this.adapter.getYear(max)) return true;\n return false;\n }\n\n // Interaction\n\n protected onCellClick(date: Date): void {\n if (this.isDisabled(date)) return;\n if (this.mode() === 'single') {\n this.date.set(this.adapter.clone(date));\n } else {\n this.applyRangeClick(date);\n }\n this.focusedDate.set(date);\n if (!this.adapter.isSameMonth(date, this.viewDate())) {\n this.viewDate.set(date);\n }\n }\n\n protected onCellEnter(date: Date): void {\n if (this.mode() === 'range') this.hoverDate.set(date);\n }\n\n protected onCellLeave(): void {\n if (this.mode() === 'range') this.hoverDate.set(null);\n }\n\n private applyRangeClick(date: Date): void {\n const [start, end] = this.range();\n if (!start || (start && end)) {\n this.range.set([this.adapter.clone(date), null]);\n return;\n }\n if (this.adapter.compareDate(date, start) < 0) {\n this.range.set([this.adapter.clone(date), start]);\n } else {\n this.range.set([start, this.adapter.clone(date)]);\n }\n this.hoverDate.set(null);\n }\n\n // Keyboard\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n\n // The listener sits on the HOST, which also wraps the nav header — so\n // without this every key aimed at a `‹` button drove the day grid instead,\n // and the `preventDefault()` below cancelled the button's own activation:\n // Enter on `‹` picked a day the user never touched, ArrowDown on the header\n // yanked real focus into the grid. The host element itself is deliberately\n // let through: `WrCalendarHarness` sends its keys to `<wr-calendar>` rather\n // than to a cell, because the calendar moves focus in an `afterNextRender`\n // and jsdom often has focus nowhere at all.\n const target = event.target as Element | null;\n if (target !== this.host.nativeElement && target?.closest('.wr-calendar__header')) return;\n\n // The month and year views are listboxes, and the arrows belong to them\n // while they are up — there is no day grid on screen to drive. Their chips\n // are real `<button>`s, so Enter and Space fall through to the browser's own\n // activation and must not be swallowed here.\n if (this.viewMode() !== 'day') {\n this.onChipKeyDown(event);\n return;\n }\n\n const current = this.focusedDate();\n let next: Date | null = null;\n // Which way the key travels, so a landing on a closed-off day can keep\n // going instead of stopping on it. See `nearestEnabledToward`.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = this.adapter.addDays(current, -1);\n dir = -1;\n break;\n case 'ArrowRight':\n next = this.adapter.addDays(current, 1);\n break;\n case 'ArrowUp':\n next = this.adapter.addDays(current, -7);\n dir = -1;\n break;\n case 'ArrowDown':\n next = this.adapter.addDays(current, 7);\n break;\n case 'Home': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, -((dow - first + 7) % 7));\n dir = -1;\n break;\n }\n case 'End': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, 6 - ((dow - first + 7) % 7));\n break;\n }\n case 'PageUp':\n next = event.shiftKey ? this.adapter.addYears(current, -1) : this.adapter.addMonths(current, -1);\n dir = -1;\n break;\n case 'PageDown':\n next = event.shiftKey ? this.adapter.addYears(current, 1) : this.adapter.addMonths(current, 1);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.onCellClick(current);\n return;\n }\n\n if (!next) return;\n event.preventDefault();\n\n // The seed is routed through `nearestEnabled` for a reason, and navigation\n // needs the same care: a cell renders `disabled` AND carries the grid's only\n // `tabindex=\"0\"`, so parking the ring on a closed-off day leaves zero\n // tabbable cells — the user tabs out of the calendar and can never tab back\n // in. Real focus splits from the ring too, because `.focus()` on a disabled\n // button is a no-op. Reached by nothing more exotic than `[minDate]`.\n const landing = this.nearestEnabledToward(next, dir);\n if (!landing) return;\n next = landing;\n\n this.focusedDate.set(next);\n if (!this.adapter.isSameMonth(next, this.viewDate())) {\n this.viewDate.set(next);\n }\n // `afterNextRender`, NOT `queueMicrotask`. Under zoneless CD the scheduler\n // runs change detection in a macrotask, so a microtask fires FIRST — the\n // `--focused` class is still on the cell we just left, and this focuses\n // that one. The ring moved and real focus did not, permanently: a screen\n // reader kept announcing the previous day.\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /**\n * Arrow / Home / End inside the month or year listbox — the roving half of the\n * pattern their `role` has always claimed.\n *\n * Steps by one along the row and by a full row vertically, and the inline pair\n * mirrors under `dir=\"rtl\"` for the same reason the grid's does: those two keys\n * name a side of the screen. The page does NOT wrap or spill into the next\n * one — a month list is twelve fixed cells, and the header's `‹` / `›` are what\n * change which twelve. Anything else (Enter, Space, Tab, Escape) is left to the\n * button and to whatever owns the calendar.\n */\n private onChipKeyDown(event: KeyboardEvent): void {\n const cols = this.viewMode() === 'month' ? MONTH_COLS : YEAR_COLS;\n const count = this.chipCount();\n const current = this.activeChip();\n // Assigned on every branch that does not return, so it needs no placeholder.\n let next: number;\n // Which way to keep looking when the landing chip is closed off, exactly as\n // `nearestEnabledToward` does for days.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = current - 1;\n dir = -1;\n break;\n case 'ArrowRight':\n next = current + 1;\n break;\n case 'ArrowUp':\n next = current - cols;\n dir = -1;\n break;\n case 'ArrowDown':\n next = current + cols;\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = count - 1;\n dir = -1;\n break;\n default:\n return;\n }\n\n const landing = this.enabledChipToward(next, dir);\n if (landing === null) return;\n\n event.preventDefault();\n this.rovedChip.set(landing);\n // `afterNextRender`, not `queueMicrotask` — same trap as the grid: under\n // zoneless CD the microtask runs before the new `tabindex` is in the DOM, so\n // the focus call would land on the chip the ring just left.\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /** How many chips the current view renders — twelve either way, read rather than assumed. */\n private chipCount(): number {\n return this.viewMode() === 'month' ? this.monthsView().length : this.yearsView().length;\n }\n\n /** Whether the chip at `index` refuses selection in the current view. */\n private isChipDisabled(index: number): boolean {\n if (this.viewMode() === 'month') return this.isMonthDisabled(index);\n const year = this.yearsView()[index];\n return year === undefined || this.isYearDisabled(year);\n }\n\n /** The chip the view itself points at: the month or year currently on screen. */\n private currentChip(): number {\n if (this.viewMode() === 'month') return this.adapter.getMonth(this.viewDate());\n const index = this.yearsView().indexOf(this.adapter.getYear(this.viewDate()));\n return index === -1 ? 0 : index;\n }\n\n /**\n * The first selectable chip at or after `from`, else the first before it, else\n * `from` unchanged when the whole page is closed off — the chip version of\n * {@link nearestEnabled}, and it exists for the same reason: the ring carries\n * the only `tabindex=\"0\"`, and a disabled button cannot hold it.\n */\n private nearestEnabledChip(from: number): number {\n const count = this.chipCount();\n const start = Math.min(Math.max(from, 0), count - 1);\n if (!this.isChipDisabled(start)) return start;\n\n for (const step of [1, -1] as const) {\n const found = this.enabledChipToward(start + step, step);\n if (found !== null) return found;\n }\n return start;\n }\n\n /**\n * The first selectable chip at `from` or beyond it in `step`'s direction, else\n * null when that whole direction is closed off — which is the answer for an\n * ArrowLeft on the first chip: stay put.\n */\n private enabledChipToward(from: number, step: 1 | -1): number | null {\n for (let i = from; i >= 0 && i < this.chipCount(); i += step) {\n if (!this.isChipDisabled(i)) return i;\n }\n return null;\n }\n\n private focusActiveChip(): void {\n // By the tab stop, not by index: it is the same element the ring is on, and\n // asking for it this way cannot drift out of step with the template.\n this.host.nativeElement.querySelector<HTMLElement>('.wr-calendar__chip[tabindex=\"0\"]')?.focus();\n }\n\n /**\n * The first selectable day at or after `candidate`, else the first before it,\n * else `candidate` unchanged when everything nearby is closed off. Bounded at\n * a year each way so a pathological `dateFilter` cannot spin.\n */\n private nearestEnabled(candidate: Date): Date {\n if (!this.isDisabled(candidate)) return candidate;\n\n for (const step of [1, -1] as const) {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n probe = this.adapter.addDays(probe, step);\n if (!this.isDisabled(probe)) return probe;\n }\n }\n return candidate;\n }\n\n /**\n * The first selectable day at `candidate` or beyond it in `step`'s direction,\n * else null when that whole direction is closed off — which is the answer for\n * an ArrowLeft that would cross `min`: stay put.\n *\n * Direction matters. Reusing `nearestEnabled`, which probes forward first,\n * would send an ArrowLeft over a disabled weekend straight back to the day it\n * started from, so the ring could never cross the hole.\n */\n private nearestEnabledToward(candidate: Date, step: 1 | -1): Date | null {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n if (!this.isDisabled(probe)) return probe;\n probe = this.adapter.addDays(probe, step);\n }\n return null;\n }\n\n private focusActiveCell(): void {\n const el = this.host.nativeElement.querySelector('.wr-calendar__day--focused');\n (el as HTMLElement | null)?.focus();\n }\n\n /** Used by the template's `track` expression. */\n protected trackByTime(_: number, date: Date): number {\n return date.getTime();\n }\n\n /**\n * The key as the GRID sees it.\n *\n * Arrow keys follow visual order, and a calendar grid mirrors under\n * `dir=\"rtl\"`: the day to the visual right of today is yesterday. Only the\n * inline pair swaps — Up/Down step a week either way, and PageUp/PageDown and\n * Home/End are semantic rather than physical.\n */\n private inlineKey(key: string): string {\n if (this.dir?.value !== 'rtl') return key;\n if (key === 'ArrowRight') return 'ArrowLeft';\n if (key === 'ArrowLeft') return 'ArrowRight';\n return key;\n }\n}\n","<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-label]=\"dayLabel(day)\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model — arrow to a month, Tab\n out of the list — that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\" [attr.aria-label]=\"monthListLabel()\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\" [attr.aria-label]=\"yearListLabel()\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n"],"mappings":"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"}
|
|
@@ -38,6 +38,8 @@ var WrCascader = class WrCascader {
|
|
|
38
38
|
transform: coerceBooleanProperty
|
|
39
39
|
});
|
|
40
40
|
fieldAria = useFormFieldAria();
|
|
41
|
+
labelledBy = computed(() => this.ariaLabel() ? null : this.fieldAria.labelledBy(), ...ngDevMode ? [{ debugName: "labelledBy" }] : /* istanbul ignore next */ []);
|
|
42
|
+
nameLabel = computed(() => this.labelledBy() ? null : this.resolvedAriaLabel(), ...ngDevMode ? [{ debugName: "nameLabel" }] : /* istanbul ignore next */ []);
|
|
41
43
|
size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
|
|
42
44
|
clearable = input(true, {
|
|
43
45
|
...ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {},
|
|
@@ -346,8 +348,8 @@ var WrCascader = class WrCascader {
|
|
|
346
348
|
isSignal: true
|
|
347
349
|
}],
|
|
348
350
|
ngImport: i0,
|
|
349
|
-
template: "<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"
|
|
350
|
-
styles: [".wr-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-table__sort-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-tabs__tab:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-sidebar__entry:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-sidebar__item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-anchor__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-collapse__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-command-palette__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-mention-panel__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-segmented__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-back-top:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-stepper__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-window__chrome-action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-dropdown-item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-alert__close:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-graph__viewport:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-cascader{--wr-cascader-color: var(--wr-color-on-surface);--wr-cascader-bg: var(--wr-color-surface);--wr-cascader-border: var(--wr-color-outline);--wr-cascader-radius: var(--wr-control-radius-md);--wr-cascader-padding-y: var(--wr-control-padding-y-md);--wr-cascader-padding-x: var(--wr-control-padding-x-md);--wr-cascader-font-size: var(--wr-control-font-size-md);--wr-cascader-line-height: var(--wr-control-line-height-md);--wr-cascader-
|
|
351
|
+
template: "<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"nameLabel()\"\n [attr.aria-labelledby]=\"labelledBy()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'tree'\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n (click)=\"onTriggerClick()\"\n (keydown)=\"onTriggerKeydown($event)\"\n (blur)=\"touch.emit()\"\n>\n @if (displayLabel(); as label) {\n <span class=\"wr-cascader__value\">{{ label }}</span>\n } @else {\n <span class=\"wr-cascader__placeholder\">{{ placeholder() }}</span>\n }\n\n @if (clearable() && hasSelection() && !disabled() && !readonly()) {\n <span\n class=\"wr-cascader__clear\"\n role=\"button\"\n [attr.aria-label]=\"resolvedClearLabel()\"\n tabindex=\"-1\"\n (click)=\"clearSelection($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n }\n\n <svg\n class=\"wr-icon__svg wr-cascader__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n</button>\n\n<ng-template #panelTpl>\n <div\n class=\"wr-cascader-panel\"\n [class.wr-cascader-panel--sm]=\"size() === 'sm'\"\n [class.wr-cascader-panel--lg]=\"size() === 'lg'\"\n role=\"tree\"\n [attr.id]=\"panelId\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <!--\n tree / group / treeitem, and NOT menu. A combobox's popup may be a listbox,\n a tree, a grid or a dialog and nothing else, so `aria-haspopup=\"menu\"` on\n the trigger was an author error — and a `menu` may own menuitems and\n groups, never other menus, so the columns were a second one. Neither is\n visible to axe: `menu` is a valid token for the global `aria-haspopup`, and\n `aria-required-children` passes a menu-inside-menu (measured against this\n exact fragment). A tree is what this control has always been — the value is\n a PATH, and only `treeitem` supports aria-expanded, aria-level,\n aria-setsize, aria-posinset and aria-selected at once.\n\n The columns stay `group` rather than collapsing to `role=\"presentation\"`,\n which is also axe-clean: the DOM is column-MAJOR, so a flat tree would\n leave level plus document order as the only structure, and \"Germany\"\n (level 2) would read as a child of \"Antarctica\" (level 1, the item\n immediately before it in source order).\n -->\n @for (col of columns(); track $index; let colIndex = $index) {\n <ul\n class=\"wr-cascader__col\"\n role=\"group\"\n [attr.id]=\"columnId(colIndex)\"\n [attr.aria-labelledby]=\"parentOptionId(colIndex)\"\n >\n @for (opt of col; track opt.value; let optIndex = $index) {\n <!--\n `aria-expanded` is exactly `isActiveAt`: `columns()` renders the next\n column for the active option and only when it has children, so the\n state can never claim a column that is not on screen — and\n `aria-controls` rides that same invariant, which is what makes\n \"expanded\" refer to something when the expanded content is a SIBLING\n rather than a descendant. It is emitted only while expanded: a\n reference to an absent id is a violation with `aria-expanded=\"true\"`\n and clean while collapsed.\n\n `aria-level` is load-bearing rather than decorative. The columns are\n siblings, so the DOM ancestry represents no level at all and every\n option would read as level 1. `aria-setsize` / `aria-posinset` are\n not strictly required — each column IS a complete sibling set — and\n are written anyway, because a tree that owns sibling groups is the\n uncommon shape where browser/AT pairs are known to miscompute both.\n\n `aria-selected` is written on every option that can be COMMITTED,\n `false` included, matching `wr-tree`. The alternative a reviewer may\n prefer: only the selected node, leaning on treeitem's implicit false,\n which is quieter in a long column and loses the \"this row is\n selectable\" signal that presence carries.\n -->\n <li\n class=\"wr-cascader__opt\"\n role=\"treeitem\"\n [attr.id]=\"optionId(colIndex, optIndex)\"\n [class.wr-cascader__opt--active]=\"isActiveAt(colIndex, opt.value)\"\n [class.wr-cascader__opt--disabled]=\"opt.disabled\"\n [attr.tabindex]=\"opt.disabled ? -1 : 0\"\n [attr.aria-disabled]=\"opt.disabled ? true : null\"\n [attr.aria-level]=\"colIndex + 1\"\n [attr.aria-setsize]=\"$count\"\n [attr.aria-posinset]=\"optIndex + 1\"\n [attr.aria-selected]=\"isSelectedAt(colIndex, opt)\"\n [attr.aria-expanded]=\"opt.children?.length ? isActiveAt(colIndex, opt.value) : null\"\n [attr.aria-controls]=\"\n opt.children?.length && isActiveAt(colIndex, opt.value) ? columnId(colIndex + 1) : null\n \"\n (click)=\"onOptionClick(colIndex, opt, $event)\"\n (keydown.enter)=\"onOptionClick(colIndex, opt, $event)\"\n (keydown.space)=\"onOptionClick(colIndex, opt, $event)\"\n >\n <span class=\"wr-cascader__opt-label\">{{ opt.label }}</span>\n @if (opt.children?.length) {\n <svg\n class=\"wr-icon__svg wr-cascader__opt-arrow\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n }\n </li>\n }\n </ul>\n }\n </div>\n</ng-template>\n",
|
|
352
|
+
styles: [".wr-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-table__sort-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-tabs__tab:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-sidebar__entry:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-sidebar__item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-anchor__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-collapse__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-command-palette__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-mention-panel__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-segmented__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-back-top:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-stepper__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-window__chrome-action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-dropdown-item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-alert__close:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-graph__viewport:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-cascader{--wr-cascader-color: var(--wr-color-on-surface);--wr-cascader-bg: var(--wr-color-surface);--wr-cascader-border: var(--wr-color-outline);--wr-cascader-radius: var(--wr-control-radius-md);--wr-cascader-padding-y: var(--wr-control-padding-y-md);--wr-cascader-padding-x: var(--wr-control-padding-x-md);--wr-cascader-font-size: var(--wr-control-font-size-md);--wr-cascader-line-height: var(--wr-control-line-height-md);--wr-cascader-min-width: 12rem;display:inline-grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto 0;vertical-align:middle}.wr-cascader:after{content:\"\";flex:0 0 0;width:var(--wr-cascader-min-width);max-width:100%;height:0}.wr-cascader--disabled{--wr-cascader-color: var(--wr-color-on-surface-muted);--wr-cascader-bg: var(--wr-color-fill)}.wr-cascader--sm{--wr-cascader-radius: var(--wr-control-radius-sm);--wr-cascader-padding-y: var(--wr-control-padding-y-sm);--wr-cascader-padding-x: var(--wr-control-padding-x-sm);--wr-cascader-font-size: var(--wr-control-font-size-sm);--wr-cascader-line-height: var(--wr-control-line-height-sm)}.wr-cascader--lg{--wr-cascader-radius: var(--wr-control-radius-lg);--wr-cascader-padding-y: var(--wr-control-padding-y-lg);--wr-cascader-padding-x: var(--wr-control-padding-x-lg);--wr-cascader-font-size: var(--wr-control-font-size-lg);--wr-cascader-line-height: var(--wr-control-line-height-lg)}.wr-cascader__trigger{display:inline-flex;align-items:center;gap:.5rem;width:100%;min-width:0;appearance:none;background:var(--wr-cascader-bg);color:var(--wr-cascader-color);border:1px solid var(--wr-cascader-border);border-radius:var(--wr-cascader-radius);padding:calc(var(--wr-cascader-padding-y) * var(--wr-density-y, 1)) calc(var(--wr-cascader-padding-x) * var(--wr-density-x, 1));font-family:var(--wr-font-family-base);font-size:var(--wr-cascader-font-size);line-height:var(--wr-cascader-line-height);cursor:pointer;text-align:start;transition:border-color var(--wr-transition-base),box-shadow var(--wr-transition-base)}.wr-cascader__trigger:focus-visible{border-color:var(--wr-color-primary);outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-cascader__trigger:disabled{cursor:not-allowed}@media(pointer:coarse){.wr-cascader__trigger{overflow-y:clip}}.wr-cascader--readonly .wr-cascader__trigger{cursor:default}.wr-cascader--open .wr-cascader__trigger{border-color:var(--wr-color-primary);box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.15)}.wr-cascader__value,.wr-cascader__placeholder{flex:1 1 auto;min-height:1lh;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wr-cascader__placeholder{color:var(--wr-color-placeholder)}.wr-cascader__chevron{flex:0 0 auto;color:var(--wr-color-on-surface-muted);transition:transform var(--wr-transition-base)}.wr-cascader--open .wr-cascader__chevron{transform:rotate(180deg)}.wr-cascader__clear{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;margin-block:-1rem;border-radius:999px;color:var(--wr-color-on-surface-muted);cursor:pointer;transition:background .12s ease,color .12s ease}.wr-cascader__clear:hover{background:rgba(var(--wr-color-on-surface-rgb),.06);color:var(--wr-color-on-surface)}@media(pointer:coarse){.wr-cascader__clear{position:relative}.wr-cascader__clear:after{content:\"\";position:absolute;top:50%;left:50%;width:100%;height:100%;min-width:2rem;min-height:2rem;transform:translate(-50%,-50%)}}.wr-cascader-overlay{padding-top:.25rem}.wr-cascader-panel{--wr-cascader-opt-font: var(--wr-control-font-size-md);--wr-cascader-opt-py: .5rem;--wr-cascader-col-width: 12rem;--wr-cascader-max-height: 16rem;display:flex;background:var(--wr-color-surface);border:1px solid var(--wr-color-outline);border-radius:var(--wr-border-radius-base);box-shadow:var(--wr-shadow-overlay);font-family:var(--wr-font-family-base);font-size:var(--wr-cascader-opt-font);overflow:hidden}.wr-cascader-panel--sm{--wr-cascader-opt-font: var(--wr-control-font-size-sm);--wr-cascader-opt-py: .375rem}.wr-cascader-panel--lg{--wr-cascader-opt-font: var(--wr-control-font-size-lg);--wr-cascader-opt-py: .625rem}.wr-cascader-panel .wr-cascader__col{list-style:none;margin:0;padding:.25rem;width:var(--wr-cascader-col-width);max-height:var(--wr-cascader-max-height);overflow-y:auto;display:flex;flex-direction:column;gap:.125rem}.wr-cascader-panel .wr-cascader__col+.wr-cascader__col{border-inline-start:1px solid var(--wr-color-outline)}.wr-cascader-panel .wr-cascader__opt{display:flex;align-items:center;gap:.5rem;padding:var(--wr-cascader-opt-py) .625rem;border-radius:var(--wr-border-radius-sm);color:var(--wr-color-on-surface);cursor:pointer;transition:background var(--wr-transition-short)}.wr-cascader-panel .wr-cascader__opt:hover{background:var(--wr-color-hover)}.wr-cascader-panel .wr-cascader__opt--active{background:var(--wr-color-primary-soft);color:var(--wr-color-primary-ink);font-weight:500}.wr-cascader-panel .wr-cascader__opt--disabled{color:var(--wr-color-on-surface-muted);cursor:not-allowed;opacity:var(--wr-disabled-opacity)}.wr-cascader-panel .wr-cascader__opt--disabled:hover{background:transparent}.wr-cascader-panel .wr-cascader__opt-label{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wr-cascader-panel .wr-cascader__opt-arrow{flex:0 0 auto;color:var(--wr-color-on-surface-muted)}[dir=rtl] .wr-cascader-panel .wr-cascader__opt-arrow{transform:scaleX(-1)}@media(pointer:coarse){.wr-cascader-panel .wr-cascader__opt{padding-top:.75rem;padding-bottom:.75rem}}\n"],
|
|
351
353
|
encapsulation: i0.ViewEncapsulation.None
|
|
352
354
|
});
|
|
353
355
|
};
|
|
@@ -362,8 +364,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
362
364
|
selector: "wr-cascader",
|
|
363
365
|
encapsulation: ViewEncapsulation.None,
|
|
364
366
|
host: { "[class]": "classes()" },
|
|
365
|
-
template: "<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"
|
|
366
|
-
styles: [".wr-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-table__sort-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-tabs__tab:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-sidebar__entry:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-sidebar__item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-anchor__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-collapse__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-command-palette__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-mention-panel__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-segmented__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-back-top:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-stepper__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-window__chrome-action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-dropdown-item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-alert__close:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-graph__viewport:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-cascader{--wr-cascader-color: var(--wr-color-on-surface);--wr-cascader-bg: var(--wr-color-surface);--wr-cascader-border: var(--wr-color-outline);--wr-cascader-radius: var(--wr-control-radius-md);--wr-cascader-padding-y: var(--wr-control-padding-y-md);--wr-cascader-padding-x: var(--wr-control-padding-x-md);--wr-cascader-font-size: var(--wr-control-font-size-md);--wr-cascader-line-height: var(--wr-control-line-height-md);--wr-cascader-
|
|
367
|
+
template: "<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"nameLabel()\"\n [attr.aria-labelledby]=\"labelledBy()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'tree'\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n (click)=\"onTriggerClick()\"\n (keydown)=\"onTriggerKeydown($event)\"\n (blur)=\"touch.emit()\"\n>\n @if (displayLabel(); as label) {\n <span class=\"wr-cascader__value\">{{ label }}</span>\n } @else {\n <span class=\"wr-cascader__placeholder\">{{ placeholder() }}</span>\n }\n\n @if (clearable() && hasSelection() && !disabled() && !readonly()) {\n <span\n class=\"wr-cascader__clear\"\n role=\"button\"\n [attr.aria-label]=\"resolvedClearLabel()\"\n tabindex=\"-1\"\n (click)=\"clearSelection($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n }\n\n <svg\n class=\"wr-icon__svg wr-cascader__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n</button>\n\n<ng-template #panelTpl>\n <div\n class=\"wr-cascader-panel\"\n [class.wr-cascader-panel--sm]=\"size() === 'sm'\"\n [class.wr-cascader-panel--lg]=\"size() === 'lg'\"\n role=\"tree\"\n [attr.id]=\"panelId\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <!--\n tree / group / treeitem, and NOT menu. A combobox's popup may be a listbox,\n a tree, a grid or a dialog and nothing else, so `aria-haspopup=\"menu\"` on\n the trigger was an author error — and a `menu` may own menuitems and\n groups, never other menus, so the columns were a second one. Neither is\n visible to axe: `menu` is a valid token for the global `aria-haspopup`, and\n `aria-required-children` passes a menu-inside-menu (measured against this\n exact fragment). A tree is what this control has always been — the value is\n a PATH, and only `treeitem` supports aria-expanded, aria-level,\n aria-setsize, aria-posinset and aria-selected at once.\n\n The columns stay `group` rather than collapsing to `role=\"presentation\"`,\n which is also axe-clean: the DOM is column-MAJOR, so a flat tree would\n leave level plus document order as the only structure, and \"Germany\"\n (level 2) would read as a child of \"Antarctica\" (level 1, the item\n immediately before it in source order).\n -->\n @for (col of columns(); track $index; let colIndex = $index) {\n <ul\n class=\"wr-cascader__col\"\n role=\"group\"\n [attr.id]=\"columnId(colIndex)\"\n [attr.aria-labelledby]=\"parentOptionId(colIndex)\"\n >\n @for (opt of col; track opt.value; let optIndex = $index) {\n <!--\n `aria-expanded` is exactly `isActiveAt`: `columns()` renders the next\n column for the active option and only when it has children, so the\n state can never claim a column that is not on screen — and\n `aria-controls` rides that same invariant, which is what makes\n \"expanded\" refer to something when the expanded content is a SIBLING\n rather than a descendant. It is emitted only while expanded: a\n reference to an absent id is a violation with `aria-expanded=\"true\"`\n and clean while collapsed.\n\n `aria-level` is load-bearing rather than decorative. The columns are\n siblings, so the DOM ancestry represents no level at all and every\n option would read as level 1. `aria-setsize` / `aria-posinset` are\n not strictly required — each column IS a complete sibling set — and\n are written anyway, because a tree that owns sibling groups is the\n uncommon shape where browser/AT pairs are known to miscompute both.\n\n `aria-selected` is written on every option that can be COMMITTED,\n `false` included, matching `wr-tree`. The alternative a reviewer may\n prefer: only the selected node, leaning on treeitem's implicit false,\n which is quieter in a long column and loses the \"this row is\n selectable\" signal that presence carries.\n -->\n <li\n class=\"wr-cascader__opt\"\n role=\"treeitem\"\n [attr.id]=\"optionId(colIndex, optIndex)\"\n [class.wr-cascader__opt--active]=\"isActiveAt(colIndex, opt.value)\"\n [class.wr-cascader__opt--disabled]=\"opt.disabled\"\n [attr.tabindex]=\"opt.disabled ? -1 : 0\"\n [attr.aria-disabled]=\"opt.disabled ? true : null\"\n [attr.aria-level]=\"colIndex + 1\"\n [attr.aria-setsize]=\"$count\"\n [attr.aria-posinset]=\"optIndex + 1\"\n [attr.aria-selected]=\"isSelectedAt(colIndex, opt)\"\n [attr.aria-expanded]=\"opt.children?.length ? isActiveAt(colIndex, opt.value) : null\"\n [attr.aria-controls]=\"\n opt.children?.length && isActiveAt(colIndex, opt.value) ? columnId(colIndex + 1) : null\n \"\n (click)=\"onOptionClick(colIndex, opt, $event)\"\n (keydown.enter)=\"onOptionClick(colIndex, opt, $event)\"\n (keydown.space)=\"onOptionClick(colIndex, opt, $event)\"\n >\n <span class=\"wr-cascader__opt-label\">{{ opt.label }}</span>\n @if (opt.children?.length) {\n <svg\n class=\"wr-icon__svg wr-cascader__opt-arrow\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n }\n </li>\n }\n </ul>\n }\n </div>\n</ng-template>\n",
|
|
368
|
+
styles: [".wr-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-table__sort-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-tabs__tab:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-sidebar__entry:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-sidebar__item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-anchor__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-collapse__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-command-palette__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-mention-panel__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-segmented__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-back-top:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-stepper__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-window__chrome-action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-dropdown-item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-alert__close:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-graph__viewport:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-cascader{--wr-cascader-color: var(--wr-color-on-surface);--wr-cascader-bg: var(--wr-color-surface);--wr-cascader-border: var(--wr-color-outline);--wr-cascader-radius: var(--wr-control-radius-md);--wr-cascader-padding-y: var(--wr-control-padding-y-md);--wr-cascader-padding-x: var(--wr-control-padding-x-md);--wr-cascader-font-size: var(--wr-control-font-size-md);--wr-cascader-line-height: var(--wr-control-line-height-md);--wr-cascader-min-width: 12rem;display:inline-grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto 0;vertical-align:middle}.wr-cascader:after{content:\"\";flex:0 0 0;width:var(--wr-cascader-min-width);max-width:100%;height:0}.wr-cascader--disabled{--wr-cascader-color: var(--wr-color-on-surface-muted);--wr-cascader-bg: var(--wr-color-fill)}.wr-cascader--sm{--wr-cascader-radius: var(--wr-control-radius-sm);--wr-cascader-padding-y: var(--wr-control-padding-y-sm);--wr-cascader-padding-x: var(--wr-control-padding-x-sm);--wr-cascader-font-size: var(--wr-control-font-size-sm);--wr-cascader-line-height: var(--wr-control-line-height-sm)}.wr-cascader--lg{--wr-cascader-radius: var(--wr-control-radius-lg);--wr-cascader-padding-y: var(--wr-control-padding-y-lg);--wr-cascader-padding-x: var(--wr-control-padding-x-lg);--wr-cascader-font-size: var(--wr-control-font-size-lg);--wr-cascader-line-height: var(--wr-control-line-height-lg)}.wr-cascader__trigger{display:inline-flex;align-items:center;gap:.5rem;width:100%;min-width:0;appearance:none;background:var(--wr-cascader-bg);color:var(--wr-cascader-color);border:1px solid var(--wr-cascader-border);border-radius:var(--wr-cascader-radius);padding:calc(var(--wr-cascader-padding-y) * var(--wr-density-y, 1)) calc(var(--wr-cascader-padding-x) * var(--wr-density-x, 1));font-family:var(--wr-font-family-base);font-size:var(--wr-cascader-font-size);line-height:var(--wr-cascader-line-height);cursor:pointer;text-align:start;transition:border-color var(--wr-transition-base),box-shadow var(--wr-transition-base)}.wr-cascader__trigger:focus-visible{border-color:var(--wr-color-primary);outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-cascader__trigger:disabled{cursor:not-allowed}@media(pointer:coarse){.wr-cascader__trigger{overflow-y:clip}}.wr-cascader--readonly .wr-cascader__trigger{cursor:default}.wr-cascader--open .wr-cascader__trigger{border-color:var(--wr-color-primary);box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.15)}.wr-cascader__value,.wr-cascader__placeholder{flex:1 1 auto;min-height:1lh;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wr-cascader__placeholder{color:var(--wr-color-placeholder)}.wr-cascader__chevron{flex:0 0 auto;color:var(--wr-color-on-surface-muted);transition:transform var(--wr-transition-base)}.wr-cascader--open .wr-cascader__chevron{transform:rotate(180deg)}.wr-cascader__clear{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;margin-block:-1rem;border-radius:999px;color:var(--wr-color-on-surface-muted);cursor:pointer;transition:background .12s ease,color .12s ease}.wr-cascader__clear:hover{background:rgba(var(--wr-color-on-surface-rgb),.06);color:var(--wr-color-on-surface)}@media(pointer:coarse){.wr-cascader__clear{position:relative}.wr-cascader__clear:after{content:\"\";position:absolute;top:50%;left:50%;width:100%;height:100%;min-width:2rem;min-height:2rem;transform:translate(-50%,-50%)}}.wr-cascader-overlay{padding-top:.25rem}.wr-cascader-panel{--wr-cascader-opt-font: var(--wr-control-font-size-md);--wr-cascader-opt-py: .5rem;--wr-cascader-col-width: 12rem;--wr-cascader-max-height: 16rem;display:flex;background:var(--wr-color-surface);border:1px solid var(--wr-color-outline);border-radius:var(--wr-border-radius-base);box-shadow:var(--wr-shadow-overlay);font-family:var(--wr-font-family-base);font-size:var(--wr-cascader-opt-font);overflow:hidden}.wr-cascader-panel--sm{--wr-cascader-opt-font: var(--wr-control-font-size-sm);--wr-cascader-opt-py: .375rem}.wr-cascader-panel--lg{--wr-cascader-opt-font: var(--wr-control-font-size-lg);--wr-cascader-opt-py: .625rem}.wr-cascader-panel .wr-cascader__col{list-style:none;margin:0;padding:.25rem;width:var(--wr-cascader-col-width);max-height:var(--wr-cascader-max-height);overflow-y:auto;display:flex;flex-direction:column;gap:.125rem}.wr-cascader-panel .wr-cascader__col+.wr-cascader__col{border-inline-start:1px solid var(--wr-color-outline)}.wr-cascader-panel .wr-cascader__opt{display:flex;align-items:center;gap:.5rem;padding:var(--wr-cascader-opt-py) .625rem;border-radius:var(--wr-border-radius-sm);color:var(--wr-color-on-surface);cursor:pointer;transition:background var(--wr-transition-short)}.wr-cascader-panel .wr-cascader__opt:hover{background:var(--wr-color-hover)}.wr-cascader-panel .wr-cascader__opt--active{background:var(--wr-color-primary-soft);color:var(--wr-color-primary-ink);font-weight:500}.wr-cascader-panel .wr-cascader__opt--disabled{color:var(--wr-color-on-surface-muted);cursor:not-allowed;opacity:var(--wr-disabled-opacity)}.wr-cascader-panel .wr-cascader__opt--disabled:hover{background:transparent}.wr-cascader-panel .wr-cascader__opt-label{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wr-cascader-panel .wr-cascader__opt-arrow{flex:0 0 auto;color:var(--wr-color-on-surface-muted)}[dir=rtl] .wr-cascader-panel .wr-cascader__opt-arrow{transform:scaleX(-1)}@media(pointer:coarse){.wr-cascader-panel .wr-cascader__opt{padding-top:.75rem;padding-bottom:.75rem}}\n"]
|
|
367
369
|
}]
|
|
368
370
|
}],
|
|
369
371
|
ctorParameters: () => [],
|