ngwr 8.0.0 → 9.0.1
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 +76 -29
- package/action-sheet/styles/_index.scss +93 -0
- package/alert/styles/_index.scss +10 -10
- package/anchor/styles/_index.scss +3 -3
- package/back-top/styles/_index.scss +1 -1
- package/badge/styles/_tag.scss +3 -3
- package/bar-chart/styles/_index.scss +4 -4
- package/border-glow/styles/_index.scss +3 -3
- package/breadcrumbs/styles/_index.scss +3 -3
- package/burger/styles/_index.scss +1 -1
- package/button/styles/_index.scss +4 -4
- package/calendar/styles/_index.scss +4 -4
- package/calendar-heatmap/styles/_index.scss +3 -3
- package/card/styles/_index.scss +5 -5
- package/carousel/styles/_index.scss +5 -5
- package/cascader/styles/_index.scss +15 -15
- package/checkbox/styles/_index.scss +20 -5
- package/collapse/styles/_index.scss +6 -6
- package/color-picker/styles/_index.scss +15 -9
- package/command-palette/styles/_index.scss +19 -16
- package/compare/styles/_index.scss +3 -3
- package/context-menu/styles/_index.scss +16 -6
- package/counter/styles/_index.scss +12 -1
- package/date-picker/styles/_index.scss +8 -8
- package/descriptions/styles/_index.scss +9 -9
- package/dialog/styles/_index.scss +7 -6
- package/divider/styles/_index.scss +2 -2
- package/donut-chart/styles/_index.scss +3 -3
- package/drag-drop/styles/_index.scss +11 -6
- package/drawer/styles/_index.scss +15 -6
- package/dropdown/styles/_index.scss +5 -5
- package/empty/styles/_index.scss +4 -4
- package/fesm2022/ngwr-action-sheet.mjs +81 -0
- package/fesm2022/ngwr-action-sheet.mjs.map +1 -0
- package/fesm2022/ngwr-affix.mjs +3 -3
- package/fesm2022/ngwr-alert.mjs +4 -4
- package/fesm2022/ngwr-alert.mjs.map +1 -1
- package/fesm2022/ngwr-anchor.mjs +4 -4
- package/fesm2022/ngwr-anchor.mjs.map +1 -1
- package/fesm2022/ngwr-aurora.mjs +5 -4
- package/fesm2022/ngwr-aurora.mjs.map +1 -1
- package/fesm2022/ngwr-avatar.mjs +4 -4
- package/fesm2022/ngwr-avatar.mjs.map +1 -1
- package/fesm2022/ngwr-back-top.mjs +4 -4
- package/fesm2022/ngwr-back-top.mjs.map +1 -1
- package/fesm2022/ngwr-badge.mjs +8 -8
- package/fesm2022/ngwr-badge.mjs.map +1 -1
- package/fesm2022/ngwr-bar-chart.mjs +4 -4
- package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text.mjs +3 -3
- package/fesm2022/ngwr-border-glow.mjs +4 -4
- package/fesm2022/ngwr-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +8 -8
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-burger.mjs +4 -4
- package/fesm2022/ngwr-burger.mjs.map +1 -1
- package/fesm2022/ngwr-button.mjs +8 -8
- package/fesm2022/ngwr-button.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap.mjs +4 -4
- package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
- package/fesm2022/ngwr-calendar.mjs +4 -4
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-card.mjs +11 -11
- package/fesm2022/ngwr-card.mjs.map +1 -1
- package/fesm2022/ngwr-carousel.mjs +7 -7
- package/fesm2022/ngwr-carousel.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +52 -60
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +74 -106
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text.mjs +5 -4
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-click-spark.mjs +5 -4
- package/fesm2022/ngwr-click-spark.mjs.map +1 -1
- package/fesm2022/ngwr-clipboard.mjs +4 -4
- package/fesm2022/ngwr-clipboard.mjs.map +1 -1
- package/fesm2022/ngwr-collapse.mjs +12 -12
- package/fesm2022/ngwr-collapse.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +58 -66
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette.mjs +4 -4
- package/fesm2022/ngwr-command-palette.mjs.map +1 -1
- package/fesm2022/ngwr-compare.mjs +4 -4
- package/fesm2022/ngwr-compare.mjs.map +1 -1
- package/fesm2022/ngwr-confetti.mjs +3 -3
- package/fesm2022/ngwr-context-menu.mjs +86 -15
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-cookie.mjs +19 -6
- package/fesm2022/ngwr-cookie.mjs.map +1 -1
- package/fesm2022/ngwr-counter.mjs +26 -12
- package/fesm2022/ngwr-counter.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapter-fns.mjs +3 -3
- package/fesm2022/ngwr-date-adapter-luxon.mjs +3 -3
- package/fesm2022/ngwr-date-adapter.mjs +10 -5
- package/fesm2022/ngwr-date-adapter.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +128 -123
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-decrypt-text.mjs +3 -3
- package/fesm2022/ngwr-density.mjs +7 -7
- package/fesm2022/ngwr-density.mjs.map +1 -1
- package/fesm2022/ngwr-descriptions.mjs +7 -7
- package/fesm2022/ngwr-descriptions.mjs.map +1 -1
- package/fesm2022/ngwr-dialog.mjs +16 -16
- package/fesm2022/ngwr-dialog.mjs.map +1 -1
- package/fesm2022/ngwr-directives.mjs +21 -15
- package/fesm2022/ngwr-directives.mjs.map +1 -1
- package/fesm2022/ngwr-divider.mjs +4 -4
- package/fesm2022/ngwr-divider.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart.mjs +4 -4
- package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +10 -9
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-drawer.mjs +19 -18
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +13 -12
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-empty.mjs +4 -4
- package/fesm2022/ngwr-empty.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text.mjs +5 -4
- package/fesm2022/ngwr-falling-text.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload.mjs +58 -60
- package/fesm2022/ngwr-file-upload.mjs.map +1 -1
- package/fesm2022/ngwr-form.mjs +11 -11
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text.mjs +5 -4
- package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
- package/fesm2022/ngwr-gauge.mjs +4 -4
- package/fesm2022/ngwr-gauge.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text.mjs +4 -4
- package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text.mjs +4 -4
- package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
- package/fesm2022/ngwr-hotkey.mjs +7 -7
- package/fesm2022/ngwr-hotkey.mjs.map +1 -1
- package/fesm2022/ngwr-i18n.mjs +10 -10
- package/fesm2022/ngwr-i18n.mjs.map +1 -1
- package/fesm2022/ngwr-icon-adapters-lucide.mjs +6 -7
- package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
- package/fesm2022/ngwr-icon.mjs +4 -4
- package/fesm2022/ngwr-icon.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper.mjs +6 -5
- package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
- package/fesm2022/ngwr-input-number.mjs +56 -73
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp.mjs +46 -52
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-input.mjs +17 -17
- package/fesm2022/ngwr-input.mjs.map +1 -1
- package/fesm2022/ngwr-keyboard.mjs +4 -4
- package/fesm2022/ngwr-keyboard.mjs.map +1 -1
- package/fesm2022/ngwr-knob.mjs +47 -58
- package/fesm2022/ngwr-knob.mjs.map +1 -1
- package/fesm2022/ngwr-layout.mjs +16 -16
- package/fesm2022/ngwr-layout.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox.mjs +7 -6
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart.mjs +4 -4
- package/fesm2022/ngwr-line-chart.mjs.map +1 -1
- package/fesm2022/ngwr-list.mjs +8 -8
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar.mjs +7 -7
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-marquee.mjs +6 -5
- package/fesm2022/ngwr-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-media.mjs +4 -4
- package/fesm2022/ngwr-media.mjs.map +1 -1
- package/fesm2022/ngwr-mention.mjs +15 -9
- package/fesm2022/ngwr-mention.mjs.map +1 -1
- package/fesm2022/ngwr-meta.mjs +7 -7
- package/fesm2022/ngwr-meta.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group.mjs +4 -4
- package/fesm2022/ngwr-meter-group.mjs.map +1 -1
- package/fesm2022/ngwr-overlay.mjs +9 -4
- package/fesm2022/ngwr-overlay.mjs.map +1 -1
- package/fesm2022/ngwr-page-header.mjs +4 -4
- package/fesm2022/ngwr-page-header.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +4 -4
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-pipes.mjs +21 -21
- package/fesm2022/ngwr-platform.mjs +169 -5
- package/fesm2022/ngwr-platform.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm.mjs +7 -7
- package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
- package/fesm2022/ngwr-popover.mjs +7 -7
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-progress.mjs +4 -4
- package/fesm2022/ngwr-progress.mjs.map +1 -1
- package/fesm2022/ngwr-pull-to-refresh.mjs +172 -0
- package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -0
- package/fesm2022/ngwr-qr.mjs +5 -5
- package/fesm2022/ngwr-qr.mjs.map +1 -1
- package/fesm2022/ngwr-radio.mjs +27 -52
- package/fesm2022/ngwr-radio.mjs.map +1 -1
- package/fesm2022/ngwr-rating.mjs +35 -48
- package/fesm2022/ngwr-rating.mjs.map +1 -1
- package/fesm2022/ngwr-result.mjs +13 -13
- package/fesm2022/ngwr-result.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text.mjs +15 -4
- package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
- package/fesm2022/ngwr-scroll.mjs +4 -4
- package/fesm2022/ngwr-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-segmented.mjs +3 -3
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +289 -85
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text.mjs +7 -7
- package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
- package/fesm2022/ngwr-sidebar.mjs +4 -4
- package/fesm2022/ngwr-sidebar.mjs.map +1 -1
- package/fesm2022/ngwr-skeleton.mjs +4 -4
- package/fesm2022/ngwr-skeleton.mjs.map +1 -1
- package/fesm2022/ngwr-slider.mjs +79 -73
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline.mjs +4 -4
- package/fesm2022/ngwr-sparkline.mjs.map +1 -1
- package/fesm2022/ngwr-speed-dial.mjs +13 -5
- package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
- package/fesm2022/ngwr-spinner.mjs +4 -4
- package/fesm2022/ngwr-spinner.mjs.map +1 -1
- package/fesm2022/ngwr-splash-cursor.mjs +4 -4
- package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
- package/fesm2022/ngwr-split-text.mjs +3 -3
- package/fesm2022/ngwr-splitter.mjs +4 -4
- package/fesm2022/ngwr-splitter.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card.mjs +7 -7
- package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-squircle.mjs +7 -7
- package/fesm2022/ngwr-squircle.mjs.map +1 -1
- package/fesm2022/ngwr-star-border.mjs +4 -4
- package/fesm2022/ngwr-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-statistic.mjs +65 -10
- package/fesm2022/ngwr-statistic.mjs.map +1 -1
- package/fesm2022/ngwr-stepper.mjs +8 -8
- package/fesm2022/ngwr-stepper.mjs.map +1 -1
- package/fesm2022/ngwr-storage.mjs +4 -4
- package/fesm2022/ngwr-storage.mjs.map +1 -1
- package/fesm2022/ngwr-switch.mjs +16 -48
- package/fesm2022/ngwr-switch.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +824 -20
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +9 -8
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +18 -50
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-theme.mjs +20 -5
- package/fesm2022/ngwr-theme.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card.mjs +27 -11
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-timeline.mjs +7 -7
- package/fesm2022/ngwr-timeline.mjs.map +1 -1
- package/fesm2022/ngwr-toast.mjs +10 -10
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-toolbar.mjs +4 -4
- package/fesm2022/ngwr-toolbar.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +280 -84
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter.mjs +10 -5
- package/fesm2022/ngwr-typewriter.mjs.map +1 -1
- package/fesm2022/ngwr-typography.mjs +4 -4
- package/fesm2022/ngwr-typography.mjs.map +1 -1
- package/fesm2022/ngwr-validators.mjs +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 +9 -7
- package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-waves.mjs +6 -5
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +16 -15
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/file-upload/styles/_index.scss +11 -11
- package/form/styles/_index.scss +4 -4
- package/gauge/styles/_index.scss +2 -2
- package/glitch-text/styles/_index.scss +1 -1
- package/gradient-text/styles/_index.scss +1 -1
- package/image-cropper/styles/_index.scss +5 -4
- package/input/styles/_index.scss +9 -9
- package/input-number/styles/_index.scss +1 -1
- package/input-otp/styles/_index.scss +5 -5
- package/keyboard/styles/_index.scss +5 -5
- package/knob/styles/_index.scss +6 -2
- package/layout/styles/_index.scss +12 -12
- package/lightbox/styles/_index.scss +10 -8
- package/line-chart/styles/_index.scss +5 -5
- package/list/styles/_index.scss +3 -3
- package/llms-full.txt +31 -5
- package/llms.txt +48 -32
- package/marquee/styles/_index.scss +1 -1
- package/mention/styles/_index.scss +4 -4
- package/meter-group/styles/_index.scss +4 -4
- package/overlay/styles/_index.scss +8 -0
- package/package.json +21 -9
- package/page-header/styles/_index.scss +4 -4
- package/pagination/styles/_index.scss +3 -3
- package/popconfirm/styles/_index.scss +3 -3
- package/popover/styles/_index.scss +5 -5
- package/progress/styles/_index.scss +1 -1
- package/pull-to-refresh/styles/_index.scss +38 -0
- package/radio/styles/_index.scss +4 -4
- package/rating/styles/_index.scss +1 -1
- package/result/styles/_index.scss +3 -3
- package/schematics/migrations/v9/index.js +71 -0
- package/schematics/migrations.json +5 -0
- package/schematics/ng-add/schema.json +1 -1
- package/schematics/use/symbol-map.json +13 -0
- package/segmented/styles/_index.scss +4 -4
- package/select/styles/_index.scss +53 -18
- package/shiny-text/styles/_index.scss +4 -4
- package/sidebar/styles/_index.scss +12 -12
- package/slider/styles/_index.scss +5 -5
- package/speed-dial/styles/_index.scss +22 -6
- package/splash-cursor/styles/_index.scss +1 -0
- package/splitter/styles/_index.scss +7 -4
- package/spotlight-card/styles/_index.scss +7 -7
- package/star-border/styles/_index.scss +3 -3
- package/statistic/styles/_index.scss +51 -4
- package/stepper/styles/_index.scss +6 -6
- package/styles/_typography.scss +4 -1
- package/styles.scss +2 -0
- package/switch/styles/_index.scss +4 -4
- package/table/styles/_index.scss +447 -17
- package/tabs/styles/_index.scss +3 -3
- package/textarea/styles/_index.scss +7 -7
- package/theme/styles/_colors.scss +27 -3
- package/tilt-card/styles/_index.scss +4 -4
- package/timeline/styles/_index.scss +7 -6
- package/toast/styles/_index.scss +11 -11
- package/toolbar/styles/_index.scss +4 -4
- package/tree/styles/_index.scss +45 -15
- package/types/ngwr-action-sheet.d.ts +75 -0
- package/types/ngwr-alert.d.ts +1 -1
- package/types/ngwr-anchor.d.ts +1 -1
- package/types/ngwr-avatar.d.ts +1 -1
- package/types/ngwr-back-top.d.ts +1 -1
- package/types/ngwr-badge.d.ts +4 -4
- package/types/ngwr-bar-chart.d.ts +1 -1
- package/types/ngwr-breadcrumbs.d.ts +1 -1
- package/types/ngwr-burger.d.ts +1 -1
- package/types/ngwr-button.d.ts +3 -3
- package/types/ngwr-calendar-heatmap.d.ts +1 -1
- package/types/ngwr-calendar.d.ts +1 -1
- package/types/ngwr-card.d.ts +1 -1
- package/types/ngwr-carousel.d.ts +1 -1
- package/types/ngwr-cascader.d.ts +27 -16
- package/types/ngwr-checkbox.d.ts +63 -43
- package/types/ngwr-clipboard.d.ts +1 -1
- package/types/ngwr-collapse.d.ts +3 -3
- package/types/ngwr-color-picker.d.ts +24 -19
- package/types/ngwr-command-palette.d.ts +1 -1
- package/types/ngwr-compare.d.ts +1 -1
- package/types/ngwr-context-menu.d.ts +25 -1
- package/types/ngwr-cookie.d.ts +7 -1
- package/types/ngwr-counter.d.ts +9 -2
- package/types/ngwr-date-picker.d.ts +36 -23
- package/types/ngwr-density.d.ts +1 -1
- package/types/ngwr-descriptions.d.ts +1 -1
- package/types/ngwr-dialog.d.ts +1 -1
- package/types/ngwr-directives.d.ts +1 -0
- package/types/ngwr-divider.d.ts +2 -2
- package/types/ngwr-donut-chart.d.ts +1 -1
- package/types/ngwr-drag-drop.d.ts +1 -1
- package/types/ngwr-drawer.d.ts +1 -1
- package/types/ngwr-dropdown.d.ts +1 -1
- package/types/ngwr-empty.d.ts +1 -1
- package/types/ngwr-file-upload.d.ts +28 -17
- package/types/ngwr-form.d.ts +2 -2
- package/types/ngwr-gauge.d.ts +1 -1
- package/types/ngwr-hotkey.d.ts +1 -1
- package/types/ngwr-i18n.d.ts +1 -1
- package/types/ngwr-icon-adapters-lucide.d.ts +5 -3
- package/types/ngwr-icon.d.ts +1 -1
- package/types/ngwr-image-cropper.d.ts +1 -1
- package/types/ngwr-input-number.d.ts +25 -19
- package/types/ngwr-input-otp.d.ts +23 -17
- package/types/ngwr-input.d.ts +2 -2
- package/types/ngwr-keyboard.d.ts +1 -1
- package/types/ngwr-knob.d.ts +24 -19
- package/types/ngwr-layout.d.ts +1 -1
- package/types/ngwr-lightbox.d.ts +1 -1
- package/types/ngwr-line-chart.d.ts +1 -1
- package/types/ngwr-list.d.ts +1 -1
- package/types/ngwr-loading-bar.d.ts +1 -1
- package/types/ngwr-marquee.d.ts +1 -1
- package/types/ngwr-media.d.ts +1 -1
- package/types/ngwr-mention.d.ts +1 -1
- package/types/ngwr-meta.d.ts +1 -1
- package/types/ngwr-meter-group.d.ts +1 -1
- package/types/ngwr-page-header.d.ts +1 -1
- package/types/ngwr-pagination.d.ts +1 -1
- package/types/ngwr-platform.d.ts +93 -2
- package/types/ngwr-popconfirm.d.ts +3 -3
- package/types/ngwr-progress.d.ts +2 -2
- package/types/ngwr-pull-to-refresh.d.ts +69 -0
- package/types/ngwr-qr.d.ts +1 -1
- package/types/ngwr-radio.d.ts +25 -22
- package/types/ngwr-rating.d.ts +28 -20
- package/types/ngwr-result.d.ts +1 -1
- package/types/ngwr-rotating-text.d.ts +1 -0
- package/types/ngwr-scroll.d.ts +1 -1
- package/types/ngwr-segmented.d.ts +1 -1
- package/types/ngwr-select.d.ts +93 -26
- package/types/ngwr-sidebar.d.ts +1 -1
- package/types/ngwr-skeleton.d.ts +2 -2
- package/types/ngwr-slider.d.ts +35 -21
- package/types/ngwr-sparkline.d.ts +1 -1
- package/types/ngwr-speed-dial.d.ts +8 -2
- package/types/ngwr-spinner.d.ts +1 -1
- package/types/ngwr-splitter.d.ts +1 -1
- package/types/ngwr-squircle.d.ts +1 -1
- package/types/ngwr-statistic.d.ts +40 -5
- package/types/ngwr-stepper.d.ts +2 -2
- package/types/ngwr-storage.d.ts +1 -1
- package/types/ngwr-switch.d.ts +20 -16
- package/types/ngwr-table.d.ts +417 -6
- package/types/ngwr-tabs.d.ts +1 -1
- package/types/ngwr-textarea.d.ts +21 -18
- package/types/ngwr-theme.d.ts +7 -2
- package/types/ngwr-tilt-card.d.ts +3 -0
- package/types/ngwr-timeline.d.ts +1 -1
- package/types/ngwr-toast.d.ts +1 -1
- package/types/ngwr-toolbar.d.ts +1 -1
- package/types/ngwr-tree.d.ts +100 -19
- package/types/ngwr-typography.d.ts +1 -1
- package/types/ngwr-validators.d.ts +1 -1
- package/types/ngwr-version.d.ts +1 -1
- package/types/ngwr-virtual-scroll.d.ts +1 -1
- package/types/ngwr-window.d.ts +1 -1
- package/typography/styles/_index.scss +11 -11
- package/virtual-scroll/styles/_index.scss +1 -1
- package/waves/styles/_index.scss +1 -1
- package/window/styles/_index.scss +18 -18
package/fesm2022/ngwr-tree.mjs
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
1
|
+
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
|
|
2
2
|
import { ScrollStrategyOptions } from '@angular/cdk/overlay';
|
|
3
3
|
import { TemplatePortal } from '@angular/cdk/portal';
|
|
4
|
-
import { NgTemplateOutlet } from '@angular/common';
|
|
4
|
+
import { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
|
-
import { input, model, inject, ElementRef, ViewContainerRef, DestroyRef, signal, computed, viewChild, TemplateRef, effect,
|
|
6
|
+
import { input, model, output, inject, ElementRef, ViewContainerRef, DestroyRef, PLATFORM_ID, signal, computed, viewChild, TemplateRef, effect, untracked, ViewEncapsulation, Component } from '@angular/core';
|
|
7
7
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
8
|
-
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
9
8
|
import { readI18nText, useI18nFormatter } from 'ngwr/i18n';
|
|
10
9
|
import { WR_OVERLAY } from 'ngwr/overlay';
|
|
11
|
-
import { noop } from 'ngwr/utils';
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
12
|
* @license
|
|
@@ -27,9 +25,11 @@ let panelUid = 0;
|
|
|
27
25
|
* - `'inline'` (default) — renders the tree list in-place. Use as a display
|
|
28
26
|
* widget or form-less hierarchical picker.
|
|
29
27
|
* - `'overlay'` — renders a `<wr-select>`-style trigger button (with chips
|
|
30
|
-
* in multi mode) that opens a popover containing the tree.
|
|
31
|
-
*
|
|
32
|
-
* `
|
|
28
|
+
* in multi mode) that opens a popover containing the tree. A signal-forms
|
|
29
|
+
* native control: it implements `FormValueControl<unknown>`, so `[formField]`
|
|
30
|
+
* binds straight to its `value` model — no `ControlValueAccessor` in between.
|
|
31
|
+
* `[(value)]` and classic `[(ngModel)]` / reactive forms all keep working via
|
|
32
|
+
* Angular's bridge. Replaces the standalone `<wr-tree-select>`.
|
|
33
33
|
*
|
|
34
34
|
* Value type in `overlay` mode: `TId | null` in single mode,
|
|
35
35
|
* `readonly TId[]` in multi mode.
|
|
@@ -39,17 +39,20 @@ let panelUid = 0;
|
|
|
39
39
|
* <!-- Inline tree (display widget) -->
|
|
40
40
|
* <wr-tree [nodes]="folders" [(selected)]="picked" [(expanded)]="open" />
|
|
41
41
|
*
|
|
42
|
-
* <!-- Form-bound combobox -->
|
|
42
|
+
* <!-- Form-bound combobox (signal forms) -->
|
|
43
43
|
* <wr-tree
|
|
44
44
|
* openOn="overlay"
|
|
45
45
|
* [nodes]="folders"
|
|
46
46
|
* selectionMode="single"
|
|
47
|
-
* [
|
|
47
|
+
* [formField]="form.folder"
|
|
48
48
|
* placeholder="Pick a folder"
|
|
49
49
|
* />
|
|
50
|
+
*
|
|
51
|
+
* <!-- standalone two-way binding -->
|
|
52
|
+
* <wr-tree openOn="overlay" [nodes]="folders" [(value)]="picked" placeholder="Pick a folder" />
|
|
50
53
|
* ```
|
|
51
54
|
*
|
|
52
|
-
* @see https://ngwr.dev/components/tree
|
|
55
|
+
* @see https://ngwr.dev/reference/components/tree
|
|
53
56
|
*/
|
|
54
57
|
class WrTree {
|
|
55
58
|
/** Tree data. */
|
|
@@ -64,7 +67,12 @@ class WrTree {
|
|
|
64
67
|
/** Selection behavior. @default 'single' */
|
|
65
68
|
selectionMode = input('single', /* @ts-ignore */
|
|
66
69
|
...(ngDevMode ? [{ debugName: "selectionMode" }] : /* istanbul ignore next */ []));
|
|
67
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Disable the whole tree. Bound automatically from the field's disabled
|
|
72
|
+
* state when used with `[formField]`.
|
|
73
|
+
*
|
|
74
|
+
* @default false
|
|
75
|
+
*/
|
|
68
76
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
|
|
69
77
|
// Overlay-mode inputs (ignored when openOn='inline')
|
|
70
78
|
/** Render shape. @default 'inline' */
|
|
@@ -83,12 +91,48 @@ class WrTree {
|
|
|
83
91
|
maxTagCount = input(0, { ...(ngDevMode ? { debugName: "maxTagCount" } : /* istanbul ignore next */ {}), transform: (v) => Math.max(0, Number(v) || 0) });
|
|
84
92
|
/** Auto-expand every node that has children on first open of the overlay. @default false */
|
|
85
93
|
defaultExpandAll = input(false, { ...(ngDevMode ? { debugName: "defaultExpandAll" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
|
|
94
|
+
/**
|
|
95
|
+
* Window the visible-node list so a large tree keeps only ~one viewport of
|
|
96
|
+
* rows in the DOM. Opt-in and OFF by default — a tree without it renders
|
|
97
|
+
* byte-identically to today. Works in both `inline` and `overlay` shapes;
|
|
98
|
+
* while on, keyboard navigation switches to the `aria-activedescendant`
|
|
99
|
+
* pattern so Arrow / Home / End / Enter keep working across un-rendered rows.
|
|
100
|
+
* @default false
|
|
101
|
+
*/
|
|
102
|
+
virtualScroll = input(false, { ...(ngDevMode ? { debugName: "virtualScroll" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
|
|
103
|
+
/**
|
|
104
|
+
* Uniform row height in px used to map scroll offset to node index. `0`
|
|
105
|
+
* (default) measures the first rendered row once and reuses it, so it adapts
|
|
106
|
+
* to the active density / touch target automatically. Read only when
|
|
107
|
+
* `virtualScroll` is on. @default 0
|
|
108
|
+
*/
|
|
109
|
+
rowHeight = input(0, { ...(ngDevMode ? { debugName: "rowHeight" } : /* istanbul ignore next */ {}), transform: (v) => Math.max(0, coerceNumberProperty(v, 0)) });
|
|
110
|
+
/**
|
|
111
|
+
* Height of the scroll viewport when `virtualScroll` is on — a number (px) or
|
|
112
|
+
* any CSS length (`'60vh'`). A numeric px value lets the server prerender the
|
|
113
|
+
* exact first window. @default 288
|
|
114
|
+
*/
|
|
115
|
+
viewportHeight = input(288, /* @ts-ignore */
|
|
116
|
+
...(ngDevMode ? [{ debugName: "viewportHeight" }] : /* istanbul ignore next */ []));
|
|
117
|
+
/** Extra rows kept rendered above and below the viewport as scroll headroom. @default 6 */
|
|
118
|
+
overscan = input(6, { ...(ngDevMode ? { debugName: "overscan" } : /* istanbul ignore next */ {}), transform: (v) => Math.max(0, coerceNumberProperty(v, 6)) });
|
|
119
|
+
/**
|
|
120
|
+
* Form value — the current selection as seen by a bound field. Bound by
|
|
121
|
+
* `[formField]`, or two-way via `[(value)]`. Shape follows `selectionMode`:
|
|
122
|
+
* `TId | null` in single mode, `readonly TId[]` in multi mode. Meaningful in
|
|
123
|
+
* `overlay` mode; inline mode drives selection via `[(selected)]` instead.
|
|
124
|
+
*/
|
|
125
|
+
value = model(undefined, /* @ts-ignore */
|
|
126
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
127
|
+
/** Emitted on blur so a bound field can mark itself touched. */
|
|
128
|
+
touch = output();
|
|
86
129
|
// Internals
|
|
87
130
|
host = inject(ElementRef);
|
|
88
131
|
overlay = inject(WR_OVERLAY);
|
|
89
132
|
vcr = inject(ViewContainerRef);
|
|
90
133
|
scrollStrategies = inject(ScrollStrategyOptions);
|
|
91
134
|
destroyRef = inject(DestroyRef);
|
|
135
|
+
platformId = inject(PLATFORM_ID);
|
|
92
136
|
/** Currently focused row's index in the flattened visible list. */
|
|
93
137
|
focusedIndex = signal(0, /* @ts-ignore */
|
|
94
138
|
...(ngDevMode ? [{ debugName: "focusedIndex" }] : /* istanbul ignore next */ []));
|
|
@@ -102,12 +146,12 @@ class WrTree {
|
|
|
102
146
|
const expanded = new Set(this.expanded());
|
|
103
147
|
const out = [];
|
|
104
148
|
const walk = (list, depth) => {
|
|
105
|
-
|
|
149
|
+
list.forEach((node, i) => {
|
|
106
150
|
const hasChildren = (node.children?.length ?? 0) > 0;
|
|
107
|
-
out.push({ node, depth, hasChildren });
|
|
151
|
+
out.push({ node, depth, hasChildren, index: out.length, posinset: i + 1, setsize: list.length });
|
|
108
152
|
if (hasChildren && expanded.has(node.id))
|
|
109
153
|
walk(node.children, depth + 1);
|
|
110
|
-
}
|
|
154
|
+
});
|
|
111
155
|
};
|
|
112
156
|
walk(this.nodes(), 0);
|
|
113
157
|
return out;
|
|
@@ -168,13 +212,9 @@ class WrTree {
|
|
|
168
212
|
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
169
213
|
/** Trigger / panel id for `aria-controls`. */
|
|
170
214
|
panelId = `wr-tree-panel-${++panelUid}`;
|
|
171
|
-
disabledFromCva = signal(false, /* @ts-ignore */
|
|
172
|
-
...(ngDevMode ? [{ debugName: "disabledFromCva" }] : /* istanbul ignore next */ []));
|
|
173
|
-
isDisabled = computed(() => this.disabled() || this.disabledFromCva(), /* @ts-ignore */
|
|
174
|
-
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
175
215
|
classes = computed(() => {
|
|
176
216
|
const parts = ['wr-tree'];
|
|
177
|
-
if (this.
|
|
217
|
+
if (this.disabled())
|
|
178
218
|
parts.push('wr-tree--disabled');
|
|
179
219
|
if (this.isOverlay()) {
|
|
180
220
|
parts.push('wr-tree--combobox');
|
|
@@ -188,10 +228,103 @@ class WrTree {
|
|
|
188
228
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
189
229
|
panelTpl = viewChild('panelTpl', { ...(ngDevMode ? { debugName: "panelTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
|
|
190
230
|
overlayRef = null;
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
231
|
+
// --- Virtual scroll -------------------------------------------------------
|
|
232
|
+
static FALLBACK_ROW_PX = 32;
|
|
233
|
+
static FALLBACK_VIEWPORT_PX = 288;
|
|
234
|
+
/** Live vertical scroll offset (px); 0 on the server / before first scroll. */
|
|
235
|
+
scrollTop = signal(0, /* @ts-ignore */
|
|
236
|
+
...(ngDevMode ? [{ debugName: "scrollTop" }] : /* istanbul ignore next */ []));
|
|
237
|
+
/** Measured viewport clientHeight (px); 0 until the browser observer fires. */
|
|
238
|
+
viewportPx = signal(0, /* @ts-ignore */
|
|
239
|
+
...(ngDevMode ? [{ debugName: "viewportPx" }] : /* istanbul ignore next */ []));
|
|
240
|
+
/** Measured first-row height (px) when `rowHeight` is auto; 0 until measured. */
|
|
241
|
+
measuredRowPx = signal(0, /* @ts-ignore */
|
|
242
|
+
...(ngDevMode ? [{ debugName: "measuredRowPx" }] : /* istanbul ignore next */ []));
|
|
243
|
+
/** Virtualization active (opt-in and there is anything to window). */
|
|
244
|
+
virtualized = computed(() => this.virtualScroll() && this.flat().length > 0, /* @ts-ignore */
|
|
245
|
+
...(ngDevMode ? [{ debugName: "virtualized" }] : /* istanbul ignore next */ []));
|
|
246
|
+
/** Effective uniform row height (px). */
|
|
247
|
+
effRowH = computed(() => this.rowHeight() > 0 ? this.rowHeight() : this.measuredRowPx() || WrTree.FALLBACK_ROW_PX, /* @ts-ignore */
|
|
248
|
+
...(ngDevMode ? [{ debugName: "effRowH" }] : /* istanbul ignore next */ []));
|
|
249
|
+
/** Deterministic viewport px for SSR + first paint (numeric height, else fallback). */
|
|
250
|
+
fallbackViewportPx = computed(() => {
|
|
251
|
+
const h = this.viewportHeight();
|
|
252
|
+
if (typeof h === 'number')
|
|
253
|
+
return h;
|
|
254
|
+
return /^\d+$/.test(h) ? Number(h) : WrTree.FALLBACK_VIEWPORT_PX;
|
|
255
|
+
}, /* @ts-ignore */
|
|
256
|
+
...(ngDevMode ? [{ debugName: "fallbackViewportPx" }] : /* istanbul ignore next */ []));
|
|
257
|
+
/** `viewportHeight` as a CSS length for the inline max-height (bare number → px). */
|
|
258
|
+
resolvedViewportHeight = computed(() => {
|
|
259
|
+
const h = this.viewportHeight();
|
|
260
|
+
return typeof h === 'number' || /^\d+$/.test(h) ? `${h}px` : h;
|
|
261
|
+
}, /* @ts-ignore */
|
|
262
|
+
...(ngDevMode ? [{ debugName: "resolvedViewportHeight" }] : /* istanbul ignore next */ []));
|
|
263
|
+
/** Rendered window [start,end) + spacer pads (px). Pure math from `scrollTop`. */
|
|
264
|
+
virtualWindow = computed(() => {
|
|
265
|
+
const total = this.flat().length;
|
|
266
|
+
if (!this.virtualized() || total === 0)
|
|
267
|
+
return { start: 0, end: total, padTop: 0, padBottom: 0 };
|
|
268
|
+
const h = this.effRowH();
|
|
269
|
+
const vp = this.viewportPx() || this.fallbackViewportPx();
|
|
270
|
+
const over = this.overscan();
|
|
271
|
+
// Clamp `first` so a transient effRowH shrink (auto-measure landing below the
|
|
272
|
+
// fallback within one frame) can't push it past the list and slice to empty.
|
|
273
|
+
const first = Math.min(Math.floor(this.scrollTop() / h), total - 1);
|
|
274
|
+
// `+ 1` covers the partial row at the viewport's bottom edge even at overscan 0.
|
|
275
|
+
const count = Math.ceil(vp / h) + 1;
|
|
276
|
+
const start = Math.max(0, first - over);
|
|
277
|
+
const end = Math.min(total, first + count + over);
|
|
278
|
+
return { start, end, padTop: start * h, padBottom: (total - end) * h };
|
|
279
|
+
}, /* @ts-ignore */
|
|
280
|
+
...(ngDevMode ? [{ debugName: "virtualWindow" }] : /* istanbul ignore next */ []));
|
|
281
|
+
/** Nodes placed in the list. SAME array instance as `flat()` when off → byte-identical DOM. */
|
|
282
|
+
windowRows = computed(() => {
|
|
283
|
+
if (!this.virtualized())
|
|
284
|
+
return this.flat();
|
|
285
|
+
const { start, end } = this.virtualWindow();
|
|
286
|
+
return this.flat().slice(start, end);
|
|
287
|
+
}, /* @ts-ignore */
|
|
288
|
+
...(ngDevMode ? [{ debugName: "windowRows" }] : /* istanbul ignore next */ []));
|
|
289
|
+
/** Stable id for a row at flat index `i` — the `aria-activedescendant` target. */
|
|
290
|
+
rowId(i) {
|
|
291
|
+
return `${this.panelId}-row-${i}`;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Active-descendant id when virtualized (focus stays on the list container),
|
|
295
|
+
* else `null`. Returns `null` while the focused row is outside the rendered
|
|
296
|
+
* window (e.g. mouse-wheeled away) so `aria-activedescendant` never dangles at
|
|
297
|
+
* a removed element — the next arrow key scrolls it back and re-establishes it.
|
|
298
|
+
*/
|
|
299
|
+
activeRowId = computed(() => {
|
|
300
|
+
if (!this.virtualized())
|
|
301
|
+
return null;
|
|
302
|
+
const i = this.focusedIndex();
|
|
303
|
+
const { start, end } = this.virtualWindow();
|
|
304
|
+
return i >= start && i < end ? this.rowId(i) : null;
|
|
305
|
+
}, /* @ts-ignore */
|
|
306
|
+
...(ngDevMode ? [{ debugName: "activeRowId" }] : /* istanbul ignore next */ []));
|
|
307
|
+
/** The scrollable `<ul>` — inside the overlay panel in overlay mode, else in the host. */
|
|
308
|
+
get listElement() {
|
|
309
|
+
const root = this.overlayRef?.overlayElement ?? this.host.nativeElement;
|
|
310
|
+
return root.querySelector('.wr-tree__list');
|
|
311
|
+
}
|
|
312
|
+
/** Scroll flat index `i` just into view (sets the `scrollTop` signal synchronously). */
|
|
313
|
+
ensureVisible(i) {
|
|
314
|
+
const h = this.effRowH();
|
|
315
|
+
const vp = this.viewportPx() || this.fallbackViewportPx();
|
|
316
|
+
const top = i * h;
|
|
317
|
+
const cur = this.scrollTop();
|
|
318
|
+
let next = cur;
|
|
319
|
+
if (top < cur)
|
|
320
|
+
next = top;
|
|
321
|
+
else if (top + h > cur + vp)
|
|
322
|
+
next = top + h - vp;
|
|
323
|
+
if (next !== cur) {
|
|
324
|
+
this.scrollTop.set(next);
|
|
325
|
+
this.listElement?.scrollTo({ top: next });
|
|
326
|
+
}
|
|
327
|
+
}
|
|
195
328
|
constructor() {
|
|
196
329
|
// Drive the overlay open/close in response to the `open` signal.
|
|
197
330
|
effect(() => {
|
|
@@ -207,49 +340,114 @@ class WrTree {
|
|
|
207
340
|
this.closeOverlay();
|
|
208
341
|
}
|
|
209
342
|
});
|
|
343
|
+
// Disabling the control closes any open overlay (mirrors the side effect
|
|
344
|
+
// of the old CVA setDisabledState).
|
|
345
|
+
effect(() => {
|
|
346
|
+
if (this.disabled())
|
|
347
|
+
this.open.set(false);
|
|
348
|
+
});
|
|
349
|
+
// Bridge an external `value` write back into the internal `selected`
|
|
350
|
+
// state (this is the old writeValue body). `undefined` is the untouched
|
|
351
|
+
// sentinel — no field / ngModel has written yet, so leave any preset
|
|
352
|
+
// `[(selected)]` alone; a real `null` still clears, exactly as
|
|
353
|
+
// `writeValue(null)` did. Guarded against the echo of our own `emit()`
|
|
354
|
+
// (equality check under `untracked`) so a live pick is never clobbered.
|
|
355
|
+
effect(() => {
|
|
356
|
+
const value = this.value();
|
|
357
|
+
if (value === undefined)
|
|
358
|
+
return;
|
|
359
|
+
untracked(() => {
|
|
360
|
+
const next = this.isMulti()
|
|
361
|
+
? Array.isArray(value)
|
|
362
|
+
? value
|
|
363
|
+
: []
|
|
364
|
+
: value == null
|
|
365
|
+
? []
|
|
366
|
+
: [value];
|
|
367
|
+
const current = this.selected();
|
|
368
|
+
if (next.length === current.length && next.every((id, i) => id === current[i]))
|
|
369
|
+
return;
|
|
370
|
+
this.selected.set(next);
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
// Wire the scroll listener + viewport/row measurement — only while virtual
|
|
374
|
+
// and in the browser. Re-runs when the list (re)appears (overlay open, data
|
|
375
|
+
// change), deferring the DOM read to a microtask so the portal / inline list
|
|
376
|
+
// is attached. No-op on the server (SSR renders the deterministic first
|
|
377
|
+
// window from inputs alone).
|
|
378
|
+
effect(onCleanup => {
|
|
379
|
+
if (!isPlatformBrowser(this.platformId) || !this.virtualScroll())
|
|
380
|
+
return;
|
|
381
|
+
const open = this.isOverlay() ? this.open() : true;
|
|
382
|
+
this.flat();
|
|
383
|
+
if (!open)
|
|
384
|
+
return;
|
|
385
|
+
let raf = 0;
|
|
386
|
+
let ro = null;
|
|
387
|
+
let el = null;
|
|
388
|
+
const onScroll = () => {
|
|
389
|
+
if (raf)
|
|
390
|
+
return;
|
|
391
|
+
raf = requestAnimationFrame(() => {
|
|
392
|
+
raf = 0;
|
|
393
|
+
if (el)
|
|
394
|
+
this.scrollTop.set(el.scrollTop);
|
|
395
|
+
});
|
|
396
|
+
};
|
|
397
|
+
queueMicrotask(() => {
|
|
398
|
+
el = this.listElement;
|
|
399
|
+
if (!el)
|
|
400
|
+
return;
|
|
401
|
+
// The overlay `<ul>` is destroyed + recreated on each open, but the
|
|
402
|
+
// `scrollTop` signal persists — restore the fresh element to it so a
|
|
403
|
+
// reopened panel isn't blank (window computed from a non-zero signal
|
|
404
|
+
// while the new DOM sits at scrollTop 0). No-op on first open / inline.
|
|
405
|
+
if (el.scrollTop !== this.scrollTop())
|
|
406
|
+
el.scrollTop = this.scrollTop();
|
|
407
|
+
this.viewportPx.set(el.clientHeight);
|
|
408
|
+
if (this.rowHeight() === 0) {
|
|
409
|
+
const h = el.querySelector('.wr-tree__row')?.offsetHeight ?? 0;
|
|
410
|
+
if (h > 0)
|
|
411
|
+
this.measuredRowPx.set(h);
|
|
412
|
+
}
|
|
413
|
+
el.addEventListener('scroll', onScroll, { passive: true });
|
|
414
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
415
|
+
ro = new ResizeObserver(() => {
|
|
416
|
+
if (el)
|
|
417
|
+
this.viewportPx.set(el.clientHeight);
|
|
418
|
+
});
|
|
419
|
+
ro.observe(el);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
onCleanup(() => {
|
|
423
|
+
if (raf)
|
|
424
|
+
cancelAnimationFrame(raf);
|
|
425
|
+
if (el)
|
|
426
|
+
el.removeEventListener('scroll', onScroll);
|
|
427
|
+
ro?.disconnect();
|
|
428
|
+
});
|
|
429
|
+
});
|
|
210
430
|
this.destroyRef.onDestroy(() => this.closeOverlay());
|
|
211
431
|
}
|
|
212
|
-
writeValue(value) {
|
|
213
|
-
if (this.isMulti()) {
|
|
214
|
-
this.selected.set(Array.isArray(value) ? value : []);
|
|
215
|
-
}
|
|
216
|
-
else if (value == null) {
|
|
217
|
-
this.selected.set([]);
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
this.selected.set([value]);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
registerOnChange(fn) {
|
|
224
|
-
this.onChange = fn;
|
|
225
|
-
}
|
|
226
|
-
registerOnTouched(fn) {
|
|
227
|
-
this.onTouched = fn;
|
|
228
|
-
}
|
|
229
|
-
setDisabledState(isDisabled) {
|
|
230
|
-
this.disabledFromCva.set(coerceBooleanProperty(isDisabled));
|
|
231
|
-
if (isDisabled)
|
|
232
|
-
this.open.set(false);
|
|
233
|
-
}
|
|
234
432
|
// Template handlers
|
|
235
433
|
onRowClick(flat, event) {
|
|
236
|
-
if (this.
|
|
434
|
+
if (this.disabled() || flat.node.disabled)
|
|
237
435
|
return;
|
|
238
436
|
if (flat.hasChildren && event.target.closest('.wr-tree__toggle')) {
|
|
239
437
|
this.toggleExpanded(flat.node.id);
|
|
240
438
|
return;
|
|
241
439
|
}
|
|
242
|
-
this.focusIndex(
|
|
440
|
+
this.focusIndex(flat.index);
|
|
243
441
|
this.select(flat.node.id, event.ctrlKey || event.metaKey);
|
|
244
442
|
}
|
|
245
443
|
onToggleClick(node, event) {
|
|
246
444
|
event.stopPropagation();
|
|
247
|
-
if (this.
|
|
445
|
+
if (this.disabled() || node.disabled)
|
|
248
446
|
return;
|
|
249
447
|
this.toggleExpanded(node.id);
|
|
250
448
|
}
|
|
251
449
|
onKeydown(event) {
|
|
252
|
-
if (this.
|
|
450
|
+
if (this.disabled())
|
|
253
451
|
return;
|
|
254
452
|
const flat = this.flat();
|
|
255
453
|
const i = this.focusedIndex();
|
|
@@ -308,13 +506,17 @@ class WrTree {
|
|
|
308
506
|
}
|
|
309
507
|
// Overlay-mode trigger handlers
|
|
310
508
|
onTriggerClick() {
|
|
311
|
-
if (this.
|
|
509
|
+
if (this.disabled())
|
|
312
510
|
return;
|
|
313
511
|
this.open.update(v => !v);
|
|
314
512
|
}
|
|
513
|
+
/** Trigger blur — mark the bound field touched. */
|
|
514
|
+
onBlur() {
|
|
515
|
+
this.touch.emit();
|
|
516
|
+
}
|
|
315
517
|
removeChip(id, event) {
|
|
316
518
|
event.stopPropagation();
|
|
317
|
-
if (this.
|
|
519
|
+
if (this.disabled())
|
|
318
520
|
return;
|
|
319
521
|
const next = this.selected().filter(x => x !== id);
|
|
320
522
|
this.selected.set(next);
|
|
@@ -322,16 +524,10 @@ class WrTree {
|
|
|
322
524
|
}
|
|
323
525
|
clearSelection(event) {
|
|
324
526
|
event.stopPropagation();
|
|
325
|
-
if (this.
|
|
527
|
+
if (this.disabled())
|
|
326
528
|
return;
|
|
327
529
|
this.selected.set([]);
|
|
328
|
-
|
|
329
|
-
this.onChange([]);
|
|
330
|
-
}
|
|
331
|
-
else {
|
|
332
|
-
this.onChange(null);
|
|
333
|
-
}
|
|
334
|
-
this.onTouched();
|
|
530
|
+
this.emit();
|
|
335
531
|
}
|
|
336
532
|
// Selection / expansion plumbing
|
|
337
533
|
toggleExpanded(id) {
|
|
@@ -368,7 +564,7 @@ class WrTree {
|
|
|
368
564
|
}
|
|
369
565
|
this.selected.set([...set]);
|
|
370
566
|
}
|
|
371
|
-
// Overlay mode: propagate to
|
|
567
|
+
// Overlay mode: propagate to the bound value, close on single-mode pick.
|
|
372
568
|
if (this.isOverlay()) {
|
|
373
569
|
this.emit();
|
|
374
570
|
if (mode === 'single' && this.selected().length > 0) {
|
|
@@ -377,17 +573,27 @@ class WrTree {
|
|
|
377
573
|
}
|
|
378
574
|
}
|
|
379
575
|
emit() {
|
|
380
|
-
this.
|
|
576
|
+
this.touch.emit();
|
|
381
577
|
if (this.isMulti()) {
|
|
382
|
-
this.
|
|
578
|
+
this.value.set(this.selected());
|
|
383
579
|
}
|
|
384
580
|
else {
|
|
385
|
-
this.
|
|
581
|
+
this.value.set(this.selected()[0] ?? null);
|
|
386
582
|
}
|
|
387
583
|
}
|
|
388
584
|
focusIndex(i) {
|
|
389
585
|
this.focusedIndex.set(i);
|
|
390
|
-
|
|
586
|
+
if (this.virtualized()) {
|
|
587
|
+
// Managed-focus (aria-activedescendant): focus stays on the list container.
|
|
588
|
+
// Setting `scrollTop` synchronously materializes row `i` in the SAME change
|
|
589
|
+
// detection pass, so the id referenced by `aria-activedescendant` is present
|
|
590
|
+
// — no rAF/microtask race, no "points at an absent id" gap.
|
|
591
|
+
this.ensureVisible(i);
|
|
592
|
+
this.listElement?.focus();
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
// Non-virtual roving tabindex: defer so the DOM has updated tabindex, then
|
|
596
|
+
// move focus to the row element.
|
|
391
597
|
queueMicrotask(() => {
|
|
392
598
|
const root = this.overlayRef?.overlayElement ?? this.host.nativeElement;
|
|
393
599
|
const row = root.querySelector(`[data-tree-index="${i}"]`);
|
|
@@ -429,6 +635,10 @@ class WrTree {
|
|
|
429
635
|
panelClass: 'wr-tree-overlay',
|
|
430
636
|
});
|
|
431
637
|
this.overlayRef.attach(new TemplatePortal(tpl, this.vcr));
|
|
638
|
+
// Virtual mode drives keyboard nav via aria-activedescendant on the list
|
|
639
|
+
// container, so it must hold focus once the panel is attached.
|
|
640
|
+
if (this.virtualized())
|
|
641
|
+
queueMicrotask(() => this.listElement?.focus());
|
|
432
642
|
this.overlayRef
|
|
433
643
|
.outsidePointerEvents()
|
|
434
644
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
@@ -453,27 +663,13 @@ class WrTree {
|
|
|
453
663
|
this.overlayRef.dispose();
|
|
454
664
|
this.overlayRef = null;
|
|
455
665
|
}
|
|
456
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0
|
|
457
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0
|
|
458
|
-
{
|
|
459
|
-
provide: NG_VALUE_ACCESSOR,
|
|
460
|
-
// eslint-disable-next-line @angular-eslint/no-forward-ref
|
|
461
|
-
useExisting: forwardRef(() => WrTree),
|
|
462
|
-
multi: true,
|
|
463
|
-
},
|
|
464
|
-
], viewQueries: [{ propertyName: "panelTpl", first: true, predicate: ["panelTpl"], descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "@if (isOverlay()) {\n <button\n type=\"button\"\n class=\"wr-tree__trigger\"\n role=\"combobox\"\n [disabled]=\"isDisabled()\"\n [attr.aria-haspopup]=\"'tree'\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-multiselectable]=\"isMulti() ? 'true' : null\"\n (click)=\"onTriggerClick()\"\n (blur)=\"onTouched()\"\n >\n @if (isMulti()) {\n @if (hasSelection()) {\n <span class=\"wr-tree__chips\">\n @for (chip of visibleChips(); track chip.id) {\n <span class=\"wr-tree__chip\">\n <span class=\"wr-tree__chip-label\">{{ chip.label }}</span>\n <span\n class=\"wr-tree__chip-remove\"\n role=\"button\"\n [attr.aria-label]=\"chipRemoveLabel({ label: chip.label })\"\n tabindex=\"-1\"\n (click)=\"removeChip(chip.id, $event)\"\n (keydown.enter)=\"removeChip(chip.id, $event)\"\n (keydown.space)=\"removeChip(chip.id, $event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n </span>\n }\n @if (hiddenChipCount(); as extra) {\n <span class=\"wr-tree__chip wr-tree__chip--more\">+{{ extra }} more</span>\n }\n </span>\n } @else {\n <span class=\"wr-tree__placeholder\">{{ placeholder() }}</span>\n }\n } @else {\n @if (singleLabel(); as label) {\n <span class=\"wr-tree__value\">{{ label }}</span>\n } @else {\n <span class=\"wr-tree__placeholder\">{{ placeholder() }}</span>\n }\n }\n\n @if (clearable() && hasSelection() && !isDisabled()) {\n <span\n class=\"wr-tree__clear\"\n role=\"button\"\n [attr.aria-label]=\"clearLabel\"\n tabindex=\"-1\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n }\n\n <svg\n class=\"wr-icon__svg wr-tree__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </button>\n\n <!-- Tree list lives inside the overlay panel. -->\n <ng-template #panelTpl>\n <div class=\"wr-tree-panel\" [attr.id]=\"panelId\">\n <ng-container [ngTemplateOutlet]=\"listTpl\" />\n </div>\n </ng-template>\n} @else {\n <ng-container [ngTemplateOutlet]=\"listTpl\" />\n}\n\n<!-- Shared row list \u2014 rendered inline (default) or projected into the\n overlay panel (when openOn=\"overlay\"). -->\n<ng-template #listTpl>\n <!-- Roving tabindex: the tree owns keyboard focus and routes arrow keys\n to its currently-focused row. -->\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n <ul class=\"wr-tree__list\" role=\"tree\" (keydown)=\"onKeydown($event)\">\n @for (entry of flat(); track entry.node.id) {\n <!-- Click handler lives on focusable rows; keyboard handling is owned\n by the parent <ul> via the roving-tabindex pattern. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n <li\n class=\"wr-tree__row\"\n role=\"treeitem\"\n [class.wr-tree__row--selected]=\"selectedSet().has(entry.node.id)\"\n [class.wr-tree__row--disabled]=\"entry.node.disabled\"\n [attr.aria-level]=\"entry.depth + 1\"\n [attr.aria-expanded]=\"entry.hasChildren ? expandedSet().has(entry.node.id) : null\"\n [attr.aria-selected]=\"selectionMode() === 'none' ? null : selectedSet().has(entry.node.id)\"\n [attr.aria-disabled]=\"entry.node.disabled || isDisabled() || null\"\n [attr.data-tree-index]=\"$index\"\n [attr.tabindex]=\"$index === focusedIndex() ? 0 : -1\"\n [style.--wr-tree-depth]=\"entry.depth\"\n (click)=\"onRowClick(entry, $event)\"\n >\n @if (entry.hasChildren) {\n <button\n type=\"button\"\n class=\"wr-tree__toggle\"\n tabindex=\"-1\"\n [attr.aria-label]=\"expandedSet().has(entry.node.id) ? collapseLabel : expandLabel\"\n (click)=\"onToggleClick(entry.node, $event)\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M3 1 L7 5 L3 9 Z\" fill=\"currentColor\" />\n </svg>\n </button>\n } @else {\n <span class=\"wr-tree__toggle wr-tree__toggle--leaf\" aria-hidden=\"true\"></span>\n }\n <span class=\"wr-tree__label\">{{ entry.node.label }}</span>\n </li>\n }\n </ul>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
666
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTree, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
667
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: WrTree, isStandalone: true, selector: "wr-tree", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, openOn: { classPropertyName: "openOn", publicName: "openOn", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, maxTagCount: { classPropertyName: "maxTagCount", publicName: "maxTagCount", isSignal: true, isRequired: false, transformFunction: null }, defaultExpandAll: { classPropertyName: "defaultExpandAll", publicName: "defaultExpandAll", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, viewportHeight: { classPropertyName: "viewportHeight", publicName: "viewportHeight", isSignal: true, isRequired: false, transformFunction: null }, overscan: { classPropertyName: "overscan", publicName: "overscan", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange", expanded: "expandedChange", value: "valueChange", touch: "touch" }, host: { properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "panelTpl", first: true, predicate: ["panelTpl"], descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "@if (isOverlay()) {\n <button\n type=\"button\"\n class=\"wr-tree__trigger\"\n role=\"combobox\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'tree'\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-multiselectable]=\"isMulti() ? 'true' : null\"\n (click)=\"onTriggerClick()\"\n (blur)=\"onBlur()\"\n >\n @if (isMulti()) {\n @if (hasSelection()) {\n <span class=\"wr-tree__chips\">\n @for (chip of visibleChips(); track chip.id) {\n <span class=\"wr-tree__chip\">\n <span class=\"wr-tree__chip-label\">{{ chip.label }}</span>\n <span\n class=\"wr-tree__chip-remove\"\n role=\"button\"\n [attr.aria-label]=\"chipRemoveLabel({ label: chip.label })\"\n tabindex=\"-1\"\n (click)=\"removeChip(chip.id, $event)\"\n (keydown.enter)=\"removeChip(chip.id, $event)\"\n (keydown.space)=\"removeChip(chip.id, $event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n </span>\n }\n @if (hiddenChipCount(); as extra) {\n <span class=\"wr-tree__chip wr-tree__chip--more\">+{{ extra }} more</span>\n }\n </span>\n } @else {\n <span class=\"wr-tree__placeholder\">{{ placeholder() }}</span>\n }\n } @else {\n @if (singleLabel(); as label) {\n <span class=\"wr-tree__value\">{{ label }}</span>\n } @else {\n <span class=\"wr-tree__placeholder\">{{ placeholder() }}</span>\n }\n }\n\n @if (clearable() && hasSelection() && !disabled()) {\n <span\n class=\"wr-tree__clear\"\n role=\"button\"\n [attr.aria-label]=\"clearLabel\"\n tabindex=\"-1\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n }\n\n <svg\n class=\"wr-icon__svg wr-tree__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </button>\n\n <!-- Tree list lives inside the overlay panel. -->\n <ng-template #panelTpl>\n <div class=\"wr-tree-panel\" [class.wr-tree-panel--virtual]=\"virtualized()\" [attr.id]=\"panelId\">\n <ng-container [ngTemplateOutlet]=\"listTpl\" />\n </div>\n </ng-template>\n} @else {\n <ng-container [ngTemplateOutlet]=\"listTpl\" />\n}\n\n<!-- Shared row list \u2014 rendered inline (default) or projected into the\n overlay panel (when openOn=\"overlay\"). -->\n<ng-template #listTpl>\n <!-- Roving tabindex (non-virtual) / aria-activedescendant (virtual): the tree\n owns keyboard focus and routes arrow keys to its currently-focused row. -->\n <ul\n class=\"wr-tree__list\"\n role=\"tree\"\n [class.wr-tree__list--virtual]=\"virtualized()\"\n [attr.tabindex]=\"virtualized() ? 0 : null\"\n [attr.aria-activedescendant]=\"activeRowId()\"\n [style.max-height]=\"virtualized() ? resolvedViewportHeight() : null\"\n [style.overflow-y]=\"virtualized() ? 'auto' : null\"\n (keydown)=\"onKeydown($event)\"\n >\n @if (virtualized() && virtualWindow().padTop > 0) {\n <li\n class=\"wr-tree__spacer\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.height.px]=\"virtualWindow().padTop\"\n ></li>\n }\n @for (entry of windowRows(); track entry.node.id) {\n <!-- Click handler lives on focusable rows; keyboard handling is owned\n by the parent <ul> via the roving-tabindex pattern. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n <li\n class=\"wr-tree__row\"\n role=\"treeitem\"\n [attr.id]=\"virtualized() ? rowId(entry.index) : null\"\n [class.wr-tree__row--selected]=\"selectedSet().has(entry.node.id)\"\n [class.wr-tree__row--active]=\"virtualized() && entry.index === focusedIndex()\"\n [class.wr-tree__row--disabled]=\"entry.node.disabled\"\n [attr.aria-level]=\"entry.depth + 1\"\n [attr.aria-setsize]=\"virtualized() ? entry.setsize : null\"\n [attr.aria-posinset]=\"virtualized() ? entry.posinset : null\"\n [attr.aria-expanded]=\"entry.hasChildren ? expandedSet().has(entry.node.id) : null\"\n [attr.aria-selected]=\"selectionMode() === 'none' ? null : selectedSet().has(entry.node.id)\"\n [attr.aria-disabled]=\"entry.node.disabled || disabled() || null\"\n [attr.data-tree-index]=\"entry.index\"\n [attr.tabindex]=\"virtualized() ? null : entry.index === focusedIndex() ? 0 : -1\"\n [style.--wr-tree-depth]=\"entry.depth\"\n (click)=\"onRowClick(entry, $event)\"\n >\n @if (entry.hasChildren) {\n <button\n type=\"button\"\n class=\"wr-tree__toggle\"\n tabindex=\"-1\"\n [attr.aria-label]=\"expandedSet().has(entry.node.id) ? collapseLabel : expandLabel\"\n (click)=\"onToggleClick(entry.node, $event)\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M3 1 L7 5 L3 9 Z\" fill=\"currentColor\" />\n </svg>\n </button>\n } @else {\n <span class=\"wr-tree__toggle wr-tree__toggle--leaf\" aria-hidden=\"true\"></span>\n }\n <span class=\"wr-tree__label\">{{ entry.node.label }}</span>\n </li>\n }\n @if (virtualized() && virtualWindow().padBottom > 0) {\n <li\n class=\"wr-tree__spacer\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.height.px]=\"virtualWindow().padBottom\"\n ></li>\n }\n </ul>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
465
668
|
}
|
|
466
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0
|
|
669
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTree, decorators: [{
|
|
467
670
|
type: Component,
|
|
468
|
-
args: [{ selector: 'wr-tree', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, imports: [NgTemplateOutlet],
|
|
469
|
-
|
|
470
|
-
provide: NG_VALUE_ACCESSOR,
|
|
471
|
-
// eslint-disable-next-line @angular-eslint/no-forward-ref
|
|
472
|
-
useExisting: forwardRef(() => WrTree),
|
|
473
|
-
multi: true,
|
|
474
|
-
},
|
|
475
|
-
], template: "@if (isOverlay()) {\n <button\n type=\"button\"\n class=\"wr-tree__trigger\"\n role=\"combobox\"\n [disabled]=\"isDisabled()\"\n [attr.aria-haspopup]=\"'tree'\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-multiselectable]=\"isMulti() ? 'true' : null\"\n (click)=\"onTriggerClick()\"\n (blur)=\"onTouched()\"\n >\n @if (isMulti()) {\n @if (hasSelection()) {\n <span class=\"wr-tree__chips\">\n @for (chip of visibleChips(); track chip.id) {\n <span class=\"wr-tree__chip\">\n <span class=\"wr-tree__chip-label\">{{ chip.label }}</span>\n <span\n class=\"wr-tree__chip-remove\"\n role=\"button\"\n [attr.aria-label]=\"chipRemoveLabel({ label: chip.label })\"\n tabindex=\"-1\"\n (click)=\"removeChip(chip.id, $event)\"\n (keydown.enter)=\"removeChip(chip.id, $event)\"\n (keydown.space)=\"removeChip(chip.id, $event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n </span>\n }\n @if (hiddenChipCount(); as extra) {\n <span class=\"wr-tree__chip wr-tree__chip--more\">+{{ extra }} more</span>\n }\n </span>\n } @else {\n <span class=\"wr-tree__placeholder\">{{ placeholder() }}</span>\n }\n } @else {\n @if (singleLabel(); as label) {\n <span class=\"wr-tree__value\">{{ label }}</span>\n } @else {\n <span class=\"wr-tree__placeholder\">{{ placeholder() }}</span>\n }\n }\n\n @if (clearable() && hasSelection() && !isDisabled()) {\n <span\n class=\"wr-tree__clear\"\n role=\"button\"\n [attr.aria-label]=\"clearLabel\"\n tabindex=\"-1\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n }\n\n <svg\n class=\"wr-icon__svg wr-tree__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </button>\n\n <!-- Tree list lives inside the overlay panel. -->\n <ng-template #panelTpl>\n <div class=\"wr-tree-panel\" [attr.id]=\"panelId\">\n <ng-container [ngTemplateOutlet]=\"listTpl\" />\n </div>\n </ng-template>\n} @else {\n <ng-container [ngTemplateOutlet]=\"listTpl\" />\n}\n\n<!-- Shared row list \u2014 rendered inline (default) or projected into the\n overlay panel (when openOn=\"overlay\"). -->\n<ng-template #listTpl>\n <!-- Roving tabindex: the tree owns keyboard focus and routes arrow keys\n to its currently-focused row. -->\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n <ul class=\"wr-tree__list\" role=\"tree\" (keydown)=\"onKeydown($event)\">\n @for (entry of flat(); track entry.node.id) {\n <!-- Click handler lives on focusable rows; keyboard handling is owned\n by the parent <ul> via the roving-tabindex pattern. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n <li\n class=\"wr-tree__row\"\n role=\"treeitem\"\n [class.wr-tree__row--selected]=\"selectedSet().has(entry.node.id)\"\n [class.wr-tree__row--disabled]=\"entry.node.disabled\"\n [attr.aria-level]=\"entry.depth + 1\"\n [attr.aria-expanded]=\"entry.hasChildren ? expandedSet().has(entry.node.id) : null\"\n [attr.aria-selected]=\"selectionMode() === 'none' ? null : selectedSet().has(entry.node.id)\"\n [attr.aria-disabled]=\"entry.node.disabled || isDisabled() || null\"\n [attr.data-tree-index]=\"$index\"\n [attr.tabindex]=\"$index === focusedIndex() ? 0 : -1\"\n [style.--wr-tree-depth]=\"entry.depth\"\n (click)=\"onRowClick(entry, $event)\"\n >\n @if (entry.hasChildren) {\n <button\n type=\"button\"\n class=\"wr-tree__toggle\"\n tabindex=\"-1\"\n [attr.aria-label]=\"expandedSet().has(entry.node.id) ? collapseLabel : expandLabel\"\n (click)=\"onToggleClick(entry.node, $event)\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M3 1 L7 5 L3 9 Z\" fill=\"currentColor\" />\n </svg>\n </button>\n } @else {\n <span class=\"wr-tree__toggle wr-tree__toggle--leaf\" aria-hidden=\"true\"></span>\n }\n <span class=\"wr-tree__label\">{{ entry.node.label }}</span>\n </li>\n }\n </ul>\n</ng-template>\n" }]
|
|
476
|
-
}], ctorParameters: () => [], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }, { type: i0.Output, args: ["selectedChange"] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], openOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOn", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], maxTagCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTagCount", required: false }] }], defaultExpandAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultExpandAll", required: false }] }], panelTpl: [{ type: i0.ViewChild, args: ['panelTpl', { ...{ read: TemplateRef }, isSignal: true }] }] } });
|
|
671
|
+
args: [{ selector: 'wr-tree', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, imports: [NgTemplateOutlet], template: "@if (isOverlay()) {\n <button\n type=\"button\"\n class=\"wr-tree__trigger\"\n role=\"combobox\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'tree'\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-multiselectable]=\"isMulti() ? 'true' : null\"\n (click)=\"onTriggerClick()\"\n (blur)=\"onBlur()\"\n >\n @if (isMulti()) {\n @if (hasSelection()) {\n <span class=\"wr-tree__chips\">\n @for (chip of visibleChips(); track chip.id) {\n <span class=\"wr-tree__chip\">\n <span class=\"wr-tree__chip-label\">{{ chip.label }}</span>\n <span\n class=\"wr-tree__chip-remove\"\n role=\"button\"\n [attr.aria-label]=\"chipRemoveLabel({ label: chip.label })\"\n tabindex=\"-1\"\n (click)=\"removeChip(chip.id, $event)\"\n (keydown.enter)=\"removeChip(chip.id, $event)\"\n (keydown.space)=\"removeChip(chip.id, $event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n </span>\n }\n @if (hiddenChipCount(); as extra) {\n <span class=\"wr-tree__chip wr-tree__chip--more\">+{{ extra }} more</span>\n }\n </span>\n } @else {\n <span class=\"wr-tree__placeholder\">{{ placeholder() }}</span>\n }\n } @else {\n @if (singleLabel(); as label) {\n <span class=\"wr-tree__value\">{{ label }}</span>\n } @else {\n <span class=\"wr-tree__placeholder\">{{ placeholder() }}</span>\n }\n }\n\n @if (clearable() && hasSelection() && !disabled()) {\n <span\n class=\"wr-tree__clear\"\n role=\"button\"\n [attr.aria-label]=\"clearLabel\"\n tabindex=\"-1\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </span>\n }\n\n <svg\n class=\"wr-icon__svg wr-tree__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </button>\n\n <!-- Tree list lives inside the overlay panel. -->\n <ng-template #panelTpl>\n <div class=\"wr-tree-panel\" [class.wr-tree-panel--virtual]=\"virtualized()\" [attr.id]=\"panelId\">\n <ng-container [ngTemplateOutlet]=\"listTpl\" />\n </div>\n </ng-template>\n} @else {\n <ng-container [ngTemplateOutlet]=\"listTpl\" />\n}\n\n<!-- Shared row list \u2014 rendered inline (default) or projected into the\n overlay panel (when openOn=\"overlay\"). -->\n<ng-template #listTpl>\n <!-- Roving tabindex (non-virtual) / aria-activedescendant (virtual): the tree\n owns keyboard focus and routes arrow keys to its currently-focused row. -->\n <ul\n class=\"wr-tree__list\"\n role=\"tree\"\n [class.wr-tree__list--virtual]=\"virtualized()\"\n [attr.tabindex]=\"virtualized() ? 0 : null\"\n [attr.aria-activedescendant]=\"activeRowId()\"\n [style.max-height]=\"virtualized() ? resolvedViewportHeight() : null\"\n [style.overflow-y]=\"virtualized() ? 'auto' : null\"\n (keydown)=\"onKeydown($event)\"\n >\n @if (virtualized() && virtualWindow().padTop > 0) {\n <li\n class=\"wr-tree__spacer\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.height.px]=\"virtualWindow().padTop\"\n ></li>\n }\n @for (entry of windowRows(); track entry.node.id) {\n <!-- Click handler lives on focusable rows; keyboard handling is owned\n by the parent <ul> via the roving-tabindex pattern. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n <li\n class=\"wr-tree__row\"\n role=\"treeitem\"\n [attr.id]=\"virtualized() ? rowId(entry.index) : null\"\n [class.wr-tree__row--selected]=\"selectedSet().has(entry.node.id)\"\n [class.wr-tree__row--active]=\"virtualized() && entry.index === focusedIndex()\"\n [class.wr-tree__row--disabled]=\"entry.node.disabled\"\n [attr.aria-level]=\"entry.depth + 1\"\n [attr.aria-setsize]=\"virtualized() ? entry.setsize : null\"\n [attr.aria-posinset]=\"virtualized() ? entry.posinset : null\"\n [attr.aria-expanded]=\"entry.hasChildren ? expandedSet().has(entry.node.id) : null\"\n [attr.aria-selected]=\"selectionMode() === 'none' ? null : selectedSet().has(entry.node.id)\"\n [attr.aria-disabled]=\"entry.node.disabled || disabled() || null\"\n [attr.data-tree-index]=\"entry.index\"\n [attr.tabindex]=\"virtualized() ? null : entry.index === focusedIndex() ? 0 : -1\"\n [style.--wr-tree-depth]=\"entry.depth\"\n (click)=\"onRowClick(entry, $event)\"\n >\n @if (entry.hasChildren) {\n <button\n type=\"button\"\n class=\"wr-tree__toggle\"\n tabindex=\"-1\"\n [attr.aria-label]=\"expandedSet().has(entry.node.id) ? collapseLabel : expandLabel\"\n (click)=\"onToggleClick(entry.node, $event)\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M3 1 L7 5 L3 9 Z\" fill=\"currentColor\" />\n </svg>\n </button>\n } @else {\n <span class=\"wr-tree__toggle wr-tree__toggle--leaf\" aria-hidden=\"true\"></span>\n }\n <span class=\"wr-tree__label\">{{ entry.node.label }}</span>\n </li>\n }\n @if (virtualized() && virtualWindow().padBottom > 0) {\n <li\n class=\"wr-tree__spacer\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.height.px]=\"virtualWindow().padBottom\"\n ></li>\n }\n </ul>\n</ng-template>\n" }]
|
|
672
|
+
}], ctorParameters: () => [], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }, { type: i0.Output, args: ["selectedChange"] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], openOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOn", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], maxTagCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTagCount", required: false }] }], defaultExpandAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultExpandAll", required: false }] }], virtualScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualScroll", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], viewportHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewportHeight", required: false }] }], overscan: [{ type: i0.Input, args: [{ isSignal: true, alias: "overscan", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touch: [{ type: i0.Output, args: ["touch"] }], panelTpl: [{ type: i0.ViewChild, args: ['panelTpl', { ...{ read: TemplateRef }, isSignal: true }] }] } });
|
|
477
673
|
|
|
478
674
|
/**
|
|
479
675
|
* Generated bundle index. Do not edit.
|