ngwr 14.8.0 → 14.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -332
- package/alert/styles/_index.scss +10 -0
- package/avatar/styles/_index.scss +18 -7
- package/badge/styles/_index.scss +7 -0
- package/badge/styles/_tag.scss +7 -1
- package/button/styles/_index.scss +6 -0
- package/cascader/styles/_rules.scss +1 -1
- package/checkbox/styles/_index.scss +4 -0
- package/command-palette/styles/_index.scss +1 -1
- package/divider/styles/_index.scss +2 -0
- package/editor/styles/_index.scss +441 -0
- package/fesm2022/ngwr-action-sheet-testing.mjs.map +1 -1
- package/fesm2022/ngwr-action-sheet.mjs +3 -3
- package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
- package/fesm2022/ngwr-affix.mjs +3 -3
- package/fesm2022/ngwr-affix.mjs.map +1 -1
- package/fesm2022/ngwr-alert.mjs +3 -3
- package/fesm2022/ngwr-alert.mjs.map +1 -1
- package/fesm2022/ngwr-anchor.mjs +3 -3
- package/fesm2022/ngwr-anchor.mjs.map +1 -1
- package/fesm2022/ngwr-aurora.mjs +3 -3
- package/fesm2022/ngwr-aurora.mjs.map +1 -1
- package/fesm2022/ngwr-avatar.mjs +3 -3
- package/fesm2022/ngwr-avatar.mjs.map +1 -1
- package/fesm2022/ngwr-back-top.mjs +3 -3
- package/fesm2022/ngwr-back-top.mjs.map +1 -1
- package/fesm2022/ngwr-badge.mjs +28 -13
- package/fesm2022/ngwr-badge.mjs.map +1 -1
- package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-bar-chart.mjs +3 -3
- package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text.mjs +3 -3
- package/fesm2022/ngwr-blur-text.mjs.map +1 -1
- package/fesm2022/ngwr-border-glow-testing.mjs.map +1 -1
- package/fesm2022/ngwr-border-glow.mjs +3 -3
- package/fesm2022/ngwr-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-burger.mjs +3 -3
- package/fesm2022/ngwr-burger.mjs.map +1 -1
- package/fesm2022/ngwr-button-testing.mjs.map +1 -1
- package/fesm2022/ngwr-button.mjs +6 -6
- package/fesm2022/ngwr-button.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
- package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-calendar.mjs +3 -3
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-card.mjs +9 -9
- package/fesm2022/ngwr-card.mjs.map +1 -1
- package/fesm2022/ngwr-carousel-testing.mjs.map +1 -1
- package/fesm2022/ngwr-carousel.mjs +6 -6
- package/fesm2022/ngwr-carousel.mjs.map +1 -1
- package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +4 -4
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +6 -6
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text.mjs +3 -3
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-click-spark.mjs +3 -3
- package/fesm2022/ngwr-click-spark.mjs.map +1 -1
- package/fesm2022/ngwr-clipboard.mjs +3 -3
- package/fesm2022/ngwr-clipboard.mjs.map +1 -1
- package/fesm2022/ngwr-collapse-testing.mjs.map +1 -1
- package/fesm2022/ngwr-collapse.mjs +9 -9
- package/fesm2022/ngwr-collapse.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +6 -6
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette-testing.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette.mjs +3 -3
- package/fesm2022/ngwr-command-palette.mjs.map +1 -1
- package/fesm2022/ngwr-compare.mjs +3 -3
- package/fesm2022/ngwr-compare.mjs.map +1 -1
- package/fesm2022/ngwr-confetti.mjs +3 -3
- package/fesm2022/ngwr-confetti.mjs.map +1 -1
- package/fesm2022/ngwr-config.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu.mjs +12 -12
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-cookie.mjs +3 -3
- package/fesm2022/ngwr-cookie.mjs.map +1 -1
- package/fesm2022/ngwr-counter.mjs +6 -6
- package/fesm2022/ngwr-counter.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
- package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
- package/fesm2022/ngwr-date-adapters-luxon.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +21 -21
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-date.mjs +3 -3
- package/fesm2022/ngwr-date.mjs.map +1 -1
- package/fesm2022/ngwr-decrypt-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-decrypt-text.mjs +3 -3
- package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
- package/fesm2022/ngwr-density.mjs +6 -6
- package/fesm2022/ngwr-density.mjs.map +1 -1
- package/fesm2022/ngwr-descriptions.mjs +6 -6
- package/fesm2022/ngwr-descriptions.mjs.map +1 -1
- package/fesm2022/ngwr-dialog-testing.mjs.map +1 -1
- package/fesm2022/ngwr-dialog.mjs +15 -15
- package/fesm2022/ngwr-dialog.mjs.map +1 -1
- package/fesm2022/ngwr-directives.mjs +12 -12
- package/fesm2022/ngwr-directives.mjs.map +1 -1
- package/fesm2022/ngwr-divider.mjs +3 -3
- package/fesm2022/ngwr-divider.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart.mjs +3 -3
- package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +6 -6
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-drawer-testing.mjs.map +1 -1
- package/fesm2022/ngwr-drawer.mjs +18 -18
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown-testing.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +9 -9
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-editor-testing.mjs +568 -0
- package/fesm2022/ngwr-editor-testing.mjs.map +1 -0
- package/fesm2022/ngwr-editor.mjs +2601 -0
- package/fesm2022/ngwr-editor.mjs.map +1 -0
- package/fesm2022/ngwr-empty.mjs +3 -3
- package/fesm2022/ngwr-empty.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar.mjs +6 -6
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text.mjs +3 -3
- package/fesm2022/ngwr-falling-text.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload-testing.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload.mjs +3 -3
- package/fesm2022/ngwr-file-upload.mjs.map +1 -1
- package/fesm2022/ngwr-form-testing.mjs.map +1 -1
- package/fesm2022/ngwr-form.mjs +9 -9
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
- package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
- package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
- package/fesm2022/ngwr-gauge.mjs +3 -3
- package/fesm2022/ngwr-gauge.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text.mjs +3 -3
- package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text.mjs +3 -3
- package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
- package/fesm2022/ngwr-graph-testing.mjs.map +1 -1
- package/fesm2022/ngwr-graph.mjs +6 -6
- package/fesm2022/ngwr-graph.mjs.map +1 -1
- package/fesm2022/ngwr-hotkey.mjs +6 -6
- package/fesm2022/ngwr-hotkey.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ar.mjs +29 -0
- package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-cs.mjs +29 -0
- package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-de.mjs +29 -0
- package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +34 -0
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-es.mjs +29 -0
- package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-fr.mjs +29 -0
- package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-he.mjs +29 -0
- package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-hi.mjs +29 -0
- package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-id.mjs +29 -0
- package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-it.mjs +29 -0
- package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ja.mjs +29 -0
- package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ko.mjs +29 -0
- package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-nl.mjs +29 -0
- package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pl.mjs +29 -0
- package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pt.mjs +29 -0
- package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +29 -0
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-sv.mjs +29 -0
- package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-tr.mjs +29 -0
- package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-uk.mjs +29 -0
- package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-vi.mjs +29 -0
- package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh-TW.mjs +29 -0
- package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh.mjs +29 -0
- package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
- package/fesm2022/ngwr-i18n.mjs +9 -9
- package/fesm2022/ngwr-i18n.mjs.map +1 -1
- package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
- package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
- package/fesm2022/ngwr-icon.mjs +6 -6
- package/fesm2022/ngwr-icon.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper.mjs +3 -3
- package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
- package/fesm2022/ngwr-input-number-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input-number.mjs +3 -3
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp.mjs +3 -3
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-input-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input.mjs +15 -15
- package/fesm2022/ngwr-input.mjs.map +1 -1
- package/fesm2022/ngwr-keyboard.mjs +3 -3
- package/fesm2022/ngwr-keyboard.mjs.map +1 -1
- package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
- package/fesm2022/ngwr-knob.mjs +3 -3
- package/fesm2022/ngwr-knob.mjs.map +1 -1
- package/fesm2022/ngwr-layout.mjs +15 -15
- package/fesm2022/ngwr-layout.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox-testing.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox.mjs +3 -3
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart.mjs +3 -3
- package/fesm2022/ngwr-line-chart.mjs.map +1 -1
- package/fesm2022/ngwr-list.mjs +6 -6
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar.mjs +6 -6
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-markdown-testing.mjs.map +1 -1
- package/fesm2022/ngwr-markdown.mjs +798 -17
- package/fesm2022/ngwr-markdown.mjs.map +1 -1
- package/fesm2022/ngwr-marquee-testing.mjs.map +1 -1
- package/fesm2022/ngwr-marquee.mjs +3 -3
- package/fesm2022/ngwr-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-media.mjs +3 -3
- package/fesm2022/ngwr-media.mjs.map +1 -1
- package/fesm2022/ngwr-mention-testing.mjs.map +1 -1
- package/fesm2022/ngwr-mention.mjs +6 -6
- package/fesm2022/ngwr-mention.mjs.map +1 -1
- package/fesm2022/ngwr-meta.mjs +6 -6
- package/fesm2022/ngwr-meta.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group.mjs +3 -3
- package/fesm2022/ngwr-meter-group.mjs.map +1 -1
- package/fesm2022/ngwr-overlay.mjs +6 -6
- package/fesm2022/ngwr-overlay.mjs.map +1 -1
- package/fesm2022/ngwr-page-header.mjs +3 -3
- package/fesm2022/ngwr-page-header.mjs.map +1 -1
- package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +3 -3
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-pipes.mjs +21 -21
- package/fesm2022/ngwr-pipes.mjs.map +1 -1
- package/fesm2022/ngwr-platform.mjs +9 -9
- package/fesm2022/ngwr-platform.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm-testing.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm.mjs +6 -6
- package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
- package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
- package/fesm2022/ngwr-popover.mjs +12 -12
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-progress.mjs +3 -3
- package/fesm2022/ngwr-progress.mjs.map +1 -1
- package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
- package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -1
- package/fesm2022/ngwr-qr.mjs +3 -3
- package/fesm2022/ngwr-qr.mjs.map +1 -1
- package/fesm2022/ngwr-radio-testing.mjs.map +1 -1
- package/fesm2022/ngwr-radio.mjs +6 -6
- package/fesm2022/ngwr-radio.mjs.map +1 -1
- package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
- package/fesm2022/ngwr-rating.mjs +3 -3
- package/fesm2022/ngwr-rating.mjs.map +1 -1
- package/fesm2022/ngwr-result.mjs +12 -12
- package/fesm2022/ngwr-result.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text.mjs +3 -3
- package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
- package/fesm2022/ngwr-schema-form.mjs +3 -3
- package/fesm2022/ngwr-schema-form.mjs.map +1 -1
- package/fesm2022/ngwr-scroll.mjs +3 -3
- package/fesm2022/ngwr-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
- package/fesm2022/ngwr-segmented.mjs +3 -3
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select-testing.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +12 -12
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text.mjs +6 -6
- package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
- package/fesm2022/ngwr-sidebar.mjs +3 -3
- package/fesm2022/ngwr-sidebar.mjs.map +1 -1
- package/fesm2022/ngwr-skeleton.mjs +3 -3
- package/fesm2022/ngwr-skeleton.mjs.map +1 -1
- package/fesm2022/ngwr-slider-testing.mjs.map +1 -1
- package/fesm2022/ngwr-slider.mjs +3 -3
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline-testing.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline.mjs +3 -3
- package/fesm2022/ngwr-sparkline.mjs.map +1 -1
- package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -1
- package/fesm2022/ngwr-speed-dial.mjs +3 -3
- package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
- package/fesm2022/ngwr-spinner.mjs +3 -3
- package/fesm2022/ngwr-spinner.mjs.map +1 -1
- package/fesm2022/ngwr-splash-cursor-testing.mjs.map +1 -1
- package/fesm2022/ngwr-splash-cursor.mjs +3 -3
- package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
- package/fesm2022/ngwr-split-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-split-text.mjs +3 -3
- package/fesm2022/ngwr-split-text.mjs.map +1 -1
- package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
- package/fesm2022/ngwr-splitter.mjs +3 -3
- package/fesm2022/ngwr-splitter.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card-testing.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card.mjs +6 -6
- package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-squircle.mjs +6 -6
- package/fesm2022/ngwr-squircle.mjs.map +1 -1
- package/fesm2022/ngwr-star-border-testing.mjs.map +1 -1
- package/fesm2022/ngwr-star-border.mjs +3 -3
- package/fesm2022/ngwr-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-statistic.mjs +9 -9
- package/fesm2022/ngwr-statistic.mjs.map +1 -1
- package/fesm2022/ngwr-stepper-testing.mjs.map +1 -1
- package/fesm2022/ngwr-stepper.mjs +6 -6
- package/fesm2022/ngwr-stepper.mjs.map +1 -1
- package/fesm2022/ngwr-storage.mjs +3 -3
- package/fesm2022/ngwr-storage.mjs.map +1 -1
- package/fesm2022/ngwr-switch-testing.mjs.map +1 -1
- package/fesm2022/ngwr-switch.mjs +3 -3
- package/fesm2022/ngwr-switch.mjs.map +1 -1
- package/fesm2022/ngwr-table-testing.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +18 -18
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-router.mjs +3 -3
- package/fesm2022/ngwr-tabs-router.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +6 -6
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-textarea-testing.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +3 -3
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-theme.mjs +3 -3
- package/fesm2022/ngwr-theme.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card.mjs +6 -6
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-timeline.mjs +6 -6
- package/fesm2022/ngwr-timeline.mjs.map +1 -1
- package/fesm2022/ngwr-toast-testing.mjs.map +1 -1
- package/fesm2022/ngwr-toast.mjs +9 -9
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-toolbar.mjs +3 -3
- package/fesm2022/ngwr-toolbar.mjs.map +1 -1
- package/fesm2022/ngwr-tour-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tour.mjs +6 -6
- package/fesm2022/ngwr-tour.mjs.map +1 -1
- package/fesm2022/ngwr-transfer-testing.mjs.map +1 -1
- package/fesm2022/ngwr-transfer.mjs +3 -3
- package/fesm2022/ngwr-transfer.mjs.map +1 -1
- package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +3 -3
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter.mjs +3 -3
- package/fesm2022/ngwr-typewriter.mjs.map +1 -1
- package/fesm2022/ngwr-typography.mjs +7 -3
- package/fesm2022/ngwr-typography.mjs.map +1 -1
- package/fesm2022/ngwr-utils.mjs.map +1 -1
- package/fesm2022/ngwr-validators.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
- package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-waves-testing.mjs.map +1 -1
- package/fesm2022/ngwr-waves.mjs +3 -3
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/fesm2022/ngwr-window-testing.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +12 -12
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/form/styles/_index.scss +5 -0
- package/i18n/ar.json +29 -0
- package/i18n/cs.json +29 -0
- package/i18n/de.json +29 -0
- package/i18n/en.json +29 -0
- package/i18n/es.json +29 -0
- package/i18n/fr.json +29 -0
- package/i18n/he.json +29 -0
- package/i18n/hi.json +29 -0
- package/i18n/id.json +29 -0
- package/i18n/it.json +29 -0
- package/i18n/ja.json +29 -0
- package/i18n/ko.json +29 -0
- package/i18n/nl.json +29 -0
- package/i18n/pl.json +29 -0
- package/i18n/pt.json +29 -0
- package/i18n/ru.json +29 -0
- package/i18n/sv.json +29 -0
- package/i18n/tr.json +29 -0
- package/i18n/uk.json +29 -0
- package/i18n/vi.json +29 -0
- package/i18n/zh-TW.json +29 -0
- package/i18n/zh.json +29 -0
- package/input/styles/_index.scss +5 -1
- package/input-otp/styles/_index.scss +5 -5
- package/llms-full.txt +11 -1
- package/llms.txt +188 -132
- package/mcp/providers.js +2 -2
- package/mcp/server.js +1 -1
- package/overlay/styles/_arrow.scss +3 -0
- package/package.json +43 -2
- package/progress/styles/_index.scss +4 -0
- package/radio/styles/_index.scss +4 -1
- package/schematics/use/symbol-map.json +1 -0
- package/select/styles/_index.scss +3 -3
- package/sidebar/styles/_index.scss +10 -0
- package/skeleton/styles/_index.scss +3 -0
- package/skills/ngwr/SKILL.md +5 -5
- package/skills/ngwr/references/catalog.md +2 -0
- package/skills/ngwr/references/setup.md +3 -3
- package/styles.scss +1 -0
- package/table/styles/_index.scss +7 -0
- package/textarea/styles/_index.scss +12 -3
- package/theme/styles/_colors.scss +39 -13
- package/theme/styles/_contrast.scss +9 -7
- package/toast/styles/_index.scss +4 -0
- package/tree/styles/_index.scss +1 -1
- package/types/ngwr-badge.d.ts +22 -7
- package/types/ngwr-config.d.ts +12 -0
- package/types/ngwr-editor-testing.d.ts +378 -0
- package/types/ngwr-editor.d.ts +449 -0
- package/types/ngwr-markdown.d.ts +61 -2
- package/types/ngwr-typography.d.ts +4 -0
- package/types/ngwr-version.d.ts +1 -1
- package/typography/styles/_index.scss +16 -0
package/fesm2022/ngwr-affix.mjs
CHANGED
|
@@ -119,10 +119,10 @@ class WrAffix {
|
|
|
119
119
|
});
|
|
120
120
|
});
|
|
121
121
|
}
|
|
122
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
123
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.
|
|
122
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAffix, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
123
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: WrAffix, isStandalone: true, selector: "[wrAffix]", inputs: { offsetTop: { classPropertyName: "offsetTop", publicName: "wrAffixOffsetTop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { affixChange: "wrAffixChange" }, host: { properties: { "style.position": "\"sticky\"", "style.top.px": "offsetTop()" }, classAttribute: "wr-affix" }, ngImport: i0 });
|
|
124
124
|
}
|
|
125
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
125
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAffix, decorators: [{
|
|
126
126
|
type: Directive,
|
|
127
127
|
args: [{
|
|
128
128
|
selector: '[wrAffix]',
|
|
@@ -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 {\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 // NOT `!entry.isIntersecting` on its own. A sentinel is outside\n // the root in TWO directions, and only one of them means the\n // header has stuck: above the line because the page scrolled past\n // it, or below it because the host simply starts further down the\n // page than the first screen. The bare negation called both\n // \"affixed\", so any sticky element below the fold reported\n // `affixed = true` and painted `.wr-affix--active` on its very\n // first observer callback — before a pixel had scrolled — and\n // emitted a transition that never happened.\n //\n // `rootBounds.top` is the offset line (the negative `rootMargin`\n // above moves it), so a sentinel above it has genuinely gone by.\n const rootTop = entry.rootBounds?.top ?? offset;\n const next = !entry.isIntersecting && entry.boundingClientRect.top < rootTop;\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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
|
|
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 // NOT `!entry.isIntersecting` on its own. A sentinel is outside\n // the root in TWO directions, and only one of them means the\n // header has stuck: above the line because the page scrolled past\n // it, or below it because the host simply starts further down the\n // page than the first screen. The bare negation called both\n // \"affixed\", so any sticky element below the fold reported\n // `affixed = true` and painted `.wr-affix--active` on its very\n // first observer callback — before a pixel had scrolled — and\n // emitted a transition that never happened.\n //\n // `rootBounds.top` is the offset line (the negative `rootMargin`\n // above moves it), so a sentinel above it has genuinely gone by.\n const rootTop = entry.rootBounds?.top ?? offset;\n const next = !entry.isIntersecting && entry.boundingClientRect.top < rootTop;\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-alert.mjs
CHANGED
|
@@ -89,10 +89,10 @@ class WrAlert {
|
|
|
89
89
|
this.dismissed.set(true);
|
|
90
90
|
this.closed.emit();
|
|
91
91
|
}
|
|
92
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
93
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
92
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
93
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: WrAlert, isStandalone: true, selector: "wr-alert", inputs: { closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, iconName: { classPropertyName: "iconName", publicName: "iconName", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { properties: { "class": "classes()", "attr.role": "liveRole()", "attr.aria-live": "liveLevel()" } }, ngImport: i0, template: "@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n <!-- An OCTAGON, and the shape is the point. `danger` used to be a\n circle holding a bar over a dot, which is the vertical mirror of\n the `i` the @default branch draws \u2014 at the rendered 18px the two\n differ only by where a 1.5px gap sits. The stop-sign silhouette\n reads at that size and survives greyscale, which a mirrored gap\n does not. -->\n @case ('danger') {\n <path\n d=\"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z\"\n />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n <!-- A bar, not the exclamation mark `danger` used to carry: `neutral`\n emitted that glyph byte for byte. The icon is the whole difference\n between these two, because what the component actually paints \u2014\n `danger-ink` #a32a33 (L 0.0968) against `on-surface-muted` #5f6c7d\n (L 0.1464) on tints 1.036:1 apart \u2014 is a hue difference and little\n else. -->\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n </div>\n\n @if (closable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
94
94
|
}
|
|
95
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
95
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAlert, decorators: [{
|
|
96
96
|
type: Component,
|
|
97
97
|
args: [{ selector: 'wr-alert', imports: [WrIcon], encapsulation: ViewEncapsulation.None, host: {
|
|
98
98
|
'[class]': 'classes()',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-alert.mjs","sources":["../../../projects/lib/alert/alert.ts","../../../projects/lib/alert/alert.html","../../../projects/lib/alert/ngwr-alert.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input, output, signal } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\n\nimport type { WrAlertType } from './interfaces';\n\n/**\n * Inline status banner. Use for feedback messages — saved/failed/notice etc.\n *\n * @example\n * ```html\n * <wr-alert title=\"Saved\" message=\"Your changes are live.\" type=\"success\" />\n * <wr-alert title=\"Failed\" type=\"danger\" closable (closed)=\"onClose()\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/alert\n */\n@Component({\n selector: 'wr-alert',\n templateUrl: './alert.html',\n imports: [WrIcon],\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.role]': 'liveRole()',\n '[attr.aria-live]': 'liveLevel()',\n },\n})\nexport class WrAlert {\n /** Accessible name. Falls back to `alert.close`, then `'Close alert'`. */\n readonly closeLabel = input<string | null>(null);\n\n protected readonly resolvedCloseLabel = useI18nText(this.closeLabel, 'alert.close', 'Close alert');\n\n /**\n * Optional headline shown at the top of the alert.\n *\n * @default null\n */\n readonly title = input<string | null>(null);\n\n /**\n * Visual variant.\n *\n * @default 'info'\n */\n readonly type = input<WrAlertType>('info');\n\n /**\n * Override the default per-type icon with any ngwr icon name.\n *\n * @default null\n */\n readonly iconName = input<WrIconName | null>(null);\n\n /**\n * Optional secondary message rendered below the title.\n *\n * @default null\n */\n readonly message = input<string | null>(null);\n\n /**\n * When `true`, renders a leading status icon matching the `type`.\n * Pass `false` to hide. Ignored when `iconName` is set.\n *\n * @default true\n */\n readonly icon = input(true, { transform: coerceBooleanProperty });\n\n /**\n * When `true`, renders a close button.\n *\n * @default false\n */\n readonly closable = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Emitted when the user dismisses the alert via the close button.\n */\n readonly closed = output<void>();\n\n protected readonly dismissed = signal(false);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-alert', `wr-alert--${this.type()}`];\n if (this.dismissed()) parts.push('wr-alert--dismissed');\n return parts.join(' ');\n });\n\n /** Escalate role/aria-live for danger/warning alerts. */\n protected readonly liveRole = computed(() =>\n this.dismissed() ? null : this.type() === 'danger' ? 'alert' : 'status'\n );\n protected readonly liveLevel = computed(() =>\n this.dismissed() ? null : this.type() === 'danger' || this.type() === 'warning' ? 'assertive' : 'polite'\n );\n\n protected onClose(): void {\n this.dismissed.set(true);\n this.closed.emit();\n }\n}\n","@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n <!-- An OCTAGON, and the shape is the point. `danger` used to be a\n circle holding a bar over a dot, which is the vertical mirror of\n the `i` the @default branch draws — at the rendered 18px the two\n differ only by where a 1.5px gap sits. The stop-sign silhouette\n reads at that size and survives greyscale, which a mirrored gap\n does not. -->\n @case ('danger') {\n <path\n d=\"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z\"\n />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n <!-- A bar, not the exclamation mark `danger` used to carry: `neutral`\n emitted that glyph byte for byte. The icon is the whole difference\n between these two, because what the component actually paints —\n `danger-ink` #a32a33 (L 0.0968) against `on-surface-muted` #5f6c7d\n (L 0.1464) on tints 1.036:1 apart — is a hue difference and little\n else. -->\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n </div>\n\n @if (closable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ngwr-alert.mjs","sources":["../../../projects/lib/alert/alert.ts","../../../projects/lib/alert/alert.html","../../../projects/lib/alert/ngwr-alert.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input, output, signal } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\n\nimport type { WrAlertType } from './interfaces';\n\n/**\n * Inline status banner. Use for feedback messages — saved/failed/notice etc.\n *\n * @example\n * ```html\n * <wr-alert title=\"Saved\" message=\"Your changes are live.\" type=\"success\" />\n * <wr-alert title=\"Failed\" type=\"danger\" closable (closed)=\"onClose()\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/alert\n */\n@Component({\n selector: 'wr-alert',\n templateUrl: './alert.html',\n imports: [WrIcon],\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.role]': 'liveRole()',\n '[attr.aria-live]': 'liveLevel()',\n },\n})\nexport class WrAlert {\n /** Accessible name. Falls back to `alert.close`, then `'Close alert'`. */\n readonly closeLabel = input<string | null>(null);\n\n protected readonly resolvedCloseLabel = useI18nText(this.closeLabel, 'alert.close', 'Close alert');\n\n /**\n * Optional headline shown at the top of the alert.\n *\n * @default null\n */\n readonly title = input<string | null>(null);\n\n /**\n * Visual variant.\n *\n * @default 'info'\n */\n readonly type = input<WrAlertType>('info');\n\n /**\n * Override the default per-type icon with any ngwr icon name.\n *\n * @default null\n */\n readonly iconName = input<WrIconName | null>(null);\n\n /**\n * Optional secondary message rendered below the title.\n *\n * @default null\n */\n readonly message = input<string | null>(null);\n\n /**\n * When `true`, renders a leading status icon matching the `type`.\n * Pass `false` to hide. Ignored when `iconName` is set.\n *\n * @default true\n */\n readonly icon = input(true, { transform: coerceBooleanProperty });\n\n /**\n * When `true`, renders a close button.\n *\n * @default false\n */\n readonly closable = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Emitted when the user dismisses the alert via the close button.\n */\n readonly closed = output<void>();\n\n protected readonly dismissed = signal(false);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-alert', `wr-alert--${this.type()}`];\n if (this.dismissed()) parts.push('wr-alert--dismissed');\n return parts.join(' ');\n });\n\n /** Escalate role/aria-live for danger/warning alerts. */\n protected readonly liveRole = computed(() =>\n this.dismissed() ? null : this.type() === 'danger' ? 'alert' : 'status'\n );\n protected readonly liveLevel = computed(() =>\n this.dismissed() ? null : this.type() === 'danger' || this.type() === 'warning' ? 'assertive' : 'polite'\n );\n\n protected onClose(): void {\n this.dismissed.set(true);\n this.closed.emit();\n }\n}\n","@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n <!-- An OCTAGON, and the shape is the point. `danger` used to be a\n circle holding a bar over a dot, which is the vertical mirror of\n the `i` the @default branch draws — at the rendered 18px the two\n differ only by where a 1.5px gap sits. The stop-sign silhouette\n reads at that size and survives greyscale, which a mirrored gap\n does not. -->\n @case ('danger') {\n <path\n d=\"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z\"\n />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n <!-- A bar, not the exclamation mark `danger` used to carry: `neutral`\n emitted that glyph byte for byte. The icon is the whole difference\n between these two, because what the component actually paints —\n `danger-ink` #a32a33 (L 0.0968) against `on-surface-muted` #5f6c7d\n (L 0.1464) on tints 1.036:1 apart — is a hue difference and little\n else. -->\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n </div>\n\n @if (closable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n","/**\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
|
@@ -99,10 +99,10 @@ class WrAnchor {
|
|
|
99
99
|
this.scroll.to(`#${id}`, { offset: this.offset() });
|
|
100
100
|
this.activeId.set(id);
|
|
101
101
|
}
|
|
102
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
103
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
102
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAnchor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
103
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: WrAnchor, isStandalone: true, selector: "wr-anchor", inputs: { links: { classPropertyName: "links", publicName: "links", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, hitArea: { classPropertyName: "hitArea", publicName: "hitArea", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "resolvedAriaLabel()" }, classAttribute: "wr-anchor" }, ngImport: i0, template: "<ul class=\"wr-anchor__list\">\n @for (link of links(); track link.id) {\n <li class=\"wr-anchor__item\">\n <a\n class=\"wr-anchor__link\"\n [class.wr-anchor__link--active]=\"activeId() === link.id\"\n [attr.aria-current]=\"activeId() === link.id ? 'location' : null\"\n [href]=\"`#${link.id}`\"\n (click)=\"onClick(link.id, $event)\"\n >\n {{ link.label }}\n </a>\n @if (link.children?.length) {\n <ul class=\"wr-anchor__list wr-anchor__list--nested\">\n @for (child of link.children; track child.id) {\n <li class=\"wr-anchor__item\">\n <a\n class=\"wr-anchor__link\"\n [class.wr-anchor__link--active]=\"activeId() === child.id\"\n [attr.aria-current]=\"activeId() === child.id ? 'location' : null\"\n [href]=\"`#${child.id}`\"\n (click)=\"onClick(child.id, $event)\"\n >\n {{ child.label }}\n </a>\n </li>\n }\n </ul>\n }\n </li>\n }\n</ul>\n", encapsulation: i0.ViewEncapsulation.None });
|
|
104
104
|
}
|
|
105
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
105
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAnchor, decorators: [{
|
|
106
106
|
type: Component,
|
|
107
107
|
args: [{ selector: 'wr-anchor', encapsulation: ViewEncapsulation.None, host: { class: 'wr-anchor', role: 'navigation', '[attr.aria-label]': 'resolvedAriaLabel()' }, template: "<ul class=\"wr-anchor__list\">\n @for (link of links(); track link.id) {\n <li class=\"wr-anchor__item\">\n <a\n class=\"wr-anchor__link\"\n [class.wr-anchor__link--active]=\"activeId() === link.id\"\n [attr.aria-current]=\"activeId() === link.id ? 'location' : null\"\n [href]=\"`#${link.id}`\"\n (click)=\"onClick(link.id, $event)\"\n >\n {{ link.label }}\n </a>\n @if (link.children?.length) {\n <ul class=\"wr-anchor__list wr-anchor__list--nested\">\n @for (child of link.children; track child.id) {\n <li class=\"wr-anchor__item\">\n <a\n class=\"wr-anchor__link\"\n [class.wr-anchor__link--active]=\"activeId() === child.id\"\n [attr.aria-current]=\"activeId() === child.id ? 'location' : null\"\n [href]=\"`#${child.id}`\"\n (click)=\"onClick(child.id, $event)\"\n >\n {{ child.label }}\n </a>\n </li>\n }\n </ul>\n }\n </li>\n }\n</ul>\n" }]
|
|
108
108
|
}], ctorParameters: () => [], propDecorators: { links: [{ type: i0.Input, args: [{ isSignal: true, alias: "links", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], hitArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "hitArea", required: false }] }] } });
|
|
@@ -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 {\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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
|
|
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
|
@@ -294,10 +294,10 @@ class WrAurora {
|
|
|
294
294
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
295
295
|
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
296
296
|
}
|
|
297
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
298
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.
|
|
297
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAurora, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
298
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.7", 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%}\n"], encapsulation: i0.ViewEncapsulation.None });
|
|
299
299
|
}
|
|
300
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
300
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAurora, decorators: [{
|
|
301
301
|
type: Component,
|
|
302
302
|
args: [{ selector: 'wr-aurora', template: '<canvas #canvas class="wr-aurora__canvas" aria-hidden="true"></canvas>', encapsulation: ViewEncapsulation.None, host: { class: 'wr-aurora' }, styles: [".wr-aurora{--wr-aurora-stop-1: #6366f1;--wr-aurora-stop-2: #10b981;--wr-aurora-stop-3: #6366f1;position:absolute;inset:0;display:block;overflow:hidden;pointer-events:none;z-index:0}.wr-aurora__canvas{display:block;width:100%;height:100%}\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 }] }] } });
|
|
@@ -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\" 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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"}
|
|
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
|
@@ -169,10 +169,10 @@ class WrAvatar {
|
|
|
169
169
|
onImageError() {
|
|
170
170
|
this.failed.set(true);
|
|
171
171
|
}
|
|
172
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
173
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
172
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
173
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", 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()", "style.--wr-avatar-size": "cssSize()" } }, viewQueries: [{ propertyName: "img", first: true, predicate: ["img"], descendants: true, isSignal: true }], ngImport: i0, template: "<span class=\"wr-avatar__content\" [attr.aria-hidden]=\"fallbackHidden() ? 'true' : null\"><ng-content /></span>\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\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 });
|
|
174
174
|
}
|
|
175
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
175
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrAvatar, decorators: [{
|
|
176
176
|
type: Component,
|
|
177
177
|
args: [{ selector: 'wr-avatar', encapsulation: ViewEncapsulation.None, host: {
|
|
178
178
|
'[class]': 'classes()',
|
|
@@ -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 {\n Component,\n type ElementRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n input,\n signal,\n untracked,\n viewChild,\n} 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 * Projected content (typically initials) is the FALLBACK: it shows with no\n * `url`, while the image loads and after it fails, and leaves the paint once the\n * image has loaded. It is projected into a `.wr-avatar__content` wrapper, so a\n * `wr-avatar > …` child selector no longer reaches it. While it is there, no\n * spinner is drawn over it; with nothing projected, the spinner marks the\n * loading state instead. See `alt` for what a screen reader hears.\n *\n * Projected initials take the text size around the avatar, capped at\n * `--wr-avatar-initials-scale` (`0.375`) of the box, so they shrink only where\n * they would not fit: a 16px avatar in a 14px chip draws 6px letters, while a\n * `6rem` one keeps the surrounding size up to 36px and is capped only past it.\n * Anything projected that is sized in `em` follows the cap too — a `<wr-icon>`\n * at its default `1.2em` included — so pin a `px` or `rem` size on the projected\n * element, or override the hook, to keep it. A `font-size` rule on the avatar\n * itself still wins, unless it sits in a cascade layer (Tailwind v4's utilities\n * do), which ngwr's unlayered stylesheet beats whatever the selector.\n *\n * The initials are inert: `pointer-events: none` hands a click on them to whatever\n * holds the avatar, and `user-select: none` keeps them out of a text selection.\n *\n * @example\n * ```html\n * <wr-avatar url=\"/me.png\" alt=\"Roman\" size=\"3rem\" shape=\"circle\" />\n * <wr-avatar [url]=\"photo\" alt=\"Roman Khegay\" [size]=\"48\">RK</wr-avatar>\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 // What the stylesheet sizes projected initials against. Always px or rem: a\n // value `resolveCssSize` has no pixels for falls back to the default box.\n '[style.--wr-avatar-size]': 'cssSize()',\n },\n imports: [WrSpinner],\n})\nexport class WrAvatar {\n /**\n * Image URL. Projected content (e.g. initials) shows while it is unset,\n * loading or broken, and gives way once the image has loaded.\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 * With an `alt`, projected initials are hidden from assistive technology while\n * an image is in play, so the name is announced once. Without one, the image\n * carries only the generic name, so the initials stay announced beside it —\n * visually hidden once it has loaded, never dropped.\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. The resolved value is\n * published on the host as `--wr-avatar-size`.\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 private readonly img = viewChild<ElementRef<HTMLImageElement>>('img');\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 afterNextRender(() => this.adoptSettledImage());\n }\n\n /**\n * A prerendered `<img>` starts loading when the browser parses the HTML, and\n * `(load)` / `(error)` are only attached at hydration — so on a slow bundle the\n * image settles first, both events go nowhere, and the avatar sits on its\n * fallback over a photo it already has (or names a broken image it never\n * learns about). Only the FIRST render can race: every later `<img>` is\n * created on the client with its listeners in place before `src` is set.\n */\n private adoptSettledImage(): void {\n const img = this.img()?.nativeElement;\n if (!img?.complete || this.loaded() || this.failed()) return;\n\n if (img.naturalWidth > 0) {\n this.loaded.set(true);\n return;\n }\n\n // Zero wide is a broken image, or an SVG with no intrinsic size in an engine\n // that reports it as 0 — only the element can tell. Setting `src` to the\n // value it already has makes it fire `load` or `error` again, to listeners\n // that exist now.\n const src = img.getAttribute('src');\n if (src !== null) img.setAttribute('src', src);\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 /**\n * Whether the projected fallback is `aria-hidden`: an `<img>` is in the DOM\n * (loading or loaded) AND the consumer named it. Then the image's `alt` owns\n * the name, announced once and unchanged at the moment the photo arrives.\n * Without a real `alt` the image is only \"Avatar\", and hiding the initials\n * would drop the one thing that says who this is.\n *\n * The stylesheet keys on the same attribute once `--loaded`: a hidden fallback\n * leaves the paint through `visibility`, a named-by-initials one is clipped and\n * stays in the accessibility tree. While loading it is painted either way.\n */\n protected readonly fallbackHidden = computed(() => !!this.url() && !this.failed() && !!this.alt()?.trim());\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","<span class=\"wr-avatar__content\" [attr.aria-hidden]=\"fallbackHidden() ? 'true' : null\"><ng-content /></span>\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\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":";;;;;;AAAA;;;;;AAKG;AAqBH,MAAM,YAAY,GAAiB,MAAM;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BG;MAeU,QAAQ,CAAA;AACnB;;;;;AAKG;IACM,GAAG,GAAG,KAAK,CAAgB,IAAI;4EAAC;AAEzC;;;;;;;;;;AAUG;IACM,GAAG,GAAG,KAAK,CAAgB,IAAI;4EAAC;IAEtB,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,QAAQ,CAAC;AAE9E;;;;;AAKG;IACM,KAAK,GAAG,KAAK,CAAgB,SAAS;8EAAC;AAEhD;;;;;AAKG;IACM,IAAI,GAAG,KAAK,CAAe,YAAY;6EAAC;IAE9B,MAAM,GAAG,MAAM,CAAC,KAAK;+EAAC;AAEzC;;;;AAIG;IACgB,MAAM,GAAG,MAAM,CAAC,KAAK;+EAAC;IAExB,GAAG,GAAG,SAAS,CAA+B,KAAK;4EAAC;AAErE,IAAA,WAAA,GAAA;;;QAGE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,GAAG,EAAE;YACV,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACtB,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACxB,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;QAEF,eAAe,CAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACjD;AAEA;;;;;;;AAOG;IACK,iBAAiB,GAAA;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,aAAa;AACrC,QAAA,IAAI,CAAC,GAAG,EAAE,QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE;YAAE;AAEtD,QAAA,IAAI,GAAG,CAAC,YAAY,GAAG,CAAC,EAAE;AACxB,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YACrB;QACF;;;;;QAMA,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC;QACnC,IAAI,GAAG,KAAK,IAAI;AAAE,YAAA,GAAG,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC;IAChD;AAEmB,IAAA,QAAQ,GAAG,QAAQ,CAAkB,MAAK;AAC3D,QAAA,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;AAC1E,QAAA,IAAI,MAAM,CAAC,OAAO,IAAI,IAAI,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,EAAE;YACjD,OAAO,cAAc,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;QACrE;AACA,QAAA,OAAO,MAAM;IACf,CAAC;iFAAC;AAEF;;;;;;;;;;AAUG;IACgB,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE;uFAAC;IAEvF,OAAO,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ;gFAAC;IAClD,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO;+EAAC;AAEhD,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,MAAM,KAAK,GAAG,CAAC,WAAW,CAAC;AAC3B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;QAC1B,IAAI,KAAK,KAAK,SAAS;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAA,CAAE,CAAC;QAC1D,IAAI,IAAI,CAAC,MAAM,EAAE;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC;AAClD,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IACxB,CAAC;gFAAC;IAEQ,WAAW,GAAA;AACnB,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;IACvB;IAEU,YAAY,GAAA;AACpB,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;IACvB;uGAhIW,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAR,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,aAAA,EAAA,WAAA,EAAA,cAAA,EAAA,WAAA,EAAA,wBAAA,EAAA,WAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,KAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,KAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECzErB,2gBAqBA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDkDY,SAAS,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,WAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAER,QAAQ,EAAA,UAAA,EAAA,CAAA;kBAdpB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,WAAW,EAAA,aAAA,EAEN,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B;AACJ,wBAAA,SAAS,EAAE,WAAW;AACtB,wBAAA,eAAe,EAAE,WAAW;AAC5B,wBAAA,gBAAgB,EAAE,WAAW;;;AAG7B,wBAAA,0BAA0B,EAAE,WAAW;qBACxC,EAAA,OAAA,EACQ,CAAC,SAAS,CAAC,EAAA,QAAA,EAAA,2gBAAA,EAAA;ybAmD2C,KAAK,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AE1HtE;;AAEG;;;;"}
|
|
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 {\n Component,\n type ElementRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n input,\n signal,\n untracked,\n viewChild,\n} 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 * Projected content (typically initials) is the FALLBACK: it shows with no\n * `url`, while the image loads and after it fails, and leaves the paint once the\n * image has loaded. It is projected into a `.wr-avatar__content` wrapper, so a\n * `wr-avatar > …` child selector no longer reaches it. While it is there, no\n * spinner is drawn over it; with nothing projected, the spinner marks the\n * loading state instead. See `alt` for what a screen reader hears.\n *\n * Projected initials take the text size around the avatar, capped at\n * `--wr-avatar-initials-scale` (`0.375`) of the box, so they shrink only where\n * they would not fit: a 16px avatar in a 14px chip draws 6px letters, while a\n * `6rem` one keeps the surrounding size up to 36px and is capped only past it.\n * Anything projected that is sized in `em` follows the cap too — a `<wr-icon>`\n * at its default `1.2em` included — so pin a `px` or `rem` size on the projected\n * element, or override the hook, to keep it. A `font-size` rule on the avatar\n * itself still wins, unless it sits in a cascade layer (Tailwind v4's utilities\n * do), which ngwr's unlayered stylesheet beats whatever the selector.\n *\n * The initials are inert: `pointer-events: none` hands a click on them to whatever\n * holds the avatar, and `user-select: none` keeps them out of a text selection.\n *\n * @example\n * ```html\n * <wr-avatar url=\"/me.png\" alt=\"Roman\" size=\"3rem\" shape=\"circle\" />\n * <wr-avatar [url]=\"photo\" alt=\"Roman Khegay\" [size]=\"48\">RK</wr-avatar>\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 // What the stylesheet sizes projected initials against. Always px or rem: a\n // value `resolveCssSize` has no pixels for falls back to the default box.\n '[style.--wr-avatar-size]': 'cssSize()',\n },\n imports: [WrSpinner],\n})\nexport class WrAvatar {\n /**\n * Image URL. Projected content (e.g. initials) shows while it is unset,\n * loading or broken, and gives way once the image has loaded.\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 * With an `alt`, projected initials are hidden from assistive technology while\n * an image is in play, so the name is announced once. Without one, the image\n * carries only the generic name, so the initials stay announced beside it —\n * visually hidden once it has loaded, never dropped.\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. The resolved value is\n * published on the host as `--wr-avatar-size`.\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 private readonly img = viewChild<ElementRef<HTMLImageElement>>('img');\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 afterNextRender(() => this.adoptSettledImage());\n }\n\n /**\n * A prerendered `<img>` starts loading when the browser parses the HTML, and\n * `(load)` / `(error)` are only attached at hydration — so on a slow bundle the\n * image settles first, both events go nowhere, and the avatar sits on its\n * fallback over a photo it already has (or names a broken image it never\n * learns about). Only the FIRST render can race: every later `<img>` is\n * created on the client with its listeners in place before `src` is set.\n */\n private adoptSettledImage(): void {\n const img = this.img()?.nativeElement;\n if (!img?.complete || this.loaded() || this.failed()) return;\n\n if (img.naturalWidth > 0) {\n this.loaded.set(true);\n return;\n }\n\n // Zero wide is a broken image, or an SVG with no intrinsic size in an engine\n // that reports it as 0 — only the element can tell. Setting `src` to the\n // value it already has makes it fire `load` or `error` again, to listeners\n // that exist now.\n const src = img.getAttribute('src');\n if (src !== null) img.setAttribute('src', src);\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 /**\n * Whether the projected fallback is `aria-hidden`: an `<img>` is in the DOM\n * (loading or loaded) AND the consumer named it. Then the image's `alt` owns\n * the name, announced once and unchanged at the moment the photo arrives.\n * Without a real `alt` the image is only \"Avatar\", and hiding the initials\n * would drop the one thing that says who this is.\n *\n * The stylesheet keys on the same attribute once `--loaded`: a hidden fallback\n * leaves the paint through `visibility`, a named-by-initials one is clipped and\n * stays in the accessibility tree. While loading it is painted either way.\n */\n protected readonly fallbackHidden = computed(() => !!this.url() && !this.failed() && !!this.alt()?.trim());\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","<span class=\"wr-avatar__content\" [attr.aria-hidden]=\"fallbackHidden() ? 'true' : null\"><ng-content /></span>\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\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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"}
|
|
@@ -74,10 +74,10 @@ class WrBackTop {
|
|
|
74
74
|
onClick() {
|
|
75
75
|
this.scroll.toTop({ offset: this.offset() });
|
|
76
76
|
}
|
|
77
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
78
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.
|
|
77
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBackTop, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
78
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: WrBackTop, isStandalone: true, selector: "wr-back-top", inputs: { visibilityThreshold: { classPropertyName: "visibilityThreshold", publicName: "visibilityThreshold", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.aria-hidden": "!visible()", "attr.inert": "visible() ? null : ''" } }, ngImport: i0, template: "<button type=\"button\" class=\"wr-back-top__button\" [attr.aria-label]=\"resolvedAriaLabel()\" (click)=\"onClick()\">\n <!-- The arrow is FALLBACK content: rendered next to a projected icon rather\n than instead of it, the documented custom-icon example put two glyphs in\n one 44px circle. -->\n <ng-content>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" aria-hidden=\"true\">\n <path\n d=\"M9 4 L9 14 M4 9 L9 4 L14 9\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </ng-content>\n</button>\n", encapsulation: i0.ViewEncapsulation.None });
|
|
79
79
|
}
|
|
80
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
80
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBackTop, decorators: [{
|
|
81
81
|
type: Component,
|
|
82
82
|
args: [{ selector: 'wr-back-top', encapsulation: ViewEncapsulation.None, host: {
|
|
83
83
|
'[class]': 'classes()',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-back-top.mjs","sources":["../../../projects/lib/back-top/back-top.ts","../../../projects/lib/back-top/back-top.html","../../../projects/lib/back-top/ngwr-back-top.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 { Component, DestroyRef, NgZone, ViewEncapsulation, computed, inject, input, signal } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrPlatform } from 'ngwr/platform';\nimport { WrScroll } from 'ngwr/scroll';\n\n/**\n * Pinned floating button that scrolls the page back to the top. Appears\n * once the user has scrolled past `visibilityThreshold` pixels.\n *\n * @example\n * ```html\n * <wr-back-top />\n *\n * <wr-back-top visibilityThreshold=\"600\" [offset]=\"80\">\n * <svg>…custom icon…</svg>\n * </wr-back-top>\n * ```\n *\n * @see https://ngwr.dev/reference/components/back-top\n */\n@Component({\n selector: 'wr-back-top',\n templateUrl: './back-top.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.aria-hidden]': '!visible()',\n // `aria-hidden` alone left a 44px button that focus still landed on: invisible\n // (opacity 0) but in the tab order, and unannounceable once it got there.\n // `inert` is what actually takes it out of both.\n '[attr.inert]': \"visible() ? null : ''\",\n },\n})\nexport class WrBackTop {\n /** Show the button once `window.scrollY` exceeds this many pixels. @default 400 */\n readonly visibilityThreshold = input(400, {\n transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 400)),\n });\n\n /** Pixel offset subtracted from the scroll target — for sticky headers. @default 0 */\n readonly offset = input(0, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 0)) });\n\n /** Accessible label for the button. Falls back to `backTop.label`, then `'Back to top'`. */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'backTop.label', 'Back to top');\n\n protected readonly visible = signal(false);\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 protected readonly classes = computed(() => {\n const parts = ['wr-back-top'];\n if (this.visible()) parts.push('wr-back-top--visible');\n return parts.join(' ');\n });\n\n constructor() {\n if (!this.platform.isBrowser) return;\n const handler = (): void => {\n const should = window.scrollY > this.visibilityThreshold();\n if (should !== this.visible()) this.zone.run(() => this.visible.set(should));\n };\n this.zone.runOutsideAngular(() => window.addEventListener('scroll', handler, { passive: true }));\n // Initial check (page might already be scrolled), and it is SYNCHRONOUS on\n // purpose. `window.scrollY` forces a style + layout flush, which is what\n // makes constructing N of these quadratic — 1000 instances cost 90ms and\n // 5000 cost 1640ms, of which ~95% is the flush: replacing `scrollY` with a\n // plain property drops 5000 to 83ms with all 5000 scroll listeners still\n // registered, so the per-instance listener is not the cost it looks like.\n // The bulk figure is nobody's bill — a page has one back-to-top button, and\n // one instance measures 0.03ms over an equivalent component. Deferring to\n // `afterNextRender` would land the signal a change-detection pass later, so\n // a page restored part way down would fade the button in from `opacity: 0`\n // instead of painting it in place. That first paint is the contract.\n handler();\n this.destroyRef.onDestroy(() => window.removeEventListener('scroll', handler));\n }\n\n protected onClick(): void {\n this.scroll.toTop({ offset: this.offset() });\n }\n}\n","<button type=\"button\" class=\"wr-back-top__button\" [attr.aria-label]=\"resolvedAriaLabel()\" (click)=\"onClick()\">\n <!-- The arrow is FALLBACK content: rendered next to a projected icon rather\n than instead of it, the documented custom-icon example put two glyphs in\n one 44px circle. -->\n <ng-content>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" aria-hidden=\"true\">\n <path\n d=\"M9 4 L9 14 M4 9 L9 4 L14 9\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </ng-content>\n</button>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ngwr-back-top.mjs","sources":["../../../projects/lib/back-top/back-top.ts","../../../projects/lib/back-top/back-top.html","../../../projects/lib/back-top/ngwr-back-top.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 { Component, DestroyRef, NgZone, ViewEncapsulation, computed, inject, input, signal } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrPlatform } from 'ngwr/platform';\nimport { WrScroll } from 'ngwr/scroll';\n\n/**\n * Pinned floating button that scrolls the page back to the top. Appears\n * once the user has scrolled past `visibilityThreshold` pixels.\n *\n * @example\n * ```html\n * <wr-back-top />\n *\n * <wr-back-top visibilityThreshold=\"600\" [offset]=\"80\">\n * <svg>…custom icon…</svg>\n * </wr-back-top>\n * ```\n *\n * @see https://ngwr.dev/reference/components/back-top\n */\n@Component({\n selector: 'wr-back-top',\n templateUrl: './back-top.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.aria-hidden]': '!visible()',\n // `aria-hidden` alone left a 44px button that focus still landed on: invisible\n // (opacity 0) but in the tab order, and unannounceable once it got there.\n // `inert` is what actually takes it out of both.\n '[attr.inert]': \"visible() ? null : ''\",\n },\n})\nexport class WrBackTop {\n /** Show the button once `window.scrollY` exceeds this many pixels. @default 400 */\n readonly visibilityThreshold = input(400, {\n transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 400)),\n });\n\n /** Pixel offset subtracted from the scroll target — for sticky headers. @default 0 */\n readonly offset = input(0, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 0)) });\n\n /** Accessible label for the button. Falls back to `backTop.label`, then `'Back to top'`. */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'backTop.label', 'Back to top');\n\n protected readonly visible = signal(false);\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 protected readonly classes = computed(() => {\n const parts = ['wr-back-top'];\n if (this.visible()) parts.push('wr-back-top--visible');\n return parts.join(' ');\n });\n\n constructor() {\n if (!this.platform.isBrowser) return;\n const handler = (): void => {\n const should = window.scrollY > this.visibilityThreshold();\n if (should !== this.visible()) this.zone.run(() => this.visible.set(should));\n };\n this.zone.runOutsideAngular(() => window.addEventListener('scroll', handler, { passive: true }));\n // Initial check (page might already be scrolled), and it is SYNCHRONOUS on\n // purpose. `window.scrollY` forces a style + layout flush, which is what\n // makes constructing N of these quadratic — 1000 instances cost 90ms and\n // 5000 cost 1640ms, of which ~95% is the flush: replacing `scrollY` with a\n // plain property drops 5000 to 83ms with all 5000 scroll listeners still\n // registered, so the per-instance listener is not the cost it looks like.\n // The bulk figure is nobody's bill — a page has one back-to-top button, and\n // one instance measures 0.03ms over an equivalent component. Deferring to\n // `afterNextRender` would land the signal a change-detection pass later, so\n // a page restored part way down would fade the button in from `opacity: 0`\n // instead of painting it in place. That first paint is the contract.\n handler();\n this.destroyRef.onDestroy(() => window.removeEventListener('scroll', handler));\n }\n\n protected onClick(): void {\n this.scroll.toTop({ offset: this.offset() });\n }\n}\n","<button type=\"button\" class=\"wr-back-top__button\" [attr.aria-label]=\"resolvedAriaLabel()\" (click)=\"onClick()\">\n <!-- The arrow is FALLBACK content: rendered next to a projected icon rather\n than instead of it, the documented custom-icon example put two glyphs in\n one 44px circle. -->\n <ng-content>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" aria-hidden=\"true\">\n <path\n d=\"M9 4 L9 14 M4 9 L9 4 L14 9\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </ng-content>\n</button>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;AAAA;;;;;AAKG;AASH;;;;;;;;;;;;;;AAcG;MAcU,SAAS,CAAA;;IAEX,mBAAmB,GAAG,KAAK,CAAC,GAAG,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,qBAAA,EAAA,8BAAA,EAAA,CAAA,EACtC,SAAS,EAAE,CAAC,CAAU,KAAa,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAA,CAC5E;;IAGO,MAAM,GAAG,KAAK,CAAC,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,QAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,CAAC,CAAU,KAAa,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAA,CAAG;;IAGjG,SAAS,GAAG,KAAK,CAAgB,IAAI;kFAAC;IAE5B,iBAAiB,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,aAAa,CAAC;IAE/E,OAAO,GAAG,MAAM,CAAC,KAAK;gFAAC;AAEzB,IAAA,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;AACzB,IAAA,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC;AAC7B,IAAA,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;AACrB,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAE7B,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,MAAM,KAAK,GAAG,CAAC,aAAa,CAAC;QAC7B,IAAI,IAAI,CAAC,OAAO,EAAE;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC;AACtD,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IACxB,CAAC;gFAAC;AAEF,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS;YAAE;QAC9B,MAAM,OAAO,GAAG,MAAW;YACzB,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,mBAAmB,EAAE;AAC1D,YAAA,IAAI,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE;AAAE,gBAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC9E,QAAA,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;;;;;;;;;;;;AAYhG,QAAA,OAAO,EAAE;AACT,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChF;IAEU,OAAO,GAAA;AACf,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;IAC9C;uGAnDW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAT,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,SAAS,6mBC1CtB,2pBAiBA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDyBa,SAAS,EAAA,UAAA,EAAA,CAAA;kBAbrB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,aAAa,EAAA,aAAA,EAER,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B;AACJ,wBAAA,SAAS,EAAE,WAAW;AACtB,wBAAA,oBAAoB,EAAE,YAAY;;;;AAIlC,wBAAA,cAAc,EAAE,uBAAuB;AACxC,qBAAA,EAAA,QAAA,EAAA,2pBAAA,EAAA;;;AExCH;;AAEG;;"}
|