ngwr 10.2.1 → 11.1.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 +39 -19
- package/action-sheet/styles/_index.scss +4 -1
- package/anchor/styles/_index.scss +6 -5
- package/back-top/styles/_index.scss +6 -1
- package/blur-text/styles/_index.scss +13 -0
- package/button/styles/_index.scss +11 -6
- package/calendar/styles/_index.scss +11 -2
- package/carousel/styles/_index.scss +13 -2
- package/cascader/styles/_index.scss +5 -3
- package/circular-text/styles/_index.scss +2 -0
- package/collapse/styles/_index.scss +1 -1
- package/color-picker/styles/_index.scss +6 -1
- package/command-palette/styles/_index.scss +2 -1
- package/compare/styles/_index.scss +1 -2
- package/context-menu/styles/_index.scss +8 -2
- package/descriptions/styles/_index.scss +2 -2
- package/dialog/styles/_index.scss +7 -0
- package/drawer/styles/_index.scss +20 -1
- package/dropdown/styles/_index.scss +19 -5
- package/empty/styles/_index.scss +10 -0
- package/falling-text/styles/_index.scss +2 -1
- package/fesm2022/ngwr-action-sheet.mjs +13 -3
- package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
- package/fesm2022/ngwr-affix.mjs +40 -13
- package/fesm2022/ngwr-affix.mjs.map +1 -1
- package/fesm2022/ngwr-anchor.mjs +18 -6
- package/fesm2022/ngwr-anchor.mjs.map +1 -1
- package/fesm2022/ngwr-aurora.mjs +2 -2
- package/fesm2022/ngwr-aurora.mjs.map +1 -1
- package/fesm2022/ngwr-avatar.mjs +31 -7
- package/fesm2022/ngwr-avatar.mjs.map +1 -1
- package/fesm2022/ngwr-back-top.mjs +6 -2
- package/fesm2022/ngwr-back-top.mjs.map +1 -1
- package/fesm2022/ngwr-badge.mjs +1 -1
- package/fesm2022/ngwr-badge.mjs.map +1 -1
- package/fesm2022/ngwr-bar-chart.mjs +30 -9
- package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text.mjs +2 -2
- package/fesm2022/ngwr-blur-text.mjs.map +1 -1
- package/fesm2022/ngwr-border-glow.mjs +2 -2
- package/fesm2022/ngwr-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +2 -2
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-burger.mjs +9 -4
- package/fesm2022/ngwr-burger.mjs.map +1 -1
- package/fesm2022/ngwr-button-testing.mjs +96 -0
- package/fesm2022/ngwr-button-testing.mjs.map +1 -0
- package/fesm2022/ngwr-button.mjs +31 -14
- package/fesm2022/ngwr-button.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap.mjs +40 -8
- package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
- package/fesm2022/ngwr-calendar.mjs +20 -1
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-card.mjs +2 -2
- package/fesm2022/ngwr-card.mjs.map +1 -1
- package/fesm2022/ngwr-carousel-testing.mjs +377 -0
- package/fesm2022/ngwr-carousel-testing.mjs.map +1 -0
- package/fesm2022/ngwr-carousel.mjs +67 -13
- package/fesm2022/ngwr-carousel.mjs.map +1 -1
- package/fesm2022/ngwr-cascader-testing.mjs +534 -0
- package/fesm2022/ngwr-cascader-testing.mjs.map +1 -0
- package/fesm2022/ngwr-cascader.mjs +2 -2
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox-testing.mjs +90 -0
- package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -0
- package/fesm2022/ngwr-checkbox.mjs +9 -3
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text.mjs +2 -2
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-click-spark.mjs +2 -2
- package/fesm2022/ngwr-click-spark.mjs.map +1 -1
- package/fesm2022/ngwr-collapse-testing.mjs +368 -0
- package/fesm2022/ngwr-collapse-testing.mjs.map +1 -0
- package/fesm2022/ngwr-color-picker.mjs +134 -14
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette-testing.mjs +589 -0
- package/fesm2022/ngwr-command-palette-testing.mjs.map +1 -0
- package/fesm2022/ngwr-command-palette.mjs +58 -8
- package/fesm2022/ngwr-command-palette.mjs.map +1 -1
- package/fesm2022/ngwr-compare.mjs +103 -13
- package/fesm2022/ngwr-compare.mjs.map +1 -1
- package/fesm2022/ngwr-config.mjs +106 -0
- package/fesm2022/ngwr-config.mjs.map +1 -0
- package/fesm2022/ngwr-context-menu-testing.mjs +631 -0
- package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -0
- package/fesm2022/ngwr-context-menu.mjs +94 -8
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-cookie.mjs +5 -1
- package/fesm2022/ngwr-cookie.mjs.map +1 -1
- package/fesm2022/ngwr-counter.mjs +11 -3
- package/fesm2022/ngwr-counter.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapter-luxon.mjs +52 -4
- package/fesm2022/ngwr-date-adapter-luxon.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapter.mjs +54 -8
- package/fesm2022/ngwr-date-adapter.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker-testing.mjs +766 -0
- package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -0
- package/fesm2022/ngwr-date-picker.mjs +73 -3
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-decrypt-text.mjs +27 -9
- package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
- package/fesm2022/ngwr-dialog-testing.mjs +89 -0
- package/fesm2022/ngwr-dialog-testing.mjs.map +1 -0
- package/fesm2022/ngwr-directives.mjs +36 -12
- package/fesm2022/ngwr-directives.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart.mjs +22 -5
- package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +2 -2
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-drawer-testing.mjs +250 -0
- package/fesm2022/ngwr-drawer-testing.mjs.map +1 -0
- package/fesm2022/ngwr-dropdown-testing.mjs +291 -0
- package/fesm2022/ngwr-dropdown-testing.mjs.map +1 -0
- package/fesm2022/ngwr-dropdown.mjs +10 -2
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-empty.mjs +24 -7
- package/fesm2022/ngwr-empty.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar.mjs +57 -10
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text.mjs +2 -2
- package/fesm2022/ngwr-falling-text.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload-testing.mjs +332 -0
- package/fesm2022/ngwr-file-upload-testing.mjs.map +1 -0
- package/fesm2022/ngwr-form-testing.mjs +451 -0
- package/fesm2022/ngwr-form-testing.mjs.map +1 -0
- package/fesm2022/ngwr-form.mjs +19 -3
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text.mjs +9 -2
- package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
- package/fesm2022/ngwr-gauge.mjs +19 -5
- package/fesm2022/ngwr-gauge.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text.mjs +2 -2
- package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text.mjs +2 -2
- package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +50 -0
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +48 -0
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper.mjs +23 -0
- package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
- package/fesm2022/ngwr-input-number-testing.mjs +306 -0
- package/fesm2022/ngwr-input-number-testing.mjs.map +1 -0
- package/fesm2022/ngwr-input-number.mjs +35 -3
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp-testing.mjs +419 -0
- package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -0
- package/fesm2022/ngwr-input-otp.mjs +36 -5
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-input-testing.mjs +102 -0
- package/fesm2022/ngwr-input-testing.mjs.map +1 -0
- package/fesm2022/ngwr-input.mjs +47 -10
- package/fesm2022/ngwr-input.mjs.map +1 -1
- package/fesm2022/ngwr-knob.mjs +44 -8
- package/fesm2022/ngwr-knob.mjs.map +1 -1
- package/fesm2022/ngwr-layout.mjs +21 -5
- package/fesm2022/ngwr-layout.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox.mjs +33 -6
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart.mjs +17 -4
- package/fesm2022/ngwr-line-chart.mjs.map +1 -1
- package/fesm2022/ngwr-list.mjs +2 -2
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar.mjs +2 -2
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-markdown-testing.mjs +516 -0
- package/fesm2022/ngwr-markdown-testing.mjs.map +1 -0
- package/fesm2022/ngwr-markdown.mjs +1492 -0
- package/fesm2022/ngwr-markdown.mjs.map +1 -0
- package/fesm2022/ngwr-marquee.mjs +17 -6
- package/fesm2022/ngwr-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-mention-testing.mjs +513 -0
- package/fesm2022/ngwr-mention-testing.mjs.map +1 -0
- package/fesm2022/ngwr-mention.mjs +10 -1
- package/fesm2022/ngwr-mention.mjs.map +1 -1
- package/fesm2022/ngwr-meta.mjs +22 -7
- package/fesm2022/ngwr-meta.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group.mjs +19 -5
- package/fesm2022/ngwr-meter-group.mjs.map +1 -1
- package/fesm2022/ngwr-overlay.mjs +41 -1
- package/fesm2022/ngwr-overlay.mjs.map +1 -1
- package/fesm2022/ngwr-pagination-testing.mjs +389 -0
- package/fesm2022/ngwr-pagination-testing.mjs.map +1 -0
- package/fesm2022/ngwr-pagination.mjs +14 -2
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm-testing.mjs +309 -0
- package/fesm2022/ngwr-popconfirm-testing.mjs.map +1 -0
- package/fesm2022/ngwr-popconfirm.mjs +95 -17
- package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
- package/fesm2022/ngwr-popover-testing.mjs +316 -0
- package/fesm2022/ngwr-popover-testing.mjs.map +1 -0
- package/fesm2022/ngwr-popover.mjs +21 -3
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-pull-to-refresh.mjs +17 -2
- package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -1
- package/fesm2022/ngwr-qr.mjs +13 -3
- package/fesm2022/ngwr-qr.mjs.map +1 -1
- package/fesm2022/ngwr-radio-testing.mjs +392 -0
- package/fesm2022/ngwr-radio-testing.mjs.map +1 -0
- package/fesm2022/ngwr-radio.mjs +10 -3
- package/fesm2022/ngwr-radio.mjs.map +1 -1
- package/fesm2022/ngwr-rating-testing.mjs +384 -0
- package/fesm2022/ngwr-rating-testing.mjs.map +1 -0
- package/fesm2022/ngwr-rating.mjs +37 -2
- package/fesm2022/ngwr-rating.mjs.map +1 -1
- package/fesm2022/ngwr-segmented-testing.mjs +512 -0
- package/fesm2022/ngwr-segmented-testing.mjs.map +1 -0
- package/fesm2022/ngwr-select-testing.mjs +268 -0
- package/fesm2022/ngwr-select-testing.mjs.map +1 -0
- package/fesm2022/ngwr-select.mjs +87 -16
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text.mjs +2 -2
- package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
- package/fesm2022/ngwr-sidebar.mjs +65 -12
- package/fesm2022/ngwr-sidebar.mjs.map +1 -1
- package/fesm2022/ngwr-slider-testing.mjs +478 -0
- package/fesm2022/ngwr-slider-testing.mjs.map +1 -0
- package/fesm2022/ngwr-slider.mjs +57 -13
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline.mjs +26 -6
- package/fesm2022/ngwr-sparkline.mjs.map +1 -1
- package/fesm2022/ngwr-speed-dial.mjs +37 -4
- package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
- package/fesm2022/ngwr-spinner.mjs +12 -3
- package/fesm2022/ngwr-spinner.mjs.map +1 -1
- package/fesm2022/ngwr-splash-cursor.mjs +2 -2
- package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
- package/fesm2022/ngwr-split-text.mjs +2 -2
- package/fesm2022/ngwr-split-text.mjs.map +1 -1
- package/fesm2022/ngwr-splitter.mjs +70 -9
- package/fesm2022/ngwr-splitter.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card.mjs +2 -2
- package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-star-border.mjs +2 -2
- package/fesm2022/ngwr-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-statistic.mjs +24 -7
- package/fesm2022/ngwr-statistic.mjs.map +1 -1
- package/fesm2022/ngwr-stepper-testing.mjs +477 -0
- package/fesm2022/ngwr-stepper-testing.mjs.map +1 -0
- package/fesm2022/ngwr-switch-testing.mjs +77 -0
- package/fesm2022/ngwr-switch-testing.mjs.map +1 -0
- package/fesm2022/ngwr-switch.mjs +9 -3
- package/fesm2022/ngwr-switch.mjs.map +1 -1
- package/fesm2022/ngwr-table-testing.mjs +580 -0
- package/fesm2022/ngwr-table-testing.mjs.map +1 -0
- package/fesm2022/ngwr-table.mjs +87 -14
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-testing.mjs +617 -0
- package/fesm2022/ngwr-tabs-testing.mjs.map +1 -0
- package/fesm2022/ngwr-tabs.mjs +38 -6
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-textarea-testing.mjs +238 -0
- package/fesm2022/ngwr-textarea-testing.mjs.map +1 -0
- package/fesm2022/ngwr-textarea.mjs +32 -4
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card.mjs +2 -2
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-toast-testing.mjs +101 -0
- package/fesm2022/ngwr-toast-testing.mjs.map +1 -0
- package/fesm2022/ngwr-toast.mjs +2 -2
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-tour.mjs +61 -9
- package/fesm2022/ngwr-tour.mjs.map +1 -1
- package/fesm2022/ngwr-transfer-testing.mjs +538 -0
- package/fesm2022/ngwr-transfer-testing.mjs.map +1 -0
- package/fesm2022/ngwr-transfer.mjs +45 -14
- package/fesm2022/ngwr-transfer.mjs.map +1 -1
- package/fesm2022/ngwr-tree-testing.mjs +734 -0
- package/fesm2022/ngwr-tree-testing.mjs.map +1 -0
- package/fesm2022/ngwr-tree.mjs +73 -7
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter.mjs +5 -3
- package/fesm2022/ngwr-typewriter.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 +31 -5
- package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-waves.mjs +3 -3
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +8 -0
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/file-upload/styles/_index.scss +7 -2
- package/gauge/styles/_index.scss +1 -1
- package/glitch-text/styles/_index.scss +4 -0
- package/i18n/en.json +48 -0
- package/i18n/ru.json +48 -0
- package/image-cropper/styles/_index.scss +13 -1
- package/input/styles/_index.scss +2 -2
- package/input-number/styles/_index.scss +7 -2
- package/knob/styles/_index.scss +8 -1
- package/layout/styles/_index.scss +3 -3
- package/lightbox/styles/_index.scss +10 -2
- package/line-chart/styles/_index.scss +6 -0
- package/llms-full.txt +151 -4
- package/llms.txt +57 -8
- package/loading-bar/styles/_index.scss +1 -2
- package/markdown/styles/_index.scss +296 -0
- package/marquee/styles/_index.scss +12 -0
- package/mcp/api.js +512 -0
- package/mcp/catalog.js +157 -0
- package/mcp/server.js +273 -0
- package/mcp/tools.js +366 -0
- package/meter-group/styles/_index.scss +1 -1
- package/package.json +186 -35
- package/pagination/styles/_index.scss +6 -6
- package/popover/styles/_index.scss +37 -5
- package/rating/styles/_index.scss +10 -0
- package/result/styles/_index.scss +3 -1
- package/schematics/use/symbol-map.json +2 -0
- package/segmented/styles/_index.scss +12 -1
- package/select/styles/_index.scss +32 -10
- package/sidebar/styles/_index.scss +30 -5
- package/slider/styles/_index.scss +15 -0
- package/speed-dial/styles/_index.scss +20 -0
- package/split-text/styles/_index.scss +13 -0
- package/star-border/styles/_index.scss +2 -0
- package/stepper/styles/_index.scss +19 -3
- package/styles/_grid.scss +4 -4
- package/styles.scss +1 -0
- package/switch/styles/_index.scss +5 -3
- package/table/styles/_index.scss +25 -12
- package/tabs/styles/_index.scss +11 -1
- package/textarea/styles/_index.scss +5 -0
- package/theme/styles/_colors.scss +44 -15
- package/theme/styles/_dark.scss +35 -15
- package/theme/styles/_mixins.scss +3 -0
- package/timeline/styles/_index.scss +2 -2
- package/toast/styles/_index.scss +17 -8
- package/toolbar/styles/_index.scss +3 -3
- package/tour/styles/_index.scss +7 -1
- package/tree/styles/_index.scss +9 -5
- package/types/ngwr-action-sheet.d.ts +9 -1
- package/types/ngwr-affix.d.ts +7 -1
- package/types/ngwr-anchor.d.ts +8 -1
- package/types/ngwr-avatar.d.ts +13 -3
- package/types/ngwr-bar-chart.d.ts +16 -0
- package/types/ngwr-burger.d.ts +6 -2
- package/types/ngwr-button-testing.d.ts +85 -0
- package/types/ngwr-button.d.ts +26 -10
- package/types/ngwr-calendar-heatmap.d.ts +16 -2
- package/types/ngwr-calendar.d.ts +10 -0
- package/types/ngwr-carousel-testing.d.ts +257 -0
- package/types/ngwr-carousel.d.ts +20 -4
- package/types/ngwr-cascader-testing.d.ts +392 -0
- package/types/ngwr-checkbox-testing.d.ts +77 -0
- package/types/ngwr-checkbox.d.ts +7 -2
- package/types/ngwr-collapse-testing.d.ts +290 -0
- package/types/ngwr-color-picker.d.ts +20 -11
- package/types/ngwr-command-palette-testing.d.ts +437 -0
- package/types/ngwr-command-palette.d.ts +25 -2
- package/types/ngwr-compare.d.ts +50 -2
- package/types/ngwr-config.d.ts +176 -0
- package/types/ngwr-context-menu-testing.d.ts +401 -0
- package/types/ngwr-context-menu.d.ts +65 -17
- package/types/ngwr-counter.d.ts +6 -1
- package/types/ngwr-date-adapter-luxon.d.ts +26 -0
- package/types/ngwr-date-picker-testing.d.ts +518 -0
- package/types/ngwr-date-picker.d.ts +4 -0
- package/types/ngwr-dialog-testing.d.ts +79 -0
- package/types/ngwr-directives.d.ts +10 -1
- package/types/ngwr-donut-chart.d.ts +8 -1
- package/types/ngwr-drawer-testing.d.ts +196 -0
- package/types/ngwr-dropdown-testing.d.ts +202 -0
- package/types/ngwr-dropdown.d.ts +7 -1
- package/types/ngwr-empty.d.ts +19 -4
- package/types/ngwr-event-calendar.d.ts +26 -1
- package/types/ngwr-file-upload-testing.d.ts +194 -0
- package/types/ngwr-form-testing.d.ts +379 -0
- package/types/ngwr-form.d.ts +17 -0
- package/types/ngwr-gauge.d.ts +13 -1
- package/types/ngwr-image-cropper.d.ts +10 -0
- package/types/ngwr-input-number-testing.d.ts +226 -0
- package/types/ngwr-input-number.d.ts +29 -1
- package/types/ngwr-input-otp-testing.d.ts +299 -0
- package/types/ngwr-input-otp.d.ts +23 -2
- package/types/ngwr-input-testing.d.ts +84 -0
- package/types/ngwr-input.d.ts +20 -6
- package/types/ngwr-knob.d.ts +18 -0
- package/types/ngwr-layout.d.ts +1 -0
- package/types/ngwr-lightbox.d.ts +17 -3
- package/types/ngwr-line-chart.d.ts +9 -2
- package/types/ngwr-markdown-testing.d.ts +462 -0
- package/types/ngwr-markdown.d.ts +534 -0
- package/types/ngwr-marquee.d.ts +12 -2
- package/types/ngwr-mention-testing.d.ts +359 -0
- package/types/ngwr-meta.d.ts +4 -2
- package/types/ngwr-meter-group.d.ts +11 -1
- package/types/ngwr-overlay.d.ts +33 -2
- package/types/ngwr-pagination-testing.d.ts +291 -0
- package/types/ngwr-pagination.d.ts +1 -0
- package/types/ngwr-popconfirm-testing.d.ts +235 -0
- package/types/ngwr-popconfirm.d.ts +31 -21
- package/types/ngwr-popover-testing.d.ts +221 -0
- package/types/ngwr-popover.d.ts +9 -0
- package/types/ngwr-pull-to-refresh.d.ts +7 -0
- package/types/ngwr-qr.d.ts +9 -1
- package/types/ngwr-radio-testing.d.ts +296 -0
- package/types/ngwr-radio.d.ts +8 -2
- package/types/ngwr-rating-testing.d.ts +291 -0
- package/types/ngwr-rating.d.ts +23 -0
- package/types/ngwr-segmented-testing.d.ts +401 -0
- package/types/ngwr-select-testing.d.ts +175 -0
- package/types/ngwr-select.d.ts +45 -4
- package/types/ngwr-sidebar.d.ts +17 -2
- package/types/ngwr-slider-testing.d.ts +329 -0
- package/types/ngwr-slider.d.ts +35 -1
- package/types/ngwr-sparkline.d.ts +12 -2
- package/types/ngwr-speed-dial.d.ts +17 -18
- package/types/ngwr-spinner.d.ts +8 -1
- package/types/ngwr-splitter.d.ts +24 -1
- package/types/ngwr-statistic.d.ts +12 -2
- package/types/ngwr-stepper-testing.d.ts +346 -0
- package/types/ngwr-switch-testing.d.ts +66 -0
- package/types/ngwr-switch.d.ts +7 -2
- package/types/ngwr-table-testing.d.ts +423 -0
- package/types/ngwr-table.d.ts +42 -0
- package/types/ngwr-tabs-testing.d.ts +470 -0
- package/types/ngwr-tabs.d.ts +9 -0
- package/types/ngwr-textarea-testing.d.ts +184 -0
- package/types/ngwr-textarea.d.ts +7 -2
- package/types/ngwr-toast-testing.d.ts +80 -0
- package/types/ngwr-tour.d.ts +27 -0
- package/types/ngwr-transfer-testing.d.ts +444 -0
- package/types/ngwr-transfer.d.ts +16 -1
- package/types/ngwr-tree-testing.d.ts +501 -0
- package/types/ngwr-tree.d.ts +33 -0
- package/types/ngwr-version.d.ts +1 -1
- package/types/ngwr-virtual-scroll.d.ts +13 -1
- package/typewriter/styles/_index.scss +1 -1
- package/typography/styles/_index.scss +1 -1
- package/window/styles/_index.scss +32 -9
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, model, input, output, computed, ViewEncapsulation, Component } from '@angular/core';
|
|
3
3
|
import { WrDrawer, WrDrawerTitle } from 'ngwr/drawer';
|
|
4
|
+
import { useI18nText } from 'ngwr/i18n';
|
|
4
5
|
import { WrIcon } from 'ngwr/icon';
|
|
5
6
|
import { WrHaptics } from 'ngwr/platform';
|
|
6
7
|
|
|
@@ -49,6 +50,15 @@ class WrActionSheet {
|
|
|
49
50
|
/** Optional bold heading above the rows. */
|
|
50
51
|
title = input('', /* @ts-ignore */
|
|
51
52
|
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
53
|
+
/**
|
|
54
|
+
* Name announced for the dialog when there is no visible `title`. Falls back to
|
|
55
|
+
* `actionSheet.label`, then `'Actions'` — it used to be that English string,
|
|
56
|
+
* written into the template of a component whose every other string comes from
|
|
57
|
+
* the caller.
|
|
58
|
+
*/
|
|
59
|
+
titleFallback = input(null, /* @ts-ignore */
|
|
60
|
+
...(ngDevMode ? [{ debugName: "titleFallback" }] : /* istanbul ignore next */ []));
|
|
61
|
+
resolvedTitleFallback = useI18nText(this.titleFallback, 'actionSheet.label', 'Actions');
|
|
52
62
|
/** Optional muted sub-heading under the title. */
|
|
53
63
|
message = input('', /* @ts-ignore */
|
|
54
64
|
...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
@@ -66,12 +76,12 @@ class WrActionSheet {
|
|
|
66
76
|
this.open.set(false);
|
|
67
77
|
}
|
|
68
78
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrActionSheet, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
69
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", 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 }, 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>
|
|
79
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", 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 });
|
|
70
80
|
}
|
|
71
81
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrActionSheet, decorators: [{
|
|
72
82
|
type: Component,
|
|
73
|
-
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>
|
|
74
|
-
}], 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 }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
|
|
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
|
+
}], 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"] }] } });
|
|
75
85
|
|
|
76
86
|
/**
|
|
77
87
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-action-sheet.mjs","sources":["../../../projects/lib/action-sheet/action-sheet.ts","../../../projects/lib/action-sheet/action-sheet.html","../../../projects/lib/action-sheet/ngwr-action-sheet.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 { Component, ViewEncapsulation, computed, inject, input, model, output } from '@angular/core';\n\nimport { WrDrawer, WrDrawerTitle } from 'ngwr/drawer';\nimport { WrIcon } from 'ngwr/icon';\nimport { WrHaptics } from 'ngwr/platform';\n\nimport type { WrActionSheetAction } from './interfaces';\n\n/**\n * iOS-style action sheet — a bottom sheet offering a short list of choices.\n * A thin preset over {@link WrDrawer} (bottom position, rounded, grab handle,\n * safe-area padding), driven by data rather than projected content.\n *\n * Pass `actions`; picking one emits `action` and closes the sheet. Rows with\n * `role: 'destructive'` are painted in the danger colour, and `role: 'cancel'`\n * rows drop to a separate group at the bottom. Dismissing via the backdrop,\n * `Escape`, or a swipe-down closes without emitting. Picking fires a light\n * {@link WrHaptics} tick.\n *\n * @example\n * ```html\n * <wr-action-sheet\n * [(open)]=\"sheetOpen\"\n * title=\"Photo\"\n * [actions]=\"[\n * { label: 'Take Photo', icon: 'camera', value: 'camera' },\n * { label: 'Choose from Library', icon: 'image', value: 'library' },\n * { label: 'Delete', role: 'destructive', value: 'delete' },\n * { label: 'Cancel', role: 'cancel' },\n * ]\"\n * (action)=\"onPick($event)\"\n * />\n * ```\n *\n * @see https://ngwr.dev/reference/components/action-sheet\n */\n@Component({\n selector: 'wr-action-sheet',\n templateUrl: './action-sheet.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrDrawer, WrDrawerTitle, WrIcon],\n})\nexport class WrActionSheet {\n private readonly haptics = inject(WrHaptics);\n\n /** Whether the sheet is open. Two-way. @default false */\n readonly open = model<boolean>(false);\n\n /** The rows to offer. */\n readonly actions = input<readonly WrActionSheetAction[]>([]);\n\n /** Optional bold heading above the rows. */\n readonly title = input<string>('');\n\n /** Optional muted sub-heading under the title. */\n readonly message = input<string>('');\n\n /** Fires with the chosen row (never fires on a dismiss). */\n readonly action = output<WrActionSheetAction>();\n\n protected readonly mainActions = computed(() => this.actions().filter(a => a.role !== 'cancel'));\n protected readonly cancelActions = computed(() => this.actions().filter(a => a.role === 'cancel'));\n\n protected select(item: WrActionSheetAction): void {\n if (item.disabled) return;\n this.haptics.selection();\n this.action.emit(item);\n this.open.set(false);\n }\n}\n","<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>
|
|
1
|
+
{"version":3,"file":"ngwr-action-sheet.mjs","sources":["../../../projects/lib/action-sheet/action-sheet.ts","../../../projects/lib/action-sheet/action-sheet.html","../../../projects/lib/action-sheet/ngwr-action-sheet.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 { Component, ViewEncapsulation, computed, inject, input, model, output } from '@angular/core';\n\nimport { WrDrawer, WrDrawerTitle } from 'ngwr/drawer';\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrIcon } from 'ngwr/icon';\nimport { WrHaptics } from 'ngwr/platform';\n\nimport type { WrActionSheetAction } from './interfaces';\n\n/**\n * iOS-style action sheet — a bottom sheet offering a short list of choices.\n * A thin preset over {@link WrDrawer} (bottom position, rounded, grab handle,\n * safe-area padding), driven by data rather than projected content.\n *\n * Pass `actions`; picking one emits `action` and closes the sheet. Rows with\n * `role: 'destructive'` are painted in the danger colour, and `role: 'cancel'`\n * rows drop to a separate group at the bottom. Dismissing via the backdrop,\n * `Escape`, or a swipe-down closes without emitting. Picking fires a light\n * {@link WrHaptics} tick.\n *\n * @example\n * ```html\n * <wr-action-sheet\n * [(open)]=\"sheetOpen\"\n * title=\"Photo\"\n * [actions]=\"[\n * { label: 'Take Photo', icon: 'camera', value: 'camera' },\n * { label: 'Choose from Library', icon: 'image', value: 'library' },\n * { label: 'Delete', role: 'destructive', value: 'delete' },\n * { label: 'Cancel', role: 'cancel' },\n * ]\"\n * (action)=\"onPick($event)\"\n * />\n * ```\n *\n * @see https://ngwr.dev/reference/components/action-sheet\n */\n@Component({\n selector: 'wr-action-sheet',\n templateUrl: './action-sheet.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrDrawer, WrDrawerTitle, WrIcon],\n})\nexport class WrActionSheet {\n private readonly haptics = inject(WrHaptics);\n\n /** Whether the sheet is open. Two-way. @default false */\n readonly open = model<boolean>(false);\n\n /** The rows to offer. */\n readonly actions = input<readonly WrActionSheetAction[]>([]);\n\n /** Optional bold heading above the rows. */\n readonly title = input<string>('');\n\n /**\n * Name announced for the dialog when there is no visible `title`. Falls back to\n * `actionSheet.label`, then `'Actions'` — it used to be that English string,\n * written into the template of a component whose every other string comes from\n * the caller.\n */\n readonly titleFallback = input<string | null>(null);\n\n protected readonly resolvedTitleFallback = useI18nText(this.titleFallback, 'actionSheet.label', 'Actions');\n\n /** Optional muted sub-heading under the title. */\n readonly message = input<string>('');\n\n /** Fires with the chosen row (never fires on a dismiss). */\n readonly action = output<WrActionSheetAction>();\n\n protected readonly mainActions = computed(() => this.actions().filter(a => a.role !== 'cancel'));\n protected readonly cancelActions = computed(() => this.actions().filter(a => a.role === 'cancel'));\n\n protected select(item: WrActionSheetAction): void {\n if (item.disabled) return;\n this.haptics.selection();\n this.action.emit(item);\n this.open.set(false);\n }\n}\n","<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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;AAAA;;;;;AAKG;AAWH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;MAOU,aAAa,CAAA;AACP,IAAA,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC;;IAGnC,IAAI,GAAG,KAAK,CAAU,KAAK;6EAAC;;IAG5B,OAAO,GAAG,KAAK,CAAiC,EAAE;gFAAC;;IAGnD,KAAK,GAAG,KAAK,CAAS,EAAE;8EAAC;AAElC;;;;;AAKG;IACM,aAAa,GAAG,KAAK,CAAgB,IAAI;sFAAC;IAEhC,qBAAqB,GAAG,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,mBAAmB,EAAE,SAAS,CAAC;;IAGjG,OAAO,GAAG,KAAK,CAAS,EAAE;gFAAC;;IAG3B,MAAM,GAAG,MAAM,EAAuB;IAE5B,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;oFAAC;IAC7E,aAAa,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;sFAAC;AAExF,IAAA,MAAM,CAAC,IAAyB,EAAA;QACxC,IAAI,IAAI,CAAC,QAAQ;YAAE;AACnB,QAAA,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;AACxB,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;IACtB;uGApCW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,mwBClD1B,+6DAoDA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDJY,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,SAAA,EAAA,YAAA,EAAA,UAAA,EAAA,aAAA,EAAA,sBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,YAAA,CAAA,EAAA,OAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,aAAa,4DAAE,MAAM,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAE9B,aAAa,EAAA,UAAA,EAAA,CAAA;kBANzB,SAAS;+BACE,iBAAiB,EAAA,aAAA,EAEZ,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,CAAC,EAAA,QAAA,EAAA,+6DAAA,EAAA;;;AEhD5C;;AAEG;;;;"}
|
package/fesm2022/ngwr-affix.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { coerceNumberProperty } from '@angular/cdk/coercion';
|
|
2
2
|
import { isPlatformBrowser } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { input, output, inject, ElementRef, DestroyRef, PLATFORM_ID, afterNextRender, Directive } from '@angular/core';
|
|
4
|
+
import { input, output, inject, ElementRef, DestroyRef, PLATFORM_ID, Injector, afterNextRender, effect, Directive } from '@angular/core';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @license
|
|
@@ -11,7 +11,7 @@ import { input, output, inject, ElementRef, DestroyRef, PLATFORM_ID, afterNextRe
|
|
|
11
11
|
*/
|
|
12
12
|
/**
|
|
13
13
|
* Stick-on-scroll directive. Combines native CSS `position: sticky` with
|
|
14
|
-
* an `IntersectionObserver`-driven
|
|
14
|
+
* an `IntersectionObserver`-driven `wr-affix--active` state class, so consumers
|
|
15
15
|
* can style the element differently while it's pinned (e.g. add a
|
|
16
16
|
* shadow, change the background, shrink the height).
|
|
17
17
|
*
|
|
@@ -46,6 +46,12 @@ class WrAffix {
|
|
|
46
46
|
host = inject(ElementRef);
|
|
47
47
|
destroyRef = inject(DestroyRef);
|
|
48
48
|
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
49
|
+
/**
|
|
50
|
+
* `afterNextRender`'s callback is not an injection context, and the observer
|
|
51
|
+
* cannot exist before the sentinel it watches — so the effect that rebuilds it
|
|
52
|
+
* is handed the injector explicitly.
|
|
53
|
+
*/
|
|
54
|
+
injector = inject(Injector);
|
|
49
55
|
constructor() {
|
|
50
56
|
if (!this.isBrowser)
|
|
51
57
|
return;
|
|
@@ -62,18 +68,39 @@ class WrAffix {
|
|
|
62
68
|
sentinel.setAttribute('aria-hidden', 'true');
|
|
63
69
|
sentinel.style.cssText = 'height:0;width:100%;margin:0;padding:0;pointer-events:none;';
|
|
64
70
|
parent.insertBefore(sentinel, el);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
observer.
|
|
71
|
+
// The observer reports STATE, not transitions: it delivers an entry for the
|
|
72
|
+
// sentinel as soon as it starts watching it — before anything has scrolled —
|
|
73
|
+
// and can repeat a state the host is already in (a resize, another crossing of
|
|
74
|
+
// the same threshold). `affixChange` is documented as the transition, so it
|
|
75
|
+
// only fires on one. The starting state is "not affixed", which is what the
|
|
76
|
+
// element already renders as, so that first entry is silent.
|
|
77
|
+
let affixed = false;
|
|
78
|
+
let observer = null;
|
|
79
|
+
// `rootMargin` is fixed for an observer's lifetime, so a changed offset means
|
|
80
|
+
// a NEW observer. Without this the two halves of the offset drifted apart:
|
|
81
|
+
// `[style.top.px]` is a live binding, so a header that animates its offset
|
|
82
|
+
// pinned at the new line while still flipping state at the old one.
|
|
83
|
+
// Re-observing re-delivers the current state, which the transition guard
|
|
84
|
+
// above absorbs when nothing has actually changed.
|
|
85
|
+
effect(onCleanup => {
|
|
86
|
+
const offset = this.offsetTop();
|
|
87
|
+
observer = new IntersectionObserver(([entry]) => {
|
|
88
|
+
const next = !entry.isIntersecting;
|
|
89
|
+
if (next === affixed)
|
|
90
|
+
return;
|
|
91
|
+
affixed = next;
|
|
92
|
+
el.classList.toggle('wr-affix--active', next);
|
|
93
|
+
this.affixChange.emit(next);
|
|
94
|
+
}, {
|
|
95
|
+
// Trigger when the sentinel's top crosses the offset line.
|
|
96
|
+
rootMargin: `-${offset}px 0px 0px 0px`,
|
|
97
|
+
threshold: [0],
|
|
98
|
+
});
|
|
99
|
+
observer.observe(sentinel);
|
|
100
|
+
onCleanup(() => observer?.disconnect());
|
|
101
|
+
}, { injector: this.injector });
|
|
75
102
|
this.destroyRef.onDestroy(() => {
|
|
76
|
-
observer
|
|
103
|
+
observer?.disconnect();
|
|
77
104
|
sentinel.remove();
|
|
78
105
|
el.classList.remove('wr-affix--active');
|
|
79
106
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-affix.mjs","sources":["../../../projects/lib/affix/affix.ts","../../../projects/lib/affix/ngwr-affix.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 { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {
|
|
1
|
+
{"version":3,"file":"ngwr-affix.mjs","sources":["../../../projects/lib/affix/affix.ts","../../../projects/lib/affix/ngwr-affix.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 { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n PLATFORM_ID,\n afterNextRender,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\n\n/**\n * Stick-on-scroll directive. Combines native CSS `position: sticky` with\n * an `IntersectionObserver`-driven `wr-affix--active` state class, so consumers\n * can style the element differently while it's pinned (e.g. add a\n * shadow, change the background, shrink the height).\n *\n * The host gets `position: sticky; top: ${offsetTop}px;` inline. A tiny\n * sentinel `<div>` is inserted just before the host — when the sentinel\n * scrolls out of view, the host is \"stuck\" and gets `wr-affix--active`\n * + an `(wrAffixChange)` emission.\n *\n * Works inside any scroll container without configuration — CSS sticky\n * picks the nearest scrollable ancestor automatically.\n *\n * @example\n * ```html\n * <header wrAffix [wrAffixOffsetTop]=\"0\">\n * <!-- adds a shadow once stuck -->\n * </header>\n * ```\n *\n * ```scss\n * header.wr-affix.wr-affix--active {\n * box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n * }\n * ```\n */\n@Directive({\n selector: '[wrAffix]',\n host: {\n class: 'wr-affix',\n '[style.position]': '\"sticky\"',\n '[style.top.px]': 'offsetTop()',\n },\n})\nexport class WrAffix {\n /** Pixels from the top of the scroll container when stuck. @default 0 */\n readonly offsetTop = input(0, {\n alias: 'wrAffixOffsetTop',\n transform: (v: unknown): number => coerceNumberProperty(v, 0),\n });\n\n /** Emits `true` when the element becomes affixed, `false` when it unsticks. */\n // eslint-disable-next-line @angular-eslint/no-output-rename -- keep wr-prefixed binding to match `[wrAffix]`\n readonly affixChange = output<boolean>({ alias: 'wrAffixChange' });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n /**\n * `afterNextRender`'s callback is not an injection context, and the observer\n * cannot exist before the sentinel it watches — so the effect that rebuilds it\n * is handed the injector explicitly.\n */\n private readonly injector = inject(Injector);\n\n constructor() {\n if (!this.isBrowser) return;\n\n afterNextRender(() => {\n const el = this.host.nativeElement;\n const parent = el.parentElement;\n if (!parent) return;\n\n // Sentinel: an empty zero-height block placed immediately before\n // the host. When the sentinel scrolls out of view, the host is\n // necessarily \"stuck\" at the configured offset.\n const sentinel = el.ownerDocument.createElement('div');\n sentinel.className = 'wr-affix__sentinel';\n sentinel.setAttribute('aria-hidden', 'true');\n sentinel.style.cssText = 'height:0;width:100%;margin:0;padding:0;pointer-events:none;';\n parent.insertBefore(sentinel, el);\n\n // The observer reports STATE, not transitions: it delivers an entry for the\n // sentinel as soon as it starts watching it — before anything has scrolled —\n // and can repeat a state the host is already in (a resize, another crossing of\n // the same threshold). `affixChange` is documented as the transition, so it\n // only fires on one. The starting state is \"not affixed\", which is what the\n // element already renders as, so that first entry is silent.\n let affixed = false;\n\n let observer: IntersectionObserver | null = null;\n\n // `rootMargin` is fixed for an observer's lifetime, so a changed offset means\n // a NEW observer. Without this the two halves of the offset drifted apart:\n // `[style.top.px]` is a live binding, so a header that animates its offset\n // pinned at the new line while still flipping state at the old one.\n // Re-observing re-delivers the current state, which the transition guard\n // above absorbs when nothing has actually changed.\n effect(\n onCleanup => {\n const offset = this.offsetTop();\n\n observer = new IntersectionObserver(\n ([entry]) => {\n const next = !entry.isIntersecting;\n if (next === affixed) return;\n\n affixed = next;\n el.classList.toggle('wr-affix--active', next);\n this.affixChange.emit(next);\n },\n {\n // Trigger when the sentinel's top crosses the offset line.\n rootMargin: `-${offset}px 0px 0px 0px`,\n threshold: [0],\n }\n );\n observer.observe(sentinel);\n\n onCleanup(() => observer?.disconnect());\n },\n { injector: this.injector }\n );\n\n this.destroyRef.onDestroy(() => {\n observer?.disconnect();\n sentinel.remove();\n el.classList.remove('wr-affix--active');\n });\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/fesm2022/ngwr-anchor.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { coerceNumberProperty } from '@angular/cdk/coercion';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, signal, computed, inject, NgZone, DestroyRef, ViewEncapsulation, Component } from '@angular/core';
|
|
3
|
+
import { input, signal, computed, inject, NgZone, DestroyRef, afterNextRender, ViewEncapsulation, Component } from '@angular/core';
|
|
4
|
+
import { useI18nText } from 'ngwr/i18n';
|
|
4
5
|
import { WrPlatform } from 'ngwr/platform';
|
|
5
6
|
import { WrScroll } from 'ngwr/scroll';
|
|
6
7
|
|
|
@@ -34,6 +35,14 @@ import { WrScroll } from 'ngwr/scroll';
|
|
|
34
35
|
class WrAnchor {
|
|
35
36
|
links = input([], /* @ts-ignore */
|
|
36
37
|
...(ngDevMode ? [{ debugName: "links" }] : /* istanbul ignore next */ []));
|
|
38
|
+
/**
|
|
39
|
+
* Accessible name for the navigation landmark. Falls back to `anchor.label`,
|
|
40
|
+
* then `'Table of contents'` — it used to be that English string, hard-coded
|
|
41
|
+
* on the host, in a landmark a screen reader reads out on every page.
|
|
42
|
+
*/
|
|
43
|
+
ariaLabel = input(null, /* @ts-ignore */
|
|
44
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
45
|
+
resolvedAriaLabel = useI18nText(this.ariaLabel, 'anchor.label', 'Table of contents');
|
|
37
46
|
/** Pixel offset subtracted on scroll — for sticky headers. @default 0 */
|
|
38
47
|
offset = input(0, { ...(ngDevMode ? { debugName: "offset" } : /* istanbul ignore next */ {}), transform: (v) => Math.max(0, coerceNumberProperty(v, 0)) });
|
|
39
48
|
/** Highlight an item when its target's top is within this many px of the offset line. @default 80 */
|
|
@@ -78,9 +87,12 @@ class WrAnchor {
|
|
|
78
87
|
this.zone.run(() => this.activeId.set(active));
|
|
79
88
|
};
|
|
80
89
|
this.zone.runOutsideAngular(() => window.addEventListener('scroll', handler, { passive: true }));
|
|
81
|
-
// Initial pass.
|
|
82
|
-
handler();
|
|
83
90
|
this.destroyRef.onDestroy(() => window.removeEventListener('scroll', handler));
|
|
91
|
+
// The first pass has to wait for a render: the targets are elsewhere on the
|
|
92
|
+
// page and are usually rendered AFTER this list, so a constructor-time pass
|
|
93
|
+
// found nothing by `getElementById` and left the page with no highlight at
|
|
94
|
+
// all until the reader happened to scroll.
|
|
95
|
+
afterNextRender(() => handler());
|
|
84
96
|
}
|
|
85
97
|
onClick(id, event) {
|
|
86
98
|
event.preventDefault();
|
|
@@ -88,12 +100,12 @@ class WrAnchor {
|
|
|
88
100
|
this.activeId.set(id);
|
|
89
101
|
}
|
|
90
102
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAnchor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
91
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: WrAnchor, isStandalone: true, selector: "wr-anchor", inputs: { links: { classPropertyName: "links", publicName: "links", 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", "aria-label": "
|
|
103
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", 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 });
|
|
92
104
|
}
|
|
93
105
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAnchor, decorators: [{
|
|
94
106
|
type: Component,
|
|
95
|
-
args: [{ selector: 'wr-anchor', encapsulation: ViewEncapsulation.None, host: { class: 'wr-anchor', role: 'navigation', 'aria-label': '
|
|
96
|
-
}], ctorParameters: () => [], propDecorators: { links: [{ type: i0.Input, args: [{ isSignal: true, alias: "links", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], hitArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "hitArea", required: false }] }] } });
|
|
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
|
+
}], 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 }] }] } });
|
|
97
109
|
|
|
98
110
|
/**
|
|
99
111
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-anchor.mjs","sources":["../../../projects/lib/anchor/anchor.ts","../../../projects/lib/anchor/anchor.html","../../../projects/lib/anchor/ngwr-anchor.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 { coerceNumberProperty } from '@angular/cdk/coercion';\nimport {
|
|
1
|
+
{"version":3,"file":"ngwr-anchor.mjs","sources":["../../../projects/lib/anchor/anchor.ts","../../../projects/lib/anchor/anchor.html","../../../projects/lib/anchor/ngwr-anchor.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 { coerceNumberProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n DestroyRef,\n NgZone,\n ViewEncapsulation,\n afterNextRender,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrPlatform } from 'ngwr/platform';\nimport { WrScroll } from 'ngwr/scroll';\n\nimport type { WrAnchorLink } from './interfaces';\n\n/**\n * Scroll-spy in-page navigation. Renders a list of links to elements on\n * the page; clicking a link smooth-scrolls (via {@link WrScroll}),\n * and the closest visible heading auto-highlights as the user scrolls.\n *\n * @example\n * ```html\n * <wr-anchor\n * [links]=\"[\n * { id: 'intro', label: 'Introduction' },\n * { id: 'usage', label: 'Usage', children: [\n * { id: 'basic', label: 'Basic' },\n * { id: 'advanced', label: 'Advanced' },\n * ]}\n * ]\"\n * [offset]=\"80\"\n * />\n * ```\n *\n * @see https://ngwr.dev/reference/components/anchor\n */\n@Component({\n selector: 'wr-anchor',\n templateUrl: './anchor.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-anchor', role: 'navigation', '[attr.aria-label]': 'resolvedAriaLabel()' },\n})\nexport class WrAnchor {\n readonly links = input<readonly WrAnchorLink[]>([]);\n\n /**\n * Accessible name for the navigation landmark. Falls back to `anchor.label`,\n * then `'Table of contents'` — it used to be that English string, hard-coded\n * on the host, in a landmark a screen reader reads out on every page.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'anchor.label', 'Table of contents');\n\n /** Pixel offset subtracted on scroll — for sticky headers. @default 0 */\n readonly offset = input(0, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 0)) });\n\n /** Highlight an item when its target's top is within this many px of the offset line. @default 80 */\n readonly hitArea = input(80, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 80)) });\n\n protected readonly activeId = signal<string | null>(null);\n\n /** Flat list of all ids (top-level + children) — used for scroll spy. */\n protected readonly flatIds = computed<readonly string[]>(() => {\n const out: string[] = [];\n const walk = (list: readonly WrAnchorLink[]): void => {\n for (const item of list) {\n out.push(item.id);\n if (item.children) walk(item.children);\n }\n };\n walk(this.links());\n return out;\n });\n\n private readonly scroll = inject(WrScroll);\n private readonly platform = inject(WrPlatform);\n private readonly zone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n if (!this.platform.isBrowser) return;\n const handler = (): void => {\n const cursor = this.offset() + this.hitArea();\n let active: string | null = null;\n for (const id of this.flatIds()) {\n const el = document.getElementById(id);\n if (!el) continue;\n const top = el.getBoundingClientRect().top;\n if (top <= cursor) active = id;\n else break;\n }\n if (active !== this.activeId()) this.zone.run(() => this.activeId.set(active));\n };\n this.zone.runOutsideAngular(() => window.addEventListener('scroll', handler, { passive: true }));\n this.destroyRef.onDestroy(() => window.removeEventListener('scroll', handler));\n // The first pass has to wait for a render: the targets are elsewhere on the\n // page and are usually rendered AFTER this list, so a constructor-time pass\n // found nothing by `getElementById` and left the page with no highlight at\n // all until the reader happened to scroll.\n afterNextRender(() => handler());\n }\n\n protected onClick(id: string, event: MouseEvent): void {\n event.preventDefault();\n this.scroll.to(`#${id}`, { offset: this.offset() });\n this.activeId.set(id);\n }\n}\n\nexport type { WrAnchorLink } from './interfaces';\n","<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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/fesm2022/ngwr-aurora.mjs
CHANGED
|
@@ -295,11 +295,11 @@ class WrAurora {
|
|
|
295
295
|
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
296
296
|
}
|
|
297
297
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAurora, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
298
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.1", 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"></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 });
|
|
298
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.1", 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
300
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAurora, decorators: [{
|
|
301
301
|
type: Component,
|
|
302
|
-
args: [{ selector: 'wr-aurora', template: '<canvas #canvas class="wr-aurora__canvas"></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"] }]
|
|
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 }] }] } });
|
|
304
304
|
|
|
305
305
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-aurora.mjs","sources":["../../../projects/lib/aurora/aurora.ts","../../../projects/lib/aurora/ngwr-aurora.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 Aurora background by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/backgrounds/aurora\n *\n * The reactbits version renders through the OGL library; this port talks\n * to WebGL2 directly — same vertex/fragment shaders, zero dependencies.\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n NgZone,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n effect,\n inject,\n input,\n viewChild,\n} from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\nconst VERT = `#version 300 es\nin vec2 position;\nvoid main() {\n gl_Position = vec4(position, 0.0, 1.0);\n}\n`;\n\nconst FRAG = `#version 300 es\nprecision highp float;\n\nuniform float uTime;\nuniform float uAmplitude;\nuniform vec3 uColorStops[3];\nuniform vec2 uResolution;\nuniform float uBlend;\n\nout vec4 fragColor;\n\nvec3 permute(vec3 x) {\n return mod(((x * 34.0) + 1.0) * x, 289.0);\n}\n\nfloat snoise(vec2 v){\n const vec4 C = vec4(\n 0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439\n );\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n\n vec3 p = permute(\n permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0)\n );\n\n vec3 m = max(\n 0.5 - vec3(\n dot(x0, x0),\n dot(x12.xy, x12.xy),\n dot(x12.zw, x12.zw)\n ),\n 0.0\n );\n m = m * m;\n m = m * m;\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);\n\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\nstruct ColorStop {\n vec3 color;\n float position;\n};\n\n#define COLOR_RAMP(colors, factor, finalColor) { \\\\\n int index = 0; \\\\\n for (int i = 0; i < 2; i++) { \\\\\n ColorStop currentColor = colors[i]; \\\\\n bool isInBetween = currentColor.position <= factor; \\\\\n index = int(mix(float(index), float(i), float(isInBetween))); \\\\\n } \\\\\n ColorStop currentColor = colors[index]; \\\\\n ColorStop nextColor = colors[index + 1]; \\\\\n float range = nextColor.position - currentColor.position; \\\\\n float lerpFactor = (factor - currentColor.position) / range; \\\\\n finalColor = mix(currentColor.color, nextColor.color, lerpFactor); \\\\\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / uResolution;\n\n ColorStop colors[3];\n colors[0] = ColorStop(uColorStops[0], 0.0);\n colors[1] = ColorStop(uColorStops[1], 0.5);\n colors[2] = ColorStop(uColorStops[2], 1.0);\n\n vec3 rampColor;\n COLOR_RAMP(colors, uv.x, rampColor);\n\n float height = snoise(vec2(uv.x * 2.0 + uTime * 0.1, uTime * 0.25)) * 0.5 * uAmplitude;\n height = exp(height);\n height = (uv.y * 2.0 - height + 0.2);\n float intensity = 0.6 * height;\n\n float midPoint = 0.20;\n float auroraAlpha = smoothstep(midPoint - uBlend * 0.5, midPoint + uBlend * 0.5, intensity);\n\n // Clamp the brightness floor: the upstream shader multiplies colour by\n // raw intensity, which fades the ribbon to BLACK while still opaque —\n // invisible on dark pages, a dirty gray halo on light ones. Keeping the\n // hue saturated and letting alpha alone do the fading works on both.\n vec3 auroraColor = rampColor * max(intensity, 0.85);\n\n fragColor = vec4(auroraColor * auroraAlpha, auroraAlpha);\n}\n`;\n\nfunction hexToRgb01(hex: string): [number, number, number] {\n let val = hex.replace('#', '');\n if (val.length === 3) val = val[0] + val[0] + val[1] + val[1] + val[2] + val[2];\n return [\n Number.parseInt(val.slice(0, 2), 16) / 255,\n Number.parseInt(val.slice(2, 4), 16) / 255,\n Number.parseInt(val.slice(4, 6), 16) / 255,\n ];\n}\n\n/**\n * Aurora background — flowing northern-lights ribbons rendered with a\n * WebGL2 simplex-noise shader, ramped across three colour stops. Fills\n * its nearest positioned ancestor; renders nothing without WebGL2.\n *\n * Under `prefers-reduced-motion` a single static frame is drawn.\n *\n * @example\n * ```html\n * <div style=\"position: relative; min-height: 24rem; overflow: hidden\">\n * <wr-aurora />\n * <h1 style=\"position: relative\">Welcome aboard</h1>\n * </div>\n * ```\n *\n * @see https://ngwr.dev/animations/aurora\n */\n@Component({\n selector: 'wr-aurora',\n template: '<canvas #canvas class=\"wr-aurora__canvas\"></canvas>',\n styleUrl: './aurora.scss',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-aurora' },\n})\nexport class WrAurora {\n /**\n * Exactly three colour stops, ramped left → right. When unset, the\n * theme decides: deep violet/emerald on light, the neon reactbits\n * palette on dark.\n */\n readonly colorStops = input<readonly string[] | null>(null);\n\n /** Wave height multiplier. @default 1 */\n readonly amplitude = input(1, { transform: numAttr(1) });\n\n /** Softness of the aurora's lower edge, 0..1. @default 0.5 */\n readonly blend = input(0.5, { transform: numAttr(0.5) });\n\n /** Time multiplier. @default 1 */\n readonly speed = input(1, { transform: numAttr(1) });\n\n private readonly canvasRef = viewChild.required<ElementRef<HTMLCanvasElement>>('canvas');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly zone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private gl: WebGL2RenderingContext | null = null;\n private uniforms: Record<string, WebGLUniformLocation | null> = {};\n private rafId = 0;\n\n constructor() {\n if (!this.isBrowser) return;\n\n afterNextRender(() => this.zone.runOutsideAngular(() => this.boot()));\n\n // Push input changes into uniforms without restarting the loop. Under\n // reduced motion this also repaints the static frame.\n effect(() => {\n this.colorStops();\n this.amplitude();\n this.blend();\n if (!this.gl) return;\n this.pushUniforms();\n if (this.platform.prefersReducedMotion()) this.draw(0);\n });\n }\n\n private boot(): void {\n const canvas = this.canvasRef().nativeElement;\n const gl = canvas.getContext('webgl2', { alpha: true, premultipliedAlpha: true, antialias: true });\n if (!gl) return;\n this.gl = gl;\n\n gl.clearColor(0, 0, 0, 0);\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\n const compile = (type: number, source: string): WebGLShader => {\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n // eslint-disable-next-line no-console -- GPU shader failures are otherwise invisible\n console.error('wr-aurora shader error:', gl.getShaderInfoLog(shader));\n }\n return shader;\n };\n\n const program = gl.createProgram();\n gl.attachShader(program, compile(gl.VERTEX_SHADER, VERT));\n gl.attachShader(program, compile(gl.FRAGMENT_SHADER, FRAG));\n gl.linkProgram(program);\n gl.useProgram(program);\n\n for (const name of ['uTime', 'uAmplitude', 'uColorStops', 'uResolution', 'uBlend']) {\n this.uniforms[name] = gl.getUniformLocation(program, name);\n }\n\n // One oversized triangle covers the viewport — no index buffer needed.\n const buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW);\n const position = gl.getAttribLocation(program, 'position');\n gl.enableVertexAttribArray(position);\n gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);\n\n const resize = (): void => {\n const rect = this.host.nativeElement.getBoundingClientRect();\n canvas.width = Math.max(1, Math.round(rect.width));\n canvas.height = Math.max(1, Math.round(rect.height));\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(this.uniforms['uResolution'], canvas.width, canvas.height);\n if (this.platform.prefersReducedMotion()) this.draw(0);\n };\n\n window.addEventListener('resize', resize);\n const ro = new ResizeObserver(resize);\n ro.observe(this.host.nativeElement);\n\n resize();\n this.pushUniforms();\n\n if (this.platform.prefersReducedMotion()) {\n // Static frame — the ribbons hold their t=0 shape.\n this.draw(0);\n } else {\n const loop = (t: number): void => {\n this.rafId = requestAnimationFrame(loop);\n this.pushUniforms();\n this.draw(t * 0.01 * this.speed() * 0.1);\n };\n this.rafId = requestAnimationFrame(loop);\n }\n\n this.destroyRef.onDestroy(() => {\n cancelAnimationFrame(this.rafId);\n window.removeEventListener('resize', resize);\n ro.disconnect();\n });\n }\n\n private pushUniforms(): void {\n const gl = this.gl;\n if (!gl) return;\n const stops = this.resolveStops();\n const flat = new Float32Array(9);\n for (let i = 0; i < 3; i++) {\n const [r, g, b] = hexToRgb01(stops[Math.min(i, stops.length - 1)] ?? '#5227ff');\n flat[i * 3] = r;\n flat[i * 3 + 1] = g;\n flat[i * 3 + 2] = b;\n }\n gl.uniform3fv(this.uniforms['uColorStops'], flat);\n gl.uniform1f(this.uniforms['uAmplitude'], this.amplitude());\n gl.uniform1f(this.uniforms['uBlend'], this.blend());\n }\n\n /** Explicit input wins; otherwise the theme's `--wr-aurora-stop-*` vars. */\n private resolveStops(): readonly string[] {\n const explicit = this.colorStops();\n if (explicit !== null) return explicit;\n const style = getComputedStyle(this.host.nativeElement);\n return [\n style.getPropertyValue('--wr-aurora-stop-1').trim() || '#5227ff',\n style.getPropertyValue('--wr-aurora-stop-2').trim() || '#7cff67',\n style.getPropertyValue('--wr-aurora-stop-3').trim() || '#5227ff',\n ];\n }\n\n private draw(time: number): void {\n const gl = this.gl;\n if (!gl) return;\n gl.uniform1f(this.uniforms['uTime'], time);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;AAAA;;;;;;;;;;;AAWG;AAoBH,MAAM,IAAI,GAAG,CAAA;;;;;CAKZ;AAED,MAAM,IAAI,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqGZ;AAED,SAAS,UAAU,CAAC,GAAW,EAAA;IAC7B,IAAI,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;AAC9B,IAAA,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC/E,OAAO;AACL,QAAA,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG;AAC1C,QAAA,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG;AAC1C,QAAA,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG;KAC3C;AACH;AAEA;;;;;;;;;;;;;;;;AAgBG;MAQU,QAAQ,CAAA;AACnB;;;;AAIG;IACM,UAAU,GAAG,KAAK,CAA2B,IAAI;mFAAC;;AAGlD,IAAA,SAAS,GAAG,KAAK,CAAC,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,WAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAAA,CAAG;;AAG/C,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,KAAK,GAAG,KAAK,CAAC,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,OAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAAA,CAAG;AAEnC,IAAA,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAgC,QAAQ;kFAAC;AAEvE,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC;AAClD,IAAA,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;AACrB,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,IAAA,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC;IAC7B,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE3D,EAAE,GAAkC,IAAI;IACxC,QAAQ,GAAgD,EAAE;IAC1D,KAAK,GAAG,CAAC;AAEjB,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;AAErB,QAAA,eAAe,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;;;QAIrE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,UAAU,EAAE;YACjB,IAAI,CAAC,SAAS,EAAE;YAChB,IAAI,CAAC,KAAK,EAAE;YACZ,IAAI,CAAC,IAAI,CAAC,EAAE;gBAAE;YACd,IAAI,CAAC,YAAY,EAAE;AACnB,YAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE;AAAE,gBAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACxD,QAAA,CAAC,CAAC;IACJ;IAEQ,IAAI,GAAA;QACV,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,aAAa;QAC7C,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAClG,QAAA,IAAI,CAAC,EAAE;YAAE;AACT,QAAA,IAAI,CAAC,EAAE,GAAG,EAAE;QAEZ,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACzB,QAAA,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;QACnB,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,mBAAmB,CAAC;AAE5C,QAAA,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,MAAc,KAAiB;YAC5D,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAE;AACrC,YAAA,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC;AAC/B,YAAA,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC;AACxB,YAAA,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE;;AAErD,gBAAA,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YACvE;AACA,YAAA,OAAO,MAAM;AACf,QAAA,CAAC;AAED,QAAA,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,EAAE;AAClC,QAAA,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AACzD,QAAA,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;AAC3D,QAAA,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC;AACvB,QAAA,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;AAEtB,QAAA,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE;AAClF,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC;QAC5D;;AAGA,QAAA,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,EAAE;QAChC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;AACtC,QAAA,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC;QACxF,MAAM,QAAQ,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC;AAC1D,QAAA,EAAE,CAAC,uBAAuB,CAAC,QAAQ,CAAC;AACpC,QAAA,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAE1D,MAAM,MAAM,GAAG,MAAW;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,qBAAqB,EAAE;AAC5D,YAAA,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClD,YAAA,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACpD,YAAA,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;AAC9C,YAAA,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;AACvE,YAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE;AAAE,gBAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACxD,QAAA,CAAC;AAED,QAAA,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC;AACzC,QAAA,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC;QACrC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;AAEnC,QAAA,MAAM,EAAE;QACR,IAAI,CAAC,YAAY,EAAE;AAEnB,QAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,EAAE;;AAExC,YAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACd;aAAO;AACL,YAAA,MAAM,IAAI,GAAG,CAAC,CAAS,KAAU;AAC/B,gBAAA,IAAI,CAAC,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC;gBACxC,IAAI,CAAC,YAAY,EAAE;AACnB,gBAAA,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC;AAC1C,YAAA,CAAC;AACD,YAAA,IAAI,CAAC,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC;QAC1C;AAEA,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;AAC7B,YAAA,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC;AAChC,YAAA,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC;YAC5C,EAAE,CAAC,UAAU,EAAE;AACjB,QAAA,CAAC,CAAC;IACJ;IAEQ,YAAY,GAAA;AAClB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE;AAClB,QAAA,IAAI,CAAC,EAAE;YAAE;AACT,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE;AACjC,QAAA,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC;AAChC,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;AAC1B,YAAA,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;AAC/E,YAAA,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;YACf,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;YACnB,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;QACrB;AACA,QAAA,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC;AACjD,QAAA,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;AAC3D,QAAA,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IACrD;;IAGQ,YAAY,GAAA;AAClB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE;QAClC,IAAI,QAAQ,KAAK,IAAI;AAAE,YAAA,OAAO,QAAQ;QACtC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;QACvD,OAAO;YACL,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS;YAChE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS;YAChE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS;SACjE;IACH;AAEQ,IAAA,IAAI,CAAC,IAAY,EAAA;AACvB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE;AAClB,QAAA,IAAI,CAAC,EAAE;YAAE;AACT,QAAA,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC;AAC1C,QAAA,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC;QAC7B,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;IACnC;uGA1JW,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAR,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAQ,wuBALT,qDAAqD,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,kWAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAKpD,QAAQ,EAAA,UAAA,EAAA,CAAA;kBAPpB,SAAS;+BACE,WAAW,EAAA,QAAA,EACX,qDAAqD,EAAA,aAAA,EAEhD,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B,EAAE,KAAK,EAAE,WAAW,EAAE,EAAA,MAAA,EAAA,CAAA,kWAAA,CAAA,EAAA;2dAmBmD,QAAQ,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AChMzF;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ngwr-aurora.mjs","sources":["../../../projects/lib/aurora/aurora.ts","../../../projects/lib/aurora/ngwr-aurora.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 Aurora background by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/backgrounds/aurora\n *\n * The reactbits version renders through the OGL library; this port talks\n * to WebGL2 directly — same vertex/fragment shaders, zero dependencies.\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n NgZone,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n effect,\n inject,\n input,\n viewChild,\n} from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\nconst VERT = `#version 300 es\nin vec2 position;\nvoid main() {\n gl_Position = vec4(position, 0.0, 1.0);\n}\n`;\n\nconst FRAG = `#version 300 es\nprecision highp float;\n\nuniform float uTime;\nuniform float uAmplitude;\nuniform vec3 uColorStops[3];\nuniform vec2 uResolution;\nuniform float uBlend;\n\nout vec4 fragColor;\n\nvec3 permute(vec3 x) {\n return mod(((x * 34.0) + 1.0) * x, 289.0);\n}\n\nfloat snoise(vec2 v){\n const vec4 C = vec4(\n 0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439\n );\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n\n vec3 p = permute(\n permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0)\n );\n\n vec3 m = max(\n 0.5 - vec3(\n dot(x0, x0),\n dot(x12.xy, x12.xy),\n dot(x12.zw, x12.zw)\n ),\n 0.0\n );\n m = m * m;\n m = m * m;\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);\n\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\nstruct ColorStop {\n vec3 color;\n float position;\n};\n\n#define COLOR_RAMP(colors, factor, finalColor) { \\\\\n int index = 0; \\\\\n for (int i = 0; i < 2; i++) { \\\\\n ColorStop currentColor = colors[i]; \\\\\n bool isInBetween = currentColor.position <= factor; \\\\\n index = int(mix(float(index), float(i), float(isInBetween))); \\\\\n } \\\\\n ColorStop currentColor = colors[index]; \\\\\n ColorStop nextColor = colors[index + 1]; \\\\\n float range = nextColor.position - currentColor.position; \\\\\n float lerpFactor = (factor - currentColor.position) / range; \\\\\n finalColor = mix(currentColor.color, nextColor.color, lerpFactor); \\\\\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / uResolution;\n\n ColorStop colors[3];\n colors[0] = ColorStop(uColorStops[0], 0.0);\n colors[1] = ColorStop(uColorStops[1], 0.5);\n colors[2] = ColorStop(uColorStops[2], 1.0);\n\n vec3 rampColor;\n COLOR_RAMP(colors, uv.x, rampColor);\n\n float height = snoise(vec2(uv.x * 2.0 + uTime * 0.1, uTime * 0.25)) * 0.5 * uAmplitude;\n height = exp(height);\n height = (uv.y * 2.0 - height + 0.2);\n float intensity = 0.6 * height;\n\n float midPoint = 0.20;\n float auroraAlpha = smoothstep(midPoint - uBlend * 0.5, midPoint + uBlend * 0.5, intensity);\n\n // Clamp the brightness floor: the upstream shader multiplies colour by\n // raw intensity, which fades the ribbon to BLACK while still opaque —\n // invisible on dark pages, a dirty gray halo on light ones. Keeping the\n // hue saturated and letting alpha alone do the fading works on both.\n vec3 auroraColor = rampColor * max(intensity, 0.85);\n\n fragColor = vec4(auroraColor * auroraAlpha, auroraAlpha);\n}\n`;\n\nfunction hexToRgb01(hex: string): [number, number, number] {\n let val = hex.replace('#', '');\n if (val.length === 3) val = val[0] + val[0] + val[1] + val[1] + val[2] + val[2];\n return [\n Number.parseInt(val.slice(0, 2), 16) / 255,\n Number.parseInt(val.slice(2, 4), 16) / 255,\n Number.parseInt(val.slice(4, 6), 16) / 255,\n ];\n}\n\n/**\n * Aurora background — flowing northern-lights ribbons rendered with a\n * WebGL2 simplex-noise shader, ramped across three colour stops. Fills\n * its nearest positioned ancestor; renders nothing without WebGL2.\n *\n * Under `prefers-reduced-motion` a single static frame is drawn.\n *\n * @example\n * ```html\n * <div style=\"position: relative; min-height: 24rem; overflow: hidden\">\n * <wr-aurora />\n * <h1 style=\"position: relative\">Welcome aboard</h1>\n * </div>\n * ```\n *\n * @see https://ngwr.dev/animations/aurora\n */\n@Component({\n selector: 'wr-aurora',\n template: '<canvas #canvas class=\"wr-aurora__canvas\" aria-hidden=\"true\"></canvas>',\n styleUrl: './aurora.scss',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-aurora' },\n})\nexport class WrAurora {\n /**\n * Exactly three colour stops, ramped left → right. When unset, the\n * theme decides: deep violet/emerald on light, the neon reactbits\n * palette on dark.\n */\n readonly colorStops = input<readonly string[] | null>(null);\n\n /** Wave height multiplier. @default 1 */\n readonly amplitude = input(1, { transform: numAttr(1) });\n\n /** Softness of the aurora's lower edge, 0..1. @default 0.5 */\n readonly blend = input(0.5, { transform: numAttr(0.5) });\n\n /** Time multiplier. @default 1 */\n readonly speed = input(1, { transform: numAttr(1) });\n\n private readonly canvasRef = viewChild.required<ElementRef<HTMLCanvasElement>>('canvas');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly zone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private gl: WebGL2RenderingContext | null = null;\n private uniforms: Record<string, WebGLUniformLocation | null> = {};\n private rafId = 0;\n\n constructor() {\n if (!this.isBrowser) return;\n\n afterNextRender(() => this.zone.runOutsideAngular(() => this.boot()));\n\n // Push input changes into uniforms without restarting the loop. Under\n // reduced motion this also repaints the static frame.\n effect(() => {\n this.colorStops();\n this.amplitude();\n this.blend();\n if (!this.gl) return;\n this.pushUniforms();\n if (this.platform.prefersReducedMotion()) this.draw(0);\n });\n }\n\n private boot(): void {\n const canvas = this.canvasRef().nativeElement;\n const gl = canvas.getContext('webgl2', { alpha: true, premultipliedAlpha: true, antialias: true });\n if (!gl) return;\n this.gl = gl;\n\n gl.clearColor(0, 0, 0, 0);\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\n const compile = (type: number, source: string): WebGLShader => {\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n // eslint-disable-next-line no-console -- GPU shader failures are otherwise invisible\n console.error('wr-aurora shader error:', gl.getShaderInfoLog(shader));\n }\n return shader;\n };\n\n const program = gl.createProgram();\n gl.attachShader(program, compile(gl.VERTEX_SHADER, VERT));\n gl.attachShader(program, compile(gl.FRAGMENT_SHADER, FRAG));\n gl.linkProgram(program);\n gl.useProgram(program);\n\n for (const name of ['uTime', 'uAmplitude', 'uColorStops', 'uResolution', 'uBlend']) {\n this.uniforms[name] = gl.getUniformLocation(program, name);\n }\n\n // One oversized triangle covers the viewport — no index buffer needed.\n const buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW);\n const position = gl.getAttribLocation(program, 'position');\n gl.enableVertexAttribArray(position);\n gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);\n\n const resize = (): void => {\n const rect = this.host.nativeElement.getBoundingClientRect();\n canvas.width = Math.max(1, Math.round(rect.width));\n canvas.height = Math.max(1, Math.round(rect.height));\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(this.uniforms['uResolution'], canvas.width, canvas.height);\n if (this.platform.prefersReducedMotion()) this.draw(0);\n };\n\n window.addEventListener('resize', resize);\n const ro = new ResizeObserver(resize);\n ro.observe(this.host.nativeElement);\n\n resize();\n this.pushUniforms();\n\n if (this.platform.prefersReducedMotion()) {\n // Static frame — the ribbons hold their t=0 shape.\n this.draw(0);\n } else {\n const loop = (t: number): void => {\n this.rafId = requestAnimationFrame(loop);\n this.pushUniforms();\n this.draw(t * 0.01 * this.speed() * 0.1);\n };\n this.rafId = requestAnimationFrame(loop);\n }\n\n this.destroyRef.onDestroy(() => {\n cancelAnimationFrame(this.rafId);\n window.removeEventListener('resize', resize);\n ro.disconnect();\n });\n }\n\n private pushUniforms(): void {\n const gl = this.gl;\n if (!gl) return;\n const stops = this.resolveStops();\n const flat = new Float32Array(9);\n for (let i = 0; i < 3; i++) {\n const [r, g, b] = hexToRgb01(stops[Math.min(i, stops.length - 1)] ?? '#5227ff');\n flat[i * 3] = r;\n flat[i * 3 + 1] = g;\n flat[i * 3 + 2] = b;\n }\n gl.uniform3fv(this.uniforms['uColorStops'], flat);\n gl.uniform1f(this.uniforms['uAmplitude'], this.amplitude());\n gl.uniform1f(this.uniforms['uBlend'], this.blend());\n }\n\n /** Explicit input wins; otherwise the theme's `--wr-aurora-stop-*` vars. */\n private resolveStops(): readonly string[] {\n const explicit = this.colorStops();\n if (explicit !== null) return explicit;\n const style = getComputedStyle(this.host.nativeElement);\n return [\n style.getPropertyValue('--wr-aurora-stop-1').trim() || '#5227ff',\n style.getPropertyValue('--wr-aurora-stop-2').trim() || '#7cff67',\n style.getPropertyValue('--wr-aurora-stop-3').trim() || '#5227ff',\n ];\n }\n\n private draw(time: number): void {\n const gl = this.gl;\n if (!gl) return;\n gl.uniform1f(this.uniforms['uTime'], time);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/fesm2022/ngwr-avatar.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, signal, computed, ViewEncapsulation, Component } from '@angular/core';
|
|
2
|
+
import { input, signal, effect, untracked, computed, ViewEncapsulation, Component } from '@angular/core';
|
|
3
|
+
import { useI18nText } from 'ngwr/i18n';
|
|
3
4
|
import { WrSpinner } from 'ngwr/spinner';
|
|
4
5
|
import { resolveCssSize } from 'ngwr/utils';
|
|
5
6
|
|
|
@@ -32,12 +33,14 @@ class WrAvatar {
|
|
|
32
33
|
url = input(null, /* @ts-ignore */
|
|
33
34
|
...(ngDevMode ? [{ debugName: "url" }] : /* istanbul ignore next */ []));
|
|
34
35
|
/**
|
|
35
|
-
* Alt text for the image.
|
|
36
|
+
* Alt text for the image. Falls back to `avatar.alt`, then `'Avatar'` — pass
|
|
37
|
+
* the person's name where you have it, since that is what a reader wants.
|
|
36
38
|
*
|
|
37
|
-
* @default
|
|
39
|
+
* @default null
|
|
38
40
|
*/
|
|
39
|
-
alt = input(
|
|
41
|
+
alt = input(null, /* @ts-ignore */
|
|
40
42
|
...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
|
|
43
|
+
resolvedAlt = useI18nText(this.alt, 'avatar.alt', 'Avatar');
|
|
41
44
|
/**
|
|
42
45
|
* Corner treatment. `rounded` (default) is a soft rounded square,
|
|
43
46
|
* `circle` is the classic profile avatar, `squircle` is the iOS look.
|
|
@@ -55,6 +58,24 @@ class WrAvatar {
|
|
|
55
58
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
56
59
|
loaded = signal(false, /* @ts-ignore */
|
|
57
60
|
...(ngDevMode ? [{ debugName: "loaded" }] : /* istanbul ignore next */ []));
|
|
61
|
+
/**
|
|
62
|
+
* Whether the image failed. Without this the spinner spun forever on a broken
|
|
63
|
+
* URL — the one state where an avatar is guaranteed to have projected initials
|
|
64
|
+
* worth showing instead.
|
|
65
|
+
*/
|
|
66
|
+
failed = signal(false, /* @ts-ignore */
|
|
67
|
+
...(ngDevMode ? [{ debugName: "failed" }] : /* istanbul ignore next */ []));
|
|
68
|
+
constructor() {
|
|
69
|
+
// A new URL is a new attempt: after a failure the fallback would otherwise
|
|
70
|
+
// stay put for an image that loads perfectly well.
|
|
71
|
+
effect(() => {
|
|
72
|
+
this.url();
|
|
73
|
+
untracked(() => {
|
|
74
|
+
this.loaded.set(false);
|
|
75
|
+
this.failed.set(false);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
58
79
|
resolved = computed(() => {
|
|
59
80
|
const result = resolveCssSize(this.size(), { defaultValue: DEFAULT_SIZE });
|
|
60
81
|
if (result.pxValue == null || result.pxValue <= 0) {
|
|
@@ -80,8 +101,11 @@ class WrAvatar {
|
|
|
80
101
|
onImageLoad() {
|
|
81
102
|
this.loaded.set(true);
|
|
82
103
|
}
|
|
104
|
+
onImageError() {
|
|
105
|
+
this.failed.set(true);
|
|
106
|
+
}
|
|
83
107
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
84
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", 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 <img\n
|
|
108
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", 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 });
|
|
85
109
|
}
|
|
86
110
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAvatar, decorators: [{
|
|
87
111
|
type: Component,
|
|
@@ -89,8 +113,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImpor
|
|
|
89
113
|
'[class]': 'classes()',
|
|
90
114
|
'[style.width]': 'cssSize()',
|
|
91
115
|
'[style.height]': 'cssSize()',
|
|
92
|
-
}, imports: [WrSpinner], template: "<ng-content />\n\n@if (url(); as src) {\n <img\n
|
|
93
|
-
}], propDecorators: { url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
116
|
+
}, imports: [WrSpinner], 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" }]
|
|
117
|
+
}], ctorParameters: () => [], propDecorators: { url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
94
118
|
|
|
95
119
|
/**
|
|
96
120
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-avatar.mjs","sources":["../../../projects/lib/avatar/avatar.ts","../../../projects/lib/avatar/avatar.html","../../../projects/lib/avatar/ngwr-avatar.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 { Component, ViewEncapsulation, computed, input, signal } from '@angular/core';\n\nimport { WrSpinner } from 'ngwr/spinner';\nimport { resolveCssSize, type ResolvedCssSize } from 'ngwr/utils';\n\nimport type { WrAvatarShape, WrAvatarSize } from './interfaces';\n\nconst DEFAULT_SIZE: WrAvatarSize = '6rem';\n\n/**\n * Image avatar with configurable corner treatment.\n *\n * A spinner is shown while the image loads, then crossfades in.\n *\n * @example\n * ```html\n * <wr-avatar url=\"/me.png\" alt=\"Roman\" size=\"3rem\" shape=\"circle\" />\n * <wr-avatar url=\"/me.png\" alt=\"Roman\" [size]=\"48\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/avatar\n */\n@Component({\n selector: 'wr-avatar',\n templateUrl: './avatar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[style.width]': 'cssSize()',\n '[style.height]': 'cssSize()',\n },\n imports: [WrSpinner],\n})\nexport class WrAvatar {\n /**\n * Image URL. When unset, only projected content (e.g. initials) renders.\n *\n * @default null\n */\n readonly url = input<string | null>(null);\n\n /**\n * Alt text for the image.\n *\n * @default
|
|
1
|
+
{"version":3,"file":"ngwr-avatar.mjs","sources":["../../../projects/lib/avatar/avatar.ts","../../../projects/lib/avatar/avatar.html","../../../projects/lib/avatar/ngwr-avatar.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 { Component, ViewEncapsulation, computed, effect, input, signal, untracked } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrSpinner } from 'ngwr/spinner';\nimport { resolveCssSize, type ResolvedCssSize } from 'ngwr/utils';\n\nimport type { WrAvatarShape, WrAvatarSize } from './interfaces';\n\nconst DEFAULT_SIZE: WrAvatarSize = '6rem';\n\n/**\n * Image avatar with configurable corner treatment.\n *\n * A spinner is shown while the image loads, then crossfades in.\n *\n * @example\n * ```html\n * <wr-avatar url=\"/me.png\" alt=\"Roman\" size=\"3rem\" shape=\"circle\" />\n * <wr-avatar url=\"/me.png\" alt=\"Roman\" [size]=\"48\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/avatar\n */\n@Component({\n selector: 'wr-avatar',\n templateUrl: './avatar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[style.width]': 'cssSize()',\n '[style.height]': 'cssSize()',\n },\n imports: [WrSpinner],\n})\nexport class WrAvatar {\n /**\n * Image URL. When unset, only projected content (e.g. initials) renders.\n *\n * @default null\n */\n readonly url = input<string | null>(null);\n\n /**\n * Alt text for the image. Falls back to `avatar.alt`, then `'Avatar'` — pass\n * the person's name where you have it, since that is what a reader wants.\n *\n * @default null\n */\n readonly alt = input<string | null>(null);\n\n protected readonly resolvedAlt = useI18nText(this.alt, 'avatar.alt', 'Avatar');\n\n /**\n * Corner treatment. `rounded` (default) is a soft rounded square,\n * `circle` is the classic profile avatar, `squircle` is the iOS look.\n *\n * @default 'rounded'\n */\n readonly shape = input<WrAvatarShape>('rounded');\n\n /**\n * Box size. See {@link WrAvatarSize} for accepted values.\n *\n * @default '6rem'\n */\n readonly size = input<WrAvatarSize>(DEFAULT_SIZE);\n\n protected readonly loaded = signal(false);\n\n /**\n * Whether the image failed. Without this the spinner spun forever on a broken\n * URL — the one state where an avatar is guaranteed to have projected initials\n * worth showing instead.\n */\n protected readonly failed = signal(false);\n\n constructor() {\n // A new URL is a new attempt: after a failure the fallback would otherwise\n // stay put for an image that loads perfectly well.\n effect(() => {\n this.url();\n untracked(() => {\n this.loaded.set(false);\n this.failed.set(false);\n });\n });\n }\n\n protected readonly resolved = computed<ResolvedCssSize>(() => {\n const result = resolveCssSize(this.size(), { defaultValue: DEFAULT_SIZE });\n if (result.pxValue == null || result.pxValue <= 0) {\n return resolveCssSize(DEFAULT_SIZE, { defaultValue: DEFAULT_SIZE });\n }\n return result;\n });\n\n protected readonly cssSize = computed(() => this.resolved().cssValue);\n protected readonly pxSize = computed(() => this.resolved().pxValue);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-avatar'];\n const shape = this.shape();\n if (shape !== 'rounded') parts.push(`wr-avatar--${shape}`);\n if (this.loaded()) parts.push('wr-avatar--loaded');\n return parts.join(' ');\n });\n\n protected onImageLoad(): void {\n this.loaded.set(true);\n }\n\n protected onImageError(): void {\n this.failed.set(true);\n }\n}\n","<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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|