ngwr 11.2.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/collapse/styles/_index.scss +2 -2
- package/color-picker/styles/_index.scss +3 -3
- 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.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 +20 -2
- package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-bar-chart.mjs +3 -3
- package/fesm2022/ngwr-blur-text.mjs +3 -3
- package/fesm2022/ngwr-blur-text.mjs.map +1 -1
- 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.mjs +17 -5
- package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-testing.mjs +1 -1
- package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-calendar.mjs +187 -9
- 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 +48 -5
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +6 -6
- 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 +26 -6
- package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +98 -8
- 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 +333 -43
- 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 +11 -6
- 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.mjs +3 -3
- 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 +8 -4
- package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
- 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 +121 -58
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +26 -10
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-empty.mjs +3 -3
- package/fesm2022/ngwr-event-calendar.mjs +28 -15
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text-testing.mjs +5 -3
- package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -1
- 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.mjs +21 -11
- package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
- package/fesm2022/ngwr-gauge.mjs +3 -3
- package/fesm2022/ngwr-glitch-text-testing.mjs +51 -17
- package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text.mjs +7 -7
- package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text-testing.mjs +46 -11
- package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -1
- 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 +73 -1
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +55 -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 +53 -9
- package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper.mjs +150 -12
- 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 +17 -10
- 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.mjs +3 -3
- package/fesm2022/ngwr-layout.mjs +15 -15
- package/fesm2022/ngwr-lightbox.mjs +4 -4
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- 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.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 +26 -6
- package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group.mjs +3 -3
- package/fesm2022/ngwr-overlay.mjs +6 -6
- 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 +155 -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.mjs +3 -3
- 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 +159 -34
- package/fesm2022/ngwr-select.mjs.map +1 -1
- 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 +100 -9
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline.mjs +3 -3
- package/fesm2022/ngwr-speed-dial-testing.mjs +15 -13
- package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -1
- 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.mjs +3 -3
- package/fesm2022/ngwr-split-text.mjs +17 -5
- package/fesm2022/ngwr-split-text.mjs.map +1 -1
- package/fesm2022/ngwr-splitter.mjs +3 -3
- 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.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 +99 -39
- 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 +36 -10
- 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.mjs +7 -7
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-timeline.mjs +6 -6
- package/fesm2022/ngwr-toast.mjs +9 -9
- package/fesm2022/ngwr-toolbar.mjs +3 -3
- 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 +28 -10
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter-testing.mjs +15 -1
- package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -1
- 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.mjs +4 -4
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +94 -24
- 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 +56 -6
- package/i18n/ru.json +56 -6
- 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 +18 -23
- package/llms.txt +22 -6
- package/markdown/styles/_index.scss +3 -3
- package/mcp/api.js +6 -4
- package/mcp/catalog.js +40 -3
- package/mcp/providers.js +16 -3
- package/mcp/tools.js +21 -1
- package/meter-group/styles/_index.scss +1 -1
- package/overlay/styles/_index.scss +33 -1
- package/package.json +17 -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 +7 -5
- package/skills/ngwr/references/catalog.md +9 -9
- package/skills/ngwr/references/setup.md +10 -5
- 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-bar-chart-testing.d.ts +9 -1
- package/types/ngwr-blur-text.d.ts +8 -4
- package/types/ngwr-breadcrumbs.d.ts +17 -10
- package/types/ngwr-calendar-testing.d.ts +1 -1
- package/types/ngwr-calendar.d.ts +66 -0
- package/types/ngwr-carousel.d.ts +85 -6
- package/types/ngwr-cascader.d.ts +17 -0
- package/types/ngwr-click-spark.d.ts +4 -0
- package/types/ngwr-color-picker-testing.d.ts +8 -0
- package/types/ngwr-color-picker.d.ts +21 -1
- 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 +56 -0
- 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 +11 -6
- 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-dialog.d.ts +38 -1
- package/types/ngwr-divider.d.ts +25 -0
- package/types/ngwr-donut-chart-testing.d.ts +7 -3
- package/types/ngwr-donut-chart.d.ts +3 -3
- package/types/ngwr-drag-drop.d.ts +56 -2
- package/types/ngwr-drawer.d.ts +56 -5
- package/types/ngwr-event-calendar.d.ts +8 -2
- package/types/ngwr-falling-text-testing.d.ts +5 -3
- package/types/ngwr-falling-text.d.ts +1 -1
- package/types/ngwr-form.d.ts +12 -2
- package/types/ngwr-glitch-text-testing.d.ts +37 -8
- package/types/ngwr-gradient-text-testing.d.ts +16 -3
- package/types/ngwr-i18n.d.ts +13 -4
- package/types/ngwr-image-cropper-testing.d.ts +49 -10
- package/types/ngwr-image-cropper.d.ts +70 -5
- package/types/ngwr-input-number-testing.d.ts +15 -10
- package/types/ngwr-input-number.d.ts +11 -4
- package/types/ngwr-input-otp-testing.d.ts +12 -6
- package/types/ngwr-input-otp.d.ts +15 -1
- package/types/ngwr-line-chart.d.ts +20 -3
- package/types/ngwr-markdown.d.ts +11 -0
- package/types/ngwr-mention.d.ts +32 -0
- package/types/ngwr-meter-group-testing.d.ts +12 -2
- package/types/ngwr-overlay.d.ts +1 -0
- 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-segmented-testing.d.ts +9 -0
- package/types/ngwr-segmented.d.ts +21 -1
- package/types/ngwr-select.d.ts +68 -6
- package/types/ngwr-shiny-text.d.ts +4 -2
- package/types/ngwr-sidebar.d.ts +14 -5
- package/types/ngwr-slider.d.ts +69 -1
- package/types/ngwr-speed-dial-testing.d.ts +15 -11
- package/types/ngwr-speed-dial.d.ts +22 -3
- package/types/ngwr-split-text.d.ts +9 -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 +104 -11
- 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-tour.d.ts +22 -4
- package/types/ngwr-tree.d.ts +5 -4
- package/types/ngwr-typewriter-testing.d.ts +10 -0
- package/types/ngwr-utils.d.ts +5 -2
- package/types/ngwr-version.d.ts +1 -1
- package/types/ngwr-window.d.ts +39 -11
- package/typography/styles/_index.scss +1 -1
- package/window/styles/_index.scss +72 -26
- 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
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// The house fill for a header strip — `wr-table` and `wr-transfer` use the
|
|
13
13
|
// same one. NOT `--wr-color-light`, which is an intent colour: it composites
|
|
14
14
|
// dark enough that `--wr-color-on-surface-muted` on top of it lands at 3.6:1.
|
|
15
|
-
--wr-event-calendar-fill:
|
|
15
|
+
--wr-event-calendar-fill: var(--wr-color-fill);
|
|
16
16
|
--wr-event-calendar-cols: 7;
|
|
17
17
|
|
|
18
18
|
display: flex;
|
|
@@ -38,6 +38,17 @@
|
|
|
38
38
|
height: 1em;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
// `__nav` is a plain flex row, so it already mirrors: under `dir="rtl"` the
|
|
42
|
+
// prev button lays out at the right edge. Its chevron is drawn pointing
|
|
43
|
+
// physically left, though, so it ends up aiming at the period it moves AWAY
|
|
44
|
+
// from. Turn the glyphs around with the row, the same way the pagination and
|
|
45
|
+
// carousel arrows do — "previous" is the inline start in both directions.
|
|
46
|
+
// Scoped to `__step`, the two icon-only buttons: `__today` sits between them
|
|
47
|
+
// and is text, which must not mirror.
|
|
48
|
+
[dir='rtl'] &__step .wr-icon__svg {
|
|
49
|
+
transform: scaleX(-1);
|
|
50
|
+
}
|
|
51
|
+
|
|
41
52
|
&__title {
|
|
42
53
|
flex: 1 1 auto;
|
|
43
54
|
margin: 0;
|
|
@@ -115,7 +126,7 @@
|
|
|
115
126
|
|
|
116
127
|
&:focus-visible {
|
|
117
128
|
z-index: 2;
|
|
118
|
-
outline:
|
|
129
|
+
outline: var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);
|
|
119
130
|
outline-offset: -2px;
|
|
120
131
|
}
|
|
121
132
|
|
|
@@ -190,7 +201,7 @@
|
|
|
190
201
|
|
|
191
202
|
&:focus-visible {
|
|
192
203
|
z-index: 3;
|
|
193
|
-
outline:
|
|
204
|
+
outline: var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);
|
|
194
205
|
outline-offset: 1px;
|
|
195
206
|
}
|
|
196
207
|
|
|
@@ -209,9 +220,20 @@
|
|
|
209
220
|
|
|
210
221
|
&--time {
|
|
211
222
|
padding: 0.125rem 0.25rem;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
223
|
+
// The clock and the title share a line while there is room for both and
|
|
224
|
+
// the title drops below it when there is not. `flex-direction: column`
|
|
225
|
+
// dropped it unconditionally, and a timed chip's height is a PERCENTAGE
|
|
226
|
+
// of its slot — a 15-minute event in a 30-minute grid is 12px against a
|
|
227
|
+
// 14.4px line box, so the clock came out sliced through the digits and
|
|
228
|
+
// the title rendered at 0px. Wrapping keeps a one-slot chip to a single
|
|
229
|
+
// readable line; `min-height` floors the box at that line plus its
|
|
230
|
+
// padding, so a short event overlaps the slot below rather than showing
|
|
231
|
+
// half a glyph. `align-content` keeps the lines packed at the top — a
|
|
232
|
+
// tall chip would otherwise spread them down its whole height.
|
|
233
|
+
flex-wrap: wrap;
|
|
234
|
+
align-content: flex-start;
|
|
235
|
+
row-gap: 0;
|
|
236
|
+
min-height: 1.25rem;
|
|
215
237
|
white-space: normal;
|
|
216
238
|
}
|
|
217
239
|
|
|
@@ -237,7 +259,20 @@
|
|
|
237
259
|
|
|
238
260
|
&-time {
|
|
239
261
|
font-weight: var(--wr-font-weight-medium);
|
|
240
|
-
|
|
262
|
+
// `--time` turns wrapping back on for the sake of the title; the clock
|
|
263
|
+
// must not follow it. In a week column ~55px wide "09:30 AM" broke over
|
|
264
|
+
// two lines and asked the chip for 28.8px of height — twice what a
|
|
265
|
+
// one-slot event has — so the label was clipped through its own digits.
|
|
266
|
+
white-space: nowrap;
|
|
267
|
+
// The muted role is calibrated against the plain surface, and the chip
|
|
268
|
+
// puts an 18% wash of the event colour under it (line ~192) — which spent
|
|
269
|
+
// the whole margin: 4.18–4.28:1 across the shipped demo colours, under AA
|
|
270
|
+
// in LIGHT for every one of them. Mixing toward the page's own ink is the
|
|
271
|
+
// `-ink` recipe: `--wr-color-on-surface` flips per theme, so one
|
|
272
|
+
// declaration darkens on a light tint and lightens on a dark one. 85% is
|
|
273
|
+
// the most muted share that still reaches 5.0:1 on the deepest tint the
|
|
274
|
+
// demos paint (5.08 on #d1ead1); dark was already clear and only gains.
|
|
275
|
+
color: color-mix(in srgb, var(--wr-color-on-surface-muted) 85%, var(--wr-color-on-surface));
|
|
241
276
|
}
|
|
242
277
|
|
|
243
278
|
&-title {
|
|
@@ -254,10 +289,21 @@
|
|
|
254
289
|
cursor: ns-resize;
|
|
255
290
|
}
|
|
256
291
|
|
|
292
|
+
// The one thing in a day cell that is NOT absolutely positioned, and it has
|
|
293
|
+
// to stay that way. Its lane is `maxLanes` — one past the last chip — so
|
|
294
|
+
// absolute put it at 1.75rem + 3 x 1.375rem = 5.875rem inside a cell whose
|
|
295
|
+
// floor is 5.5rem: the entire button landed in the following week's row,
|
|
296
|
+
// which comes later in the DOM and (correctly, per the `__cell` note above)
|
|
297
|
+
// has no z-index to lose to it, so it swallowed every click. A block box in
|
|
298
|
+
// flow lands on exactly the same 5.875rem — the day-number line box is
|
|
299
|
+
// precisely the 1.75rem the chips offset by, so only the lanes have to be
|
|
300
|
+
// skipped — and makes the cell GROW to hold it instead. `min-height` on the
|
|
301
|
+
// cell is a floor, not a size; the row stretches its siblings to match.
|
|
257
302
|
&__more {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
top: calc(
|
|
303
|
+
display: block;
|
|
304
|
+
width: fit-content;
|
|
305
|
+
margin-top: calc(var(--wr-event-calendar-lane) * (var(--wr-event-calendar-band-height) + 0.125rem));
|
|
306
|
+
margin-inline-start: 0.125rem;
|
|
261
307
|
padding: 0 0.375rem;
|
|
262
308
|
font: inherit;
|
|
263
309
|
font-size: var(--wr-text-xs);
|
|
@@ -275,6 +321,17 @@
|
|
|
275
321
|
|
|
276
322
|
&--editable &__chip {
|
|
277
323
|
cursor: grab;
|
|
324
|
+
// Own the drag gesture — without this a coarse pointer hands the press to
|
|
325
|
+
// the browser as a pan, which fires `pointercancel` before any `pointerup`,
|
|
326
|
+
// and the host's cancel binding drops the drag: a chip could not be moved
|
|
327
|
+
// with a finger at all. Arbitration intersects `touch-action` up the
|
|
328
|
+
// ancestors, so nested `__resize` is covered by the same rule (its 0.375rem
|
|
329
|
+
// height is a separate question). The cost is that a finger-scroll STARTING
|
|
330
|
+
// on a chip no longer scrolls, on an editable calendar only — the trade
|
|
331
|
+
// `wr-splitter`'s gutter already makes. `pan-y` is no softer fallback here:
|
|
332
|
+
// vertical is the axis a week/day move travels, and the only one a resize
|
|
333
|
+
// has.
|
|
334
|
+
touch-action: none;
|
|
278
335
|
}
|
|
279
336
|
|
|
280
337
|
&--dragging {
|
|
@@ -75,10 +75,10 @@ class WrActionSheet {
|
|
|
75
75
|
this.action.emit(item);
|
|
76
76
|
this.open.set(false);
|
|
77
77
|
}
|
|
78
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
79
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
78
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrActionSheet, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
79
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: WrActionSheet, isStandalone: true, selector: "wr-action-sheet", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, titleFallback: { classPropertyName: "titleFallback", publicName: "titleFallback", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", action: "action" }, ngImport: i0, template: "<wr-drawer [(open)]=\"open\" position=\"bottom\" height=\"auto\" rounded showHandle safeArea maxHeight=\"90dvh\">\n <div class=\"wr-action-sheet\">\n @if (title() || message()) {\n <div class=\"wr-action-sheet__header\">\n @if (title()) {\n <div class=\"wr-action-sheet__title\" wrDrawerTitle>{{ title() }}</div>\n }\n @if (message()) {\n <div class=\"wr-action-sheet__message\">{{ message() }}</div>\n }\n </div>\n }\n <!-- The drawer opens as an aria-modal dialog; name it via wrDrawerTitle.\n When there is no visible title, a screen-reader-only fallback keeps the\n dialog from being announced as unnamed. -->\n @if (!title()) {\n <span class=\"wr-action-sheet__sr-only\" wrDrawerTitle>{{ resolvedTitleFallback() }}</span>\n }\n\n <div class=\"wr-action-sheet__group\">\n @for (item of mainActions(); track $index) {\n <button\n type=\"button\"\n class=\"wr-action-sheet__action\"\n [class.wr-action-sheet__action--destructive]=\"item.role === 'destructive'\"\n [disabled]=\"item.disabled\"\n (click)=\"select(item)\"\n >\n @if (item.icon) {\n <wr-icon class=\"wr-action-sheet__icon\" [name]=\"item.icon\" />\n }\n <span class=\"wr-action-sheet__label\">{{ item.label }}</span>\n </button>\n }\n </div>\n\n @if (cancelActions().length) {\n <div class=\"wr-action-sheet__group wr-action-sheet__group--cancel\">\n @for (item of cancelActions(); track $index) {\n <button\n type=\"button\"\n class=\"wr-action-sheet__action wr-action-sheet__action--cancel\"\n [disabled]=\"item.disabled\"\n (click)=\"select(item)\"\n >\n <span class=\"wr-action-sheet__label\">{{ item.label }}</span>\n </button>\n }\n </div>\n }\n </div>\n</wr-drawer>\n", dependencies: [{ kind: "component", type: WrDrawer, selector: "wr-drawer", inputs: ["open", "position", "width", "height", "maxHeight", "rounded", "showHandle", "safeArea", "hasBackdrop", "closeOnBackdropClick", "closeOnEscape", "closable", "closeLabel"], outputs: ["openChange"] }, { kind: "directive", type: WrDrawerTitle, selector: "[wrDrawerTitle]" }, { kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
80
80
|
}
|
|
81
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
81
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrActionSheet, decorators: [{
|
|
82
82
|
type: Component,
|
|
83
83
|
args: [{ selector: 'wr-action-sheet', encapsulation: ViewEncapsulation.None, imports: [WrDrawer, WrDrawerTitle, WrIcon], template: "<wr-drawer [(open)]=\"open\" position=\"bottom\" height=\"auto\" rounded showHandle safeArea maxHeight=\"90dvh\">\n <div class=\"wr-action-sheet\">\n @if (title() || message()) {\n <div class=\"wr-action-sheet__header\">\n @if (title()) {\n <div class=\"wr-action-sheet__title\" wrDrawerTitle>{{ title() }}</div>\n }\n @if (message()) {\n <div class=\"wr-action-sheet__message\">{{ message() }}</div>\n }\n </div>\n }\n <!-- The drawer opens as an aria-modal dialog; name it via wrDrawerTitle.\n When there is no visible title, a screen-reader-only fallback keeps the\n dialog from being announced as unnamed. -->\n @if (!title()) {\n <span class=\"wr-action-sheet__sr-only\" wrDrawerTitle>{{ resolvedTitleFallback() }}</span>\n }\n\n <div class=\"wr-action-sheet__group\">\n @for (item of mainActions(); track $index) {\n <button\n type=\"button\"\n class=\"wr-action-sheet__action\"\n [class.wr-action-sheet__action--destructive]=\"item.role === 'destructive'\"\n [disabled]=\"item.disabled\"\n (click)=\"select(item)\"\n >\n @if (item.icon) {\n <wr-icon class=\"wr-action-sheet__icon\" [name]=\"item.icon\" />\n }\n <span class=\"wr-action-sheet__label\">{{ item.label }}</span>\n </button>\n }\n </div>\n\n @if (cancelActions().length) {\n <div class=\"wr-action-sheet__group wr-action-sheet__group--cancel\">\n @for (item of cancelActions(); track $index) {\n <button\n type=\"button\"\n class=\"wr-action-sheet__action wr-action-sheet__action--cancel\"\n [disabled]=\"item.disabled\"\n (click)=\"select(item)\"\n >\n <span class=\"wr-action-sheet__label\">{{ item.label }}</span>\n </button>\n }\n </div>\n }\n </div>\n</wr-drawer>\n" }]
|
|
84
84
|
}], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], titleFallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleFallback", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
|
package/fesm2022/ngwr-affix.mjs
CHANGED
|
@@ -106,10 +106,10 @@ class WrAffix {
|
|
|
106
106
|
});
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
110
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.
|
|
109
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAffix, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
110
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.2", type: WrAffix, isStandalone: true, selector: "[wrAffix]", inputs: { offsetTop: { classPropertyName: "offsetTop", publicName: "wrAffixOffsetTop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { affixChange: "wrAffixChange" }, host: { properties: { "style.position": "\"sticky\"", "style.top.px": "offsetTop()" }, classAttribute: "wr-affix" }, ngImport: i0 });
|
|
111
111
|
}
|
|
112
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAffix, decorators: [{
|
|
113
113
|
type: Directive,
|
|
114
114
|
args: [{
|
|
115
115
|
selector: '[wrAffix]',
|
package/fesm2022/ngwr-alert.mjs
CHANGED
|
@@ -89,10 +89,10 @@ class WrAlert {
|
|
|
89
89
|
this.dismissed.set(true);
|
|
90
90
|
this.closed.emit();
|
|
91
91
|
}
|
|
92
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
93
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
92
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
93
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: WrAlert, isStandalone: true, selector: "wr-alert", inputs: { closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, iconName: { classPropertyName: "iconName", publicName: "iconName", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, closeable: { classPropertyName: "closeable", publicName: "closeable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { properties: { "class": "classes()", "attr.role": "liveRole()", "attr.aria-live": "liveLevel()" } }, ngImport: i0, template: "@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n @case ('danger') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n </div>\n\n @if (closeable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
94
94
|
}
|
|
95
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
95
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAlert, decorators: [{
|
|
96
96
|
type: Component,
|
|
97
97
|
args: [{ selector: 'wr-alert', imports: [WrIcon], encapsulation: ViewEncapsulation.None, host: {
|
|
98
98
|
'[class]': 'classes()',
|
package/fesm2022/ngwr-anchor.mjs
CHANGED
|
@@ -99,10 +99,10 @@ class WrAnchor {
|
|
|
99
99
|
this.scroll.to(`#${id}`, { offset: this.offset() });
|
|
100
100
|
this.activeId.set(id);
|
|
101
101
|
}
|
|
102
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
103
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
102
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAnchor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
103
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: WrAnchor, isStandalone: true, selector: "wr-anchor", inputs: { links: { classPropertyName: "links", publicName: "links", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, hitArea: { classPropertyName: "hitArea", publicName: "hitArea", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "resolvedAriaLabel()" }, classAttribute: "wr-anchor" }, ngImport: i0, template: "<ul class=\"wr-anchor__list\">\n @for (link of links(); track link.id) {\n <li class=\"wr-anchor__item\">\n <a\n class=\"wr-anchor__link\"\n [class.wr-anchor__link--active]=\"activeId() === link.id\"\n [attr.aria-current]=\"activeId() === link.id ? 'location' : null\"\n [href]=\"`#${link.id}`\"\n (click)=\"onClick(link.id, $event)\"\n >\n {{ link.label }}\n </a>\n @if (link.children?.length) {\n <ul class=\"wr-anchor__list wr-anchor__list--nested\">\n @for (child of link.children; track child.id) {\n <li class=\"wr-anchor__item\">\n <a\n class=\"wr-anchor__link\"\n [class.wr-anchor__link--active]=\"activeId() === child.id\"\n [attr.aria-current]=\"activeId() === child.id ? 'location' : null\"\n [href]=\"`#${child.id}`\"\n (click)=\"onClick(child.id, $event)\"\n >\n {{ child.label }}\n </a>\n </li>\n }\n </ul>\n }\n </li>\n }\n</ul>\n", encapsulation: i0.ViewEncapsulation.None });
|
|
104
104
|
}
|
|
105
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
105
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAnchor, decorators: [{
|
|
106
106
|
type: Component,
|
|
107
107
|
args: [{ selector: 'wr-anchor', encapsulation: ViewEncapsulation.None, host: { class: 'wr-anchor', role: 'navigation', '[attr.aria-label]': 'resolvedAriaLabel()' }, template: "<ul class=\"wr-anchor__list\">\n @for (link of links(); track link.id) {\n <li class=\"wr-anchor__item\">\n <a\n class=\"wr-anchor__link\"\n [class.wr-anchor__link--active]=\"activeId() === link.id\"\n [attr.aria-current]=\"activeId() === link.id ? 'location' : null\"\n [href]=\"`#${link.id}`\"\n (click)=\"onClick(link.id, $event)\"\n >\n {{ link.label }}\n </a>\n @if (link.children?.length) {\n <ul class=\"wr-anchor__list wr-anchor__list--nested\">\n @for (child of link.children; track child.id) {\n <li class=\"wr-anchor__item\">\n <a\n class=\"wr-anchor__link\"\n [class.wr-anchor__link--active]=\"activeId() === child.id\"\n [attr.aria-current]=\"activeId() === child.id ? 'location' : null\"\n [href]=\"`#${child.id}`\"\n (click)=\"onClick(child.id, $event)\"\n >\n {{ child.label }}\n </a>\n </li>\n }\n </ul>\n }\n </li>\n }\n</ul>\n" }]
|
|
108
108
|
}], ctorParameters: () => [], propDecorators: { links: [{ type: i0.Input, args: [{ isSignal: true, alias: "links", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], hitArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "hitArea", required: false }] }] } });
|
package/fesm2022/ngwr-aurora.mjs
CHANGED
|
@@ -294,10 +294,10 @@ class WrAurora {
|
|
|
294
294
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
295
295
|
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
296
296
|
}
|
|
297
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
298
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.
|
|
297
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAurora, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
298
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.2", type: WrAurora, isStandalone: true, selector: "wr-aurora", inputs: { colorStops: { classPropertyName: "colorStops", publicName: "colorStops", isSignal: true, isRequired: false, transformFunction: null }, amplitude: { classPropertyName: "amplitude", publicName: "amplitude", isSignal: true, isRequired: false, transformFunction: null }, blend: { classPropertyName: "blend", publicName: "blend", isSignal: true, isRequired: false, transformFunction: null }, speed: { classPropertyName: "speed", publicName: "speed", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-aurora" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, isSignal: true }], ngImport: i0, template: '<canvas #canvas class="wr-aurora__canvas" aria-hidden="true"></canvas>', isInline: true, styles: [".wr-aurora{--wr-aurora-stop-1: #6366f1;--wr-aurora-stop-2: #10b981;--wr-aurora-stop-3: #6366f1;position:absolute;inset:0;display:block;overflow:hidden;pointer-events:none;z-index:0}.wr-aurora__canvas{display:block;width:100%;height:100%}[data-theme=dark] .wr-aurora{--wr-aurora-stop-1: #5227ff;--wr-aurora-stop-2: #7cff67;--wr-aurora-stop-3: #5227ff}\n"], encapsulation: i0.ViewEncapsulation.None });
|
|
299
299
|
}
|
|
300
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
300
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAurora, decorators: [{
|
|
301
301
|
type: Component,
|
|
302
302
|
args: [{ selector: 'wr-aurora', template: '<canvas #canvas class="wr-aurora__canvas" aria-hidden="true"></canvas>', encapsulation: ViewEncapsulation.None, host: { class: 'wr-aurora' }, styles: [".wr-aurora{--wr-aurora-stop-1: #6366f1;--wr-aurora-stop-2: #10b981;--wr-aurora-stop-3: #6366f1;position:absolute;inset:0;display:block;overflow:hidden;pointer-events:none;z-index:0}.wr-aurora__canvas{display:block;width:100%;height:100%}[data-theme=dark] .wr-aurora{--wr-aurora-stop-1: #5227ff;--wr-aurora-stop-2: #7cff67;--wr-aurora-stop-3: #5227ff}\n"] }]
|
|
303
303
|
}], ctorParameters: () => [], propDecorators: { colorStops: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorStops", required: false }] }], amplitude: [{ type: i0.Input, args: [{ isSignal: true, alias: "amplitude", required: false }] }], blend: [{ type: i0.Input, args: [{ isSignal: true, alias: "blend", required: false }] }], speed: [{ type: i0.Input, args: [{ isSignal: true, alias: "speed", required: false }] }], canvasRef: [{ type: i0.ViewChild, args: ['canvas', { isSignal: true }] }] } });
|
package/fesm2022/ngwr-avatar.mjs
CHANGED
|
@@ -104,10 +104,10 @@ class WrAvatar {
|
|
|
104
104
|
onImageError() {
|
|
105
105
|
this.failed.set(true);
|
|
106
106
|
}
|
|
107
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
108
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
107
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
108
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: WrAvatar, isStandalone: true, selector: "wr-avatar", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "style.width": "cssSize()", "style.height": "cssSize()" } }, ngImport: i0, template: "<ng-content />\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\n class=\"wr-avatar__img\"\n [src]=\"src\"\n [alt]=\"resolvedAlt()\"\n [attr.width]=\"pxSize()\"\n [attr.height]=\"pxSize()\"\n (load)=\"onImageLoad()\"\n (error)=\"onImageError()\"\n decoding=\"async\"\n />\n\n @if (!loaded()) {\n <wr-spinner class=\"wr-avatar__spin\" />\n }\n }\n}\n", dependencies: [{ kind: "component", type: WrSpinner, selector: "wr-spinner", inputs: ["size", "ariaLabel"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
109
109
|
}
|
|
110
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
110
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrAvatar, decorators: [{
|
|
111
111
|
type: Component,
|
|
112
112
|
args: [{ selector: 'wr-avatar', encapsulation: ViewEncapsulation.None, host: {
|
|
113
113
|
'[class]': 'classes()',
|
|
@@ -64,10 +64,10 @@ class WrBackTop {
|
|
|
64
64
|
onClick() {
|
|
65
65
|
this.scroll.toTop({ offset: this.offset() });
|
|
66
66
|
}
|
|
67
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
68
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.
|
|
67
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrBackTop, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
68
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.2", type: WrBackTop, isStandalone: true, selector: "wr-back-top", inputs: { visibilityThreshold: { classPropertyName: "visibilityThreshold", publicName: "visibilityThreshold", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.aria-hidden": "!visible()", "attr.inert": "visible() ? null : ''" } }, ngImport: i0, template: "<button type=\"button\" class=\"wr-back-top__button\" [attr.aria-label]=\"resolvedAriaLabel()\" (click)=\"onClick()\">\n <!-- The arrow is FALLBACK content: rendered next to a projected icon rather\n than instead of it, the documented custom-icon example put two glyphs in\n one 44px circle. -->\n <ng-content>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" aria-hidden=\"true\">\n <path\n d=\"M9 4 L9 14 M4 9 L9 4 L14 9\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </ng-content>\n</button>\n", encapsulation: i0.ViewEncapsulation.None });
|
|
69
69
|
}
|
|
70
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
70
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrBackTop, decorators: [{
|
|
71
71
|
type: Component,
|
|
72
72
|
args: [{ selector: 'wr-back-top', encapsulation: ViewEncapsulation.None, host: {
|
|
73
73
|
'[class]': 'classes()',
|
package/fesm2022/ngwr-badge.mjs
CHANGED
|
@@ -69,10 +69,10 @@ class WrBadge {
|
|
|
69
69
|
return parts.join(' ');
|
|
70
70
|
}, /* @ts-ignore */
|
|
71
71
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
72
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
73
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.
|
|
72
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrBadge, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
73
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.2", type: WrBadge, isStandalone: true, selector: "wr-badge", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, outlined: { classPropertyName: "outlined", publicName: "outlined", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
|
|
74
74
|
}
|
|
75
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
75
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrBadge, decorators: [{
|
|
76
76
|
type: Component,
|
|
77
77
|
args: [{
|
|
78
78
|
selector: 'wr-badge',
|
|
@@ -176,10 +176,10 @@ class WrTag {
|
|
|
176
176
|
return parts.join(' ');
|
|
177
177
|
}, /* @ts-ignore */
|
|
178
178
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
179
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
180
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
179
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrTag, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
180
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: WrTag, isStandalone: true, selector: "wr-tag", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null }, outlined: { classPropertyName: "outlined", publicName: "outlined", isSignal: true, isRequired: false, transformFunction: null }, transparent: { classPropertyName: "transparent", publicName: "transparent", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", 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 } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "@if (iconPosition() === 'start') {\n @if (loading()) {\n <wr-spinner class=\"wr-tag__adornment\" size=\"sm\" />\n } @else if (icon(); as name) {\n <wr-icon class=\"wr-tag__adornment\" [name]=\"name\" />\n }\n}\n\n<ng-content />\n\n@if (iconPosition() === 'end') {\n @if (loading()) {\n <wr-spinner class=\"wr-tag__adornment\" size=\"sm\" />\n } @else if (icon(); as name) {\n <wr-icon class=\"wr-tag__adornment\" [name]=\"name\" />\n }\n}\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }, { kind: "component", type: WrSpinner, selector: "wr-spinner", inputs: ["size", "ariaLabel"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
181
181
|
}
|
|
182
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
182
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrTag, decorators: [{
|
|
183
183
|
type: Component,
|
|
184
184
|
args: [{ selector: 'wr-tag', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, imports: [WrIcon, WrSpinner], template: "@if (iconPosition() === 'start') {\n @if (loading()) {\n <wr-spinner class=\"wr-tag__adornment\" size=\"sm\" />\n } @else if (icon(); as name) {\n <wr-icon class=\"wr-tag__adornment\" [name]=\"name\" />\n }\n}\n\n<ng-content />\n\n@if (iconPosition() === 'end') {\n @if (loading()) {\n <wr-spinner class=\"wr-tag__adornment\" size=\"sm\" />\n } @else if (icon(); as name) {\n <wr-icon class=\"wr-tag__adornment\" [name]=\"name\" />\n }\n}\n" }]
|
|
185
185
|
}], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], outlined: [{ type: i0.Input, args: [{ isSignal: true, alias: "outlined", required: false }] }], transparent: [{ type: i0.Input, args: [{ isSignal: true, alias: "transparent", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], hoverable: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
|
|
@@ -6,13 +6,21 @@ import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
|
|
|
6
6
|
* Use of this source code is governed by an MIT-style license that can be
|
|
7
7
|
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
8
8
|
*/
|
|
9
|
+
/** The `height: <n>%` the component writes onto a bar, out of its inline `style`. */
|
|
10
|
+
const BAR_HEIGHT = /(?:^|;)\s*height\s*:\s*([\d.]+)%/;
|
|
9
11
|
/**
|
|
10
12
|
* Test harness for `<wr-bar-chart>`.
|
|
11
13
|
*
|
|
12
14
|
* **The bars are read as PERCENTAGES, not as pixels.** Each column's height is
|
|
13
15
|
* written inline as a share of the chart's maximum, which is the one number that
|
|
14
16
|
* survives a test with no layout — and it is also the component's whole job, since
|
|
15
|
-
* the maximum is either given or derived from the data.
|
|
17
|
+
* the maximum is either given or derived from the data. That share is read off the
|
|
18
|
+
* `style` ATTRIBUTE rather than through `getCssValue()`, and the difference is not
|
|
19
|
+
* cosmetic: `getCssValue()` is `getComputedStyle()`, which hands the declared `60%`
|
|
20
|
+
* straight back in jsdom and resolves it to used pixels in a real browser — so the
|
|
21
|
+
* same harness answered `100` here and `200` under Selenium or a browser runner,
|
|
22
|
+
* with no error to say which one you got. The stylesheet's own `min-height: 1px`
|
|
23
|
+
* is a second way that read lies, turning an empty bar into `1`.
|
|
16
24
|
*
|
|
17
25
|
* **The visible label row is decoration.** Every column carries `role="img"` with
|
|
18
26
|
* the label AND the value in its name, and the printed labels underneath are
|
|
@@ -53,10 +61,20 @@ class WrBarChartHarness extends ComponentHarness {
|
|
|
53
61
|
label: labels[index] ?? '',
|
|
54
62
|
value: value === '' ? null : value,
|
|
55
63
|
name: await column.getAttribute('aria-label'),
|
|
56
|
-
heightPercent:
|
|
64
|
+
heightPercent: WrBarChartHarness.heightPercentOf(await bars[index].getAttribute('style')),
|
|
57
65
|
};
|
|
58
66
|
}));
|
|
59
67
|
}
|
|
68
|
+
/** Parse one bar's declared share. See the class note on why this is not `getCssValue()`. */
|
|
69
|
+
static heightPercentOf(style) {
|
|
70
|
+
const match = BAR_HEIGHT.exec(style ?? '');
|
|
71
|
+
if (!match) {
|
|
72
|
+
throw new Error(`WrBarChartHarness.getBars(): a bar carries no inline height percentage (style: "${style ?? ''}"). ` +
|
|
73
|
+
'The component writes one for every bar, an empty one included, so its absence is the bug — ' +
|
|
74
|
+
'reporting 0 would read as a bar with nothing in it.');
|
|
75
|
+
}
|
|
76
|
+
return Number.parseFloat(match[1]);
|
|
77
|
+
}
|
|
60
78
|
/** The labels printed under the columns, in order. */
|
|
61
79
|
async getLabels() {
|
|
62
80
|
const labels = await this.locatorForAll('.wr-bar-chart__label')();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-bar-chart-testing.mjs","sources":["../../../projects/lib/bar-chart/testing/wr-bar-chart-harness.ts","../../../projects/lib/bar-chart/testing/ngwr-bar-chart-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 } from '@angular/cdk/testing';\n\nimport type { WrBarChartBar, WrBarChartHarnessFilters } from './interfaces';\n\n/**\n * Test harness for `<wr-bar-chart>`.\n *\n * **The bars are read as PERCENTAGES, not as pixels.** Each column's height is\n * written inline as a share of the chart's maximum, which is the one number that\n * survives a test with no layout — and it is also the component's whole job, since\n * the maximum is either given or derived from the data
|
|
1
|
+
{"version":3,"file":"ngwr-bar-chart-testing.mjs","sources":["../../../projects/lib/bar-chart/testing/wr-bar-chart-harness.ts","../../../projects/lib/bar-chart/testing/ngwr-bar-chart-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 } from '@angular/cdk/testing';\n\nimport type { WrBarChartBar, WrBarChartHarnessFilters } from './interfaces';\n\n/** The `height: <n>%` the component writes onto a bar, out of its inline `style`. */\nconst BAR_HEIGHT = /(?:^|;)\\s*height\\s*:\\s*([\\d.]+)%/;\n\n/**\n * Test harness for `<wr-bar-chart>`.\n *\n * **The bars are read as PERCENTAGES, not as pixels.** Each column's height is\n * written inline as a share of the chart's maximum, which is the one number that\n * survives a test with no layout — and it is also the component's whole job, since\n * the maximum is either given or derived from the data. That share is read off the\n * `style` ATTRIBUTE rather than through `getCssValue()`, and the difference is not\n * cosmetic: `getCssValue()` is `getComputedStyle()`, which hands the declared `60%`\n * straight back in jsdom and resolves it to used pixels in a real browser — so the\n * same harness answered `100` here and `200` under Selenium or a browser runner,\n * with no error to say which one you got. The stylesheet's own `min-height: 1px`\n * is a second way that read lies, turning an empty bar into `1`.\n *\n * **The visible label row is decoration.** Every column carries `role=\"img\"` with\n * the label AND the value in its name, and the printed labels underneath are\n * `aria-hidden` — so {@link WrBarChartBar.name} is what a screen reader gets and\n * {@link WrBarChartBar.label} is what is drawn. Asserting only the second would pass\n * on a chart that announces nothing.\n *\n * @example\n * ```ts\n * const chart = await loader.getHarness(WrBarChartHarness);\n *\n * expect(await chart.getLabels()).toEqual(['Mon', 'Tue', 'Wed']);\n * expect((await chart.getBars())[1].heightPercent).toBe(100);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrBarChartHarness extends ComponentHarness {\n static hostSelector = 'wr-bar-chart';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrBarChartHarnessFilters = {}): HarnessPredicate<WrBarChartHarness> {\n return new HarnessPredicate(WrBarChartHarness, options).addOption(\n 'barLabel',\n options.barLabel,\n async (harness, label) => {\n for (const printed of await harness.getLabels()) {\n if (await HarnessPredicate.stringMatches(printed, label)) return true;\n }\n return false;\n }\n );\n }\n\n /** Every column, in data order. */\n async getBars(): Promise<WrBarChartBar[]> {\n const columns = await this.locatorForAll('.wr-bar-chart__column')();\n const bars = await this.locatorForAll('.wr-bar-chart__bar')();\n const labels = await this.getLabels();\n\n return Promise.all(\n columns.map(async (column, index) => {\n const value = await column.text();\n return {\n label: labels[index] ?? '',\n value: value === '' ? null : value,\n name: await column.getAttribute('aria-label'),\n heightPercent: WrBarChartHarness.heightPercentOf(await bars[index].getAttribute('style')),\n };\n })\n );\n }\n\n /** Parse one bar's declared share. See the class note on why this is not `getCssValue()`. */\n private static heightPercentOf(style: string | null): number {\n const match = BAR_HEIGHT.exec(style ?? '');\n if (!match) {\n throw new Error(\n `WrBarChartHarness.getBars(): a bar carries no inline height percentage (style: \"${style ?? ''}\"). ` +\n 'The component writes one for every bar, an empty one included, so its absence is the bug — ' +\n 'reporting 0 would read as a bar with nothing in it.'\n );\n }\n return Number.parseFloat(match[1]);\n }\n\n /** The labels printed under the columns, in order. */\n async getLabels(): Promise<string[]> {\n const labels = await this.locatorForAll('.wr-bar-chart__label')();\n return Promise.all(labels.map(label => label.text()));\n }\n\n /** What each column announces — the label and the value together. */\n async getAccessibleNames(): Promise<(string | null)[]> {\n const columns = await this.locatorForAll('.wr-bar-chart__column')();\n return Promise.all(columns.map(column => column.getAttribute('aria-label')));\n }\n\n /** How many columns the chart drew. */\n async getBarCount(): Promise<number> {\n return (await this.locatorForAll('.wr-bar-chart__column')()).length;\n }\n\n /** Whether the values are printed above the bars (`showValues`). */\n async hasValues(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-bar-chart__value')()) !== null;\n }\n\n /** The plot's height in pixels, as the component writes it inline. */\n async getPlotHeight(): Promise<number> {\n return Number.parseFloat(await (await this.locatorFor('.wr-bar-chart__plot')()).getCssValue('height'));\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -74,10 +74,10 @@ class WrBarChart {
|
|
|
74
74
|
};
|
|
75
75
|
}), /* @ts-ignore */
|
|
76
76
|
...(ngDevMode ? [{ debugName: "bars" }] : /* istanbul ignore next */ []));
|
|
77
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
78
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
77
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrBarChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
78
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: WrBarChart, isStandalone: true, selector: "wr-bar-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, showValues: { classPropertyName: "showValues", publicName: "showValues", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-bar-chart" }, ngImport: i0, template: "<div class=\"wr-bar-chart__plot\" [style.height.px]=\"height()\">\n @for (bar of bars(); track $index) {\n <div class=\"wr-bar-chart__column\" role=\"img\" [attr.aria-label]=\"bar.name\">\n @if (showValues()) {\n <span class=\"wr-bar-chart__value\">{{ bar.value }}</span>\n }\n <div class=\"wr-bar-chart__bar\" [style.height.%]=\"bar.heightPercent\" [style.background]=\"bar.color\"></div>\n </div>\n }\n</div>\n<!-- Named on the column above, so the visible label row is decoration here. -->\n<div class=\"wr-bar-chart__labels\" aria-hidden=\"true\">\n @for (bar of bars(); track $index) {\n <span class=\"wr-bar-chart__label\">{{ bar.label }}</span>\n }\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
|
|
79
79
|
}
|
|
80
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
80
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrBarChart, decorators: [{
|
|
81
81
|
type: Component,
|
|
82
82
|
args: [{ selector: 'wr-bar-chart', encapsulation: ViewEncapsulation.None, host: { class: 'wr-bar-chart' }, template: "<div class=\"wr-bar-chart__plot\" [style.height.px]=\"height()\">\n @for (bar of bars(); track $index) {\n <div class=\"wr-bar-chart__column\" role=\"img\" [attr.aria-label]=\"bar.name\">\n @if (showValues()) {\n <span class=\"wr-bar-chart__value\">{{ bar.value }}</span>\n }\n <div class=\"wr-bar-chart__bar\" [style.height.%]=\"bar.heightPercent\" [style.background]=\"bar.color\"></div>\n </div>\n }\n</div>\n<!-- Named on the column above, so the visible label row is decoration here. -->\n<div class=\"wr-bar-chart__labels\" aria-hidden=\"true\">\n @for (bar of bars(); track $index) {\n <span class=\"wr-bar-chart__label\">{{ bar.label }}</span>\n }\n</div>\n" }]
|
|
83
83
|
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], showValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValues", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }] } });
|
|
@@ -179,10 +179,10 @@ class WrBlurText {
|
|
|
179
179
|
};
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
183
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
182
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrBlurText, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
183
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: WrBlurText, isStandalone: true, selector: "wr-blur-text", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, animateBy: { classPropertyName: "animateBy", publicName: "animateBy", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, stepDuration: { classPropertyName: "stepDuration", publicName: "stepDuration", isSignal: true, isRequired: false, transformFunction: null }, easing: { classPropertyName: "easing", publicName: "easing", isSignal: true, isRequired: false, transformFunction: null }, threshold: { classPropertyName: "threshold", publicName: "threshold", isSignal: true, isRequired: false, transformFunction: null }, rootMargin: { classPropertyName: "rootMargin", publicName: "rootMargin", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { animationComplete: "animationComplete" }, host: { classAttribute: "wr-blur-text" }, ngImport: i0, template: "<!-- The readable text, once: the pieces below are per-character spans. -->\n<span class=\"wr-blur-text__sr-only\">{{ text() }}</span>\n@for (p of pieces(); track $index) {\n @if (p.kind === 'piece') {\n <span class=\"wr-blur-text__piece\" aria-hidden=\"true\">{{ p.text }}</span>\n } @else {\n <span class=\"wr-blur-text__space\" aria-hidden=\"true\">{{ p.text }}</span>\n }\n}\n", styles: [".wr-blur-text{display:inline-flex;flex-wrap:wrap}.wr-blur-text__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.wr-blur-text__piece{display:inline-block;will-change:transform,filter,opacity}.wr-blur-text__space{display:inline;white-space:pre}\n"], encapsulation: i0.ViewEncapsulation.None });
|
|
184
184
|
}
|
|
185
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
185
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WrBlurText, decorators: [{
|
|
186
186
|
type: Component,
|
|
187
187
|
args: [{ selector: 'wr-blur-text', encapsulation: ViewEncapsulation.None, host: { class: 'wr-blur-text' }, template: "<!-- The readable text, once: the pieces below are per-character spans. -->\n<span class=\"wr-blur-text__sr-only\">{{ text() }}</span>\n@for (p of pieces(); track $index) {\n @if (p.kind === 'piece') {\n <span class=\"wr-blur-text__piece\" aria-hidden=\"true\">{{ p.text }}</span>\n } @else {\n <span class=\"wr-blur-text__space\" aria-hidden=\"true\">{{ p.text }}</span>\n }\n}\n", styles: [".wr-blur-text{display:inline-flex;flex-wrap:wrap}.wr-blur-text__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.wr-blur-text__piece{display:inline-block;will-change:transform,filter,opacity}.wr-blur-text__space{display:inline;white-space:pre}\n"] }]
|
|
188
188
|
}], ctorParameters: () => [], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], animateBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "animateBy", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], stepDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepDuration", required: false }] }], easing: [{ type: i0.Input, args: [{ isSignal: true, alias: "easing", required: false }] }], threshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "threshold", required: false }] }], rootMargin: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootMargin", required: false }] }], animationComplete: [{ type: i0.Output, args: ["animationComplete"] }] } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-blur-text.mjs","sources":["../../../projects/lib/blur-text/blur-text.ts","../../../projects/lib/blur-text/blur-text.html","../../../projects/lib/blur-text/ngwr-blur-text.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 * Angular adaptation of the BlurText effect by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/text-animations/blur-text\n *\n * The reactbits version uses `motion/react` (framer-motion successor).\n * This port is dependency-free — uses the Web Animations API for the\n * three-keyframe blur-and-fade-in, triggered by `IntersectionObserver`.\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\ntype Unit = 'chars' | 'words';\ntype Direction = 'top' | 'bottom';\ntype Piece = { readonly kind: 'piece'; readonly text: string } | { readonly kind: 'space'; readonly text: string };\n\nfunction splitPieces(text: string, unit: Unit): readonly Piece[] {\n if (!text) return [];\n if (unit === 'words') {\n return text.split(/(\\s+)/).flatMap<Piece>(seg => {\n if (seg.length === 0) return [];\n if (/^\\s+$/.test(seg)) return [{ kind: 'space', text: seg }];\n return [{ kind: 'piece', text: seg }];\n });\n }\n return [...text].map<Piece>(ch => (/\\s/.test(ch) ? { kind: 'space', text: ch } : { kind: 'piece', text: ch }));\n}\n\n/**\n * Reveals text by splitting it into chars or words and animating each\n * piece in from a blurred / offset state through a brief mid-step into\n * the steady state. Triggers when the host enters the viewport.\n *\n * @example\n * ```html\n * <wr-blur-text\n * text=\"Welcome to ngwr\"\n * animateBy=\"words\"\n * direction=\"top\"\n * [delay]=\"120\"\n * [stepDuration]=\"0.4\"\n * />\n * ```\n *\n * @see https://www.reactbits.dev/text-animations/blur-text\n */\n@Component({\n selector: 'wr-blur-text',\n templateUrl: './blur-text.html',\n styleUrl: './blur-text.scss',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-blur-text' },\n})\nexport class WrBlurText {\n /** Text to animate. Required. */\n readonly text = input.required<string>();\n\n /** Split granularity. @default 'words' */\n readonly animateBy = input<Unit>('words');\n\n /** Entry direction. `'top'` slides down into place; `'bottom'` slides up. @default 'top' */\n readonly direction = input<Direction>('top');\n\n /** Per-piece stagger in ms. @default 200 */\n readonly delay = input(200, { transform: numAttr(200) });\n\n /** Duration of each keyframe step in seconds (total = 2 × stepDuration). @default 0.35 */\n readonly stepDuration = input(0.35, { transform: numAttr(0.35) });\n\n /** CSS easing function. @default 'linear' (matches reactbits' identity easing) */\n readonly easing = input('linear');\n\n /** `IntersectionObserver.threshold` (0..1). @default 0.1 */\n readonly threshold = input(0.1, { transform: numAttr(0.1) });\n\n /** `IntersectionObserver.rootMargin`. @default '0px' */\n readonly rootMargin = input('0px');\n\n /** Emitted once all pieces finish animating. */\n readonly animationComplete = output<void>();\n\n protected readonly pieces = computed(() => splitPieces(this.text(), this.animateBy()));\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly platform = inject(WrPlatform);\n\n private hasAnimated = false;\n\n /**\n * The ONE observer, replaced rather than stacked.\n *\n * `startObserver()` used to `new IntersectionObserver(…)` and register its own\n * `destroyRef.onDestroy` every time, and the effect below calls it on every\n * `text` change after setting `hasAnimated = false` — so the guard at the top\n * of `startObserver` never blocked that path. An off-screen element (the only\n * case where the observer does not immediately disconnect itself) therefore\n * leaked one live observer AND one destroy callback per change, all of them\n * watching the same host and all of them able to fire `animate()`.\n */\n private observer: IntersectionObserver | null = null;\n\n constructor() {\n if (!this.isBrowser) return;\n this.destroyRef.onDestroy(() => this.observer?.disconnect());\n afterNextRender(() => this.startObserver());\n effect(() => {\n this.text();\n this.animateBy();\n this.hasAnimated = false;\n queueMicrotask(() => this.startObserver());\n });\n }\n\n private startObserver(): void {\n if (this.hasAnimated) return;\n const host = this.host.nativeElement;\n this.observer?.disconnect();\n const io = new IntersectionObserver(\n (entries, obs) => {\n for (const e of entries) {\n if (e.isIntersecting) {\n obs.disconnect();\n this.animate();\n break;\n }\n }\n },\n { threshold: this.threshold(), rootMargin: this.rootMargin() }\n );\n this.observer = io;\n io.observe(host);\n }\n\n private animate(): void {\n if (this.hasAnimated) return;\n this.hasAnimated = true;\n\n // Reduced motion: pieces already render clear and in place — skip\n // the blur tween and report completion right away.\n if (this.platform.prefersReducedMotion()) {\n this.animationComplete.emit();\n return;\n }\n\n const targets = this.host.nativeElement.querySelectorAll<HTMLElement>('.wr-blur-text__piece');\n if (targets.length === 0) {\n this.animationComplete.emit();\n return;\n }\n\n const dir = this.direction();\n const stepMs = this.stepDuration() * 1000;\n const totalMs = stepMs * 2;\n const stagger = this.delay();\n const easing = this.easing();\n\n // Three-keyframe shape per reactbits:\n // 0 → fully blurred, offset, transparent\n // 50% → half-blur, half-opacity, small reverse offset\n // 100% → clear, opaque, at rest\n const startY = dir === 'top' ? -50 : 50;\n const midY = dir === 'top' ? 5 : -5;\n const keyframes: Keyframe[] = [\n { opacity: 0, filter: 'blur(10px)', transform: `translate3d(0, ${startY}px, 0)` },\n { opacity: 0.5, filter: 'blur(5px)', transform: `translate3d(0, ${midY}px, 0)`, offset: 0.5 },\n { opacity: 1, filter: 'blur(0px)', transform: 'translate3d(0, 0, 0)' },\n ];\n\n let remaining = targets.length;\n targets.forEach((el, i) => {\n el.style.opacity = '0';\n el.style.filter = 'blur(10px)';\n el.style.transform = `translate3d(0, ${startY}px, 0)`;\n const animation = el.animate(keyframes, {\n duration: totalMs,\n delay: i * stagger,\n easing,\n fill: 'forwards',\n });\n animation.onfinish = (): void => {\n el.style.opacity = '1';\n el.style.filter = 'blur(0px)';\n el.style.transform = 'translate3d(0, 0, 0)';\n try {\n animation.cancel();\n } catch {\n /* noop */\n }\n remaining -= 1;\n if (remaining === 0) this.animationComplete.emit();\n };\n });\n }\n}\n","<!-- The readable text, once: the pieces below are per-character spans. -->\n<span class=\"wr-blur-text__sr-only\">{{ text() }}</span>\n@for (p of pieces(); track $index) {\n @if (p.kind === 'piece') {\n <span class=\"wr-blur-text__piece\" aria-hidden=\"true\">{{ p.text }}</span>\n } @else {\n <span class=\"wr-blur-text__space\" aria-hidden=\"true\">{{ p.text }}</span>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;AAAA;;;;;;;;;;;;AAYG;AAwBH,SAAS,WAAW,CAAC,IAAY,EAAE,IAAU,EAAA;AAC3C,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,EAAE;AACpB,IAAA,IAAI,IAAI,KAAK,OAAO,EAAE;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAQ,GAAG,IAAG;AAC9C,YAAA,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;AAAE,gBAAA,OAAO,EAAE;AAC/B,YAAA,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YAC5D,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACvC,QAAA,CAAC,CAAC;IACJ;IACA,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAQ,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;AAChH;AAEA;;;;;;;;;;;;;;;;;AAiBG;MAQU,UAAU,CAAA;;IAEZ,IAAI,GAAG,KAAK,CAAC,QAAQ;6EAAU;;IAG/B,SAAS,GAAG,KAAK,CAAO,OAAO;kFAAC;;IAGhC,SAAS,GAAG,KAAK,CAAY,KAAK;kFAAC;;AAGnC,IAAA,KAAK,GAAG,KAAK,CAAC,GAAG,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,OAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,EAAA,CAAG;;AAG/C,IAAA,YAAY,GAAG,KAAK,CAAC,IAAI,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,cAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,EAAA,CAAG;;IAGxD,MAAM,GAAG,KAAK,CAAC,QAAQ;+EAAC;;AAGxB,IAAA,SAAS,GAAG,KAAK,CAAC,GAAG,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,WAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,EAAA,CAAG;;IAGnD,UAAU,GAAG,KAAK,CAAC,KAAK;mFAAC;;IAGzB,iBAAiB,GAAG,MAAM,EAAQ;AAExB,IAAA,MAAM,GAAG,QAAQ,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;+EAAC;AAErE,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC;AAClD,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAC/B,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAClD,IAAA,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC;IAEtC,WAAW,GAAG,KAAK;AAE3B;;;;;;;;;;AAUG;IACK,QAAQ,GAAgC,IAAI;AAEpD,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;AACrB,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC;QAC5D,eAAe,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC3C,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,IAAI,EAAE;YACX,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,CAAC,WAAW,GAAG,KAAK;YACxB,cAAc,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;AAC5C,QAAA,CAAC,CAAC;IACJ;IAEQ,aAAa,GAAA;QACnB,IAAI,IAAI,CAAC,WAAW;YAAE;AACtB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa;AACpC,QAAA,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE;QAC3B,MAAM,EAAE,GAAG,IAAI,oBAAoB,CACjC,CAAC,OAAO,EAAE,GAAG,KAAI;AACf,YAAA,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE;AACvB,gBAAA,IAAI,CAAC,CAAC,cAAc,EAAE;oBACpB,GAAG,CAAC,UAAU,EAAE;oBAChB,IAAI,CAAC,OAAO,EAAE;oBACd;gBACF;YACF;AACF,QAAA,CAAC,EACD,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,CAC/D;AACD,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE;AAClB,QAAA,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAClB;IAEQ,OAAO,GAAA;QACb,IAAI,IAAI,CAAC,WAAW;YAAE;AACtB,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;;;AAIvB,QAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,EAAE;AACxC,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE;YAC7B;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAc,sBAAsB,CAAC;AAC7F,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;AACxB,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE;YAC7B;QACF;AAEA,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI;AACzC,QAAA,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC;AAC1B,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE;AAC5B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;;;;;AAM5B,QAAA,MAAM,MAAM,GAAG,GAAG,KAAK,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE;AACvC,QAAA,MAAM,IAAI,GAAG,GAAG,KAAK,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;AACnC,QAAA,MAAM,SAAS,GAAe;AAC5B,YAAA,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAA,eAAA,EAAkB,MAAM,QAAQ,EAAE;AACjF,YAAA,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,kBAAkB,IAAI,CAAA,MAAA,CAAQ,EAAE,MAAM,EAAE,GAAG,EAAE;YAC7F,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,sBAAsB,EAAE;SACvE;AAED,QAAA,IAAI,SAAS,GAAG,OAAO,CAAC,MAAM;QAC9B,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,KAAI;AACxB,YAAA,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG;AACtB,YAAA,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY;YAC9B,EAAE,CAAC,KAAK,CAAC,SAAS,GAAG,CAAA,eAAA,EAAkB,MAAM,QAAQ;AACrD,YAAA,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE;AACtC,gBAAA,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC,GAAG,OAAO;gBAClB,MAAM;AACN,gBAAA,IAAI,EAAE,UAAU;AACjB,aAAA,CAAC;AACF,YAAA,SAAS,CAAC,QAAQ,GAAG,MAAW;AAC9B,gBAAA,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG;AACtB,gBAAA,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW;AAC7B,gBAAA,EAAE,CAAC,KAAK,CAAC,SAAS,GAAG,sBAAsB;AAC3C,gBAAA,IAAI;oBACF,SAAS,CAAC,MAAM,EAAE;gBACpB;AAAE,gBAAA,MAAM;;gBAER;gBACA,SAAS,IAAI,CAAC;gBACd,IAAI,SAAS,KAAK,CAAC;AAAE,oBAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE;AACpD,YAAA,CAAC;AACH,QAAA,CAAC,CAAC;IACJ;uGA7IW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,0rCCzEvB,uYASA,EAAA,MAAA,EAAA,CAAA,iUAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDgEa,UAAU,EAAA,UAAA,EAAA,CAAA;kBAPtB,SAAS;+BACE,cAAc,EAAA,aAAA,EAGT,iBAAiB,CAAC,IAAI,QAC/B,EAAE,KAAK,EAAE,cAAc,EAAE,EAAA,QAAA,EAAA,uYAAA,EAAA,MAAA,EAAA,CAAA,iUAAA,CAAA,EAAA;;;AEvEjC;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ngwr-blur-text.mjs","sources":["../../../projects/lib/blur-text/blur-text.ts","../../../projects/lib/blur-text/blur-text.html","../../../projects/lib/blur-text/ngwr-blur-text.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 * Angular adaptation of the BlurText effect by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/text-animations/blur-text\n *\n * The reactbits version uses `motion/react` (framer-motion successor).\n * This port is dependency-free — uses the Web Animations API for the\n * three-keyframe blur-and-fade-in, triggered by `IntersectionObserver`.\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\nimport type { WrBlurTextDirection, WrBlurTextUnit } from './interfaces';\n\ntype Piece = { readonly kind: 'piece'; readonly text: string } | { readonly kind: 'space'; readonly text: string };\n\nfunction splitPieces(text: string, unit: WrBlurTextUnit): readonly Piece[] {\n if (!text) return [];\n if (unit === 'words') {\n return text.split(/(\\s+)/).flatMap<Piece>(seg => {\n if (seg.length === 0) return [];\n if (/^\\s+$/.test(seg)) return [{ kind: 'space', text: seg }];\n return [{ kind: 'piece', text: seg }];\n });\n }\n return [...text].map<Piece>(ch => (/\\s/.test(ch) ? { kind: 'space', text: ch } : { kind: 'piece', text: ch }));\n}\n\n/**\n * Reveals text by splitting it into chars or words and animating each\n * piece in from a blurred / offset state through a brief mid-step into\n * the steady state. Triggers when the host enters the viewport.\n *\n * @example\n * ```html\n * <wr-blur-text\n * text=\"Welcome to ngwr\"\n * animateBy=\"words\"\n * direction=\"top\"\n * [delay]=\"120\"\n * [stepDuration]=\"0.4\"\n * />\n * ```\n *\n * @see https://www.reactbits.dev/text-animations/blur-text\n */\n@Component({\n selector: 'wr-blur-text',\n templateUrl: './blur-text.html',\n styleUrl: './blur-text.scss',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-blur-text' },\n})\nexport class WrBlurText {\n /** Text to animate. Required. */\n readonly text = input.required<string>();\n\n /** Split granularity. @default 'words' */\n readonly animateBy = input<WrBlurTextUnit>('words');\n\n /** Entry direction. `'top'` slides down into place; `'bottom'` slides up. @default 'top' */\n readonly direction = input<WrBlurTextDirection>('top');\n\n /** Per-piece stagger in ms. @default 200 */\n readonly delay = input(200, { transform: numAttr(200) });\n\n /** Duration of each keyframe step in seconds (total = 2 × stepDuration). @default 0.35 */\n readonly stepDuration = input(0.35, { transform: numAttr(0.35) });\n\n /** CSS easing function. @default 'linear' (matches reactbits' identity easing) */\n readonly easing = input('linear');\n\n /** `IntersectionObserver.threshold` (0..1). @default 0.1 */\n readonly threshold = input(0.1, { transform: numAttr(0.1) });\n\n /** `IntersectionObserver.rootMargin`. @default '0px' */\n readonly rootMargin = input('0px');\n\n /** Emitted once all pieces finish animating. */\n readonly animationComplete = output<void>();\n\n protected readonly pieces = computed(() => splitPieces(this.text(), this.animateBy()));\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly platform = inject(WrPlatform);\n\n private hasAnimated = false;\n\n /**\n * The ONE observer, replaced rather than stacked.\n *\n * `startObserver()` used to `new IntersectionObserver(…)` and register its own\n * `destroyRef.onDestroy` every time, and the effect below calls it on every\n * `text` change after setting `hasAnimated = false` — so the guard at the top\n * of `startObserver` never blocked that path. An off-screen element (the only\n * case where the observer does not immediately disconnect itself) therefore\n * leaked one live observer AND one destroy callback per change, all of them\n * watching the same host and all of them able to fire `animate()`.\n */\n private observer: IntersectionObserver | null = null;\n\n constructor() {\n if (!this.isBrowser) return;\n this.destroyRef.onDestroy(() => this.observer?.disconnect());\n afterNextRender(() => this.startObserver());\n effect(() => {\n this.text();\n this.animateBy();\n this.hasAnimated = false;\n queueMicrotask(() => this.startObserver());\n });\n }\n\n private startObserver(): void {\n if (this.hasAnimated) return;\n const host = this.host.nativeElement;\n this.observer?.disconnect();\n const io = new IntersectionObserver(\n (entries, obs) => {\n for (const e of entries) {\n if (e.isIntersecting) {\n obs.disconnect();\n this.animate();\n break;\n }\n }\n },\n { threshold: this.threshold(), rootMargin: this.rootMargin() }\n );\n this.observer = io;\n io.observe(host);\n }\n\n private animate(): void {\n if (this.hasAnimated) return;\n this.hasAnimated = true;\n\n // Reduced motion: pieces already render clear and in place — skip\n // the blur tween and report completion right away.\n if (this.platform.prefersReducedMotion()) {\n this.animationComplete.emit();\n return;\n }\n\n const targets = this.host.nativeElement.querySelectorAll<HTMLElement>('.wr-blur-text__piece');\n if (targets.length === 0) {\n this.animationComplete.emit();\n return;\n }\n\n const dir = this.direction();\n const stepMs = this.stepDuration() * 1000;\n const totalMs = stepMs * 2;\n const stagger = this.delay();\n const easing = this.easing();\n\n // Three-keyframe shape per reactbits:\n // 0 → fully blurred, offset, transparent\n // 50% → half-blur, half-opacity, small reverse offset\n // 100% → clear, opaque, at rest\n const startY = dir === 'top' ? -50 : 50;\n const midY = dir === 'top' ? 5 : -5;\n const keyframes: Keyframe[] = [\n { opacity: 0, filter: 'blur(10px)', transform: `translate3d(0, ${startY}px, 0)` },\n { opacity: 0.5, filter: 'blur(5px)', transform: `translate3d(0, ${midY}px, 0)`, offset: 0.5 },\n { opacity: 1, filter: 'blur(0px)', transform: 'translate3d(0, 0, 0)' },\n ];\n\n let remaining = targets.length;\n targets.forEach((el, i) => {\n el.style.opacity = '0';\n el.style.filter = 'blur(10px)';\n el.style.transform = `translate3d(0, ${startY}px, 0)`;\n const animation = el.animate(keyframes, {\n duration: totalMs,\n delay: i * stagger,\n easing,\n fill: 'forwards',\n });\n animation.onfinish = (): void => {\n el.style.opacity = '1';\n el.style.filter = 'blur(0px)';\n el.style.transform = 'translate3d(0, 0, 0)';\n try {\n animation.cancel();\n } catch {\n /* noop */\n }\n remaining -= 1;\n if (remaining === 0) this.animationComplete.emit();\n };\n });\n }\n}\n\nexport type { WrBlurTextDirection, WrBlurTextUnit } from './interfaces';\n","<!-- The readable text, once: the pieces below are per-character spans. -->\n<span class=\"wr-blur-text__sr-only\">{{ text() }}</span>\n@for (p of pieces(); track $index) {\n @if (p.kind === 'piece') {\n <span class=\"wr-blur-text__piece\" aria-hidden=\"true\">{{ p.text }}</span>\n } @else {\n <span class=\"wr-blur-text__space\" aria-hidden=\"true\">{{ p.text }}</span>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|