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-calendar.mjs","sources":["../../../projects/lib/calendar/calendar.ts","../../../projects/lib/calendar/calendar.html","../../../projects/lib/calendar/ngwr-calendar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { WrDateAdapter } from 'ngwr/date';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport type { WrCalendarMode, WrCalendarRange } from './interfaces';\n\n/**\n * Stands in for the consumer input `useI18nText` expects, for labels the calendar\n * exposes no input for. Constant and read-only, so one instance is safe to share.\n */\nconst NO_OVERRIDE = signal<string | null>(null).asReadonly();\n\nconst ROWS = 6;\nconst COLS = 7;\n\n/**\n * Chips per row in the month and year views — the vertical arrows step by one\n * of these, so they have to agree with `grid-template-columns` in\n * `styles/_index.scss`. Two numbers because the two grids differ: twelve months\n * read as four rows of three, twelve years as three rows of four.\n */\nconst MONTH_COLS = 3;\nconst YEAR_COLS = 4;\n\n/**\n * Month-view calendar. Supports single-date selection (`mode=\"single\"`) or\n * date-range selection (`mode=\"range\"`). Reusable on its own; consumed by\n * `<wr-date-picker>` inside an overlay.\n *\n * Uses {@link WrDateAdapter} for all date math and formatting — register\n * one via {@link provideWrDateAdapter} at bootstrap.\n *\n * @example\n * ```html\n * <wr-calendar [(date)]=\"picked\" [min]=\"minDate\" />\n *\n * <wr-calendar mode=\"range\" [(range)]=\"[start, end]\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar\n */\n@Component({\n selector: 'wr-calendar',\n templateUrl: './calendar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n // No `role=\"grid\"` here: the host also wraps the nav header, and a grid may\n // only own rows. The role sits on `.wr-calendar__body`, which is the day\n // matrix and nothing else.\n '(keydown)': 'onKeyDown($event)',\n },\n})\nexport class WrCalendar {\n /** Selection mode. @default 'single' */\n readonly mode = input<WrCalendarMode>('single');\n\n /** Two-way bindable single value (used when `mode === 'single'`). */\n readonly date = model<Date | null>(null);\n\n /** Two-way bindable `[start, end]` (used when `mode === 'range'`). */\n readonly range = model<WrCalendarRange>([null, null]);\n\n /** Min selectable date (inclusive). */\n readonly min = input<Date | null>(null);\n\n /** Max selectable date (inclusive). */\n readonly max = input<Date | null>(null);\n\n /** Predicate — return `false` to disable specific dates (e.g. weekends only). */\n readonly dateFilter = input<((date: Date) => boolean) | null>(null);\n\n /**\n * Move real focus onto the roving cell as soon as the grid is on screen.\n *\n * Off by default: a standalone `<wr-calendar>` sitting in a page must not\n * steal focus on load. `wr-date-picker` turns it on for the popup it opens\n * from its trigger, where the user asked to be taken to the calendar.\n * @default false\n */\n readonly autoFocus = input(false, { transform: coerceBooleanProperty });\n\n /** Disable interaction entirely. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n private readonly adapter = inject<WrDateAdapter<Date>>(WrDateAdapter);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n\n /** Currently displayed month (any date inside it). */\n protected readonly viewDate = signal(this.adapter.today());\n\n /** Date currently focused by keyboard (single roving tabindex). */\n protected readonly focusedDate = signal(this.adapter.today());\n\n /** Hovered date during range-mode end-pick — drives the preview highlight. */\n protected readonly hoverDate = signal<Date | null>(null);\n\n /** Which sub-view is currently shown. Cycles `day → month → year` on header click. */\n protected readonly viewMode = signal<'day' | 'month' | 'year'>('day');\n\n /**\n * Chip the month / year listbox has moved its ring to, as an index into\n * `monthsView()` / `yearsView()`. `null` means \"nobody has pressed an arrow\n * yet\", which resolves to the month or year on screen — see {@link activeChip}.\n *\n * Reset on every view change rather than remembered: coming back to the month\n * list should ring the month you are looking at, not the one an earlier visit\n * happened to leave the ring on.\n */\n private readonly rovedChip = signal<number | null>(null);\n\n // The four month/year strings have been in both catalogs since they were written\n // and nothing read them: the template hard-coded the same English beside them, so a\n // localized app announced its calendar's arrows in English. `nullSignal()` is the\n // shim for exactly this — a label with no consumer input to forward.\n private readonly prevMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.prevMonth', 'Previous month');\n private readonly nextMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.nextMonth', 'Next month');\n protected readonly monthListLabel = useI18nText(NO_OVERRIDE, 'calendar.monthList', 'Months');\n protected readonly yearListLabel = useI18nText(NO_OVERRIDE, 'calendar.yearList', 'Years');\n private readonly prevYearLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYear', 'Previous year');\n private readonly nextYearLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYear', 'Next year');\n private readonly prevYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYears', 'Previous 12 years');\n private readonly nextYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYears', 'Next 12 years');\n\n /** What the ← button does from here — a month, a year, or a 12-year page. */\n protected readonly prevLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.prevYearsLabel();\n case 'month':\n return this.prevYearLabel();\n default:\n return this.prevMonthLabel();\n }\n });\n\n /** What the → button does from here. */\n protected readonly nextLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.nextYearsLabel();\n case 'month':\n return this.nextYearLabel();\n default:\n return this.nextMonthLabel();\n }\n });\n\n protected readonly today = computed(() => this.adapter.today());\n\n protected readonly weekdayNames = computed(() => this.adapter.getDayOfWeekNames('short'));\n\n protected readonly monthsView = computed(() => this.adapter.getMonthNames('short'));\n\n /** 12-year window centered on the floor-aligned decade containing `viewDate`. */\n protected readonly yearsView = computed<readonly number[]>(() => {\n const y = this.adapter.getYear(this.viewDate());\n const start = Math.floor(y / 12) * 12;\n return Array.from({ length: 12 }, (_, i) => start + i);\n });\n\n /**\n * The header above the grid.\n *\n * Both templated strings used to be assembled here: `${month} ${year}` and\n * `${first} – ${last}`. That is English word order with an English separator\n * baked into TypeScript, and no catalog could move either — ja-JP writes\n * 2026年3月, which is not a translation of any word in `March 2026` but a\n * different arrangement of the same two values. So the arrangement is the\n * translatable unit, and `calendar.header` / `calendar.yearRange` are it.\n */\n protected readonly headerLabel = computed(() => {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day': {\n const monthNames = this.adapter.getMonthNames('long');\n return this.headerText({\n month: monthNames[this.adapter.getMonth(v)],\n year: this.adapter.getYear(v),\n });\n }\n case 'month':\n return `${this.adapter.getYear(v)}`;\n case 'year': {\n const years = this.yearsView();\n return this.yearRangeText({ from: years[0], to: years[years.length - 1] });\n }\n }\n });\n\n private readonly headerText = useI18nFormatter('calendar.header', '{{month}} {{year}}');\n private readonly yearRangeText = useI18nFormatter('calendar.yearRange', '{{from}} – {{to}}');\n private readonly dayLabelText = useI18nFormatter('calendar.dayLabel', '{{weekday}}, {{date}}');\n\n /**\n * Long weekday names for the cell names.\n *\n * `getDayOfWeekNames` returns them in COLUMN order — index 0 is\n * `getFirstDayOfWeek()`, not Sunday — which is what the header strip wants and\n * what a `getDayOfWeek()` result (0 = Sunday) must be rotated into. Indexing\n * it directly reads Monday's name for a Sunday in every locale that starts its\n * week on Monday, which is most of them.\n */\n private readonly longWeekdays = computed(() => this.adapter.getDayOfWeekNames('long'));\n\n /**\n * A day cell's accessible name — \"Sunday, March 15, 2026\".\n *\n * The cell had none. Its only content is the day NUMBER, and `role=\"gridcell\"`\n * does not inherit a name from the grid's header or from the column header\n * above it, so every date in the month announced as a bare number: the month,\n * the year and the weekday were all on screen and none of them reachable.\n *\n * `{{date}}` is the adapter's `longDate`, so its field order, its separators\n * and its digits are `Intl`'s — the catalog decides only where the weekday\n * goes. Building it from `getMonthNames('long')` instead would have hard-coded\n * the nominative month, which Russian and Finnish inflect inside a date.\n */\n protected dayLabel(date: Date): string {\n return this.dayLabelText({\n weekday: this.longWeekdays()[(this.adapter.getDayOfWeek(date) - this.adapter.getFirstDayOfWeek() + 7) % 7],\n date: this.adapter.format(date, 'longDate'),\n });\n }\n\n /** 6×7 day grid covering the current month plus spillover. */\n protected readonly weeks = computed<readonly (readonly Date[])[]>(() => {\n const view = this.viewDate();\n const year = this.adapter.getYear(view);\n const month = this.adapter.getMonth(view);\n const firstOfMonth = this.adapter.createDate(year, month, 1);\n const firstWeekday = this.adapter.getDayOfWeek(firstOfMonth);\n const firstDayOfWeek = this.adapter.getFirstDayOfWeek();\n const lead = (firstWeekday - firstDayOfWeek + 7) % 7;\n const gridStart = this.adapter.addDays(firstOfMonth, -lead);\n\n const out: Date[][] = [];\n for (let w = 0; w < ROWS; w++) {\n const row: Date[] = [];\n for (let d = 0; d < COLS; d++) {\n row.push(this.adapter.addDays(gridStart, w * COLS + d));\n }\n out.push(row);\n }\n return out;\n });\n\n /**\n * The chip carrying the listbox's only `tabindex=\"0\"` — where the ring is, and\n * where Tab lands.\n *\n * A listbox owns its arrows, and these two did not: twelve months were twelve\n * tab stops, so the role promised an interaction model the component never\n * implemented. One tab stop plus arrow keys is the roving-tabindex half of the\n * pattern the day grid already uses.\n *\n * Routed through {@link nearestEnabledChip} on BOTH paths — the seed and every\n * arrow — for the reason the grid learned first: `.focus()` on a\n * `<button disabled>` is a no-op, so parking the sole tab stop on a month a\n * `[min]` has closed off leaves the whole view unreachable by keyboard.\n * `-1` on the day view, where there are no chips at all.\n */\n protected readonly activeChip = computed(() => {\n if (this.viewMode() === 'day') return -1;\n return this.nearestEnabledChip(this.rovedChip() ?? this.currentChip());\n });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-calendar', `wr-calendar--${this.mode()}`];\n if (this.disabled()) parts.push('wr-calendar--disabled');\n return parts.join(' ');\n });\n\n constructor() {\n // Initial focus: selected date if any, else today. Also snap viewDate to\n // that month.\n //\n // Stepped onto an ENABLED day, because the roving tabindex puts the grid's\n // only `tabindex=\"0\"` on this cell: seed it on a disabled one — which is\n // exactly what a `min` in the future does to \"today\" — and the sole tab\n // stop is an unfocusable button, leaving the grid unreachable by keyboard.\n afterNextRender(() => {\n const initial = this.nearestEnabled(this.date() ?? this.range()[0] ?? this.adapter.today());\n this.focusedDate.set(initial);\n this.viewDate.set(initial);\n\n // A second, NESTED hook: the lines above only SET the signals, which\n // schedules another change-detection pass — the `--focused` class and the\n // `tabindex` are not in the DOM until that one has run.\n if (this.autoFocus()) {\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n });\n\n // Keep viewDate in sync when date / range changes externally to a\n // different month. The viewDate read must stay untracked — otherwise\n // the effect re-runs on every internal navigation (month stepping,\n // year picking) and snaps the view back to the selected month.\n effect(() => {\n const candidate = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!candidate) return;\n untracked(() => {\n if (!this.adapter.isSameMonth(candidate, this.viewDate())) {\n this.viewDate.set(candidate);\n }\n });\n });\n }\n\n // Navigation\n\n /** Header `‹` button — steps by month / year / decade based on the active view. */\n protected prev(): void {\n this.viewDate.set(this.stepViewDate(-1));\n }\n\n /** Header `›` button — steps by month / year / decade based on the active view. */\n protected next(): void {\n this.viewDate.set(this.stepViewDate(1));\n }\n\n /** Header label click — zooms out (`day → month → year`). No-op at year view. */\n protected onLabelClick(): void {\n if (this.disabled()) return;\n if (this.viewMode() === 'day') {\n this.setViewMode('month');\n } else if (this.viewMode() === 'month') {\n this.setViewMode('year');\n }\n }\n\n /**\n * Picking a month drops to the day grid — and takes real focus with it.\n *\n * The `@switch (viewMode())` in the template destroys the chip that holds DOM\n * focus, so without the two lines below `document.activeElement` became\n * `<body>`: the ring appeared on the new view and focus did not, the arrow\n * keys went dead (the keydown handler is a HOST binding, so nothing reaches\n * the component from `<body>`), and the next Tab restarted from the top of the\n * document — out of the calendar entirely. It is the same trap the two\n * keyboard paths in this file already fix, and for the same reason\n * `afterNextRender` rather than `queueMicrotask`: under zoneless CD the\n * microtask runs before the new view is in the DOM.\n *\n * `focusedDate` has to move too, and that half is easy to miss. The grid marks\n * its focusable cell by comparing against `focusedDate`, not `viewDate`, so\n * choosing a DIFFERENT month rendered a grid with no `--focused` cell and no\n * `tabindex=\"0\"` at all — unreachable by keyboard from either direction. The\n * day is preserved when the month already holds it and otherwise falls to the\n * first, which is where `viewDate` lands anyway.\n */\n protected onMonthSelect(monthIdx: number): void {\n if (this.isMonthDisabled(monthIdx)) return;\n const v = this.viewDate();\n const year = this.adapter.getYear(v);\n this.viewDate.set(this.adapter.createDate(year, monthIdx, 1));\n\n const focused = this.focusedDate();\n const alreadyThere = this.adapter.getYear(focused) === year && this.adapter.getMonth(focused) === monthIdx;\n if (!alreadyThere) this.focusedDate.set(this.adapter.createDate(year, monthIdx, 1));\n\n this.setViewMode('day');\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /** Year → month view, with the same focus restoration; the landing view is chips. */\n protected onYearSelect(year: number): void {\n if (this.isYearDisabled(year)) return;\n const v = this.viewDate();\n this.viewDate.set(this.adapter.createDate(year, this.adapter.getMonth(v), 1));\n this.setViewMode('month');\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /**\n * Switch views and drop the chip ring with them.\n *\n * Every view change is the only thing that changes what the chips MEAN, so it\n * is the one place the ring has to forget where it was — otherwise a year\n * picked at index 7 rings the eighth MONTH on the way back down.\n */\n private setViewMode(view: 'day' | 'month' | 'year'): void {\n this.rovedChip.set(null);\n this.viewMode.set(view);\n }\n\n private stepViewDate(direction: -1 | 1): Date {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day':\n return this.adapter.addMonths(v, direction);\n case 'month':\n return this.adapter.addYears(v, direction);\n case 'year':\n return this.adapter.addYears(v, direction * 12);\n }\n }\n\n // Cell state predicates (used by template)\n\n protected isToday(date: Date): boolean {\n return this.adapter.isSameDay(date, this.today());\n }\n\n protected isOutOfMonth(date: Date): boolean {\n return !this.adapter.isSameMonth(date, this.viewDate());\n }\n\n protected isSelected(date: Date): boolean {\n if (this.mode() === 'single') {\n const v = this.date();\n return v ? this.adapter.isSameDay(date, v) : false;\n }\n const [start, end] = this.range();\n if (start && this.adapter.isSameDay(date, start)) return true;\n if (end && this.adapter.isSameDay(date, end)) return true;\n return false;\n }\n\n protected isInRange(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n if (!start || !end) return false;\n return this.adapter.compareDate(date, start) > 0 && this.adapter.compareDate(date, end) < 0;\n }\n\n protected isInRangePreview(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n const hover = this.hoverDate();\n if (!start || end || !hover) return false;\n const before = this.adapter.compareDate(start, hover) <= 0;\n const lo = before ? start : hover;\n const hi = before ? hover : start;\n return this.adapter.compareDate(date, lo) > 0 && this.adapter.compareDate(date, hi) < 0;\n }\n\n protected isFocused(date: Date): boolean {\n return this.adapter.isSameDay(date, this.focusedDate());\n }\n\n protected isDisabled(date: Date): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && this.adapter.compareDate(date, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(date, max) > 0) return true;\n const filter = this.dateFilter();\n if (filter && !filter(date)) return true;\n return false;\n }\n\n // Month / year view predicates\n\n protected isMonthCurrent(monthIdx: number): boolean {\n return this.adapter.getMonth(this.viewDate()) === monthIdx;\n }\n\n protected isMonthSelected(monthIdx: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!v) return false;\n return this.adapter.getYear(v) === this.adapter.getYear(this.viewDate()) && this.adapter.getMonth(v) === monthIdx;\n }\n\n protected isMonthDisabled(monthIdx: number): boolean {\n if (this.disabled()) return true;\n const year = this.adapter.getYear(this.viewDate());\n const monthStart = this.adapter.createDate(year, monthIdx, 1);\n const monthEnd = this.adapter.createDate(year, monthIdx, this.adapter.getDaysInMonth(monthStart));\n const min = this.min();\n if (min && this.adapter.compareDate(monthEnd, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(monthStart, max) > 0) return true;\n return false;\n }\n\n protected isYearCurrent(year: number): boolean {\n return this.adapter.getYear(this.viewDate()) === year;\n }\n\n protected isYearSelected(year: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n return v ? this.adapter.getYear(v) === year : false;\n }\n\n protected isYearDisabled(year: number): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && year < this.adapter.getYear(min)) return true;\n const max = this.max();\n if (max && year > this.adapter.getYear(max)) return true;\n return false;\n }\n\n // Interaction\n\n protected onCellClick(date: Date): void {\n if (this.isDisabled(date)) return;\n if (this.mode() === 'single') {\n this.date.set(this.adapter.clone(date));\n } else {\n this.applyRangeClick(date);\n }\n this.focusedDate.set(date);\n if (!this.adapter.isSameMonth(date, this.viewDate())) {\n this.viewDate.set(date);\n }\n }\n\n protected onCellEnter(date: Date): void {\n if (this.mode() === 'range') this.hoverDate.set(date);\n }\n\n protected onCellLeave(): void {\n if (this.mode() === 'range') this.hoverDate.set(null);\n }\n\n private applyRangeClick(date: Date): void {\n const [start, end] = this.range();\n if (!start || (start && end)) {\n this.range.set([this.adapter.clone(date), null]);\n return;\n }\n if (this.adapter.compareDate(date, start) < 0) {\n this.range.set([this.adapter.clone(date), start]);\n } else {\n this.range.set([start, this.adapter.clone(date)]);\n }\n this.hoverDate.set(null);\n }\n\n // Keyboard\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n\n // The listener sits on the HOST, which also wraps the nav header — so\n // without this every key aimed at a `‹` button drove the day grid instead,\n // and the `preventDefault()` below cancelled the button's own activation:\n // Enter on `‹` picked a day the user never touched, ArrowDown on the header\n // yanked real focus into the grid. The host element itself is deliberately\n // let through: `WrCalendarHarness` sends its keys to `<wr-calendar>` rather\n // than to a cell, because the calendar moves focus in an `afterNextRender`\n // and jsdom often has focus nowhere at all.\n const target = event.target as Element | null;\n if (target !== this.host.nativeElement && target?.closest('.wr-calendar__header')) return;\n\n // The month and year views are listboxes, and the arrows belong to them\n // while they are up — there is no day grid on screen to drive. Their chips\n // are real `<button>`s, so Enter and Space fall through to the browser's own\n // activation and must not be swallowed here.\n if (this.viewMode() !== 'day') {\n this.onChipKeyDown(event);\n return;\n }\n\n const current = this.focusedDate();\n let next: Date | null = null;\n // Which way the key travels, so a landing on a closed-off day can keep\n // going instead of stopping on it. See `nearestEnabledToward`.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = this.adapter.addDays(current, -1);\n dir = -1;\n break;\n case 'ArrowRight':\n next = this.adapter.addDays(current, 1);\n break;\n case 'ArrowUp':\n next = this.adapter.addDays(current, -7);\n dir = -1;\n break;\n case 'ArrowDown':\n next = this.adapter.addDays(current, 7);\n break;\n case 'Home': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, -((dow - first + 7) % 7));\n dir = -1;\n break;\n }\n case 'End': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, 6 - ((dow - first + 7) % 7));\n break;\n }\n case 'PageUp':\n next = event.shiftKey ? this.adapter.addYears(current, -1) : this.adapter.addMonths(current, -1);\n dir = -1;\n break;\n case 'PageDown':\n next = event.shiftKey ? this.adapter.addYears(current, 1) : this.adapter.addMonths(current, 1);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.onCellClick(current);\n return;\n }\n\n if (!next) return;\n event.preventDefault();\n\n // The seed is routed through `nearestEnabled` for a reason, and navigation\n // needs the same care: a cell renders `disabled` AND carries the grid's only\n // `tabindex=\"0\"`, so parking the ring on a closed-off day leaves zero\n // tabbable cells — the user tabs out of the calendar and can never tab back\n // in. Real focus splits from the ring too, because `.focus()` on a disabled\n // button is a no-op. Reached by nothing more exotic than `[minDate]`.\n const landing = this.nearestEnabledToward(next, dir);\n if (!landing) return;\n next = landing;\n\n this.focusedDate.set(next);\n if (!this.adapter.isSameMonth(next, this.viewDate())) {\n this.viewDate.set(next);\n }\n // `afterNextRender`, NOT `queueMicrotask`. Under zoneless CD the scheduler\n // runs change detection in a macrotask, so a microtask fires FIRST — the\n // `--focused` class is still on the cell we just left, and this focuses\n // that one. The ring moved and real focus did not, permanently: a screen\n // reader kept announcing the previous day.\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /**\n * Arrow / Home / End inside the month or year listbox — the roving half of the\n * pattern their `role` has always claimed.\n *\n * Steps by one along the row and by a full row vertically, and the inline pair\n * mirrors under `dir=\"rtl\"` for the same reason the grid's does: those two keys\n * name a side of the screen. The page does NOT wrap or spill into the next\n * one — a month list is twelve fixed cells, and the header's `‹` / `›` are what\n * change which twelve. Anything else (Enter, Space, Tab, Escape) is left to the\n * button and to whatever owns the calendar.\n */\n private onChipKeyDown(event: KeyboardEvent): void {\n const cols = this.viewMode() === 'month' ? MONTH_COLS : YEAR_COLS;\n const count = this.chipCount();\n const current = this.activeChip();\n // Assigned on every branch that does not return, so it needs no placeholder.\n let next: number;\n // Which way to keep looking when the landing chip is closed off, exactly as\n // `nearestEnabledToward` does for days.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = current - 1;\n dir = -1;\n break;\n case 'ArrowRight':\n next = current + 1;\n break;\n case 'ArrowUp':\n next = current - cols;\n dir = -1;\n break;\n case 'ArrowDown':\n next = current + cols;\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = count - 1;\n dir = -1;\n break;\n default:\n return;\n }\n\n const landing = this.enabledChipToward(next, dir);\n if (landing === null) return;\n\n event.preventDefault();\n this.rovedChip.set(landing);\n // `afterNextRender`, not `queueMicrotask` — same trap as the grid: under\n // zoneless CD the microtask runs before the new `tabindex` is in the DOM, so\n // the focus call would land on the chip the ring just left.\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /** How many chips the current view renders — twelve either way, read rather than assumed. */\n private chipCount(): number {\n return this.viewMode() === 'month' ? this.monthsView().length : this.yearsView().length;\n }\n\n /** Whether the chip at `index` refuses selection in the current view. */\n private isChipDisabled(index: number): boolean {\n if (this.viewMode() === 'month') return this.isMonthDisabled(index);\n const year = this.yearsView()[index];\n return year === undefined || this.isYearDisabled(year);\n }\n\n /** The chip the view itself points at: the month or year currently on screen. */\n private currentChip(): number {\n if (this.viewMode() === 'month') return this.adapter.getMonth(this.viewDate());\n const index = this.yearsView().indexOf(this.adapter.getYear(this.viewDate()));\n return index === -1 ? 0 : index;\n }\n\n /**\n * The first selectable chip at or after `from`, else the first before it, else\n * `from` unchanged when the whole page is closed off — the chip version of\n * {@link nearestEnabled}, and it exists for the same reason: the ring carries\n * the only `tabindex=\"0\"`, and a disabled button cannot hold it.\n */\n private nearestEnabledChip(from: number): number {\n const count = this.chipCount();\n const start = Math.min(Math.max(from, 0), count - 1);\n if (!this.isChipDisabled(start)) return start;\n\n for (const step of [1, -1] as const) {\n const found = this.enabledChipToward(start + step, step);\n if (found !== null) return found;\n }\n return start;\n }\n\n /**\n * The first selectable chip at `from` or beyond it in `step`'s direction, else\n * null when that whole direction is closed off — which is the answer for an\n * ArrowLeft on the first chip: stay put.\n */\n private enabledChipToward(from: number, step: 1 | -1): number | null {\n for (let i = from; i >= 0 && i < this.chipCount(); i += step) {\n if (!this.isChipDisabled(i)) return i;\n }\n return null;\n }\n\n private focusActiveChip(): void {\n // By the tab stop, not by index: it is the same element the ring is on, and\n // asking for it this way cannot drift out of step with the template.\n this.host.nativeElement.querySelector<HTMLElement>('.wr-calendar__chip[tabindex=\"0\"]')?.focus();\n }\n\n /**\n * The first selectable day at or after `candidate`, else the first before it,\n * else `candidate` unchanged when everything nearby is closed off. Bounded at\n * a year each way so a pathological `dateFilter` cannot spin.\n */\n private nearestEnabled(candidate: Date): Date {\n if (!this.isDisabled(candidate)) return candidate;\n\n for (const step of [1, -1] as const) {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n probe = this.adapter.addDays(probe, step);\n if (!this.isDisabled(probe)) return probe;\n }\n }\n return candidate;\n }\n\n /**\n * The first selectable day at `candidate` or beyond it in `step`'s direction,\n * else null when that whole direction is closed off — which is the answer for\n * an ArrowLeft that would cross `min`: stay put.\n *\n * Direction matters. Reusing `nearestEnabled`, which probes forward first,\n * would send an ArrowLeft over a disabled weekend straight back to the day it\n * started from, so the ring could never cross the hole.\n */\n private nearestEnabledToward(candidate: Date, step: 1 | -1): Date | null {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n if (!this.isDisabled(probe)) return probe;\n probe = this.adapter.addDays(probe, step);\n }\n return null;\n }\n\n private focusActiveCell(): void {\n const el = this.host.nativeElement.querySelector('.wr-calendar__day--focused');\n (el as HTMLElement | null)?.focus();\n }\n\n /** Used by the template's `track` expression. */\n protected trackByTime(_: number, date: Date): number {\n return date.getTime();\n }\n\n /**\n * The key as the GRID sees it.\n *\n * Arrow keys follow visual order, and a calendar grid mirrors under\n * `dir=\"rtl\"`: the day to the visual right of today is yesterday. Only the\n * inline pair swaps — Up/Down step a week either way, and PageUp/PageDown and\n * Home/End are semantic rather than physical.\n */\n private inlineKey(key: string): string {\n if (this.dir?.value !== 'rtl') return key;\n if (key === 'ArrowRight') return 'ArrowLeft';\n if (key === 'ArrowLeft') return 'ArrowRight';\n return key;\n }\n}\n","<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-label]=\"dayLabel(day)\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model — arrow to a month, Tab\n out of the list — that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\" [attr.aria-label]=\"monthListLabel()\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\" [attr.aria-label]=\"yearListLabel()\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngwr-calendar.mjs","sources":["../../../projects/lib/calendar/calendar.ts","../../../projects/lib/calendar/calendar.html","../../../projects/lib/calendar/ngwr-calendar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { WrDateAdapter } from 'ngwr/date';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport type { WrCalendarMode, WrCalendarRange } from './interfaces';\n\n/**\n * Stands in for the consumer input `useI18nText` expects, for labels the calendar\n * exposes no input for. Constant and read-only, so one instance is safe to share.\n */\nconst NO_OVERRIDE = signal<string | null>(null).asReadonly();\n\nconst ROWS = 6;\nconst COLS = 7;\n\n/**\n * Chips per row in the month and year views — the vertical arrows step by one\n * of these, so they have to agree with `grid-template-columns` in\n * `styles/_index.scss`. Two numbers because the two grids differ: twelve months\n * read as four rows of three, twelve years as three rows of four.\n */\nconst MONTH_COLS = 3;\nconst YEAR_COLS = 4;\n\n/**\n * Month-view calendar. Supports single-date selection (`mode=\"single\"`) or\n * date-range selection (`mode=\"range\"`). Reusable on its own; consumed by\n * `<wr-date-picker>` inside an overlay.\n *\n * Uses {@link WrDateAdapter} for all date math and formatting — register\n * one via {@link provideWrDateAdapter} at bootstrap.\n *\n * @example\n * ```html\n * <wr-calendar [(date)]=\"picked\" [min]=\"minDate\" />\n *\n * <wr-calendar mode=\"range\" [(range)]=\"[start, end]\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar\n */\n@Component({\n selector: 'wr-calendar',\n templateUrl: './calendar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n // No `role=\"grid\"` here: the host also wraps the nav header, and a grid may\n // only own rows. The role sits on `.wr-calendar__body`, which is the day\n // matrix and nothing else.\n '(keydown)': 'onKeyDown($event)',\n },\n})\nexport class WrCalendar {\n /** Selection mode. @default 'single' */\n readonly mode = input<WrCalendarMode>('single');\n\n /** Two-way bindable single value (used when `mode === 'single'`). */\n readonly date = model<Date | null>(null);\n\n /** Two-way bindable `[start, end]` (used when `mode === 'range'`). */\n readonly range = model<WrCalendarRange>([null, null]);\n\n /** Min selectable date (inclusive). */\n readonly min = input<Date | null>(null);\n\n /** Max selectable date (inclusive). */\n readonly max = input<Date | null>(null);\n\n /** Predicate — return `false` to disable specific dates (e.g. weekends only). */\n readonly dateFilter = input<((date: Date) => boolean) | null>(null);\n\n /**\n * Move real focus onto the roving cell as soon as the grid is on screen.\n *\n * Off by default: a standalone `<wr-calendar>` sitting in a page must not\n * steal focus on load. `wr-date-picker` turns it on for the popup it opens\n * from its trigger, where the user asked to be taken to the calendar.\n * @default false\n */\n readonly autoFocus = input(false, { transform: coerceBooleanProperty });\n\n /** Disable interaction entirely. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n private readonly adapter = inject<WrDateAdapter<Date>>(WrDateAdapter);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n\n /** Currently displayed month (any date inside it). */\n protected readonly viewDate = signal(this.adapter.today());\n\n /** Date currently focused by keyboard (single roving tabindex). */\n protected readonly focusedDate = signal(this.adapter.today());\n\n /** Hovered date during range-mode end-pick — drives the preview highlight. */\n protected readonly hoverDate = signal<Date | null>(null);\n\n /** Which sub-view is currently shown. Cycles `day → month → year` on header click. */\n protected readonly viewMode = signal<'day' | 'month' | 'year'>('day');\n\n /**\n * Chip the month / year listbox has moved its ring to, as an index into\n * `monthsView()` / `yearsView()`. `null` means \"nobody has pressed an arrow\n * yet\", which resolves to the month or year on screen — see {@link activeChip}.\n *\n * Reset on every view change rather than remembered: coming back to the month\n * list should ring the month you are looking at, not the one an earlier visit\n * happened to leave the ring on.\n */\n private readonly rovedChip = signal<number | null>(null);\n\n // The four month/year strings have been in both catalogs since they were written\n // and nothing read them: the template hard-coded the same English beside them, so a\n // localized app announced its calendar's arrows in English. `nullSignal()` is the\n // shim for exactly this — a label with no consumer input to forward.\n private readonly prevMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.prevMonth', 'Previous month');\n private readonly nextMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.nextMonth', 'Next month');\n protected readonly monthListLabel = useI18nText(NO_OVERRIDE, 'calendar.monthList', 'Months');\n protected readonly yearListLabel = useI18nText(NO_OVERRIDE, 'calendar.yearList', 'Years');\n private readonly prevYearLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYear', 'Previous year');\n private readonly nextYearLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYear', 'Next year');\n private readonly prevYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYears', 'Previous 12 years');\n private readonly nextYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYears', 'Next 12 years');\n\n /** What the ← button does from here — a month, a year, or a 12-year page. */\n protected readonly prevLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.prevYearsLabel();\n case 'month':\n return this.prevYearLabel();\n default:\n return this.prevMonthLabel();\n }\n });\n\n /** What the → button does from here. */\n protected readonly nextLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.nextYearsLabel();\n case 'month':\n return this.nextYearLabel();\n default:\n return this.nextMonthLabel();\n }\n });\n\n protected readonly today = computed(() => this.adapter.today());\n\n protected readonly weekdayNames = computed(() => this.adapter.getDayOfWeekNames('short'));\n\n protected readonly monthsView = computed(() => this.adapter.getMonthNames('short'));\n\n /** 12-year window centered on the floor-aligned decade containing `viewDate`. */\n protected readonly yearsView = computed<readonly number[]>(() => {\n const y = this.adapter.getYear(this.viewDate());\n const start = Math.floor(y / 12) * 12;\n return Array.from({ length: 12 }, (_, i) => start + i);\n });\n\n /**\n * The header above the grid.\n *\n * Both templated strings used to be assembled here: `${month} ${year}` and\n * `${first} – ${last}`. That is English word order with an English separator\n * baked into TypeScript, and no catalog could move either — ja-JP writes\n * 2026年3月, which is not a translation of any word in `March 2026` but a\n * different arrangement of the same two values. So the arrangement is the\n * translatable unit, and `calendar.header` / `calendar.yearRange` are it.\n */\n protected readonly headerLabel = computed(() => {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day': {\n const monthNames = this.adapter.getMonthNames('long');\n return this.headerText({\n month: monthNames[this.adapter.getMonth(v)],\n year: this.adapter.getYear(v),\n });\n }\n case 'month':\n return `${this.adapter.getYear(v)}`;\n case 'year': {\n const years = this.yearsView();\n return this.yearRangeText({ from: years[0], to: years[years.length - 1] });\n }\n }\n });\n\n private readonly headerText = useI18nFormatter('calendar.header', '{{month}} {{year}}');\n private readonly yearRangeText = useI18nFormatter('calendar.yearRange', '{{from}} – {{to}}');\n private readonly dayLabelText = useI18nFormatter('calendar.dayLabel', '{{weekday}}, {{date}}');\n\n /**\n * Long weekday names for the cell names.\n *\n * `getDayOfWeekNames` returns them in COLUMN order — index 0 is\n * `getFirstDayOfWeek()`, not Sunday — which is what the header strip wants and\n * what a `getDayOfWeek()` result (0 = Sunday) must be rotated into. Indexing\n * it directly reads Monday's name for a Sunday in every locale that starts its\n * week on Monday, which is most of them.\n */\n private readonly longWeekdays = computed(() => this.adapter.getDayOfWeekNames('long'));\n\n /**\n * A day cell's accessible name — \"Sunday, March 15, 2026\".\n *\n * The cell had none. Its only content is the day NUMBER, and `role=\"gridcell\"`\n * does not inherit a name from the grid's header or from the column header\n * above it, so every date in the month announced as a bare number: the month,\n * the year and the weekday were all on screen and none of them reachable.\n *\n * `{{date}}` is the adapter's `longDate`, so its field order, its separators\n * and its digits are `Intl`'s — the catalog decides only where the weekday\n * goes. Building it from `getMonthNames('long')` instead would have hard-coded\n * the nominative month, which Russian and Finnish inflect inside a date.\n */\n protected dayLabel(date: Date): string {\n return this.dayLabelText({\n weekday: this.longWeekdays()[(this.adapter.getDayOfWeek(date) - this.adapter.getFirstDayOfWeek() + 7) % 7],\n date: this.adapter.format(date, 'longDate'),\n });\n }\n\n /** 6×7 day grid covering the current month plus spillover. */\n protected readonly weeks = computed<readonly (readonly Date[])[]>(() => {\n const view = this.viewDate();\n const year = this.adapter.getYear(view);\n const month = this.adapter.getMonth(view);\n const firstOfMonth = this.adapter.createDate(year, month, 1);\n const firstWeekday = this.adapter.getDayOfWeek(firstOfMonth);\n const firstDayOfWeek = this.adapter.getFirstDayOfWeek();\n const lead = (firstWeekday - firstDayOfWeek + 7) % 7;\n const gridStart = this.adapter.addDays(firstOfMonth, -lead);\n\n const out: Date[][] = [];\n for (let w = 0; w < ROWS; w++) {\n const row: Date[] = [];\n for (let d = 0; d < COLS; d++) {\n row.push(this.adapter.addDays(gridStart, w * COLS + d));\n }\n out.push(row);\n }\n return out;\n });\n\n /**\n * The chip carrying the listbox's only `tabindex=\"0\"` — where the ring is, and\n * where Tab lands.\n *\n * A listbox owns its arrows, and these two did not: twelve months were twelve\n * tab stops, so the role promised an interaction model the component never\n * implemented. One tab stop plus arrow keys is the roving-tabindex half of the\n * pattern the day grid already uses.\n *\n * Routed through {@link nearestEnabledChip} on BOTH paths — the seed and every\n * arrow — for the reason the grid learned first: `.focus()` on a\n * `<button disabled>` is a no-op, so parking the sole tab stop on a month a\n * `[min]` has closed off leaves the whole view unreachable by keyboard.\n * `-1` on the day view, where there are no chips at all.\n */\n protected readonly activeChip = computed(() => {\n if (this.viewMode() === 'day') return -1;\n return this.nearestEnabledChip(this.rovedChip() ?? this.currentChip());\n });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-calendar', `wr-calendar--${this.mode()}`];\n if (this.disabled()) parts.push('wr-calendar--disabled');\n return parts.join(' ');\n });\n\n constructor() {\n // Initial focus: selected date if any, else today. Also snap viewDate to\n // that month.\n //\n // Stepped onto an ENABLED day, because the roving tabindex puts the grid's\n // only `tabindex=\"0\"` on this cell: seed it on a disabled one — which is\n // exactly what a `min` in the future does to \"today\" — and the sole tab\n // stop is an unfocusable button, leaving the grid unreachable by keyboard.\n afterNextRender(() => {\n const initial = this.nearestEnabled(this.date() ?? this.range()[0] ?? this.adapter.today());\n this.focusedDate.set(initial);\n this.viewDate.set(initial);\n\n // A second, NESTED hook: the lines above only SET the signals, which\n // schedules another change-detection pass — the `--focused` class and the\n // `tabindex` are not in the DOM until that one has run.\n if (this.autoFocus()) {\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n });\n\n // Keep viewDate in sync when date / range changes externally to a\n // different month. The viewDate read must stay untracked — otherwise\n // the effect re-runs on every internal navigation (month stepping,\n // year picking) and snaps the view back to the selected month.\n effect(() => {\n const candidate = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!candidate) return;\n untracked(() => {\n if (!this.adapter.isSameMonth(candidate, this.viewDate())) {\n this.viewDate.set(candidate);\n }\n });\n });\n }\n\n // Navigation\n\n /** Header `‹` button — steps by month / year / decade based on the active view. */\n protected prev(): void {\n this.viewDate.set(this.stepViewDate(-1));\n }\n\n /** Header `›` button — steps by month / year / decade based on the active view. */\n protected next(): void {\n this.viewDate.set(this.stepViewDate(1));\n }\n\n /** Header label click — zooms out (`day → month → year`). No-op at year view. */\n protected onLabelClick(): void {\n if (this.disabled()) return;\n if (this.viewMode() === 'day') {\n this.setViewMode('month');\n } else if (this.viewMode() === 'month') {\n this.setViewMode('year');\n }\n }\n\n /**\n * Picking a month drops to the day grid — and takes real focus with it.\n *\n * The `@switch (viewMode())` in the template destroys the chip that holds DOM\n * focus, so without the two lines below `document.activeElement` became\n * `<body>`: the ring appeared on the new view and focus did not, the arrow\n * keys went dead (the keydown handler is a HOST binding, so nothing reaches\n * the component from `<body>`), and the next Tab restarted from the top of the\n * document — out of the calendar entirely. It is the same trap the two\n * keyboard paths in this file already fix, and for the same reason\n * `afterNextRender` rather than `queueMicrotask`: under zoneless CD the\n * microtask runs before the new view is in the DOM.\n *\n * `focusedDate` has to move too, and that half is easy to miss. The grid marks\n * its focusable cell by comparing against `focusedDate`, not `viewDate`, so\n * choosing a DIFFERENT month rendered a grid with no `--focused` cell and no\n * `tabindex=\"0\"` at all — unreachable by keyboard from either direction. The\n * day is preserved when the month already holds it and otherwise falls to the\n * first, which is where `viewDate` lands anyway.\n */\n protected onMonthSelect(monthIdx: number): void {\n if (this.isMonthDisabled(monthIdx)) return;\n const v = this.viewDate();\n const year = this.adapter.getYear(v);\n this.viewDate.set(this.adapter.createDate(year, monthIdx, 1));\n\n const focused = this.focusedDate();\n const alreadyThere = this.adapter.getYear(focused) === year && this.adapter.getMonth(focused) === monthIdx;\n if (!alreadyThere) this.focusedDate.set(this.adapter.createDate(year, monthIdx, 1));\n\n this.setViewMode('day');\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /** Year → month view, with the same focus restoration; the landing view is chips. */\n protected onYearSelect(year: number): void {\n if (this.isYearDisabled(year)) return;\n const v = this.viewDate();\n this.viewDate.set(this.adapter.createDate(year, this.adapter.getMonth(v), 1));\n this.setViewMode('month');\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /**\n * Switch views and drop the chip ring with them.\n *\n * Every view change is the only thing that changes what the chips MEAN, so it\n * is the one place the ring has to forget where it was — otherwise a year\n * picked at index 7 rings the eighth MONTH on the way back down.\n */\n private setViewMode(view: 'day' | 'month' | 'year'): void {\n this.rovedChip.set(null);\n this.viewMode.set(view);\n }\n\n private stepViewDate(direction: -1 | 1): Date {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day':\n return this.adapter.addMonths(v, direction);\n case 'month':\n return this.adapter.addYears(v, direction);\n case 'year':\n return this.adapter.addYears(v, direction * 12);\n }\n }\n\n // Cell state predicates (used by template)\n\n protected isToday(date: Date): boolean {\n return this.adapter.isSameDay(date, this.today());\n }\n\n protected isOutOfMonth(date: Date): boolean {\n return !this.adapter.isSameMonth(date, this.viewDate());\n }\n\n protected isSelected(date: Date): boolean {\n if (this.mode() === 'single') {\n const v = this.date();\n return v ? this.adapter.isSameDay(date, v) : false;\n }\n const [start, end] = this.range();\n if (start && this.adapter.isSameDay(date, start)) return true;\n if (end && this.adapter.isSameDay(date, end)) return true;\n return false;\n }\n\n protected isInRange(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n if (!start || !end) return false;\n return this.adapter.compareDate(date, start) > 0 && this.adapter.compareDate(date, end) < 0;\n }\n\n protected isInRangePreview(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n const hover = this.hoverDate();\n if (!start || end || !hover) return false;\n const before = this.adapter.compareDate(start, hover) <= 0;\n const lo = before ? start : hover;\n const hi = before ? hover : start;\n return this.adapter.compareDate(date, lo) > 0 && this.adapter.compareDate(date, hi) < 0;\n }\n\n protected isFocused(date: Date): boolean {\n return this.adapter.isSameDay(date, this.focusedDate());\n }\n\n protected isDisabled(date: Date): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && this.adapter.compareDate(date, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(date, max) > 0) return true;\n const filter = this.dateFilter();\n if (filter && !filter(date)) return true;\n return false;\n }\n\n // Month / year view predicates\n\n protected isMonthCurrent(monthIdx: number): boolean {\n return this.adapter.getMonth(this.viewDate()) === monthIdx;\n }\n\n protected isMonthSelected(monthIdx: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!v) return false;\n return this.adapter.getYear(v) === this.adapter.getYear(this.viewDate()) && this.adapter.getMonth(v) === monthIdx;\n }\n\n protected isMonthDisabled(monthIdx: number): boolean {\n if (this.disabled()) return true;\n const year = this.adapter.getYear(this.viewDate());\n const monthStart = this.adapter.createDate(year, monthIdx, 1);\n const monthEnd = this.adapter.createDate(year, monthIdx, this.adapter.getDaysInMonth(monthStart));\n const min = this.min();\n if (min && this.adapter.compareDate(monthEnd, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(monthStart, max) > 0) return true;\n return false;\n }\n\n protected isYearCurrent(year: number): boolean {\n return this.adapter.getYear(this.viewDate()) === year;\n }\n\n protected isYearSelected(year: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n return v ? this.adapter.getYear(v) === year : false;\n }\n\n protected isYearDisabled(year: number): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && year < this.adapter.getYear(min)) return true;\n const max = this.max();\n if (max && year > this.adapter.getYear(max)) return true;\n return false;\n }\n\n // Interaction\n\n protected onCellClick(date: Date): void {\n if (this.isDisabled(date)) return;\n if (this.mode() === 'single') {\n this.date.set(this.adapter.clone(date));\n } else {\n this.applyRangeClick(date);\n }\n this.focusedDate.set(date);\n if (!this.adapter.isSameMonth(date, this.viewDate())) {\n this.viewDate.set(date);\n }\n }\n\n protected onCellEnter(date: Date): void {\n if (this.mode() === 'range') this.hoverDate.set(date);\n }\n\n protected onCellLeave(): void {\n if (this.mode() === 'range') this.hoverDate.set(null);\n }\n\n private applyRangeClick(date: Date): void {\n const [start, end] = this.range();\n if (!start || (start && end)) {\n this.range.set([this.adapter.clone(date), null]);\n return;\n }\n if (this.adapter.compareDate(date, start) < 0) {\n this.range.set([this.adapter.clone(date), start]);\n } else {\n this.range.set([start, this.adapter.clone(date)]);\n }\n this.hoverDate.set(null);\n }\n\n // Keyboard\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n\n // The listener sits on the HOST, which also wraps the nav header — so\n // without this every key aimed at a `‹` button drove the day grid instead,\n // and the `preventDefault()` below cancelled the button's own activation:\n // Enter on `‹` picked a day the user never touched, ArrowDown on the header\n // yanked real focus into the grid. The host element itself is deliberately\n // let through: `WrCalendarHarness` sends its keys to `<wr-calendar>` rather\n // than to a cell, because the calendar moves focus in an `afterNextRender`\n // and jsdom often has focus nowhere at all.\n const target = event.target as Element | null;\n if (target !== this.host.nativeElement && target?.closest('.wr-calendar__header')) return;\n\n // The month and year views are listboxes, and the arrows belong to them\n // while they are up — there is no day grid on screen to drive. Their chips\n // are real `<button>`s, so Enter and Space fall through to the browser's own\n // activation and must not be swallowed here.\n if (this.viewMode() !== 'day') {\n this.onChipKeyDown(event);\n return;\n }\n\n const current = this.focusedDate();\n let next: Date | null = null;\n // Which way the key travels, so a landing on a closed-off day can keep\n // going instead of stopping on it. See `nearestEnabledToward`.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = this.adapter.addDays(current, -1);\n dir = -1;\n break;\n case 'ArrowRight':\n next = this.adapter.addDays(current, 1);\n break;\n case 'ArrowUp':\n next = this.adapter.addDays(current, -7);\n dir = -1;\n break;\n case 'ArrowDown':\n next = this.adapter.addDays(current, 7);\n break;\n case 'Home': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, -((dow - first + 7) % 7));\n dir = -1;\n break;\n }\n case 'End': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, 6 - ((dow - first + 7) % 7));\n break;\n }\n case 'PageUp':\n next = event.shiftKey ? this.adapter.addYears(current, -1) : this.adapter.addMonths(current, -1);\n dir = -1;\n break;\n case 'PageDown':\n next = event.shiftKey ? this.adapter.addYears(current, 1) : this.adapter.addMonths(current, 1);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.onCellClick(current);\n return;\n }\n\n if (!next) return;\n event.preventDefault();\n\n // The seed is routed through `nearestEnabled` for a reason, and navigation\n // needs the same care: a cell renders `disabled` AND carries the grid's only\n // `tabindex=\"0\"`, so parking the ring on a closed-off day leaves zero\n // tabbable cells — the user tabs out of the calendar and can never tab back\n // in. Real focus splits from the ring too, because `.focus()` on a disabled\n // button is a no-op. Reached by nothing more exotic than `[minDate]`.\n const landing = this.nearestEnabledToward(next, dir);\n if (!landing) return;\n next = landing;\n\n this.focusedDate.set(next);\n if (!this.adapter.isSameMonth(next, this.viewDate())) {\n this.viewDate.set(next);\n }\n // `afterNextRender`, NOT `queueMicrotask`. Under zoneless CD the scheduler\n // runs change detection in a macrotask, so a microtask fires FIRST — the\n // `--focused` class is still on the cell we just left, and this focuses\n // that one. The ring moved and real focus did not, permanently: a screen\n // reader kept announcing the previous day.\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /**\n * Arrow / Home / End inside the month or year listbox — the roving half of the\n * pattern their `role` has always claimed.\n *\n * Steps by one along the row and by a full row vertically, and the inline pair\n * mirrors under `dir=\"rtl\"` for the same reason the grid's does: those two keys\n * name a side of the screen. The page does NOT wrap or spill into the next\n * one — a month list is twelve fixed cells, and the header's `‹` / `›` are what\n * change which twelve. Anything else (Enter, Space, Tab, Escape) is left to the\n * button and to whatever owns the calendar.\n */\n private onChipKeyDown(event: KeyboardEvent): void {\n const cols = this.viewMode() === 'month' ? MONTH_COLS : YEAR_COLS;\n const count = this.chipCount();\n const current = this.activeChip();\n // Assigned on every branch that does not return, so it needs no placeholder.\n let next: number;\n // Which way to keep looking when the landing chip is closed off, exactly as\n // `nearestEnabledToward` does for days.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = current - 1;\n dir = -1;\n break;\n case 'ArrowRight':\n next = current + 1;\n break;\n case 'ArrowUp':\n next = current - cols;\n dir = -1;\n break;\n case 'ArrowDown':\n next = current + cols;\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = count - 1;\n dir = -1;\n break;\n default:\n return;\n }\n\n const landing = this.enabledChipToward(next, dir);\n if (landing === null) return;\n\n event.preventDefault();\n this.rovedChip.set(landing);\n // `afterNextRender`, not `queueMicrotask` — same trap as the grid: under\n // zoneless CD the microtask runs before the new `tabindex` is in the DOM, so\n // the focus call would land on the chip the ring just left.\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /** How many chips the current view renders — twelve either way, read rather than assumed. */\n private chipCount(): number {\n return this.viewMode() === 'month' ? this.monthsView().length : this.yearsView().length;\n }\n\n /** Whether the chip at `index` refuses selection in the current view. */\n private isChipDisabled(index: number): boolean {\n if (this.viewMode() === 'month') return this.isMonthDisabled(index);\n const year = this.yearsView()[index];\n return year === undefined || this.isYearDisabled(year);\n }\n\n /** The chip the view itself points at: the month or year currently on screen. */\n private currentChip(): number {\n if (this.viewMode() === 'month') return this.adapter.getMonth(this.viewDate());\n const index = this.yearsView().indexOf(this.adapter.getYear(this.viewDate()));\n return index === -1 ? 0 : index;\n }\n\n /**\n * The first selectable chip at or after `from`, else the first before it, else\n * `from` unchanged when the whole page is closed off — the chip version of\n * {@link nearestEnabled}, and it exists for the same reason: the ring carries\n * the only `tabindex=\"0\"`, and a disabled button cannot hold it.\n */\n private nearestEnabledChip(from: number): number {\n const count = this.chipCount();\n const start = Math.min(Math.max(from, 0), count - 1);\n if (!this.isChipDisabled(start)) return start;\n\n for (const step of [1, -1] as const) {\n const found = this.enabledChipToward(start + step, step);\n if (found !== null) return found;\n }\n return start;\n }\n\n /**\n * The first selectable chip at `from` or beyond it in `step`'s direction, else\n * null when that whole direction is closed off — which is the answer for an\n * ArrowLeft on the first chip: stay put.\n */\n private enabledChipToward(from: number, step: 1 | -1): number | null {\n for (let i = from; i >= 0 && i < this.chipCount(); i += step) {\n if (!this.isChipDisabled(i)) return i;\n }\n return null;\n }\n\n private focusActiveChip(): void {\n // By the tab stop, not by index: it is the same element the ring is on, and\n // asking for it this way cannot drift out of step with the template.\n this.host.nativeElement.querySelector<HTMLElement>('.wr-calendar__chip[tabindex=\"0\"]')?.focus();\n }\n\n /**\n * The first selectable day at or after `candidate`, else the first before it,\n * else `candidate` unchanged when everything nearby is closed off. Bounded at\n * a year each way so a pathological `dateFilter` cannot spin.\n */\n private nearestEnabled(candidate: Date): Date {\n if (!this.isDisabled(candidate)) return candidate;\n\n for (const step of [1, -1] as const) {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n probe = this.adapter.addDays(probe, step);\n if (!this.isDisabled(probe)) return probe;\n }\n }\n return candidate;\n }\n\n /**\n * The first selectable day at `candidate` or beyond it in `step`'s direction,\n * else null when that whole direction is closed off — which is the answer for\n * an ArrowLeft that would cross `min`: stay put.\n *\n * Direction matters. Reusing `nearestEnabled`, which probes forward first,\n * would send an ArrowLeft over a disabled weekend straight back to the day it\n * started from, so the ring could never cross the hole.\n */\n private nearestEnabledToward(candidate: Date, step: 1 | -1): Date | null {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n if (!this.isDisabled(probe)) return probe;\n probe = this.adapter.addDays(probe, step);\n }\n return null;\n }\n\n private focusActiveCell(): void {\n const el = this.host.nativeElement.querySelector('.wr-calendar__day--focused');\n (el as HTMLElement | null)?.focus();\n }\n\n /** Used by the template's `track` expression. */\n protected trackByTime(_: number, date: Date): number {\n return date.getTime();\n }\n\n /**\n * The key as the GRID sees it.\n *\n * Arrow keys follow visual order, and a calendar grid mirrors under\n * `dir=\"rtl\"`: the day to the visual right of today is yesterday. Only the\n * inline pair swaps — Up/Down step a week either way, and PageUp/PageDown and\n * Home/End are semantic rather than physical.\n */\n private inlineKey(key: string): string {\n if (this.dir?.value !== 'rtl') return key;\n if (key === 'ArrowRight') return 'ArrowLeft';\n if (key === 'ArrowLeft') return 'ArrowRight';\n return key;\n }\n}\n","<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-label]=\"dayLabel(day)\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model — arrow to a month, Tab\n out of the list — that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\" [attr.aria-label]=\"monthListLabel()\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\" [attr.aria-label]=\"yearListLabel()\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/fesm2022/ngwr-card.mjs
CHANGED
|
@@ -53,10 +53,10 @@ class WrCard {
|
|
|
53
53
|
return parts.join(' ');
|
|
54
54
|
}, /* @ts-ignore */
|
|
55
55
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
56
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
57
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
56
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
57
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: WrCard, isStandalone: true, selector: "wr-card", inputs: { bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.aria-busy": "loading() ? true : null" } }, ngImport: i0, template: "<ng-content select=\"wr-card-header\" />\n<div class=\"wr-card__body\"><ng-content /></div>\n<ng-content select=\"wr-card-footer\" />\n@if (loading()) {\n <div class=\"wr-card__loading\" aria-hidden=\"true\">\n <span class=\"wr-card__spinner\"></span>\n </div>\n}\n", styles: [".wr-card{--wr-card-bg: var(--wr-color-surface);--wr-card-color: var(--wr-color-on-surface);--wr-card-border: var(--wr-color-outline);--wr-card-radius: var(--wr-border-radius-base);--wr-card-padding-y: 1rem;--wr-card-padding-x: 1.25rem;--wr-card-shadow: var(--wr-shadow-xs);--wr-card-shadow-hover: var(--wr-shadow-overlay);position:relative;display:flex;flex-direction:column;background:var(--wr-card-bg);color:var(--wr-card-color);border-radius:var(--wr-card-radius)}@supports (corner-shape: squircle){.wr-card{corner-shape:squircle;border-radius:calc(var(--wr-card-radius) * 1.85)}}.wr-card{box-shadow:var(--wr-card-shadow);font-family:var(--wr-font-family-base);transition:box-shadow var(--wr-transition-base),transform var(--wr-transition-base)}.wr-card--bordered{border:1px solid var(--wr-card-border)}.wr-card--hoverable{cursor:pointer}.wr-card--hoverable:hover{box-shadow:var(--wr-card-shadow-hover);transform:translateY(-1px)}.wr-card--compact{--wr-card-padding-y: .5rem;--wr-card-padding-x: .75rem}.wr-card--loading .wr-card__body{opacity:.6}.wr-card__header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:var(--wr-card-padding-y) var(--wr-card-padding-x);border-bottom:1px solid var(--wr-card-border);font-weight:500}.wr-card__body{flex:1 1 auto;padding:var(--wr-card-padding-y) var(--wr-card-padding-x)}.wr-card__footer{display:flex;align-items:center;justify-content:flex-end;gap:.5rem;padding:var(--wr-card-padding-y) var(--wr-card-padding-x);border-top:1px solid var(--wr-card-border)}.wr-card__loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;border-radius:var(--wr-card-radius)}@supports (corner-shape: squircle){.wr-card__loading{corner-shape:squircle;border-radius:calc(var(--wr-card-radius) * 1.85)}}.wr-card__loading{background:rgba(var(--wr-color-surface-rgb),.5);pointer-events:none}.wr-card__spinner{width:1.5rem;height:1.5rem;border:2px solid rgb(var(--wr-color-on-surface-muted-rgb)/30%);border-top-color:var(--wr-color-primary);border-radius:50%;animation:wr-card-spin .7s linear infinite}@keyframes wr-card-spin{to{transform:rotate(360deg)}}\n"], encapsulation: i0.ViewEncapsulation.None });
|
|
58
58
|
}
|
|
59
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
59
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCard, decorators: [{
|
|
60
60
|
type: Component,
|
|
61
61
|
args: [{ selector: 'wr-card', encapsulation: ViewEncapsulation.None, host: {
|
|
62
62
|
'[class]': 'classes()',
|
|
@@ -65,10 +65,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
|
|
|
65
65
|
}], propDecorators: { bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], hoverable: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }] } });
|
|
66
66
|
/** Header slot — projects content under `.wr-card__header`. */
|
|
67
67
|
class WrCardHeader {
|
|
68
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
69
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.
|
|
68
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCardHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
69
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: WrCardHeader, isStandalone: true, selector: "wr-card-header", host: { classAttribute: "wr-card__header" }, ngImport: i0, template: `<ng-content />`, isInline: true, encapsulation: i0.ViewEncapsulation.None });
|
|
70
70
|
}
|
|
71
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
71
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCardHeader, decorators: [{
|
|
72
72
|
type: Component,
|
|
73
73
|
args: [{
|
|
74
74
|
selector: 'wr-card-header',
|
|
@@ -79,10 +79,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
|
|
|
79
79
|
}] });
|
|
80
80
|
/** Footer slot — projects content under `.wr-card__footer`. */
|
|
81
81
|
class WrCardFooter {
|
|
82
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
83
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.
|
|
82
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCardFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
83
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: WrCardFooter, isStandalone: true, selector: "wr-card-footer", host: { classAttribute: "wr-card__footer" }, ngImport: i0, template: `<ng-content />`, isInline: true, encapsulation: i0.ViewEncapsulation.None });
|
|
84
84
|
}
|
|
85
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
85
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCardFooter, decorators: [{
|
|
86
86
|
type: Component,
|
|
87
87
|
args: [{
|
|
88
88
|
selector: 'wr-card-footer',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-card.mjs","sources":["../../../projects/lib/card/card.ts","../../../projects/lib/card/card.html","../../../projects/lib/card/ngwr-card.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Surface container with optional header, body, and footer slots.\n *\n * Compose with `<wr-card-header>`, the projected body content, and\n * `<wr-card-footer>`. Each slot is a tiny component that just projects\n * its content under the matching BEM class — consumers keep full control\n * of the markup inside.\n *\n * @example Basic\n * ```html\n * <wr-card>\n * <wr-card-header>\n * <h3>Settings</h3>\n * </wr-card-header>\n * <p>Body content.</p>\n * <wr-card-footer>\n * <button wr-btn>Save</button>\n * </wr-card-footer>\n * </wr-card>\n * ```\n *\n * @see https://ngwr.dev/reference/components/card\n */\n@Component({\n selector: 'wr-card',\n templateUrl: './card.html',\n styleUrl: './card.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.aria-busy]': 'loading() ? true : null',\n },\n})\nexport class WrCard {\n /** Render a 1px border around the surface. @default true */\n readonly bordered = input(true, { transform: coerceBooleanProperty });\n\n /** Lift / shadow the card on hover. @default false */\n readonly hoverable = input(false, { transform: coerceBooleanProperty });\n\n /** Overlay with a centred spinner — for in-place data loads. @default false */\n readonly loading = input(false, { transform: coerceBooleanProperty });\n\n /** Compact paddings — half the default vertical / horizontal spacing. @default false */\n readonly compact = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-card'];\n if (this.bordered()) parts.push('wr-card--bordered');\n if (this.hoverable()) parts.push('wr-card--hoverable');\n if (this.loading()) parts.push('wr-card--loading');\n if (this.compact()) parts.push('wr-card--compact');\n return parts.join(' ');\n });\n}\n\n/** Header slot — projects content under `.wr-card__header`. */\n@Component({\n selector: 'wr-card-header',\n template: `<ng-content />`,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-card__header' },\n})\nexport class WrCardHeader {}\n\n/** Footer slot — projects content under `.wr-card__footer`. */\n@Component({\n selector: 'wr-card-footer',\n template: `<ng-content />`,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-card__footer' },\n})\nexport class WrCardFooter {}\n","<ng-content select=\"wr-card-header\" />\n<div class=\"wr-card__body\"><ng-content /></div>\n<ng-content select=\"wr-card-footer\" />\n@if (loading()) {\n <div class=\"wr-card__loading\" aria-hidden=\"true\">\n <span class=\"wr-card__spinner\"></span>\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-card.mjs","sources":["../../../projects/lib/card/card.ts","../../../projects/lib/card/card.html","../../../projects/lib/card/ngwr-card.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Surface container with optional header, body, and footer slots.\n *\n * Compose with `<wr-card-header>`, the projected body content, and\n * `<wr-card-footer>`. Each slot is a tiny component that just projects\n * its content under the matching BEM class — consumers keep full control\n * of the markup inside.\n *\n * @example Basic\n * ```html\n * <wr-card>\n * <wr-card-header>\n * <h3>Settings</h3>\n * </wr-card-header>\n * <p>Body content.</p>\n * <wr-card-footer>\n * <button wr-btn>Save</button>\n * </wr-card-footer>\n * </wr-card>\n * ```\n *\n * @see https://ngwr.dev/reference/components/card\n */\n@Component({\n selector: 'wr-card',\n templateUrl: './card.html',\n styleUrl: './card.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.aria-busy]': 'loading() ? true : null',\n },\n})\nexport class WrCard {\n /** Render a 1px border around the surface. @default true */\n readonly bordered = input(true, { transform: coerceBooleanProperty });\n\n /** Lift / shadow the card on hover. @default false */\n readonly hoverable = input(false, { transform: coerceBooleanProperty });\n\n /** Overlay with a centred spinner — for in-place data loads. @default false */\n readonly loading = input(false, { transform: coerceBooleanProperty });\n\n /** Compact paddings — half the default vertical / horizontal spacing. @default false */\n readonly compact = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-card'];\n if (this.bordered()) parts.push('wr-card--bordered');\n if (this.hoverable()) parts.push('wr-card--hoverable');\n if (this.loading()) parts.push('wr-card--loading');\n if (this.compact()) parts.push('wr-card--compact');\n return parts.join(' ');\n });\n}\n\n/** Header slot — projects content under `.wr-card__header`. */\n@Component({\n selector: 'wr-card-header',\n template: `<ng-content />`,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-card__header' },\n})\nexport class WrCardHeader {}\n\n/** Footer slot — projects content under `.wr-card__footer`. */\n@Component({\n selector: 'wr-card-footer',\n template: `<ng-content />`,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-card__footer' },\n})\nexport class WrCardFooter {}\n","<ng-content select=\"wr-card-header\" />\n<div class=\"wr-card__body\"><ng-content /></div>\n<ng-content select=\"wr-card-footer\" />\n@if (loading()) {\n <div class=\"wr-card__loading\" aria-hidden=\"true\">\n <span class=\"wr-card__spinner\"></span>\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-carousel-testing.mjs","sources":["../../../projects/lib/carousel/testing/wr-carousel-harness.ts","../../../projects/lib/carousel/testing/ngwr-carousel-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, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrCarouselHarnessFilters } from './interfaces';\n\n/**\n * The settled percentage out of `translateX(-100%)`, and out of the mid-drag\n * `translateX(calc(-100% + 12px))` — the pixel half is the finger, not the slide.\n */\nconst TRACK_OFFSET = /translateX\\(\\s*(?:calc\\(\\s*)?(-?[\\d.]+)%/;\n\n/**\n * Test harness for `<wr-carousel>` — drive the strip the way someone on the page\n * drives it.\n *\n * Everything it reads is public API: the `.wr-carousel__*` elements, the dots'\n * `aria-current`, and the `aria-roledescription` the viewport and each slide\n * publish. Two things are worth knowing before writing an assertion against it:\n *\n * - **The slides do not say which one is showing.** A `<wr-carousel-slide>` carries\n * `role=\"group\"` and `aria-roledescription=\"slide\"` and nothing else — no\n * `aria-current`, no `aria-hidden` on the ones off-screen. The current slide is\n * published in exactly two places, the dot carrying `aria-current=\"true\"` and the\n * track's own offset, and {@link getActiveIndex} reads them in that order. There\n * is likewise no live region: the component announces a move to nobody, so a\n * harness cannot report one.\n * - **It never drags.** The swipe the component supports is a touch gesture\n * measured against the viewport's own width, and jsdom has no layout — that width\n * is 0, so the \"20% of the viewport\" threshold is 0 too and EVERY drag clears it,\n * a 1px twitch included. The result says nothing about a real finger, and the spec\n * pins that artifact rather than pretending otherwise. Every move here goes\n * through the arrow buttons and the dots instead, which is the accessible path\n * anyway. `carousel.spec.ts` is where the gesture itself is pinned, by staging the\n * touch events and declaring an `offsetWidth`.\n *\n * @example\n * ```ts\n * const loader = TestbedHarnessEnvironment.loader(fixture);\n * const gallery = await loader.getHarness(WrCarouselHarness.with({ ariaLabel: 'Gallery' }));\n *\n * expect(await gallery.getSlideCount()).toBe(3);\n * await gallery.next();\n * expect(await gallery.getActiveIndex()).toBe(1);\n *\n * await gallery.goTo(2);\n * expect(await gallery.getActiveSlideText()).toBe('Dunes');\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCarouselHarness extends ComponentHarness {\n static hostSelector = 'wr-carousel';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrCarouselHarnessFilters = {}): HarnessPredicate<WrCarouselHarness> {\n return new HarnessPredicate(WrCarouselHarness, options)\n .addOption('ariaLabel', options.ariaLabel, (harness, label) =>\n HarnessPredicate.stringMatches(harness.getAccessibleName(), label)\n )\n .addOption('slideCount', options.slideCount, async (harness, count) => (await harness.getSlideCount()) === count)\n .addOption('slideText', options.slideText, async (harness, text) => {\n for (const slide of await harness.getSlideTexts()) {\n if (await HarnessPredicate.stringMatches(slide, text)) return true;\n }\n return false;\n });\n }\n\n // What the carousel announces\n\n /**\n * The role the strip announces — `group`, which is what lets\n * `aria-roledescription` mean anything.\n *\n * Read off the VIEWPORT rather than the host, and that is the whole point of the\n * pairing: `aria-roledescription` is dropped on an element with no semantic role,\n * and the host element (`<wr-carousel>`) has none.\n */\n async getRole(): Promise<string | null> {\n return (await this.viewport()).getAttribute('role');\n }\n\n /** How the strip describes itself to a screen reader — `carousel`. */\n async getRoleDescription(): Promise<string | null> {\n return (await this.viewport()).getAttribute('aria-roledescription');\n }\n\n /**\n * The carousel's accessible name.\n *\n * The RESOLVED one, which is the only one the page has: the `ariaLabel` input\n * defaults to `null` and the component runs it through the `ngwr/i18n` catalog\n * (`carousel.label`, falling back to `'Carousel'`), so a consumer who passed\n * nothing still gets a named group and this still answers. Reporting the raw\n * input would say `null` about a carousel that announces itself perfectly well.\n */\n async getAccessibleName(): Promise<string | null> {\n return (await this.viewport()).getAttribute('aria-label');\n }\n\n /** The accessible name of the previous-slide button. Throws when the arrows are not rendered. */\n async getPreviousLabel(): Promise<string | null> {\n return (await this.nav('prev', 'getPreviousLabel')).getAttribute('aria-label');\n }\n\n /** The accessible name of the next-slide button. Throws when the arrows are not rendered. */\n async getNextLabel(): Promise<string | null> {\n return (await this.nav('next', 'getNextLabel')).getAttribute('aria-label');\n }\n\n /**\n * The accessible name of the dot group — what names the row of dots as a set\n * rather than leaving a screen reader with N unexplained buttons.\n *\n * Throws when the dots are not rendered: there is no group to name then, and a\n * `null` would read like a group that lost its label.\n */\n async getPaginationLabel(): Promise<string | null> {\n const dots = await this.locatorForOptional('.wr-carousel__dots')();\n if (!dots) {\n throw new Error(\n 'WrCarouselHarness.getPaginationLabel(): this carousel renders no dot group — the dots are dropped ' +\n 'when [showDots] is false or when there are fewer than two slides.'\n );\n }\n return dots.getAttribute('aria-label');\n }\n\n /**\n * What each slide announces itself as — `slide`, on every one of them, in DOM\n * order.\n *\n * The one piece of ARIA the slides carry, and the reason it is worth asking: it\n * is set on the slide component's own host, so a slide reaching the page through\n * some other element would come back `null` here while the carousel kept working.\n */\n async getSlideRoleDescriptions(): Promise<(string | null)[]> {\n const slides = await this.slides();\n return Promise.all(slides.map(slide => slide.getAttribute('aria-roledescription')));\n }\n\n // What the carousel is showing\n\n /** How many slides the carousel holds. */\n async getSlideCount(): Promise<number> {\n return (await this.slides()).length;\n }\n\n /** The text of every slide, in DOM order. */\n async getSlideTexts(): Promise<string[]> {\n const slides = await this.slides();\n return Promise.all(slides.map(slide => slide.text()));\n }\n\n /**\n * Which slide is showing, as a zero-based index.\n *\n * Taken from the dot carrying `aria-current=\"true\"` whenever the dots are\n * rendered — that attribute is the only thing on the page that tells a screen\n * reader where in the strip it has got to, so it is the answer that matters —\n * and derived from the track's rendered offset when they are not, `[showDots]`\n * being off and a single-slide carousel both dropping the strip entirely.\n *\n * That fallback takes the MAGNITUDE of the offset on purpose. The transform is\n * physical while the slides sit on the inline axis, so a mirrored carousel paints\n * `translateX(100%)` for the very slide an LTR one paints `translateX(-100%)`\n * for; signed, this reported slide -1 for a perfectly healthy RTL carousel.\n *\n * Throws on a carousel with no slides at all — nothing is showing there, and `0`\n * would read like the first slide.\n */\n async getActiveIndex(): Promise<number> {\n const count = await this.getSlideCount();\n if (count === 0) {\n throw new Error(\n 'WrCarouselHarness.getActiveIndex(): this carousel has no <wr-carousel-slide> children, so no slide is ' +\n 'current — 0 would read like the first one.'\n );\n }\n\n const dots = await this.dots();\n if (dots.length) {\n for (let index = 0; index < dots.length; index++) {\n if ((await dots[index].getAttribute('aria-current')) === 'true') return index;\n }\n throw new Error(\n 'WrCarouselHarness.getActiveIndex(): the dots are rendered but none of them carries aria-current, so the ' +\n 'page tells a screen reader that no slide is current. The component clamps `active` into range, so look ' +\n 'for a lost aria-current binding rather than an out-of-range index — the `--active` class alone is paint.'\n );\n }\n\n return Math.round(Math.abs(await this.getTrackOffsetPercent()) / 100);\n }\n\n /** The text of the slide that is showing. Throws on a carousel with no slides. */\n async getActiveSlideText(): Promise<string> {\n const index = await this.getActiveIndex();\n return (await this.slides())[index].text();\n }\n\n /**\n * The track's rendered offset, as a percentage of one viewport: `-100` for the\n * second slide of an LTR carousel, `+100` for the second slide of a mirrored one.\n *\n * Read off the inline `style` attribute rather than through `getCssValue()`,\n * because the percentage only survives where the component wrote it. jsdom hands\n * a declared `transform` straight back through `getComputedStyle`, so\n * `getCssValue()` answers correctly HERE and would stop the moment the same\n * harness ran against a real browser, which resolves the property to a pixel\n * matrix — a green unit test would be hiding it. Mid-drag the component writes\n * `translateX(calc(-100% + 12px))` and this reports the settled `-100`: the pixel\n * half is the finger's own displacement, which is physical in both directions and\n * belongs to no slide.\n *\n * Worth asserting next to {@link getActiveIndex}: it is the same fact painted\n * instead of announced, and a carousel that lights the right dot while parking\n * the track in blank space is exactly the failure nobody sees in a spec.\n */\n async getTrackOffsetPercent(): Promise<number> {\n const style = (await (await this.track()).getAttribute('style')) ?? '';\n const match = TRACK_OFFSET.exec(style);\n if (!match) {\n throw new Error(\n `WrCarouselHarness.getTrackOffsetPercent(): the track carries no translateX() offset (style: \"${style}\"). ` +\n 'That transform is how the carousel moves at all, so it should always be there.'\n );\n }\n return Number(match[1]);\n }\n\n // The controls the carousel renders\n\n /** Whether the prev / next arrows are on the page. Both are dropped together. */\n async hasArrows(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-carousel__nav--next')()) !== null;\n }\n\n /** Whether the dot strip is on the page. */\n async hasDots(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-carousel__dots')()) !== null;\n }\n\n /** How many dots are rendered — one per slide, or `0` while the strip is hidden. */\n async getDotCount(): Promise<number> {\n return (await this.dots()).length;\n }\n\n /**\n * The accessible name of every dot, in order — `'Go to slide 1'`, … resolved\n * through the `ngwr/i18n` catalog.\n *\n * A dot is a bare button with no text of its own, so this label is all a screen\n * reader has to tell one from another. `[]` when the strip is hidden, matching\n * {@link getDotCount}.\n */\n async getDotLabels(): Promise<(string | null)[]> {\n const dots = await this.dots();\n return Promise.all(dots.map(dot => dot.getAttribute('aria-label')));\n }\n\n // Moving the carousel\n\n /**\n * Click the next-slide arrow.\n *\n * \"Next\" is the next SLIDE, not the next thing on the right: the buttons keep\n * their semantics under `dir=\"rtl\"` and only the travel under them turns around.\n * At the last slide this wraps to the first one, unless `[loop]` is off — in\n * which case it legitimately does nothing, so nothing is asserted about the move.\n */\n async next(): Promise<void> {\n return (await this.nav('next', 'next')).click();\n }\n\n /** Click the previous-slide arrow. Wraps to the last slide unless `[loop]` is off. */\n async previous(): Promise<void> {\n return (await this.nav('prev', 'previous')).click();\n }\n\n /**\n * Jump to a slide by clicking its dot — the only way the page offers to reach a\n * slide directly.\n *\n * Throws when the dots are hidden (the component's own `goTo()` is still there\n * for a spec holding the instance, but nothing on the page can be clicked) and\n * throws on an index no slide has, rather than clicking nothing and leaving the\n * carousel where it was.\n */\n async goTo(index: number): Promise<void> {\n const dots = await this.dots();\n if (!dots.length) {\n throw new Error(\n `WrCarouselHarness.goTo(${index}): this carousel renders no dots, and they are the only way to reach a ` +\n 'slide directly from the page — they are dropped when [showDots] is false or when there are fewer than ' +\n 'two slides. Use next() / previous(), or write the active index from the host.'\n );\n }\n if (!Number.isInteger(index) || index < 0 || index >= dots.length) {\n throw new Error(\n `WrCarouselHarness.goTo(${index}): out of range — this carousel has ${dots.length} slides, so the index ` +\n `must be a whole number between 0 and ${dots.length - 1}.`\n );\n }\n return dots[index].click();\n }\n\n // Holding autoplay\n\n /**\n * Move the pointer onto the carousel, which is what HOLDS autoplay.\n *\n * Aimed at the host and not the viewport, deliberately: the arrows and the dots\n * are the viewport's SIBLINGS, so a viewport-scoped hover would let a slide\n * change under a cursor that is aiming at an arrow.\n */\n async hover(): Promise<void> {\n return (await this.host()).hover();\n }\n\n /** Move the pointer away again, releasing the hold. */\n async mouseAway(): Promise<void> {\n return (await this.host()).mouseAway();\n }\n\n /**\n * Put keyboard focus on the first control the carousel renders — the previous\n * arrow, or the first dot when the arrows are hidden.\n *\n * This is the keyboard half of the autoplay hold: WCAG 2.2.2 wants a way to stop\n * moving content, and hovering is not one for someone who never touches a mouse,\n * so the component listens for `focusin` on its host as well. Focus lands on the\n * carousel's OWN controls; anything focusable a slide happens to project is not\n * this harness's business, though in a browser it would hold autoplay just the\n * same.\n *\n * Note what this is NOT: the dot of the slide showing. The dots are ordinary\n * buttons with no roving `tabindex`, so each of them is a tab stop of its own and\n * the first one a Tab press meets is the prev arrow whatever slide is current —\n * two different questions, answered here and by {@link getActiveIndex}.\n *\n * Throws when the carousel renders no controls at all, because then there is\n * nothing for a Tab press to land on and no keyboard mechanism to assert.\n */\n async focus(): Promise<void> {\n const [first] = await this.controls();\n if (!first) {\n throw new Error(\n 'WrCarouselHarness.focus(): this carousel renders no controls of its own — the arrows and the dots are ' +\n 'both gone (a single slide, or [showArrows] and [showDots] switched off), so a Tab press has nothing ' +\n 'inside it to land on.'\n );\n }\n return first.focus();\n }\n\n /**\n * Take focus off whichever of the carousel's controls holds it, releasing the\n * hold {@link focus} started.\n *\n * Throws when none of them is focused: `focusout` is what the component listens\n * for, and blurring an element that never had focus fires nothing — a quiet\n * no-op here surfaces as an autoplay assertion failing three lines later.\n */\n async blur(): Promise<void> {\n for (const control of await this.controls()) {\n if (await control.isFocused()) return control.blur();\n }\n throw new Error(\n 'WrCarouselHarness.blur(): none of the controls this carousel renders holds focus, so there is no focus to ' +\n 'release. Call focus() first — the hold is released by blurring the element that took it.'\n );\n }\n\n /** Whether one of the carousel's own controls holds focus — which is what holds autoplay. */\n async isFocused(): Promise<boolean> {\n for (const control of await this.controls()) {\n if (await control.isFocused()) return true;\n }\n return false;\n }\n\n // Internals\n\n /** The element that carries the carousel's role and name. */\n private async viewport(): Promise<TestElement> {\n return this.locatorFor('.wr-carousel__viewport')();\n }\n\n /** The moving strip, whose inline transform is where the carousel IS. */\n private async track(): Promise<TestElement> {\n return this.locatorFor('.wr-carousel__track')();\n }\n\n private async slides(): Promise<TestElement[]> {\n return this.locatorForAll('wr-carousel-slide')();\n }\n\n private async dots(): Promise<TestElement[]> {\n return this.locatorForAll('.wr-carousel__dot')();\n }\n\n /**\n * Every control the carousel renders itself, in the order a Tab press meets\n * them: the two arrows, then the dots.\n */\n private async controls(): Promise<TestElement[]> {\n const navs = await this.locatorForAll('.wr-carousel__nav')();\n return [...navs, ...(await this.dots())];\n }\n\n /** One arrow, or a failure naming both reasons it might not be there. */\n private async nav(side: 'prev' | 'next', caller: string): Promise<TestElement> {\n const button = await this.locatorForOptional(`.wr-carousel__nav--${side}`)();\n if (!button) {\n throw new Error(\n `WrCarouselHarness.${caller}(): this carousel renders no ${side} arrow — the arrows are dropped when ` +\n '[showArrows] is false or when there are fewer than two slides to page through.'\n );\n }\n return button;\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-carousel-testing.mjs","sources":["../../../projects/lib/carousel/testing/wr-carousel-harness.ts","../../../projects/lib/carousel/testing/ngwr-carousel-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, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrCarouselHarnessFilters } from './interfaces';\n\n/**\n * The settled percentage out of `translateX(-100%)`, and out of the mid-drag\n * `translateX(calc(-100% + 12px))` — the pixel half is the finger, not the slide.\n */\nconst TRACK_OFFSET = /translateX\\(\\s*(?:calc\\(\\s*)?(-?[\\d.]+)%/;\n\n/**\n * Test harness for `<wr-carousel>` — drive the strip the way someone on the page\n * drives it.\n *\n * Everything it reads is public API: the `.wr-carousel__*` elements, the dots'\n * `aria-current`, and the `aria-roledescription` the viewport and each slide\n * publish. Two things are worth knowing before writing an assertion against it:\n *\n * - **The slides do not say which one is showing.** A `<wr-carousel-slide>` carries\n * `role=\"group\"` and `aria-roledescription=\"slide\"` and nothing else — no\n * `aria-current`, no `aria-hidden` on the ones off-screen. The current slide is\n * published in exactly two places, the dot carrying `aria-current=\"true\"` and the\n * track's own offset, and {@link getActiveIndex} reads them in that order. There\n * is likewise no live region: the component announces a move to nobody, so a\n * harness cannot report one.\n * - **It never drags.** The swipe the component supports is a touch gesture\n * measured against the viewport's own width, and jsdom has no layout — that width\n * is 0, so the \"20% of the viewport\" threshold is 0 too and EVERY drag clears it,\n * a 1px twitch included. The result says nothing about a real finger, and the spec\n * pins that artifact rather than pretending otherwise. Every move here goes\n * through the arrow buttons and the dots instead, which is the accessible path\n * anyway. `carousel.spec.ts` is where the gesture itself is pinned, by staging the\n * touch events and declaring an `offsetWidth`.\n *\n * @example\n * ```ts\n * const loader = TestbedHarnessEnvironment.loader(fixture);\n * const gallery = await loader.getHarness(WrCarouselHarness.with({ ariaLabel: 'Gallery' }));\n *\n * expect(await gallery.getSlideCount()).toBe(3);\n * await gallery.next();\n * expect(await gallery.getActiveIndex()).toBe(1);\n *\n * await gallery.goTo(2);\n * expect(await gallery.getActiveSlideText()).toBe('Dunes');\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCarouselHarness extends ComponentHarness {\n static hostSelector = 'wr-carousel';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrCarouselHarnessFilters = {}): HarnessPredicate<WrCarouselHarness> {\n return new HarnessPredicate(WrCarouselHarness, options)\n .addOption('ariaLabel', options.ariaLabel, (harness, label) =>\n HarnessPredicate.stringMatches(harness.getAccessibleName(), label)\n )\n .addOption('slideCount', options.slideCount, async (harness, count) => (await harness.getSlideCount()) === count)\n .addOption('slideText', options.slideText, async (harness, text) => {\n for (const slide of await harness.getSlideTexts()) {\n if (await HarnessPredicate.stringMatches(slide, text)) return true;\n }\n return false;\n });\n }\n\n // What the carousel announces\n\n /**\n * The role the strip announces — `group`, which is what lets\n * `aria-roledescription` mean anything.\n *\n * Read off the VIEWPORT rather than the host, and that is the whole point of the\n * pairing: `aria-roledescription` is dropped on an element with no semantic role,\n * and the host element (`<wr-carousel>`) has none.\n */\n async getRole(): Promise<string | null> {\n return (await this.viewport()).getAttribute('role');\n }\n\n /** How the strip describes itself to a screen reader — `carousel`. */\n async getRoleDescription(): Promise<string | null> {\n return (await this.viewport()).getAttribute('aria-roledescription');\n }\n\n /**\n * The carousel's accessible name.\n *\n * The RESOLVED one, which is the only one the page has: the `ariaLabel` input\n * defaults to `null` and the component runs it through the `ngwr/i18n` catalog\n * (`carousel.label`, falling back to `'Carousel'`), so a consumer who passed\n * nothing still gets a named group and this still answers. Reporting the raw\n * input would say `null` about a carousel that announces itself perfectly well.\n */\n async getAccessibleName(): Promise<string | null> {\n return (await this.viewport()).getAttribute('aria-label');\n }\n\n /** The accessible name of the previous-slide button. Throws when the arrows are not rendered. */\n async getPreviousLabel(): Promise<string | null> {\n return (await this.nav('prev', 'getPreviousLabel')).getAttribute('aria-label');\n }\n\n /** The accessible name of the next-slide button. Throws when the arrows are not rendered. */\n async getNextLabel(): Promise<string | null> {\n return (await this.nav('next', 'getNextLabel')).getAttribute('aria-label');\n }\n\n /**\n * The accessible name of the dot group — what names the row of dots as a set\n * rather than leaving a screen reader with N unexplained buttons.\n *\n * Throws when the dots are not rendered: there is no group to name then, and a\n * `null` would read like a group that lost its label.\n */\n async getPaginationLabel(): Promise<string | null> {\n const dots = await this.locatorForOptional('.wr-carousel__dots')();\n if (!dots) {\n throw new Error(\n 'WrCarouselHarness.getPaginationLabel(): this carousel renders no dot group — the dots are dropped ' +\n 'when [showDots] is false or when there are fewer than two slides.'\n );\n }\n return dots.getAttribute('aria-label');\n }\n\n /**\n * What each slide announces itself as — `slide`, on every one of them, in DOM\n * order.\n *\n * The one piece of ARIA the slides carry, and the reason it is worth asking: it\n * is set on the slide component's own host, so a slide reaching the page through\n * some other element would come back `null` here while the carousel kept working.\n */\n async getSlideRoleDescriptions(): Promise<(string | null)[]> {\n const slides = await this.slides();\n return Promise.all(slides.map(slide => slide.getAttribute('aria-roledescription')));\n }\n\n // What the carousel is showing\n\n /** How many slides the carousel holds. */\n async getSlideCount(): Promise<number> {\n return (await this.slides()).length;\n }\n\n /** The text of every slide, in DOM order. */\n async getSlideTexts(): Promise<string[]> {\n const slides = await this.slides();\n return Promise.all(slides.map(slide => slide.text()));\n }\n\n /**\n * Which slide is showing, as a zero-based index.\n *\n * Taken from the dot carrying `aria-current=\"true\"` whenever the dots are\n * rendered — that attribute is the only thing on the page that tells a screen\n * reader where in the strip it has got to, so it is the answer that matters —\n * and derived from the track's rendered offset when they are not, `[showDots]`\n * being off and a single-slide carousel both dropping the strip entirely.\n *\n * That fallback takes the MAGNITUDE of the offset on purpose. The transform is\n * physical while the slides sit on the inline axis, so a mirrored carousel paints\n * `translateX(100%)` for the very slide an LTR one paints `translateX(-100%)`\n * for; signed, this reported slide -1 for a perfectly healthy RTL carousel.\n *\n * Throws on a carousel with no slides at all — nothing is showing there, and `0`\n * would read like the first slide.\n */\n async getActiveIndex(): Promise<number> {\n const count = await this.getSlideCount();\n if (count === 0) {\n throw new Error(\n 'WrCarouselHarness.getActiveIndex(): this carousel has no <wr-carousel-slide> children, so no slide is ' +\n 'current — 0 would read like the first one.'\n );\n }\n\n const dots = await this.dots();\n if (dots.length) {\n for (let index = 0; index < dots.length; index++) {\n if ((await dots[index].getAttribute('aria-current')) === 'true') return index;\n }\n throw new Error(\n 'WrCarouselHarness.getActiveIndex(): the dots are rendered but none of them carries aria-current, so the ' +\n 'page tells a screen reader that no slide is current. The component clamps `active` into range, so look ' +\n 'for a lost aria-current binding rather than an out-of-range index — the `--active` class alone is paint.'\n );\n }\n\n return Math.round(Math.abs(await this.getTrackOffsetPercent()) / 100);\n }\n\n /** The text of the slide that is showing. Throws on a carousel with no slides. */\n async getActiveSlideText(): Promise<string> {\n const index = await this.getActiveIndex();\n return (await this.slides())[index].text();\n }\n\n /**\n * The track's rendered offset, as a percentage of one viewport: `-100` for the\n * second slide of an LTR carousel, `+100` for the second slide of a mirrored one.\n *\n * Read off the inline `style` attribute rather than through `getCssValue()`,\n * because the percentage only survives where the component wrote it. jsdom hands\n * a declared `transform` straight back through `getComputedStyle`, so\n * `getCssValue()` answers correctly HERE and would stop the moment the same\n * harness ran against a real browser, which resolves the property to a pixel\n * matrix — a green unit test would be hiding it. Mid-drag the component writes\n * `translateX(calc(-100% + 12px))` and this reports the settled `-100`: the pixel\n * half is the finger's own displacement, which is physical in both directions and\n * belongs to no slide.\n *\n * Worth asserting next to {@link getActiveIndex}: it is the same fact painted\n * instead of announced, and a carousel that lights the right dot while parking\n * the track in blank space is exactly the failure nobody sees in a spec.\n */\n async getTrackOffsetPercent(): Promise<number> {\n const style = (await (await this.track()).getAttribute('style')) ?? '';\n const match = TRACK_OFFSET.exec(style);\n if (!match) {\n throw new Error(\n `WrCarouselHarness.getTrackOffsetPercent(): the track carries no translateX() offset (style: \"${style}\"). ` +\n 'That transform is how the carousel moves at all, so it should always be there.'\n );\n }\n return Number(match[1]);\n }\n\n // The controls the carousel renders\n\n /** Whether the prev / next arrows are on the page. Both are dropped together. */\n async hasArrows(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-carousel__nav--next')()) !== null;\n }\n\n /** Whether the dot strip is on the page. */\n async hasDots(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-carousel__dots')()) !== null;\n }\n\n /** How many dots are rendered — one per slide, or `0` while the strip is hidden. */\n async getDotCount(): Promise<number> {\n return (await this.dots()).length;\n }\n\n /**\n * The accessible name of every dot, in order — `'Go to slide 1'`, … resolved\n * through the `ngwr/i18n` catalog.\n *\n * A dot is a bare button with no text of its own, so this label is all a screen\n * reader has to tell one from another. `[]` when the strip is hidden, matching\n * {@link getDotCount}.\n */\n async getDotLabels(): Promise<(string | null)[]> {\n const dots = await this.dots();\n return Promise.all(dots.map(dot => dot.getAttribute('aria-label')));\n }\n\n // Moving the carousel\n\n /**\n * Click the next-slide arrow.\n *\n * \"Next\" is the next SLIDE, not the next thing on the right: the buttons keep\n * their semantics under `dir=\"rtl\"` and only the travel under them turns around.\n * At the last slide this wraps to the first one, unless `[loop]` is off — in\n * which case it legitimately does nothing, so nothing is asserted about the move.\n */\n async next(): Promise<void> {\n return (await this.nav('next', 'next')).click();\n }\n\n /** Click the previous-slide arrow. Wraps to the last slide unless `[loop]` is off. */\n async previous(): Promise<void> {\n return (await this.nav('prev', 'previous')).click();\n }\n\n /**\n * Jump to a slide by clicking its dot — the only way the page offers to reach a\n * slide directly.\n *\n * Throws when the dots are hidden (the component's own `goTo()` is still there\n * for a spec holding the instance, but nothing on the page can be clicked) and\n * throws on an index no slide has, rather than clicking nothing and leaving the\n * carousel where it was.\n */\n async goTo(index: number): Promise<void> {\n const dots = await this.dots();\n if (!dots.length) {\n throw new Error(\n `WrCarouselHarness.goTo(${index}): this carousel renders no dots, and they are the only way to reach a ` +\n 'slide directly from the page — they are dropped when [showDots] is false or when there are fewer than ' +\n 'two slides. Use next() / previous(), or write the active index from the host.'\n );\n }\n if (!Number.isInteger(index) || index < 0 || index >= dots.length) {\n throw new Error(\n `WrCarouselHarness.goTo(${index}): out of range — this carousel has ${dots.length} slides, so the index ` +\n `must be a whole number between 0 and ${dots.length - 1}.`\n );\n }\n return dots[index].click();\n }\n\n // Holding autoplay\n\n /**\n * Move the pointer onto the carousel, which is what HOLDS autoplay.\n *\n * Aimed at the host and not the viewport, deliberately: the arrows and the dots\n * are the viewport's SIBLINGS, so a viewport-scoped hover would let a slide\n * change under a cursor that is aiming at an arrow.\n */\n async hover(): Promise<void> {\n return (await this.host()).hover();\n }\n\n /** Move the pointer away again, releasing the hold. */\n async mouseAway(): Promise<void> {\n return (await this.host()).mouseAway();\n }\n\n /**\n * Put keyboard focus on the first control the carousel renders — the previous\n * arrow, or the first dot when the arrows are hidden.\n *\n * This is the keyboard half of the autoplay hold: WCAG 2.2.2 wants a way to stop\n * moving content, and hovering is not one for someone who never touches a mouse,\n * so the component listens for `focusin` on its host as well. Focus lands on the\n * carousel's OWN controls; anything focusable a slide happens to project is not\n * this harness's business, though in a browser it would hold autoplay just the\n * same.\n *\n * Note what this is NOT: the dot of the slide showing. The dots are ordinary\n * buttons with no roving `tabindex`, so each of them is a tab stop of its own and\n * the first one a Tab press meets is the prev arrow whatever slide is current —\n * two different questions, answered here and by {@link getActiveIndex}.\n *\n * Throws when the carousel renders no controls at all, because then there is\n * nothing for a Tab press to land on and no keyboard mechanism to assert.\n */\n async focus(): Promise<void> {\n const [first] = await this.controls();\n if (!first) {\n throw new Error(\n 'WrCarouselHarness.focus(): this carousel renders no controls of its own — the arrows and the dots are ' +\n 'both gone (a single slide, or [showArrows] and [showDots] switched off), so a Tab press has nothing ' +\n 'inside it to land on.'\n );\n }\n return first.focus();\n }\n\n /**\n * Take focus off whichever of the carousel's controls holds it, releasing the\n * hold {@link focus} started.\n *\n * Throws when none of them is focused: `focusout` is what the component listens\n * for, and blurring an element that never had focus fires nothing — a quiet\n * no-op here surfaces as an autoplay assertion failing three lines later.\n */\n async blur(): Promise<void> {\n for (const control of await this.controls()) {\n if (await control.isFocused()) return control.blur();\n }\n throw new Error(\n 'WrCarouselHarness.blur(): none of the controls this carousel renders holds focus, so there is no focus to ' +\n 'release. Call focus() first — the hold is released by blurring the element that took it.'\n );\n }\n\n /** Whether one of the carousel's own controls holds focus — which is what holds autoplay. */\n async isFocused(): Promise<boolean> {\n for (const control of await this.controls()) {\n if (await control.isFocused()) return true;\n }\n return false;\n }\n\n // Internals\n\n /** The element that carries the carousel's role and name. */\n private async viewport(): Promise<TestElement> {\n return this.locatorFor('.wr-carousel__viewport')();\n }\n\n /** The moving strip, whose inline transform is where the carousel IS. */\n private async track(): Promise<TestElement> {\n return this.locatorFor('.wr-carousel__track')();\n }\n\n private async slides(): Promise<TestElement[]> {\n return this.locatorForAll('wr-carousel-slide')();\n }\n\n private async dots(): Promise<TestElement[]> {\n return this.locatorForAll('.wr-carousel__dot')();\n }\n\n /**\n * Every control the carousel renders itself, in the order a Tab press meets\n * them: the two arrows, then the dots.\n */\n private async controls(): Promise<TestElement[]> {\n const navs = await this.locatorForAll('.wr-carousel__nav')();\n return [...navs, ...(await this.dots())];\n }\n\n /** One arrow, or a failure naming both reasons it might not be there. */\n private async nav(side: 'prev' | 'next', caller: string): Promise<TestElement> {\n const button = await this.locatorForOptional(`.wr-carousel__nav--${side}`)();\n if (!button) {\n throw new Error(\n `WrCarouselHarness.${caller}(): this carousel renders no ${side} arrow — the arrows are dropped when ` +\n '[showArrows] is false or when there are fewer than two slides to page through.'\n );\n }\n return button;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -62,10 +62,10 @@ class WrCarouselSlide {
|
|
|
62
62
|
return index >= 0 && index !== this.carousel.active();
|
|
63
63
|
}, /* @ts-ignore */
|
|
64
64
|
...(ngDevMode ? [{ debugName: "offScreen" }] : /* istanbul ignore next */ []));
|
|
65
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
66
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.
|
|
65
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCarouselSlide, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
66
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: WrCarouselSlide, isStandalone: true, selector: "wr-carousel-slide", inputs: { roledescription: { classPropertyName: "roledescription", publicName: "roledescription", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group" }, properties: { "attr.aria-roledescription": "resolvedRoledescription()", "attr.inert": "offScreen() ? \"\" : null", "attr.aria-hidden": "offScreen() ? \"true\" : null" }, classAttribute: "wr-carousel-slide" }, ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
|
|
67
67
|
}
|
|
68
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
68
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCarouselSlide, decorators: [{
|
|
69
69
|
type: Component,
|
|
70
70
|
args: [{
|
|
71
71
|
selector: 'wr-carousel-slide',
|
|
@@ -302,8 +302,8 @@ class WrCarousel {
|
|
|
302
302
|
else if (retreat)
|
|
303
303
|
this.prev();
|
|
304
304
|
}
|
|
305
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
306
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
305
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCarousel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
306
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: WrCarousel, isStandalone: true, selector: "wr-carousel", inputs: { prevLabel: { classPropertyName: "prevLabel", publicName: "prevLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, paginationLabel: { classPropertyName: "paginationLabel", publicName: "paginationLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, roledescription: { classPropertyName: "roledescription", publicName: "roledescription", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, showArrows: { classPropertyName: "showArrows", publicName: "showArrows", isSignal: true, isRequired: false, transformFunction: null }, showDots: { classPropertyName: "showDots", publicName: "showDots", isSignal: true, isRequired: false, transformFunction: null }, autoplay: { classPropertyName: "autoplay", publicName: "autoplay", isSignal: true, isRequired: false, transformFunction: null }, intervalMs: { classPropertyName: "intervalMs", publicName: "intervalMs", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { active: "activeChange" }, host: { listeners: { "mouseenter": "onHoverIn()", "mouseleave": "onHoverOut()", "focusin": "onFocusIn()", "focusout": "onFocusOut()" }, classAttribute: "wr-carousel" }, providers: [
|
|
307
307
|
{
|
|
308
308
|
provide: WR_CAROUSEL,
|
|
309
309
|
// eslint-disable-next-line @angular-eslint/no-forward-ref
|
|
@@ -311,7 +311,7 @@ class WrCarousel {
|
|
|
311
311
|
},
|
|
312
312
|
], queries: [{ propertyName: "slides", predicate: WrCarouselSlide, isSignal: true }], ngImport: i0, template: "<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", encapsulation: i0.ViewEncapsulation.None });
|
|
313
313
|
}
|
|
314
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
314
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCarousel, decorators: [{
|
|
315
315
|
type: Component,
|
|
316
316
|
args: [{ selector: 'wr-carousel', encapsulation: ViewEncapsulation.None, host: {
|
|
317
317
|
class: 'wr-carousel',
|