ngwr 11.1.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/burger/styles/_index.scss +1 -1
- package/button/styles/_index.scss +2 -2
- package/calendar/styles/_index.scss +32 -12
- package/calendar-heatmap/styles/_index.scss +20 -0
- package/carousel/styles/_index.scss +23 -1
- package/cascader/styles/_index.scss +15 -3
- package/checkbox/styles/_index.scss +2 -2
- package/circular-text/styles/_index.scss +11 -0
- package/collapse/styles/_index.scss +2 -2
- package/color-picker/styles/_index.scss +3 -3
- package/command-palette/styles/_index.scss +12 -0
- package/compare/styles/_index.scss +18 -2
- package/context-menu/styles/_index.scss +21 -2
- package/date-picker/styles/_index.scss +5 -5
- package/descriptions/styles/_index.scss +1 -1
- package/drag-drop/styles/_index.scss +28 -1
- package/drawer/styles/_index.scss +37 -0
- package/dropdown/styles/_index.scss +2 -2
- package/event-calendar/styles/_index.scss +67 -10
- package/fesm2022/ngwr-action-sheet-testing.mjs +313 -0
- package/fesm2022/ngwr-action-sheet-testing.mjs.map +1 -0
- package/fesm2022/ngwr-action-sheet.mjs +3 -3
- package/fesm2022/ngwr-affix.mjs +3 -3
- package/fesm2022/ngwr-alert.mjs +3 -3
- package/fesm2022/ngwr-anchor.mjs +3 -3
- package/fesm2022/ngwr-aurora.mjs +3 -3
- package/fesm2022/ngwr-avatar.mjs +3 -3
- package/fesm2022/ngwr-back-top.mjs +3 -3
- package/fesm2022/ngwr-badge.mjs +6 -6
- package/fesm2022/ngwr-bar-chart-testing.mjs +107 -0
- package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-bar-chart.mjs +3 -3
- package/fesm2022/ngwr-blur-text-testing.mjs +203 -0
- package/fesm2022/ngwr-blur-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-blur-text.mjs +18 -4
- package/fesm2022/ngwr-blur-text.mjs.map +1 -1
- package/fesm2022/ngwr-border-glow-testing.mjs +325 -0
- package/fesm2022/ngwr-border-glow-testing.mjs.map +1 -0
- package/fesm2022/ngwr-border-glow.mjs +4 -4
- package/fesm2022/ngwr-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +29 -17
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-burger.mjs +3 -3
- package/fesm2022/ngwr-button.mjs +6 -6
- package/fesm2022/ngwr-calendar-heatmap-testing.mjs +95 -0
- package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -0
- package/fesm2022/ngwr-calendar-heatmap.mjs +17 -5
- package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-testing.mjs +368 -0
- package/fesm2022/ngwr-calendar-testing.mjs.map +1 -0
- package/fesm2022/ngwr-calendar.mjs +228 -10
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-card.mjs +10 -10
- package/fesm2022/ngwr-card.mjs.map +1 -1
- package/fesm2022/ngwr-carousel.mjs +124 -24
- package/fesm2022/ngwr-carousel.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +60 -5
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +14 -6
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text-testing.mjs +230 -0
- package/fesm2022/ngwr-circular-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-circular-text.mjs +4 -4
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-click-spark.mjs +27 -7
- package/fesm2022/ngwr-click-spark.mjs.map +1 -1
- package/fesm2022/ngwr-clipboard.mjs +3 -3
- package/fesm2022/ngwr-collapse.mjs +9 -9
- package/fesm2022/ngwr-color-picker-testing.mjs +452 -0
- package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -0
- package/fesm2022/ngwr-color-picker.mjs +126 -10
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette.mjs +14 -5
- package/fesm2022/ngwr-command-palette.mjs.map +1 -1
- package/fesm2022/ngwr-compare.mjs +3 -3
- package/fesm2022/ngwr-confetti.mjs +31 -6
- package/fesm2022/ngwr-confetti.mjs.map +1 -1
- package/fesm2022/ngwr-config.mjs +9 -0
- package/fesm2022/ngwr-config.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu-testing.mjs +30 -11
- package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu.mjs +358 -48
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-cookie.mjs +3 -3
- package/fesm2022/ngwr-counter.mjs +25 -9
- package/fesm2022/ngwr-counter.mjs.map +1 -1
- package/fesm2022/{ngwr-date-adapter-fns.mjs → ngwr-date-adapters-fns.mjs} +37 -10
- package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -0
- package/fesm2022/{ngwr-date-adapter-luxon.mjs → ngwr-date-adapters-luxon.mjs} +5 -5
- package/fesm2022/ngwr-date-adapters-luxon.mjs.map +1 -0
- package/fesm2022/ngwr-date-picker-testing.mjs +21 -85
- package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +119 -37
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/{ngwr-date-adapter.mjs → ngwr-date.mjs} +36 -10
- package/fesm2022/ngwr-date.mjs.map +1 -0
- package/fesm2022/ngwr-decrypt-text-testing.mjs +261 -0
- package/fesm2022/ngwr-decrypt-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-decrypt-text.mjs +9 -4
- package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
- package/fesm2022/ngwr-density.mjs +6 -6
- package/fesm2022/ngwr-descriptions.mjs +6 -6
- package/fesm2022/ngwr-dialog.mjs +73 -18
- package/fesm2022/ngwr-dialog.mjs.map +1 -1
- package/fesm2022/ngwr-directives.mjs +12 -12
- package/fesm2022/ngwr-divider.mjs +52 -5
- package/fesm2022/ngwr-divider.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart-testing.mjs +97 -0
- package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-donut-chart.mjs +7 -7
- package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +160 -11
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-drawer.mjs +156 -64
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +58 -12
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-empty.mjs +3 -3
- package/fesm2022/ngwr-event-calendar-testing.mjs +446 -0
- package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -0
- package/fesm2022/ngwr-event-calendar.mjs +66 -28
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text-testing.mjs +220 -0
- package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-falling-text.mjs +75 -46
- package/fesm2022/ngwr-falling-text.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload.mjs +3 -3
- package/fesm2022/ngwr-form.mjs +32 -15
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text-testing.mjs +134 -0
- package/fesm2022/ngwr-fuzzy-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-fuzzy-text.mjs +21 -11
- package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
- package/fesm2022/ngwr-gauge-testing.mjs +86 -0
- package/fesm2022/ngwr-gauge-testing.mjs.map +1 -0
- package/fesm2022/ngwr-gauge.mjs +3 -3
- package/fesm2022/ngwr-glitch-text-testing.mjs +215 -0
- package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-glitch-text.mjs +7 -7
- package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text-testing.mjs +258 -0
- package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-gradient-text.mjs +4 -4
- package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
- package/fesm2022/ngwr-hotkey.mjs +24 -9
- package/fesm2022/ngwr-hotkey.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +87 -1
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +69 -1
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n.mjs +26 -15
- package/fesm2022/ngwr-i18n.mjs.map +1 -1
- package/fesm2022/ngwr-icon.mjs +6 -6
- package/fesm2022/ngwr-image-cropper-testing.mjs +200 -0
- package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -0
- package/fesm2022/ngwr-image-cropper.mjs +156 -11
- package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
- package/fesm2022/ngwr-input-number-testing.mjs +15 -10
- package/fesm2022/ngwr-input-number-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input-number.mjs +89 -15
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp-testing.mjs +12 -6
- package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp.mjs +24 -5
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-input.mjs +15 -15
- package/fesm2022/ngwr-keyboard.mjs +3 -3
- package/fesm2022/ngwr-knob-testing.mjs +220 -0
- package/fesm2022/ngwr-knob-testing.mjs.map +1 -0
- package/fesm2022/ngwr-knob.mjs +3 -3
- package/fesm2022/ngwr-layout.mjs +15 -15
- package/fesm2022/ngwr-lightbox-testing.mjs +223 -0
- package/fesm2022/ngwr-lightbox-testing.mjs.map +1 -0
- package/fesm2022/ngwr-lightbox.mjs +11 -4
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart-testing.mjs +119 -0
- package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-line-chart.mjs +73 -26
- package/fesm2022/ngwr-line-chart.mjs.map +1 -1
- package/fesm2022/ngwr-list.mjs +7 -7
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar.mjs +7 -7
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-markdown.mjs +66 -8
- package/fesm2022/ngwr-markdown.mjs.map +1 -1
- package/fesm2022/ngwr-marquee-testing.mjs +336 -0
- package/fesm2022/ngwr-marquee-testing.mjs.map +1 -0
- package/fesm2022/ngwr-marquee.mjs +4 -4
- package/fesm2022/ngwr-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-media.mjs +3 -3
- package/fesm2022/ngwr-mention.mjs +108 -13
- package/fesm2022/ngwr-mention.mjs.map +1 -1
- package/fesm2022/ngwr-meta.mjs +6 -6
- package/fesm2022/ngwr-meter-group-testing.mjs +100 -0
- package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -0
- package/fesm2022/ngwr-meter-group.mjs +3 -3
- package/fesm2022/ngwr-overlay.mjs +34 -7
- package/fesm2022/ngwr-overlay.mjs.map +1 -1
- package/fesm2022/ngwr-page-header.mjs +3 -3
- package/fesm2022/ngwr-pagination-testing.mjs +6 -6
- package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +17 -13
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-pipes.mjs +39 -26
- package/fesm2022/ngwr-pipes.mjs.map +1 -1
- package/fesm2022/ngwr-platform.mjs +9 -9
- package/fesm2022/ngwr-popconfirm.mjs +6 -6
- package/fesm2022/ngwr-popover-testing.mjs +7 -2
- package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
- package/fesm2022/ngwr-popover.mjs +169 -33
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-progress.mjs +3 -3
- package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
- package/fesm2022/ngwr-qr.mjs +42 -5
- package/fesm2022/ngwr-qr.mjs.map +1 -1
- package/fesm2022/ngwr-radio.mjs +6 -6
- package/fesm2022/ngwr-rating.mjs +3 -3
- package/fesm2022/ngwr-result.mjs +21 -30
- package/fesm2022/ngwr-result.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text-testing.mjs +220 -0
- package/fesm2022/ngwr-rotating-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-rotating-text.mjs +4 -4
- package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
- package/fesm2022/ngwr-scroll.mjs +3 -3
- package/fesm2022/ngwr-segmented-testing.mjs +14 -1
- package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
- package/fesm2022/ngwr-segmented.mjs +29 -6
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +227 -43
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text-testing.mjs +237 -0
- package/fesm2022/ngwr-shiny-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-shiny-text.mjs +11 -9
- package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
- package/fesm2022/ngwr-sidebar.mjs +31 -16
- package/fesm2022/ngwr-sidebar.mjs.map +1 -1
- package/fesm2022/ngwr-skeleton.mjs +3 -3
- package/fesm2022/ngwr-slider.mjs +143 -14
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline-testing.mjs +76 -0
- package/fesm2022/ngwr-sparkline-testing.mjs.map +1 -0
- package/fesm2022/ngwr-sparkline.mjs +3 -3
- package/fesm2022/ngwr-speed-dial-testing.mjs +281 -0
- package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -0
- package/fesm2022/ngwr-speed-dial.mjs +27 -12
- package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
- package/fesm2022/ngwr-spinner.mjs +3 -3
- package/fesm2022/ngwr-splash-cursor-testing.mjs +89 -0
- package/fesm2022/ngwr-splash-cursor-testing.mjs.map +1 -0
- package/fesm2022/ngwr-splash-cursor.mjs +3 -3
- package/fesm2022/ngwr-split-text-testing.mjs +224 -0
- package/fesm2022/ngwr-split-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-split-text.mjs +31 -5
- package/fesm2022/ngwr-split-text.mjs.map +1 -1
- package/fesm2022/ngwr-splitter-testing.mjs +245 -0
- package/fesm2022/ngwr-splitter-testing.mjs.map +1 -0
- package/fesm2022/ngwr-splitter.mjs +3 -3
- package/fesm2022/ngwr-spotlight-card-testing.mjs +368 -0
- package/fesm2022/ngwr-spotlight-card-testing.mjs.map +1 -0
- package/fesm2022/ngwr-spotlight-card.mjs +7 -7
- package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-squircle.mjs +6 -6
- package/fesm2022/ngwr-star-border-testing.mjs +172 -0
- package/fesm2022/ngwr-star-border-testing.mjs.map +1 -0
- package/fesm2022/ngwr-star-border.mjs +4 -4
- package/fesm2022/ngwr-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-statistic.mjs +9 -9
- package/fesm2022/ngwr-stepper-testing.mjs +8 -8
- package/fesm2022/ngwr-stepper-testing.mjs.map +1 -1
- package/fesm2022/ngwr-stepper.mjs +33 -8
- package/fesm2022/ngwr-stepper.mjs.map +1 -1
- package/fesm2022/ngwr-storage.mjs +17 -5
- package/fesm2022/ngwr-storage.mjs.map +1 -1
- package/fesm2022/ngwr-switch.mjs +3 -3
- package/fesm2022/ngwr-table.mjs +110 -40
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-testing.mjs +11 -10
- package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +51 -11
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +3 -3
- package/fesm2022/ngwr-theme.mjs +181 -4
- package/fesm2022/ngwr-theme.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card-testing.mjs +190 -0
- package/fesm2022/ngwr-tilt-card-testing.mjs.map +1 -0
- package/fesm2022/ngwr-tilt-card.mjs +26 -8
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-timeline.mjs +6 -6
- package/fesm2022/ngwr-toast.mjs +44 -15
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-toolbar.mjs +3 -3
- package/fesm2022/ngwr-tour-testing.mjs +173 -0
- package/fesm2022/ngwr-tour-testing.mjs.map +1 -0
- package/fesm2022/ngwr-tour.mjs +34 -10
- package/fesm2022/ngwr-tour.mjs.map +1 -1
- package/fesm2022/ngwr-transfer.mjs +3 -3
- package/fesm2022/ngwr-tree.mjs +36 -11
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter-testing.mjs +242 -0
- package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -0
- package/fesm2022/ngwr-typewriter.mjs +13 -5
- package/fesm2022/ngwr-typewriter.mjs.map +1 -1
- package/fesm2022/ngwr-typography.mjs +3 -3
- package/fesm2022/ngwr-utils.mjs +5 -2
- package/fesm2022/ngwr-utils.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +4 -4
- package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-waves-testing.mjs +128 -0
- package/fesm2022/ngwr-waves-testing.mjs.map +1 -0
- package/fesm2022/ngwr-waves.mjs +4 -4
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/fesm2022/ngwr-window-testing.mjs +361 -0
- package/fesm2022/ngwr-window-testing.mjs.map +1 -0
- package/fesm2022/ngwr-window.mjs +175 -31
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/file-upload/styles/_index.scss +2 -2
- package/glitch-text/styles/_index.scss +27 -12
- package/i18n/en.json +71 -7
- package/i18n/ru.json +71 -7
- package/image-cropper/styles/_index.scss +19 -0
- package/input/styles/_index.scss +2 -2
- package/input-number/styles/_index.scss +2 -2
- package/input-otp/styles/_index.scss +9 -2
- package/knob/styles/_index.scss +1 -1
- package/lightbox/styles/_index.scss +16 -2
- package/line-chart/styles/_index.scss +28 -14
- package/list/styles/_index.scss +1 -1
- package/llms-full.txt +161 -19
- package/llms.txt +45 -10
- package/markdown/styles/_index.scss +3 -3
- package/mcp/api.js +6 -4
- package/mcp/catalog.js +40 -3
- package/mcp/providers.js +42 -0
- package/mcp/tools.js +22 -30
- package/meter-group/styles/_index.scss +1 -1
- package/overlay/styles/_index.scss +33 -1
- package/package.json +161 -12
- package/pagination/styles/_index.scss +23 -1
- package/popover/styles/_index.scss +16 -7
- package/progress/styles/_index.scss +1 -1
- package/radio/styles/_index.scss +2 -2
- package/rating/styles/_index.scss +1 -1
- package/schematics/collection.json +1 -1
- package/schematics/migrations/v12/index.js +65 -0
- package/schematics/migrations/v7/index.js +12 -1
- package/schematics/migrations/v8/index.js +10 -1
- package/schematics/migrations.json +5 -0
- package/schematics/ng-add/index.js +8 -3
- package/schematics/provider/index.js +80 -13
- package/schematics/use/index.js +9 -129
- package/schematics/use/rule.js +206 -0
- package/schematics/use/symbol-map.json +4 -4
- package/segmented/styles/_index.scss +14 -3
- package/select/styles/_index.scss +14 -2
- package/sidebar/styles/_index.scss +12 -10
- package/skills/ngwr/SKILL.md +117 -0
- package/skills/ngwr/references/catalog.md +212 -0
- package/skills/ngwr/references/setup.md +78 -0
- package/slider/styles/_index.scss +1 -1
- package/speed-dial/styles/_index.scss +1 -1
- package/stepper/styles/_index.scss +12 -3
- package/switch/styles/_index.scss +2 -2
- package/table/styles/_index.scss +61 -12
- package/tabs/styles/_index.scss +1 -1
- package/textarea/styles/_index.scss +1 -1
- package/theme/styles/_colors.scss +142 -56
- package/theme/styles/_dark.scss +46 -3
- package/theme/styles/_focus.scss +28 -5
- package/theme/styles/_mixins.scss +1 -1
- package/theme/styles/_variables.scss +67 -0
- package/transfer/styles/_index.scss +26 -3
- package/tree/styles/_index.scss +29 -6
- package/types/ngwr-action-sheet-testing.d.ts +260 -0
- package/types/ngwr-bar-chart-testing.d.ts +85 -0
- package/types/ngwr-blur-text-testing.d.ts +180 -0
- package/types/ngwr-blur-text.d.ts +20 -4
- package/types/ngwr-border-glow-testing.d.ts +219 -0
- package/types/ngwr-breadcrumbs.d.ts +17 -10
- package/types/ngwr-calendar-heatmap-testing.d.ts +79 -0
- package/types/ngwr-calendar-testing.d.ts +277 -0
- package/types/ngwr-calendar.d.ts +76 -0
- package/types/ngwr-carousel.d.ts +85 -6
- package/types/ngwr-cascader.d.ts +17 -0
- package/types/ngwr-checkbox.d.ts +13 -0
- package/types/ngwr-circular-text-testing.d.ts +196 -0
- package/types/ngwr-click-spark.d.ts +4 -0
- package/types/ngwr-color-picker-testing.d.ts +299 -0
- package/types/ngwr-color-picker.d.ts +34 -2
- package/types/ngwr-confetti.d.ts +8 -0
- package/types/ngwr-config.d.ts +10 -1
- package/types/ngwr-context-menu-testing.d.ts +24 -11
- package/types/ngwr-context-menu.d.ts +71 -1
- package/types/ngwr-counter.d.ts +1 -0
- package/types/{ngwr-date-adapter-fns.d.ts → ngwr-date-adapters-fns.d.ts} +33 -6
- package/types/{ngwr-date-adapter-luxon.d.ts → ngwr-date-adapters-luxon.d.ts} +1 -1
- package/types/ngwr-date-picker-testing.d.ts +17 -72
- package/types/ngwr-date-picker.d.ts +8 -4
- package/types/{ngwr-date-adapter.d.ts → ngwr-date.d.ts} +24 -5
- package/types/ngwr-decrypt-text-testing.d.ts +222 -0
- package/types/ngwr-dialog.d.ts +38 -1
- package/types/ngwr-divider.d.ts +25 -0
- package/types/ngwr-donut-chart-testing.d.ts +83 -0
- package/types/ngwr-donut-chart.d.ts +3 -3
- package/types/ngwr-drag-drop.d.ts +56 -2
- package/types/ngwr-drawer.d.ts +68 -5
- package/types/ngwr-dropdown.d.ts +9 -0
- package/types/ngwr-event-calendar-testing.d.ts +301 -0
- package/types/ngwr-event-calendar.d.ts +17 -8
- package/types/ngwr-falling-text-testing.d.ts +188 -0
- package/types/ngwr-falling-text.d.ts +1 -1
- package/types/ngwr-form.d.ts +12 -2
- package/types/ngwr-fuzzy-text-testing.d.ts +130 -0
- package/types/ngwr-gauge-testing.d.ts +71 -0
- package/types/ngwr-glitch-text-testing.d.ts +201 -0
- package/types/ngwr-gradient-text-testing.d.ts +186 -0
- package/types/ngwr-i18n.d.ts +13 -4
- package/types/ngwr-image-cropper-testing.d.ts +173 -0
- package/types/ngwr-image-cropper.d.ts +71 -5
- package/types/ngwr-input-number-testing.d.ts +15 -10
- package/types/ngwr-input-number.d.ts +44 -5
- package/types/ngwr-input-otp-testing.d.ts +12 -6
- package/types/ngwr-input-otp.d.ts +15 -1
- package/types/ngwr-knob-testing.d.ts +150 -0
- package/types/ngwr-lightbox-testing.d.ts +154 -0
- package/types/ngwr-lightbox.d.ts +6 -0
- package/types/ngwr-line-chart-testing.d.ts +93 -0
- package/types/ngwr-line-chart.d.ts +20 -3
- package/types/ngwr-markdown.d.ts +11 -0
- package/types/ngwr-marquee-testing.d.ts +280 -0
- package/types/ngwr-mention.d.ts +32 -0
- package/types/ngwr-meter-group-testing.d.ts +77 -0
- package/types/ngwr-overlay.d.ts +20 -1
- package/types/ngwr-pagination-testing.d.ts +4 -4
- package/types/ngwr-pipes.d.ts +1 -1
- package/types/ngwr-popover-testing.d.ts +7 -2
- package/types/ngwr-popover.d.ts +1 -0
- package/types/ngwr-result.d.ts +6 -0
- package/types/ngwr-rotating-text-testing.d.ts +191 -0
- package/types/ngwr-segmented-testing.d.ts +9 -0
- package/types/ngwr-segmented.d.ts +21 -1
- package/types/ngwr-select.d.ts +100 -6
- package/types/ngwr-shiny-text-testing.d.ts +165 -0
- package/types/ngwr-shiny-text.d.ts +4 -2
- package/types/ngwr-sidebar.d.ts +14 -5
- package/types/ngwr-slider.d.ts +84 -1
- package/types/ngwr-sparkline-testing.d.ts +69 -0
- package/types/ngwr-speed-dial-testing.d.ts +199 -0
- package/types/ngwr-speed-dial.d.ts +22 -3
- package/types/ngwr-splash-cursor-testing.d.ts +95 -0
- package/types/ngwr-split-text-testing.d.ts +209 -0
- package/types/ngwr-split-text.d.ts +21 -0
- package/types/ngwr-splitter-testing.d.ts +174 -0
- package/types/ngwr-spotlight-card-testing.d.ts +303 -0
- package/types/ngwr-star-border-testing.d.ts +135 -0
- package/types/ngwr-stepper-testing.d.ts +5 -5
- package/types/ngwr-stepper.d.ts +8 -0
- package/types/ngwr-storage.d.ts +1 -0
- package/types/ngwr-table.d.ts +114 -12
- package/types/ngwr-tabs-testing.d.ts +11 -10
- package/types/ngwr-tabs.d.ts +2 -0
- package/types/ngwr-theme.d.ts +82 -1
- package/types/ngwr-tilt-card-testing.d.ts +158 -0
- package/types/ngwr-tilt-card.d.ts +2 -0
- package/types/ngwr-toast.d.ts +14 -5
- package/types/ngwr-tour-testing.d.ts +143 -0
- package/types/ngwr-tour.d.ts +22 -4
- package/types/ngwr-tree.d.ts +12 -4
- package/types/ngwr-typewriter-testing.d.ts +211 -0
- package/types/ngwr-utils.d.ts +5 -2
- package/types/ngwr-version.d.ts +1 -1
- package/types/ngwr-waves-testing.d.ts +121 -0
- package/types/ngwr-window-testing.d.ts +263 -0
- package/types/ngwr-window.d.ts +66 -21
- package/typography/styles/_index.scss +1 -1
- package/window/styles/_index.scss +116 -42
- package/fesm2022/ngwr-date-adapter-fns.mjs.map +0 -1
- package/fesm2022/ngwr-date-adapter-luxon.mjs.map +0 -1
- package/fesm2022/ngwr-date-adapter.mjs.map +0 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { BaseHarnessFilters, TestKey, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
|
|
2
|
+
import { WrCropHandle } from 'ngwr/image-cropper';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @license
|
|
6
|
+
*
|
|
7
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
8
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Narrows which `<wr-image-cropper>` a harness query matches. */
|
|
12
|
+
interface WrImageCropperHarnessFilters extends BaseHarnessFilters {
|
|
13
|
+
/**
|
|
14
|
+
* Match croppers holding an image (`false`) or showing the empty state (`true`).
|
|
15
|
+
* A cropper with a `src` it has not measured yet is NOT empty — see
|
|
16
|
+
* `WrImageCropperHarness.isReady`.
|
|
17
|
+
*/
|
|
18
|
+
readonly empty?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @license
|
|
23
|
+
*
|
|
24
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
25
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
declare const ARROWS: {
|
|
29
|
+
readonly left: TestKey.LEFT_ARROW;
|
|
30
|
+
readonly right: TestKey.RIGHT_ARROW;
|
|
31
|
+
readonly up: TestKey.UP_ARROW;
|
|
32
|
+
readonly down: TestKey.DOWN_ARROW;
|
|
33
|
+
};
|
|
34
|
+
/** The four directions the crop window's keyboard model understands. */
|
|
35
|
+
type WrCropArrow = keyof typeof ARROWS;
|
|
36
|
+
/** Where the crop window sits over the DISPLAYED image, in CSS pixels. */
|
|
37
|
+
interface WrCropWindowBox {
|
|
38
|
+
readonly x: number;
|
|
39
|
+
readonly y: number;
|
|
40
|
+
readonly width: number;
|
|
41
|
+
readonly height: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Test harness for `<wr-image-cropper>`.
|
|
45
|
+
*
|
|
46
|
+
* **This is the smallest honest surface of any harness here, and the reason is worth
|
|
47
|
+
* reading before you reach for a method that is not on it.** Almost everything the
|
|
48
|
+
* cropper does is measured: it reads the `<img>`'s rendered box and its
|
|
49
|
+
* `naturalWidth`, converts between display and source pixels, and moves the crop
|
|
50
|
+
* window with pointer deltas. jsdom measures nothing — every rect is 0×0 and
|
|
51
|
+
* `naturalWidth` is 0 — so an image never "loads", the crop UI never renders, and a
|
|
52
|
+
* synthetic drag divides by zero. There is deliberately no drag method: it would
|
|
53
|
+
* write `NaN` and report success.
|
|
54
|
+
*
|
|
55
|
+
* What a spec CAN do is give the image a box and a natural size itself, then call
|
|
56
|
+
* {@link dispatchImageLoad} — the two numbers `onImageLoad` reads are the whole
|
|
57
|
+
* stub, and from there {@link getCropBox} and {@link getHandles} are real answers,
|
|
58
|
+
* because the component writes the crop window's geometry as inline pixels. The
|
|
59
|
+
* KEYBOARD path needs the same stub to get the crop UI up, but nothing beyond it:
|
|
60
|
+
* its step is a constant rather than a pointer delta, so {@link pressArrow} lands
|
|
61
|
+
* on a number a spec can name.
|
|
62
|
+
*
|
|
63
|
+
* ```ts
|
|
64
|
+
* // In your spec, before dispatching the load:
|
|
65
|
+
* const img = fixture.nativeElement.querySelector('.wr-image-cropper__image');
|
|
66
|
+
* img.getBoundingClientRect = () => ({ width: 400, height: 400, x: 0, y: 0 }) as DOMRect;
|
|
67
|
+
* Object.defineProperty(img, 'naturalWidth', { value: 800 });
|
|
68
|
+
* Object.defineProperty(img, 'naturalHeight', { value: 800 });
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* **There is nothing to click.** The cropper renders no buttons: the result
|
|
72
|
+
* arrives on the `(cropped)` output, which emits a `Blob` after each drag end or
|
|
73
|
+
* each run of arrow keys, and a consumer who wants a one-off read calls `toBlob()` /
|
|
74
|
+
* `toDataUrl()` — or `cropRect()` for the geometry — on the component through a
|
|
75
|
+
* `viewChild`. An output and three instance members: component API rather than DOM,
|
|
76
|
+
* so all of it is outside what a harness can reach at all, which is worth knowing
|
|
77
|
+
* rather than discovering.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* const cropper = await loader.getHarness(WrImageCropperHarness);
|
|
82
|
+
*
|
|
83
|
+
* expect(await cropper.isEmpty()).toBe(false);
|
|
84
|
+
* expect(await cropper.isReady()).toBe(false); // nothing measured yet
|
|
85
|
+
*
|
|
86
|
+
* await cropper.dispatchImageLoad();
|
|
87
|
+
* expect(await cropper.getCropBox()).toEqual({ x: 80, y: 80, width: 240, height: 240 });
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @see https://ngwr.dev/guides/testing
|
|
91
|
+
*/
|
|
92
|
+
declare class WrImageCropperHarness extends ComponentHarness {
|
|
93
|
+
static hostSelector: string;
|
|
94
|
+
/** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
|
|
95
|
+
static with(options?: WrImageCropperHarnessFilters): HarnessPredicate<WrImageCropperHarness>;
|
|
96
|
+
private readonly image;
|
|
97
|
+
private readonly cropWindow;
|
|
98
|
+
/** Whether the cropper has no source at all, and is showing its placeholder. */
|
|
99
|
+
isEmpty(): Promise<boolean>;
|
|
100
|
+
/** The placeholder's text, or `null` when there is an image. Comes from the catalog. */
|
|
101
|
+
getEmptyText(): Promise<string | null>;
|
|
102
|
+
/**
|
|
103
|
+
* Whether the crop UI is up.
|
|
104
|
+
*
|
|
105
|
+
* Not the same question as {@link isEmpty}: a cropper with a perfectly good `src`
|
|
106
|
+
* shows nothing but the image until it has been MEASURED, because the window's size
|
|
107
|
+
* is a fraction of the rendered box. In a browser that happens on load; in a unit
|
|
108
|
+
* test it happens when the spec stubs the box and calls
|
|
109
|
+
* {@link dispatchImageLoad}.
|
|
110
|
+
*/
|
|
111
|
+
isReady(): Promise<boolean>;
|
|
112
|
+
/**
|
|
113
|
+
* What the `<img>` is pointing at.
|
|
114
|
+
*
|
|
115
|
+
* A `File` or `Blob` source becomes an object URL, so this is `blob:…` for those
|
|
116
|
+
* and the plain string for a string `src`. Comparing the two is not useful; asking
|
|
117
|
+
* whether it CHANGED is.
|
|
118
|
+
*/
|
|
119
|
+
getImageSrc(): Promise<string | null>;
|
|
120
|
+
/**
|
|
121
|
+
* Fire the image's `load` event.
|
|
122
|
+
*
|
|
123
|
+
* The event, not a real load: jsdom fetches nothing, and the handler reads
|
|
124
|
+
* `getBoundingClientRect()` and `naturalWidth` off the element. Stub those first —
|
|
125
|
+
* see this class's docs — or the crop window will still not render and
|
|
126
|
+
* {@link isReady} will stay `false`, which is exactly what a real cropper does with
|
|
127
|
+
* a zero-sized image.
|
|
128
|
+
*/
|
|
129
|
+
dispatchImageLoad(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Where the crop window sits over the displayed image, in CSS pixels.
|
|
132
|
+
*
|
|
133
|
+
* From the inline styles the component writes — a measured box would be 0×0 — and
|
|
134
|
+
* in DISPLAY pixels, which is not what a consumer receives: `cropRect()` converts
|
|
135
|
+
* to the image's natural pixels, and that conversion is the component's own contract
|
|
136
|
+
* rather than something the DOM shows.
|
|
137
|
+
*/
|
|
138
|
+
getCropBox(): Promise<WrCropWindowBox>;
|
|
139
|
+
/** The eight resize handles, by their compass suffix. Throws before the crop UI is up. */
|
|
140
|
+
getHandles(): Promise<WrCropHandle[]>;
|
|
141
|
+
/** Whether the dimming backdrop with the cut-out is drawn. */
|
|
142
|
+
hasBackdrop(): Promise<boolean>;
|
|
143
|
+
/**
|
|
144
|
+
* Press an arrow key on the crop window — one display pixel, or ten with
|
|
145
|
+
* `shift`; `alt` resizes from the east / south edge instead of moving.
|
|
146
|
+
*
|
|
147
|
+
* Sent to the crop window, where the component listens, so it does not depend on
|
|
148
|
+
* jsdom having managed to focus anything. `sendKeys` fires keyup as well as
|
|
149
|
+
* keydown, which is what makes `(cropped)` emit — the component treats a run of
|
|
150
|
+
* arrows as one gesture, the way a drag is one.
|
|
151
|
+
*/
|
|
152
|
+
pressArrow(arrow: WrCropArrow, modifiers?: {
|
|
153
|
+
alt?: boolean;
|
|
154
|
+
shift?: boolean;
|
|
155
|
+
}): Promise<void>;
|
|
156
|
+
/** The crop window's accessible name. Comes from the catalog. */
|
|
157
|
+
getCropWindowLabel(): Promise<string | null>;
|
|
158
|
+
/**
|
|
159
|
+
* The last thing the live region announced — the crop rect in SOURCE pixels,
|
|
160
|
+
* as `x, y, width × height`.
|
|
161
|
+
*
|
|
162
|
+
* Empty until a key has moved the crop: a pointer drag deliberately says nothing
|
|
163
|
+
* (it would flood the region and the sighted user can see it), and the initial
|
|
164
|
+
* crop is not news. Two questions, not one — {@link getCropBox} reads the window's
|
|
165
|
+
* DISPLAY geometry, and a component that moved the box without announcing it
|
|
166
|
+
* would still pass that one.
|
|
167
|
+
*/
|
|
168
|
+
getAnnouncement(): Promise<string>;
|
|
169
|
+
private requireReady;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export { WrImageCropperHarness };
|
|
173
|
+
export type { WrCropArrow, WrCropWindowBox, WrImageCropperHarnessFilters };
|
|
@@ -30,8 +30,12 @@ interface RectPx {
|
|
|
30
30
|
* the crop window or any of its eight handles. Optionally lock the crop
|
|
31
31
|
* to a fixed `[aspectRatio]`.
|
|
32
32
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
33
|
+
* The crop window is also the one tab stop: arrow keys move it, Alt with an
|
|
34
|
+
* arrow key resizes it, and Shift makes either step ten pixels instead of one.
|
|
35
|
+
*
|
|
36
|
+
* `(cropped)` fires after each drag end — or each run of arrow keys — with a
|
|
37
|
+
* freshly-rendered `Blob` of the cropped region. For one-off reads use
|
|
38
|
+
* `toBlob()` / `toDataUrl()`.
|
|
35
39
|
*
|
|
36
40
|
* @example
|
|
37
41
|
* ```html
|
|
@@ -61,6 +65,16 @@ declare class WrImageCropper {
|
|
|
61
65
|
readonly cropped: _angular_core.OutputEmitterRef<Blob>;
|
|
62
66
|
protected readonly imgEl: _angular_core.Signal<ElementRef<HTMLImageElement>>;
|
|
63
67
|
/** Resolved object URL for `src` (so File / Blob render in `<img>`). */
|
|
68
|
+
protected readonly emptyText: _angular_core.Signal<string>;
|
|
69
|
+
/** Accessible name of the crop window — the component's only tab stop. */
|
|
70
|
+
protected readonly resolvedWindowLabel: _angular_core.Signal<string>;
|
|
71
|
+
/** The key model, referenced by the window's `aria-describedby`. */
|
|
72
|
+
protected readonly resolvedKeyHelp: _angular_core.Signal<string>;
|
|
73
|
+
/** Id linking the crop window to the help text. Random rather than counted:
|
|
74
|
+
* the crop UI only exists after a real image load, so it never prerenders. */
|
|
75
|
+
protected readonly helpId: string;
|
|
76
|
+
/** Live-region text — written by the keyboard path only (see `onWindowKeydown`). */
|
|
77
|
+
protected readonly announcement: _angular_core.WritableSignal<string>;
|
|
64
78
|
protected readonly objectUrl: _angular_core.WritableSignal<string | null>;
|
|
65
79
|
/** Previous object URL we created — kept off-signal so the resolve
|
|
66
80
|
* effect doesn't depend on its own writes (which would loop). */
|
|
@@ -77,6 +91,8 @@ declare class WrImageCropper {
|
|
|
77
91
|
}>;
|
|
78
92
|
/** Crop rect in display coordinates. */
|
|
79
93
|
protected readonly cropDisplay: _angular_core.WritableSignal<RectPx>;
|
|
94
|
+
/** Watches the rendered image box — see `watchResize`. */
|
|
95
|
+
private resizeObserver;
|
|
80
96
|
/** Currently active drag handle. */
|
|
81
97
|
private active;
|
|
82
98
|
private startPointer;
|
|
@@ -90,18 +106,68 @@ declare class WrImageCropper {
|
|
|
90
106
|
*
|
|
91
107
|
* `display` is the field that gates everything downstream — the crop UI renders on
|
|
92
108
|
* `display().w > 0` and `cropRect` returns zeros without it — so it is the only one
|
|
93
|
-
* a test can observe. The other two are reset for coherence:
|
|
94
|
-
*
|
|
95
|
-
*
|
|
109
|
+
* a test can observe. The other two are reset for coherence: the resize observer
|
|
110
|
+
* below also writes `display`, and left alone they would resurrect a crop measured
|
|
111
|
+
* against the previous image (which is why `onResize` refuses to run on a zeroed
|
|
112
|
+
* `display` — see there).
|
|
96
113
|
*/
|
|
97
114
|
private resetGeometry;
|
|
98
115
|
protected onImageLoad(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Keep `display` on the box the image is actually rendered at.
|
|
118
|
+
*
|
|
119
|
+
* The stylesheet sizes the image responsively — `max-width: 100%`,
|
|
120
|
+
* `max-height: 70dvh`, `height: auto` — so the single measurement taken in the
|
|
121
|
+
* `(load)` handler stops being true as soon as the container or the viewport
|
|
122
|
+
* changes. Everything the user sees and touches is in DISPLAY pixels: the crop
|
|
123
|
+
* window's inline `left` / `top` / `width` / `height`, the backdrop cut-out, and
|
|
124
|
+
* the bounds `applyMove` / `applyResize` clamp against. Measured once, a narrowed
|
|
125
|
+
* window leaves the crop painted past the edge of the image and draggable off it.
|
|
126
|
+
*
|
|
127
|
+
* Re-observed per load rather than once, because a new `src` may mount a new
|
|
128
|
+
* `<img>`; the old observation would then be on a detached element.
|
|
129
|
+
*/
|
|
130
|
+
private watchResize;
|
|
131
|
+
/**
|
|
132
|
+
* Rescale the crop by however much the image did, so the user keeps the region
|
|
133
|
+
* they picked instead of having it re-centred: `cropRect()` — the source-pixel
|
|
134
|
+
* value a consumer acts on — comes out the same across the resize.
|
|
135
|
+
*/
|
|
136
|
+
private onResize;
|
|
99
137
|
/** Compute a sensible initial crop — centered, respecting aspectRatio. */
|
|
100
138
|
private initialCrop;
|
|
101
139
|
protected readonly handles: readonly WrCropHandle[];
|
|
102
140
|
protected onPointerDown(handle: WrCropHandle, event: PointerEvent): void;
|
|
103
141
|
protected onPointerMove(event: PointerEvent): void;
|
|
104
142
|
protected onPointerUp(event: PointerEvent): void;
|
|
143
|
+
/** Whether a key has moved the crop since the last `keyup`. */
|
|
144
|
+
private keyboardDirty;
|
|
145
|
+
/**
|
|
146
|
+
* The component's only keyboard path. Arrow keys move the crop window; Alt
|
|
147
|
+
* with an arrow key resizes it from the east / south edge; Shift makes either
|
|
148
|
+
* one ten display pixels instead of one — the coarse modifier `wr-slider`,
|
|
149
|
+
* `wr-knob` and `wr-splitter` all use, which is why Alt and not Shift carries
|
|
150
|
+
* the mode switch here.
|
|
151
|
+
*
|
|
152
|
+
* Nothing mirrors under `dir="rtl"`: the image is not flipped and the window
|
|
153
|
+
* is placed with a physical `left`, so ArrowLeft moves the crop visually left
|
|
154
|
+
* in both directions.
|
|
155
|
+
*
|
|
156
|
+
* Both branches go through `applyMove` / `applyResize`, so the `aspectRatio`
|
|
157
|
+
* lock, the `minWidth` / `minHeight` floors and the canvas bounds hold for a
|
|
158
|
+
* keystroke exactly as they do for a drag. Those two measure from `startRect`
|
|
159
|
+
* rather than from the live rect, so it is re-seeded per keystroke — a 1px
|
|
160
|
+
* delta against the rect from the first press would make a held arrow stall
|
|
161
|
+
* after one pixel instead of accumulating.
|
|
162
|
+
*/
|
|
163
|
+
protected onWindowKeydown(event: KeyboardEvent): void;
|
|
164
|
+
/**
|
|
165
|
+
* Emit once per gesture, not once per keystroke. A held arrow repeats its
|
|
166
|
+
* keydown many times a second and each `emitCropped` renders a canvas and
|
|
167
|
+
* encodes a Blob; `keyup` fires once when the run ends, which is the keyboard's
|
|
168
|
+
* equivalent of the `pointerup` the drag path emits on.
|
|
169
|
+
*/
|
|
170
|
+
protected onWindowKeyup(): void;
|
|
105
171
|
private applyMove;
|
|
106
172
|
private applyResize;
|
|
107
173
|
/** Render the current crop as a Blob. */
|
|
@@ -173,13 +173,17 @@ declare class WrInputNumberHarness extends ComponentHarness {
|
|
|
173
173
|
/** The field's placeholder. */
|
|
174
174
|
getPlaceholder(): Promise<string>;
|
|
175
175
|
/**
|
|
176
|
-
* The field's
|
|
176
|
+
* The field's `aria-label`, or `null` when it carries none.
|
|
177
177
|
*
|
|
178
178
|
* Read from the native input, not from the host: an `aria-label` on a component
|
|
179
179
|
* element does not reach the control inside it, which is why the component
|
|
180
|
-
* takes an `ariaLabel` input and forwards it here
|
|
181
|
-
*
|
|
182
|
-
*
|
|
180
|
+
* takes an `ariaLabel` input and forwards it here.
|
|
181
|
+
*
|
|
182
|
+
* NOT the accessible name — `null` is the usual answer and usually correct.
|
|
183
|
+
* Nothing is forwarded unless `[ariaLabel]` is bound: inside a
|
|
184
|
+
* `<wr-form-field>` the name comes from the label's `for`, and standalone it
|
|
185
|
+
* comes from the `placeholder` (see {@link getPlaceholder}), neither of which
|
|
186
|
+
* is an attribute on this element.
|
|
183
187
|
*/
|
|
184
188
|
getAriaLabel(): Promise<string | null>;
|
|
185
189
|
/**
|
|
@@ -212,12 +216,13 @@ declare class WrInputNumberHarness extends ComponentHarness {
|
|
|
212
216
|
/**
|
|
213
217
|
* One of the two stepper buttons, BY POSITION — ▲ first, ▼ second.
|
|
214
218
|
*
|
|
215
|
-
* Not by `aria-label`: those strings
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
219
|
+
* Not by `aria-label`: those strings resolve through the i18n catalog
|
|
220
|
+
* (`inputNumber.increment` / `.decrement`) and an `[incrementLabel]` /
|
|
221
|
+
* `[decrementLabel]` binding overrides them, so keying on them would make this
|
|
222
|
+
* harness answer in whatever locale the app under test is configured for — the
|
|
223
|
+
* same call `WrTimePanelHarness` makes about its own columns. Order is the
|
|
224
|
+
* layout contract, and the spec pins it by asserting which way each button
|
|
225
|
+
* moves the value.
|
|
221
226
|
*/
|
|
222
227
|
private stepButton;
|
|
223
228
|
}
|
|
@@ -14,7 +14,7 @@ import { WrInputSize } from 'ngwr/input';
|
|
|
14
14
|
* re-formats with grouping + fixed decimals on blur.
|
|
15
15
|
*
|
|
16
16
|
* Locale comes from Angular's `LOCALE_ID` — input-number intentionally does
|
|
17
|
-
* NOT depend on `ngwr/date
|
|
17
|
+
* NOT depend on `ngwr/date` so it can be used in date-free apps.
|
|
18
18
|
*
|
|
19
19
|
* @example
|
|
20
20
|
* ```html
|
|
@@ -73,12 +73,30 @@ declare class WrInputNumber implements FormValueControl<number | null> {
|
|
|
73
73
|
/** Placeholder shown when the input is empty. */
|
|
74
74
|
readonly placeholder: _angular_core.InputSignal<string>;
|
|
75
75
|
/**
|
|
76
|
-
* Accessible name for the field.
|
|
77
|
-
*
|
|
78
|
-
*
|
|
76
|
+
* Accessible name for the field. Unset, the field is named by whatever labels
|
|
77
|
+
* it — there is deliberately no fallback here.
|
|
78
|
+
*
|
|
79
|
+
* It used to mirror the `placeholder`, and an `aria-label` OUTRANKS a
|
|
80
|
+
* `<label>` in the accname order: inside a `<wr-form-field label="Quantity">`
|
|
81
|
+
* the very input that adopts the field's id announced the placeholder ("0")
|
|
82
|
+
* instead, and a placeholder disappears as soon as the user types. Standalone
|
|
83
|
+
* nothing was lost by dropping it — an input with no other name already falls
|
|
84
|
+
* back to its own `placeholder` attribute, which is the name axe's `label`
|
|
85
|
+
* rule accepts too.
|
|
79
86
|
*/
|
|
80
87
|
readonly ariaLabel: _angular_core.InputSignal<string | null>;
|
|
81
88
|
protected readonly resolvedAriaLabel: _angular_core.Signal<string | null>;
|
|
89
|
+
/** Increment button aria-label. Falls back to `inputNumber.increment`. */
|
|
90
|
+
readonly incrementLabel: _angular_core.InputSignal<string | null>;
|
|
91
|
+
/** Decrement button aria-label. Falls back to `inputNumber.decrement`. */
|
|
92
|
+
readonly decrementLabel: _angular_core.InputSignal<string | null>;
|
|
93
|
+
/**
|
|
94
|
+
* The steppers are icon-only buttons, so these ARE their accessible names.
|
|
95
|
+
* They were hard-coded English while the catalog carried the keys for them
|
|
96
|
+
* unread — a Russian app announced "Increment".
|
|
97
|
+
*/
|
|
98
|
+
protected readonly resolvedIncrement: _angular_core.Signal<string>;
|
|
99
|
+
protected readonly resolvedDecrement: _angular_core.Signal<string>;
|
|
82
100
|
/** Disable interaction. @default false */
|
|
83
101
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
84
102
|
/** Read-only — values cannot be changed (steppers + typing disabled). @default false */
|
|
@@ -97,6 +115,27 @@ declare class WrInputNumber implements FormValueControl<number | null> {
|
|
|
97
115
|
protected readonly atMin: _angular_core.Signal<boolean>;
|
|
98
116
|
protected readonly atMax: _angular_core.Signal<boolean>;
|
|
99
117
|
protected readonly classes: _angular_core.Signal<string>;
|
|
118
|
+
/**
|
|
119
|
+
* Fraction digits the stepper rounds its arithmetic to when `decimals` says
|
|
120
|
+
* nothing. High enough to leave a real value alone, low enough to erase the
|
|
121
|
+
* binary-float tail that repeated stepping accumulates.
|
|
122
|
+
*/
|
|
123
|
+
private static readonly STEP_PRECISION;
|
|
124
|
+
/**
|
|
125
|
+
* Above this, the anti-drift round is skipped — it would MANUFACTURE drift.
|
|
126
|
+
*
|
|
127
|
+
* `round(v, 10)` is `Math.round((v + EPSILON) * 1e10) / 1e10`, and the scale
|
|
128
|
+
* factor is only exact while `v * 1e10` stays inside 2^53, i.e. |v| under
|
|
129
|
+
* about 900,720. In practice the round-trip still recovers up to ~9.2e8 and
|
|
130
|
+
* then breaks: `round(1000000001, 10)` is `1000000000.9999999`, and since
|
|
131
|
+
* `format` prints up to 20 fraction digits that tail reaches the screen —
|
|
132
|
+
* and compounds, because the next press starts from it. Integer stepping at
|
|
133
|
+
* that magnitude is exact in IEEE754 and needed no help; the only thing this
|
|
134
|
+
* rounding exists to defend is `0.1 + 0.1 + 0.1`.
|
|
135
|
+
*/
|
|
136
|
+
private static readonly SAFE_ROUND_MAGNITUDE;
|
|
137
|
+
/** Steps finer than this would be rounded away by {@link STEP_PRECISION}. */
|
|
138
|
+
private static readonly SAFE_ROUND_STEP;
|
|
100
139
|
constructor();
|
|
101
140
|
protected onInput(event: Event): void;
|
|
102
141
|
protected onFocus(): void;
|
|
@@ -112,7 +151,7 @@ declare class WrInputNumber implements FormValueControl<number | null> {
|
|
|
112
151
|
/** Format a value using `Intl.NumberFormat` for the active locale. */
|
|
113
152
|
private format;
|
|
114
153
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrInputNumber, never>;
|
|
115
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrInputNumber, "wr-input-number", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "decimals": { "alias": "decimals"; "required": false; "isSignal": true; }; "showSteppers": { "alias": "showSteppers"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, never, true, never>;
|
|
154
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrInputNumber, "wr-input-number", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "decimals": { "alias": "decimals"; "required": false; "isSignal": true; }; "showSteppers": { "alias": "showSteppers"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "incrementLabel": { "alias": "incrementLabel"; "required": false; "isSignal": true; }; "decrementLabel": { "alias": "decrementLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, never, true, never>;
|
|
116
155
|
}
|
|
117
156
|
|
|
118
157
|
export { WrInputNumber };
|
|
@@ -54,11 +54,11 @@ interface WrInputOtpHarnessFilters extends BaseHarnessFilters {
|
|
|
54
54
|
* single character.
|
|
55
55
|
*
|
|
56
56
|
* A box is more than the string it shows: it carries its own accessible name
|
|
57
|
-
* (`Digit 3`
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* box's, so a spec can hold on to
|
|
61
|
-
* four parallel arrays by index.
|
|
57
|
+
* (`Digit 3` on a numeric strip, `Character 3` on the others), its own
|
|
58
|
+
* emptiness, its own masking, and it is the thing that either has focus or does
|
|
59
|
+
* not. The root harness answers the control's questions (the assembled code,
|
|
60
|
+
* which index is focused); this one answers the box's, so a spec can hold on to
|
|
61
|
+
* "the box that has focus" instead of zipping four parallel arrays by index.
|
|
62
62
|
*
|
|
63
63
|
* @example
|
|
64
64
|
* ```ts
|
|
@@ -93,11 +93,17 @@ declare class WrInputOtpBoxHarness extends ComponentHarness {
|
|
|
93
93
|
/** Whether the box is still waiting for a character. */
|
|
94
94
|
isEmpty(): Promise<boolean>;
|
|
95
95
|
/**
|
|
96
|
-
* The box's accessible name — `Digit 1`, `Digit 2`, …
|
|
96
|
+
* The box's accessible name — `Digit 1`, `Digit 2`, … on a numeric strip.
|
|
97
97
|
*
|
|
98
98
|
* This is the whole of a box's identity for a screen-reader user: the boxes
|
|
99
99
|
* carry no visible label and no position in an `aria-*` set, so the name is
|
|
100
100
|
* how someone knows which one they are in.
|
|
101
|
+
*
|
|
102
|
+
* The word depends on `mode`, so an assertion has to follow it: the
|
|
103
|
+
* `alphanumeric` and `text` modes accept letters, and the component names
|
|
104
|
+
* their boxes `Character 1`, `Character 2`, … rather than call an `A` a digit.
|
|
105
|
+
* Both come from the `inputOtp.digit` / `inputOtp.character` catalog entries,
|
|
106
|
+
* so a localized app answers here in its own language.
|
|
101
107
|
*/
|
|
102
108
|
getLabel(): Promise<string | null>;
|
|
103
109
|
/** Whether the box hides what was typed, like a password field. */
|
|
@@ -42,6 +42,9 @@ type WrInputOtpSize = 'sm' | 'md' | 'lg';
|
|
|
42
42
|
*/
|
|
43
43
|
declare class WrInputOtp implements FormValueControl<string> {
|
|
44
44
|
private readonly dir;
|
|
45
|
+
/** Accessible name of the whole strip. Falls back to `inputOtp.label`. */
|
|
46
|
+
readonly ariaLabel: _angular_core.InputSignal<string | null>;
|
|
47
|
+
protected readonly resolvedAriaLabel: _angular_core.Signal<string>;
|
|
45
48
|
/** Number of cells to render. Clamped to `[1, 20]`. @default 6 */
|
|
46
49
|
readonly length: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
47
50
|
/** Character set per cell. @default 'numeric' */
|
|
@@ -81,6 +84,8 @@ declare class WrInputOtp implements FormValueControl<string> {
|
|
|
81
84
|
protected readonly classes: _angular_core.Signal<string>;
|
|
82
85
|
protected readonly cellType: _angular_core.Signal<"text" | "password">;
|
|
83
86
|
protected readonly cellInputMode: _angular_core.Signal<"numeric" | "text">;
|
|
87
|
+
private readonly digitLabel;
|
|
88
|
+
private readonly characterLabel;
|
|
84
89
|
protected readonly cellRefs: _angular_core.Signal<readonly ElementRef<HTMLInputElement>[]>;
|
|
85
90
|
constructor();
|
|
86
91
|
protected onInput(event: Event, index: number): void;
|
|
@@ -88,6 +93,15 @@ declare class WrInputOtp implements FormValueControl<string> {
|
|
|
88
93
|
protected onPaste(event: ClipboardEvent): void;
|
|
89
94
|
protected onBlur(): void;
|
|
90
95
|
protected trackIndex(index: number): number;
|
|
96
|
+
/**
|
|
97
|
+
* A box's accessible name. It projects no text and carries no label of its own,
|
|
98
|
+
* so this string IS the name a screen reader reads for it.
|
|
99
|
+
*
|
|
100
|
+
* Keyed off `mode`, not fixed: `sanitiseChar` passes any letter through in
|
|
101
|
+
* `alphanumeric` and `text`, so the old literal announced "Digit 3" over a box
|
|
102
|
+
* holding `A` — wrong in a way translating it would not have fixed.
|
|
103
|
+
*/
|
|
104
|
+
protected cellLabel(index: number): string;
|
|
91
105
|
private update;
|
|
92
106
|
private emitChange;
|
|
93
107
|
private focusCell;
|
|
@@ -102,7 +116,7 @@ declare class WrInputOtp implements FormValueControl<string> {
|
|
|
102
116
|
*/
|
|
103
117
|
private inlineKey;
|
|
104
118
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrInputOtp, never>;
|
|
105
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrInputOtp, "wr-input-otp", never, { "length": { "alias": "length"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "mask": { "alias": "mask"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "completed": "completed"; "touch": "touch"; }, never, never, true, never>;
|
|
119
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrInputOtp, "wr-input-otp", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "length": { "alias": "length"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "mask": { "alias": "mask"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "completed": "completed"; "touch": "touch"; }, never, never, true, never>;
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
export { WrInputOtp };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Narrows which `<wr-knob>` a harness query matches. */
|
|
11
|
+
interface WrKnobHarnessFilters extends BaseHarnessFilters {
|
|
12
|
+
/** Match the dial's accessible name — a string is an exact match, a RegExp is tested. */
|
|
13
|
+
readonly label?: string | RegExp;
|
|
14
|
+
/** Match the current value, as `aria-valuenow` reports it. */
|
|
15
|
+
readonly value?: number;
|
|
16
|
+
/** Match only enabled (`false`) or only disabled (`true`) dials. */
|
|
17
|
+
readonly disabled?: boolean;
|
|
18
|
+
/** Match only writable (`false`) or only read-only (`true`) dials. */
|
|
19
|
+
readonly readonly?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @license
|
|
24
|
+
*
|
|
25
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
26
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** The two arrow keys that raise the value, and the two that lower it. */
|
|
30
|
+
type Arrow = 'left' | 'right' | 'up' | 'down';
|
|
31
|
+
/**
|
|
32
|
+
* Test harness for `<wr-knob>` — the radial dial.
|
|
33
|
+
*
|
|
34
|
+
* **Driven by the keyboard, and the drag is not merely unsupported.** Turning the
|
|
35
|
+
* dial with a pointer takes `getBoundingClientRect()`, measures the angle from the
|
|
36
|
+
* centre to the cursor, and maps it onto a 270° arc. jsdom lays nothing out, so the
|
|
37
|
+
* centre is `(0, 0)` and every synthetic gesture writes the same corner of the arc
|
|
38
|
+
* whatever coordinates it is given — a `turnTo()` built on one would pass while
|
|
39
|
+
* proving nothing. The arrows reach every value on the grid and are the accessible
|
|
40
|
+
* path anyway.
|
|
41
|
+
*
|
|
42
|
+
* **Two questions about the value, not one.** {@link getValue} is the number
|
|
43
|
+
* `aria-valuenow` carries; {@link getDisplayValue} is the string in the middle of the
|
|
44
|
+
* dial, which the `suffix` input can make `"50%"` while the announced value stays
|
|
45
|
+
* `50`. They are separate methods because they can disagree, and because
|
|
46
|
+
* `showValue` can remove the text entirely without touching the value.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const knob = await loader.getHarness(WrKnobHarness);
|
|
51
|
+
*
|
|
52
|
+
* await knob.setValue(60);
|
|
53
|
+
* expect(await knob.getValue()).toBe(60);
|
|
54
|
+
* expect(await knob.getDisplayValue()).toBe('60%');
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @see https://ngwr.dev/guides/testing
|
|
58
|
+
*/
|
|
59
|
+
declare class WrKnobHarness extends ComponentHarness {
|
|
60
|
+
static hostSelector: string;
|
|
61
|
+
/** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
|
|
62
|
+
static with(options?: WrKnobHarnessFilters): HarnessPredicate<WrKnobHarness>;
|
|
63
|
+
private readonly surface;
|
|
64
|
+
/** The value the dial announces, from `aria-valuenow`. */
|
|
65
|
+
getValue(): Promise<number>;
|
|
66
|
+
/** The bottom of the range, from `aria-valuemin`. */
|
|
67
|
+
getMin(): Promise<number>;
|
|
68
|
+
/** The top of the range, from `aria-valuemax`. */
|
|
69
|
+
getMax(): Promise<number>;
|
|
70
|
+
/**
|
|
71
|
+
* The text printed in the middle of the dial, suffix included, or `null` when the
|
|
72
|
+
* knob was built with `[showValue]="false"`.
|
|
73
|
+
*
|
|
74
|
+
* Not the same question as {@link getValue}: with a `suffix` the two disagree by
|
|
75
|
+
* design, and a screen reader is told the bare number — the component publishes no
|
|
76
|
+
* `aria-valuetext`, so `50` is what gets announced for a dial that reads `50%`.
|
|
77
|
+
*/
|
|
78
|
+
getDisplayValue(): Promise<string | null>;
|
|
79
|
+
/** The suffix alone, or `null` when there is none (or no value text at all). */
|
|
80
|
+
getSuffix(): Promise<string | null>;
|
|
81
|
+
/** The dial's accessible name — `role="slider"` needs one. */
|
|
82
|
+
getLabel(): Promise<string | null>;
|
|
83
|
+
/** Whether the dial is disabled, from `aria-disabled`. */
|
|
84
|
+
isDisabled(): Promise<boolean>;
|
|
85
|
+
/** Whether the dial is read-only, from `aria-readonly`. */
|
|
86
|
+
isReadonly(): Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* Whether the dial is a tab stop.
|
|
89
|
+
*
|
|
90
|
+
* The component drops it out of the tab order for BOTH disabled and read-only,
|
|
91
|
+
* which is worth knowing: a read-only slider that a keyboard user cannot reach is
|
|
92
|
+
* also one they cannot read, and this is the method that says so.
|
|
93
|
+
*/
|
|
94
|
+
isFocusable(): Promise<boolean>;
|
|
95
|
+
/** Move keyboard focus to the dial. */
|
|
96
|
+
focus(): Promise<void>;
|
|
97
|
+
/** Whether the dial currently holds focus. */
|
|
98
|
+
isFocused(): Promise<boolean>;
|
|
99
|
+
/** Blur the dial — which is what emits `touch` for a knob moved with the keyboard. */
|
|
100
|
+
blur(): Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* Press one arrow key.
|
|
103
|
+
*
|
|
104
|
+
* Right and Up raise the value, Left and Down lower it — all four are live on this
|
|
105
|
+
* component, which has one axis and no mirroring to do. `shift` multiplies the step
|
|
106
|
+
* by ten.
|
|
107
|
+
*/
|
|
108
|
+
pressArrow(arrow: Arrow, options?: {
|
|
109
|
+
shift?: boolean;
|
|
110
|
+
}): Promise<void>;
|
|
111
|
+
/** Press Home — the bottom of the range. */
|
|
112
|
+
pressHome(): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Press End — the top of the range, or the last value ON the grid below it: a range
|
|
115
|
+
* that is not a whole number of steps cannot reach its own maximum.
|
|
116
|
+
*/
|
|
117
|
+
pressEnd(): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Walk the dial to a value with the arrow keys, and assert it landed there.
|
|
120
|
+
*
|
|
121
|
+
* It measures the step as it goes rather than being told it — `step` is an input
|
|
122
|
+
* with no DOM presence, and the value can arrive off the grid, since an external
|
|
123
|
+
* write is clamped but never snapped. So the first press may move by less than a
|
|
124
|
+
* step (it snaps onto the grid) and the walk adapts, which also means the ten-step
|
|
125
|
+
* hops only start once a real step has been seen.
|
|
126
|
+
*
|
|
127
|
+
* Throws rather than half-arriving, and the two reasons read differently: a target
|
|
128
|
+
* outside `[min, max]` is refused before anything moves, while a target BETWEEN two
|
|
129
|
+
* grid points is only discovered by overshooting it, and says where it landed. A
|
|
130
|
+
* dial that will not move at all — disabled, read-only — is the third.
|
|
131
|
+
*/
|
|
132
|
+
setValue(target: number): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Where the handle dot sits, in the SVG's own 100×100 viewBox units.
|
|
135
|
+
*
|
|
136
|
+
* The dial's whole visual state is an arc path and this dot, and neither can be
|
|
137
|
+
* measured in a unit test — but the dot's centre is written as plain `cx` / `cy`
|
|
138
|
+
* attributes, so it reads with no layout at all. That makes it the evidence that
|
|
139
|
+
* the drawing followed the value: at `min` the handle is at the 7 o'clock end of
|
|
140
|
+
* the arc, at `max` the 5 o'clock end.
|
|
141
|
+
*/
|
|
142
|
+
getHandlePosition(): Promise<{
|
|
143
|
+
x: number;
|
|
144
|
+
y: number;
|
|
145
|
+
}>;
|
|
146
|
+
private numeric;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export { WrKnobHarness };
|
|
150
|
+
export type { WrKnobHarnessFilters };
|