ngwr 14.7.0 → 14.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bar-chart/styles/_index.scss +1 -0
- package/calendar-heatmap/styles/_index.scss +1 -0
- package/cascader/styles/_rules.scss +86 -14
- package/date-picker/styles/_index.scss +30 -0
- package/density/styles/_index.scss +4 -2
- package/donut-chart/styles/_index.scss +10 -0
- package/dropdown/styles/_index.scss +67 -5
- package/event-calendar/styles/_index.scss +209 -35
- package/fesm2022/ngwr-bar-chart.mjs +29 -4
- package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap.mjs +59 -4
- package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +2 -2
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +12 -2
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +705 -46
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart.mjs +46 -4
- package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +166 -17
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar.mjs +9 -2
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-form.mjs +52 -1
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-gauge.mjs +33 -4
- package/fesm2022/ngwr-gauge.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ar.mjs +2 -0
- package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-cs.mjs +2 -0
- package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-de.mjs +2 -0
- package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +5 -0
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-es.mjs +2 -0
- package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-fr.mjs +2 -0
- package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-he.mjs +2 -0
- package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-hi.mjs +2 -0
- package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-id.mjs +2 -0
- package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-it.mjs +2 -0
- package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ja.mjs +2 -0
- package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ko.mjs +2 -0
- package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-nl.mjs +2 -0
- package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pl.mjs +2 -0
- package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pt.mjs +2 -0
- package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +2 -0
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-sv.mjs +2 -0
- package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-tr.mjs +2 -0
- package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-uk.mjs +2 -0
- package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-vi.mjs +2 -0
- package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh-TW.mjs +2 -0
- package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh.mjs +2 -0
- package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
- package/fesm2022/ngwr-input-number.mjs +12 -0
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart.mjs +16 -5
- package/fesm2022/ngwr-line-chart.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group-testing.mjs +7 -3
- package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group.mjs +24 -4
- package/fesm2022/ngwr-meter-group.mjs.map +1 -1
- package/fesm2022/ngwr-page-header.mjs +10 -2
- package/fesm2022/ngwr-page-header.mjs.map +1 -1
- package/fesm2022/ngwr-popover.mjs +569 -7
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-sidebar.mjs +7 -0
- package/fesm2022/ngwr-sidebar.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline.mjs +82 -8
- package/fesm2022/ngwr-sparkline.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +1 -1
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-toolbar.mjs +7 -0
- package/fesm2022/ngwr-toolbar.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/form/styles/_index.scss +11 -1
- package/gauge/styles/_index.scss +1 -0
- package/i18n/ar.json +3 -1
- package/i18n/cs.json +3 -1
- package/i18n/de.json +3 -1
- package/i18n/en.json +3 -1
- package/i18n/es.json +3 -1
- package/i18n/fr.json +3 -1
- package/i18n/he.json +3 -1
- package/i18n/hi.json +3 -1
- package/i18n/id.json +3 -1
- package/i18n/it.json +3 -1
- package/i18n/ja.json +3 -1
- package/i18n/ko.json +3 -1
- package/i18n/nl.json +3 -1
- package/i18n/pl.json +3 -1
- package/i18n/pt.json +3 -1
- package/i18n/ru.json +3 -1
- package/i18n/sv.json +3 -1
- package/i18n/tr.json +3 -1
- package/i18n/uk.json +3 -1
- package/i18n/vi.json +3 -1
- package/i18n/zh-TW.json +3 -1
- package/i18n/zh.json +3 -1
- package/input/styles/_index.scss +19 -0
- package/input-number/styles/_index.scss +69 -0
- package/line-chart/styles/_index.scss +30 -2
- package/llms-full.txt +3 -3
- package/meter-group/styles/_index.scss +1 -0
- package/overlay/styles/_arrow.scss +27 -2
- package/package.json +1 -1
- package/page-header/styles/_index.scss +37 -1
- package/pagination/styles/_index.scss +9 -5
- package/popover/styles/_index.scss +73 -5
- package/select/styles/_index.scss +48 -9
- package/sidebar/styles/_index.scss +34 -2
- package/sparkline/styles/_index.scss +19 -0
- package/toolbar/styles/_index.scss +35 -1
- package/tree/styles/_index.scss +45 -6
- package/types/ngwr-bar-chart.d.ts +19 -1
- package/types/ngwr-calendar-heatmap.d.ts +29 -1
- package/types/ngwr-checkbox.d.ts +2 -0
- package/types/ngwr-date-picker.d.ts +308 -43
- package/types/ngwr-donut-chart.d.ts +24 -1
- package/types/ngwr-dropdown.d.ts +22 -2
- package/types/ngwr-event-calendar.d.ts +8 -0
- package/types/ngwr-form.d.ts +35 -5
- package/types/ngwr-gauge.d.ts +20 -1
- package/types/ngwr-input-number.d.ts +7 -0
- package/types/ngwr-line-chart.d.ts +9 -1
- package/types/ngwr-meter-group-testing.d.ts +3 -2
- package/types/ngwr-meter-group.d.ts +14 -1
- package/types/ngwr-page-header.d.ts +10 -2
- package/types/ngwr-popover.d.ts +154 -3
- package/types/ngwr-sidebar.d.ts +7 -0
- package/types/ngwr-sparkline.d.ts +43 -1
- package/types/ngwr-toolbar.d.ts +7 -0
- package/types/ngwr-version.d.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-calendar-heatmap.mjs","sources":["../../../projects/lib/calendar-heatmap/calendar-heatmap.ts","../../../projects/lib/calendar-heatmap/calendar-heatmap.html","../../../projects/lib/calendar-heatmap/ngwr-calendar-heatmap.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { WR_DATE_LOCALE } from 'ngwr/date';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport type { WrHeatmapDatum } from './interfaces';\n\ninterface Cell {\n readonly iso: string;\n /** The day as the reader's locale writes it — see `cellTitle`. */\n readonly date: Date;\n readonly value: number;\n readonly intensity: number;\n readonly week: number;\n readonly day: number;\n}\n\nfunction toIso(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n}\n\nfunction parseInput(value: string | Date): Date {\n return value instanceof Date ? new Date(value) : new Date(`${value}T00:00:00`);\n}\n\n/** Which rows carry a weekday label: three of seven, or they do not fit. */\nconst LABELLED_ROWS = new Set([1, 3, 5]);\n\n/**\n * A day's contribution, with anything non-finite read as `0`.\n *\n * One `NaN` used to flatten the entire rendered window rather than its own day:\n * `Math.max(a, NaN)` is `NaN`, so the data set's maximum became `NaN`, `max > 0`\n * was false, and every cell fell to intensity 0 — a map that reads as a stretch\n * with no activity at all. The bad day also printed the literal text `NaN` in its\n * `title`.\n */\nfunction amount(raw: number): number {\n return Number.isFinite(raw) ? raw : 0;\n}\n\n/**\n * GitHub-style year-grid heatmap. One column per ISO week, one row per\n * weekday — cells coloured by `value` relative to the data set's max.\n *\n * @example\n * ```html\n * <wr-calendar-heatmap [data]=\"contributions\" />\n * <wr-calendar-heatmap [data]=\"data\" [endDate]=\"today\" [weeks]=\"26\" color=\"#10b981\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar-heatmap\n */\n@Component({\n selector: 'wr-calendar-heatmap',\n templateUrl: './calendar-heatmap.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-calendar-heatmap' },\n})\nexport class WrCalendarHeatmap {\n readonly data = input<readonly WrHeatmapDatum[]>([]);\n\n /**\n * Accessible name of the whole grid. Its cells are bare spans whose `title` a screen\n * reader on a role-less element does not read, so the map used to be several hundred\n * anonymous nodes with no name. Falls back to `calendarHeatmap.label`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'calendarHeatmap.label', 'Calendar heatmap');\n\n private readonly cellText = useI18nFormatter('calendarHeatmap.cell', '{{date}}: {{count}}');\n\n /**\n * A cell's tooltip, with both halves formatted and the sentence in the catalog.\n *\n * It used to be `` `${cell.iso}: ${cell.value}` `` — a raw ISO date beside an\n * unformatted number, joined by a hard-coded `': '`. Three things were wrong\n * at once and none of them are visible from the template: `2026-09-10` is not\n * how most of the world writes a date, `1234` is not how every locale groups\n * digits (`ar-SA` does not even use these ones), and the separator and order\n * were frozen into a shape a translator could not reach.\n *\n * Both halves go through `Intl` on the SAME locale the rest of the component\n * resolves — `WR_DATE_LOCALE`, which since v14 follows Angular's `LOCALE_ID`.\n * The key ships as `{{date}}: {{count}}` everywhere, so nothing reorders today\n * and every locale can.\n */\n protected cellTitle(cell: { readonly date: Date; readonly value: number }): string {\n return this.cellText({\n date: new Intl.DateTimeFormat(this.locale, { dateStyle: 'medium' }).format(cell.date),\n count: new Intl.NumberFormat(this.locale).format(cell.value),\n });\n }\n\n /** Last day to render. @default today */\n readonly endDate = input<string | Date | null>(null);\n\n /** Number of weeks (columns) to render. @default 53 */\n readonly weeks = input(53, { transform: (v: unknown): number => Math.max(4, coerceNumberProperty(v, 53)) });\n\n /** Cell side in CSS pixels. @default 11 */\n readonly cellSize = input(11, { transform: (v: unknown): number => Math.max(4, coerceNumberProperty(v, 11)) });\n\n /** Pixel gap between cells. @default 2 */\n readonly cellGap = input(2, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 2)) });\n\n /** Cell fill colour at full intensity. @default primary */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /** Background colour for zero-value days. @default light tint */\n readonly emptyColor = input<string>('rgba(var(--wr-color-light-rgb), 0.5)');\n\n /** Show the weekday + month labels around the grid. @default true */\n readonly showLabels = input(true, { transform: coerceBooleanProperty });\n\n private readonly locale = inject(WR_DATE_LOCALE);\n\n /**\n * Weekday names from the locale rather than a hard-coded English list — the row order is\n * Sunday-first, matching the grid's own alignment, so 7 Jan 2024 (a Sunday) is the\n * reference. Rows without a label stay blank on purpose: seven labels do not fit.\n */\n protected readonly weekdayLabels = computed<readonly string[]>(() => {\n const formatter = new Intl.DateTimeFormat(this.locale, { weekday: 'short' });\n const sunday = new Date(2024, 0, 7);\n return Array.from({ length: 7 }, (_, row) => {\n if (!LABELLED_ROWS.has(row)) return '';\n const day = new Date(sunday);\n day.setDate(sunday.getDate() + row);\n return formatter.format(day);\n });\n });\n\n private readonly monthNames = computed<readonly string[]>(() => {\n const formatter = new Intl.DateTimeFormat(this.locale, { month: 'short' });\n return Array.from({ length: 12 }, (_, month) => formatter.format(new Date(2024, month, 15)));\n });\n\n protected readonly cells = computed<readonly Cell[]>(() => {\n const end = this.endDate() ? parseInput(this.endDate()!) : new Date();\n end.setHours(0, 0, 0, 0);\n const weeks = this.weeks();\n const totalDays = weeks * 7;\n\n // Build value lookup.\n const map = new Map<string, number>();\n for (const d of this.data()) {\n const iso = toIso(parseInput(d.date));\n map.set(iso, (map.get(iso) ?? 0) + amount(d.value));\n }\n const max = [...map.values()].reduce((a, b) => Math.max(a, b), 0);\n\n // Walk backwards from end day; arrange into columns by week, rows by weekday.\n const out: Cell[] = [];\n const start = new Date(end);\n start.setDate(end.getDate() - totalDays + 1);\n // Align start so column 0 begins on a Sunday (matches GitHub).\n start.setDate(start.getDate() - start.getDay());\n\n const cursor = new Date(start);\n let column = 0;\n while (cursor <= end) {\n for (let row = 0; row < 7; row++) {\n const iso = toIso(cursor);\n const value = map.get(iso) ?? 0;\n // Clamped at the BOTTOM as well as the top. A negative value produced a\n // negative intensity, which is not zero — so `colorFor` painted it in\n // the accent colour and `opacityFor` put it in the lightest band,\n // rendering a day of negative activity exactly like a day of light\n // activity, and unlike the empty day it should have matched. The scale\n // has no negative half; the honest floor is \"nothing\".\n const intensity = max > 0 ? Math.min(1, Math.max(0, value / max)) : 0;\n out.push({ iso, date: new Date(cursor), value, intensity, week: column, day: row });\n cursor.setDate(cursor.getDate() + 1);\n }\n column++;\n }\n return out;\n });\n\n protected readonly monthLabels = computed(() => {\n // Pull the first cell of each visible month → render a label centered\n // over its column.\n const cells = this.cells();\n const seen = new Set<string>();\n return cells\n .filter(cell => {\n const date = new Date(`${cell.iso}T00:00:00`);\n if (date.getDate() !== 1) return false;\n const key = `${date.getFullYear()}-${date.getMonth()}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .map(cell => ({\n label: this.monthNames()[new Date(`${cell.iso}T00:00:00`).getMonth()],\n week: cell.week,\n }));\n });\n\n protected readonly columnCount = computed(() => {\n const cells = this.cells();\n return cells.length === 0 ? 0 : cells[cells.length - 1].week + 1;\n });\n\n protected colorFor(intensity: number): string {\n if (intensity === 0) return this.emptyColor();\n return this.color();\n }\n\n protected opacityFor(intensity: number): number {\n if (intensity === 0) return 1;\n // 4 levels — match the GitHub aesthetic.\n if (intensity < 0.25) return 0.25;\n if (intensity < 0.5) return 0.5;\n if (intensity < 0.75) return 0.75;\n return 1;\n }\n}\n\nexport type { WrHeatmapDatum } from './interfaces';\n","<div\n class=\"wr-calendar-heatmap__grid\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.--wr-heatmap-cell-size.px]=\"cellSize()\"\n [style.--wr-heatmap-cell-gap.px]=\"cellGap()\"\n [style.--wr-heatmap-columns]=\"columnCount()\"\n>\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__weekdays\">\n @for (label of weekdayLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__weekday\">{{ label }}</span>\n }\n </div>\n }\n\n <div class=\"wr-calendar-heatmap__cells\">\n @for (cell of cells(); track cell.iso) {\n <span\n class=\"wr-calendar-heatmap__cell\"\n [style.background]=\"colorFor(cell.intensity)\"\n [style.opacity]=\"opacityFor(cell.intensity)\"\n [style.grid-column]=\"cell.week + 1\"\n [style.grid-row]=\"cell.day + 1\"\n [title]=\"cellTitle(cell)\"\n [attr.data-date]=\"cell.iso\"\n [attr.data-value]=\"cell.value\"\n aria-hidden=\"true\"\n ></span>\n }\n </div>\n\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__months\">\n @for (m of monthLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__month\" [style.grid-column]=\"m.week + 1\">{{ m.label }}</span>\n }\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngwr-calendar-heatmap.mjs","sources":["../../../projects/lib/calendar-heatmap/calendar-heatmap.ts","../../../projects/lib/calendar-heatmap/calendar-heatmap.html","../../../projects/lib/calendar-heatmap/ngwr-calendar-heatmap.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, type ElementRef, ViewEncapsulation, computed, inject, input, viewChild } from '@angular/core';\n\nimport { WR_DATE_LOCALE } from 'ngwr/date';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\nimport { useChartTooltip } from 'ngwr/popover';\n\nimport type { WrHeatmapDatum } from './interfaces';\n\ninterface Cell {\n readonly iso: string;\n /** The day as the reader's locale writes it — see `cellTitle`. */\n readonly date: Date;\n readonly value: number;\n readonly intensity: number;\n readonly week: number;\n readonly day: number;\n}\n\nfunction toIso(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n}\n\nfunction parseInput(value: string | Date): Date {\n return value instanceof Date ? new Date(value) : new Date(`${value}T00:00:00`);\n}\n\n/** Which rows carry a weekday label: three of seven, or they do not fit. */\nconst LABELLED_ROWS = new Set([1, 3, 5]);\n\n/**\n * A day's contribution, with anything non-finite read as `0`.\n *\n * One `NaN` used to flatten the entire rendered window rather than its own day:\n * `Math.max(a, NaN)` is `NaN`, so the data set's maximum became `NaN`, `max > 0`\n * was false, and every cell fell to intensity 0 — a map that reads as a stretch\n * with no activity at all. The bad day also printed the literal text `NaN` in its\n * `title`.\n */\nfunction amount(raw: number): number {\n return Number.isFinite(raw) ? raw : 0;\n}\n\n/**\n * GitHub-style year-grid heatmap. One column per ISO week, one row per\n * weekday — cells coloured by `value` relative to the data set's max.\n *\n * @example\n * ```html\n * <wr-calendar-heatmap [data]=\"contributions\" />\n * <wr-calendar-heatmap [data]=\"data\" [endDate]=\"today\" [weeks]=\"26\" color=\"#10b981\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar-heatmap\n */\n@Component({\n selector: 'wr-calendar-heatmap',\n templateUrl: './calendar-heatmap.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-calendar-heatmap' },\n})\nexport class WrCalendarHeatmap {\n readonly data = input<readonly WrHeatmapDatum[]>([]);\n\n /**\n * Accessible name of the whole grid. Its cells are bare spans whose `title` a screen\n * reader on a role-less element does not read, so the map used to be several hundred\n * anonymous nodes with no name. Falls back to `calendarHeatmap.label`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'calendarHeatmap.label', 'Calendar heatmap');\n\n private readonly cellText = useI18nFormatter('calendarHeatmap.cell', '{{date}}: {{count}}');\n\n /**\n * A cell's tooltip, with both halves formatted and the sentence in the catalog.\n *\n * It used to be `` `${cell.iso}: ${cell.value}` `` — a raw ISO date beside an\n * unformatted number, joined by a hard-coded `': '`. Three things were wrong\n * at once and none of them are visible from the template: `2026-09-10` is not\n * how most of the world writes a date, `1234` is not how every locale groups\n * digits (`ar-SA` does not even use these ones), and the separator and order\n * were frozen into a shape a translator could not reach.\n *\n * Both halves go through `Intl` on the SAME locale the rest of the component\n * resolves — `WR_DATE_LOCALE`, which since v14 follows Angular's `LOCALE_ID`.\n * The key ships as `{{date}}: {{count}}` everywhere, so nothing reorders today\n * and every locale can.\n */\n protected cellTitle(cell: { readonly date: Date; readonly value: number }): string {\n return this.cellText({\n date: new Intl.DateTimeFormat(this.locale, { dateStyle: 'medium' }).format(cell.date),\n count: new Intl.NumberFormat(this.locale).format(cell.value),\n });\n }\n\n /** Last day to render. @default today */\n readonly endDate = input<string | Date | null>(null);\n\n /** Number of weeks (columns) to render. @default 53 */\n readonly weeks = input(53, { transform: (v: unknown): number => Math.max(4, coerceNumberProperty(v, 53)) });\n\n /** Cell side in CSS pixels. @default 11 */\n readonly cellSize = input(11, { transform: (v: unknown): number => Math.max(4, coerceNumberProperty(v, 11)) });\n\n /** Pixel gap between cells. @default 2 */\n readonly cellGap = input(2, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 2)) });\n\n /** Cell fill colour at full intensity. @default primary */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /** Background colour for zero-value days. @default light tint */\n readonly emptyColor = input<string>('rgba(var(--wr-color-light-rgb), 0.5)');\n\n /** Show the weekday + month labels around the grid. @default true */\n readonly showLabels = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Show a tooltip with the day and its count on hover. It is the sentence the\n * square's `title` carried, so the `title` is written only while this is off —\n * or the browser would open a second copy a moment later. @default true\n */\n readonly tooltip = input(true, { transform: coerceBooleanProperty });\n\n private readonly daysEl = viewChild<ElementRef<HTMLElement>>('days');\n\n private readonly locale = inject(WR_DATE_LOCALE);\n\n /**\n * Weekday names from the locale rather than a hard-coded English list — the row order is\n * Sunday-first, matching the grid's own alignment, so 7 Jan 2024 (a Sunday) is the\n * reference. Rows without a label stay blank on purpose: seven labels do not fit.\n */\n protected readonly weekdayLabels = computed<readonly string[]>(() => {\n const formatter = new Intl.DateTimeFormat(this.locale, { weekday: 'short' });\n const sunday = new Date(2024, 0, 7);\n return Array.from({ length: 7 }, (_, row) => {\n if (!LABELLED_ROWS.has(row)) return '';\n const day = new Date(sunday);\n day.setDate(sunday.getDate() + row);\n return formatter.format(day);\n });\n });\n\n private readonly monthNames = computed<readonly string[]>(() => {\n const formatter = new Intl.DateTimeFormat(this.locale, { month: 'short' });\n return Array.from({ length: 12 }, (_, month) => formatter.format(new Date(2024, month, 15)));\n });\n\n protected readonly cells = computed<readonly Cell[]>(() => {\n const end = this.endDate() ? parseInput(this.endDate()!) : new Date();\n end.setHours(0, 0, 0, 0);\n const weeks = this.weeks();\n const totalDays = weeks * 7;\n\n // Build value lookup.\n const map = new Map<string, number>();\n for (const d of this.data()) {\n const iso = toIso(parseInput(d.date));\n map.set(iso, (map.get(iso) ?? 0) + amount(d.value));\n }\n const max = [...map.values()].reduce((a, b) => Math.max(a, b), 0);\n\n // Walk backwards from end day; arrange into columns by week, rows by weekday.\n const out: Cell[] = [];\n const start = new Date(end);\n start.setDate(end.getDate() - totalDays + 1);\n // Align start so column 0 begins on a Sunday (matches GitHub).\n start.setDate(start.getDate() - start.getDay());\n\n const cursor = new Date(start);\n let column = 0;\n while (cursor <= end) {\n for (let row = 0; row < 7; row++) {\n const iso = toIso(cursor);\n const value = map.get(iso) ?? 0;\n // Clamped at the BOTTOM as well as the top. A negative value produced a\n // negative intensity, which is not zero — so `colorFor` painted it in\n // the accent colour and `opacityFor` put it in the lightest band,\n // rendering a day of negative activity exactly like a day of light\n // activity, and unlike the empty day it should have matched. The scale\n // has no negative half; the honest floor is \"nothing\".\n const intensity = max > 0 ? Math.min(1, Math.max(0, value / max)) : 0;\n out.push({ iso, date: new Date(cursor), value, intensity, week: column, day: row });\n cursor.setDate(cursor.getDate() + 1);\n }\n column++;\n }\n return out;\n });\n\n protected readonly monthLabels = computed(() => {\n // Pull the first cell of each visible month → render a label centered\n // over its column.\n const cells = this.cells();\n const seen = new Set<string>();\n return cells\n .filter(cell => {\n const date = new Date(`${cell.iso}T00:00:00`);\n if (date.getDate() !== 1) return false;\n const key = `${date.getFullYear()}-${date.getMonth()}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .map(cell => ({\n label: this.monthNames()[new Date(`${cell.iso}T00:00:00`).getMonth()],\n week: cell.week,\n }));\n });\n\n protected readonly columnCount = computed(() => {\n const cells = this.cells();\n return cells.length === 0 ? 0 : cells[cells.length - 1].week + 1;\n });\n\n /** Each day's position in `cells()`, for the square the pointer lands on. */\n private readonly indexByIso = computed(() => new Map(this.cells().map((cell, index) => [cell.iso, index])));\n\n /**\n * One tooltip for the whole year, pointing at the hovered day: above its square,\n * below it when there is no room above, and slid along the viewport edge for the\n * first and last weeks with the arrow still on the square. A listener on the grid\n * rather than one per square: a year is 371 of them.\n *\n * The box is the square's LAYOUT box rather than its client rect. The hovered square\n * grows by `:hover` over a transition, and a rect read part way through it would\n * move the chip by up to a fifth of a square depending on when it was measured;\n * the scale is centred, so the layout box is the rect's centre and the square's\n * own size.\n */\n protected readonly tip = useChartTooltip(this.tooltip, index => {\n const cell = this.cells()[index];\n // The squares are the container's only children, drawn in `cells()` order.\n const square = cell ? this.daysEl()?.nativeElement.children.item(index) : null;\n if (!cell || !(square instanceof HTMLElement)) return null;\n const rect = square.getBoundingClientRect();\n const width = square.offsetWidth;\n const height = square.offsetHeight;\n return {\n datum: { value: this.cellTitle(cell) },\n anchor: {\n x: (rect.left + rect.right - width) / 2,\n y: (rect.top + rect.bottom - height) / 2,\n width,\n height,\n },\n };\n });\n\n /**\n * Which square the pointer is on, from a `mousemove` on the grid. Over the gap\n * between two squares it is on none, and the tooltip starts to leave.\n */\n protected onCellsPointer(event: MouseEvent): void {\n const iso = (event.target as Element | null)?.closest<HTMLElement>('.wr-calendar-heatmap__cell')?.dataset['date'];\n const index = iso === undefined ? undefined : this.indexByIso().get(iso);\n if (index === undefined) this.tip.leave(event);\n else this.tip.enter(index);\n }\n\n protected colorFor(intensity: number): string {\n if (intensity === 0) return this.emptyColor();\n return this.color();\n }\n\n protected opacityFor(intensity: number): number {\n if (intensity === 0) return 1;\n // 4 levels — match the GitHub aesthetic.\n if (intensity < 0.25) return 0.25;\n if (intensity < 0.5) return 0.5;\n if (intensity < 0.75) return 0.75;\n return 1;\n }\n}\n\nexport type { WrHeatmapDatum } from './interfaces';\n","<div\n class=\"wr-calendar-heatmap__grid\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.--wr-heatmap-cell-size.px]=\"cellSize()\"\n [style.--wr-heatmap-cell-gap.px]=\"cellGap()\"\n [style.--wr-heatmap-columns]=\"columnCount()\"\n>\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__weekdays\">\n @for (label of weekdayLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__weekday\">{{ label }}</span>\n }\n </div>\n }\n\n <div #days class=\"wr-calendar-heatmap__cells\" (mousemove)=\"onCellsPointer($event)\" (mouseleave)=\"tip.leave($event)\">\n @for (cell of cells(); track cell.iso) {\n <span\n class=\"wr-calendar-heatmap__cell\"\n [style.background]=\"colorFor(cell.intensity)\"\n [style.opacity]=\"opacityFor(cell.intensity)\"\n [style.grid-column]=\"cell.week + 1\"\n [style.grid-row]=\"cell.day + 1\"\n [attr.title]=\"tooltip() ? null : cellTitle(cell)\"\n [attr.data-date]=\"cell.iso\"\n [attr.data-value]=\"cell.value\"\n aria-hidden=\"true\"\n ></span>\n }\n </div>\n\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__months\">\n @for (m of monthLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__month\" [style.grid-column]=\"m.week + 1\">{{ m.label }}</span>\n }\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -406,11 +406,11 @@ class WrCascader {
|
|
|
406
406
|
this.host.nativeElement.querySelector('.wr-cascader__trigger')?.focus();
|
|
407
407
|
}
|
|
408
408
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCascader, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
409
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrCascader, isStandalone: true, selector: "wr-cascader", inputs: { clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, changeOnSelect: { classPropertyName: "changeOnSelect", publicName: "changeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "panelTpl", first: true, predicate: ["panelTpl"], descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\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 \u2014 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 \u2014 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 \u2014 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 \u2014 each column IS a complete sibling set \u2014 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", 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-col-width: 12rem;--wr-cascader-max-height: 16rem;--wr-cascader-min-width: 12rem;display:inline-flex;vertical-align:middle}.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:var(--wr-cascader-min-width);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}.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;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wr-cascader__placeholder{color:var(--wr-color-text-muted)}.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;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)}.wr-cascader-overlay{padding-top:.25rem}.wr-cascader-panel{--wr-cascader-opt-font: var(--wr-control-font-size-md);--wr-cascader-opt-py: .5rem;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, 12rem);max-height:var(--wr-cascader-max-height, 16rem);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__clear{width:2rem;height:2rem}.wr-cascader-panel .wr-cascader__opt{padding-top:.75rem;padding-bottom:.75rem}}\n"], encapsulation: i0.ViewEncapsulation.None });
|
|
409
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrCascader, isStandalone: true, selector: "wr-cascader", inputs: { clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, changeOnSelect: { classPropertyName: "changeOnSelect", publicName: "changeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "panelTpl", first: true, predicate: ["panelTpl"], descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\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 \u2014 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 \u2014 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 \u2014 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 \u2014 each column IS a complete sibling set \u2014 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", 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-col-width: 12rem;--wr-cascader-max-height: 16rem;--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-text-muted)}.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;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, 12rem);max-height:var(--wr-cascader-max-height, 16rem);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"], encapsulation: i0.ViewEncapsulation.None });
|
|
410
410
|
}
|
|
411
411
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCascader, decorators: [{
|
|
412
412
|
type: Component,
|
|
413
|
-
args: [{ selector: 'wr-cascader', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\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 \u2014 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 \u2014 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 \u2014 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 \u2014 each column IS a complete sibling set \u2014 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", 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-col-width: 12rem;--wr-cascader-max-height: 16rem;--wr-cascader-min-width: 12rem;display:inline-flex;vertical-align:middle}.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:var(--wr-cascader-min-width);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}.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;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wr-cascader__placeholder{color:var(--wr-color-text-muted)}.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;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)}.wr-cascader-overlay{padding-top:.25rem}.wr-cascader-panel{--wr-cascader-opt-font: var(--wr-control-font-size-md);--wr-cascader-opt-py: .5rem;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, 12rem);max-height:var(--wr-cascader-max-height, 16rem);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__clear{width:2rem;height:2rem}.wr-cascader-panel .wr-cascader__opt{padding-top:.75rem;padding-bottom:.75rem}}\n"] }]
|
|
413
|
+
args: [{ selector: 'wr-cascader', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\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 \u2014 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 \u2014 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 \u2014 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 \u2014 each column IS a complete sibling set \u2014 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", 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-col-width: 12rem;--wr-cascader-max-height: 16rem;--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-text-muted)}.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;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, 12rem);max-height:var(--wr-cascader-max-height, 16rem);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"] }]
|
|
414
414
|
}], ctorParameters: () => [], propDecorators: { clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], changeOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "changeOnSelect", required: false }] }], separator: [{ type: i0.Input, args: [{ isSignal: true, alias: "separator", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touch: [{ type: i0.Output, args: ["touch"] }], panelTpl: [{ type: i0.ViewChild, args: ['panelTpl', { ...{ read: TemplateRef }, isSignal: true }] }] } });
|
|
415
415
|
|
|
416
416
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-cascader.mjs","sources":["../../../projects/lib/cascader/cascader.ts","../../../projects/lib/cascader/cascader.html","../../../projects/lib/cascader/ngwr-cascader.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n TemplateRef,\n ViewContainerRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { useFormFieldAria } from 'ngwr/form';\nimport { useI18nText } from 'ngwr/i18n';\nimport { WR_OVERLAY, WrOutsideClick, wrFollowDirection } from 'ngwr/overlay';\n\nimport type { WrCascaderOption } from './interfaces';\n\nlet panelUid = 0;\n\n/**\n * Multi-level select — drills down through hierarchical categories\n * (e.g. country → state → city). Each level renders as a column; clicks\n * advance to the next column. Selecting a leaf (no children) commits\n * the full path.\n *\n * A signal-forms native control: it implements `FormValueControl<unknown>`,\n * so `[formField]` binds straight to its `value` model — no\n * `ControlValueAccessor` in between. `[(value)]` works standalone. The value\n * is the path through the tree (an array from root to leaf).\n *\n * @example\n * ```html\n * <!-- signal forms -->\n * <wr-cascader [options]=\"locations\" [formField]=\"form.path\" placeholder=\"Pick a location\" />\n *\n * <!-- standalone two-way binding -->\n * <wr-cascader [options]=\"locations\" [(value)]=\"path\" placeholder=\"Pick a location\" />\n * ```\n *\n * ```ts\n * locations: WrCascaderOption[] = [\n * {\n * value: 'us', label: 'United States', children: [\n * { value: 'ny', label: 'New York', children: [\n * { value: 'nyc', label: 'NYC' },\n * { value: 'buf', label: 'Buffalo' },\n * ] },\n * ],\n * },\n * ];\n * ```\n *\n * @see https://ngwr.dev/reference/components/cascader\n */\nexport type WrCascaderSize = 'sm' | 'md' | 'lg';\n\n@Component({\n selector: 'wr-cascader',\n templateUrl: './cascader.html',\n styleUrl: './cascader.scss',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrCascader<T = string> implements FormValueControl<unknown> {\n /** Accessible name. Falls back to `select.clearSelection`, then `'Clear selection'`. */\n readonly clearLabel = input<string | null>(null);\n\n protected readonly resolvedClearLabel = useI18nText(this.clearLabel, 'select.clearSelection', 'Clear selection');\n\n /** Root-level options. Each may have `children` for deeper levels. */\n readonly options = input.required<readonly WrCascaderOption<T>[]>();\n\n /** Placeholder shown when no path is selected. @default '' */\n readonly placeholder = input<string>('');\n\n /**\n * Accessible name of the trigger. Falls back to the placeholder, then to\n * `select.label` — a `role=\"combobox\"` with nothing selected and no\n * placeholder otherwise has no name at all.\n */\n readonly ariaLabel = input<string | null>(null);\n\n private readonly labelText = useI18nText(this.ariaLabel, 'select.label', 'Select');\n protected readonly resolvedAriaLabel = computed(() => {\n // Not `??`: an empty placeholder must fall through to the catalog string.\n const explicit = this.ariaLabel();\n if (explicit) return explicit;\n const placeholder = this.placeholder();\n return placeholder ? placeholder : this.labelText();\n });\n\n /**\n * Disable the cascader. Bound automatically from the field's disabled state\n * when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Refuse changes while the trigger stays focusable and the path still submits.\n * Bound automatically from the field's readonly state when used with\n * `[formField]`.\n *\n * The panel is where every edit happens, so a read-only cascader simply does\n * not open — there is nothing to browse that is not already on the trigger —\n * and the clear button goes away with it. Mirrored as `aria-readonly`, which\n * role `combobox` supports.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /** The surrounding `<wr-form-field>`'s error state. @internal */\n protected readonly fieldAria = useFormFieldAria();\n\n /** Control size — shares the `--wr-control-*` contract. @default 'md' */\n readonly size = input<WrCascaderSize>('md');\n\n /** Show a clear-all (×) button on the trigger when a path is selected. @default true */\n readonly clearable = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Allow selecting non-leaf (parent) nodes. When `false`, only leaves\n * (nodes without children) commit a selection. @default false\n */\n readonly changeOnSelect = input(false, { transform: coerceBooleanProperty });\n\n /** Separator between labels in the trigger display. @default '/' */\n readonly separator = input<string>('/');\n\n /**\n * Committed selection path (full array from root to leaf). Bound by\n * `[formField]`, or two-way via `[(value)]`.\n */\n readonly value = model<unknown>([]);\n\n /** Emitted on blur / commit so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n /** Committed selection path (full T[] from root to leaf). @internal */\n protected readonly path = signal<readonly T[]>([]);\n\n /** Currently-expanded column path — drives which columns the panel shows. @internal */\n protected readonly activePath = signal<readonly T[]>([]);\n\n protected readonly open = signal(false);\n\n /** Panel id used by the trigger's `aria-controls`. */\n protected readonly panelId = `wr-cascader-panel-${++panelUid}`;\n\n /**\n * Columns visible in the panel. Each column shows the children of the\n * preceding activePath entry. Column 0 = root options. The last\n * column is whatever the deepest active node's children resolve to —\n * we only render a column when there are children to show.\n */\n protected readonly columns = computed<readonly (readonly WrCascaderOption<T>[])[]>(() => {\n const cols: (readonly WrCascaderOption<T>[])[] = [this.options()];\n const trail = this.activePath();\n let list: readonly WrCascaderOption<T>[] = this.options();\n for (const v of trail) {\n const node = list.find(o => o.value === v);\n if (!node?.children?.length) break;\n cols.push(node.children);\n list = node.children;\n }\n return cols;\n });\n\n /** Label trail joined by `separator()` — what the trigger shows. */\n protected readonly displayLabel = computed(() => {\n const p = this.path();\n if (p.length === 0) return null;\n const labels: string[] = [];\n let list: readonly WrCascaderOption<T>[] = this.options();\n for (const v of p) {\n const node = list.find(o => o.value === v);\n if (!node) return null;\n labels.push(node.label);\n list = node.children ?? [];\n }\n const sep = ` ${this.separator()} `;\n return labels.join(sep);\n });\n\n protected readonly hasSelection = computed(() => this.path().length > 0);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-cascader'];\n const size = this.size();\n if (size !== 'md') parts.push(`wr-cascader--${size}`);\n if (this.open()) parts.push('wr-cascader--open');\n if (this.disabled()) parts.push('wr-cascader--disabled');\n else if (this.readonly()) parts.push('wr-cascader--readonly');\n return parts.join(' ');\n });\n\n protected readonly panelTpl = viewChild.required('panelTpl', { read: TemplateRef });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly outsideClick = inject(WrOutsideClick);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly destroyRef = inject(DestroyRef);\n private readonly injector = inject(Injector);\n /**\n * Ambient reading direction, for the open panel alone — nothing in this\n * component reads it directly. Optional so a bare `TestBed` needs no\n * provider; `Directionality` is root-provided anyway, and a missing one\n * simply reads as `ltr`.\n */\n private readonly dir = inject(Directionality, { optional: true });\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n // Same contract as wr-select / wr-dropdown / wr-lightbox: an overlay lives in\n // the CDK container, not in this component's view, so destroying the\n // component while the panel is open would strand the pane and its scroll\n // strategy.\n this.destroyRef.onDestroy(() => this.closeOverlay());\n\n effect(() => {\n if (this.open()) {\n this.openOverlay();\n } else {\n this.closeOverlay();\n }\n });\n\n // Close the panel if the control becomes disabled or read-only while open.\n effect(() => {\n if (this.disabled() || this.readonly()) this.open.set(false);\n });\n\n // Mirror an external `value` write into the internal path/activePath\n // (the old `writeValue`). Skipped when the write merely echoes the\n // committed path, so a live drill-down can never be clobbered.\n effect(() => {\n // Coerce null/undefined/non-array to an empty path — a classic-forms\n // binding can write null, which the old `writeValue(value: unknown)`\n // treated as \"no selection\" too.\n const value = this.value();\n untracked(() => {\n const next: readonly T[] = Array.isArray(value) ? (value as readonly T[]) : [];\n if (this.pathsEqual(this.path(), next)) return;\n this.path.set(next);\n this.activePath.set(next);\n });\n });\n }\n\n // Template handlers\n\n protected onTriggerClick(): void {\n if (this.disabled() || this.readonly()) return;\n if (!this.open()) this.activePath.set(this.path());\n this.open.update(v => !v);\n }\n\n /**\n * ArrowDown / ArrowUp open the panel, Alt+ArrowDown included — the combobox way in,\n * and the shape `wr-dropdown`'s trigger uses. Enter and Space need no branch: the\n * trigger is a real `<button>`, so the browser turns them into the click above.\n *\n * Only while closed. Once the panel is up the caret is inside it, and its options\n * own their own keys.\n */\n protected onTriggerKeydown(event: KeyboardEvent): void {\n if (this.disabled() || this.readonly() || this.open()) return;\n\n // Backspace is the × from the keyboard, and it has to be: the × is a\n // `tabindex=\"-1\"` span INSIDE this button, and a keydown goes to the focused\n // element, so the `(keydown.enter)` / `(keydown.space)` it used to carry could\n // never fire. Clearing was reachable by pointer alone — a WCAG 2.1.1 failure,\n // not a missing convenience. The span stays unfocusable, because a focusable\n // child of a button is `nested-interactive`. Same key, same gating as\n // `wr-select`: `clearable()` IS the clear control, so a consumer who turned\n // the × off did not ask for a keyboard twin of it.\n if (event.key === 'Backspace') {\n if (!this.clearable() || !this.hasSelection()) return;\n event.preventDefault();\n this.clearSelection(event);\n return;\n }\n\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;\n event.preventDefault();\n this.activePath.set(this.path());\n this.open.set(true);\n }\n\n protected onOptionClick(colIndex: number, opt: WrCascaderOption<T>, event: Event): void {\n event.stopPropagation();\n if (opt.disabled || this.disabled() || this.readonly()) return;\n\n const head = this.activePath().slice(0, colIndex);\n const newPath = [...head, opt.value];\n\n const hasChildren = !!opt.children?.length;\n\n // Always update active column for visual feedback / next column.\n this.activePath.set(newPath);\n\n // Commit when we've reached a leaf, or when changeOnSelect is on.\n if (!hasChildren || this.changeOnSelect()) {\n this.path.set(newPath);\n this.value.set(newPath);\n this.touch.emit();\n // Close once we hit a true leaf — parent commits keep the panel open.\n if (!hasChildren) this.open.set(false);\n }\n }\n\n protected clearSelection(event: Event): void {\n event.stopPropagation();\n if (this.disabled() || this.readonly()) return;\n this.path.set([]);\n this.activePath.set([]);\n this.value.set([]);\n this.touch.emit();\n }\n\n protected isActiveAt(colIndex: number, value: T): boolean {\n return this.activePath()[colIndex] === value;\n }\n\n /**\n * Whether this option is the committed choice — `null` when it is not a\n * choice at all.\n *\n * Two questions the panel has to keep apart, and `--active` answers only the\n * first: `activePath()` is where the user has NAVIGATED to, `path()` is what\n * they have COMMITTED. They agree once a leaf is picked and diverge for the\n * whole walk down.\n *\n * `null` — the attribute absent — on a branch while `changeOnSelect` is off,\n * because such a branch genuinely cannot be chosen; ARIA reads a missing\n * `aria-selected` as \"not selectable\", which is exactly true here. That makes\n * this binding the first expression the `changeOnSelect` contract has ever had\n * in ARIA, in both directions.\n */\n protected isSelectedAt(colIndex: number, opt: WrCascaderOption<T>): boolean | null {\n const committable = !opt.children?.length || this.changeOnSelect();\n if (!committable) return null;\n const path = this.path();\n return colIndex === path.length - 1 && path[colIndex] === opt.value;\n }\n\n /** Stable id for one option — what a column's `aria-labelledby` points at. */\n protected optionId(colIndex: number, optIndex: number): string {\n return `${this.panelId}-opt-${colIndex}-${optIndex}`;\n }\n\n /** Stable id for one column — what an expanded branch's `aria-controls` points at. */\n protected columnId(colIndex: number): string {\n return `${this.panelId}-col-${colIndex}`;\n }\n\n /**\n * The option whose children a column holds, by id — its accessible name.\n *\n * The columns are DOM SIBLINGS, so nothing in the markup says the second one\n * belongs to \"Europe\". Column 0 has no parent and stays unnamed; the tree\n * itself already carries the control's name.\n */\n protected parentOptionId(colIndex: number): string | null {\n if (colIndex === 0) return null;\n const parent = this.columns()[colIndex - 1] ?? [];\n const index = parent.findIndex(o => this.isActiveAt(colIndex - 1, o.value));\n return index < 0 ? null : this.optionId(colIndex - 1, index);\n }\n\n private pathsEqual(a: readonly T[], b: readonly T[]): boolean {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n }\n\n // Overlay\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n const positionStrategy = this.overlay\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions([\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },\n ])\n .withPush(true);\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.reposition(),\n panelClass: 'wr-cascader-overlay',\n });\n\n // The columns cascade inline-wards, and the CDK captured the direction as a\n // string when this ref was created — so a flip while the panel is open left\n // the whole cascade running the other way from the page around it.\n wrFollowDirection(this.overlayRef, this.dir, this.injector);\n\n const portal = new TemplatePortal(this.panelTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n // Move the caret into the panel it just opened. Nothing did, and the pane is\n // appended to `<body>`, so an opened cascader left focus on the trigger and its\n // options were reachable only by tabbing past the whole rest of the page —\n // `wr-tree` and `wr-context-menu` were the same defect. `closeOverlay` below\n // already assumes this is where the caret lives.\n //\n // `afterNextRender`, NOT `queueMicrotask`: under zoneless CD change detection runs\n // in a macrotask, so a microtask queued here fires before the columns are in the\n // DOM — the trap that once left `wr-calendar`'s ring and its real focus on\n // different days.\n afterNextRender(() => this.focusPanelOption(), { injector: this.injector });\n\n this.outsideClick\n .outsidePointerEvents(this.overlayRef)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (this.host.nativeElement.contains(event.target as Node)) return;\n this.open.set(false);\n });\n\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.open.set(false);\n }\n });\n }\n\n /**\n * The option the panel opens on: the selected one in the first column when there is\n * a selection, otherwise the first enabled root. A disabled option is skipped — it\n * still carries `tabindex=\"-1\"`, so `focus()` would land on it and answer for a\n * choice nobody can make.\n */\n private focusPanelOption(): void {\n const pane = this.overlayRef?.overlayElement;\n if (!pane) return;\n const option =\n pane.querySelector<HTMLElement>('.wr-cascader__opt--active:not(.wr-cascader__opt--disabled)') ??\n pane.querySelector<HTMLElement>('.wr-cascader__opt:not(.wr-cascader__opt--disabled)');\n option?.focus();\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n // Every enabled option carries `tabindex=\"0\"` and commits on Enter, so on\n // the keyboard the caret is INSIDE the pane by design — and the ordinary\n // way to finish choosing (`onOptionClick` on a leaf) closes it. Disposing\n // without handing focus back dropped it on `<body>` on the SUCCESS path,\n // not merely on dismissal: a keyboard user who had just picked a value then\n // had to Tab from the top of the document to get back to the control.\n // Untouched when focus had already moved elsewhere — that click is usually\n // what closed us, and stealing the caret back would fight the user for it.\n const pane = this.overlayRef.overlayElement;\n const focusWasInside = pane.contains(this.host.nativeElement.ownerDocument.activeElement);\n this.overlayRef.dispose();\n this.overlayRef = null;\n if (focusWasInside) this.host.nativeElement.querySelector<HTMLElement>('.wr-cascader__trigger')?.focus();\n }\n}\n\nexport type { WrCascaderOption } from './interfaces';\n","<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngwr-cascader.mjs","sources":["../../../projects/lib/cascader/cascader.ts","../../../projects/lib/cascader/cascader.html","../../../projects/lib/cascader/ngwr-cascader.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n TemplateRef,\n ViewContainerRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { useFormFieldAria } from 'ngwr/form';\nimport { useI18nText } from 'ngwr/i18n';\nimport { WR_OVERLAY, WrOutsideClick, wrFollowDirection } from 'ngwr/overlay';\n\nimport type { WrCascaderOption } from './interfaces';\n\nlet panelUid = 0;\n\n/**\n * Multi-level select — drills down through hierarchical categories\n * (e.g. country → state → city). Each level renders as a column; clicks\n * advance to the next column. Selecting a leaf (no children) commits\n * the full path.\n *\n * A signal-forms native control: it implements `FormValueControl<unknown>`,\n * so `[formField]` binds straight to its `value` model — no\n * `ControlValueAccessor` in between. `[(value)]` works standalone. The value\n * is the path through the tree (an array from root to leaf).\n *\n * @example\n * ```html\n * <!-- signal forms -->\n * <wr-cascader [options]=\"locations\" [formField]=\"form.path\" placeholder=\"Pick a location\" />\n *\n * <!-- standalone two-way binding -->\n * <wr-cascader [options]=\"locations\" [(value)]=\"path\" placeholder=\"Pick a location\" />\n * ```\n *\n * ```ts\n * locations: WrCascaderOption[] = [\n * {\n * value: 'us', label: 'United States', children: [\n * { value: 'ny', label: 'New York', children: [\n * { value: 'nyc', label: 'NYC' },\n * { value: 'buf', label: 'Buffalo' },\n * ] },\n * ],\n * },\n * ];\n * ```\n *\n * @see https://ngwr.dev/reference/components/cascader\n */\nexport type WrCascaderSize = 'sm' | 'md' | 'lg';\n\n@Component({\n selector: 'wr-cascader',\n templateUrl: './cascader.html',\n styleUrl: './cascader.scss',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrCascader<T = string> implements FormValueControl<unknown> {\n /** Accessible name. Falls back to `select.clearSelection`, then `'Clear selection'`. */\n readonly clearLabel = input<string | null>(null);\n\n protected readonly resolvedClearLabel = useI18nText(this.clearLabel, 'select.clearSelection', 'Clear selection');\n\n /** Root-level options. Each may have `children` for deeper levels. */\n readonly options = input.required<readonly WrCascaderOption<T>[]>();\n\n /** Placeholder shown when no path is selected. @default '' */\n readonly placeholder = input<string>('');\n\n /**\n * Accessible name of the trigger. Falls back to the placeholder, then to\n * `select.label` — a `role=\"combobox\"` with nothing selected and no\n * placeholder otherwise has no name at all.\n */\n readonly ariaLabel = input<string | null>(null);\n\n private readonly labelText = useI18nText(this.ariaLabel, 'select.label', 'Select');\n protected readonly resolvedAriaLabel = computed(() => {\n // Not `??`: an empty placeholder must fall through to the catalog string.\n const explicit = this.ariaLabel();\n if (explicit) return explicit;\n const placeholder = this.placeholder();\n return placeholder ? placeholder : this.labelText();\n });\n\n /**\n * Disable the cascader. Bound automatically from the field's disabled state\n * when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Refuse changes while the trigger stays focusable and the path still submits.\n * Bound automatically from the field's readonly state when used with\n * `[formField]`.\n *\n * The panel is where every edit happens, so a read-only cascader simply does\n * not open — there is nothing to browse that is not already on the trigger —\n * and the clear button goes away with it. Mirrored as `aria-readonly`, which\n * role `combobox` supports.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /** The surrounding `<wr-form-field>`'s error state. @internal */\n protected readonly fieldAria = useFormFieldAria();\n\n /** Control size — shares the `--wr-control-*` contract. @default 'md' */\n readonly size = input<WrCascaderSize>('md');\n\n /** Show a clear-all (×) button on the trigger when a path is selected. @default true */\n readonly clearable = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Allow selecting non-leaf (parent) nodes. When `false`, only leaves\n * (nodes without children) commit a selection. @default false\n */\n readonly changeOnSelect = input(false, { transform: coerceBooleanProperty });\n\n /** Separator between labels in the trigger display. @default '/' */\n readonly separator = input<string>('/');\n\n /**\n * Committed selection path (full array from root to leaf). Bound by\n * `[formField]`, or two-way via `[(value)]`.\n */\n readonly value = model<unknown>([]);\n\n /** Emitted on blur / commit so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n /** Committed selection path (full T[] from root to leaf). @internal */\n protected readonly path = signal<readonly T[]>([]);\n\n /** Currently-expanded column path — drives which columns the panel shows. @internal */\n protected readonly activePath = signal<readonly T[]>([]);\n\n protected readonly open = signal(false);\n\n /** Panel id used by the trigger's `aria-controls`. */\n protected readonly panelId = `wr-cascader-panel-${++panelUid}`;\n\n /**\n * Columns visible in the panel. Each column shows the children of the\n * preceding activePath entry. Column 0 = root options. The last\n * column is whatever the deepest active node's children resolve to —\n * we only render a column when there are children to show.\n */\n protected readonly columns = computed<readonly (readonly WrCascaderOption<T>[])[]>(() => {\n const cols: (readonly WrCascaderOption<T>[])[] = [this.options()];\n const trail = this.activePath();\n let list: readonly WrCascaderOption<T>[] = this.options();\n for (const v of trail) {\n const node = list.find(o => o.value === v);\n if (!node?.children?.length) break;\n cols.push(node.children);\n list = node.children;\n }\n return cols;\n });\n\n /** Label trail joined by `separator()` — what the trigger shows. */\n protected readonly displayLabel = computed(() => {\n const p = this.path();\n if (p.length === 0) return null;\n const labels: string[] = [];\n let list: readonly WrCascaderOption<T>[] = this.options();\n for (const v of p) {\n const node = list.find(o => o.value === v);\n if (!node) return null;\n labels.push(node.label);\n list = node.children ?? [];\n }\n const sep = ` ${this.separator()} `;\n return labels.join(sep);\n });\n\n protected readonly hasSelection = computed(() => this.path().length > 0);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-cascader'];\n const size = this.size();\n if (size !== 'md') parts.push(`wr-cascader--${size}`);\n if (this.open()) parts.push('wr-cascader--open');\n if (this.disabled()) parts.push('wr-cascader--disabled');\n else if (this.readonly()) parts.push('wr-cascader--readonly');\n return parts.join(' ');\n });\n\n protected readonly panelTpl = viewChild.required('panelTpl', { read: TemplateRef });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly outsideClick = inject(WrOutsideClick);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly destroyRef = inject(DestroyRef);\n private readonly injector = inject(Injector);\n /**\n * Ambient reading direction, for the open panel alone — nothing in this\n * component reads it directly. Optional so a bare `TestBed` needs no\n * provider; `Directionality` is root-provided anyway, and a missing one\n * simply reads as `ltr`.\n */\n private readonly dir = inject(Directionality, { optional: true });\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n // Same contract as wr-select / wr-dropdown / wr-lightbox: an overlay lives in\n // the CDK container, not in this component's view, so destroying the\n // component while the panel is open would strand the pane and its scroll\n // strategy.\n this.destroyRef.onDestroy(() => this.closeOverlay());\n\n effect(() => {\n if (this.open()) {\n this.openOverlay();\n } else {\n this.closeOverlay();\n }\n });\n\n // Close the panel if the control becomes disabled or read-only while open.\n effect(() => {\n if (this.disabled() || this.readonly()) this.open.set(false);\n });\n\n // Mirror an external `value` write into the internal path/activePath\n // (the old `writeValue`). Skipped when the write merely echoes the\n // committed path, so a live drill-down can never be clobbered.\n effect(() => {\n // Coerce null/undefined/non-array to an empty path — a classic-forms\n // binding can write null, which the old `writeValue(value: unknown)`\n // treated as \"no selection\" too.\n const value = this.value();\n untracked(() => {\n const next: readonly T[] = Array.isArray(value) ? (value as readonly T[]) : [];\n if (this.pathsEqual(this.path(), next)) return;\n this.path.set(next);\n this.activePath.set(next);\n });\n });\n }\n\n // Template handlers\n\n protected onTriggerClick(): void {\n if (this.disabled() || this.readonly()) return;\n if (!this.open()) this.activePath.set(this.path());\n this.open.update(v => !v);\n }\n\n /**\n * ArrowDown / ArrowUp open the panel, Alt+ArrowDown included — the combobox way in,\n * and the shape `wr-dropdown`'s trigger uses. Enter and Space need no branch: the\n * trigger is a real `<button>`, so the browser turns them into the click above.\n *\n * Only while closed. Once the panel is up the caret is inside it, and its options\n * own their own keys.\n */\n protected onTriggerKeydown(event: KeyboardEvent): void {\n if (this.disabled() || this.readonly() || this.open()) return;\n\n // Backspace is the × from the keyboard, and it has to be: the × is a\n // `tabindex=\"-1\"` span INSIDE this button, and a keydown goes to the focused\n // element, so the `(keydown.enter)` / `(keydown.space)` it used to carry could\n // never fire. Clearing was reachable by pointer alone — a WCAG 2.1.1 failure,\n // not a missing convenience. The span stays unfocusable, because a focusable\n // child of a button is `nested-interactive`. Same key, same gating as\n // `wr-select`: `clearable()` IS the clear control, so a consumer who turned\n // the × off did not ask for a keyboard twin of it.\n if (event.key === 'Backspace') {\n if (!this.clearable() || !this.hasSelection()) return;\n event.preventDefault();\n this.clearSelection(event);\n return;\n }\n\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;\n event.preventDefault();\n this.activePath.set(this.path());\n this.open.set(true);\n }\n\n protected onOptionClick(colIndex: number, opt: WrCascaderOption<T>, event: Event): void {\n event.stopPropagation();\n if (opt.disabled || this.disabled() || this.readonly()) return;\n\n const head = this.activePath().slice(0, colIndex);\n const newPath = [...head, opt.value];\n\n const hasChildren = !!opt.children?.length;\n\n // Always update active column for visual feedback / next column.\n this.activePath.set(newPath);\n\n // Commit when we've reached a leaf, or when changeOnSelect is on.\n if (!hasChildren || this.changeOnSelect()) {\n this.path.set(newPath);\n this.value.set(newPath);\n this.touch.emit();\n // Close once we hit a true leaf — parent commits keep the panel open.\n if (!hasChildren) this.open.set(false);\n }\n }\n\n protected clearSelection(event: Event): void {\n event.stopPropagation();\n if (this.disabled() || this.readonly()) return;\n this.path.set([]);\n this.activePath.set([]);\n this.value.set([]);\n this.touch.emit();\n }\n\n protected isActiveAt(colIndex: number, value: T): boolean {\n return this.activePath()[colIndex] === value;\n }\n\n /**\n * Whether this option is the committed choice — `null` when it is not a\n * choice at all.\n *\n * Two questions the panel has to keep apart, and `--active` answers only the\n * first: `activePath()` is where the user has NAVIGATED to, `path()` is what\n * they have COMMITTED. They agree once a leaf is picked and diverge for the\n * whole walk down.\n *\n * `null` — the attribute absent — on a branch while `changeOnSelect` is off,\n * because such a branch genuinely cannot be chosen; ARIA reads a missing\n * `aria-selected` as \"not selectable\", which is exactly true here. That makes\n * this binding the first expression the `changeOnSelect` contract has ever had\n * in ARIA, in both directions.\n */\n protected isSelectedAt(colIndex: number, opt: WrCascaderOption<T>): boolean | null {\n const committable = !opt.children?.length || this.changeOnSelect();\n if (!committable) return null;\n const path = this.path();\n return colIndex === path.length - 1 && path[colIndex] === opt.value;\n }\n\n /** Stable id for one option — what a column's `aria-labelledby` points at. */\n protected optionId(colIndex: number, optIndex: number): string {\n return `${this.panelId}-opt-${colIndex}-${optIndex}`;\n }\n\n /** Stable id for one column — what an expanded branch's `aria-controls` points at. */\n protected columnId(colIndex: number): string {\n return `${this.panelId}-col-${colIndex}`;\n }\n\n /**\n * The option whose children a column holds, by id — its accessible name.\n *\n * The columns are DOM SIBLINGS, so nothing in the markup says the second one\n * belongs to \"Europe\". Column 0 has no parent and stays unnamed; the tree\n * itself already carries the control's name.\n */\n protected parentOptionId(colIndex: number): string | null {\n if (colIndex === 0) return null;\n const parent = this.columns()[colIndex - 1] ?? [];\n const index = parent.findIndex(o => this.isActiveAt(colIndex - 1, o.value));\n return index < 0 ? null : this.optionId(colIndex - 1, index);\n }\n\n private pathsEqual(a: readonly T[], b: readonly T[]): boolean {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n }\n\n // Overlay\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n const positionStrategy = this.overlay\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions([\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },\n ])\n .withPush(true);\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.reposition(),\n panelClass: 'wr-cascader-overlay',\n });\n\n // The columns cascade inline-wards, and the CDK captured the direction as a\n // string when this ref was created — so a flip while the panel is open left\n // the whole cascade running the other way from the page around it.\n wrFollowDirection(this.overlayRef, this.dir, this.injector);\n\n const portal = new TemplatePortal(this.panelTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n // Move the caret into the panel it just opened. Nothing did, and the pane is\n // appended to `<body>`, so an opened cascader left focus on the trigger and its\n // options were reachable only by tabbing past the whole rest of the page —\n // `wr-tree` and `wr-context-menu` were the same defect. `closeOverlay` below\n // already assumes this is where the caret lives.\n //\n // `afterNextRender`, NOT `queueMicrotask`: under zoneless CD change detection runs\n // in a macrotask, so a microtask queued here fires before the columns are in the\n // DOM — the trap that once left `wr-calendar`'s ring and its real focus on\n // different days.\n afterNextRender(() => this.focusPanelOption(), { injector: this.injector });\n\n this.outsideClick\n .outsidePointerEvents(this.overlayRef)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (this.host.nativeElement.contains(event.target as Node)) return;\n this.open.set(false);\n });\n\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.open.set(false);\n }\n });\n }\n\n /**\n * The option the panel opens on: the selected one in the first column when there is\n * a selection, otherwise the first enabled root. A disabled option is skipped — it\n * still carries `tabindex=\"-1\"`, so `focus()` would land on it and answer for a\n * choice nobody can make.\n */\n private focusPanelOption(): void {\n const pane = this.overlayRef?.overlayElement;\n if (!pane) return;\n const option =\n pane.querySelector<HTMLElement>('.wr-cascader__opt--active:not(.wr-cascader__opt--disabled)') ??\n pane.querySelector<HTMLElement>('.wr-cascader__opt:not(.wr-cascader__opt--disabled)');\n option?.focus();\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n // Every enabled option carries `tabindex=\"0\"` and commits on Enter, so on\n // the keyboard the caret is INSIDE the pane by design — and the ordinary\n // way to finish choosing (`onOptionClick` on a leaf) closes it. Disposing\n // without handing focus back dropped it on `<body>` on the SUCCESS path,\n // not merely on dismissal: a keyboard user who had just picked a value then\n // had to Tab from the top of the document to get back to the control.\n // Untouched when focus had already moved elsewhere — that click is usually\n // what closed us, and stealing the caret back would fight the user for it.\n const pane = this.overlayRef.overlayElement;\n const focusWasInside = pane.contains(this.host.nativeElement.ownerDocument.activeElement);\n this.overlayRef.dispose();\n this.overlayRef = null;\n if (focusWasInside) this.host.nativeElement.querySelector<HTMLElement>('.wr-cascader__trigger')?.focus();\n }\n}\n\nexport type { WrCascaderOption } from './interfaces';\n","<button\n type=\"button\"\n class=\"wr-cascader__trigger\"\n role=\"combobox\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -120,6 +120,8 @@ class WrCheckbox {
|
|
|
120
120
|
* only and controlled: set it yourself for a parent "select all" whose
|
|
121
121
|
* children are partly checked, and clear it on the next toggle. Takes visual
|
|
122
122
|
* precedence over `checked`; the native input reports `aria-checked="mixed"`.
|
|
123
|
+
* A click the host does not answer still toggles `checked` underneath, and the
|
|
124
|
+
* dash and the mixed state both stay until the binding turns `false`.
|
|
123
125
|
*
|
|
124
126
|
* @default false
|
|
125
127
|
*/
|
|
@@ -180,16 +182,24 @@ class WrCheckbox {
|
|
|
180
182
|
event.preventDefault();
|
|
181
183
|
}
|
|
182
184
|
onInputChange(event) {
|
|
185
|
+
const inputEl = event.target;
|
|
186
|
+
// Activating a checkbox clears its own `indeterminate` before `change` fires,
|
|
187
|
+
// and the `[indeterminate]` binding never writes again while the bound value
|
|
188
|
+
// stays `true` — so the box kept painting the dash while the accessibility
|
|
189
|
+
// tree announced "checked". The input is controlled: the mixed state holds
|
|
190
|
+
// until the host clears it, and a host that does clears it through the
|
|
191
|
+
// binding on the next change detection.
|
|
192
|
+
inputEl.indeterminate = this.indeterminate();
|
|
183
193
|
if (this.effectiveReadonly()) {
|
|
184
194
|
// A synthetic `change` cannot be prevented — put the DOM back instead.
|
|
185
|
-
|
|
195
|
+
inputEl.checked = this.isChecked();
|
|
186
196
|
return;
|
|
187
197
|
}
|
|
188
198
|
if (this.group) {
|
|
189
199
|
this.group.toggle(this.checkboxValue());
|
|
190
200
|
return;
|
|
191
201
|
}
|
|
192
|
-
this.checked.set(
|
|
202
|
+
this.checked.set(inputEl.checked);
|
|
193
203
|
}
|
|
194
204
|
onInputBlur() {
|
|
195
205
|
// Inside a group the GROUP is the bound control, and its own `touch` is
|