ngwr 14.7.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/bar-chart/styles/_index.scss +1 -0
- package/button/styles/_index.scss +6 -0
- package/calendar-heatmap/styles/_index.scss +1 -0
- package/cascader/styles/_rules.scss +87 -15
- package/checkbox/styles/_index.scss +4 -0
- package/command-palette/styles/_index.scss +1 -1
- package/date-picker/styles/_index.scss +30 -0
- package/density/styles/_index.scss +4 -2
- package/divider/styles/_index.scss +2 -0
- package/donut-chart/styles/_index.scss +10 -0
- package/dropdown/styles/_index.scss +67 -5
- package/editor/styles/_index.scss +441 -0
- package/event-calendar/styles/_index.scss +209 -35
- 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 +31 -6
- 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 +61 -6
- 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 +18 -8
- 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 +721 -62
- 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 +48 -6
- 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 +174 -25
- 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 +14 -7
- 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 +61 -10
- 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 +35 -6
- 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 +31 -0
- package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-cs.mjs +31 -0
- package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-de.mjs +31 -0
- package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +39 -0
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-es.mjs +31 -0
- package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-fr.mjs +31 -0
- package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-he.mjs +31 -0
- package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-hi.mjs +31 -0
- package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-id.mjs +31 -0
- package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-it.mjs +31 -0
- package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ja.mjs +31 -0
- package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ko.mjs +31 -0
- package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-nl.mjs +31 -0
- package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pl.mjs +31 -0
- package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pt.mjs +31 -0
- package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +31 -0
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-sv.mjs +31 -0
- package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-tr.mjs +31 -0
- package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-uk.mjs +31 -0
- package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-vi.mjs +31 -0
- package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh-TW.mjs +31 -0
- package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh.mjs +31 -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 +15 -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 +18 -7
- 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 +7 -3
- package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group.mjs +26 -6
- 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 +13 -5
- 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 +578 -16
- 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 +10 -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 +84 -10
- 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 +10 -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 +16 -1
- package/gauge/styles/_index.scss +1 -0
- package/i18n/ar.json +32 -1
- package/i18n/cs.json +32 -1
- package/i18n/de.json +32 -1
- package/i18n/en.json +32 -1
- package/i18n/es.json +32 -1
- package/i18n/fr.json +32 -1
- package/i18n/he.json +32 -1
- package/i18n/hi.json +32 -1
- package/i18n/id.json +32 -1
- package/i18n/it.json +32 -1
- package/i18n/ja.json +32 -1
- package/i18n/ko.json +32 -1
- package/i18n/nl.json +32 -1
- package/i18n/pl.json +32 -1
- package/i18n/pt.json +32 -1
- package/i18n/ru.json +32 -1
- package/i18n/sv.json +32 -1
- package/i18n/tr.json +32 -1
- package/i18n/uk.json +32 -1
- package/i18n/vi.json +32 -1
- package/i18n/zh-TW.json +32 -1
- package/i18n/zh.json +32 -1
- package/input/styles/_index.scss +24 -1
- package/input-number/styles/_index.scss +69 -0
- package/input-otp/styles/_index.scss +5 -5
- package/line-chart/styles/_index.scss +30 -2
- package/llms-full.txt +14 -4
- package/llms.txt +188 -132
- package/mcp/providers.js +2 -2
- package/mcp/server.js +1 -1
- package/meter-group/styles/_index.scss +1 -0
- package/overlay/styles/_arrow.scss +30 -2
- package/package.json +43 -2
- package/page-header/styles/_index.scss +37 -1
- package/pagination/styles/_index.scss +9 -5
- package/popover/styles/_index.scss +73 -5
- 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 +51 -12
- package/sidebar/styles/_index.scss +44 -2
- 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/sparkline/styles/_index.scss +19 -0
- 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/toolbar/styles/_index.scss +35 -1
- package/tree/styles/_index.scss +46 -7
- package/types/ngwr-badge.d.ts +22 -7
- package/types/ngwr-bar-chart.d.ts +19 -1
- package/types/ngwr-calendar-heatmap.d.ts +29 -1
- package/types/ngwr-checkbox.d.ts +2 -0
- package/types/ngwr-config.d.ts +12 -0
- package/types/ngwr-date-picker.d.ts +308 -43
- package/types/ngwr-donut-chart.d.ts +24 -1
- package/types/ngwr-dropdown.d.ts +22 -2
- package/types/ngwr-editor-testing.d.ts +378 -0
- package/types/ngwr-editor.d.ts +449 -0
- package/types/ngwr-event-calendar.d.ts +8 -0
- package/types/ngwr-form.d.ts +35 -5
- package/types/ngwr-gauge.d.ts +20 -1
- package/types/ngwr-input-number.d.ts +7 -0
- package/types/ngwr-line-chart.d.ts +9 -1
- package/types/ngwr-markdown.d.ts +61 -2
- package/types/ngwr-meter-group-testing.d.ts +3 -2
- package/types/ngwr-meter-group.d.ts +14 -1
- package/types/ngwr-page-header.d.ts +10 -2
- package/types/ngwr-popover.d.ts +154 -3
- package/types/ngwr-sidebar.d.ts +7 -0
- package/types/ngwr-sparkline.d.ts +43 -1
- package/types/ngwr-toolbar.d.ts +7 -0
- package/types/ngwr-typography.d.ts +4 -0
- package/types/ngwr-version.d.ts +1 -1
- package/typography/styles/_index.scss +16 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-border-glow.mjs","sources":["../../../projects/lib/border-glow/border-glow.ts","../../../projects/lib/border-glow/border-glow.html","../../../projects/lib/border-glow/ngwr-border-glow.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 * Port of the reactbits.dev BorderGlow effect — a cursor-tracked cone of\n * mesh-gradient light that follows the pointer along the card's perimeter,\n * with an outer halo and optional auto-sweep on mount.\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport { Component, ElementRef, PLATFORM_ID, ViewEncapsulation, computed, effect, inject, input } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { isSafeCssValue, numAttr } from 'ngwr/utils';\n\nconst RADIANS_TO_DEG = 180 / Math.PI;\n\ninterface ParsedHsl {\n readonly h: number;\n readonly s: number;\n readonly l: number;\n}\n\nfunction parseHsl(input: string): ParsedHsl {\n const match = /([\\d.]+)\\s*([\\d.]+)%?\\s*([\\d.]+)%?/.exec(input);\n if (!match) return { h: 40, s: 80, l: 80 };\n return { h: Number.parseFloat(match[1]), s: Number.parseFloat(match[2]), l: Number.parseFloat(match[3]) };\n}\n\nconst GLOW_OPACITY_STEPS = [100, 60, 50, 40, 30, 20, 10] as const;\nconst GLOW_VAR_SUFFIXES = ['', '-60', '-50', '-40', '-30', '-20', '-10'] as const;\n\nconst GRADIENT_POSITIONS = ['80% 55%', '69% 34%', '8% 6%', '41% 38%', '86% 85%', '82% 18%', '51% 4%'] as const;\nconst GRADIENT_VAR_NAMES = [\n '--wr-border-glow-gradient-one',\n '--wr-border-glow-gradient-two',\n '--wr-border-glow-gradient-three',\n '--wr-border-glow-gradient-four',\n '--wr-border-glow-gradient-five',\n '--wr-border-glow-gradient-six',\n '--wr-border-glow-gradient-seven',\n] as const;\nconst GRADIENT_COLOR_INDEX = [0, 1, 2, 0, 1, 2, 1] as const;\n\nconst DEFAULT_COLORS: readonly string[] = ['#c084fc', '#f472b6', '#38bdf8'];\n\nfunction buildGlowVars(glowColor: string, intensity: number): Record<string, string> {\n const { h, s, l } = parseHsl(glowColor);\n const base = `${h}deg ${s}% ${l}%`;\n const out: Record<string, string> = {};\n for (let i = 0; i < GLOW_OPACITY_STEPS.length; i++) {\n const alpha = Math.min(GLOW_OPACITY_STEPS[i] * intensity, 100);\n out[`--wr-border-glow-color${GLOW_VAR_SUFFIXES[i]}`] = `hsl(${base} / ${alpha}%)`;\n }\n return out;\n}\n\nfunction buildGradientVars(colors: readonly string[]): Record<string, string> {\n const out: Record<string, string> = {};\n // Each entry is INTERPOLATED into the `radial-gradient()` below, so a value\n // that balances the parens around it escapes into a sibling layer and can add\n // a `url()` the browser fetches. One unsafe entry discards the palette — the\n // same all-or-nothing rule `wr-gradient-text` follows, for the same reason.\n const palette = colors.length > 0 && colors.every(color => isSafeCssValue(color)) ? colors : DEFAULT_COLORS;\n for (let i = 0; i < GRADIENT_VAR_NAMES.length; i++) {\n const colour = palette[Math.min(GRADIENT_COLOR_INDEX[i], palette.length - 1)];\n out[GRADIENT_VAR_NAMES[i]] = `radial-gradient(at ${GRADIENT_POSITIONS[i]}, ${colour} 0px, transparent 50%)`;\n }\n out['--wr-border-glow-gradient-base'] = `linear-gradient(${palette[0]} 0 100%)`;\n return out;\n}\n\ninterface AnimateOptions {\n readonly start?: number;\n readonly end?: number;\n readonly duration?: number;\n readonly delay?: number;\n readonly ease?: (t: number) => number;\n readonly onUpdate: (v: number) => void;\n readonly onEnd?: () => void;\n}\n\n/** Tiny rAF-driven tweener. Returns a cancel function so callers can clean up on destroy. */\nfunction animateValue(opts: AnimateOptions): () => void {\n const { start = 0, end = 100, duration = 1000, delay = 0, ease = (t: number): number => t, onUpdate, onEnd } = opts;\n let raf = 0;\n let cancelled = false;\n\n const startAt = performance.now() + delay;\n const tick = (): void => {\n if (cancelled) return;\n const elapsed = performance.now() - startAt;\n const t = Math.min(Math.max(elapsed / duration, 0), 1);\n onUpdate(start + (end - start) * ease(t));\n if (t < 1) raf = requestAnimationFrame(tick);\n else if (onEnd) onEnd();\n };\n\n const timer = setTimeout(() => {\n raf = requestAnimationFrame(tick);\n }, delay);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n cancelAnimationFrame(raf);\n };\n}\n\n/**\n * Cursor-tracked glowing border card. A cone of light follows the pointer\n * along the card's perimeter, brightening as the cursor approaches an edge.\n *\n * - Outer halo via stacked `box-shadow` on an inner `.edge-light` element.\n * - Inner \"soft bloom\" via `mix-blend-mode: soft-light` for content near the\n * edges (subtle; control via `[fillOpacity]`).\n * - Optional `[animated]` mode performs a one-shot sweep on mount, useful\n * for drawing attention to a freshly-rendered card.\n *\n * @example\n * ```html\n * <wr-border-glow [animated]=\"true\" [colors]=\"['#c084fc', '#f472b6', '#38bdf8']\">\n * <h3>Hover me</h3>\n * <p>The border lights up where the cursor is.</p>\n * </wr-border-glow>\n * ```\n *\n * @see https://www.reactbits.dev/components/border-glow (visual reference)\n */\n@Component({\n selector: 'wr-border-glow',\n templateUrl: './border-glow.html',\n styleUrl: './border-glow.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-border-glow',\n '(pointermove)': 'onPointerMove($event)',\n },\n})\nexport class WrBorderGlow {\n /** Card background fill. When unset, uses the theme surface token. */\n readonly backgroundColor = input<string | null>(null);\n\n /** Corner radius in pixels. @default 28 */\n readonly borderRadius = input(28, { transform: numAttr(28) });\n\n /** Halo extent in pixels — how far the outer glow reaches past the card edge. @default 40 */\n readonly glowRadius = input(40, { transform: numAttr(40) });\n\n /** Halo opacity multiplier (1 = full strength). @default 1 */\n readonly glowIntensity = input(1, { transform: numAttr(1) });\n\n /** Width of the lit cone as a percentage of the perimeter. @default 25 */\n readonly coneSpread = input(25, { transform: numAttr(25) });\n\n /** How sharply the halo fades as the cursor leaves the edge. Lower = wider falloff. @default 30 */\n readonly edgeSensitivity = input(30, { transform: numAttr(30) });\n\n /** Strength of the soft-light interior fill near edges. @default 0.5 */\n readonly fillOpacity = input(0.5, { transform: numAttr(0.5) });\n\n /**\n * Halo colour as `'H S L'` (HSL parts, no commas). When unset, the theme\n * decides: a deep amber on light surfaces, pale amber on dark. Note\n * `glowIntensity` only applies alongside an explicit `glowColor`.\n */\n readonly glowColor = input<string | null>(null);\n\n /**\n * Mesh-gradient palette for the colored border slice. When unset, the\n * theme decides: deep tones on light, pastels on dark.\n */\n readonly colors = input<readonly string[] | null>(null);\n\n /** Play a one-shot perimeter sweep on mount, then fade out. @default false */\n readonly animated = input(false, { transform: coerceBooleanProperty });\n\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Inline CSS variable bag — recomputed when colour / radius / sensitivity inputs change. */\n protected readonly cssVars = computed<Record<string, string>>(() => {\n const vars: Record<string, string> = {\n '--wr-border-glow-radius': `${this.borderRadius()}px`,\n '--wr-border-glow-padding': `${this.glowRadius()}px`,\n '--wr-border-glow-cone-spread': String(this.coneSpread()),\n '--wr-border-glow-edge-sensitivity': String(this.edgeSensitivity()),\n '--wr-border-glow-fill-opacity': String(this.fillOpacity()),\n };\n const colors = this.colors();\n if (colors !== null) Object.assign(vars, buildGradientVars(colors));\n // Colour vars are written only when set — otherwise the stylesheet's\n // per-theme defaults (light vs dark) take over.\n // Composed, not passed through: `_rules.scss` reads this var inside a\n // `linear-gradient()` and again in a `background` shorthand, where a `url()`\n // is valid and fetches. An audit bound `url(\"…\")` here and recorded the\n // request. Validated like its `colors` sibling on this same component —\n // leaving one of the two unchecked is two rules inside one component.\n const bg = this.backgroundColor();\n if (bg !== null && isSafeCssValue(bg)) vars['--wr-border-glow-bg'] = bg;\n const glow = this.glowColor();\n if (glow !== null) Object.assign(vars, buildGlowVars(glow, this.glowIntensity()));\n return vars;\n });\n\n constructor() {\n // Apply the variable bag to the host on every input change. Bind in an\n // effect rather than `host: { '[style.--foo]': '...' }` so a single\n // `setProperty` loop handles the lot.\n effect(() => {\n const host = this.el.nativeElement;\n const vars = this.cssVars();\n for (const [k, v] of Object.entries(vars)) host.style.setProperty(k, v);\n });\n\n if (!this.isBrowser) return;\n\n // Auto-sweep on mount — fires once when `animated` is true.\n effect(onCleanup => {\n if (!this.animated()) return;\n onCleanup(this.runAutoSweep());\n });\n }\n\n /** Pointer-driven update of `--wr-border-glow-angle` + `--wr-border-glow-edge-proximity`. */\n protected onPointerMove(event: PointerEvent): void {\n const host = this.el.nativeElement;\n const rect = host.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n\n const dx = x - cx;\n const dy = y - cy;\n\n // `edge-proximity`: 0 at centre, 1 at the perimeter (whichever axis hits first).\n let edge = 0;\n if (dx !== 0 || dy !== 0) {\n const kx = dx === 0 ? Infinity : cx / Math.abs(dx);\n const ky = dy === 0 ? Infinity : cy / Math.abs(dy);\n edge = Math.min(Math.max(1 / Math.min(kx, ky), 0), 1);\n }\n\n // `cursor-angle`: 0deg = top, increases clockwise.\n let angle = 0;\n if (dx !== 0 || dy !== 0) {\n angle = Math.atan2(dy, dx) * RADIANS_TO_DEG + 90;\n if (angle < 0) angle += 360;\n }\n\n host.style.setProperty('--wr-border-glow-edge-proximity', (edge * 100).toFixed(3));\n host.style.setProperty('--wr-border-glow-angle', `${angle.toFixed(3)}deg`);\n }\n\n /** One-shot perimeter sweep: in → around → out, mirroring the reactbits behaviour. */\n private runAutoSweep(): () => void {\n // Reduced motion: skip the decorative mount sweep. The pointer-driven\n // glow stays — it maps 1:1 to the cursor with no autonomous motion.\n if (this.platform.prefersReducedMotion()) return () => undefined;\n const host = this.el.nativeElement;\n const ANGLE_START = 110;\n const ANGLE_END = 465;\n host.classList.add('wr-border-glow--sweeping');\n host.style.setProperty('--wr-border-glow-angle', `${ANGLE_START}deg`);\n\n const easeOutCubic = (t: number): number => 1 - (1 - t) ** 3;\n const easeInCubic = (t: number): number => t * t * t;\n const lerpAngle = (v: number): string => `${(ANGLE_END - ANGLE_START) * (v / 100) + ANGLE_START}deg`;\n\n // 1. Ramp edge-proximity up to 100 quickly.\n const cancelA = animateValue({\n duration: 500,\n onUpdate: v => host.style.setProperty('--wr-border-glow-edge-proximity', `${v}`),\n });\n // 2. Sweep angle first half (ease-in).\n const cancelB = animateValue({\n duration: 1500,\n end: 50,\n ease: easeInCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-angle', lerpAngle(v)),\n });\n // 3. Sweep angle second half (ease-out).\n const cancelC = animateValue({\n delay: 1500,\n duration: 2250,\n start: 50,\n end: 100,\n ease: easeOutCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-angle', lerpAngle(v)),\n });\n // 4. Fade proximity back to 0.\n const cancelD = animateValue({\n delay: 2500,\n duration: 1500,\n start: 100,\n end: 0,\n ease: easeInCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-edge-proximity', `${v}`),\n onEnd: () => host.classList.remove('wr-border-glow--sweeping'),\n });\n\n // Returned rather than registered on `destroyRef`: this method runs from an\n // effect, so registering there stacked one more teardown per re-run and none\n // of them fired until the component died. The caller ties it to the effect's\n // own cleanup instead.\n return () => {\n cancelA();\n cancelB();\n cancelC();\n cancelD();\n host.classList.remove('wr-border-glow--sweeping');\n };\n }\n}\n","<span class=\"wr-border-glow__edge\" aria-hidden=\"true\"></span>\n<div class=\"wr-border-glow__inner\">\n <ng-content />\n</div>\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-border-glow.mjs","sources":["../../../projects/lib/border-glow/border-glow.ts","../../../projects/lib/border-glow/border-glow.html","../../../projects/lib/border-glow/ngwr-border-glow.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 * Port of the reactbits.dev BorderGlow effect — a cursor-tracked cone of\n * mesh-gradient light that follows the pointer along the card's perimeter,\n * with an outer halo and optional auto-sweep on mount.\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport { Component, ElementRef, PLATFORM_ID, ViewEncapsulation, computed, effect, inject, input } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { isSafeCssValue, numAttr } from 'ngwr/utils';\n\nconst RADIANS_TO_DEG = 180 / Math.PI;\n\ninterface ParsedHsl {\n readonly h: number;\n readonly s: number;\n readonly l: number;\n}\n\nfunction parseHsl(input: string): ParsedHsl {\n const match = /([\\d.]+)\\s*([\\d.]+)%?\\s*([\\d.]+)%?/.exec(input);\n if (!match) return { h: 40, s: 80, l: 80 };\n return { h: Number.parseFloat(match[1]), s: Number.parseFloat(match[2]), l: Number.parseFloat(match[3]) };\n}\n\nconst GLOW_OPACITY_STEPS = [100, 60, 50, 40, 30, 20, 10] as const;\nconst GLOW_VAR_SUFFIXES = ['', '-60', '-50', '-40', '-30', '-20', '-10'] as const;\n\nconst GRADIENT_POSITIONS = ['80% 55%', '69% 34%', '8% 6%', '41% 38%', '86% 85%', '82% 18%', '51% 4%'] as const;\nconst GRADIENT_VAR_NAMES = [\n '--wr-border-glow-gradient-one',\n '--wr-border-glow-gradient-two',\n '--wr-border-glow-gradient-three',\n '--wr-border-glow-gradient-four',\n '--wr-border-glow-gradient-five',\n '--wr-border-glow-gradient-six',\n '--wr-border-glow-gradient-seven',\n] as const;\nconst GRADIENT_COLOR_INDEX = [0, 1, 2, 0, 1, 2, 1] as const;\n\nconst DEFAULT_COLORS: readonly string[] = ['#c084fc', '#f472b6', '#38bdf8'];\n\nfunction buildGlowVars(glowColor: string, intensity: number): Record<string, string> {\n const { h, s, l } = parseHsl(glowColor);\n const base = `${h}deg ${s}% ${l}%`;\n const out: Record<string, string> = {};\n for (let i = 0; i < GLOW_OPACITY_STEPS.length; i++) {\n const alpha = Math.min(GLOW_OPACITY_STEPS[i] * intensity, 100);\n out[`--wr-border-glow-color${GLOW_VAR_SUFFIXES[i]}`] = `hsl(${base} / ${alpha}%)`;\n }\n return out;\n}\n\nfunction buildGradientVars(colors: readonly string[]): Record<string, string> {\n const out: Record<string, string> = {};\n // Each entry is INTERPOLATED into the `radial-gradient()` below, so a value\n // that balances the parens around it escapes into a sibling layer and can add\n // a `url()` the browser fetches. One unsafe entry discards the palette — the\n // same all-or-nothing rule `wr-gradient-text` follows, for the same reason.\n const palette = colors.length > 0 && colors.every(color => isSafeCssValue(color)) ? colors : DEFAULT_COLORS;\n for (let i = 0; i < GRADIENT_VAR_NAMES.length; i++) {\n const colour = palette[Math.min(GRADIENT_COLOR_INDEX[i], palette.length - 1)];\n out[GRADIENT_VAR_NAMES[i]] = `radial-gradient(at ${GRADIENT_POSITIONS[i]}, ${colour} 0px, transparent 50%)`;\n }\n out['--wr-border-glow-gradient-base'] = `linear-gradient(${palette[0]} 0 100%)`;\n return out;\n}\n\ninterface AnimateOptions {\n readonly start?: number;\n readonly end?: number;\n readonly duration?: number;\n readonly delay?: number;\n readonly ease?: (t: number) => number;\n readonly onUpdate: (v: number) => void;\n readonly onEnd?: () => void;\n}\n\n/** Tiny rAF-driven tweener. Returns a cancel function so callers can clean up on destroy. */\nfunction animateValue(opts: AnimateOptions): () => void {\n const { start = 0, end = 100, duration = 1000, delay = 0, ease = (t: number): number => t, onUpdate, onEnd } = opts;\n let raf = 0;\n let cancelled = false;\n\n const startAt = performance.now() + delay;\n const tick = (): void => {\n if (cancelled) return;\n const elapsed = performance.now() - startAt;\n const t = Math.min(Math.max(elapsed / duration, 0), 1);\n onUpdate(start + (end - start) * ease(t));\n if (t < 1) raf = requestAnimationFrame(tick);\n else if (onEnd) onEnd();\n };\n\n const timer = setTimeout(() => {\n raf = requestAnimationFrame(tick);\n }, delay);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n cancelAnimationFrame(raf);\n };\n}\n\n/**\n * Cursor-tracked glowing border card. A cone of light follows the pointer\n * along the card's perimeter, brightening as the cursor approaches an edge.\n *\n * - Outer halo via stacked `box-shadow` on an inner `.edge-light` element.\n * - Inner \"soft bloom\" via `mix-blend-mode: soft-light` for content near the\n * edges (subtle; control via `[fillOpacity]`).\n * - Optional `[animated]` mode performs a one-shot sweep on mount, useful\n * for drawing attention to a freshly-rendered card.\n *\n * @example\n * ```html\n * <wr-border-glow [animated]=\"true\" [colors]=\"['#c084fc', '#f472b6', '#38bdf8']\">\n * <h3>Hover me</h3>\n * <p>The border lights up where the cursor is.</p>\n * </wr-border-glow>\n * ```\n *\n * @see https://www.reactbits.dev/components/border-glow (visual reference)\n */\n@Component({\n selector: 'wr-border-glow',\n templateUrl: './border-glow.html',\n styleUrl: './border-glow.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-border-glow',\n '(pointermove)': 'onPointerMove($event)',\n },\n})\nexport class WrBorderGlow {\n /** Card background fill. When unset, uses the theme surface token. */\n readonly backgroundColor = input<string | null>(null);\n\n /** Corner radius in pixels. @default 28 */\n readonly borderRadius = input(28, { transform: numAttr(28) });\n\n /** Halo extent in pixels — how far the outer glow reaches past the card edge. @default 40 */\n readonly glowRadius = input(40, { transform: numAttr(40) });\n\n /** Halo opacity multiplier (1 = full strength). @default 1 */\n readonly glowIntensity = input(1, { transform: numAttr(1) });\n\n /** Width of the lit cone as a percentage of the perimeter. @default 25 */\n readonly coneSpread = input(25, { transform: numAttr(25) });\n\n /** How sharply the halo fades as the cursor leaves the edge. Lower = wider falloff. @default 30 */\n readonly edgeSensitivity = input(30, { transform: numAttr(30) });\n\n /** Strength of the soft-light interior fill near edges. @default 0.5 */\n readonly fillOpacity = input(0.5, { transform: numAttr(0.5) });\n\n /**\n * Halo colour as `'H S L'` (HSL parts, no commas). When unset, the theme\n * decides: a deep amber on light surfaces, pale amber on dark. Note\n * `glowIntensity` only applies alongside an explicit `glowColor`.\n */\n readonly glowColor = input<string | null>(null);\n\n /**\n * Mesh-gradient palette for the colored border slice. When unset, the\n * theme decides: deep tones on light, pastels on dark.\n */\n readonly colors = input<readonly string[] | null>(null);\n\n /** Play a one-shot perimeter sweep on mount, then fade out. @default false */\n readonly animated = input(false, { transform: coerceBooleanProperty });\n\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Inline CSS variable bag — recomputed when colour / radius / sensitivity inputs change. */\n protected readonly cssVars = computed<Record<string, string>>(() => {\n const vars: Record<string, string> = {\n '--wr-border-glow-radius': `${this.borderRadius()}px`,\n '--wr-border-glow-padding': `${this.glowRadius()}px`,\n '--wr-border-glow-cone-spread': String(this.coneSpread()),\n '--wr-border-glow-edge-sensitivity': String(this.edgeSensitivity()),\n '--wr-border-glow-fill-opacity': String(this.fillOpacity()),\n };\n const colors = this.colors();\n if (colors !== null) Object.assign(vars, buildGradientVars(colors));\n // Colour vars are written only when set — otherwise the stylesheet's\n // per-theme defaults (light vs dark) take over.\n // Composed, not passed through: `_rules.scss` reads this var inside a\n // `linear-gradient()` and again in a `background` shorthand, where a `url()`\n // is valid and fetches. An audit bound `url(\"…\")` here and recorded the\n // request. Validated like its `colors` sibling on this same component —\n // leaving one of the two unchecked is two rules inside one component.\n const bg = this.backgroundColor();\n if (bg !== null && isSafeCssValue(bg)) vars['--wr-border-glow-bg'] = bg;\n const glow = this.glowColor();\n if (glow !== null) Object.assign(vars, buildGlowVars(glow, this.glowIntensity()));\n return vars;\n });\n\n constructor() {\n // Apply the variable bag to the host on every input change. Bind in an\n // effect rather than `host: { '[style.--foo]': '...' }` so a single\n // `setProperty` loop handles the lot.\n effect(() => {\n const host = this.el.nativeElement;\n const vars = this.cssVars();\n for (const [k, v] of Object.entries(vars)) host.style.setProperty(k, v);\n });\n\n if (!this.isBrowser) return;\n\n // Auto-sweep on mount — fires once when `animated` is true.\n effect(onCleanup => {\n if (!this.animated()) return;\n onCleanup(this.runAutoSweep());\n });\n }\n\n /** Pointer-driven update of `--wr-border-glow-angle` + `--wr-border-glow-edge-proximity`. */\n protected onPointerMove(event: PointerEvent): void {\n const host = this.el.nativeElement;\n const rect = host.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n\n const dx = x - cx;\n const dy = y - cy;\n\n // `edge-proximity`: 0 at centre, 1 at the perimeter (whichever axis hits first).\n let edge = 0;\n if (dx !== 0 || dy !== 0) {\n const kx = dx === 0 ? Infinity : cx / Math.abs(dx);\n const ky = dy === 0 ? Infinity : cy / Math.abs(dy);\n edge = Math.min(Math.max(1 / Math.min(kx, ky), 0), 1);\n }\n\n // `cursor-angle`: 0deg = top, increases clockwise.\n let angle = 0;\n if (dx !== 0 || dy !== 0) {\n angle = Math.atan2(dy, dx) * RADIANS_TO_DEG + 90;\n if (angle < 0) angle += 360;\n }\n\n host.style.setProperty('--wr-border-glow-edge-proximity', (edge * 100).toFixed(3));\n host.style.setProperty('--wr-border-glow-angle', `${angle.toFixed(3)}deg`);\n }\n\n /** One-shot perimeter sweep: in → around → out, mirroring the reactbits behaviour. */\n private runAutoSweep(): () => void {\n // Reduced motion: skip the decorative mount sweep. The pointer-driven\n // glow stays — it maps 1:1 to the cursor with no autonomous motion.\n if (this.platform.prefersReducedMotion()) return () => undefined;\n const host = this.el.nativeElement;\n const ANGLE_START = 110;\n const ANGLE_END = 465;\n host.classList.add('wr-border-glow--sweeping');\n host.style.setProperty('--wr-border-glow-angle', `${ANGLE_START}deg`);\n\n const easeOutCubic = (t: number): number => 1 - (1 - t) ** 3;\n const easeInCubic = (t: number): number => t * t * t;\n const lerpAngle = (v: number): string => `${(ANGLE_END - ANGLE_START) * (v / 100) + ANGLE_START}deg`;\n\n // 1. Ramp edge-proximity up to 100 quickly.\n const cancelA = animateValue({\n duration: 500,\n onUpdate: v => host.style.setProperty('--wr-border-glow-edge-proximity', `${v}`),\n });\n // 2. Sweep angle first half (ease-in).\n const cancelB = animateValue({\n duration: 1500,\n end: 50,\n ease: easeInCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-angle', lerpAngle(v)),\n });\n // 3. Sweep angle second half (ease-out).\n const cancelC = animateValue({\n delay: 1500,\n duration: 2250,\n start: 50,\n end: 100,\n ease: easeOutCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-angle', lerpAngle(v)),\n });\n // 4. Fade proximity back to 0.\n const cancelD = animateValue({\n delay: 2500,\n duration: 1500,\n start: 100,\n end: 0,\n ease: easeInCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-edge-proximity', `${v}`),\n onEnd: () => host.classList.remove('wr-border-glow--sweeping'),\n });\n\n // Returned rather than registered on `destroyRef`: this method runs from an\n // effect, so registering there stacked one more teardown per re-run and none\n // of them fired until the component died. The caller ties it to the effect's\n // own cleanup instead.\n return () => {\n cancelA();\n cancelB();\n cancelC();\n cancelD();\n host.classList.remove('wr-border-glow--sweeping');\n };\n }\n}\n","<span class=\"wr-border-glow__edge\" aria-hidden=\"true\"></span>\n<div class=\"wr-border-glow__inner\">\n <ng-content />\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -57,10 +57,10 @@ class WrBreadcrumbs {
|
|
|
57
57
|
// whole fix, and it is lossless: a separator that IS a quote still renders.
|
|
58
58
|
separatorValue = computed(() => `"${cssString(this.separator())}"`, /* @ts-ignore */
|
|
59
59
|
...(ngDevMode ? [{ debugName: "separatorValue" }] : /* istanbul ignore next */ []));
|
|
60
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
61
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.
|
|
60
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBreadcrumbs, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
61
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: WrBreadcrumbs, isStandalone: true, selector: "wr-breadcrumbs", inputs: { separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--wr-breadcrumbs-separator": "separatorValue()" }, classAttribute: "wr-breadcrumbs" }, ngImport: i0, template: "<nav class=\"wr-breadcrumbs__nav\" [attr.aria-label]=\"resolvedAriaLabel()\">\n <ol class=\"wr-breadcrumbs__list\">\n <ng-content />\n </ol>\n</nav>\n", styles: [".wr-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-table__sort-btn:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-tabs__tab:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-sidebar__entry:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-sidebar__item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-anchor__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-collapse__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-command-palette__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-mention-panel__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-segmented__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-back-top:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-stepper__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-window__chrome-action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-dropdown-item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-alert__close:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-graph__viewport:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-breadcrumbs{--wr-breadcrumbs-separator: \"/\";--wr-breadcrumbs-gap: .5rem;--wr-breadcrumbs-color: rgba(var(--wr-color-on-surface-rgb), .6);--wr-breadcrumbs-current-color: var(--wr-color-on-surface);--wr-breadcrumbs-link-color: var(--wr-color-primary-ink);--wr-breadcrumbs-separator-color: rgba(var(--wr-color-on-surface-rgb), .3);display:block;font-family:var(--wr-font-family-base);font-size:var(--wr-text-sm);color:var(--wr-breadcrumbs-color)}.wr-breadcrumbs__nav{display:block}.wr-breadcrumbs__list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wr-breadcrumbs-gap);margin:0;padding:0;list-style:none}.wr-breadcrumbs__item{display:inline-flex;align-items:center;gap:var(--wr-breadcrumbs-gap)}.wr-breadcrumbs__item:not(:first-child):before{content:var(--wr-breadcrumbs-separator);color:var(--wr-breadcrumbs-separator-color);-webkit-user-select:none;user-select:none}.wr-breadcrumbs__link{display:inline-flex;align-items:center;gap:.375rem;color:var(--wr-breadcrumbs-link-color);text-decoration:none;border-radius:var(--wr-border-radius-sm);transition:color .15s ease}.wr-breadcrumbs__link:hover{text-decoration:underline}.wr-breadcrumbs__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:2px}.wr-breadcrumbs__current{display:inline-flex;align-items:center;gap:.375rem;color:var(--wr-breadcrumbs-current-color);font-weight:600}.wr-breadcrumbs__icon{--wr-icon-size: 1rem;flex:0 0 auto}\n"], encapsulation: i0.ViewEncapsulation.None });
|
|
62
62
|
}
|
|
63
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
63
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBreadcrumbs, decorators: [{
|
|
64
64
|
type: Component,
|
|
65
65
|
args: [{ selector: 'wr-breadcrumbs', encapsulation: ViewEncapsulation.None, host: {
|
|
66
66
|
class: 'wr-breadcrumbs',
|
|
@@ -109,10 +109,10 @@ class WrBreadcrumbsItem {
|
|
|
109
109
|
...(ngDevMode ? [{ debugName: "isRouter" }] : /* istanbul ignore next */ []));
|
|
110
110
|
rootClass = computed(() => (this.isLink() ? 'wr-breadcrumbs__link' : 'wr-breadcrumbs__current'), /* @ts-ignore */
|
|
111
111
|
...(ngDevMode ? [{ debugName: "rootClass" }] : /* istanbul ignore next */ []));
|
|
112
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
113
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
112
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBreadcrumbsItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
113
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: WrBreadcrumbsItem, isStandalone: true, selector: "wr-breadcrumbs-item", inputs: { href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, routerLink: { classPropertyName: "routerLink", publicName: "routerLink", isSignal: true, isRequired: false, transformFunction: null }, external: { classPropertyName: "external", publicName: "external", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "listitem" }, classAttribute: "wr-breadcrumbs__item" }, ngImport: i0, template: "<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them \u2014 the\n last in static order \u2014 and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null \u2014\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
114
114
|
}
|
|
115
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBreadcrumbsItem, decorators: [{
|
|
116
116
|
type: Component,
|
|
117
117
|
args: [{ selector: 'wr-breadcrumbs-item', encapsulation: ViewEncapsulation.None, imports: [NgTemplateOutlet, RouterLink, WrIcon], host: { class: 'wr-breadcrumbs__item', role: 'listitem' }, template: "<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them \u2014 the\n last in static order \u2014 and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null \u2014\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n}\n" }]
|
|
118
118
|
}], propDecorators: { href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], routerLink: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerLink", required: false }] }], external: [{ type: i0.Input, args: [{ isSignal: true, alias: "external", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }] } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-breadcrumbs.mjs","sources":["../../../projects/lib/breadcrumbs/breadcrumbs.ts","../../../projects/lib/breadcrumbs/breadcrumbs.html","../../../projects/lib/breadcrumbs/breadcrumbs-item.ts","../../../projects/lib/breadcrumbs/breadcrumbs-item.html","../../../projects/lib/breadcrumbs/ngwr-breadcrumbs.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\n/** Escape a string for use inside a double-quoted CSS `<string>`. */\nfunction cssString(value: string): string {\n return value.replace(/[\\\\\"]/g, '\\\\$&').replace(/[\\n\\r\\f]/g, char => `\\\\${char.codePointAt(0)!.toString(16)} `);\n}\n\n/**\n * Breadcrumb navigation. Project `<wr-breadcrumbs-item>` children — each keeps\n * its own element and takes `role=\"listitem\"` inside the `<ol>` rather than\n * rendering an `<li>`, separated by the configured glyph (default `/`). The\n * container exposes the `nav[aria-label]` landmark required by WCAG.\n *\n * @example\n * ```html\n * <wr-breadcrumbs>\n * <wr-breadcrumbs-item routerLink=\"/\">Home</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item routerLink=\"/docs\">Docs</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item>Current</wr-breadcrumbs-item>\n * </wr-breadcrumbs>\n *\n * <!-- Custom separator -->\n * <wr-breadcrumbs separator=\"›\">…</wr-breadcrumbs>\n * ```\n *\n * @see https://ngwr.dev/reference/components/breadcrumbs\n */\n@Component({\n selector: 'wr-breadcrumbs',\n templateUrl: './breadcrumbs.html',\n styleUrl: './breadcrumbs.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-breadcrumbs',\n '[style.--wr-breadcrumbs-separator]': 'separatorValue()',\n },\n})\nexport class WrBreadcrumbs {\n /** Separator glyph between items. Any short string. @default '/' */\n readonly separator = input('/');\n\n /**\n * Accessible label for the `nav` landmark. Falls back to `breadcrumbs.label`,\n * then `'Breadcrumbs'`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n // The English default used to live on the input itself, which made this the one\n // landmark in the library a catalog could not reach: `wr-anchor` and `wr-sidebar`\n // announced in Russian on the same page while this one stayed \"Breadcrumbs\", and\n // the only escape was restating `[ariaLabel]` on every trail.\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'breadcrumbs.label', 'Breadcrumbs');\n\n // The glyph is WRAPPED in quotes here and unwrapped by `content:` in the\n // stylesheet, so an unescaped `\"` inside it closes the library's own string\n // and the rest of the value is parsed as CSS — `/\" url(\"…\") \"` computes to\n // `content: \"/\" url(\"…\") \"\"`, an image the browser fetches. Escaping is the\n // whole fix, and it is lossless: a separator that IS a quote still renders.\n protected readonly separatorValue = computed(() => `\"${cssString(this.separator())}\"`);\n}\n","<nav class=\"wr-breadcrumbs__nav\" [attr.aria-label]=\"resolvedAriaLabel()\">\n <ol class=\"wr-breadcrumbs__list\">\n <ng-content />\n </ol>\n</nav>\n","/**\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 { NgTemplateOutlet } from '@angular/common';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\n\n/**\n * One row inside `<wr-breadcrumbs>`. The host itself is the row — a\n * `<wr-breadcrumbs-item role=\"listitem\" class=\"wr-breadcrumbs__item\">`\n * inside the parent's `<ol>` — and it contains either a real\n * `<a class=\"wr-breadcrumbs__link\">` (when `[href]` or `[routerLink]` is\n * set) or, for the current crumb, a non-interactive\n * `<a class=\"wr-breadcrumbs__current\" role=\"text\" tabindex=\"-1\"\n * aria-current=\"page\">` (when neither is set — typically the last crumb).\n *\n * @example\n * ```html\n * <wr-breadcrumbs-item icon=\"home\" routerLink=\"/\">Home</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item href=\"https://ngwr.dev\">External</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item>Current page</wr-breadcrumbs-item>\n * ```\n */\n@Component({\n selector: 'wr-breadcrumbs-item',\n templateUrl: './breadcrumbs-item.html',\n encapsulation: ViewEncapsulation.None,\n imports: [NgTemplateOutlet, RouterLink, WrIcon],\n host: { class: 'wr-breadcrumbs__item', role: 'listitem' },\n})\nexport class WrBreadcrumbsItem {\n /** Plain anchor href. Overridden by `routerLink` when both are set. */\n readonly href = input<string | null>(null);\n\n /** Angular router target. Anything `RouterLink` accepts (string or `any[]`). */\n readonly routerLink = input<string | readonly unknown[] | null>(null);\n\n /** Open external `href` in a new tab. Ignored when `routerLink` is set. @default false */\n readonly external = input(false);\n\n /** Optional leading icon rendered inline before the label. @default null */\n readonly icon = input<WrIconName | null>(null);\n\n protected readonly isLink = computed(() => this.href() != null || this.routerLink() != null);\n protected readonly isRouter = computed(() => this.routerLink() != null);\n\n protected readonly rootClass = computed(() => (this.isLink() ? 'wr-breadcrumbs__link' : 'wr-breadcrumbs__current'));\n}\n","<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them — the\n last in static order — and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null —\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\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-breadcrumbs.mjs","sources":["../../../projects/lib/breadcrumbs/breadcrumbs.ts","../../../projects/lib/breadcrumbs/breadcrumbs.html","../../../projects/lib/breadcrumbs/breadcrumbs-item.ts","../../../projects/lib/breadcrumbs/breadcrumbs-item.html","../../../projects/lib/breadcrumbs/ngwr-breadcrumbs.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\n/** Escape a string for use inside a double-quoted CSS `<string>`. */\nfunction cssString(value: string): string {\n return value.replace(/[\\\\\"]/g, '\\\\$&').replace(/[\\n\\r\\f]/g, char => `\\\\${char.codePointAt(0)!.toString(16)} `);\n}\n\n/**\n * Breadcrumb navigation. Project `<wr-breadcrumbs-item>` children — each keeps\n * its own element and takes `role=\"listitem\"` inside the `<ol>` rather than\n * rendering an `<li>`, separated by the configured glyph (default `/`). The\n * container exposes the `nav[aria-label]` landmark required by WCAG.\n *\n * @example\n * ```html\n * <wr-breadcrumbs>\n * <wr-breadcrumbs-item routerLink=\"/\">Home</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item routerLink=\"/docs\">Docs</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item>Current</wr-breadcrumbs-item>\n * </wr-breadcrumbs>\n *\n * <!-- Custom separator -->\n * <wr-breadcrumbs separator=\"›\">…</wr-breadcrumbs>\n * ```\n *\n * @see https://ngwr.dev/reference/components/breadcrumbs\n */\n@Component({\n selector: 'wr-breadcrumbs',\n templateUrl: './breadcrumbs.html',\n styleUrl: './breadcrumbs.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-breadcrumbs',\n '[style.--wr-breadcrumbs-separator]': 'separatorValue()',\n },\n})\nexport class WrBreadcrumbs {\n /** Separator glyph between items. Any short string. @default '/' */\n readonly separator = input('/');\n\n /**\n * Accessible label for the `nav` landmark. Falls back to `breadcrumbs.label`,\n * then `'Breadcrumbs'`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n // The English default used to live on the input itself, which made this the one\n // landmark in the library a catalog could not reach: `wr-anchor` and `wr-sidebar`\n // announced in Russian on the same page while this one stayed \"Breadcrumbs\", and\n // the only escape was restating `[ariaLabel]` on every trail.\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'breadcrumbs.label', 'Breadcrumbs');\n\n // The glyph is WRAPPED in quotes here and unwrapped by `content:` in the\n // stylesheet, so an unescaped `\"` inside it closes the library's own string\n // and the rest of the value is parsed as CSS — `/\" url(\"…\") \"` computes to\n // `content: \"/\" url(\"…\") \"\"`, an image the browser fetches. Escaping is the\n // whole fix, and it is lossless: a separator that IS a quote still renders.\n protected readonly separatorValue = computed(() => `\"${cssString(this.separator())}\"`);\n}\n","<nav class=\"wr-breadcrumbs__nav\" [attr.aria-label]=\"resolvedAriaLabel()\">\n <ol class=\"wr-breadcrumbs__list\">\n <ng-content />\n </ol>\n</nav>\n","/**\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 { NgTemplateOutlet } from '@angular/common';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\n\n/**\n * One row inside `<wr-breadcrumbs>`. The host itself is the row — a\n * `<wr-breadcrumbs-item role=\"listitem\" class=\"wr-breadcrumbs__item\">`\n * inside the parent's `<ol>` — and it contains either a real\n * `<a class=\"wr-breadcrumbs__link\">` (when `[href]` or `[routerLink]` is\n * set) or, for the current crumb, a non-interactive\n * `<a class=\"wr-breadcrumbs__current\" role=\"text\" tabindex=\"-1\"\n * aria-current=\"page\">` (when neither is set — typically the last crumb).\n *\n * @example\n * ```html\n * <wr-breadcrumbs-item icon=\"home\" routerLink=\"/\">Home</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item href=\"https://ngwr.dev\">External</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item>Current page</wr-breadcrumbs-item>\n * ```\n */\n@Component({\n selector: 'wr-breadcrumbs-item',\n templateUrl: './breadcrumbs-item.html',\n encapsulation: ViewEncapsulation.None,\n imports: [NgTemplateOutlet, RouterLink, WrIcon],\n host: { class: 'wr-breadcrumbs__item', role: 'listitem' },\n})\nexport class WrBreadcrumbsItem {\n /** Plain anchor href. Overridden by `routerLink` when both are set. */\n readonly href = input<string | null>(null);\n\n /** Angular router target. Anything `RouterLink` accepts (string or `any[]`). */\n readonly routerLink = input<string | readonly unknown[] | null>(null);\n\n /** Open external `href` in a new tab. Ignored when `routerLink` is set. @default false */\n readonly external = input(false);\n\n /** Optional leading icon rendered inline before the label. @default null */\n readonly icon = input<WrIconName | null>(null);\n\n protected readonly isLink = computed(() => this.href() != null || this.routerLink() != null);\n protected readonly isRouter = computed(() => this.routerLink() != null);\n\n protected readonly rootClass = computed(() => (this.isLink() ? 'wr-breadcrumbs__link' : 'wr-breadcrumbs__current'));\n}\n","<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them — the\n last in static order — and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null —\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\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-burger.mjs
CHANGED
|
@@ -49,10 +49,10 @@ class WrBurger {
|
|
|
49
49
|
return;
|
|
50
50
|
this.open.set(!this.open());
|
|
51
51
|
}
|
|
52
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
53
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.
|
|
52
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBurger, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
53
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: WrBurger, isStandalone: true, selector: "wr-burger", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"wr-burger__btn\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-label]=\"resolvedLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n <svg class=\"wr-burger__icon\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n class=\"wr-burger__line wr-burger__line--1\"\n d=\"M 20,29 H 80 C 80,29 94.5,28.8 94.5,66.7 94.5,78 91,81.7 85.3,81.7 79.6,81.7 75,75 75,75 L 25,25\"\n />\n <path class=\"wr-burger__line wr-burger__line--2\" d=\"M 20,50 H 80\" />\n <path\n class=\"wr-burger__line wr-burger__line--3\"\n d=\"M 20,71 H 80 C 80,71 94.5,71.2 94.5,33.3 94.5,22 91,18.3 85.3,18.3 79.6,18.3 75,25 75,25 L 25,75\"\n />\n </svg>\n</button>\n", encapsulation: i0.ViewEncapsulation.None });
|
|
54
54
|
}
|
|
55
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
55
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBurger, decorators: [{
|
|
56
56
|
type: Component,
|
|
57
57
|
args: [{ selector: 'wr-burger', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<button\n type=\"button\"\n class=\"wr-burger__btn\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-label]=\"resolvedLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n <svg class=\"wr-burger__icon\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n class=\"wr-burger__line wr-burger__line--1\"\n d=\"M 20,29 H 80 C 80,29 94.5,28.8 94.5,66.7 94.5,78 91,81.7 85.3,81.7 79.6,81.7 75,75 75,75 L 25,25\"\n />\n <path class=\"wr-burger__line wr-burger__line--2\" d=\"M 20,50 H 80\" />\n <path\n class=\"wr-burger__line wr-burger__line--3\"\n d=\"M 20,71 H 80 C 80,71 94.5,71.2 94.5,33.3 94.5,22 91,18.3 85.3,18.3 79.6,18.3 75,25 75,25 L 25,75\"\n />\n </svg>\n</button>\n" }]
|
|
58
58
|
}], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-burger.mjs","sources":["../../../projects/lib/burger/burger.ts","../../../projects/lib/burger/burger.html","../../../projects/lib/burger/ngwr-burger.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, model } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\n/**\n * Animated menu toggle — three SVG strokes morph between a hamburger and a\n * close mark on `open`. Two-way bindable, so it pairs naturally with a\n * `<wr-drawer>` or any disclosure.\n *\n * The morph is pure CSS (`stroke-dasharray` / `stroke-dashoffset` tweens),\n * so it stays smooth without JS and collapses to its end state under\n * `prefers-reduced-motion`.\n *\n * @example Toggle a drawer\n * ```html\n * <wr-burger [(open)]=\"menuOpen\" />\n * <wr-drawer [(open)]=\"menuOpen\" position=\"right\">…</wr-drawer>\n * ```\n *\n * @see https://ngwr.dev/reference/components/burger\n */\n@Component({\n selector: 'wr-burger',\n templateUrl: './burger.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrBurger {\n /** Two-way bindable open state. Drives the hamburger ↔ close morph. @default false */\n readonly open = model(false);\n\n /**\n * Accessible name for the toggle button. Falls back to `burger.label`, then\n * `'Toggle menu'`.\n */\n readonly label = input<string | null>(null);\n\n protected readonly resolvedLabel = useI18nText(this.label, 'burger.label', 'Toggle menu');\n\n /** Disable the toggle. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => ({\n 'wr-burger': true,\n 'wr-burger--opened': this.open(),\n }));\n\n protected toggle(): void {\n if (this.disabled()) return;\n this.open.set(!this.open());\n }\n}\n","<button\n type=\"button\"\n class=\"wr-burger__btn\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-label]=\"resolvedLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n <svg class=\"wr-burger__icon\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n class=\"wr-burger__line wr-burger__line--1\"\n d=\"M 20,29 H 80 C 80,29 94.5,28.8 94.5,66.7 94.5,78 91,81.7 85.3,81.7 79.6,81.7 75,75 75,75 L 25,25\"\n />\n <path class=\"wr-burger__line wr-burger__line--2\" d=\"M 20,50 H 80\" />\n <path\n class=\"wr-burger__line wr-burger__line--3\"\n d=\"M 20,71 H 80 C 80,71 94.5,71.2 94.5,33.3 94.5,22 91,18.3 85.3,18.3 79.6,18.3 75,25 75,25 L 25,75\"\n />\n </svg>\n</button>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;AAAA;;;;;AAKG;AAOH;;;;;;;;;;;;;;;;AAgBG;MAOU,QAAQ,CAAA;;IAEV,IAAI,GAAG,KAAK,CAAC,KAAK;6EAAC;AAE5B;;;AAGG;IACM,KAAK,GAAG,KAAK,CAAgB,IAAI;8EAAC;IAExB,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,aAAa,CAAC;;IAGhF,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;AAEnD,IAAA,OAAO,GAAG,QAAQ,CAAC,OAAO;AAC3C,QAAA,WAAW,EAAE,IAAI;AACjB,QAAA,mBAAmB,EAAE,IAAI,CAAC,IAAI,EAAE;KACjC,CAAC;gFAAC;IAEO,MAAM,GAAA;QACd,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;QACrB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC7B;uGAvBW,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAR,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAQ,ghBCnCrB,gwBAoBA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDea,QAAQ,EAAA,UAAA,EAAA,CAAA;kBANpB,SAAS;+BACE,WAAW,EAAA,aAAA,EAEN,iBAAiB,CAAC,IAAI,QAC/B,EAAE,SAAS,EAAE,WAAW,EAAE,EAAA,QAAA,EAAA,gwBAAA,EAAA;;;AEjClC;;AAEG
|
|
1
|
+
{"version":3,"file":"ngwr-burger.mjs","sources":["../../../projects/lib/burger/burger.ts","../../../projects/lib/burger/burger.html","../../../projects/lib/burger/ngwr-burger.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, model } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\n/**\n * Animated menu toggle — three SVG strokes morph between a hamburger and a\n * close mark on `open`. Two-way bindable, so it pairs naturally with a\n * `<wr-drawer>` or any disclosure.\n *\n * The morph is pure CSS (`stroke-dasharray` / `stroke-dashoffset` tweens),\n * so it stays smooth without JS and collapses to its end state under\n * `prefers-reduced-motion`.\n *\n * @example Toggle a drawer\n * ```html\n * <wr-burger [(open)]=\"menuOpen\" />\n * <wr-drawer [(open)]=\"menuOpen\" position=\"right\">…</wr-drawer>\n * ```\n *\n * @see https://ngwr.dev/reference/components/burger\n */\n@Component({\n selector: 'wr-burger',\n templateUrl: './burger.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrBurger {\n /** Two-way bindable open state. Drives the hamburger ↔ close morph. @default false */\n readonly open = model(false);\n\n /**\n * Accessible name for the toggle button. Falls back to `burger.label`, then\n * `'Toggle menu'`.\n */\n readonly label = input<string | null>(null);\n\n protected readonly resolvedLabel = useI18nText(this.label, 'burger.label', 'Toggle menu');\n\n /** Disable the toggle. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => ({\n 'wr-burger': true,\n 'wr-burger--opened': this.open(),\n }));\n\n protected toggle(): void {\n if (this.disabled()) return;\n this.open.set(!this.open());\n }\n}\n","<button\n type=\"button\"\n class=\"wr-burger__btn\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-label]=\"resolvedLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n <svg class=\"wr-burger__icon\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n class=\"wr-burger__line wr-burger__line--1\"\n d=\"M 20,29 H 80 C 80,29 94.5,28.8 94.5,66.7 94.5,78 91,81.7 85.3,81.7 79.6,81.7 75,75 75,75 L 25,25\"\n />\n <path class=\"wr-burger__line wr-burger__line--2\" d=\"M 20,50 H 80\" />\n <path\n class=\"wr-burger__line wr-burger__line--3\"\n d=\"M 20,71 H 80 C 80,71 94.5,71.2 94.5,33.3 94.5,22 91,18.3 85.3,18.3 79.6,18.3 75,25 75,25 L 25,75\"\n />\n </svg>\n</button>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;AAAA;;;;;AAKG;AAOH;;;;;;;;;;;;;;;;AAgBG;MAOU,QAAQ,CAAA;;IAEV,IAAI,GAAG,KAAK,CAAC,KAAK;6EAAC;AAE5B;;;AAGG;IACM,KAAK,GAAG,KAAK,CAAgB,IAAI;8EAAC;IAExB,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,aAAa,CAAC;;IAGhF,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;AAEnD,IAAA,OAAO,GAAG,QAAQ,CAAC,OAAO;AAC3C,QAAA,WAAW,EAAE,IAAI;AACjB,QAAA,mBAAmB,EAAE,IAAI,CAAC,IAAI,EAAE;KACjC,CAAC;gFAAC;IAEO,MAAM,GAAA;QACd,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;QACrB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC7B;uGAvBW,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAR,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAQ,ghBCnCrB,gwBAoBA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDea,QAAQ,EAAA,UAAA,EAAA,CAAA;kBANpB,SAAS;+BACE,WAAW,EAAA,aAAA,EAEN,iBAAiB,CAAC,IAAI,QAC/B,EAAE,SAAS,EAAE,WAAW,EAAE,EAAA,QAAA,EAAA,gwBAAA,EAAA;;;AEjClC;;AAEG;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-button-testing.mjs","sources":["../../../projects/lib/button/testing/wr-button-harness.ts","../../../projects/lib/button/testing/ngwr-button-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport { WR_COLORS, type WrColor } from 'ngwr/theme';\n\nimport type { WrButtonHarnessFilters } from './interfaces';\n\n/**\n * Test harness for `<wr-btn>` — drive a button from a consumer's spec without\n * knowing how it is built.\n *\n * Everything this reads is public API: the `wr-btn` selector, the\n * `.wr-btn__label` element, the `wr-btn--*` modifiers and the disabled attributes.\n * `<wr-btn>` is deliberately NOT always a native `<button>` — the element form\n * exists so a link or a custom host can be one — which is why the disabled state\n * is answered from the ATTRIBUTES rather than from `el.disabled`, a property half\n * of those shapes do not have.\n *\n * @example\n * ```ts\n * const loader = TestbedHarnessEnvironment.loader(fixture);\n * const save = await loader.getHarness(WrButtonHarness.with({ text: 'Save' }));\n *\n * expect(await save.isDisabled()).toBe(false);\n * await save.click();\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrButtonHarness extends ComponentHarness {\n /** Every shape the button ships in: the element, and the two attribute forms. */\n static hostSelector = 'wr-btn, button[wr-btn], a[wr-btn]';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrButtonHarnessFilters = {}): HarnessPredicate<WrButtonHarness> {\n return new HarnessPredicate(WrButtonHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled);\n }\n\n /** The button's visible label, trimmed. Icons and the spinner are not part of it. */\n async getText(): Promise<string> {\n return (await this.locatorFor('.wr-btn__label')()).text();\n }\n\n /**\n * Whether the button refuses interaction.\n *\n * Both signals are read, because the component sets them for different reasons:\n * `disabled` lands on every shape (it is inert on a custom element, which is\n * exactly why `aria-disabled` exists as well, but it is the attribute that is\n * always there). A button that is merely LOADING also answers `true` here, and\n * that is not a quirk — by default a loading button refuses clicks.\n */\n async isDisabled(): Promise<boolean> {\n const host = await this.host();\n if ((await host.getAttribute('disabled')) !== null) return true;\n return (await host.getAttribute('aria-disabled')) === 'true';\n }\n\n /** Whether the button is showing its loading spinner. */\n async isLoading(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-btn__spin')()) !== null;\n }\n\n /**\n * The intent colour, or `null` when the button carries none.\n *\n * Matched against `WR_COLORS` rather than \"the first `wr-btn--*` class\": the\n * modifier list also carries the size, the shape, `outlined`, `block`, `loading`\n * and the icon position, so a pattern match answers `icon` as readily as\n * `primary`.\n */\n async getColor(): Promise<WrColor | null> {\n const classes = (await (await this.host()).getAttribute('class')) ?? '';\n const present = classes.split(/\\s+/);\n return WR_COLORS.find(color => present.includes(`wr-btn--${color}`)) ?? null;\n }\n\n /** Click the button. A disabled button is still clicked — assert, do not assume. */\n async click(): Promise<void> {\n return (await this.host()).click();\n }\n\n /** Move keyboard focus to the button. */\n async focus(): Promise<void> {\n return (await this.host()).focus();\n }\n\n /** Whether the button currently has focus. */\n async isFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAAA;;;;;AAKG;AAQH;;;;;;;;;;;;;;;;;;;;;AAqBG;AACG,MAAO,eAAgB,SAAQ,gBAAgB,CAAA;;AAEnD,IAAA,OAAO,YAAY,GAAG,mCAAmC;;AAGzD,IAAA,OAAO,IAAI,CAAC,OAAA,GAAkC,EAAE,EAAA;AAC9C,QAAA,OAAO,IAAI,gBAAgB,CAAC,eAAe,EAAE,OAAO;aACjD,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC;aAC1G,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,MAAM,QAAQ,CAAC;IACpH;;AAGA,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,EAAE,IAAI,EAAE;IAC3D;AAEA;;;;;;;;AAQG;AACH,IAAA,MAAM,UAAU,GAAA;AACd,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE;QAC9B,IAAI,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,IAAI;AAAE,YAAA,OAAO,IAAI;QAC/D,OAAO,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,MAAM;IAC9D;;AAGA,IAAA,MAAM,SAAS,GAAA;AACb,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,EAAE,MAAM,IAAI;IACpE;AAEA;;;;;;;AAOG;AACH,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE;QACvE,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AACpC,QAAA,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,KAAK,CAAA,CAAE,CAAC,CAAC,IAAI,IAAI;IAC9E;;AAGA,IAAA,MAAM,KAAK,GAAA;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE;IACpC;;AAGA,IAAA,MAAM,KAAK,GAAA;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE;IACpC;;AAGA,IAAA,MAAM,SAAS,GAAA;QACb,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE;IACxC;;;AClGF;;AAEG
|
|
1
|
+
{"version":3,"file":"ngwr-button-testing.mjs","sources":["../../../projects/lib/button/testing/wr-button-harness.ts","../../../projects/lib/button/testing/ngwr-button-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport { WR_COLORS, type WrColor } from 'ngwr/theme';\n\nimport type { WrButtonHarnessFilters } from './interfaces';\n\n/**\n * Test harness for `<wr-btn>` — drive a button from a consumer's spec without\n * knowing how it is built.\n *\n * Everything this reads is public API: the `wr-btn` selector, the\n * `.wr-btn__label` element, the `wr-btn--*` modifiers and the disabled attributes.\n * `<wr-btn>` is deliberately NOT always a native `<button>` — the element form\n * exists so a link or a custom host can be one — which is why the disabled state\n * is answered from the ATTRIBUTES rather than from `el.disabled`, a property half\n * of those shapes do not have.\n *\n * @example\n * ```ts\n * const loader = TestbedHarnessEnvironment.loader(fixture);\n * const save = await loader.getHarness(WrButtonHarness.with({ text: 'Save' }));\n *\n * expect(await save.isDisabled()).toBe(false);\n * await save.click();\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrButtonHarness extends ComponentHarness {\n /** Every shape the button ships in: the element, and the two attribute forms. */\n static hostSelector = 'wr-btn, button[wr-btn], a[wr-btn]';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrButtonHarnessFilters = {}): HarnessPredicate<WrButtonHarness> {\n return new HarnessPredicate(WrButtonHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled);\n }\n\n /** The button's visible label, trimmed. Icons and the spinner are not part of it. */\n async getText(): Promise<string> {\n return (await this.locatorFor('.wr-btn__label')()).text();\n }\n\n /**\n * Whether the button refuses interaction.\n *\n * Both signals are read, because the component sets them for different reasons:\n * `disabled` lands on every shape (it is inert on a custom element, which is\n * exactly why `aria-disabled` exists as well, but it is the attribute that is\n * always there). A button that is merely LOADING also answers `true` here, and\n * that is not a quirk — by default a loading button refuses clicks.\n */\n async isDisabled(): Promise<boolean> {\n const host = await this.host();\n if ((await host.getAttribute('disabled')) !== null) return true;\n return (await host.getAttribute('aria-disabled')) === 'true';\n }\n\n /** Whether the button is showing its loading spinner. */\n async isLoading(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-btn__spin')()) !== null;\n }\n\n /**\n * The intent colour, or `null` when the button carries none.\n *\n * Matched against `WR_COLORS` rather than \"the first `wr-btn--*` class\": the\n * modifier list also carries the size, the shape, `outlined`, `block`, `loading`\n * and the icon position, so a pattern match answers `icon` as readily as\n * `primary`.\n */\n async getColor(): Promise<WrColor | null> {\n const classes = (await (await this.host()).getAttribute('class')) ?? '';\n const present = classes.split(/\\s+/);\n return WR_COLORS.find(color => present.includes(`wr-btn--${color}`)) ?? null;\n }\n\n /** Click the button. A disabled button is still clicked — assert, do not assume. */\n async click(): Promise<void> {\n return (await this.host()).click();\n }\n\n /** Move keyboard focus to the button. */\n async focus(): Promise<void> {\n return (await this.host()).focus();\n }\n\n /** Whether the button currently has focus. */\n async isFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAAA;;;;;AAKG;AAQH;;;;;;;;;;;;;;;;;;;;;AAqBG;AACG,MAAO,eAAgB,SAAQ,gBAAgB,CAAA;;AAEnD,IAAA,OAAO,YAAY,GAAG,mCAAmC;;AAGzD,IAAA,OAAO,IAAI,CAAC,OAAA,GAAkC,EAAE,EAAA;AAC9C,QAAA,OAAO,IAAI,gBAAgB,CAAC,eAAe,EAAE,OAAO;aACjD,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC;aAC1G,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,MAAM,QAAQ,CAAC;IACpH;;AAGA,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,EAAE,IAAI,EAAE;IAC3D;AAEA;;;;;;;;AAQG;AACH,IAAA,MAAM,UAAU,GAAA;AACd,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE;QAC9B,IAAI,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,IAAI;AAAE,YAAA,OAAO,IAAI;QAC/D,OAAO,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,MAAM;IAC9D;;AAGA,IAAA,MAAM,SAAS,GAAA;AACb,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,EAAE,MAAM,IAAI;IACpE;AAEA;;;;;;;AAOG;AACH,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE;QACvE,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AACpC,QAAA,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,KAAK,CAAA,CAAE,CAAC,CAAC,IAAI,IAAI;IAC9E;;AAGA,IAAA,MAAM,KAAK,GAAA;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE;IACpC;;AAGA,IAAA,MAAM,KAAK,GAAA;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE;IACpC;;AAGA,IAAA,MAAM,SAAS,GAAA;QACb,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE;IACxC;;;AClGF;;AAEG;;"}
|
package/fesm2022/ngwr-button.mjs
CHANGED
|
@@ -265,10 +265,10 @@ class WrButton {
|
|
|
265
265
|
return parts.join(' ');
|
|
266
266
|
}, /* @ts-ignore */
|
|
267
267
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
268
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
269
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
268
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
269
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: WrButton, isStandalone: true, selector: "wr-btn, button[wr-btn], a[wr-btn]", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, outlined: { classPropertyName: "outlined", publicName: "outlined", isSignal: true, isRequired: false, transformFunction: null }, block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabledWhenLoading: { classPropertyName: "disabledWhenLoading", publicName: "disabledWhenLoading", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown": "onHostKeydown($event)", "focus": "onHostFocus()", "blur": "onHostBlur()" }, properties: { "class": "classes()", "attr.disabled": "nativeDisabled()", "attr.aria-busy": "loading() ? \"true\" : null", "attr.role": "hostRole()", "attr.tabindex": "hostTabIndex()", "attr.aria-disabled": "hostAriaDisabled()" } }, ngImport: i0, template: "@if (loading()) {\n <wr-spinner class=\"wr-btn__spin\" size=\"sm\" />\n}\n\n@if (icon(); as name) {\n <wr-icon class=\"wr-btn__icon\" [name]=\"name\" />\n}\n\n<span class=\"wr-btn__label\">\n <ng-content />\n</span>\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }, { kind: "component", type: WrSpinner, selector: "wr-spinner", inputs: ["size", "ariaLabel"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
270
270
|
}
|
|
271
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
271
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrButton, decorators: [{
|
|
272
272
|
type: Component,
|
|
273
273
|
args: [{ selector: 'wr-btn, button[wr-btn], a[wr-btn]', encapsulation: ViewEncapsulation.None, host: {
|
|
274
274
|
'[class]': 'classes()',
|
|
@@ -331,10 +331,10 @@ class WrButtonGroup {
|
|
|
331
331
|
return parts.join(' ');
|
|
332
332
|
}, /* @ts-ignore */
|
|
333
333
|
...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
334
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
335
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.
|
|
334
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrButtonGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
335
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: WrButtonGroup, isStandalone: true, selector: "wr-btn-group", inputs: { shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group" }, properties: { "class": "hostClasses()" } }, providers: [{ provide: WR_BUTTON_GROUP, useExisting: forwardRef(() => WrButtonGroup) }], ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
|
|
336
336
|
}
|
|
337
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
337
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrButtonGroup, decorators: [{
|
|
338
338
|
type: Component,
|
|
339
339
|
args: [{
|
|
340
340
|
selector: 'wr-btn-group',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-button.mjs","sources":["../../../projects/lib/button/tokens/button-group.token.ts","../../../projects/lib/button/button.ts","../../../projects/lib/button/button.html","../../../projects/lib/button/button-group.ts","../../../projects/lib/button/ngwr-button.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 { InjectionToken, type Signal } from '@angular/core';\n\nimport type { WrButtonShape } from '../interfaces';\n\n/**\n * Contract a child `<wr-btn>` reads from its enclosing `<wr-btn-group>`.\n *\n * @internal\n */\nexport interface WrButtonGroupContext {\n /** Shape cascade — child buttons fall back to this when they don't set their own. */\n readonly shape: Signal<WrButtonShape | null>;\n}\n\n/**\n * Token a `<wr-btn>` injects to discover its parent `<wr-btn-group>`. The\n * group provides itself via this token so children can react to the\n * group's `shape` cascade.\n *\n * @internal\n */\nexport const WR_BUTTON_GROUP = new InjectionToken<WrButtonGroupContext>('WR_BUTTON_GROUP');\n","/**\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 {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n} from '@angular/core';\n\nimport { useConfigValue } from 'ngwr/config';\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\nimport { WrSpinner } from 'ngwr/spinner';\nimport type { WrColor } from 'ngwr/theme';\n\nimport type { WrButtonIconPosition, WrButtonShape, WrButtonSize } from './interfaces';\nimport { WR_BUTTON_GROUP } from './tokens';\n\n/**\n * Trigger an action. Renders as a `<wr-btn>` element, or attach to a\n * native `<button>` / `<a>` via the `wr-btn` attribute selector.\n *\n * @example\n * ```html\n * <button wr-btn color=\"primary\">Save</button>\n * <a wr-btn color=\"primary\" outlined>Cancel</a>\n * <wr-btn color=\"danger\" icon=\"trash\">Delete</wr-btn>\n * <wr-btn color=\"primary\" shape=\"pill\">Pill</wr-btn>\n * ```\n *\n * **Squircle?** Wrap with `[wrSquircle]` — the directive is the only\n * way ngwr ships smooth-corner clip-paths:\n *\n * ```html\n * <wr-btn wrSquircle [radius]=\"14\">Squircle</wr-btn>\n * ```\n *\n * Inside a `<wr-btn-group shape=\"…\">`, the group's shape is enforced on\n * every child — child `[shape]` inputs are ignored so the group reads as\n * one coherent control.\n *\n * **Inside a `<form>`, use the native form.** `<wr-btn>` is a custom element\n * carrying `role=\"button\"`, and no custom element submits a form — the platform\n * submits for `<button>`, `<input type=\"submit\">` and `<input type=\"image\">`\n * and nothing else. That is why there is no `type` input: it would look like it\n * worked. Implicit submission (Enter in a text field) does not reach it either.\n *\n * ```html\n * <button wr-btn type=\"submit\" color=\"primary\">Save</button>\n * ```\n *\n * @see https://ngwr.dev/reference/components/button\n */\n@Component({\n selector: 'wr-btn, button[wr-btn], a[wr-btn]',\n templateUrl: './button.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.disabled]': 'nativeDisabled()',\n '[attr.aria-busy]': 'loading() ? \"true\" : null',\n // The three below apply ONLY to the `<wr-btn>` element form — see\n // `isCustomHost`. A native `<button>` / `<a>` already has all of it.\n '[attr.role]': 'hostRole()',\n '[attr.tabindex]': 'hostTabIndex()',\n '[attr.aria-disabled]': 'hostAriaDisabled()',\n '(keydown)': 'onHostKeydown($event)',\n '(focus)': 'onHostFocus()',\n '(blur)': 'onHostBlur()',\n },\n imports: [WrIcon, WrSpinner],\n})\nexport class WrButton {\n /**\n * Color variant. Omit for the neutral default style.\n *\n * Deliberately NOT configurable app-wide: the library's own chrome binds\n * `[color]=\"isCurrent ? 'primary' : null\"`, where `null` means neutral, and a\n * configured intent would repaint every one of those buttons. See `WrConfig`.\n *\n * @default null\n */\n readonly color = input<WrColor | null>(null);\n\n /**\n * Size variant. Unset, it resolves through\n * `provideWrConfig({ button: { size } })` and then to `md`.\n *\n * @default 'md'\n */\n readonly size = input<WrButtonSize | null>(null);\n\n /**\n * Corner treatment — `rounded`, `pill` or `squircle`. `null` (default) falls\n * back to `rounded`. Inside a `<wr-btn-group shape=\"…\">`, the group's shape\n * ALWAYS wins over this input — the group enforces a consistent corner\n * treatment across its members.\n *\n * @default null\n */\n readonly shape = input<WrButtonShape | null>(null);\n\n /**\n * Icon name to render alongside the label. The icon is hidden while\n * `loading` is `true` so the spinner can take its place.\n *\n * @default null\n */\n readonly icon = input<WrIconName | null>(null);\n\n /** Position of the icon relative to the label. @default 'start' */\n readonly iconPosition = input<WrButtonIconPosition>('start');\n\n /** Disable the button. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /** Outlined variant — colored text and border on a transparent background. @default false */\n readonly outlined = input(false, { transform: coerceBooleanProperty });\n\n /** Stretch the button to fill its parent's width. @default false */\n readonly block = input(false, { transform: coerceBooleanProperty });\n\n /** Show a spinner overlaying the label. Layout is preserved. @default false */\n readonly loading = input(false, { transform: coerceBooleanProperty });\n\n /**\n * When `loading` is `true` and this is also `true`, pointer events are\n * suppressed and the button reports as disabled to assistive tech.\n *\n * @default true\n */\n readonly disabledWhenLoading = input(true, { transform: coerceBooleanProperty });\n\n private readonly group = inject(WR_BUTTON_GROUP, { optional: true });\n\n /** The size, or the app-wide default, or `md`. @see useConfigValue */\n protected readonly resolvedSize = useConfigValue<WrButtonSize>(this.size, c => c.button?.size, 'md');\n\n /**\n * Resolved shape. Inside a `<wr-btn-group>`, the group ALWAYS wins — child\n * `[shape]` is ignored entirely so the group reads as one coherent control.\n * Outside a group, the button's own `[shape]` is used, falling back to\n * `rounded`. Not config-resolved: see `WrConfig` for why a boolean cannot\n * express this three-valued input.\n */\n protected readonly resolvedShape = computed<WrButtonShape>(() =>\n this.group ? (this.group.shape() ?? 'rounded') : (this.shape() ?? 'rounded')\n );\n\n private readonly hostEl = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /**\n * Whether this instance is the `<wr-btn>` ELEMENT rather than the attribute\n * form on a native `<button>` / `<a>`.\n *\n * The element form is documented as first-class and is what the pagination,\n * event-calendar and popconfirm chrome use — but a custom element has no\n * button semantics of its own. It was rendering with no `role`, no\n * `tabindex` and no keyboard activation, so it was invisible to assistive\n * tech and unreachable by Tab. Measured in Chromium against the built site:\n * the whole `wr-pagination` subtree, 26 elements, contained ZERO focusable\n * nodes and sixty Tab presses never entered it. axe cannot see this — an\n * unknown element with no role simply is not an interactive control to it,\n * which is the same blind spot that lets `disabled` pass unnoticed on a\n * custom element.\n */\n private readonly isCustomHost = this.hostEl.nativeElement.tagName === 'WR-BTN';\n\n private readonly isOff = computed(() => this.disabled() || (this.loading() && this.disabledWhenLoading()));\n\n protected readonly nativeDisabled = computed<'' | null>(() => (this.isOff() ? '' : null));\n\n protected readonly hostRole = computed<'button' | null>(() => (this.isCustomHost ? 'button' : null));\n\n /** Out of the tab order while off — `disabled` is inert on a custom element. */\n protected readonly hostTabIndex = computed<'0' | null>(() => (this.isCustomHost && !this.isOff() ? '0' : null));\n\n protected readonly hostAriaDisabled = computed<'true' | null>(() =>\n this.isCustomHost && this.isOff() ? 'true' : null\n );\n\n /**\n * Enter and Space activate a button. A native one does this for free; a\n * custom element does not, so without this the element form could be focused\n * (once it had a tabindex) and still not be operable.\n *\n * `preventDefault` on Space is not optional — it scrolls the page otherwise.\n * The pointer path needs no guard here: `.wr-btn[disabled]` already sets\n * `pointer-events: none`.\n */\n protected onHostKeydown(event: KeyboardEvent): void {\n if (!this.isCustomHost) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n\n event.preventDefault();\n if (this.isOff()) return;\n this.hostEl.nativeElement.click();\n }\n\n private readonly injector = inject(Injector);\n\n /**\n * Whether this button is the one the caret was on, so it can be handed back\n * the focus that goes missing while it is off.\n *\n * A control that becomes `disabled` while focused stops being a focusable\n * area, and the browser runs the unfocusing steps: nothing else is nominated,\n * so the caret lands on `<body>`. With `disabledWhenLoading` on by default\n * that happens on EVERY async button — a keyboard user presses Enter on\n * \"Save\" and the next Tab restarts from the top of the document, while a\n * screen-reader user is told neither that the wait began nor that it ended,\n * because the element they were on has left the a11y tree. The `<wr-btn>`\n * element form loses its `tabindex` instead of gaining `disabled` and is\n * unfocused for the same reason.\n *\n * Deliberately NOT keyed on reading `activeElement` when `isOff()` flips: an\n * effect in this component's own view runs AFTER the parent has applied this\n * directive's host bindings, so by then the attribute has landed and the\n * browser has already moved the caret — the read would answer `<body>` on\n * every real browser and the button on jsdom, which is the worst of both.\n *\n * The flag is written by the focus listeners instead, and a `blur` fired\n * WHILE off keeps it set rather than clearing it: that blur is the browser\n * taking the caret away, not the user leaving. A browser that fires no blur\n * on disable at all is covered too — the flag simply stays as `focus` left it,\n * and the `<body>` test below is what decides whether the focus is orphaned.\n */\n private hadFocus = false;\n\n /** @internal Host `focus` — see `hadFocus`. */\n protected onHostFocus(): void {\n this.hadFocus = true;\n }\n\n /** @internal Host `blur` — see `hadFocus`. */\n protected onHostBlur(): void {\n this.hadFocus = this.isOff();\n }\n\n constructor() {\n effect(() => {\n if (this.isOff()) return;\n if (!this.hadFocus) return;\n const el = this.hostEl.nativeElement;\n\n // Deferred: the host binding that drops `disabled` (or restores the\n // `tabindex`) has not necessarily run yet, and `focus()` on a still\n // disabled element is a silent no-op — the exact failure this is here to\n // fix.\n afterNextRender(\n () => {\n if (!this.hadFocus || this.isOff()) return;\n const doc = el.ownerDocument;\n const active = doc?.activeElement ?? null;\n // Still ours — nothing was ever taken away, so keep the flag for the\n // cycle that does take it.\n if (active === el) return;\n // Someone else owns the caret now: a user who tabbed on while the\n // request was in flight must not be yanked back to a button they have\n // finished with.\n this.hadFocus = false;\n if (active && doc && active !== doc.body) return;\n el.focus();\n },\n { injector: this.injector }\n );\n });\n }\n\n protected readonly classes = computed(() => {\n const parts = ['wr-btn'];\n\n const color = this.color();\n if (color) parts.push(`wr-btn--${color}`);\n\n const size = this.resolvedSize();\n if (size !== 'md') parts.push(`wr-btn--${size}`);\n\n const shape = this.resolvedShape();\n if (shape !== 'rounded') parts.push(`wr-btn--${shape}`);\n\n if (this.outlined()) parts.push('wr-btn--outlined');\n if (this.block()) parts.push('wr-btn--block');\n if (this.loading()) parts.push('wr-btn--loading');\n\n const hasAdornment = !!this.icon() || this.loading();\n if (hasAdornment) parts.push(`wr-btn--icon-${this.iconPosition()}`);\n\n return parts.join(' ');\n });\n}\n","@if (loading()) {\n <wr-spinner class=\"wr-btn__spin\" size=\"sm\" />\n}\n\n@if (icon(); as name) {\n <wr-icon class=\"wr-btn__icon\" [name]=\"name\" />\n}\n\n<span class=\"wr-btn__label\">\n <ng-content />\n</span>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, forwardRef, input } from '@angular/core';\n\nimport type { WrButtonShape } from './interfaces';\nimport { WR_BUTTON_GROUP, type WrButtonGroupContext } from './tokens';\n\n/**\n * Visually group buttons by merging their borders. Optionally enforce a\n * single corner treatment across every child via `[shape]` — child\n * `<wr-btn>` `[shape]` inputs are ignored when set on the group.\n *\n * @example\n * ```html\n * <wr-btn-group>\n * <button wr-btn>Left</button>\n * <button wr-btn>Middle</button>\n * <button wr-btn>Right</button>\n * </wr-btn-group>\n *\n * <wr-btn-group shape=\"pill\">\n * <button wr-btn>One</button>\n * <button wr-btn>Two</button>\n * <button wr-btn>Three</button>\n * </wr-btn-group>\n * ```\n *\n * @see https://ngwr.dev/reference/components/button-group\n */\n@Component({\n selector: 'wr-btn-group',\n template: '<ng-content />',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'hostClasses()',\n role: 'group',\n },\n // forwardRef required: WrButtonGroup is self-referenced before its declaration ends.\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n providers: [{ provide: WR_BUTTON_GROUP, useExisting: forwardRef(() => WrButtonGroup) }],\n})\nexport class WrButtonGroup implements WrButtonGroupContext {\n /**\n * Corner treatment enforced on every child `<wr-btn>`. Child `[shape]`\n * inputs are ignored when this is set — the group exists to make a\n * uniform control. `null` (default) leaves children alone.\n *\n * @default null\n */\n readonly shape = input<WrButtonShape | null>(null);\n\n protected readonly hostClasses = computed(() => {\n const parts = ['wr-btn-group'];\n const s = this.shape();\n if (s) parts.push(`wr-btn-group--${s}`);\n return parts.join(' ');\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;AAAA;;;;;AAKG;AAgBH;;;;;;AAMG;AACI,MAAM,eAAe,GAAG,IAAI,cAAc,CAAuB,iBAAiB,CAAC;;AC5B1F;;;;;AAKG;AAuBH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCG;MAoBU,QAAQ,CAAA;AACnB;;;;;;;;AAQG;IACM,KAAK,GAAG,KAAK,CAAiB,IAAI;8EAAC;AAE5C;;;;;AAKG;IACM,IAAI,GAAG,KAAK,CAAsB,IAAI;6EAAC;AAEhD;;;;;;;AAOG;IACM,KAAK,GAAG,KAAK,CAAuB,IAAI;8EAAC;AAElD;;;;;AAKG;IACM,IAAI,GAAG,KAAK,CAAoB,IAAI;6EAAC;;IAGrC,YAAY,GAAG,KAAK,CAAuB,OAAO;qFAAC;;IAGnD,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;;IAG7D,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;;IAG7D,KAAK,GAAG,KAAK,CAAC,KAAK,6EAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;;IAG1D,OAAO,GAAG,KAAK,CAAC,KAAK,+EAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;AAErE;;;;;AAKG;IACM,mBAAmB,GAAG,KAAK,CAAC,IAAI,2FAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;IAE/D,KAAK,GAAG,MAAM,CAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;AAGjD,IAAA,YAAY,GAAG,cAAc,CAAe,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC;AAEpG;;;;;;AAMG;AACgB,IAAA,aAAa,GAAG,QAAQ,CAAgB,MACzD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,SAAS,KAAK,IAAI,CAAC,KAAK,EAAE,IAAI,SAAS,CAAC;sFAC7E;AAEgB,IAAA,MAAM,GAAG,MAAM,CAA0B,UAAU,CAAC;AAErE;;;;;;;;;;;;;;AAcG;IACc,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,KAAK,QAAQ;IAE7D,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;8EAAC;AAEvF,IAAA,cAAc,GAAG,QAAQ,CAAY,OAAO,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;uFAAC;AAEtE,IAAA,QAAQ,GAAG,QAAQ,CAAkB,OAAO,IAAI,CAAC,YAAY,GAAG,QAAQ,GAAG,IAAI,CAAC;iFAAC;;IAGjF,YAAY,GAAG,QAAQ,CAAa,OAAO,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC;qFAAC;IAE5F,gBAAgB,GAAG,QAAQ,CAAgB,MAC5D,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,MAAM,GAAG,IAAI;yFAClD;AAED;;;;;;;;AAQG;AACO,IAAA,aAAa,CAAC,KAAoB,EAAA;QAC1C,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE;QACxB,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG;YAAE;QAEhD,KAAK,CAAC,cAAc,EAAE;QACtB,IAAI,IAAI,CAAC,KAAK,EAAE;YAAE;AAClB,QAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE;IACnC;AAEiB,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;IACK,QAAQ,GAAG,KAAK;;IAGd,WAAW,GAAA;AACnB,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;IACtB;;IAGU,UAAU,GAAA;AAClB,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE;IAC9B;AAEA,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;YACV,IAAI,IAAI,CAAC,KAAK,EAAE;gBAAE;YAClB,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE;AACpB,YAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa;;;;;YAMpC,eAAe,CACb,MAAK;gBACH,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,EAAE;oBAAE;AACpC,gBAAA,MAAM,GAAG,GAAG,EAAE,CAAC,aAAa;AAC5B,gBAAA,MAAM,MAAM,GAAG,GAAG,EAAE,aAAa,IAAI,IAAI;;;gBAGzC,IAAI,MAAM,KAAK,EAAE;oBAAE;;;;AAInB,gBAAA,IAAI,CAAC,QAAQ,GAAG,KAAK;gBACrB,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,KAAK,GAAG,CAAC,IAAI;oBAAE;gBAC1C,EAAE,CAAC,KAAK,EAAE;YACZ,CAAC,EACD,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAC5B;AACH,QAAA,CAAC,CAAC;IACJ;AAEmB,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC;AAExB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;AAC1B,QAAA,IAAI,KAAK;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAA,CAAE,CAAC;AAEzC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE;QAChC,IAAI,IAAI,KAAK,IAAI;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAA,CAAE,CAAC;AAEhD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE;QAClC,IAAI,KAAK,KAAK,SAAS;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAA,CAAE,CAAC;QAEvD,IAAI,IAAI,CAAC,QAAQ,EAAE;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACnD,IAAI,IAAI,CAAC,KAAK,EAAE;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;QAC7C,IAAI,IAAI,CAAC,OAAO,EAAE;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC;AAEjD,QAAA,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE;AACpD,QAAA,IAAI,YAAY;YAAE,KAAK,CAAC,IAAI,CAAC,CAAA,aAAA,EAAgB,IAAI,CAAC,YAAY,EAAE,CAAA,CAAE,CAAC;AAEnE,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IACxB,CAAC;gFAAC;uGAzNS,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAR,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mCAAA,EAAA,MAAA,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,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,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,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,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,mBAAA,EAAA,EAAA,iBAAA,EAAA,qBAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,SAAA,EAAA,uBAAA,EAAA,OAAA,EAAA,eAAA,EAAA,MAAA,EAAA,cAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,gBAAA,EAAA,6BAAA,EAAA,WAAA,EAAA,YAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,oBAAA,EAAA,oBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClFrB,8NAWA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDqEY,MAAM,sEAAE,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;;2FAEhB,QAAQ,EAAA,UAAA,EAAA,CAAA;kBAnBpB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mCAAmC,EAAA,aAAA,EAE9B,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B;AACJ,wBAAA,SAAS,EAAE,WAAW;AACtB,wBAAA,iBAAiB,EAAE,kBAAkB;AACrC,wBAAA,kBAAkB,EAAE,2BAA2B;;;AAG/C,wBAAA,aAAa,EAAE,YAAY;AAC3B,wBAAA,iBAAiB,EAAE,gBAAgB;AACnC,wBAAA,sBAAsB,EAAE,oBAAoB;AAC5C,wBAAA,WAAW,EAAE,uBAAuB;AACpC,wBAAA,SAAS,EAAE,eAAe;AAC1B,wBAAA,QAAQ,EAAE,cAAc;AACzB,qBAAA,EAAA,OAAA,EACQ,CAAC,MAAM,EAAE,SAAS,CAAC,EAAA,QAAA,EAAA,8NAAA,EAAA;;;AEhF9B;;;;;AAKG;AAOH;;;;;;;;;;;;;;;;;;;;;AAqBG;MAaU,aAAa,CAAA;AACxB;;;;;;AAMG;IACM,KAAK,GAAG,KAAK,CAAuB,IAAI;8EAAC;AAE/B,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AAC7C,QAAA,MAAM,KAAK,GAAG,CAAC,cAAc,CAAC;AAC9B,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE;AACtB,QAAA,IAAI,CAAC;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA,CAAE,CAAC;AACvC,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IACxB,CAAC;oFAAC;uGAfS,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,oRAFb,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,CAAC,MAAM,aAAa,CAAC,EAAE,CAAC,0BAR7E,gBAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAUf,aAAa,EAAA,UAAA,EAAA,CAAA;kBAZzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,cAAc;AACxB,oBAAA,QAAQ,EAAE,gBAAgB;oBAC1B,aAAa,EAAE,iBAAiB,CAAC,IAAI;AACrC,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,eAAe;AAC1B,wBAAA,IAAI,EAAE,OAAO;AACd,qBAAA;;;AAGD,oBAAA,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,CAAC,MAAK,aAAc,CAAC,EAAE,CAAC;AACxF,iBAAA;;;AC7CD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ngwr-button.mjs","sources":["../../../projects/lib/button/tokens/button-group.token.ts","../../../projects/lib/button/button.ts","../../../projects/lib/button/button.html","../../../projects/lib/button/button-group.ts","../../../projects/lib/button/ngwr-button.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 { InjectionToken, type Signal } from '@angular/core';\n\nimport type { WrButtonShape } from '../interfaces';\n\n/**\n * Contract a child `<wr-btn>` reads from its enclosing `<wr-btn-group>`.\n *\n * @internal\n */\nexport interface WrButtonGroupContext {\n /** Shape cascade — child buttons fall back to this when they don't set their own. */\n readonly shape: Signal<WrButtonShape | null>;\n}\n\n/**\n * Token a `<wr-btn>` injects to discover its parent `<wr-btn-group>`. The\n * group provides itself via this token so children can react to the\n * group's `shape` cascade.\n *\n * @internal\n */\nexport const WR_BUTTON_GROUP = new InjectionToken<WrButtonGroupContext>('WR_BUTTON_GROUP');\n","/**\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 {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n} from '@angular/core';\n\nimport { useConfigValue } from 'ngwr/config';\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\nimport { WrSpinner } from 'ngwr/spinner';\nimport type { WrColor } from 'ngwr/theme';\n\nimport type { WrButtonIconPosition, WrButtonShape, WrButtonSize } from './interfaces';\nimport { WR_BUTTON_GROUP } from './tokens';\n\n/**\n * Trigger an action. Renders as a `<wr-btn>` element, or attach to a\n * native `<button>` / `<a>` via the `wr-btn` attribute selector.\n *\n * @example\n * ```html\n * <button wr-btn color=\"primary\">Save</button>\n * <a wr-btn color=\"primary\" outlined>Cancel</a>\n * <wr-btn color=\"danger\" icon=\"trash\">Delete</wr-btn>\n * <wr-btn color=\"primary\" shape=\"pill\">Pill</wr-btn>\n * ```\n *\n * **Squircle?** Wrap with `[wrSquircle]` — the directive is the only\n * way ngwr ships smooth-corner clip-paths:\n *\n * ```html\n * <wr-btn wrSquircle [radius]=\"14\">Squircle</wr-btn>\n * ```\n *\n * Inside a `<wr-btn-group shape=\"…\">`, the group's shape is enforced on\n * every child — child `[shape]` inputs are ignored so the group reads as\n * one coherent control.\n *\n * **Inside a `<form>`, use the native form.** `<wr-btn>` is a custom element\n * carrying `role=\"button\"`, and no custom element submits a form — the platform\n * submits for `<button>`, `<input type=\"submit\">` and `<input type=\"image\">`\n * and nothing else. That is why there is no `type` input: it would look like it\n * worked. Implicit submission (Enter in a text field) does not reach it either.\n *\n * ```html\n * <button wr-btn type=\"submit\" color=\"primary\">Save</button>\n * ```\n *\n * @see https://ngwr.dev/reference/components/button\n */\n@Component({\n selector: 'wr-btn, button[wr-btn], a[wr-btn]',\n templateUrl: './button.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.disabled]': 'nativeDisabled()',\n '[attr.aria-busy]': 'loading() ? \"true\" : null',\n // The three below apply ONLY to the `<wr-btn>` element form — see\n // `isCustomHost`. A native `<button>` / `<a>` already has all of it.\n '[attr.role]': 'hostRole()',\n '[attr.tabindex]': 'hostTabIndex()',\n '[attr.aria-disabled]': 'hostAriaDisabled()',\n '(keydown)': 'onHostKeydown($event)',\n '(focus)': 'onHostFocus()',\n '(blur)': 'onHostBlur()',\n },\n imports: [WrIcon, WrSpinner],\n})\nexport class WrButton {\n /**\n * Color variant. Omit for the neutral default style.\n *\n * Deliberately NOT configurable app-wide: the library's own chrome binds\n * `[color]=\"isCurrent ? 'primary' : null\"`, where `null` means neutral, and a\n * configured intent would repaint every one of those buttons. See `WrConfig`.\n *\n * @default null\n */\n readonly color = input<WrColor | null>(null);\n\n /**\n * Size variant. Unset, it resolves through\n * `provideWrConfig({ button: { size } })` and then to `md`.\n *\n * @default 'md'\n */\n readonly size = input<WrButtonSize | null>(null);\n\n /**\n * Corner treatment — `rounded`, `pill` or `squircle`. `null` (default) falls\n * back to `rounded`. Inside a `<wr-btn-group shape=\"…\">`, the group's shape\n * ALWAYS wins over this input — the group enforces a consistent corner\n * treatment across its members.\n *\n * @default null\n */\n readonly shape = input<WrButtonShape | null>(null);\n\n /**\n * Icon name to render alongside the label. The icon is hidden while\n * `loading` is `true` so the spinner can take its place.\n *\n * @default null\n */\n readonly icon = input<WrIconName | null>(null);\n\n /** Position of the icon relative to the label. @default 'start' */\n readonly iconPosition = input<WrButtonIconPosition>('start');\n\n /** Disable the button. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /** Outlined variant — colored text and border on a transparent background. @default false */\n readonly outlined = input(false, { transform: coerceBooleanProperty });\n\n /** Stretch the button to fill its parent's width. @default false */\n readonly block = input(false, { transform: coerceBooleanProperty });\n\n /** Show a spinner overlaying the label. Layout is preserved. @default false */\n readonly loading = input(false, { transform: coerceBooleanProperty });\n\n /**\n * When `loading` is `true` and this is also `true`, pointer events are\n * suppressed and the button reports as disabled to assistive tech.\n *\n * @default true\n */\n readonly disabledWhenLoading = input(true, { transform: coerceBooleanProperty });\n\n private readonly group = inject(WR_BUTTON_GROUP, { optional: true });\n\n /** The size, or the app-wide default, or `md`. @see useConfigValue */\n protected readonly resolvedSize = useConfigValue<WrButtonSize>(this.size, c => c.button?.size, 'md');\n\n /**\n * Resolved shape. Inside a `<wr-btn-group>`, the group ALWAYS wins — child\n * `[shape]` is ignored entirely so the group reads as one coherent control.\n * Outside a group, the button's own `[shape]` is used, falling back to\n * `rounded`. Not config-resolved: see `WrConfig` for why a boolean cannot\n * express this three-valued input.\n */\n protected readonly resolvedShape = computed<WrButtonShape>(() =>\n this.group ? (this.group.shape() ?? 'rounded') : (this.shape() ?? 'rounded')\n );\n\n private readonly hostEl = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /**\n * Whether this instance is the `<wr-btn>` ELEMENT rather than the attribute\n * form on a native `<button>` / `<a>`.\n *\n * The element form is documented as first-class and is what the pagination,\n * event-calendar and popconfirm chrome use — but a custom element has no\n * button semantics of its own. It was rendering with no `role`, no\n * `tabindex` and no keyboard activation, so it was invisible to assistive\n * tech and unreachable by Tab. Measured in Chromium against the built site:\n * the whole `wr-pagination` subtree, 26 elements, contained ZERO focusable\n * nodes and sixty Tab presses never entered it. axe cannot see this — an\n * unknown element with no role simply is not an interactive control to it,\n * which is the same blind spot that lets `disabled` pass unnoticed on a\n * custom element.\n */\n private readonly isCustomHost = this.hostEl.nativeElement.tagName === 'WR-BTN';\n\n private readonly isOff = computed(() => this.disabled() || (this.loading() && this.disabledWhenLoading()));\n\n protected readonly nativeDisabled = computed<'' | null>(() => (this.isOff() ? '' : null));\n\n protected readonly hostRole = computed<'button' | null>(() => (this.isCustomHost ? 'button' : null));\n\n /** Out of the tab order while off — `disabled` is inert on a custom element. */\n protected readonly hostTabIndex = computed<'0' | null>(() => (this.isCustomHost && !this.isOff() ? '0' : null));\n\n protected readonly hostAriaDisabled = computed<'true' | null>(() =>\n this.isCustomHost && this.isOff() ? 'true' : null\n );\n\n /**\n * Enter and Space activate a button. A native one does this for free; a\n * custom element does not, so without this the element form could be focused\n * (once it had a tabindex) and still not be operable.\n *\n * `preventDefault` on Space is not optional — it scrolls the page otherwise.\n * The pointer path needs no guard here: `.wr-btn[disabled]` already sets\n * `pointer-events: none`.\n */\n protected onHostKeydown(event: KeyboardEvent): void {\n if (!this.isCustomHost) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n\n event.preventDefault();\n if (this.isOff()) return;\n this.hostEl.nativeElement.click();\n }\n\n private readonly injector = inject(Injector);\n\n /**\n * Whether this button is the one the caret was on, so it can be handed back\n * the focus that goes missing while it is off.\n *\n * A control that becomes `disabled` while focused stops being a focusable\n * area, and the browser runs the unfocusing steps: nothing else is nominated,\n * so the caret lands on `<body>`. With `disabledWhenLoading` on by default\n * that happens on EVERY async button — a keyboard user presses Enter on\n * \"Save\" and the next Tab restarts from the top of the document, while a\n * screen-reader user is told neither that the wait began nor that it ended,\n * because the element they were on has left the a11y tree. The `<wr-btn>`\n * element form loses its `tabindex` instead of gaining `disabled` and is\n * unfocused for the same reason.\n *\n * Deliberately NOT keyed on reading `activeElement` when `isOff()` flips: an\n * effect in this component's own view runs AFTER the parent has applied this\n * directive's host bindings, so by then the attribute has landed and the\n * browser has already moved the caret — the read would answer `<body>` on\n * every real browser and the button on jsdom, which is the worst of both.\n *\n * The flag is written by the focus listeners instead, and a `blur` fired\n * WHILE off keeps it set rather than clearing it: that blur is the browser\n * taking the caret away, not the user leaving. A browser that fires no blur\n * on disable at all is covered too — the flag simply stays as `focus` left it,\n * and the `<body>` test below is what decides whether the focus is orphaned.\n */\n private hadFocus = false;\n\n /** @internal Host `focus` — see `hadFocus`. */\n protected onHostFocus(): void {\n this.hadFocus = true;\n }\n\n /** @internal Host `blur` — see `hadFocus`. */\n protected onHostBlur(): void {\n this.hadFocus = this.isOff();\n }\n\n constructor() {\n effect(() => {\n if (this.isOff()) return;\n if (!this.hadFocus) return;\n const el = this.hostEl.nativeElement;\n\n // Deferred: the host binding that drops `disabled` (or restores the\n // `tabindex`) has not necessarily run yet, and `focus()` on a still\n // disabled element is a silent no-op — the exact failure this is here to\n // fix.\n afterNextRender(\n () => {\n if (!this.hadFocus || this.isOff()) return;\n const doc = el.ownerDocument;\n const active = doc?.activeElement ?? null;\n // Still ours — nothing was ever taken away, so keep the flag for the\n // cycle that does take it.\n if (active === el) return;\n // Someone else owns the caret now: a user who tabbed on while the\n // request was in flight must not be yanked back to a button they have\n // finished with.\n this.hadFocus = false;\n if (active && doc && active !== doc.body) return;\n el.focus();\n },\n { injector: this.injector }\n );\n });\n }\n\n protected readonly classes = computed(() => {\n const parts = ['wr-btn'];\n\n const color = this.color();\n if (color) parts.push(`wr-btn--${color}`);\n\n const size = this.resolvedSize();\n if (size !== 'md') parts.push(`wr-btn--${size}`);\n\n const shape = this.resolvedShape();\n if (shape !== 'rounded') parts.push(`wr-btn--${shape}`);\n\n if (this.outlined()) parts.push('wr-btn--outlined');\n if (this.block()) parts.push('wr-btn--block');\n if (this.loading()) parts.push('wr-btn--loading');\n\n const hasAdornment = !!this.icon() || this.loading();\n if (hasAdornment) parts.push(`wr-btn--icon-${this.iconPosition()}`);\n\n return parts.join(' ');\n });\n}\n","@if (loading()) {\n <wr-spinner class=\"wr-btn__spin\" size=\"sm\" />\n}\n\n@if (icon(); as name) {\n <wr-icon class=\"wr-btn__icon\" [name]=\"name\" />\n}\n\n<span class=\"wr-btn__label\">\n <ng-content />\n</span>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, forwardRef, input } from '@angular/core';\n\nimport type { WrButtonShape } from './interfaces';\nimport { WR_BUTTON_GROUP, type WrButtonGroupContext } from './tokens';\n\n/**\n * Visually group buttons by merging their borders. Optionally enforce a\n * single corner treatment across every child via `[shape]` — child\n * `<wr-btn>` `[shape]` inputs are ignored when set on the group.\n *\n * @example\n * ```html\n * <wr-btn-group>\n * <button wr-btn>Left</button>\n * <button wr-btn>Middle</button>\n * <button wr-btn>Right</button>\n * </wr-btn-group>\n *\n * <wr-btn-group shape=\"pill\">\n * <button wr-btn>One</button>\n * <button wr-btn>Two</button>\n * <button wr-btn>Three</button>\n * </wr-btn-group>\n * ```\n *\n * @see https://ngwr.dev/reference/components/button-group\n */\n@Component({\n selector: 'wr-btn-group',\n template: '<ng-content />',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'hostClasses()',\n role: 'group',\n },\n // forwardRef required: WrButtonGroup is self-referenced before its declaration ends.\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n providers: [{ provide: WR_BUTTON_GROUP, useExisting: forwardRef(() => WrButtonGroup) }],\n})\nexport class WrButtonGroup implements WrButtonGroupContext {\n /**\n * Corner treatment enforced on every child `<wr-btn>`. Child `[shape]`\n * inputs are ignored when this is set — the group exists to make a\n * uniform control. `null` (default) leaves children alone.\n *\n * @default null\n */\n readonly shape = input<WrButtonShape | null>(null);\n\n protected readonly hostClasses = computed(() => {\n const parts = ['wr-btn-group'];\n const s = this.shape();\n if (s) parts.push(`wr-btn-group--${s}`);\n return parts.join(' ');\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-calendar-heatmap-testing.mjs","sources":["../../../projects/lib/calendar-heatmap/testing/wr-calendar-heatmap-harness.ts","../../../projects/lib/calendar-heatmap/testing/ngwr-calendar-heatmap-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport type { WrCalendarHeatmapCell, WrCalendarHeatmapHarnessFilters } from './interfaces';\n\n/**\n * Test harness for `<wr-calendar-heatmap>`.\n *\n * **Every square is `aria-hidden`, and that is the design.** The grid is one\n * `role=\"img\"` with a name; a year of individually announced days would be unusable\n * with a screen reader. What each square carries instead is `data-date` and\n * `data-value`, which is what {@link getCells} reads.\n *\n * NOT the `title`, which it used to parse. The tooltip is human-facing text now\n * — the date formatted for the reader's locale, the count through\n * `Intl.NumberFormat`, and the sentence composed in the catalog — so parsing it\n * would have made every assertion here depend on the locale the suite happens to\n * run under, and on wording a translator is free to change.\n *\n * **Four of the seven weekday labels are blank on purpose**: seven do not fit beside\n * a grid this dense. {@link getWeekdayLabels} returns them as they are, empties\n * included, rather than filtering — a spec asserting seven entries with four blanks\n * is pinning the real layout.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarHeatmapHarness extends ComponentHarness {\n static hostSelector = 'wr-calendar-heatmap';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrCalendarHeatmapHarnessFilters = {}): HarnessPredicate<WrCalendarHeatmapHarness> {\n return new HarnessPredicate(WrCalendarHeatmapHarness, options).addOption(\n 'ariaLabel',\n options.ariaLabel,\n (harness, label) => HarnessPredicate.stringMatches(harness.getAccessibleName(), label)\n );\n }\n\n private readonly grid = this.locatorFor('.wr-calendar-heatmap__grid');\n\n /** The role the grid announces — `img`, for the whole picture. */\n async getRole(): Promise<string | null> {\n return (await this.grid()).getAttribute('role');\n }\n\n /** The grid's accessible name — the only name a reader gets. */\n async getAccessibleName(): Promise<string | null> {\n return (await this.grid()).getAttribute('aria-label');\n }\n\n /** How many day squares were drawn. */\n async getCellCount(): Promise<number> {\n return (await this.locatorForAll('.wr-calendar-heatmap__cell')()).length;\n }\n\n /**\n * Every square, from its tooltip and its grid placement.\n *\n * Read from `data-date` / `data-value`, which the component writes for exactly\n * this. Everything else about a square is colour.\n */\n async getCells(): Promise<WrCalendarHeatmapCell[]> {\n const cells = await this.locatorForAll('.wr-calendar-heatmap__cell')();\n\n return Promise.all(\n cells.map(async cell => {\n return {\n iso: (await cell.getAttribute('data-date')) ?? '',\n value: (await cell.getAttribute('data-value')) ?? '',\n // `grid-column` / `grid-row` as WRITTEN, not the `-start` longhands: the\n // component sets the shorthand, and jsdom does not expand shorthands, so the\n // longhand reads back empty and every square would land at NaN.\n week: Number.parseInt(await cell.getCssValue('grid-column'), 10),\n day: Number.parseInt(await cell.getCssValue('grid-row'), 10),\n };\n })\n );\n }\n\n /** The value a given ISO date's square reports, or `null` when that day is not drawn. */\n async getValueFor(iso: string): Promise<string | null> {\n for (const cell of await this.getCells()) {\n if (cell.iso === iso) return cell.value;\n }\n return null;\n }\n\n /** Whether the weekday and month labels are drawn (`showLabels`). */\n async hasLabels(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-calendar-heatmap__weekdays')()) !== null;\n }\n\n /** The weekday labels as drawn — seven entries, four of them deliberately empty. */\n async getWeekdayLabels(): Promise<string[]> {\n const labels = await this.locatorForAll('.wr-calendar-heatmap__weekday')();\n return Promise.all(labels.map(label => label.text()));\n }\n\n /** The month labels along the top, in order. */\n async getMonthLabels(): Promise<string[]> {\n const labels = await this.locatorForAll('.wr-calendar-heatmap__month')();\n return Promise.all(labels.map(label => label.text()));\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAMH;;;;;;;;;;;;;;;;;;;;AAoBG;AACG,MAAO,wBAAyB,SAAQ,gBAAgB,CAAA;AAC5D,IAAA,OAAO,YAAY,GAAG,qBAAqB;;AAG3C,IAAA,OAAO,IAAI,CAAC,OAAA,GAA2C,EAAE,EAAA;AACvD,QAAA,OAAO,IAAI,gBAAgB,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC,SAAS,CACtE,WAAW,EACX,OAAO,CAAC,SAAS,EACjB,CAAC,OAAO,EAAE,KAAK,KAAK,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,KAAK,CAAC,CACvF;IACH;AAEiB,IAAA,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,4BAA4B,CAAC;;AAGrE,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC;IACjD;;AAGA,IAAA,MAAM,iBAAiB,GAAA;AACrB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC;IACvD;;AAGA,IAAA,MAAM,YAAY,GAAA;AAChB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC,EAAE,EAAE,MAAM;IAC1E;AAEA;;;;;AAKG;AACH,IAAA,MAAM,QAAQ,GAAA;QACZ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC,EAAE;AAEtE,QAAA,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,OAAM,IAAI,KAAG;YACrB,OAAO;gBACL,GAAG,EAAE,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE;gBACjD,KAAK,EAAE,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,KAAK,EAAE;;;;AAIpD,gBAAA,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;AAChE,gBAAA,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;aAC7D;QACH,CAAC,CAAC,CACH;IACH;;IAGA,MAAM,WAAW,CAAC,GAAW,EAAA;QAC3B,KAAK,MAAM,IAAI,IAAI,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE;AACxC,YAAA,IAAI,IAAI,CAAC,GAAG,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC,KAAK;QACzC;AACA,QAAA,OAAO,IAAI;IACb;;AAGA,IAAA,MAAM,SAAS,GAAA;AACb,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,gCAAgC,CAAC,EAAE,MAAM,IAAI;IACrF;;AAGA,IAAA,MAAM,gBAAgB,GAAA;QACpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,+BAA+B,CAAC,EAAE;AAC1E,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD;;AAGA,IAAA,MAAM,cAAc,GAAA;QAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,6BAA6B,CAAC,EAAE;AACxE,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD;;;AC5GF;;AAEG
|
|
1
|
+
{"version":3,"file":"ngwr-calendar-heatmap-testing.mjs","sources":["../../../projects/lib/calendar-heatmap/testing/wr-calendar-heatmap-harness.ts","../../../projects/lib/calendar-heatmap/testing/ngwr-calendar-heatmap-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport type { WrCalendarHeatmapCell, WrCalendarHeatmapHarnessFilters } from './interfaces';\n\n/**\n * Test harness for `<wr-calendar-heatmap>`.\n *\n * **Every square is `aria-hidden`, and that is the design.** The grid is one\n * `role=\"img\"` with a name; a year of individually announced days would be unusable\n * with a screen reader. What each square carries instead is `data-date` and\n * `data-value`, which is what {@link getCells} reads.\n *\n * NOT the `title`, which it used to parse. The tooltip is human-facing text now\n * — the date formatted for the reader's locale, the count through\n * `Intl.NumberFormat`, and the sentence composed in the catalog — so parsing it\n * would have made every assertion here depend on the locale the suite happens to\n * run under, and on wording a translator is free to change.\n *\n * **Four of the seven weekday labels are blank on purpose**: seven do not fit beside\n * a grid this dense. {@link getWeekdayLabels} returns them as they are, empties\n * included, rather than filtering — a spec asserting seven entries with four blanks\n * is pinning the real layout.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarHeatmapHarness extends ComponentHarness {\n static hostSelector = 'wr-calendar-heatmap';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrCalendarHeatmapHarnessFilters = {}): HarnessPredicate<WrCalendarHeatmapHarness> {\n return new HarnessPredicate(WrCalendarHeatmapHarness, options).addOption(\n 'ariaLabel',\n options.ariaLabel,\n (harness, label) => HarnessPredicate.stringMatches(harness.getAccessibleName(), label)\n );\n }\n\n private readonly grid = this.locatorFor('.wr-calendar-heatmap__grid');\n\n /** The role the grid announces — `img`, for the whole picture. */\n async getRole(): Promise<string | null> {\n return (await this.grid()).getAttribute('role');\n }\n\n /** The grid's accessible name — the only name a reader gets. */\n async getAccessibleName(): Promise<string | null> {\n return (await this.grid()).getAttribute('aria-label');\n }\n\n /** How many day squares were drawn. */\n async getCellCount(): Promise<number> {\n return (await this.locatorForAll('.wr-calendar-heatmap__cell')()).length;\n }\n\n /**\n * Every square, from its tooltip and its grid placement.\n *\n * Read from `data-date` / `data-value`, which the component writes for exactly\n * this. Everything else about a square is colour.\n */\n async getCells(): Promise<WrCalendarHeatmapCell[]> {\n const cells = await this.locatorForAll('.wr-calendar-heatmap__cell')();\n\n return Promise.all(\n cells.map(async cell => {\n return {\n iso: (await cell.getAttribute('data-date')) ?? '',\n value: (await cell.getAttribute('data-value')) ?? '',\n // `grid-column` / `grid-row` as WRITTEN, not the `-start` longhands: the\n // component sets the shorthand, and jsdom does not expand shorthands, so the\n // longhand reads back empty and every square would land at NaN.\n week: Number.parseInt(await cell.getCssValue('grid-column'), 10),\n day: Number.parseInt(await cell.getCssValue('grid-row'), 10),\n };\n })\n );\n }\n\n /** The value a given ISO date's square reports, or `null` when that day is not drawn. */\n async getValueFor(iso: string): Promise<string | null> {\n for (const cell of await this.getCells()) {\n if (cell.iso === iso) return cell.value;\n }\n return null;\n }\n\n /** Whether the weekday and month labels are drawn (`showLabels`). */\n async hasLabels(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-calendar-heatmap__weekdays')()) !== null;\n }\n\n /** The weekday labels as drawn — seven entries, four of them deliberately empty. */\n async getWeekdayLabels(): Promise<string[]> {\n const labels = await this.locatorForAll('.wr-calendar-heatmap__weekday')();\n return Promise.all(labels.map(label => label.text()));\n }\n\n /** The month labels along the top, in order. */\n async getMonthLabels(): Promise<string[]> {\n const labels = await this.locatorForAll('.wr-calendar-heatmap__month')();\n return Promise.all(labels.map(label => label.text()));\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAMH;;;;;;;;;;;;;;;;;;;;AAoBG;AACG,MAAO,wBAAyB,SAAQ,gBAAgB,CAAA;AAC5D,IAAA,OAAO,YAAY,GAAG,qBAAqB;;AAG3C,IAAA,OAAO,IAAI,CAAC,OAAA,GAA2C,EAAE,EAAA;AACvD,QAAA,OAAO,IAAI,gBAAgB,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC,SAAS,CACtE,WAAW,EACX,OAAO,CAAC,SAAS,EACjB,CAAC,OAAO,EAAE,KAAK,KAAK,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,KAAK,CAAC,CACvF;IACH;AAEiB,IAAA,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,4BAA4B,CAAC;;AAGrE,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC;IACjD;;AAGA,IAAA,MAAM,iBAAiB,GAAA;AACrB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC;IACvD;;AAGA,IAAA,MAAM,YAAY,GAAA;AAChB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC,EAAE,EAAE,MAAM;IAC1E;AAEA;;;;;AAKG;AACH,IAAA,MAAM,QAAQ,GAAA;QACZ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC,EAAE;AAEtE,QAAA,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,OAAM,IAAI,KAAG;YACrB,OAAO;gBACL,GAAG,EAAE,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE;gBACjD,KAAK,EAAE,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,KAAK,EAAE;;;;AAIpD,gBAAA,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;AAChE,gBAAA,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;aAC7D;QACH,CAAC,CAAC,CACH;IACH;;IAGA,MAAM,WAAW,CAAC,GAAW,EAAA;QAC3B,KAAK,MAAM,IAAI,IAAI,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE;AACxC,YAAA,IAAI,IAAI,CAAC,GAAG,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC,KAAK;QACzC;AACA,QAAA,OAAO,IAAI;IACb;;AAGA,IAAA,MAAM,SAAS,GAAA;AACb,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,gCAAgC,CAAC,EAAE,MAAM,IAAI;IACrF;;AAGA,IAAA,MAAM,gBAAgB,GAAA;QACpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,+BAA+B,CAAC,EAAE;AAC1E,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD;;AAGA,IAAA,MAAM,cAAc,GAAA;QAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,6BAA6B,CAAC,EAAE;AACxE,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD;;;AC5GF;;AAEG;;"}
|