ngwr 14.8.0 → 14.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -332
- package/alert/styles/_index.scss +10 -0
- package/avatar/styles/_index.scss +18 -7
- package/badge/styles/_index.scss +7 -0
- package/badge/styles/_tag.scss +7 -1
- package/button/styles/_index.scss +6 -0
- package/cascader/styles/_rules.scss +1 -1
- package/checkbox/styles/_index.scss +4 -0
- package/command-palette/styles/_index.scss +1 -1
- package/divider/styles/_index.scss +2 -0
- package/editor/styles/_index.scss +441 -0
- package/fesm2022/ngwr-action-sheet-testing.mjs.map +1 -1
- package/fesm2022/ngwr-action-sheet.mjs +3 -3
- package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
- package/fesm2022/ngwr-affix.mjs +3 -3
- package/fesm2022/ngwr-affix.mjs.map +1 -1
- package/fesm2022/ngwr-alert.mjs +3 -3
- package/fesm2022/ngwr-alert.mjs.map +1 -1
- package/fesm2022/ngwr-anchor.mjs +3 -3
- package/fesm2022/ngwr-anchor.mjs.map +1 -1
- package/fesm2022/ngwr-aurora.mjs +3 -3
- package/fesm2022/ngwr-aurora.mjs.map +1 -1
- package/fesm2022/ngwr-avatar.mjs +3 -3
- package/fesm2022/ngwr-avatar.mjs.map +1 -1
- package/fesm2022/ngwr-back-top.mjs +3 -3
- package/fesm2022/ngwr-back-top.mjs.map +1 -1
- package/fesm2022/ngwr-badge.mjs +28 -13
- package/fesm2022/ngwr-badge.mjs.map +1 -1
- package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-bar-chart.mjs +3 -3
- package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text.mjs +3 -3
- package/fesm2022/ngwr-blur-text.mjs.map +1 -1
- package/fesm2022/ngwr-border-glow-testing.mjs.map +1 -1
- package/fesm2022/ngwr-border-glow.mjs +3 -3
- package/fesm2022/ngwr-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-burger.mjs +3 -3
- package/fesm2022/ngwr-burger.mjs.map +1 -1
- package/fesm2022/ngwr-button-testing.mjs.map +1 -1
- package/fesm2022/ngwr-button.mjs +6 -6
- package/fesm2022/ngwr-button.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
- package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-calendar.mjs +3 -3
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-card.mjs +9 -9
- package/fesm2022/ngwr-card.mjs.map +1 -1
- package/fesm2022/ngwr-carousel-testing.mjs.map +1 -1
- package/fesm2022/ngwr-carousel.mjs +6 -6
- package/fesm2022/ngwr-carousel.mjs.map +1 -1
- package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +4 -4
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +6 -6
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text.mjs +3 -3
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-click-spark.mjs +3 -3
- package/fesm2022/ngwr-click-spark.mjs.map +1 -1
- package/fesm2022/ngwr-clipboard.mjs +3 -3
- package/fesm2022/ngwr-clipboard.mjs.map +1 -1
- package/fesm2022/ngwr-collapse-testing.mjs.map +1 -1
- package/fesm2022/ngwr-collapse.mjs +9 -9
- package/fesm2022/ngwr-collapse.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +6 -6
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette-testing.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette.mjs +3 -3
- package/fesm2022/ngwr-command-palette.mjs.map +1 -1
- package/fesm2022/ngwr-compare.mjs +3 -3
- package/fesm2022/ngwr-compare.mjs.map +1 -1
- package/fesm2022/ngwr-confetti.mjs +3 -3
- package/fesm2022/ngwr-confetti.mjs.map +1 -1
- package/fesm2022/ngwr-config.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu.mjs +12 -12
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-cookie.mjs +3 -3
- package/fesm2022/ngwr-cookie.mjs.map +1 -1
- package/fesm2022/ngwr-counter.mjs +6 -6
- package/fesm2022/ngwr-counter.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
- package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
- package/fesm2022/ngwr-date-adapters-luxon.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +21 -21
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-date.mjs +3 -3
- package/fesm2022/ngwr-date.mjs.map +1 -1
- package/fesm2022/ngwr-decrypt-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-decrypt-text.mjs +3 -3
- package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
- package/fesm2022/ngwr-density.mjs +6 -6
- package/fesm2022/ngwr-density.mjs.map +1 -1
- package/fesm2022/ngwr-descriptions.mjs +6 -6
- package/fesm2022/ngwr-descriptions.mjs.map +1 -1
- package/fesm2022/ngwr-dialog-testing.mjs.map +1 -1
- package/fesm2022/ngwr-dialog.mjs +15 -15
- package/fesm2022/ngwr-dialog.mjs.map +1 -1
- package/fesm2022/ngwr-directives.mjs +12 -12
- package/fesm2022/ngwr-directives.mjs.map +1 -1
- package/fesm2022/ngwr-divider.mjs +3 -3
- package/fesm2022/ngwr-divider.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart.mjs +3 -3
- package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +6 -6
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-drawer-testing.mjs.map +1 -1
- package/fesm2022/ngwr-drawer.mjs +18 -18
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown-testing.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +9 -9
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-editor-testing.mjs +568 -0
- package/fesm2022/ngwr-editor-testing.mjs.map +1 -0
- package/fesm2022/ngwr-editor.mjs +2601 -0
- package/fesm2022/ngwr-editor.mjs.map +1 -0
- package/fesm2022/ngwr-empty.mjs +3 -3
- package/fesm2022/ngwr-empty.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar.mjs +6 -6
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text.mjs +3 -3
- package/fesm2022/ngwr-falling-text.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload-testing.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload.mjs +3 -3
- package/fesm2022/ngwr-file-upload.mjs.map +1 -1
- package/fesm2022/ngwr-form-testing.mjs.map +1 -1
- package/fesm2022/ngwr-form.mjs +9 -9
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
- package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
- package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
- package/fesm2022/ngwr-gauge.mjs +3 -3
- package/fesm2022/ngwr-gauge.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text.mjs +3 -3
- package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text.mjs +3 -3
- package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
- package/fesm2022/ngwr-graph-testing.mjs.map +1 -1
- package/fesm2022/ngwr-graph.mjs +6 -6
- package/fesm2022/ngwr-graph.mjs.map +1 -1
- package/fesm2022/ngwr-hotkey.mjs +6 -6
- package/fesm2022/ngwr-hotkey.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ar.mjs +29 -0
- package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-cs.mjs +29 -0
- package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-de.mjs +29 -0
- package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +34 -0
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-es.mjs +29 -0
- package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-fr.mjs +29 -0
- package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-he.mjs +29 -0
- package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-hi.mjs +29 -0
- package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-id.mjs +29 -0
- package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-it.mjs +29 -0
- package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ja.mjs +29 -0
- package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ko.mjs +29 -0
- package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-nl.mjs +29 -0
- package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pl.mjs +29 -0
- package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pt.mjs +29 -0
- package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +29 -0
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-sv.mjs +29 -0
- package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-tr.mjs +29 -0
- package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-uk.mjs +29 -0
- package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-vi.mjs +29 -0
- package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh-TW.mjs +29 -0
- package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh.mjs +29 -0
- package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
- package/fesm2022/ngwr-i18n.mjs +9 -9
- package/fesm2022/ngwr-i18n.mjs.map +1 -1
- package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
- package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
- package/fesm2022/ngwr-icon.mjs +6 -6
- package/fesm2022/ngwr-icon.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper.mjs +3 -3
- package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
- package/fesm2022/ngwr-input-number-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input-number.mjs +3 -3
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp.mjs +3 -3
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-input-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input.mjs +15 -15
- package/fesm2022/ngwr-input.mjs.map +1 -1
- package/fesm2022/ngwr-keyboard.mjs +3 -3
- package/fesm2022/ngwr-keyboard.mjs.map +1 -1
- package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
- package/fesm2022/ngwr-knob.mjs +3 -3
- package/fesm2022/ngwr-knob.mjs.map +1 -1
- package/fesm2022/ngwr-layout.mjs +15 -15
- package/fesm2022/ngwr-layout.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox-testing.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox.mjs +3 -3
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart.mjs +3 -3
- package/fesm2022/ngwr-line-chart.mjs.map +1 -1
- package/fesm2022/ngwr-list.mjs +6 -6
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar.mjs +6 -6
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-markdown-testing.mjs.map +1 -1
- package/fesm2022/ngwr-markdown.mjs +798 -17
- package/fesm2022/ngwr-markdown.mjs.map +1 -1
- package/fesm2022/ngwr-marquee-testing.mjs.map +1 -1
- package/fesm2022/ngwr-marquee.mjs +3 -3
- package/fesm2022/ngwr-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-media.mjs +3 -3
- package/fesm2022/ngwr-media.mjs.map +1 -1
- package/fesm2022/ngwr-mention-testing.mjs.map +1 -1
- package/fesm2022/ngwr-mention.mjs +6 -6
- package/fesm2022/ngwr-mention.mjs.map +1 -1
- package/fesm2022/ngwr-meta.mjs +6 -6
- package/fesm2022/ngwr-meta.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group.mjs +3 -3
- package/fesm2022/ngwr-meter-group.mjs.map +1 -1
- package/fesm2022/ngwr-overlay.mjs +6 -6
- package/fesm2022/ngwr-overlay.mjs.map +1 -1
- package/fesm2022/ngwr-page-header.mjs +3 -3
- package/fesm2022/ngwr-page-header.mjs.map +1 -1
- package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +3 -3
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-pipes.mjs +21 -21
- package/fesm2022/ngwr-pipes.mjs.map +1 -1
- package/fesm2022/ngwr-platform.mjs +9 -9
- package/fesm2022/ngwr-platform.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm-testing.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm.mjs +6 -6
- package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
- package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
- package/fesm2022/ngwr-popover.mjs +12 -12
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-progress.mjs +3 -3
- package/fesm2022/ngwr-progress.mjs.map +1 -1
- package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
- package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -1
- package/fesm2022/ngwr-qr.mjs +3 -3
- package/fesm2022/ngwr-qr.mjs.map +1 -1
- package/fesm2022/ngwr-radio-testing.mjs.map +1 -1
- package/fesm2022/ngwr-radio.mjs +6 -6
- package/fesm2022/ngwr-radio.mjs.map +1 -1
- package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
- package/fesm2022/ngwr-rating.mjs +3 -3
- package/fesm2022/ngwr-rating.mjs.map +1 -1
- package/fesm2022/ngwr-result.mjs +12 -12
- package/fesm2022/ngwr-result.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text.mjs +3 -3
- package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
- package/fesm2022/ngwr-schema-form.mjs +3 -3
- package/fesm2022/ngwr-schema-form.mjs.map +1 -1
- package/fesm2022/ngwr-scroll.mjs +3 -3
- package/fesm2022/ngwr-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
- package/fesm2022/ngwr-segmented.mjs +3 -3
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select-testing.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +12 -12
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text.mjs +6 -6
- package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
- package/fesm2022/ngwr-sidebar.mjs +3 -3
- package/fesm2022/ngwr-sidebar.mjs.map +1 -1
- package/fesm2022/ngwr-skeleton.mjs +3 -3
- package/fesm2022/ngwr-skeleton.mjs.map +1 -1
- package/fesm2022/ngwr-slider-testing.mjs.map +1 -1
- package/fesm2022/ngwr-slider.mjs +3 -3
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline-testing.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline.mjs +3 -3
- package/fesm2022/ngwr-sparkline.mjs.map +1 -1
- package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -1
- package/fesm2022/ngwr-speed-dial.mjs +3 -3
- package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
- package/fesm2022/ngwr-spinner.mjs +3 -3
- package/fesm2022/ngwr-spinner.mjs.map +1 -1
- package/fesm2022/ngwr-splash-cursor-testing.mjs.map +1 -1
- package/fesm2022/ngwr-splash-cursor.mjs +3 -3
- package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
- package/fesm2022/ngwr-split-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-split-text.mjs +3 -3
- package/fesm2022/ngwr-split-text.mjs.map +1 -1
- package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
- package/fesm2022/ngwr-splitter.mjs +3 -3
- package/fesm2022/ngwr-splitter.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card-testing.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card.mjs +6 -6
- package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-squircle.mjs +6 -6
- package/fesm2022/ngwr-squircle.mjs.map +1 -1
- package/fesm2022/ngwr-star-border-testing.mjs.map +1 -1
- package/fesm2022/ngwr-star-border.mjs +3 -3
- package/fesm2022/ngwr-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-statistic.mjs +9 -9
- package/fesm2022/ngwr-statistic.mjs.map +1 -1
- package/fesm2022/ngwr-stepper-testing.mjs.map +1 -1
- package/fesm2022/ngwr-stepper.mjs +6 -6
- package/fesm2022/ngwr-stepper.mjs.map +1 -1
- package/fesm2022/ngwr-storage.mjs +3 -3
- package/fesm2022/ngwr-storage.mjs.map +1 -1
- package/fesm2022/ngwr-switch-testing.mjs.map +1 -1
- package/fesm2022/ngwr-switch.mjs +3 -3
- package/fesm2022/ngwr-switch.mjs.map +1 -1
- package/fesm2022/ngwr-table-testing.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +18 -18
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-router.mjs +3 -3
- package/fesm2022/ngwr-tabs-router.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +6 -6
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-textarea-testing.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +3 -3
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-theme.mjs +3 -3
- package/fesm2022/ngwr-theme.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card.mjs +6 -6
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-timeline.mjs +6 -6
- package/fesm2022/ngwr-timeline.mjs.map +1 -1
- package/fesm2022/ngwr-toast-testing.mjs.map +1 -1
- package/fesm2022/ngwr-toast.mjs +9 -9
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-toolbar.mjs +3 -3
- package/fesm2022/ngwr-toolbar.mjs.map +1 -1
- package/fesm2022/ngwr-tour-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tour.mjs +6 -6
- package/fesm2022/ngwr-tour.mjs.map +1 -1
- package/fesm2022/ngwr-transfer-testing.mjs.map +1 -1
- package/fesm2022/ngwr-transfer.mjs +3 -3
- package/fesm2022/ngwr-transfer.mjs.map +1 -1
- package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +3 -3
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter.mjs +3 -3
- package/fesm2022/ngwr-typewriter.mjs.map +1 -1
- package/fesm2022/ngwr-typography.mjs +7 -3
- package/fesm2022/ngwr-typography.mjs.map +1 -1
- package/fesm2022/ngwr-utils.mjs.map +1 -1
- package/fesm2022/ngwr-validators.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
- package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-waves-testing.mjs.map +1 -1
- package/fesm2022/ngwr-waves.mjs +3 -3
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/fesm2022/ngwr-window-testing.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +12 -12
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/form/styles/_index.scss +5 -0
- package/i18n/ar.json +29 -0
- package/i18n/cs.json +29 -0
- package/i18n/de.json +29 -0
- package/i18n/en.json +29 -0
- package/i18n/es.json +29 -0
- package/i18n/fr.json +29 -0
- package/i18n/he.json +29 -0
- package/i18n/hi.json +29 -0
- package/i18n/id.json +29 -0
- package/i18n/it.json +29 -0
- package/i18n/ja.json +29 -0
- package/i18n/ko.json +29 -0
- package/i18n/nl.json +29 -0
- package/i18n/pl.json +29 -0
- package/i18n/pt.json +29 -0
- package/i18n/ru.json +29 -0
- package/i18n/sv.json +29 -0
- package/i18n/tr.json +29 -0
- package/i18n/uk.json +29 -0
- package/i18n/vi.json +29 -0
- package/i18n/zh-TW.json +29 -0
- package/i18n/zh.json +29 -0
- package/input/styles/_index.scss +5 -1
- package/input-otp/styles/_index.scss +5 -5
- package/llms-full.txt +11 -1
- package/llms.txt +188 -132
- package/mcp/providers.js +2 -2
- package/mcp/server.js +1 -1
- package/overlay/styles/_arrow.scss +3 -0
- package/package.json +43 -2
- package/progress/styles/_index.scss +4 -0
- package/radio/styles/_index.scss +4 -1
- package/schematics/use/symbol-map.json +1 -0
- package/select/styles/_index.scss +3 -3
- package/sidebar/styles/_index.scss +10 -0
- package/skeleton/styles/_index.scss +3 -0
- package/skills/ngwr/SKILL.md +5 -5
- package/skills/ngwr/references/catalog.md +2 -0
- package/skills/ngwr/references/setup.md +3 -3
- package/styles.scss +1 -0
- package/table/styles/_index.scss +7 -0
- package/textarea/styles/_index.scss +12 -3
- package/theme/styles/_colors.scss +39 -13
- package/theme/styles/_contrast.scss +9 -7
- package/toast/styles/_index.scss +4 -0
- package/tree/styles/_index.scss +1 -1
- package/types/ngwr-badge.d.ts +22 -7
- package/types/ngwr-config.d.ts +12 -0
- package/types/ngwr-editor-testing.d.ts +378 -0
- package/types/ngwr-editor.d.ts +449 -0
- package/types/ngwr-markdown.d.ts +61 -2
- package/types/ngwr-typography.d.ts +4 -0
- package/types/ngwr-version.d.ts +1 -1
- package/typography/styles/_index.scss +16 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-carousel.mjs","sources":["../../../projects/lib/carousel/tokens/carousel.token.ts","../../../projects/lib/carousel/carousel-slide.ts","../../../projects/lib/carousel/carousel.ts","../../../projects/lib/carousel/carousel.html","../../../projects/lib/carousel/ngwr-carousel.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 { InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Contract a `<wr-carousel-slide>` uses to ask its parent whether it is the one\n * on screen.\n *\n * A token rather than an input, because slides arrive through `<ng-content />`:\n * nothing in `carousel.html` can bind to them, so the child has to reach up.\n * Same shape as {@link WR_TABS}.\n *\n * @internal\n */\nexport interface WrCarouselContext {\n /** Index of the slide currently on screen. */\n readonly active: Signal<number>;\n /**\n * Position of a slide in projection order, or `-1` before it has registered.\n *\n * Reads the content-children signal, so a `computed()` calling this tracks\n * both the active index and slides being added or removed.\n */\n indexOf(slide: object): number;\n}\n\n/** Token a `<wr-carousel-slide>` injects to find its parent `<wr-carousel>`. */\nexport const WR_CAROUSEL = new InjectionToken<WrCarouselContext>('WR_CAROUSEL');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\nimport { WR_CAROUSEL } from './tokens';\n\n/**\n * One slide in a {@link WrCarousel}. Holds whatever content you\n * project — image, card, video, anything.\n *\n * **An off-screen slide is `inert`.** Only one slide is visible, but the track\n * merely translates the others out of view: without this they stay in the tab\n * order and in the accessibility tree, so a keyboard user tabs into a link they\n * cannot see and a screen reader announces every slide as if they were all on\n * screen. `inert` takes the whole subtree out of both at once, which is why it\n * is preferred here over `tabindex=\"-1\"` (which reaches only the host) — the\n * same answer `wr-collapse` and `wr-marquee` use.\n *\n * `aria-hidden` rides along for the same reason it does on the marquee's\n * duplicate copies: it states the intent for anything reading the attribute\n * rather than honouring `inert`.\n */\n@Component({\n selector: 'wr-carousel-slide',\n template: '<ng-content />',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-carousel-slide',\n role: 'group',\n '[attr.aria-roledescription]': 'resolvedRoledescription()',\n '[attr.inert]': 'offScreen() ? \"\" : null',\n '[attr.aria-hidden]': 'offScreen() ? \"true\" : null',\n },\n})\nexport class WrCarouselSlide {\n private readonly carousel = inject(WR_CAROUSEL, { optional: true });\n\n /**\n * Word a screen reader speaks IN PLACE OF the `group` role. Falls back to\n * `carousel.slideRoledescription`, then `'slide'`.\n */\n readonly roledescription = input<string | null>(null);\n\n // Spoken verbatim, and only the off-screen slides are `inert` — so the visible\n // one announced an English \"slide\" inside an otherwise localized carousel.\n protected readonly resolvedRoledescription = useI18nText(\n this.roledescription,\n 'carousel.slideRoledescription',\n 'slide'\n );\n\n /**\n * Whether this slide is one of the ones translated out of view.\n *\n * `false` while the index is `-1`: content children resolve after the first\n * render, and a slide that hid itself in that window would make the carousel\n * open with everything inert. `false` too when there is no parent — the\n * component is exported, so it can be used on its own.\n */\n protected readonly offScreen = computed(() => {\n if (!this.carousel) return false;\n const index = this.carousel.indexOf(this);\n return index >= 0 && index !== this.carousel.active();\n });\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n PLATFORM_ID,\n ViewEncapsulation,\n computed,\n contentChildren,\n forwardRef,\n effect,\n inject,\n input,\n model,\n signal,\n} from '@angular/core';\n\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport { WrCarouselSlide } from './carousel-slide';\nimport { WR_CAROUSEL, type WrCarouselContext } from './tokens';\n\n/**\n * Slide carousel. Project `<wr-carousel-slide>` children — the carousel\n * snaps between them with prev/next buttons and optional dots / autoplay.\n *\n * @example\n * ```html\n * <wr-carousel [(active)]=\"i\" autoplay>\n * <wr-carousel-slide><img src=\"a.jpg\" /></wr-carousel-slide>\n * <wr-carousel-slide><img src=\"b.jpg\" /></wr-carousel-slide>\n * <wr-carousel-slide><img src=\"c.jpg\" /></wr-carousel-slide>\n * </wr-carousel>\n * ```\n *\n * @see https://ngwr.dev/reference/components/carousel\n */\n@Component({\n selector: 'wr-carousel',\n templateUrl: './carousel.html',\n encapsulation: ViewEncapsulation.None,\n // On the HOST, not the viewport: the arrows and dots are the viewport's siblings, so\n // viewport-scoped listeners let a slide change under a cursor aiming at an arrow.\n // `focusin` / `focusout` are the keyboard half — WCAG 2.2.2 wants a way to stop\n // moving content, and hovering is not one for someone who never uses a mouse.\n host: {\n class: 'wr-carousel',\n '(mouseenter)': 'onHoverIn()',\n '(mouseleave)': 'onHoverOut()',\n '(focusin)': 'onFocusIn()',\n '(focusout)': 'onFocusOut()',\n },\n providers: [\n {\n provide: WR_CAROUSEL,\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n useExisting: forwardRef(() => WrCarousel),\n },\n ],\n})\nexport class WrCarousel implements WrCarouselContext {\n /** Accessible name of the previous-slide button. Falls back to `carousel.prev`. */\n readonly prevLabel = input<string | null>(null);\n\n /** Accessible name of the next-slide button. Falls back to `carousel.next`. */\n readonly nextLabel = input<string | null>(null);\n\n /** Accessible name of the dot group. Falls back to `carousel.pagination`. */\n readonly paginationLabel = input<string | null>(null);\n\n protected readonly resolvedPrevLabel = useI18nText(this.prevLabel, 'carousel.prev', 'Previous slide');\n protected readonly resolvedNextLabel = useI18nText(this.nextLabel, 'carousel.next', 'Next slide');\n protected readonly resolvedPaginationLabel = useI18nText(\n this.paginationLabel,\n 'carousel.pagination',\n 'Carousel pagination'\n );\n\n /** Accessible name of the carousel itself. Falls back to `carousel.label`. */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'carousel.label', 'Carousel');\n\n /**\n * Word a screen reader speaks IN PLACE OF the `group` role. Falls back to\n * `carousel.roledescription`, then `'carousel'`.\n */\n readonly roledescription = input<string | null>(null);\n\n // Routed for the same reason the name above is: `aria-roledescription` is spoken\n // verbatim, so a static English \"carousel\" made the viewport announce\n // \"Карусель, carousel\" with the localized arrows right beside it.\n protected readonly resolvedRoledescription = useI18nText(\n this.roledescription,\n 'carousel.roledescription',\n 'carousel'\n );\n\n // The three labels above route through the catalog; this one was a hard-coded\n // English template, so a localized app got two languages in one pagination strip.\n protected readonly slideLabel = useI18nFormatter('carousel.goToSlide', 'Go to slide {{index}}');\n\n /** Active slide index. Two-way bindable. @default 0 */\n readonly active = model(0);\n\n /** Show prev / next arrow buttons. @default true */\n readonly showArrows = input(true, { transform: coerceBooleanProperty });\n\n /** Show dot indicators below the slides. @default true */\n readonly showDots = input(true, { transform: coerceBooleanProperty });\n\n /** Auto-advance slides. @default false */\n readonly autoplay = input(false, { transform: coerceBooleanProperty });\n\n /** Autoplay interval (ms). @default 4000 */\n readonly intervalMs = input(4000, {\n transform: (v: unknown): number => Math.max(500, coerceNumberProperty(v, 4000)),\n });\n\n /** Wrap around at the ends. @default true */\n readonly loop = input(true, { transform: coerceBooleanProperty });\n\n protected readonly slides = contentChildren(WrCarouselSlide);\n protected readonly count = computed(() => this.slides().length);\n\n /**\n * Where a slide sits in projection order — {@link WrCarouselContext}.\n *\n * Public only because the child injects the parent through `WR_CAROUSEL`;\n * reading `slides()` here is what makes the child's `computed()` re-run when a\n * slide is added or removed.\n */\n indexOf(slide: object): number {\n return this.slides().indexOf(slide as WrCarouselSlide);\n }\n\n /** Live horizontal drag offset (px) during a touch swipe. */\n protected readonly dragX = signal(0);\n protected readonly dragging = signal(false);\n\n private readonly dir = inject(Directionality, { optional: true });\n\n /**\n * Reading direction of the track. `Directionality` is root-provided, so this\n * always resolves — `optional` only guards a consumer who has deliberately\n * torn the provider out. It reads the document once at construction; a\n * subtree that overrides the direction does it with the CDK's `Dir`\n * directive, which writes `valueSignal`, so `trackStyle` re-renders instead\n * of leaving the track parked on the old side.\n */\n private readonly isRtl = computed(() => this.dir?.valueSignal() === 'rtl');\n\n /** CSS transform for the track — the per-slide offset plus any live drag. */\n protected readonly trackStyle = computed(() => {\n // `translateX` is PHYSICAL while the slides are laid out on the inline axis:\n // under `dir=\"rtl\"` the flex track runs right-to-left, so slide 1 sits to the\n // LEFT of slide 0 and reaching it means moving the track the other way. Left\n // unsigned, every RTL carousel translated itself off into blank space.\n const base = (this.isRtl() ? 1 : -1) * this.active() * 100;\n // The drag stays physical on purpose: it is the finger's own displacement,\n // and the track follows the finger in both directions.\n const drag = this.dragX();\n return drag === 0 ? `translateX(${base}%)` : `translateX(calc(${base}% + ${drag}px))`;\n });\n\n private timer: ReturnType<typeof setInterval> | null = null;\n\n // Three sources hold the pause and they release independently, so they get a\n // flag each rather than one shared boolean — the same `hovered` / `focusWithin`\n // pair `WrToastHost` keeps. With one flag whichever source released LAST won:\n // moving the pointer off the carousel while focus was still on a link inside it\n // restarted the slides under the focused element, and a `touchend` released a\n // pause it had never taken. Flags, not a counter: `mouseenter`/`mouseleave` and\n // `focusin`/`focusout` each pair exactly once per source, so a count would only\n // add a way to drift out of step.\n private readonly hovered = signal(false);\n private readonly focusWithin = signal(false);\n private readonly paused = computed(() => this.hovered() || this.focusWithin() || this.dragging());\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n constructor() {\n effect(() => {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n // `isBrowser` first: without it the prerender ran the timer too, doing work\n // nobody will ever see on a slide index that then gets serialized.\n if (!this.isBrowser || !this.autoplay() || this.paused() || this.count() < 2) return;\n const interval = this.intervalMs();\n this.timer = setInterval(() => this.next(), interval);\n });\n\n // `active` is a plain `model`, so `[(active)]` and a shrinking slide list both\n // write into it unchecked — a filtered list left it pointing past the end,\n // translating the track into blank space with no dot lit.\n effect(() => {\n const max = this.count() - 1;\n if (max < 0) return;\n const clamped = Math.min(Math.max(0, this.active()), max);\n if (clamped !== this.active()) this.active.set(clamped);\n });\n\n this.destroyRef.onDestroy(() => {\n if (this.timer) clearInterval(this.timer);\n });\n }\n\n protected onHoverIn(): void {\n this.hovered.set(true);\n }\n\n protected onHoverOut(): void {\n this.hovered.set(false);\n }\n\n protected onFocusIn(): void {\n this.focusWithin.set(true);\n }\n\n protected onFocusOut(): void {\n this.focusWithin.set(false);\n }\n\n // Imperative\n\n goTo(index: number): void {\n const max = this.count() - 1;\n if (max < 0) return;\n if (this.loop()) {\n const next = ((index % this.count()) + this.count()) % this.count();\n this.active.set(next);\n } else {\n this.active.set(Math.min(Math.max(0, index), max));\n }\n }\n\n next(): void {\n this.goTo(this.active() + 1);\n }\n\n prev(): void {\n this.goTo(this.active() - 1);\n }\n\n // Swipe navigation — the track follows the finger; releasing past ~20% of the\n // viewport advances a slide, otherwise snaps back. Which way that is follows\n // the reading direction: dragging toward the inline start (left in LTR, right\n // in RTL) pulls the next slide into view.\n\n private swipeStartX = 0;\n\n protected onSwipeStart(event: TouchEvent): void {\n const touch = event.touches[0];\n if (!touch) return;\n this.swipeStartX = touch.clientX;\n this.dragging.set(true); // holds autoplay on its own — `paused` reads it\n }\n\n protected onSwipeMove(event: TouchEvent): void {\n if (!this.dragging()) return;\n const touch = event.touches[0];\n if (!touch) return;\n this.dragX.set(touch.clientX - this.swipeStartX);\n }\n\n protected onSwipeEnd(event: TouchEvent, viewport: HTMLElement): void {\n if (!this.dragging()) return;\n this.dragging.set(false);\n const dx = this.dragX();\n this.dragX.set(0);\n const threshold = (viewport.offsetWidth || 0) * 0.2;\n // `dx` is a physical delta. The next slide sits to the physical RIGHT in LTR\n // and to the LEFT in RTL, so the drag that pulls it into view — and with it\n // the sign that advances — turns around with the direction. The buttons keep\n // their semantics either way; only the gesture is physical.\n const advance = this.isRtl() ? dx >= threshold : dx <= -threshold;\n const retreat = this.isRtl() ? dx <= -threshold : dx >= threshold;\n if (advance) this.next();\n else if (retreat) this.prev();\n }\n}\n","<div\n #viewport\n class=\"wr-carousel__viewport\"\n role=\"group\"\n [attr.aria-roledescription]=\"resolvedRoledescription()\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n (touchstart)=\"onSwipeStart($event)\"\n (touchmove)=\"onSwipeMove($event)\"\n (touchend)=\"onSwipeEnd($event, viewport)\"\n (touchcancel)=\"onSwipeEnd($event, viewport)\"\n>\n <div class=\"wr-carousel__track\" [style.transform]=\"trackStyle()\" [style.transition]=\"dragging() ? 'none' : null\">\n <ng-content />\n </div>\n</div>\n\n@if (showArrows() && count() > 1) {\n <button\n type=\"button\"\n class=\"wr-carousel__nav wr-carousel__nav--prev\"\n [attr.aria-label]=\"resolvedPrevLabel()\"\n (click)=\"prev()\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n <path d=\"M9 2 L4 7 L9 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-carousel__nav wr-carousel__nav--next\"\n [attr.aria-label]=\"resolvedNextLabel()\"\n (click)=\"next()\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n <path d=\"M5 2 L10 7 L5 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </button>\n}\n\n@if (showDots() && count() > 1) {\n <div class=\"wr-carousel__dots\" role=\"group\" [attr.aria-label]=\"resolvedPaginationLabel()\">\n @for (slide of slides(); track $index) {\n <button\n type=\"button\"\n class=\"wr-carousel__dot\"\n [class.wr-carousel__dot--active]=\"$index === active()\"\n [attr.aria-current]=\"$index === active() ? 'true' : null\"\n [attr.aria-label]=\"slideLabel({ index: $index + 1 })\"\n (click)=\"goTo($index)\"\n ></button>\n }\n </div>\n}\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-carousel.mjs","sources":["../../../projects/lib/carousel/tokens/carousel.token.ts","../../../projects/lib/carousel/carousel-slide.ts","../../../projects/lib/carousel/carousel.ts","../../../projects/lib/carousel/carousel.html","../../../projects/lib/carousel/ngwr-carousel.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 { InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Contract a `<wr-carousel-slide>` uses to ask its parent whether it is the one\n * on screen.\n *\n * A token rather than an input, because slides arrive through `<ng-content />`:\n * nothing in `carousel.html` can bind to them, so the child has to reach up.\n * Same shape as {@link WR_TABS}.\n *\n * @internal\n */\nexport interface WrCarouselContext {\n /** Index of the slide currently on screen. */\n readonly active: Signal<number>;\n /**\n * Position of a slide in projection order, or `-1` before it has registered.\n *\n * Reads the content-children signal, so a `computed()` calling this tracks\n * both the active index and slides being added or removed.\n */\n indexOf(slide: object): number;\n}\n\n/** Token a `<wr-carousel-slide>` injects to find its parent `<wr-carousel>`. */\nexport const WR_CAROUSEL = new InjectionToken<WrCarouselContext>('WR_CAROUSEL');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\nimport { WR_CAROUSEL } from './tokens';\n\n/**\n * One slide in a {@link WrCarousel}. Holds whatever content you\n * project — image, card, video, anything.\n *\n * **An off-screen slide is `inert`.** Only one slide is visible, but the track\n * merely translates the others out of view: without this they stay in the tab\n * order and in the accessibility tree, so a keyboard user tabs into a link they\n * cannot see and a screen reader announces every slide as if they were all on\n * screen. `inert` takes the whole subtree out of both at once, which is why it\n * is preferred here over `tabindex=\"-1\"` (which reaches only the host) — the\n * same answer `wr-collapse` and `wr-marquee` use.\n *\n * `aria-hidden` rides along for the same reason it does on the marquee's\n * duplicate copies: it states the intent for anything reading the attribute\n * rather than honouring `inert`.\n */\n@Component({\n selector: 'wr-carousel-slide',\n template: '<ng-content />',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-carousel-slide',\n role: 'group',\n '[attr.aria-roledescription]': 'resolvedRoledescription()',\n '[attr.inert]': 'offScreen() ? \"\" : null',\n '[attr.aria-hidden]': 'offScreen() ? \"true\" : null',\n },\n})\nexport class WrCarouselSlide {\n private readonly carousel = inject(WR_CAROUSEL, { optional: true });\n\n /**\n * Word a screen reader speaks IN PLACE OF the `group` role. Falls back to\n * `carousel.slideRoledescription`, then `'slide'`.\n */\n readonly roledescription = input<string | null>(null);\n\n // Spoken verbatim, and only the off-screen slides are `inert` — so the visible\n // one announced an English \"slide\" inside an otherwise localized carousel.\n protected readonly resolvedRoledescription = useI18nText(\n this.roledescription,\n 'carousel.slideRoledescription',\n 'slide'\n );\n\n /**\n * Whether this slide is one of the ones translated out of view.\n *\n * `false` while the index is `-1`: content children resolve after the first\n * render, and a slide that hid itself in that window would make the carousel\n * open with everything inert. `false` too when there is no parent — the\n * component is exported, so it can be used on its own.\n */\n protected readonly offScreen = computed(() => {\n if (!this.carousel) return false;\n const index = this.carousel.indexOf(this);\n return index >= 0 && index !== this.carousel.active();\n });\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n PLATFORM_ID,\n ViewEncapsulation,\n computed,\n contentChildren,\n forwardRef,\n effect,\n inject,\n input,\n model,\n signal,\n} from '@angular/core';\n\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport { WrCarouselSlide } from './carousel-slide';\nimport { WR_CAROUSEL, type WrCarouselContext } from './tokens';\n\n/**\n * Slide carousel. Project `<wr-carousel-slide>` children — the carousel\n * snaps between them with prev/next buttons and optional dots / autoplay.\n *\n * @example\n * ```html\n * <wr-carousel [(active)]=\"i\" autoplay>\n * <wr-carousel-slide><img src=\"a.jpg\" /></wr-carousel-slide>\n * <wr-carousel-slide><img src=\"b.jpg\" /></wr-carousel-slide>\n * <wr-carousel-slide><img src=\"c.jpg\" /></wr-carousel-slide>\n * </wr-carousel>\n * ```\n *\n * @see https://ngwr.dev/reference/components/carousel\n */\n@Component({\n selector: 'wr-carousel',\n templateUrl: './carousel.html',\n encapsulation: ViewEncapsulation.None,\n // On the HOST, not the viewport: the arrows and dots are the viewport's siblings, so\n // viewport-scoped listeners let a slide change under a cursor aiming at an arrow.\n // `focusin` / `focusout` are the keyboard half — WCAG 2.2.2 wants a way to stop\n // moving content, and hovering is not one for someone who never uses a mouse.\n host: {\n class: 'wr-carousel',\n '(mouseenter)': 'onHoverIn()',\n '(mouseleave)': 'onHoverOut()',\n '(focusin)': 'onFocusIn()',\n '(focusout)': 'onFocusOut()',\n },\n providers: [\n {\n provide: WR_CAROUSEL,\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n useExisting: forwardRef(() => WrCarousel),\n },\n ],\n})\nexport class WrCarousel implements WrCarouselContext {\n /** Accessible name of the previous-slide button. Falls back to `carousel.prev`. */\n readonly prevLabel = input<string | null>(null);\n\n /** Accessible name of the next-slide button. Falls back to `carousel.next`. */\n readonly nextLabel = input<string | null>(null);\n\n /** Accessible name of the dot group. Falls back to `carousel.pagination`. */\n readonly paginationLabel = input<string | null>(null);\n\n protected readonly resolvedPrevLabel = useI18nText(this.prevLabel, 'carousel.prev', 'Previous slide');\n protected readonly resolvedNextLabel = useI18nText(this.nextLabel, 'carousel.next', 'Next slide');\n protected readonly resolvedPaginationLabel = useI18nText(\n this.paginationLabel,\n 'carousel.pagination',\n 'Carousel pagination'\n );\n\n /** Accessible name of the carousel itself. Falls back to `carousel.label`. */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'carousel.label', 'Carousel');\n\n /**\n * Word a screen reader speaks IN PLACE OF the `group` role. Falls back to\n * `carousel.roledescription`, then `'carousel'`.\n */\n readonly roledescription = input<string | null>(null);\n\n // Routed for the same reason the name above is: `aria-roledescription` is spoken\n // verbatim, so a static English \"carousel\" made the viewport announce\n // \"Карусель, carousel\" with the localized arrows right beside it.\n protected readonly resolvedRoledescription = useI18nText(\n this.roledescription,\n 'carousel.roledescription',\n 'carousel'\n );\n\n // The three labels above route through the catalog; this one was a hard-coded\n // English template, so a localized app got two languages in one pagination strip.\n protected readonly slideLabel = useI18nFormatter('carousel.goToSlide', 'Go to slide {{index}}');\n\n /** Active slide index. Two-way bindable. @default 0 */\n readonly active = model(0);\n\n /** Show prev / next arrow buttons. @default true */\n readonly showArrows = input(true, { transform: coerceBooleanProperty });\n\n /** Show dot indicators below the slides. @default true */\n readonly showDots = input(true, { transform: coerceBooleanProperty });\n\n /** Auto-advance slides. @default false */\n readonly autoplay = input(false, { transform: coerceBooleanProperty });\n\n /** Autoplay interval (ms). @default 4000 */\n readonly intervalMs = input(4000, {\n transform: (v: unknown): number => Math.max(500, coerceNumberProperty(v, 4000)),\n });\n\n /** Wrap around at the ends. @default true */\n readonly loop = input(true, { transform: coerceBooleanProperty });\n\n protected readonly slides = contentChildren(WrCarouselSlide);\n protected readonly count = computed(() => this.slides().length);\n\n /**\n * Where a slide sits in projection order — {@link WrCarouselContext}.\n *\n * Public only because the child injects the parent through `WR_CAROUSEL`;\n * reading `slides()` here is what makes the child's `computed()` re-run when a\n * slide is added or removed.\n */\n indexOf(slide: object): number {\n return this.slides().indexOf(slide as WrCarouselSlide);\n }\n\n /** Live horizontal drag offset (px) during a touch swipe. */\n protected readonly dragX = signal(0);\n protected readonly dragging = signal(false);\n\n private readonly dir = inject(Directionality, { optional: true });\n\n /**\n * Reading direction of the track. `Directionality` is root-provided, so this\n * always resolves — `optional` only guards a consumer who has deliberately\n * torn the provider out. It reads the document once at construction; a\n * subtree that overrides the direction does it with the CDK's `Dir`\n * directive, which writes `valueSignal`, so `trackStyle` re-renders instead\n * of leaving the track parked on the old side.\n */\n private readonly isRtl = computed(() => this.dir?.valueSignal() === 'rtl');\n\n /** CSS transform for the track — the per-slide offset plus any live drag. */\n protected readonly trackStyle = computed(() => {\n // `translateX` is PHYSICAL while the slides are laid out on the inline axis:\n // under `dir=\"rtl\"` the flex track runs right-to-left, so slide 1 sits to the\n // LEFT of slide 0 and reaching it means moving the track the other way. Left\n // unsigned, every RTL carousel translated itself off into blank space.\n const base = (this.isRtl() ? 1 : -1) * this.active() * 100;\n // The drag stays physical on purpose: it is the finger's own displacement,\n // and the track follows the finger in both directions.\n const drag = this.dragX();\n return drag === 0 ? `translateX(${base}%)` : `translateX(calc(${base}% + ${drag}px))`;\n });\n\n private timer: ReturnType<typeof setInterval> | null = null;\n\n // Three sources hold the pause and they release independently, so they get a\n // flag each rather than one shared boolean — the same `hovered` / `focusWithin`\n // pair `WrToastHost` keeps. With one flag whichever source released LAST won:\n // moving the pointer off the carousel while focus was still on a link inside it\n // restarted the slides under the focused element, and a `touchend` released a\n // pause it had never taken. Flags, not a counter: `mouseenter`/`mouseleave` and\n // `focusin`/`focusout` each pair exactly once per source, so a count would only\n // add a way to drift out of step.\n private readonly hovered = signal(false);\n private readonly focusWithin = signal(false);\n private readonly paused = computed(() => this.hovered() || this.focusWithin() || this.dragging());\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n constructor() {\n effect(() => {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n // `isBrowser` first: without it the prerender ran the timer too, doing work\n // nobody will ever see on a slide index that then gets serialized.\n if (!this.isBrowser || !this.autoplay() || this.paused() || this.count() < 2) return;\n const interval = this.intervalMs();\n this.timer = setInterval(() => this.next(), interval);\n });\n\n // `active` is a plain `model`, so `[(active)]` and a shrinking slide list both\n // write into it unchecked — a filtered list left it pointing past the end,\n // translating the track into blank space with no dot lit.\n effect(() => {\n const max = this.count() - 1;\n if (max < 0) return;\n const clamped = Math.min(Math.max(0, this.active()), max);\n if (clamped !== this.active()) this.active.set(clamped);\n });\n\n this.destroyRef.onDestroy(() => {\n if (this.timer) clearInterval(this.timer);\n });\n }\n\n protected onHoverIn(): void {\n this.hovered.set(true);\n }\n\n protected onHoverOut(): void {\n this.hovered.set(false);\n }\n\n protected onFocusIn(): void {\n this.focusWithin.set(true);\n }\n\n protected onFocusOut(): void {\n this.focusWithin.set(false);\n }\n\n // Imperative\n\n goTo(index: number): void {\n const max = this.count() - 1;\n if (max < 0) return;\n if (this.loop()) {\n const next = ((index % this.count()) + this.count()) % this.count();\n this.active.set(next);\n } else {\n this.active.set(Math.min(Math.max(0, index), max));\n }\n }\n\n next(): void {\n this.goTo(this.active() + 1);\n }\n\n prev(): void {\n this.goTo(this.active() - 1);\n }\n\n // Swipe navigation — the track follows the finger; releasing past ~20% of the\n // viewport advances a slide, otherwise snaps back. Which way that is follows\n // the reading direction: dragging toward the inline start (left in LTR, right\n // in RTL) pulls the next slide into view.\n\n private swipeStartX = 0;\n\n protected onSwipeStart(event: TouchEvent): void {\n const touch = event.touches[0];\n if (!touch) return;\n this.swipeStartX = touch.clientX;\n this.dragging.set(true); // holds autoplay on its own — `paused` reads it\n }\n\n protected onSwipeMove(event: TouchEvent): void {\n if (!this.dragging()) return;\n const touch = event.touches[0];\n if (!touch) return;\n this.dragX.set(touch.clientX - this.swipeStartX);\n }\n\n protected onSwipeEnd(event: TouchEvent, viewport: HTMLElement): void {\n if (!this.dragging()) return;\n this.dragging.set(false);\n const dx = this.dragX();\n this.dragX.set(0);\n const threshold = (viewport.offsetWidth || 0) * 0.2;\n // `dx` is a physical delta. The next slide sits to the physical RIGHT in LTR\n // and to the LEFT in RTL, so the drag that pulls it into view — and with it\n // the sign that advances — turns around with the direction. The buttons keep\n // their semantics either way; only the gesture is physical.\n const advance = this.isRtl() ? dx >= threshold : dx <= -threshold;\n const retreat = this.isRtl() ? dx <= -threshold : dx >= threshold;\n if (advance) this.next();\n else if (retreat) this.prev();\n }\n}\n","<div\n #viewport\n class=\"wr-carousel__viewport\"\n role=\"group\"\n [attr.aria-roledescription]=\"resolvedRoledescription()\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n (touchstart)=\"onSwipeStart($event)\"\n (touchmove)=\"onSwipeMove($event)\"\n (touchend)=\"onSwipeEnd($event, viewport)\"\n (touchcancel)=\"onSwipeEnd($event, viewport)\"\n>\n <div class=\"wr-carousel__track\" [style.transform]=\"trackStyle()\" [style.transition]=\"dragging() ? 'none' : null\">\n <ng-content />\n </div>\n</div>\n\n@if (showArrows() && count() > 1) {\n <button\n type=\"button\"\n class=\"wr-carousel__nav wr-carousel__nav--prev\"\n [attr.aria-label]=\"resolvedPrevLabel()\"\n (click)=\"prev()\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n <path d=\"M9 2 L4 7 L9 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-carousel__nav wr-carousel__nav--next\"\n [attr.aria-label]=\"resolvedNextLabel()\"\n (click)=\"next()\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n <path d=\"M5 2 L10 7 L5 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </button>\n}\n\n@if (showDots() && count() > 1) {\n <div class=\"wr-carousel__dots\" role=\"group\" [attr.aria-label]=\"resolvedPaginationLabel()\">\n @for (slide of slides(); track $index) {\n <button\n type=\"button\"\n class=\"wr-carousel__dot\"\n [class.wr-carousel__dot--active]=\"$index === active()\"\n [attr.aria-current]=\"$index === active() ? 'true' : null\"\n [attr.aria-label]=\"slideLabel({ index: $index + 1 })\"\n (click)=\"goTo($index)\"\n ></button>\n }\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;AAAA;;;;;AAKG;AA0BH;MACa,WAAW,GAAG,IAAI,cAAc,CAAoB,aAAa;;AChC9E;;;;;AAKG;AAQH;;;;;;;;;;;;;;;AAeG;MAaU,eAAe,CAAA;IACT,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAEnE;;;AAGG;IACM,eAAe,GAAG,KAAK,CAAgB,IAAI;wFAAC;;;IAIlC,uBAAuB,GAAG,WAAW,CACtD,IAAI,CAAC,eAAe,EACpB,+BAA+B,EAC/B,OAAO,CACR;AAED;;;;;;;AAOG;AACgB,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;QAC3C,IAAI,CAAC,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,KAAK;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;AACzC,QAAA,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;IACvD,CAAC;kFAAC;uGA7BS,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAf,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAe,yeAVhB,gBAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAUf,eAAe,EAAA,UAAA,EAAA,CAAA;kBAZ3B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,mBAAmB;AAC7B,oBAAA,QAAQ,EAAE,gBAAgB;oBAC1B,aAAa,EAAE,iBAAiB,CAAC,IAAI;AACrC,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,mBAAmB;AAC1B,wBAAA,IAAI,EAAE,OAAO;AACb,wBAAA,6BAA6B,EAAE,2BAA2B;AAC1D,wBAAA,cAAc,EAAE,yBAAyB;AACzC,wBAAA,oBAAoB,EAAE,6BAA6B;AACpD,qBAAA;AACF,iBAAA;;;ACxCD;;;;;AAKG;AAyBH;;;;;;;;;;;;;;AAcG;MAwBU,UAAU,CAAA;;IAEZ,SAAS,GAAG,KAAK,CAAgB,IAAI;kFAAC;;IAGtC,SAAS,GAAG,KAAK,CAAgB,IAAI;kFAAC;;IAGtC,eAAe,GAAG,KAAK,CAAgB,IAAI;wFAAC;IAElC,iBAAiB,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,gBAAgB,CAAC;IAClF,iBAAiB,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,YAAY,CAAC;IAC9E,uBAAuB,GAAG,WAAW,CACtD,IAAI,CAAC,eAAe,EACpB,qBAAqB,EACrB,qBAAqB,CACtB;;IAGQ,SAAS,GAAG,KAAK,CAAgB,IAAI;kFAAC;IAE5B,iBAAiB,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,EAAE,UAAU,CAAC;AAEhG;;;AAGG;IACM,eAAe,GAAG,KAAK,CAAgB,IAAI;wFAAC;;;;IAKlC,uBAAuB,GAAG,WAAW,CACtD,IAAI,CAAC,eAAe,EACpB,0BAA0B,EAC1B,UAAU,CACX;;;AAIkB,IAAA,UAAU,GAAG,gBAAgB,CAAC,oBAAoB,EAAE,uBAAuB,CAAC;;IAGtF,MAAM,GAAG,KAAK,CAAC,CAAC;+EAAC;;IAGjB,UAAU,GAAG,KAAK,CAAC,IAAI,kFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;;IAG9D,QAAQ,GAAG,KAAK,CAAC,IAAI,gFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;;IAG5D,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;;IAG7D,UAAU,GAAG,KAAK,CAAC,IAAI,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,YAAA,EAAA,8BAAA,EAAA,CAAA,EAC9B,SAAS,EAAE,CAAC,CAAU,KAAa,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAA,CAC/E;;IAGO,IAAI,GAAG,KAAK,CAAC,IAAI,4EAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;IAE9C,MAAM,GAAG,eAAe,CAAC,eAAe;+EAAC;IACzC,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM;8EAAC;AAE/D;;;;;;AAMG;AACH,IAAA,OAAO,CAAC,KAAa,EAAA;QACnB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,KAAwB,CAAC;IACxD;;IAGmB,KAAK,GAAG,MAAM,CAAC,CAAC;8EAAC;IACjB,QAAQ,GAAG,MAAM,CAAC,KAAK;iFAAC;IAE1B,GAAG,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAEjE;;;;;;;AAOG;AACc,IAAA,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,KAAK;8EAAC;;AAGvD,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAK;;;;;QAK5C,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG;;;AAG1D,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE;AACzB,QAAA,OAAO,IAAI,KAAK,CAAC,GAAG,CAAA,WAAA,EAAc,IAAI,CAAA,EAAA,CAAI,GAAG,CAAA,gBAAA,EAAmB,IAAI,CAAA,IAAA,EAAO,IAAI,MAAM;IACvF,CAAC;mFAAC;IAEM,KAAK,GAA0C,IAAI;;;;;;;;;IAU1C,OAAO,GAAG,MAAM,CAAC,KAAK;gFAAC;IACvB,WAAW,GAAG,MAAM,CAAC,KAAK;oFAAC;AAC3B,IAAA,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE;+EAAC;AAEhF,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAC/B,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEnE,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;YACV,IAAI,IAAI,CAAC,KAAK;AAAE,gBAAA,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;AACzC,YAAA,IAAI,CAAC,KAAK,GAAG,IAAI;;;YAGjB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC;gBAAE;AAC9E,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE;AAClC,YAAA,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC;AACvD,QAAA,CAAC,CAAC;;;;QAKF,MAAM,CAAC,MAAK;YACV,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC;YAC5B,IAAI,GAAG,GAAG,CAAC;gBAAE;YACb,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC;AACzD,YAAA,IAAI,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE;AAAE,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;AACzD,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;YAC7B,IAAI,IAAI,CAAC,KAAK;AAAE,gBAAA,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;AAC3C,QAAA,CAAC,CAAC;IACJ;IAEU,SAAS,GAAA;AACjB,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IACxB;IAEU,UAAU,GAAA;AAClB,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;IACzB;IAEU,SAAS,GAAA;AACjB,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;IAC5B;IAEU,UAAU,GAAA;AAClB,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;IAC7B;;AAIA,IAAA,IAAI,CAAC,KAAa,EAAA;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC;QAC5B,IAAI,GAAG,GAAG,CAAC;YAAE;AACb,QAAA,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE;YACf,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE;AACnE,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QACvB;aAAO;YACL,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;QACpD;IACF;IAEA,IAAI,GAAA;QACF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B;IAEA,IAAI,GAAA;QACF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B;;;;;IAOQ,WAAW,GAAG,CAAC;AAEb,IAAA,YAAY,CAAC,KAAiB,EAAA;QACtC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC9B,QAAA,IAAI,CAAC,KAAK;YAAE;AACZ,QAAA,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO;QAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B;AAEU,IAAA,WAAW,CAAC,KAAiB,EAAA;AACrC,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAAE;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC9B,QAAA,IAAI,CAAC,KAAK;YAAE;AACZ,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC;IAClD;IAEU,UAAU,CAAC,KAAiB,EAAE,QAAqB,EAAA;AAC3D,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAAE;AACtB,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AACxB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE;AACvB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACjB,MAAM,SAAS,GAAG,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,IAAI,GAAG;;;;;AAKnD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,SAAS,GAAG,EAAE,IAAI,CAAC,SAAS;AACjE,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,GAAG,EAAE,IAAI,SAAS;AACjE,QAAA,IAAI,OAAO;YAAE,IAAI,CAAC,IAAI,EAAE;AACnB,aAAA,IAAI,OAAO;YAAE,IAAI,CAAC,IAAI,EAAE;IAC/B;uGA5NW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,MAAA,EAAA,cAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,YAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,SAAA,EAAA,aAAA,EAAA,UAAA,EAAA,cAAA,EAAA,EAAA,cAAA,EAAA,aAAA,EAAA,EAAA,SAAA,EARV;AACT,YAAA;AACE,gBAAA,OAAO,EAAE,WAAW;;AAEpB,gBAAA,WAAW,EAAE,UAAU,CAAC,MAAM,UAAU,CAAC;AAC1C,aAAA;SACF,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,QAAA,EAAA,SAAA,EAgE2C,eAAe,6CClI7D,i1DAqDA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDea,UAAU,EAAA,UAAA,EAAA,CAAA;kBAvBtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,aAAa,EAAA,aAAA,EAER,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAK/B;AACJ,wBAAA,KAAK,EAAE,aAAa;AACpB,wBAAA,cAAc,EAAE,aAAa;AAC7B,wBAAA,cAAc,EAAE,cAAc;AAC9B,wBAAA,WAAW,EAAE,aAAa;AAC1B,wBAAA,YAAY,EAAE,cAAc;qBAC7B,EAAA,SAAA,EACU;AACT,wBAAA;AACE,4BAAA,OAAO,EAAE,WAAW;;AAEpB,4BAAA,WAAW,EAAE,UAAU,CAAC,gBAAgB,CAAC;AAC1C,yBAAA;AACF,qBAAA,EAAA,QAAA,EAAA,i1DAAA,EAAA;muCAgE2C,eAAe,CAAA,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AElI7D;;AAEG;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-cascader-testing.mjs","sources":["../../../projects/lib/cascader/testing/wr-cascader-option-harness.ts","../../../projects/lib/cascader/testing/wr-cascader-column-harness.ts","../../../projects/lib/cascader/testing/wr-cascader-harness.ts","../../../projects/lib/cascader/testing/ngwr-cascader-testing.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 { ComponentHarness, HarnessPredicate, TestKey } from '@angular/cdk/testing';\n\nimport type { WrCascaderOptionHarnessFilters } from './interfaces';\n\n/**\n * Test harness for one option inside a `<wr-cascader>` column.\n *\n * An option is either a BRANCH (it has children, so clicking it opens the next\n * column) or a LEAF (clicking it commits the whole path and closes the panel).\n * {@link hasChildren} reads the chevron the template draws for branches;\n * {@link isExpanded} reads the state that same branch announces. The two are\n * not one question — a branch always HAS children and is expanded only while\n * the column to its right is showing them.\n *\n * The panel is a `role=\"tree\"` and an option is a `treeitem`. It was a `menu`\n * of `menuitem`s until the roles were corrected, and this class documented that\n * a branch announced nothing at all; both are historical now.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCascaderOptionHarness extends ComponentHarness {\n /** The `<li role=\"treeitem\">` a column renders per option. */\n static hostSelector = '.wr-cascader__opt';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCascaderOptionHarnessFilters = {}): HarnessPredicate<WrCascaderOptionHarness> {\n return new HarnessPredicate(WrCascaderOptionHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('active', options.active, async (harness, active) => (await harness.isActive()) === active)\n .addOption(\n 'hasChildren',\n options.hasChildren,\n async (harness, hasChildren) => (await harness.hasChildren()) === hasChildren\n );\n }\n\n /** The option's label, trimmed. The branch chevron contributes no text. */\n async getText(): Promise<string> {\n return (await this.locatorFor('.wr-cascader__opt-label')()).text();\n }\n\n /** The role the option announces — `treeitem`. */\n async getRole(): Promise<string | null> {\n return (await this.host()).getAttribute('role');\n }\n\n /** Whether the option refuses selection, from the state a screen reader is given. */\n async isDisabled(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-disabled')) === 'true';\n }\n\n /**\n * Whether this is the option its column is currently drilled into — the one\n * whose children the column to the right is showing, or the committed segment\n * at this level.\n *\n * Read from the `--active` modifier, and NOT the same question as\n * {@link isSelected}: this one tracks where the user has navigated, that one\n * tracks what they committed. They agree only once a leaf is picked, and a\n * harness that collapsed them would hide exactly the divergence it exists to\n * catch.\n */\n async isActive(): Promise<boolean> {\n return (await this.host()).hasClass('wr-cascader__opt--active');\n }\n\n /**\n * Whether this option is the committed choice, or `null` when it is not a\n * choice at all.\n *\n * `null` — the attribute absent — for a branch while `changeOnSelect` is off,\n * because such a branch genuinely cannot be chosen. Answering a plausible\n * `false` there would report an unselectable row as merely unselected, which\n * is the distinction the attribute exists to carry.\n */\n async isSelected(): Promise<boolean | null> {\n const raw = await (await this.host()).getAttribute('aria-selected');\n return raw === null ? null : raw === 'true';\n }\n\n /**\n * Whether this branch's children are the column to its right, or `null` for a\n * leaf.\n *\n * `null` rather than `false`, and the difference is the whole point: a leaf\n * does not have a collapsed subtree, it has none. `aria-expanded=\"false\"` on\n * one would state that a subtree exists and is shut.\n */\n async isExpanded(): Promise<boolean | null> {\n const raw = await (await this.host()).getAttribute('aria-expanded');\n return raw === null ? null : raw === 'true';\n }\n\n /**\n * The option's depth, 1-based — its `aria-level`.\n *\n * Worth reading in a spec rather than trusting: the columns are DOM SIBLINGS,\n * so nothing about the markup's shape carries depth. Every option would be\n * level 1 if this attribute were dropped, and no gate would say so.\n */\n async getLevel(): Promise<number | null> {\n const raw = await (await this.host()).getAttribute('aria-level');\n return raw === null ? null : Number.parseInt(raw, 10);\n }\n\n /** Whether the option opens a deeper level rather than ending the path. */\n async hasChildren(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-cascader__opt-arrow')()) !== null;\n }\n\n /**\n * The option's tab index — `0` for every enabled option, `-1` for a disabled\n * one.\n *\n * Worth asking: a cascader column is NOT a roving-cursor listbox. Every\n * enabled option is its own tab stop, in every column, which is the documented\n * reason virtual scrolling is deferred for this component — there is no\n * container-owned arrow-nav model to hang a window off.\n *\n * Read as the element's `tabIndex` PROPERTY rather than the attribute, so an\n * option that carried no `tabindex` at all answers `-1` — what the DOM says of a\n * bare `<li>` — instead of a made-up `0` that would report an unfocusable option\n * as a tab stop if this component ever moved to a roving cursor.\n */\n async getTabIndex(): Promise<number> {\n return (await this.host()).getProperty<number>('tabIndex');\n }\n\n /**\n * Click the option: a branch opens its children to the right, a leaf commits\n * the path and closes the panel.\n *\n * A disabled option is clickable here on purpose — the component refuses it in\n * its own handler rather than through `pointer-events`, so the click a spec\n * dispatches is exactly as ineffective as one in a browser.\n */\n async click(): Promise<void> {\n return (await this.host()).click();\n }\n\n /**\n * Activate the option from the keyboard (Enter; Space is bound to the same\n * handler).\n *\n * This is the component's entire keyboard model — the columns bind\n * `keydown.enter` / `keydown.space` per option and nothing else, so there are\n * no arrow keys to walk levels with. A keyboard user reaches the option they\n * want with Tab and presses Enter. Opening the panel does move focus into it —\n * `focusPanelOption()` lands on the active option, or the first enabled one —\n * so the walk starts there rather than from the trigger; this JSDoc claimed\n * the opposite for a while and was simply wrong.\n */\n async selectByKeyboard(): Promise<void> {\n return (await this.host()).sendKeys(TestKey.ENTER);\n }\n\n /**\n * Move the pointer onto the option.\n *\n * Deliberately does NOT expand a branch: this cascader drills down on CLICK\n * only, unlike the hover-to-expand cascaders elsewhere. Kept because a spec\n * may want to pin that, and because the option's hover tint is styled.\n */\n async hover(): Promise<void> {\n return (await this.host()).hover();\n }\n\n /** Move keyboard focus to the option. */\n async focus(): Promise<void> {\n return (await this.host()).focus();\n }\n\n /** Whether the option holds keyboard focus. */\n async isFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport type { WrCascaderColumnHarnessFilters, WrCascaderOptionHarnessFilters } from './interfaces';\nimport { WrCascaderOptionHarness } from './wr-cascader-option-harness';\n\n/**\n * Test harness for one COLUMN of an open `<wr-cascader>` panel.\n *\n * A column is a level of the tree: column 0 holds the root options, and each\n * further column holds the children of the active option in the column before\n * it. Which columns exist is therefore a function of what is expanded — the\n * relationship this harness exists to let a spec assert. Column 0 is always\n * there; a column only appears once there are children to put in it, so a leaf\n * adds none.\n *\n * @example\n * ```ts\n * const [countries, cities] = await cascader.getColumns();\n *\n * expect(await countries.getActiveOptionText()).toBe('Germany');\n * expect(await cities.getOptionLabels()).toEqual(['Berlin']);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCascaderColumnHarness extends ComponentHarness {\n /** The `<ul role=\"group\">` the panel renders per level, inside the `tree`. */\n static hostSelector = '.wr-cascader__col';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCascaderColumnHarnessFilters = {}): HarnessPredicate<WrCascaderColumnHarness> {\n return new HarnessPredicate(WrCascaderColumnHarness, options).addOption(\n 'optionText',\n options.optionText,\n async (harness, text) => {\n for (const label of await harness.getOptionLabels()) {\n if (await HarnessPredicate.stringMatches(label, text)) return true;\n }\n return false;\n }\n );\n }\n\n /** The role the column announces — `group`, inside the panel's `tree`. */\n async getRole(): Promise<string | null> {\n return (await this.host()).getAttribute('role');\n }\n\n /** The options this level offers, in order. */\n async getOptions(filters: WrCascaderOptionHarnessFilters = {}): Promise<WrCascaderOptionHarness[]> {\n return this.locatorForAll(WrCascaderOptionHarness.with(filters))();\n }\n\n /** The labels this level offers, in order. */\n async getOptionLabels(): Promise<string[]> {\n const options = await this.getOptions();\n return Promise.all(options.map(option => option.getText()));\n }\n\n /**\n * The first option matching the filters.\n *\n * Throws rather than answering `null`, and names what the column does offer:\n * a missing option here almost always means the level is not the one the spec\n * thought it was, and that is far easier to see with the alternatives listed.\n */\n async getOption(filters: WrCascaderOptionHarnessFilters): Promise<WrCascaderOptionHarness> {\n const [option] = await this.getOptions(filters);\n if (!option) {\n throw new Error(\n `WrCascaderColumnHarness.getOption(): no option matched ${JSON.stringify(filters)}. ` +\n `This column offers: ${(await this.getOptionLabels()).join(', ')}.`\n );\n }\n return option;\n }\n\n /** The option this level is drilled into, or `null` when nothing here is expanded. */\n async getActiveOption(): Promise<WrCascaderOptionHarness | null> {\n const [active] = await this.getOptions({ active: true });\n return active ?? null;\n }\n\n /** The label of the option this level is drilled into, or `null`. */\n async getActiveOptionText(): Promise<string | null> {\n const active = await this.getActiveOption();\n return active ? active.getText() : null;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport {\n ComponentHarness,\n type HarnessLoader,\n HarnessPredicate,\n TestKey,\n type TestElement,\n} from '@angular/cdk/testing';\n\nimport type {\n WrCascaderColumnHarnessFilters,\n WrCascaderHarnessFilters,\n WrCascaderOptionHarnessFilters,\n} from './interfaces';\nimport { WrCascaderColumnHarness } from './wr-cascader-column-harness';\nimport type { WrCascaderOptionHarness } from './wr-cascader-option-harness';\n\n/**\n * Test harness for `<wr-cascader>` — the trigger, and the panel of COLUMNS it\n * opens. Root of a small family: {@link WrCascaderColumnHarness} for one level,\n * `WrCascaderOptionHarness` for one option in it.\n *\n * A cascader is not a select with extra steps. Its value is the whole PATH from\n * root to leaf (`['eu', 'de', 'ber']`, not `'ber'`), and the panel shows one\n * column per level, so which columns exist depends on what is expanded — column\n * 0 is the roots, and every further column holds the children of the active\n * option in the column to its left. That relationship is the component, so it is\n * what {@link getColumns} and {@link getColumnLabels} are for.\n *\n * The panel is NOT inside the cascader: it is a template portal in the overlay\n * container, a sibling of the whole app. Every read of it goes through the\n * document root scoped by the `aria-controls` id the trigger publishes, so two\n * cascaders on one page can never answer with each other's columns.\n *\n * @example\n * ```ts\n * const cascader = await loader.getHarness(WrCascaderHarness);\n *\n * await cascader.selectPath(['Europe', 'Germany', 'Berlin']);\n *\n * expect(await cascader.getValueText()).toBe('Europe / Germany / Berlin');\n * expect(await cascader.isOpen()).toBe(false);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCascaderHarness extends ComponentHarness {\n static hostSelector = 'wr-cascader';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCascaderHarnessFilters = {}): HarnessPredicate<WrCascaderHarness> {\n return new HarnessPredicate(WrCascaderHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getValueText(), text))\n .addOption('placeholder', options.placeholder, (harness, placeholder) =>\n HarnessPredicate.stringMatches(harness.getPlaceholder(), placeholder)\n )\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('open', options.open, async (harness, open) => (await harness.isOpen()) === open);\n }\n\n private readonly trigger = this.locatorFor('.wr-cascader__trigger');\n\n /**\n * Whether the panel is showing.\n *\n * From the trigger's `aria-expanded` rather than the host's `--open` class:\n * both exist, and the ARIA state is the one a screen-reader user is told.\n */\n async isOpen(): Promise<boolean> {\n return (await (await this.trigger()).getAttribute('aria-expanded')) === 'true';\n }\n\n /**\n * Whether the cascader refuses interaction.\n *\n * From the trigger's native `disabled`, which is what actually stops a pointer\n * and what assistive tech reports; the host's `--disabled` class only mirrors\n * it for styling.\n */\n async isDisabled(): Promise<boolean> {\n return (await this.trigger()).getProperty<boolean>('disabled');\n }\n\n /**\n * What the trigger displays as the selection: the labels of the whole path\n * joined by the `separator` (`'Europe / Germany / Berlin'` by default), or `''`\n * while nothing is selected and the placeholder is showing.\n *\n * The joined string is all the DOM has — the separator is not published\n * anywhere on its own, so the harness will not pretend it can split the path\n * back apart. Assert against the bound value, or against\n * {@link getActiveTrail} while the panel is open, when the segments matter.\n */\n async getValueText(): Promise<string> {\n const value = await this.locatorForOptional('.wr-cascader__value')();\n return value ? value.text() : '';\n }\n\n /**\n * The placeholder, or `null` when a selection is hiding it.\n *\n * `''` is a real answer, not an absence: a cascader with no `placeholder` still\n * renders the element while unselected.\n */\n async getPlaceholder(): Promise<string | null> {\n const placeholder = await this.locatorForOptional('.wr-cascader__placeholder')();\n return placeholder ? placeholder.text() : null;\n }\n\n /**\n * The trigger's accessible name — the `ariaLabel` input, falling back to the\n * placeholder and then to the i18n catalog, because a `role=\"combobox\"` with\n * nothing selected and no placeholder would otherwise have no name at all.\n */\n async getAccessibleName(): Promise<string | null> {\n return (await this.trigger()).getAttribute('aria-label');\n }\n\n /**\n * The kind of popup the trigger promises via `aria-haspopup` — `tree`.\n *\n * Worth pinning rather than assuming: a combobox's popup may be a listbox, a\n * tree, a grid or a dialog and nothing else, and this one said `menu` for a\n * long time. `menu` is a valid token for the global `aria-haspopup`, so axe\n * reports nothing either way — an assertion here is the only guard there is.\n */\n async getPopupRole(): Promise<string | null> {\n return (await this.trigger()).getAttribute('aria-haspopup');\n }\n\n /** The role the panel announces — `tree`, matching what the trigger promised. */\n async getPanelRole(): Promise<string | null> {\n return (await this.panel()).getAttribute('role');\n }\n\n /**\n * The id the trigger publishes as `aria-controls`.\n *\n * Published unconditionally, open or closed — so while the panel is closed this\n * id resolves to nothing in the document. Exposed so a spec can pin that\n * (dangling or not) rather than have the harness quietly decide for it; every\n * panel read goes through the same id but refuses to run while closed.\n */\n async getPanelId(): Promise<string | null> {\n return (await this.trigger()).getAttribute('aria-controls');\n }\n\n /**\n * Whether the panel now in the overlay is the one this trigger claims to\n * control — `aria-controls` resolving to a real element that carries that id.\n *\n * With several cascaders on a page it is also the check that the reference lands\n * on THIS instance's panel rather than a neighbour's: the overlay container is\n * shared, so panels sit side by side in it with nothing but their ids to tell\n * them apart.\n */\n async isPanelWiredToTrigger(): Promise<boolean> {\n const rendered = await (await this.panel()).getAttribute('id');\n return rendered !== null && rendered === (await this.getPanelId());\n }\n\n /**\n * Open the panel.\n *\n * Clicks the trigger, because that is the only gesture the component binds. The\n * trigger is a native `<button>`, so a browser turns Enter / Space on it into\n * the same click — there is no separate keyboard route to model here, and jsdom\n * does not synthesise button activation from a key, so an `openByKeyboard()`\n * would only be able to lie.\n */\n async open(): Promise<void> {\n if (await this.isOpen()) return;\n\n await (await this.trigger()).click();\n if (await this.isOpen()) return;\n\n throw new Error(\n 'WrCascaderHarness.open(): the panel did not open. A disabled cascader refuses the click — ' +\n 'check isDisabled().'\n );\n }\n\n /**\n * Close the panel with Escape. A closed cascader is left alone.\n *\n * Escape reaches the panel through the CDK's keyboard dispatcher rather than\n * through the DOM tree, which is why sending it to the trigger works even\n * though the panel is somewhere else entirely.\n */\n async close(): Promise<void> {\n if (!(await this.isOpen())) return;\n\n await (await this.trigger()).sendKeys(TestKey.ESCAPE);\n if (await this.isOpen()) {\n throw new Error('WrCascaderHarness.close(): Escape did not close the panel.');\n }\n }\n\n /** Click the trigger once, whatever that does — opens a closed panel, closes an open one. */\n async clickTrigger(): Promise<void> {\n return (await this.trigger()).click();\n }\n\n /**\n * The columns of the open panel, left to right: column 0 is the root options,\n * and each further one holds the children of its neighbour's active option.\n *\n * Throws while the panel is closed. The columns do not exist anywhere until the\n * portal is attached, and an empty array reads like a panel that rendered\n * nothing — a confusing failure three lines later instead of here.\n */\n async getColumns(filters: WrCascaderColumnHarnessFilters = {}): Promise<WrCascaderColumnHarness[]> {\n const loader = await this.panelLoader();\n return loader.getAllHarnesses(WrCascaderColumnHarness.with(filters));\n }\n\n /** How many levels the panel is currently showing. */\n async getColumnCount(): Promise<number> {\n return (await this.getColumns()).length;\n }\n\n /**\n * One column by its 0-based level. Throws when the level is not showing, which\n * is the interesting failure: it means the option before it has no children, or\n * has not been expanded yet.\n */\n async getColumn(index: number): Promise<WrCascaderColumnHarness> {\n const columns = await this.getColumns();\n const column = columns[index];\n if (!column) {\n throw new Error(\n `WrCascaderHarness.getColumn(): no column at level ${index} — the panel is showing ` +\n `${columns.length}. A deeper column appears only once a parent with children is expanded.`\n );\n }\n return column;\n }\n\n /** The labels offered by every column, outer array left to right. */\n async getColumnLabels(): Promise<string[][]> {\n const columns = await this.getColumns();\n return Promise.all(columns.map(column => column.getOptionLabels()));\n }\n\n /**\n * The expanded trail — the label of the active option in each column, root\n * first.\n *\n * This is the panel's own idea of where the user is, which is NOT always the\n * committed value: drilling into a branch moves the trail without committing\n * anything unless `changeOnSelect` is on. Once a leaf is picked the two agree,\n * and this is the only place the path's segments exist separately in the DOM.\n */\n async getActiveTrail(): Promise<string[]> {\n const trail: string[] = [];\n for (const column of await this.getColumns()) {\n const active = await column.getActiveOptionText();\n if (active !== null) trail.push(active);\n }\n return trail;\n }\n\n /**\n * The first option matching the filters, anywhere in the panel. Throws when\n * nothing matches, naming what is on offer.\n *\n * Use {@link getColumn} when the level matters — the same label can legitimately\n * appear at more than one level.\n */\n async getOption(filters: WrCascaderOptionHarnessFilters): Promise<WrCascaderOptionHarness> {\n for (const column of await this.getColumns()) {\n const [option] = await column.getOptions(filters);\n if (option) return option;\n }\n\n throw new Error(\n `WrCascaderHarness.getOption(): no option matched ${JSON.stringify(filters)}. ` +\n `The panel offers: ${(await this.getColumnLabels()).map(labels => labels.join(', ')).join(' | ')}.`\n );\n }\n\n /**\n * Walk a path by label, opening the panel first if needed: each label is\n * clicked in the column it belongs to, so `['Europe', 'Germany', 'Berlin']`\n * drills two levels and commits the third.\n *\n * Clicking is the only way down — this cascader does not expand on hover, so\n * neither does the harness. A path that ends on a BRANCH just leaves that\n * branch expanded: the component commits nothing on the way down unless\n * `changeOnSelect` is on, and only a leaf closes the panel.\n */\n async selectPath(labels: readonly string[]): Promise<void> {\n if (labels.length === 0) {\n throw new Error(\n 'WrCascaderHarness.selectPath(): the path is empty. Pass at least one label, or call clear() ' +\n 'to unset the selection.'\n );\n }\n\n await this.open();\n\n for (let level = 0; level < labels.length; level++) {\n const label = labels[level];\n const columns = await this.getColumns();\n const column = columns[level];\n if (!column) {\n throw new Error(\n `WrCascaderHarness.selectPath(): \"${label}\" would be at level ${level}, but the panel is ` +\n `showing ${columns.length} column(s) — the step before it opened no deeper level.`\n );\n }\n\n const option = await column.getOption({ text: label });\n if (await option.isDisabled()) {\n throw new Error(`WrCascaderHarness.selectPath(): \"${label}\" is disabled, so no path can pass through it.`);\n }\n\n const isLast = level === labels.length - 1;\n if (!isLast && !(await option.hasChildren())) {\n throw new Error(\n `WrCascaderHarness.selectPath(): \"${label}\" is a leaf, so the path cannot continue to ` +\n `\"${labels[level + 1]}\" — picking it commits and closes the panel.`\n );\n }\n\n await option.click();\n }\n }\n\n /**\n * Click the clear (×) control on the trigger.\n *\n * Throws when there is none, and both reasons are worth failing on: the\n * cascader is not `clearable`, or nothing is selected — the control is not\n * rendered at all in either case (nor while disabled).\n */\n async clear(): Promise<void> {\n const clear = await this.locatorForOptional('.wr-cascader__clear')();\n if (!clear) {\n throw new Error(\n 'WrCascaderHarness.clear(): this cascader shows no clear control — it is rendered only when ' +\n '`clearable` is on, something is selected, and the control is enabled.'\n );\n }\n await clear.click();\n }\n\n /**\n * Clear from the keyboard — Backspace on the closed trigger.\n *\n * The × {@link clear} clicks is a `tabindex=\"-1\"` span inside the trigger, so no\n * key can ever reach it; Backspace on the trigger is its keyboard twin, and the\n * route a keyboard-only user actually has. Prefer this one in a spec that cares\n * about that user — {@link clear} proves the pointer path and nothing more.\n *\n * The component honours the key only on the CLOSED trigger, so an open panel\n * is closed first with Escape — the step a keyboard user takes too. Sending\n * Backspace into an open panel and returning would be a plausible nothing.\n *\n * Does nothing, rather than throwing, when there is nothing to clear, `clearable`\n * is off, or the cascader is disabled or read-only: that silence IS the\n * component's contract, so a spec asserts it on the value.\n */\n async clearByKeyboard(): Promise<void> {\n if (await this.isOpen()) await this.close();\n await (await this.trigger()).sendKeys(TestKey.BACKSPACE);\n }\n\n /** Move keyboard focus to the trigger. */\n async focus(): Promise<void> {\n return (await this.trigger()).focus();\n }\n\n /** Take focus off the trigger, which is what makes a bound form field touched. */\n async blur(): Promise<void> {\n return (await this.trigger()).blur();\n }\n\n /** Whether the trigger holds keyboard focus. */\n async isFocused(): Promise<boolean> {\n return (await this.trigger()).isFocused();\n }\n\n /** This cascader's panel element in the overlay — the single-element scoped read. */\n private async panel(): Promise<TestElement> {\n return this.documentRootLocatorFactory().locatorFor(`#${await this.panelId()}`)();\n }\n\n /**\n * A loader scoped to THIS cascader's panel — the list scoped read.\n *\n * Scoped by the published id rather than by `.wr-cascader-panel`: the overlay\n * container is shared with every other overlay in the app, so a bare class\n * query would answer with whichever panel happened to be open.\n */\n private async panelLoader(): Promise<HarnessLoader> {\n return this.documentRootLocatorFactory().harnessLoaderFor(`#${await this.panelId()}`);\n }\n\n /** The panel id, refusing to hand it out while there is no panel to find. */\n private async panelId(): Promise<string> {\n if (!(await this.isOpen())) {\n throw new Error(\n 'WrCascaderHarness: the panel is closed, so there are no columns to read — call open() or ' +\n 'selectPath() first. The trigger publishes `aria-controls` even while closed, so the id ' +\n 'alone is not proof the panel exists.'\n );\n }\n\n const id = await this.getPanelId();\n if (!id) {\n throw new Error('WrCascaderHarness: the trigger publishes no `aria-controls`, so its panel cannot be found.');\n }\n return id;\n }\n}\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-testing.mjs","sources":["../../../projects/lib/cascader/testing/wr-cascader-option-harness.ts","../../../projects/lib/cascader/testing/wr-cascader-column-harness.ts","../../../projects/lib/cascader/testing/wr-cascader-harness.ts","../../../projects/lib/cascader/testing/ngwr-cascader-testing.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 { ComponentHarness, HarnessPredicate, TestKey } from '@angular/cdk/testing';\n\nimport type { WrCascaderOptionHarnessFilters } from './interfaces';\n\n/**\n * Test harness for one option inside a `<wr-cascader>` column.\n *\n * An option is either a BRANCH (it has children, so clicking it opens the next\n * column) or a LEAF (clicking it commits the whole path and closes the panel).\n * {@link hasChildren} reads the chevron the template draws for branches;\n * {@link isExpanded} reads the state that same branch announces. The two are\n * not one question — a branch always HAS children and is expanded only while\n * the column to its right is showing them.\n *\n * The panel is a `role=\"tree\"` and an option is a `treeitem`. It was a `menu`\n * of `menuitem`s until the roles were corrected, and this class documented that\n * a branch announced nothing at all; both are historical now.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCascaderOptionHarness extends ComponentHarness {\n /** The `<li role=\"treeitem\">` a column renders per option. */\n static hostSelector = '.wr-cascader__opt';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCascaderOptionHarnessFilters = {}): HarnessPredicate<WrCascaderOptionHarness> {\n return new HarnessPredicate(WrCascaderOptionHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('active', options.active, async (harness, active) => (await harness.isActive()) === active)\n .addOption(\n 'hasChildren',\n options.hasChildren,\n async (harness, hasChildren) => (await harness.hasChildren()) === hasChildren\n );\n }\n\n /** The option's label, trimmed. The branch chevron contributes no text. */\n async getText(): Promise<string> {\n return (await this.locatorFor('.wr-cascader__opt-label')()).text();\n }\n\n /** The role the option announces — `treeitem`. */\n async getRole(): Promise<string | null> {\n return (await this.host()).getAttribute('role');\n }\n\n /** Whether the option refuses selection, from the state a screen reader is given. */\n async isDisabled(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-disabled')) === 'true';\n }\n\n /**\n * Whether this is the option its column is currently drilled into — the one\n * whose children the column to the right is showing, or the committed segment\n * at this level.\n *\n * Read from the `--active` modifier, and NOT the same question as\n * {@link isSelected}: this one tracks where the user has navigated, that one\n * tracks what they committed. They agree only once a leaf is picked, and a\n * harness that collapsed them would hide exactly the divergence it exists to\n * catch.\n */\n async isActive(): Promise<boolean> {\n return (await this.host()).hasClass('wr-cascader__opt--active');\n }\n\n /**\n * Whether this option is the committed choice, or `null` when it is not a\n * choice at all.\n *\n * `null` — the attribute absent — for a branch while `changeOnSelect` is off,\n * because such a branch genuinely cannot be chosen. Answering a plausible\n * `false` there would report an unselectable row as merely unselected, which\n * is the distinction the attribute exists to carry.\n */\n async isSelected(): Promise<boolean | null> {\n const raw = await (await this.host()).getAttribute('aria-selected');\n return raw === null ? null : raw === 'true';\n }\n\n /**\n * Whether this branch's children are the column to its right, or `null` for a\n * leaf.\n *\n * `null` rather than `false`, and the difference is the whole point: a leaf\n * does not have a collapsed subtree, it has none. `aria-expanded=\"false\"` on\n * one would state that a subtree exists and is shut.\n */\n async isExpanded(): Promise<boolean | null> {\n const raw = await (await this.host()).getAttribute('aria-expanded');\n return raw === null ? null : raw === 'true';\n }\n\n /**\n * The option's depth, 1-based — its `aria-level`.\n *\n * Worth reading in a spec rather than trusting: the columns are DOM SIBLINGS,\n * so nothing about the markup's shape carries depth. Every option would be\n * level 1 if this attribute were dropped, and no gate would say so.\n */\n async getLevel(): Promise<number | null> {\n const raw = await (await this.host()).getAttribute('aria-level');\n return raw === null ? null : Number.parseInt(raw, 10);\n }\n\n /** Whether the option opens a deeper level rather than ending the path. */\n async hasChildren(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-cascader__opt-arrow')()) !== null;\n }\n\n /**\n * The option's tab index — `0` for every enabled option, `-1` for a disabled\n * one.\n *\n * Worth asking: a cascader column is NOT a roving-cursor listbox. Every\n * enabled option is its own tab stop, in every column, which is the documented\n * reason virtual scrolling is deferred for this component — there is no\n * container-owned arrow-nav model to hang a window off.\n *\n * Read as the element's `tabIndex` PROPERTY rather than the attribute, so an\n * option that carried no `tabindex` at all answers `-1` — what the DOM says of a\n * bare `<li>` — instead of a made-up `0` that would report an unfocusable option\n * as a tab stop if this component ever moved to a roving cursor.\n */\n async getTabIndex(): Promise<number> {\n return (await this.host()).getProperty<number>('tabIndex');\n }\n\n /**\n * Click the option: a branch opens its children to the right, a leaf commits\n * the path and closes the panel.\n *\n * A disabled option is clickable here on purpose — the component refuses it in\n * its own handler rather than through `pointer-events`, so the click a spec\n * dispatches is exactly as ineffective as one in a browser.\n */\n async click(): Promise<void> {\n return (await this.host()).click();\n }\n\n /**\n * Activate the option from the keyboard (Enter; Space is bound to the same\n * handler).\n *\n * This is the component's entire keyboard model — the columns bind\n * `keydown.enter` / `keydown.space` per option and nothing else, so there are\n * no arrow keys to walk levels with. A keyboard user reaches the option they\n * want with Tab and presses Enter. Opening the panel does move focus into it —\n * `focusPanelOption()` lands on the active option, or the first enabled one —\n * so the walk starts there rather than from the trigger; this JSDoc claimed\n * the opposite for a while and was simply wrong.\n */\n async selectByKeyboard(): Promise<void> {\n return (await this.host()).sendKeys(TestKey.ENTER);\n }\n\n /**\n * Move the pointer onto the option.\n *\n * Deliberately does NOT expand a branch: this cascader drills down on CLICK\n * only, unlike the hover-to-expand cascaders elsewhere. Kept because a spec\n * may want to pin that, and because the option's hover tint is styled.\n */\n async hover(): Promise<void> {\n return (await this.host()).hover();\n }\n\n /** Move keyboard focus to the option. */\n async focus(): Promise<void> {\n return (await this.host()).focus();\n }\n\n /** Whether the option holds keyboard focus. */\n async isFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport type { WrCascaderColumnHarnessFilters, WrCascaderOptionHarnessFilters } from './interfaces';\nimport { WrCascaderOptionHarness } from './wr-cascader-option-harness';\n\n/**\n * Test harness for one COLUMN of an open `<wr-cascader>` panel.\n *\n * A column is a level of the tree: column 0 holds the root options, and each\n * further column holds the children of the active option in the column before\n * it. Which columns exist is therefore a function of what is expanded — the\n * relationship this harness exists to let a spec assert. Column 0 is always\n * there; a column only appears once there are children to put in it, so a leaf\n * adds none.\n *\n * @example\n * ```ts\n * const [countries, cities] = await cascader.getColumns();\n *\n * expect(await countries.getActiveOptionText()).toBe('Germany');\n * expect(await cities.getOptionLabels()).toEqual(['Berlin']);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCascaderColumnHarness extends ComponentHarness {\n /** The `<ul role=\"group\">` the panel renders per level, inside the `tree`. */\n static hostSelector = '.wr-cascader__col';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCascaderColumnHarnessFilters = {}): HarnessPredicate<WrCascaderColumnHarness> {\n return new HarnessPredicate(WrCascaderColumnHarness, options).addOption(\n 'optionText',\n options.optionText,\n async (harness, text) => {\n for (const label of await harness.getOptionLabels()) {\n if (await HarnessPredicate.stringMatches(label, text)) return true;\n }\n return false;\n }\n );\n }\n\n /** The role the column announces — `group`, inside the panel's `tree`. */\n async getRole(): Promise<string | null> {\n return (await this.host()).getAttribute('role');\n }\n\n /** The options this level offers, in order. */\n async getOptions(filters: WrCascaderOptionHarnessFilters = {}): Promise<WrCascaderOptionHarness[]> {\n return this.locatorForAll(WrCascaderOptionHarness.with(filters))();\n }\n\n /** The labels this level offers, in order. */\n async getOptionLabels(): Promise<string[]> {\n const options = await this.getOptions();\n return Promise.all(options.map(option => option.getText()));\n }\n\n /**\n * The first option matching the filters.\n *\n * Throws rather than answering `null`, and names what the column does offer:\n * a missing option here almost always means the level is not the one the spec\n * thought it was, and that is far easier to see with the alternatives listed.\n */\n async getOption(filters: WrCascaderOptionHarnessFilters): Promise<WrCascaderOptionHarness> {\n const [option] = await this.getOptions(filters);\n if (!option) {\n throw new Error(\n `WrCascaderColumnHarness.getOption(): no option matched ${JSON.stringify(filters)}. ` +\n `This column offers: ${(await this.getOptionLabels()).join(', ')}.`\n );\n }\n return option;\n }\n\n /** The option this level is drilled into, or `null` when nothing here is expanded. */\n async getActiveOption(): Promise<WrCascaderOptionHarness | null> {\n const [active] = await this.getOptions({ active: true });\n return active ?? null;\n }\n\n /** The label of the option this level is drilled into, or `null`. */\n async getActiveOptionText(): Promise<string | null> {\n const active = await this.getActiveOption();\n return active ? active.getText() : null;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport {\n ComponentHarness,\n type HarnessLoader,\n HarnessPredicate,\n TestKey,\n type TestElement,\n} from '@angular/cdk/testing';\n\nimport type {\n WrCascaderColumnHarnessFilters,\n WrCascaderHarnessFilters,\n WrCascaderOptionHarnessFilters,\n} from './interfaces';\nimport { WrCascaderColumnHarness } from './wr-cascader-column-harness';\nimport type { WrCascaderOptionHarness } from './wr-cascader-option-harness';\n\n/**\n * Test harness for `<wr-cascader>` — the trigger, and the panel of COLUMNS it\n * opens. Root of a small family: {@link WrCascaderColumnHarness} for one level,\n * `WrCascaderOptionHarness` for one option in it.\n *\n * A cascader is not a select with extra steps. Its value is the whole PATH from\n * root to leaf (`['eu', 'de', 'ber']`, not `'ber'`), and the panel shows one\n * column per level, so which columns exist depends on what is expanded — column\n * 0 is the roots, and every further column holds the children of the active\n * option in the column to its left. That relationship is the component, so it is\n * what {@link getColumns} and {@link getColumnLabels} are for.\n *\n * The panel is NOT inside the cascader: it is a template portal in the overlay\n * container, a sibling of the whole app. Every read of it goes through the\n * document root scoped by the `aria-controls` id the trigger publishes, so two\n * cascaders on one page can never answer with each other's columns.\n *\n * @example\n * ```ts\n * const cascader = await loader.getHarness(WrCascaderHarness);\n *\n * await cascader.selectPath(['Europe', 'Germany', 'Berlin']);\n *\n * expect(await cascader.getValueText()).toBe('Europe / Germany / Berlin');\n * expect(await cascader.isOpen()).toBe(false);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCascaderHarness extends ComponentHarness {\n static hostSelector = 'wr-cascader';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCascaderHarnessFilters = {}): HarnessPredicate<WrCascaderHarness> {\n return new HarnessPredicate(WrCascaderHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getValueText(), text))\n .addOption('placeholder', options.placeholder, (harness, placeholder) =>\n HarnessPredicate.stringMatches(harness.getPlaceholder(), placeholder)\n )\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('open', options.open, async (harness, open) => (await harness.isOpen()) === open);\n }\n\n private readonly trigger = this.locatorFor('.wr-cascader__trigger');\n\n /**\n * Whether the panel is showing.\n *\n * From the trigger's `aria-expanded` rather than the host's `--open` class:\n * both exist, and the ARIA state is the one a screen-reader user is told.\n */\n async isOpen(): Promise<boolean> {\n return (await (await this.trigger()).getAttribute('aria-expanded')) === 'true';\n }\n\n /**\n * Whether the cascader refuses interaction.\n *\n * From the trigger's native `disabled`, which is what actually stops a pointer\n * and what assistive tech reports; the host's `--disabled` class only mirrors\n * it for styling.\n */\n async isDisabled(): Promise<boolean> {\n return (await this.trigger()).getProperty<boolean>('disabled');\n }\n\n /**\n * What the trigger displays as the selection: the labels of the whole path\n * joined by the `separator` (`'Europe / Germany / Berlin'` by default), or `''`\n * while nothing is selected and the placeholder is showing.\n *\n * The joined string is all the DOM has — the separator is not published\n * anywhere on its own, so the harness will not pretend it can split the path\n * back apart. Assert against the bound value, or against\n * {@link getActiveTrail} while the panel is open, when the segments matter.\n */\n async getValueText(): Promise<string> {\n const value = await this.locatorForOptional('.wr-cascader__value')();\n return value ? value.text() : '';\n }\n\n /**\n * The placeholder, or `null` when a selection is hiding it.\n *\n * `''` is a real answer, not an absence: a cascader with no `placeholder` still\n * renders the element while unselected.\n */\n async getPlaceholder(): Promise<string | null> {\n const placeholder = await this.locatorForOptional('.wr-cascader__placeholder')();\n return placeholder ? placeholder.text() : null;\n }\n\n /**\n * The trigger's accessible name — the `ariaLabel` input, falling back to the\n * placeholder and then to the i18n catalog, because a `role=\"combobox\"` with\n * nothing selected and no placeholder would otherwise have no name at all.\n */\n async getAccessibleName(): Promise<string | null> {\n return (await this.trigger()).getAttribute('aria-label');\n }\n\n /**\n * The kind of popup the trigger promises via `aria-haspopup` — `tree`.\n *\n * Worth pinning rather than assuming: a combobox's popup may be a listbox, a\n * tree, a grid or a dialog and nothing else, and this one said `menu` for a\n * long time. `menu` is a valid token for the global `aria-haspopup`, so axe\n * reports nothing either way — an assertion here is the only guard there is.\n */\n async getPopupRole(): Promise<string | null> {\n return (await this.trigger()).getAttribute('aria-haspopup');\n }\n\n /** The role the panel announces — `tree`, matching what the trigger promised. */\n async getPanelRole(): Promise<string | null> {\n return (await this.panel()).getAttribute('role');\n }\n\n /**\n * The id the trigger publishes as `aria-controls`.\n *\n * Published unconditionally, open or closed — so while the panel is closed this\n * id resolves to nothing in the document. Exposed so a spec can pin that\n * (dangling or not) rather than have the harness quietly decide for it; every\n * panel read goes through the same id but refuses to run while closed.\n */\n async getPanelId(): Promise<string | null> {\n return (await this.trigger()).getAttribute('aria-controls');\n }\n\n /**\n * Whether the panel now in the overlay is the one this trigger claims to\n * control — `aria-controls` resolving to a real element that carries that id.\n *\n * With several cascaders on a page it is also the check that the reference lands\n * on THIS instance's panel rather than a neighbour's: the overlay container is\n * shared, so panels sit side by side in it with nothing but their ids to tell\n * them apart.\n */\n async isPanelWiredToTrigger(): Promise<boolean> {\n const rendered = await (await this.panel()).getAttribute('id');\n return rendered !== null && rendered === (await this.getPanelId());\n }\n\n /**\n * Open the panel.\n *\n * Clicks the trigger, because that is the only gesture the component binds. The\n * trigger is a native `<button>`, so a browser turns Enter / Space on it into\n * the same click — there is no separate keyboard route to model here, and jsdom\n * does not synthesise button activation from a key, so an `openByKeyboard()`\n * would only be able to lie.\n */\n async open(): Promise<void> {\n if (await this.isOpen()) return;\n\n await (await this.trigger()).click();\n if (await this.isOpen()) return;\n\n throw new Error(\n 'WrCascaderHarness.open(): the panel did not open. A disabled cascader refuses the click — ' +\n 'check isDisabled().'\n );\n }\n\n /**\n * Close the panel with Escape. A closed cascader is left alone.\n *\n * Escape reaches the panel through the CDK's keyboard dispatcher rather than\n * through the DOM tree, which is why sending it to the trigger works even\n * though the panel is somewhere else entirely.\n */\n async close(): Promise<void> {\n if (!(await this.isOpen())) return;\n\n await (await this.trigger()).sendKeys(TestKey.ESCAPE);\n if (await this.isOpen()) {\n throw new Error('WrCascaderHarness.close(): Escape did not close the panel.');\n }\n }\n\n /** Click the trigger once, whatever that does — opens a closed panel, closes an open one. */\n async clickTrigger(): Promise<void> {\n return (await this.trigger()).click();\n }\n\n /**\n * The columns of the open panel, left to right: column 0 is the root options,\n * and each further one holds the children of its neighbour's active option.\n *\n * Throws while the panel is closed. The columns do not exist anywhere until the\n * portal is attached, and an empty array reads like a panel that rendered\n * nothing — a confusing failure three lines later instead of here.\n */\n async getColumns(filters: WrCascaderColumnHarnessFilters = {}): Promise<WrCascaderColumnHarness[]> {\n const loader = await this.panelLoader();\n return loader.getAllHarnesses(WrCascaderColumnHarness.with(filters));\n }\n\n /** How many levels the panel is currently showing. */\n async getColumnCount(): Promise<number> {\n return (await this.getColumns()).length;\n }\n\n /**\n * One column by its 0-based level. Throws when the level is not showing, which\n * is the interesting failure: it means the option before it has no children, or\n * has not been expanded yet.\n */\n async getColumn(index: number): Promise<WrCascaderColumnHarness> {\n const columns = await this.getColumns();\n const column = columns[index];\n if (!column) {\n throw new Error(\n `WrCascaderHarness.getColumn(): no column at level ${index} — the panel is showing ` +\n `${columns.length}. A deeper column appears only once a parent with children is expanded.`\n );\n }\n return column;\n }\n\n /** The labels offered by every column, outer array left to right. */\n async getColumnLabels(): Promise<string[][]> {\n const columns = await this.getColumns();\n return Promise.all(columns.map(column => column.getOptionLabels()));\n }\n\n /**\n * The expanded trail — the label of the active option in each column, root\n * first.\n *\n * This is the panel's own idea of where the user is, which is NOT always the\n * committed value: drilling into a branch moves the trail without committing\n * anything unless `changeOnSelect` is on. Once a leaf is picked the two agree,\n * and this is the only place the path's segments exist separately in the DOM.\n */\n async getActiveTrail(): Promise<string[]> {\n const trail: string[] = [];\n for (const column of await this.getColumns()) {\n const active = await column.getActiveOptionText();\n if (active !== null) trail.push(active);\n }\n return trail;\n }\n\n /**\n * The first option matching the filters, anywhere in the panel. Throws when\n * nothing matches, naming what is on offer.\n *\n * Use {@link getColumn} when the level matters — the same label can legitimately\n * appear at more than one level.\n */\n async getOption(filters: WrCascaderOptionHarnessFilters): Promise<WrCascaderOptionHarness> {\n for (const column of await this.getColumns()) {\n const [option] = await column.getOptions(filters);\n if (option) return option;\n }\n\n throw new Error(\n `WrCascaderHarness.getOption(): no option matched ${JSON.stringify(filters)}. ` +\n `The panel offers: ${(await this.getColumnLabels()).map(labels => labels.join(', ')).join(' | ')}.`\n );\n }\n\n /**\n * Walk a path by label, opening the panel first if needed: each label is\n * clicked in the column it belongs to, so `['Europe', 'Germany', 'Berlin']`\n * drills two levels and commits the third.\n *\n * Clicking is the only way down — this cascader does not expand on hover, so\n * neither does the harness. A path that ends on a BRANCH just leaves that\n * branch expanded: the component commits nothing on the way down unless\n * `changeOnSelect` is on, and only a leaf closes the panel.\n */\n async selectPath(labels: readonly string[]): Promise<void> {\n if (labels.length === 0) {\n throw new Error(\n 'WrCascaderHarness.selectPath(): the path is empty. Pass at least one label, or call clear() ' +\n 'to unset the selection.'\n );\n }\n\n await this.open();\n\n for (let level = 0; level < labels.length; level++) {\n const label = labels[level];\n const columns = await this.getColumns();\n const column = columns[level];\n if (!column) {\n throw new Error(\n `WrCascaderHarness.selectPath(): \"${label}\" would be at level ${level}, but the panel is ` +\n `showing ${columns.length} column(s) — the step before it opened no deeper level.`\n );\n }\n\n const option = await column.getOption({ text: label });\n if (await option.isDisabled()) {\n throw new Error(`WrCascaderHarness.selectPath(): \"${label}\" is disabled, so no path can pass through it.`);\n }\n\n const isLast = level === labels.length - 1;\n if (!isLast && !(await option.hasChildren())) {\n throw new Error(\n `WrCascaderHarness.selectPath(): \"${label}\" is a leaf, so the path cannot continue to ` +\n `\"${labels[level + 1]}\" — picking it commits and closes the panel.`\n );\n }\n\n await option.click();\n }\n }\n\n /**\n * Click the clear (×) control on the trigger.\n *\n * Throws when there is none, and both reasons are worth failing on: the\n * cascader is not `clearable`, or nothing is selected — the control is not\n * rendered at all in either case (nor while disabled).\n */\n async clear(): Promise<void> {\n const clear = await this.locatorForOptional('.wr-cascader__clear')();\n if (!clear) {\n throw new Error(\n 'WrCascaderHarness.clear(): this cascader shows no clear control — it is rendered only when ' +\n '`clearable` is on, something is selected, and the control is enabled.'\n );\n }\n await clear.click();\n }\n\n /**\n * Clear from the keyboard — Backspace on the closed trigger.\n *\n * The × {@link clear} clicks is a `tabindex=\"-1\"` span inside the trigger, so no\n * key can ever reach it; Backspace on the trigger is its keyboard twin, and the\n * route a keyboard-only user actually has. Prefer this one in a spec that cares\n * about that user — {@link clear} proves the pointer path and nothing more.\n *\n * The component honours the key only on the CLOSED trigger, so an open panel\n * is closed first with Escape — the step a keyboard user takes too. Sending\n * Backspace into an open panel and returning would be a plausible nothing.\n *\n * Does nothing, rather than throwing, when there is nothing to clear, `clearable`\n * is off, or the cascader is disabled or read-only: that silence IS the\n * component's contract, so a spec asserts it on the value.\n */\n async clearByKeyboard(): Promise<void> {\n if (await this.isOpen()) await this.close();\n await (await this.trigger()).sendKeys(TestKey.BACKSPACE);\n }\n\n /** Move keyboard focus to the trigger. */\n async focus(): Promise<void> {\n return (await this.trigger()).focus();\n }\n\n /** Take focus off the trigger, which is what makes a bound form field touched. */\n async blur(): Promise<void> {\n return (await this.trigger()).blur();\n }\n\n /** Whether the trigger holds keyboard focus. */\n async isFocused(): Promise<boolean> {\n return (await this.trigger()).isFocused();\n }\n\n /** This cascader's panel element in the overlay — the single-element scoped read. */\n private async panel(): Promise<TestElement> {\n return this.documentRootLocatorFactory().locatorFor(`#${await this.panelId()}`)();\n }\n\n /**\n * A loader scoped to THIS cascader's panel — the list scoped read.\n *\n * Scoped by the published id rather than by `.wr-cascader-panel`: the overlay\n * container is shared with every other overlay in the app, so a bare class\n * query would answer with whichever panel happened to be open.\n */\n private async panelLoader(): Promise<HarnessLoader> {\n return this.documentRootLocatorFactory().harnessLoaderFor(`#${await this.panelId()}`);\n }\n\n /** The panel id, refusing to hand it out while there is no panel to find. */\n private async panelId(): Promise<string> {\n if (!(await this.isOpen())) {\n throw new Error(\n 'WrCascaderHarness: the panel is closed, so there are no columns to read — call open() or ' +\n 'selectPath() first. The trigger publishes `aria-controls` even while closed, so the id ' +\n 'alone is not proof the panel exists.'\n );\n }\n\n const id = await this.getPanelId();\n if (!id) {\n throw new Error('WrCascaderHarness: the trigger publishes no `aria-controls`, so its panel cannot be found.');\n }\n return id;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -405,12 +405,12 @@ class WrCascader {
|
|
|
405
405
|
if (focusWasInside)
|
|
406
406
|
this.host.nativeElement.querySelector('.wr-cascader__trigger')?.focus();
|
|
407
407
|
}
|
|
408
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
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 });
|
|
408
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCascader, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
409
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", 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-placeholder)}.wr-cascader__chevron{flex:0 0 auto;color:var(--wr-color-on-surface-muted);transition:transform var(--wr-transition-base)}.wr-cascader--open .wr-cascader__chevron{transform:rotate(180deg)}.wr-cascader__clear{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;margin-block:-1rem;border-radius:999px;color:var(--wr-color-on-surface-muted);cursor:pointer;transition:background .12s ease,color .12s ease}.wr-cascader__clear:hover{background:rgba(var(--wr-color-on-surface-rgb),.06);color:var(--wr-color-on-surface)}@media(pointer:coarse){.wr-cascader__clear{position:relative}.wr-cascader__clear:after{content:\"\";position:absolute;top:50%;left:50%;width:100%;height:100%;min-width:2rem;min-height:2rem;transform:translate(-50%,-50%)}}.wr-cascader-overlay{padding-top:.25rem}.wr-cascader-panel{--wr-cascader-opt-font: var(--wr-control-font-size-md);--wr-cascader-opt-py: .5rem;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
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
411
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", 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-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"] }]
|
|
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-placeholder)}.wr-cascader__chevron{flex:0 0 auto;color:var(--wr-color-on-surface-muted);transition:transform var(--wr-transition-base)}.wr-cascader--open .wr-cascader__chevron{transform:rotate(180deg)}.wr-cascader__clear{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;margin-block:-1rem;border-radius:999px;color:var(--wr-color-on-surface-muted);cursor:pointer;transition:background .12s ease,color .12s ease}.wr-cascader__clear:hover{background:rgba(var(--wr-color-on-surface-rgb),.06);color:var(--wr-color-on-surface)}@media(pointer:coarse){.wr-cascader__clear{position:relative}.wr-cascader__clear:after{content:\"\";position:absolute;top:50%;left:50%;width:100%;height:100%;min-width:2rem;min-height:2rem;transform:translate(-50%,-50%)}}.wr-cascader-overlay{padding-top:.25rem}.wr-cascader-panel{--wr-cascader-opt-font: var(--wr-control-font-size-md);--wr-cascader-opt-py: .5rem;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
|
/**
|