ngwr 15.0.1 → 15.2.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/anchor/styles/_index.scss +13 -2
- package/bits/aurora/styles/_rules.scss +11 -0
- package/bits/dot-grid/dot-grid.scss +1 -0
- package/bits/dot-grid/styles/_index.scss +8 -0
- package/bits/dot-grid/styles/_rules.scss +54 -0
- package/bits/iridescence/iridescence.scss +1 -0
- package/bits/iridescence/styles/_index.scss +8 -0
- package/bits/iridescence/styles/_rules.scss +72 -0
- package/bits/marquee/styles/_rules.scss +7 -3
- package/bits/ripple-grid/ripple-grid.scss +1 -0
- package/bits/ripple-grid/styles/_index.scss +8 -0
- package/bits/ripple-grid/styles/_rules.scss +63 -0
- package/bits/spotlight-card/styles/_rules.scss +7 -4
- package/bits/star-border/styles/_rules.scss +5 -2
- package/bits/threads/styles/_index.scss +8 -0
- package/bits/threads/styles/_rules.scss +76 -0
- package/bits/threads/threads.scss +1 -0
- package/bits/waves/styles/_rules.scss +8 -1
- package/charts/bar-chart/styles/_index.scss +607 -7
- package/charts/boxplot-chart/styles/_index.scss +297 -0
- package/charts/bullet-chart/styles/_index.scss +268 -0
- package/charts/calendar-heatmap/styles/_index.scss +25 -3
- package/charts/candlestick-chart/styles/_index.scss +307 -0
- package/charts/chart-legend/styles/_index.scss +143 -0
- package/charts/core/styles/_index.scss +30 -0
- package/charts/donut-chart/styles/_index.scss +39 -3
- package/charts/funnel-chart/styles/_index.scss +237 -0
- package/charts/gauge/styles/_index.scss +4 -2
- package/charts/heatmap-chart/styles/_index.scss +329 -0
- package/charts/line-chart/styles/_index.scss +141 -8
- package/charts/meter-group/styles/_index.scss +44 -13
- package/charts/radar-chart/styles/_index.scss +206 -0
- package/charts/scatter-chart/styles/_index.scss +245 -0
- package/charts/sparkline/styles/_index.scss +10 -1
- package/charts/treemap-chart/styles/_index.scss +215 -0
- package/charts/waterfall-chart/styles/_index.scss +321 -0
- package/collapse/styles/_index.scss +6 -1
- package/fesm2022/ngwr-affix.mjs +3 -3
- package/fesm2022/ngwr-alert.mjs +3 -3
- package/fesm2022/ngwr-anchor.mjs +3 -3
- package/fesm2022/ngwr-avatar.mjs +3 -3
- package/fesm2022/ngwr-back-top.mjs +3 -3
- package/fesm2022/ngwr-badge.mjs +6 -6
- package/fesm2022/ngwr-bits-aurora.mjs +30 -38
- package/fesm2022/ngwr-bits-aurora.mjs.map +1 -1
- package/fesm2022/ngwr-bits-blur-text.mjs +3 -3
- package/fesm2022/ngwr-bits-border-glow-testing.mjs.map +1 -1
- package/fesm2022/ngwr-bits-border-glow.mjs +11 -5
- package/fesm2022/ngwr-bits-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-bits-circular-text.mjs +3 -3
- package/fesm2022/ngwr-bits-click-spark.mjs +3 -3
- package/fesm2022/ngwr-bits-confetti.mjs +3 -3
- package/fesm2022/ngwr-bits-decrypt-text.mjs +3 -3
- package/fesm2022/ngwr-bits-dot-grid-testing.mjs +40 -0
- package/fesm2022/ngwr-bits-dot-grid-testing.mjs.map +1 -0
- package/fesm2022/ngwr-bits-dot-grid.mjs +482 -0
- package/fesm2022/ngwr-bits-dot-grid.mjs.map +1 -0
- package/fesm2022/ngwr-bits-falling-text.mjs +3 -3
- package/fesm2022/ngwr-bits-fuzzy-text.mjs +3 -3
- package/fesm2022/ngwr-bits-glitch-text.mjs +3 -3
- package/fesm2022/ngwr-bits-gradient-text.mjs +3 -3
- package/fesm2022/ngwr-bits-iridescence-testing.mjs +31 -0
- package/fesm2022/ngwr-bits-iridescence-testing.mjs.map +1 -0
- package/fesm2022/ngwr-bits-iridescence.mjs +591 -0
- package/fesm2022/ngwr-bits-iridescence.mjs.map +1 -0
- package/fesm2022/ngwr-bits-marquee-testing.mjs +1 -1
- package/fesm2022/ngwr-bits-marquee-testing.mjs.map +1 -1
- package/fesm2022/ngwr-bits-marquee.mjs +7 -7
- package/fesm2022/ngwr-bits-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-bits-ripple-grid-testing.mjs +40 -0
- package/fesm2022/ngwr-bits-ripple-grid-testing.mjs.map +1 -0
- package/fesm2022/ngwr-bits-ripple-grid.mjs +805 -0
- package/fesm2022/ngwr-bits-ripple-grid.mjs.map +1 -0
- package/fesm2022/ngwr-bits-rotating-text.mjs +3 -3
- package/fesm2022/ngwr-bits-shiny-text.mjs +6 -6
- package/fesm2022/ngwr-bits-splash-cursor.mjs +3 -3
- package/fesm2022/ngwr-bits-split-text.mjs +3 -3
- package/fesm2022/ngwr-bits-spotlight-card-testing.mjs +1 -1
- package/fesm2022/ngwr-bits-spotlight-card-testing.mjs.map +1 -1
- package/fesm2022/ngwr-bits-spotlight-card.mjs +10 -10
- package/fesm2022/ngwr-bits-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-bits-star-border-testing.mjs +1 -1
- package/fesm2022/ngwr-bits-star-border-testing.mjs.map +1 -1
- package/fesm2022/ngwr-bits-star-border.mjs +7 -7
- package/fesm2022/ngwr-bits-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-bits-threads-testing.mjs +41 -0
- package/fesm2022/ngwr-bits-threads-testing.mjs.map +1 -0
- package/fesm2022/ngwr-bits-threads.mjs +482 -0
- package/fesm2022/ngwr-bits-threads.mjs.map +1 -0
- package/fesm2022/ngwr-bits-tilt-card.mjs +6 -6
- package/fesm2022/ngwr-bits-typewriter.mjs +3 -3
- package/fesm2022/ngwr-bits-waves-testing.mjs.map +1 -1
- package/fesm2022/ngwr-bits-waves.mjs +60 -41
- package/fesm2022/ngwr-bits-waves.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +8 -8
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-burger.mjs +3 -3
- package/fesm2022/ngwr-button.mjs +6 -6
- package/fesm2022/ngwr-calendar.mjs +3 -3
- package/fesm2022/ngwr-card.mjs +9 -9
- package/fesm2022/ngwr-carousel.mjs +6 -6
- package/fesm2022/ngwr-cascader.mjs +5 -5
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-charts-bar-chart-testing.mjs +127 -3
- package/fesm2022/ngwr-charts-bar-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-charts-bar-chart.mjs +683 -49
- package/fesm2022/ngwr-charts-bar-chart.mjs.map +1 -1
- package/fesm2022/ngwr-charts-boxplot-chart-testing.mjs +161 -0
- package/fesm2022/ngwr-charts-boxplot-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-boxplot-chart.mjs +517 -0
- package/fesm2022/ngwr-charts-boxplot-chart.mjs.map +1 -0
- package/fesm2022/ngwr-charts-bullet-chart-testing.mjs +68 -0
- package/fesm2022/ngwr-charts-bullet-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-bullet-chart.mjs +459 -0
- package/fesm2022/ngwr-charts-bullet-chart.mjs.map +1 -0
- package/fesm2022/ngwr-charts-calendar-heatmap-testing.mjs +27 -0
- package/fesm2022/ngwr-charts-calendar-heatmap-testing.mjs.map +1 -1
- package/fesm2022/ngwr-charts-calendar-heatmap.mjs +96 -17
- package/fesm2022/ngwr-charts-calendar-heatmap.mjs.map +1 -1
- package/fesm2022/ngwr-charts-candlestick-chart-testing.mjs +107 -0
- package/fesm2022/ngwr-charts-candlestick-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-candlestick-chart.mjs +508 -0
- package/fesm2022/ngwr-charts-candlestick-chart.mjs.map +1 -0
- package/fesm2022/ngwr-charts-chart-legend-testing.mjs +126 -0
- package/fesm2022/ngwr-charts-chart-legend-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-chart-legend.mjs +251 -0
- package/fesm2022/ngwr-charts-chart-legend.mjs.map +1 -0
- package/fesm2022/ngwr-charts-core.mjs +383 -0
- package/fesm2022/ngwr-charts-core.mjs.map +1 -0
- package/fesm2022/ngwr-charts-donut-chart-testing.mjs +10 -1
- package/fesm2022/ngwr-charts-donut-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-charts-donut-chart.mjs +187 -31
- package/fesm2022/ngwr-charts-donut-chart.mjs.map +1 -1
- package/fesm2022/ngwr-charts-funnel-chart-testing.mjs +100 -0
- package/fesm2022/ngwr-charts-funnel-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-funnel-chart.mjs +415 -0
- package/fesm2022/ngwr-charts-funnel-chart.mjs.map +1 -0
- package/fesm2022/ngwr-charts-gauge-testing.mjs +9 -3
- package/fesm2022/ngwr-charts-gauge-testing.mjs.map +1 -1
- package/fesm2022/ngwr-charts-gauge.mjs +9 -15
- package/fesm2022/ngwr-charts-gauge.mjs.map +1 -1
- package/fesm2022/ngwr-charts-heatmap-chart-testing.mjs +120 -0
- package/fesm2022/ngwr-charts-heatmap-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-heatmap-chart.mjs +519 -0
- package/fesm2022/ngwr-charts-heatmap-chart.mjs.map +1 -0
- package/fesm2022/ngwr-charts-line-chart-testing.mjs +43 -1
- package/fesm2022/ngwr-charts-line-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-charts-line-chart.mjs +436 -122
- package/fesm2022/ngwr-charts-line-chart.mjs.map +1 -1
- package/fesm2022/ngwr-charts-meter-group-testing.mjs +14 -2
- package/fesm2022/ngwr-charts-meter-group-testing.mjs.map +1 -1
- package/fesm2022/ngwr-charts-meter-group.mjs +101 -32
- package/fesm2022/ngwr-charts-meter-group.mjs.map +1 -1
- package/fesm2022/ngwr-charts-radar-chart-testing.mjs +98 -0
- package/fesm2022/ngwr-charts-radar-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-radar-chart.mjs +720 -0
- package/fesm2022/ngwr-charts-radar-chart.mjs.map +1 -0
- package/fesm2022/ngwr-charts-scatter-chart-testing.mjs +132 -0
- package/fesm2022/ngwr-charts-scatter-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-scatter-chart.mjs +545 -0
- package/fesm2022/ngwr-charts-scatter-chart.mjs.map +1 -0
- package/fesm2022/ngwr-charts-sparkline-testing.mjs.map +1 -1
- package/fesm2022/ngwr-charts-sparkline.mjs +14 -16
- package/fesm2022/ngwr-charts-sparkline.mjs.map +1 -1
- package/fesm2022/ngwr-charts-treemap-chart-testing.mjs +103 -0
- package/fesm2022/ngwr-charts-treemap-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-treemap-chart.mjs +535 -0
- package/fesm2022/ngwr-charts-treemap-chart.mjs.map +1 -0
- package/fesm2022/ngwr-charts-waterfall-chart-testing.mjs +131 -0
- package/fesm2022/ngwr-charts-waterfall-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-charts-waterfall-chart.mjs +462 -0
- package/fesm2022/ngwr-charts-waterfall-chart.mjs.map +1 -0
- package/fesm2022/ngwr-checkbox.mjs +6 -6
- package/fesm2022/ngwr-clipboard.mjs +3 -3
- package/fesm2022/ngwr-collapse.mjs +9 -9
- package/fesm2022/ngwr-color-picker.mjs +6 -6
- package/fesm2022/ngwr-command-palette.mjs +3 -3
- package/fesm2022/ngwr-compare.mjs +3 -3
- package/fesm2022/ngwr-context-menu.mjs +12 -12
- package/fesm2022/ngwr-cookie.mjs +3 -3
- package/fesm2022/ngwr-counter.mjs +6 -6
- package/fesm2022/ngwr-date-picker.mjs +21 -21
- package/fesm2022/ngwr-date.mjs +6 -6
- package/fesm2022/ngwr-density.mjs +6 -6
- package/fesm2022/ngwr-descriptions.mjs +6 -6
- package/fesm2022/ngwr-dialog.mjs +15 -15
- package/fesm2022/ngwr-directives.mjs +12 -12
- package/fesm2022/ngwr-divider.mjs +3 -3
- package/fesm2022/ngwr-drawer.mjs +18 -18
- package/fesm2022/ngwr-dropdown.mjs +9 -9
- package/fesm2022/ngwr-editor.mjs +3 -3
- package/fesm2022/ngwr-empty.mjs +3 -3
- package/fesm2022/ngwr-event-calendar.mjs +6 -6
- package/fesm2022/ngwr-file-upload.mjs +3 -3
- package/fesm2022/ngwr-form.mjs +9 -9
- package/fesm2022/ngwr-graph.mjs +6 -6
- package/fesm2022/ngwr-hotkey.mjs +6 -6
- package/fesm2022/ngwr-i18n-ar.mjs +90 -4
- package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-cs.mjs +90 -4
- package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-de.mjs +90 -4
- package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +90 -4
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-es.mjs +90 -4
- package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-fr.mjs +90 -4
- package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-he.mjs +90 -4
- package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-hi.mjs +90 -4
- package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-id.mjs +90 -4
- package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-it.mjs +90 -4
- package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ja.mjs +90 -4
- package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ko.mjs +90 -4
- package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-nl.mjs +90 -4
- package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pl.mjs +90 -4
- package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pt.mjs +90 -4
- package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +90 -4
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-sv.mjs +90 -4
- package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-tr.mjs +90 -4
- package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-uk.mjs +90 -4
- package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-vi.mjs +90 -4
- package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh-tw.mjs +90 -4
- package/fesm2022/ngwr-i18n-zh-tw.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh.mjs +90 -4
- package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
- package/fesm2022/ngwr-i18n.mjs +9 -9
- package/fesm2022/ngwr-icon.mjs +6 -6
- package/fesm2022/ngwr-image-cropper.mjs +3 -3
- package/fesm2022/ngwr-input-number.mjs +3 -3
- package/fesm2022/ngwr-input-otp.mjs +3 -3
- package/fesm2022/ngwr-input.mjs +15 -15
- package/fesm2022/ngwr-keyboard.mjs +3 -3
- package/fesm2022/ngwr-knob.mjs +3 -3
- package/fesm2022/ngwr-layout.mjs +15 -15
- package/fesm2022/ngwr-lightbox.mjs +5 -5
- package/fesm2022/ngwr-lightbox.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 +6 -6
- package/fesm2022/ngwr-mention.mjs +6 -6
- package/fesm2022/ngwr-meta.mjs +6 -6
- package/fesm2022/ngwr-overlay.mjs +6 -6
- package/fesm2022/ngwr-page-header.mjs +3 -3
- package/fesm2022/ngwr-pagination.mjs +3 -3
- package/fesm2022/ngwr-pipes.mjs +21 -21
- package/fesm2022/ngwr-platform.mjs +6 -6
- package/fesm2022/ngwr-popconfirm.mjs +6 -6
- package/fesm2022/ngwr-popover.mjs +43 -20
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-progress.mjs +3 -3
- package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
- package/fesm2022/ngwr-qr.mjs +4 -3
- package/fesm2022/ngwr-qr.mjs.map +1 -1
- package/fesm2022/ngwr-radio.mjs +6 -6
- package/fesm2022/ngwr-rating.mjs +3 -3
- package/fesm2022/ngwr-result.mjs +12 -12
- package/fesm2022/ngwr-schema-form.mjs +3 -3
- package/fesm2022/ngwr-scroll.mjs +3 -3
- package/fesm2022/ngwr-segmented.mjs +3 -3
- package/fesm2022/ngwr-select.mjs +12 -12
- package/fesm2022/ngwr-sidebar.mjs +3 -3
- package/fesm2022/ngwr-skeleton.mjs +3 -3
- package/fesm2022/ngwr-slider.mjs +3 -3
- package/fesm2022/ngwr-sortable-list.mjs +11 -11
- package/fesm2022/ngwr-sortable-list.mjs.map +1 -1
- package/fesm2022/ngwr-speed-dial.mjs +3 -3
- package/fesm2022/ngwr-spinner.mjs +3 -3
- package/fesm2022/ngwr-splitter.mjs +3 -3
- package/fesm2022/ngwr-statistic.mjs +9 -9
- package/fesm2022/ngwr-stepper.mjs +6 -6
- package/fesm2022/ngwr-storage.mjs +3 -3
- package/fesm2022/ngwr-switch.mjs +3 -3
- package/fesm2022/ngwr-table.mjs +18 -18
- package/fesm2022/ngwr-tabs-router.mjs +3 -3
- package/fesm2022/ngwr-tabs.mjs +6 -6
- package/fesm2022/ngwr-textarea.mjs +3 -3
- package/fesm2022/ngwr-theme.mjs +3 -3
- package/fesm2022/ngwr-timeline.mjs +6 -6
- package/fesm2022/ngwr-toast-testing.mjs +2 -1
- package/fesm2022/ngwr-toast-testing.mjs.map +1 -1
- package/fesm2022/ngwr-toast.mjs +34 -15
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-toolbar.mjs +3 -3
- package/fesm2022/ngwr-tour.mjs +6 -6
- package/fesm2022/ngwr-transfer.mjs +3 -3
- package/fesm2022/ngwr-tree.mjs +3 -3
- package/fesm2022/ngwr-typography.mjs +3 -3
- package/fesm2022/ngwr-utils.mjs +31 -1
- package/fesm2022/ngwr-utils.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
- package/fesm2022/ngwr-window-testing.mjs +61 -5
- package/fesm2022/ngwr-window-testing.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +1538 -895
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/fesm2022/ngwr.mjs.map +1 -1
- package/i18n/ar.json +84 -4
- package/i18n/cs.json +84 -4
- package/i18n/de.json +84 -4
- package/i18n/en.json +84 -4
- package/i18n/es.json +84 -4
- package/i18n/fr.json +84 -4
- package/i18n/he.json +84 -4
- package/i18n/hi.json +84 -4
- package/i18n/id.json +84 -4
- package/i18n/it.json +84 -4
- package/i18n/ja.json +84 -4
- package/i18n/ko.json +84 -4
- package/i18n/nl.json +84 -4
- package/i18n/pl.json +84 -4
- package/i18n/pt.json +84 -4
- package/i18n/ru.json +84 -4
- package/i18n/sv.json +84 -4
- package/i18n/tr.json +84 -4
- package/i18n/uk.json +84 -4
- package/i18n/vi.json +84 -4
- package/i18n/zh-TW.json +84 -4
- package/i18n/zh.json +84 -4
- package/llms-full.txt +266 -9
- package/llms.txt +30 -7
- package/mcp/api.js +69 -1
- package/mcp/catalog.js +10 -1
- package/mcp/server.js +15 -1
- package/mcp/tools.js +122 -26
- package/package.json +132 -1
- package/popover/styles/_index.scss +75 -7
- package/schematics/component-style/index.js +3 -0
- package/schematics/migrations/v15/index.js +3 -26
- package/schematics/ng-add/index.js +2 -2
- package/schematics/use/symbol-map.json +14 -0
- package/schematics/utility/global-styles.js +19 -4
- package/schematics/utility/v15-moves.js +55 -0
- package/skills/ngwr/SKILL.md +8 -2
- package/skills/ngwr/references/catalog.md +28 -0
- package/skills/ngwr/references/setup.md +5 -4
- package/theme/styles/_focus.scss +8 -0
- package/toast/styles/_index.scss +103 -12
- package/types/ngwr-bits-aurora.d.ts +11 -0
- package/types/ngwr-bits-border-glow-testing.d.ts +5 -6
- package/types/ngwr-bits-border-glow.d.ts +5 -1
- package/types/ngwr-bits-dot-grid-testing.d.ts +92 -0
- package/types/ngwr-bits-dot-grid.d.ts +158 -0
- package/types/ngwr-bits-iridescence-testing.d.ts +85 -0
- package/types/ngwr-bits-iridescence.d.ts +244 -0
- package/types/ngwr-bits-ripple-grid-testing.d.ts +96 -0
- package/types/ngwr-bits-ripple-grid.d.ts +294 -0
- package/types/ngwr-bits-splash-cursor.d.ts +0 -1
- package/types/ngwr-bits-spotlight-card-testing.d.ts +3 -1
- package/types/ngwr-bits-star-border-testing.d.ts +7 -7
- package/types/ngwr-bits-threads-testing.d.ts +97 -0
- package/types/ngwr-bits-threads.d.ts +216 -0
- package/types/ngwr-bits-waves-testing.d.ts +1 -1
- package/types/ngwr-bits-waves.d.ts +20 -3
- package/types/ngwr-charts-bar-chart-testing.d.ts +193 -14
- package/types/ngwr-charts-bar-chart.d.ts +546 -38
- package/types/ngwr-charts-boxplot-chart-testing.d.ts +165 -0
- package/types/ngwr-charts-boxplot-chart.d.ts +308 -0
- package/types/ngwr-charts-bullet-chart-testing.d.ts +99 -0
- package/types/ngwr-charts-bullet-chart.d.ts +262 -0
- package/types/ngwr-charts-calendar-heatmap-testing.d.ts +32 -1
- package/types/ngwr-charts-calendar-heatmap.d.ts +55 -6
- package/types/ngwr-charts-candlestick-chart-testing.d.ts +135 -0
- package/types/ngwr-charts-candlestick-chart.d.ts +361 -0
- package/types/ngwr-charts-chart-legend-testing.d.ts +84 -0
- package/types/ngwr-charts-chart-legend.d.ts +178 -0
- package/types/ngwr-charts-core.d.ts +391 -0
- package/types/ngwr-charts-donut-chart-testing.d.ts +28 -5
- package/types/ngwr-charts-donut-chart.d.ts +124 -12
- package/types/ngwr-charts-funnel-chart-testing.d.ts +130 -0
- package/types/ngwr-charts-funnel-chart.d.ts +296 -0
- package/types/ngwr-charts-gauge-testing.d.ts +5 -0
- package/types/ngwr-charts-gauge.d.ts +6 -4
- package/types/ngwr-charts-heatmap-chart-testing.d.ts +148 -0
- package/types/ngwr-charts-heatmap-chart.d.ts +359 -0
- package/types/ngwr-charts-line-chart-testing.d.ts +72 -11
- package/types/ngwr-charts-line-chart.d.ts +291 -67
- package/types/ngwr-charts-meter-group-testing.d.ts +16 -2
- package/types/ngwr-charts-meter-group.d.ts +71 -11
- package/types/ngwr-charts-radar-chart-testing.d.ts +162 -0
- package/types/ngwr-charts-radar-chart.d.ts +461 -0
- package/types/ngwr-charts-scatter-chart-testing.d.ts +147 -0
- package/types/ngwr-charts-scatter-chart.d.ts +396 -0
- package/types/ngwr-charts-sparkline-testing.d.ts +4 -1
- package/types/ngwr-charts-sparkline.d.ts +8 -6
- package/types/ngwr-charts-treemap-chart-testing.d.ts +131 -0
- package/types/ngwr-charts-treemap-chart.d.ts +295 -0
- package/types/ngwr-charts-waterfall-chart-testing.d.ts +149 -0
- package/types/ngwr-charts-waterfall-chart.d.ts +338 -0
- package/types/ngwr-color-picker.d.ts +0 -21
- package/types/ngwr-dropdown.d.ts +0 -52
- package/types/ngwr-editor.d.ts +2 -84
- package/types/ngwr-i18n.d.ts +0 -15
- package/types/ngwr-mention.d.ts +0 -13
- package/types/ngwr-popconfirm.d.ts +0 -33
- package/types/ngwr-popover.d.ts +29 -53
- package/types/ngwr-toast-testing.d.ts +6 -1
- package/types/ngwr-tour.d.ts +0 -2
- package/types/ngwr-utils.d.ts +49 -7
- package/types/ngwr-version.d.ts +1 -1
- package/types/ngwr-window-testing.d.ts +65 -7
- package/types/ngwr-window.d.ts +831 -207
- package/types/ngwr.d.ts +1 -0
- package/window/styles/_index.scss +528 -82
package/fesm2022/ngwr-window.mjs
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, EnvironmentInjector, InjectionToken, Injector, PLATFORM_ID, Service, ViewContainerRef, ViewEncapsulation, afterNextRender, computed, effect, inject, input,
|
|
3
|
-
import {
|
|
4
|
-
import { isPlatformBrowser } from "@angular/common";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, EnvironmentInjector, InjectionToken, Injector, PLATFORM_ID, Service, TemplateRef, ViewContainerRef, ViewEncapsulation, afterNextRender, afterRenderEffect, computed, effect, inject, input, output, runInInjectionContext, signal, untracked, viewChild, viewChildren } from "@angular/core";
|
|
3
|
+
import { coerceNumberProperty } from "@angular/cdk/coercion";
|
|
4
|
+
import { NgComponentOutlet, NgTemplateOutlet, isPlatformBrowser } from "@angular/common";
|
|
5
5
|
import { useI18nFormatter, useI18nText } from "ngwr/i18n";
|
|
6
|
-
import { clamp, randomId, toClassList } from "ngwr/utils";
|
|
6
|
+
import { clamp, randomId, toClassList, wrFeature } from "ngwr/utils";
|
|
7
7
|
import { Directionality } from "@angular/cdk/bidi";
|
|
8
8
|
import { ComponentPortal } from "@angular/cdk/portal";
|
|
9
9
|
import { WR_OVERLAY, wrFollowDirection } from "ngwr/overlay";
|
|
10
10
|
import { FocusTrapFactory } from "@angular/cdk/a11y";
|
|
11
11
|
import { ReplaySubject, Subject } from "rxjs";
|
|
12
12
|
import { WrStorage } from "ngwr/storage";
|
|
13
|
+
import { WrDropdown, WrDropdownItem, WrDropdownMenu } from "ngwr/dropdown";
|
|
13
14
|
/**
|
|
14
15
|
* @license
|
|
15
16
|
*
|
|
@@ -18,6 +19,7 @@ import { WrStorage } from "ngwr/storage";
|
|
|
18
19
|
*/
|
|
19
20
|
const WR_WINDOW_REF = new InjectionToken("WR_WINDOW_REF");
|
|
20
21
|
const WR_WINDOW_DATA = new InjectionToken("WR_WINDOW_DATA");
|
|
22
|
+
const WR_WINDOW_DEFAULTS = new InjectionToken("WR_WINDOW_DEFAULTS");
|
|
21
23
|
function storageKey(cfg) {
|
|
22
24
|
return `wr:window:${cfg.prefix ? `${cfg.prefix}:` : ""}${cfg.key}`;
|
|
23
25
|
}
|
|
@@ -40,215 +42,92 @@ function detectOs() {
|
|
|
40
42
|
return "windows";
|
|
41
43
|
}
|
|
42
44
|
const DETECTED_OS = detectOs();
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
const SNAP_HOT_ZONE = 12;
|
|
46
|
+
const DRAG_THRESHOLD = 4;
|
|
47
|
+
const INTERACTIVE = "button, input, select, textarea, a[href], label, [contenteditable]:not([contenteditable=\"false\"]), [role=\"button\"], [role=\"link\"], [role=\"checkbox\"], [role=\"switch\"], [role=\"radio\"], [role=\"slider\"], [role=\"spinbutton\"], [role=\"textbox\"], [role=\"combobox\"], [role=\"tab\"], [role=\"menuitem\"], [role=\"option\"]";
|
|
48
|
+
function asTemplate(content) {
|
|
49
|
+
return content instanceof TemplateRef ? content : null;
|
|
45
50
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
width: 320,
|
|
49
|
-
height: 200
|
|
50
|
-
},
|
|
51
|
-
md: {
|
|
52
|
-
width: 480,
|
|
53
|
-
height: 320
|
|
54
|
-
},
|
|
55
|
-
lg: {
|
|
56
|
-
width: 720,
|
|
57
|
-
height: 480
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const MIN_ON_VIEWPORT = 24;
|
|
61
|
-
function viewportWidth() {
|
|
62
|
-
return typeof window === "undefined" ? 1024 : window.innerWidth;
|
|
63
|
-
}
|
|
64
|
-
function viewportHeight() {
|
|
65
|
-
return typeof window === "undefined" ? 768 : window.innerHeight;
|
|
51
|
+
function asComponent(content) {
|
|
52
|
+
return content && !(content instanceof TemplateRef) ? content : null;
|
|
66
53
|
}
|
|
67
54
|
var WrWindow = class WrWindow {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
55
|
+
model = input.required(...ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []);
|
|
56
|
+
windowRef = input(null, ...ngDevMode ? [{ debugName: "windowRef" }] : /* istanbul ignore next */ []);
|
|
57
|
+
injector = input(void 0, ...ngDevMode ? [{ debugName: "injector" }] : /* istanbul ignore next */ []);
|
|
58
|
+
titleExtra = input(null, ...ngDevMode ? [{ debugName: "titleExtra" }] : /* istanbul ignore next */ []);
|
|
59
|
+
statusBar = input(null, ...ngDevMode ? [{ debugName: "statusBar" }] : /* istanbul ignore next */ []);
|
|
60
|
+
closed = output();
|
|
71
61
|
titleId = randomId("wr-window-title");
|
|
72
62
|
closeLabel = useI18nText(NO_OVERRIDE$1, "window.close", "Close");
|
|
73
63
|
minimizeLabel = useI18nText(NO_OVERRIDE$1, "window.minimize", "Minimize");
|
|
74
64
|
maximizeLabel = useI18nText(NO_OVERRIDE$1, "window.maximize", "Maximize");
|
|
75
65
|
restoreLabel = useI18nText(NO_OVERRIDE$1, "window.restore", "Restore");
|
|
76
66
|
restoreDownLabel = useI18nText(NO_OVERRIDE$1, "window.restoreDown", "Restore down");
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
});
|
|
83
|
-
initialY = input(null, {
|
|
84
|
-
...ngDevMode ? { debugName: "initialY" } : /* istanbul ignore next */ {},
|
|
85
|
-
transform: (v) => v == null ? null : coerceNumberProperty(v, 0)
|
|
86
|
-
});
|
|
87
|
-
size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
|
|
88
|
-
initialWidth = input(null, {
|
|
89
|
-
...ngDevMode ? { debugName: "initialWidth" } : /* istanbul ignore next */ {},
|
|
90
|
-
transform: (v) => v == null ? null : coerceNumberProperty(v, 480)
|
|
91
|
-
});
|
|
92
|
-
initialHeight = input(null, {
|
|
93
|
-
...ngDevMode ? { debugName: "initialHeight" } : /* istanbul ignore next */ {},
|
|
94
|
-
transform: (v) => v == null ? null : coerceNumberProperty(v, 320)
|
|
95
|
-
});
|
|
96
|
-
os = input("auto", ...ngDevMode ? [{ debugName: "os" }] : /* istanbul ignore next */ []);
|
|
97
|
-
resolvedOs = computed(() => {
|
|
98
|
-
const o = this.os();
|
|
99
|
-
return o === "auto" ? DETECTED_OS : o;
|
|
100
|
-
}, ...ngDevMode ? [{ debugName: "resolvedOs" }] : /* istanbul ignore next */ []);
|
|
101
|
-
minimizeVisible = computed(() => this.showMinimize() ?? this.resolvedOs() !== "linux", ...ngDevMode ? [{ debugName: "minimizeVisible" }] : /* istanbul ignore next */ []);
|
|
102
|
-
maximizeVisible = computed(() => this.showMaximize() ?? this.resolvedOs() !== "linux", ...ngDevMode ? [{ debugName: "maximizeVisible" }] : /* istanbul ignore next */ []);
|
|
103
|
-
chromeSize = input("md", ...ngDevMode ? [{ debugName: "chromeSize" }] : /* istanbul ignore next */ []);
|
|
104
|
-
animations = input(true, {
|
|
105
|
-
...ngDevMode ? { debugName: "animations" } : /* istanbul ignore next */ {},
|
|
106
|
-
transform: coerceBooleanProperty
|
|
107
|
-
});
|
|
108
|
-
minWidth = input(220, {
|
|
109
|
-
...ngDevMode ? { debugName: "minWidth" } : /* istanbul ignore next */ {},
|
|
110
|
-
transform: (v) => coerceNumberProperty(v, 220)
|
|
111
|
-
});
|
|
112
|
-
minHeight = input(140, {
|
|
113
|
-
...ngDevMode ? { debugName: "minHeight" } : /* istanbul ignore next */ {},
|
|
114
|
-
transform: (v) => coerceNumberProperty(v, 140)
|
|
115
|
-
});
|
|
116
|
-
maxWidth = input(Number.POSITIVE_INFINITY, {
|
|
117
|
-
...ngDevMode ? { debugName: "maxWidth" } : /* istanbul ignore next */ {},
|
|
118
|
-
transform: (v) => v == null ? Number.POSITIVE_INFINITY : coerceNumberProperty(v, Infinity)
|
|
119
|
-
});
|
|
120
|
-
maxHeight = input(Number.POSITIVE_INFINITY, {
|
|
121
|
-
...ngDevMode ? { debugName: "maxHeight" } : /* istanbul ignore next */ {},
|
|
122
|
-
transform: (v) => v == null ? Number.POSITIVE_INFINITY : coerceNumberProperty(v, Infinity)
|
|
123
|
-
});
|
|
124
|
-
movable = input(true, {
|
|
125
|
-
...ngDevMode ? { debugName: "movable" } : /* istanbul ignore next */ {},
|
|
126
|
-
transform: coerceBooleanProperty
|
|
127
|
-
});
|
|
128
|
-
resizable = input(true, {
|
|
129
|
-
...ngDevMode ? { debugName: "resizable" } : /* istanbul ignore next */ {},
|
|
130
|
-
transform: coerceBooleanProperty
|
|
131
|
-
});
|
|
132
|
-
keepInViewport = input(true, {
|
|
133
|
-
...ngDevMode ? { debugName: "keepInViewport" } : /* istanbul ignore next */ {},
|
|
134
|
-
transform: coerceBooleanProperty
|
|
135
|
-
});
|
|
136
|
-
snap = input("none", ...ngDevMode ? [{ debugName: "snap" }] : /* istanbul ignore next */ []);
|
|
137
|
-
dragHandle = input(null, ...ngDevMode ? [{ debugName: "dragHandle" }] : /* istanbul ignore next */ []);
|
|
138
|
-
showMinimize = input(null, {
|
|
139
|
-
...ngDevMode ? { debugName: "showMinimize" } : /* istanbul ignore next */ {},
|
|
140
|
-
transform: optionalBoolean
|
|
141
|
-
});
|
|
142
|
-
showMaximize = input(null, {
|
|
143
|
-
...ngDevMode ? { debugName: "showMaximize" } : /* istanbul ignore next */ {},
|
|
144
|
-
transform: optionalBoolean
|
|
145
|
-
});
|
|
146
|
-
showClose = input(true, {
|
|
147
|
-
...ngDevMode ? { debugName: "showClose" } : /* istanbul ignore next */ {},
|
|
148
|
-
transform: coerceBooleanProperty
|
|
149
|
-
});
|
|
150
|
-
closed = output();
|
|
151
|
-
moved = output();
|
|
152
|
-
resized = output();
|
|
153
|
-
minimizedWithFocus = output();
|
|
67
|
+
untitled = useI18nText(NO_OVERRIDE$1, "window.untitled", "Untitled");
|
|
68
|
+
moveModeText = useI18nText(NO_OVERRIDE$1, "window.moveMode", "Moving the window. Use the arrow keys, Enter to finish, Escape to cancel.");
|
|
69
|
+
resizeModeText = useI18nText(NO_OVERRIDE$1, "window.resizeMode", "Resizing the window. Use the arrow keys, Enter to finish, Escape to cancel.");
|
|
70
|
+
movedText = useI18nFormatter("window.moved", "Window moved to {{x}}, {{y}}");
|
|
71
|
+
resizedText = useI18nFormatter("window.resized", "Window resized to {{width}} by {{height}}");
|
|
154
72
|
manager = inject(WrWindowManager);
|
|
155
|
-
destroyRef = inject(DestroyRef);
|
|
156
73
|
elRef = inject(ElementRef);
|
|
157
74
|
focusTraps = inject(FocusTrapFactory);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
75
|
+
dir = inject(Directionality, { optional: true });
|
|
76
|
+
endMove = null;
|
|
77
|
+
constructor() {
|
|
78
|
+
inject(DestroyRef).onDestroy(() => this.endMove?.());
|
|
79
|
+
}
|
|
80
|
+
announcement = signal("", ...ngDevMode ? [{ debugName: "announcement" }] : /* istanbul ignore next */ []);
|
|
81
|
+
lastFocused = null;
|
|
82
|
+
state = computed(() => this.model().state(), ...ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []);
|
|
83
|
+
rect = computed(() => this.model().rect(), ...ngDevMode ? [{ debugName: "rect" }] : /* istanbul ignore next */ []);
|
|
84
|
+
options = computed(() => this.model().options(), ...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
|
|
85
|
+
displayTitle = computed(() => this.model().title() || this.untitled(), ...ngDevMode ? [{ debugName: "displayTitle" }] : /* istanbul ignore next */ []);
|
|
86
|
+
resolvedOs = computed(() => {
|
|
87
|
+
const os = this.options().os;
|
|
88
|
+
return os === "auto" ? DETECTED_OS : os;
|
|
89
|
+
}, ...ngDevMode ? [{ debugName: "resolvedOs" }] : /* istanbul ignore next */ []);
|
|
90
|
+
minimizeVisible = computed(() => this.options().showMinimize ?? this.resolvedOs() !== "linux", ...ngDevMode ? [{ debugName: "minimizeVisible" }] : /* istanbul ignore next */ []);
|
|
91
|
+
maximizeVisible = computed(() => this.options().showMaximize ?? this.resolvedOs() !== "linux", ...ngDevMode ? [{ debugName: "maximizeVisible" }] : /* istanbul ignore next */ []);
|
|
92
|
+
showClose = computed(() => this.options().showClose, ...ngDevMode ? [{ debugName: "showClose" }] : /* istanbul ignore next */ []);
|
|
93
|
+
actionCount = computed(() => Number(this.minimizeVisible()) + Number(this.maximizeVisible()) + Number(this.showClose()), ...ngDevMode ? [{ debugName: "actionCount" }] : /* istanbul ignore next */ []);
|
|
94
|
+
minimizeActionLabel = computed(() => this.state() === "minimized" ? this.restoreLabel() : this.minimizeLabel(), ...ngDevMode ? [{ debugName: "minimizeActionLabel" }] : /* istanbul ignore next */ []);
|
|
95
|
+
maximizeActionLabel = computed(() => this.state() === "maximized" ? this.restoreDownLabel() : this.maximizeLabel(), ...ngDevMode ? [{ debugName: "maximizeActionLabel" }] : /* istanbul ignore next */ []);
|
|
96
|
+
resizeHandles = computed(() => this.options().resizable && this.state() === "normal", ...ngDevMode ? [{ debugName: "resizeHandles" }] : /* istanbul ignore next */ []);
|
|
168
97
|
classes = computed(() => {
|
|
98
|
+
const model = this.model();
|
|
169
99
|
const parts = [
|
|
170
100
|
"wr-window",
|
|
171
101
|
`wr-window--${this.state()}`,
|
|
172
102
|
`wr-window--os-${this.resolvedOs()}`,
|
|
173
|
-
`wr-window--chrome-${this.
|
|
103
|
+
`wr-window--chrome-${this.options().chromeSize}`,
|
|
104
|
+
model.isActive() ? "wr-window--active" : "wr-window--inactive"
|
|
174
105
|
];
|
|
175
|
-
if (
|
|
176
|
-
if (this.
|
|
177
|
-
|
|
106
|
+
if (this.resizeHandles()) parts.push("wr-window--resizable");
|
|
107
|
+
if (!this.options().animations) parts.push("wr-window--no-anim");
|
|
108
|
+
const mode = model.keyboardMode();
|
|
109
|
+
if (mode) parts.push(mode === "move" ? "wr-window--keyboard-moving" : "wr-window--keyboard-resizing");
|
|
178
110
|
return parts.join(" ");
|
|
179
111
|
}, ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
height: viewportHeight()
|
|
191
|
-
});
|
|
192
|
-
measure();
|
|
193
|
-
window.addEventListener("resize", measure);
|
|
194
|
-
this.destroyRef.onDestroy(() => window.removeEventListener("resize", measure));
|
|
195
|
-
this.seedInitialGeometry();
|
|
196
|
-
});
|
|
197
|
-
effect(() => {
|
|
198
|
-
if (this.state() !== "normal") return;
|
|
199
|
-
this.clampToViewport();
|
|
200
|
-
});
|
|
112
|
+
titleExtraTemplate = computed(() => asTemplate(this.titleExtra()), ...ngDevMode ? [{ debugName: "titleExtraTemplate" }] : /* istanbul ignore next */ []);
|
|
113
|
+
titleExtraComponent = computed(() => asComponent(this.titleExtra()), ...ngDevMode ? [{ debugName: "titleExtraComponent" }] : /* istanbul ignore next */ []);
|
|
114
|
+
statusBarTemplate = computed(() => asTemplate(this.statusBar()), ...ngDevMode ? [{ debugName: "statusBarTemplate" }] : /* istanbul ignore next */ []);
|
|
115
|
+
statusBarComponent = computed(() => asComponent(this.statusBar()), ...ngDevMode ? [{ debugName: "statusBarComponent" }] : /* istanbul ignore next */ []);
|
|
116
|
+
slotContext = computed(() => {
|
|
117
|
+
const ref = this.windowRef();
|
|
118
|
+
return ref ? { $implicit: ref } : null;
|
|
119
|
+
}, ...ngDevMode ? [{ debugName: "slotContext" }] : /* istanbul ignore next */ []);
|
|
120
|
+
ngOnInit() {
|
|
121
|
+
this.model().element = this.elRef.nativeElement;
|
|
201
122
|
}
|
|
202
123
|
close() {
|
|
203
124
|
this.closed.emit();
|
|
204
125
|
}
|
|
205
126
|
minimize() {
|
|
206
|
-
|
|
207
|
-
const hadFocus = minimizing && this.hasFocus();
|
|
208
|
-
this.state.set(minimizing ? "minimized" : "normal");
|
|
209
|
-
if (hadFocus) this.minimizedWithFocus.emit();
|
|
127
|
+
this.model().minimize();
|
|
210
128
|
}
|
|
211
129
|
maximize() {
|
|
212
|
-
|
|
213
|
-
else {
|
|
214
|
-
this.restoreGeometry = {
|
|
215
|
-
x: this.x_(),
|
|
216
|
-
y: this.y_(),
|
|
217
|
-
width: this.width_(),
|
|
218
|
-
height: this.height_()
|
|
219
|
-
};
|
|
220
|
-
this.state.set("maximized");
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
restore() {
|
|
224
|
-
if (this.state() === "maximized" && this.restoreGeometry) {
|
|
225
|
-
this.x_.set(this.restoreGeometry.x);
|
|
226
|
-
this.y_.set(this.restoreGeometry.y);
|
|
227
|
-
this.width_.set(this.restoreGeometry.width);
|
|
228
|
-
this.height_.set(this.restoreGeometry.height);
|
|
229
|
-
this.restoreGeometry = null;
|
|
230
|
-
}
|
|
231
|
-
this.state.set("normal");
|
|
232
|
-
}
|
|
233
|
-
moveTo(x, y) {
|
|
234
|
-
this.x_.set(x);
|
|
235
|
-
this.y_.set(y);
|
|
236
|
-
this.clampToViewport();
|
|
237
|
-
}
|
|
238
|
-
resizeTo(width, height) {
|
|
239
|
-
this.width_.set(clamp(width, this.minWidth(), this.maxWidth()));
|
|
240
|
-
this.height_.set(clamp(height, this.minHeight(), this.maxHeight()));
|
|
241
|
-
this.clampToViewport();
|
|
242
|
-
}
|
|
243
|
-
center() {
|
|
244
|
-
const w = this.width_();
|
|
245
|
-
const h = this.height_();
|
|
246
|
-
const { width: vw, height: vh } = this.viewport();
|
|
247
|
-
this.x_.set(Math.max(0, (vw - w) / 2));
|
|
248
|
-
this.y_.set(Math.max(0, (vh - h) / 2));
|
|
249
|
-
}
|
|
250
|
-
focus() {
|
|
251
|
-
this.z.set(this.manager.bringToFront());
|
|
130
|
+
this.model().maximize();
|
|
252
131
|
}
|
|
253
132
|
focusInitial() {
|
|
254
133
|
const host = this.elRef.nativeElement;
|
|
@@ -262,58 +141,155 @@ var WrWindow = class WrWindow {
|
|
|
262
141
|
}
|
|
263
142
|
host.focus({ preventScroll: true });
|
|
264
143
|
}
|
|
265
|
-
|
|
144
|
+
focusLast() {
|
|
266
145
|
const host = this.elRef.nativeElement;
|
|
267
|
-
|
|
146
|
+
if (!host.isConnected || this.state() === "minimized") return;
|
|
147
|
+
const last = this.lastFocused;
|
|
148
|
+
if (last?.isConnected && host.contains(last)) {
|
|
149
|
+
last.focus({ preventScroll: true });
|
|
150
|
+
if (host.ownerDocument.activeElement === last) return;
|
|
151
|
+
}
|
|
152
|
+
this.focusInitial();
|
|
153
|
+
}
|
|
154
|
+
onFocusIn(event) {
|
|
155
|
+
const target = event.target;
|
|
156
|
+
if (!(target instanceof HTMLElement) || target === this.elRef.nativeElement) return;
|
|
157
|
+
if (target.closest(".wr-window__chrome-action")) return;
|
|
158
|
+
this.lastFocused = target;
|
|
268
159
|
}
|
|
269
|
-
|
|
270
|
-
|
|
160
|
+
onFocusOut(event) {
|
|
161
|
+
const next = event.relatedTarget;
|
|
162
|
+
if (this.model().keyboardMode() && !(next instanceof Node && this.elRef.nativeElement.contains(next))) this.commitKeyboard();
|
|
163
|
+
}
|
|
164
|
+
onPointerDown(event) {
|
|
165
|
+
const model = this.model();
|
|
166
|
+
if (model.keyboardMode()) this.commitKeyboard();
|
|
167
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
168
|
+
const grab = event.button === 0 && !!target && this.isGrabArea(target);
|
|
169
|
+
if (model.state() === "minimized") return;
|
|
170
|
+
const ref = this.windowRef();
|
|
171
|
+
if (ref) this.manager._activate(ref, { focus: grab });
|
|
172
|
+
if (grab) this.startMove(event);
|
|
173
|
+
}
|
|
174
|
+
isGrabArea(target) {
|
|
175
|
+
const host = this.elRef.nativeElement;
|
|
176
|
+
if (target.closest(".wr-window__chrome-action, .wr-window__handle")) return false;
|
|
177
|
+
const control = target.closest(INTERACTIVE);
|
|
178
|
+
if (control && host.contains(control)) return false;
|
|
179
|
+
const handle = this.options().dragHandle;
|
|
180
|
+
if (handle) {
|
|
181
|
+
const match = target.closest(handle);
|
|
182
|
+
return !!match && host.contains(match);
|
|
183
|
+
}
|
|
184
|
+
return !!target.closest(".wr-window__chrome");
|
|
185
|
+
}
|
|
186
|
+
isDblClickArea(target) {
|
|
187
|
+
const host = this.elRef.nativeElement;
|
|
188
|
+
if (target.closest(".wr-window__chrome-action, .wr-window__handle")) return false;
|
|
189
|
+
const control = target.closest(INTERACTIVE);
|
|
190
|
+
if (control && host.contains(control)) return false;
|
|
191
|
+
const chrome = target.closest(".wr-window__chrome");
|
|
192
|
+
return !!chrome && host.contains(chrome) || this.isGrabArea(target);
|
|
271
193
|
}
|
|
272
194
|
startMove(event) {
|
|
273
|
-
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (
|
|
195
|
+
const model = this.model();
|
|
196
|
+
const o = model.options();
|
|
197
|
+
const state = model.state();
|
|
198
|
+
if (!o.movable || state === "minimized") return;
|
|
199
|
+
if (state === "maximized" && !o.restoreOnDrag) return;
|
|
278
200
|
event.preventDefault();
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
const
|
|
201
|
+
this.endMove?.();
|
|
202
|
+
const host = this.elRef.nativeElement;
|
|
203
|
+
const doc = host.ownerDocument;
|
|
204
|
+
const pressed = event.target instanceof Element ? event.target : host;
|
|
205
|
+
const pointerId = event.pointerId;
|
|
283
206
|
const originX = event.clientX;
|
|
284
207
|
const originY = event.clientY;
|
|
208
|
+
const start = model.rect();
|
|
209
|
+
let detached = state === "normal" && !model.snap();
|
|
210
|
+
if (!detached && !o.restoreOnDrag) {
|
|
211
|
+
model.unsnapInPlace();
|
|
212
|
+
detached = true;
|
|
213
|
+
}
|
|
214
|
+
let startX = model.x();
|
|
215
|
+
let startY = model.y();
|
|
216
|
+
let dragging = false;
|
|
285
217
|
const move = (e) => {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
218
|
+
if (e.pointerId !== pointerId) return;
|
|
219
|
+
const dx = e.clientX - originX;
|
|
220
|
+
const dy = e.clientY - originY;
|
|
221
|
+
if (!dragging && Math.hypot(dx, dy) >= DRAG_THRESHOLD) {
|
|
222
|
+
dragging = true;
|
|
223
|
+
try {
|
|
224
|
+
pressed.setPointerCapture?.(pointerId);
|
|
225
|
+
} catch {}
|
|
226
|
+
}
|
|
227
|
+
if (!detached) {
|
|
228
|
+
if (!dragging) return;
|
|
229
|
+
const fraction = start.width > 0 ? (originX - start.left) / start.width : .5;
|
|
230
|
+
model.restore();
|
|
231
|
+
startX = originX - fraction * model.width();
|
|
232
|
+
startY = start.top;
|
|
233
|
+
detached = true;
|
|
234
|
+
}
|
|
235
|
+
model.setRaw({
|
|
236
|
+
x: startX + dx,
|
|
237
|
+
y: startY + dy
|
|
238
|
+
});
|
|
239
|
+
model.clamp();
|
|
240
|
+
model.dragTarget.set(this.detectSnapTarget(e.clientX, e.clientY));
|
|
290
241
|
};
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
this.
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
242
|
+
const stop = () => {
|
|
243
|
+
doc.removeEventListener("pointermove", move);
|
|
244
|
+
doc.removeEventListener("pointerup", end);
|
|
245
|
+
doc.removeEventListener("pointercancel", end);
|
|
246
|
+
if (dragging && pressed.hasPointerCapture?.(pointerId)) pressed.releasePointerCapture?.(pointerId);
|
|
247
|
+
model.dragTarget.set(null);
|
|
248
|
+
this.endMove = null;
|
|
249
|
+
};
|
|
250
|
+
const end = (e) => {
|
|
251
|
+
if (e.pointerId !== pointerId) return;
|
|
252
|
+
const snap = model.dragTarget();
|
|
253
|
+
stop();
|
|
254
|
+
if (dragging) this.swallowClick(doc, pressed);
|
|
255
|
+
if (!detached) return;
|
|
256
|
+
if (snap) {
|
|
257
|
+
model.snapTo(snap);
|
|
258
|
+
if (snap !== "top") model.resized.next({
|
|
259
|
+
width: model.rect().width,
|
|
260
|
+
height: model.rect().height
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
const r = model.rect();
|
|
264
|
+
if (snap || r.left !== start.left || r.top !== start.top) model.moved.next({
|
|
265
|
+
x: r.left,
|
|
266
|
+
y: r.top
|
|
302
267
|
});
|
|
303
268
|
};
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
269
|
+
doc.addEventListener("pointermove", move);
|
|
270
|
+
doc.addEventListener("pointerup", end);
|
|
271
|
+
doc.addEventListener("pointercancel", end);
|
|
272
|
+
this.endMove = stop;
|
|
273
|
+
}
|
|
274
|
+
swallowClick(doc, pressed) {
|
|
275
|
+
const swallow = (e) => {
|
|
276
|
+
if (e.target !== pressed) return;
|
|
277
|
+
doc.removeEventListener("click", swallow, true);
|
|
278
|
+
e.stopPropagation();
|
|
279
|
+
e.preventDefault();
|
|
280
|
+
};
|
|
281
|
+
doc.addEventListener("click", swallow, true);
|
|
282
|
+
setTimeout(() => doc.removeEventListener("click", swallow, true));
|
|
307
283
|
}
|
|
308
284
|
detectSnapTarget(clientX, clientY) {
|
|
309
|
-
const
|
|
285
|
+
const model = this.model();
|
|
286
|
+
const mode = model.options().snap;
|
|
310
287
|
if (mode === "none") return null;
|
|
311
|
-
const
|
|
312
|
-
const
|
|
313
|
-
const
|
|
314
|
-
const
|
|
315
|
-
const
|
|
316
|
-
const nearBottom = clientY >= vh - HOT;
|
|
288
|
+
const wa = model.workArea();
|
|
289
|
+
const nearLeft = clientX <= wa.left + SNAP_HOT_ZONE;
|
|
290
|
+
const nearRight = clientX >= wa.left + wa.width - SNAP_HOT_ZONE;
|
|
291
|
+
const nearTop = clientY <= wa.top + SNAP_HOT_ZONE;
|
|
292
|
+
const nearBottom = clientY >= wa.top + wa.height - SNAP_HOT_ZONE;
|
|
317
293
|
if (mode === "all") {
|
|
318
294
|
if (nearTop && nearLeft) return "top-left";
|
|
319
295
|
if (nearTop && nearRight) return "top-right";
|
|
@@ -325,74 +301,43 @@ var WrWindow = class WrWindow {
|
|
|
325
301
|
if (nearRight) return "right";
|
|
326
302
|
return null;
|
|
327
303
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
this.x_.set(0);
|
|
344
|
-
this.y_.set(0);
|
|
345
|
-
this.width_.set(halfW);
|
|
346
|
-
this.height_.set(vh);
|
|
347
|
-
break;
|
|
348
|
-
case "right":
|
|
349
|
-
this.x_.set(halfW);
|
|
350
|
-
this.y_.set(0);
|
|
351
|
-
this.width_.set(vw - halfW);
|
|
352
|
-
this.height_.set(vh);
|
|
353
|
-
break;
|
|
354
|
-
case "top-left":
|
|
355
|
-
this.x_.set(0);
|
|
356
|
-
this.y_.set(0);
|
|
357
|
-
this.width_.set(halfW);
|
|
358
|
-
this.height_.set(halfH);
|
|
359
|
-
break;
|
|
360
|
-
case "top-right":
|
|
361
|
-
this.x_.set(halfW);
|
|
362
|
-
this.y_.set(0);
|
|
363
|
-
this.width_.set(vw - halfW);
|
|
364
|
-
this.height_.set(halfH);
|
|
365
|
-
break;
|
|
366
|
-
case "bottom-left":
|
|
367
|
-
this.x_.set(0);
|
|
368
|
-
this.y_.set(halfH);
|
|
369
|
-
this.width_.set(halfW);
|
|
370
|
-
this.height_.set(vh - halfH);
|
|
371
|
-
break;
|
|
372
|
-
case "bottom-right":
|
|
373
|
-
this.x_.set(halfW);
|
|
374
|
-
this.y_.set(halfH);
|
|
375
|
-
this.width_.set(vw - halfW);
|
|
376
|
-
this.height_.set(vh - halfH);
|
|
304
|
+
onChromeDblClick(event) {
|
|
305
|
+
this.toggleFromDblClick(event.target);
|
|
306
|
+
}
|
|
307
|
+
onBodyDblClick(event) {
|
|
308
|
+
const target = event.target;
|
|
309
|
+
if (target instanceof Element && target.closest(".wr-window__chrome")) return;
|
|
310
|
+
this.toggleFromDblClick(target);
|
|
311
|
+
}
|
|
312
|
+
toggleFromDblClick(target) {
|
|
313
|
+
if (!(target instanceof Element) || !this.isDblClickArea(target)) return;
|
|
314
|
+
const model = this.model();
|
|
315
|
+
if (model.state() === "minimized") return;
|
|
316
|
+
if (model.state() === "normal" && model.snap()) {
|
|
317
|
+
model.restore();
|
|
318
|
+
return;
|
|
377
319
|
}
|
|
378
|
-
|
|
379
|
-
width: this.width_(),
|
|
380
|
-
height: this.height_()
|
|
381
|
-
});
|
|
320
|
+
if (model.options().showMaximize !== false) model.maximize();
|
|
382
321
|
}
|
|
383
322
|
startResize(event, edges) {
|
|
384
|
-
|
|
323
|
+
const model = this.model();
|
|
324
|
+
if (!model.options().resizable || model.state() !== "normal") return;
|
|
385
325
|
event.preventDefault();
|
|
386
326
|
event.stopPropagation();
|
|
327
|
+
if (model.keyboardMode()) this.commitKeyboard();
|
|
328
|
+
const ref = this.windowRef();
|
|
329
|
+
if (ref) this.manager._activate(ref, { focus: true });
|
|
330
|
+
model.unsnapInPlace();
|
|
387
331
|
const target = event.currentTarget;
|
|
388
|
-
target.setPointerCapture(event.pointerId);
|
|
389
|
-
const startX =
|
|
390
|
-
const startY =
|
|
391
|
-
const startW =
|
|
392
|
-
const startH =
|
|
332
|
+
target.setPointerCapture?.(event.pointerId);
|
|
333
|
+
const startX = model.x();
|
|
334
|
+
const startY = model.y();
|
|
335
|
+
const startW = model.width();
|
|
336
|
+
const startH = model.height();
|
|
393
337
|
const originX = event.clientX;
|
|
394
338
|
const originY = event.clientY;
|
|
395
339
|
const move = (e) => {
|
|
340
|
+
const o = model.options();
|
|
396
341
|
const dx = e.clientX - originX;
|
|
397
342
|
const dy = e.clientY - originY;
|
|
398
343
|
let nextX = startX;
|
|
@@ -409,24 +354,26 @@ var WrWindow = class WrWindow {
|
|
|
409
354
|
nextH = startH - dy;
|
|
410
355
|
nextY = startY + dy;
|
|
411
356
|
}
|
|
412
|
-
const clampedW =
|
|
413
|
-
const clampedH =
|
|
357
|
+
const clampedW = Math.min(o.maxWidth, Math.max(o.minWidth, nextW));
|
|
358
|
+
const clampedH = Math.min(o.maxHeight, Math.max(o.minHeight, nextH));
|
|
414
359
|
if (edges.l) nextX += nextW - clampedW;
|
|
415
360
|
if (edges.t) nextY += nextH - clampedH;
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
361
|
+
model.setRaw({
|
|
362
|
+
x: nextX,
|
|
363
|
+
y: nextY,
|
|
364
|
+
width: clampedW,
|
|
365
|
+
height: clampedH
|
|
366
|
+
});
|
|
367
|
+
model.clamp();
|
|
421
368
|
};
|
|
422
369
|
const cleanup = (e) => {
|
|
423
|
-
target.releasePointerCapture(e.pointerId);
|
|
370
|
+
target.releasePointerCapture?.(e.pointerId);
|
|
424
371
|
target.removeEventListener("pointermove", move);
|
|
425
372
|
target.removeEventListener("pointerup", cleanup);
|
|
426
373
|
target.removeEventListener("pointercancel", cleanup);
|
|
427
|
-
|
|
428
|
-
width:
|
|
429
|
-
height:
|
|
374
|
+
model.resized.next({
|
|
375
|
+
width: model.width(),
|
|
376
|
+
height: model.height()
|
|
430
377
|
});
|
|
431
378
|
};
|
|
432
379
|
target.addEventListener("pointermove", move);
|
|
@@ -453,44 +400,73 @@ var WrWindow = class WrWindow {
|
|
|
453
400
|
l: true
|
|
454
401
|
});
|
|
455
402
|
resizeL = (e) => this.startResize(e, { l: true });
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
this.
|
|
467
|
-
this.
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
403
|
+
onKeydown(event) {
|
|
404
|
+
if (this.model().keyboardMode()) {
|
|
405
|
+
this.onModeKey(event);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
if (event.defaultPrevented || !event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;
|
|
409
|
+
if (event.key !== "F7" && event.key !== "F8") return;
|
|
410
|
+
if (this.startKeyboard(event.key === "F7" ? "move" : "resize")) event.preventDefault();
|
|
411
|
+
}
|
|
412
|
+
startKeyboard(mode) {
|
|
413
|
+
const model = this.model();
|
|
414
|
+
const ref = this.windowRef();
|
|
415
|
+
if (ref) this.manager._activate(ref, { focus: false });
|
|
416
|
+
if (!model.startKeyboard(mode)) return false;
|
|
417
|
+
this.elRef.nativeElement.focus({ preventScroll: true });
|
|
418
|
+
this.announce(mode === "move" ? this.moveModeText() : this.resizeModeText());
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
onModeKey(event) {
|
|
422
|
+
const model = this.model();
|
|
423
|
+
const step = event.shiftKey ? 1 : model.options().keyboardStep;
|
|
424
|
+
const delta = {
|
|
425
|
+
ArrowLeft: [-step, 0],
|
|
426
|
+
ArrowRight: [step, 0],
|
|
427
|
+
ArrowUp: [0, -step],
|
|
428
|
+
ArrowDown: [0, step]
|
|
429
|
+
}[event.key];
|
|
430
|
+
if (delta) {
|
|
431
|
+
event.preventDefault();
|
|
432
|
+
if (model.keyboardMode() === "move") model.nudge(delta[0], delta[1]);
|
|
433
|
+
else {
|
|
434
|
+
const rtl = this.dir?.value === "rtl";
|
|
435
|
+
model.grow(rtl ? -delta[0] : delta[0], delta[1], rtl);
|
|
436
|
+
}
|
|
437
|
+
return;
|
|
479
438
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
439
|
+
if (event.key === "Enter") {
|
|
440
|
+
event.preventDefault();
|
|
441
|
+
this.commitKeyboard();
|
|
442
|
+
this.focusLast();
|
|
443
|
+
} else if (event.key === "Escape") {
|
|
444
|
+
event.preventDefault();
|
|
445
|
+
const mode = model.cancelKeyboard();
|
|
446
|
+
if (mode) this.announceGeometry(mode);
|
|
447
|
+
this.focusLast();
|
|
448
|
+
} else if (event.key === "Tab") this.commitKeyboard();
|
|
483
449
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
this.
|
|
450
|
+
commitKeyboard() {
|
|
451
|
+
const mode = this.model().commitKeyboard();
|
|
452
|
+
if (mode) this.announceGeometry(mode);
|
|
453
|
+
}
|
|
454
|
+
announceGeometry(mode) {
|
|
455
|
+
const r = this.model().rect();
|
|
456
|
+
this.announce(mode === "move" ? this.movedText({
|
|
457
|
+
x: r.left,
|
|
458
|
+
y: r.top
|
|
459
|
+
}) : this.resizedText({
|
|
460
|
+
width: r.width,
|
|
461
|
+
height: r.height
|
|
462
|
+
}));
|
|
463
|
+
}
|
|
464
|
+
announce(text) {
|
|
465
|
+
this.announcement.set(text);
|
|
490
466
|
}
|
|
491
467
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
492
468
|
minVersion: "12.0.0",
|
|
493
|
-
version: "22.2.
|
|
469
|
+
version: "22.2.4",
|
|
494
470
|
ngImport: i0,
|
|
495
471
|
type: WrWindow,
|
|
496
472
|
deps: [],
|
|
@@ -498,207 +474,101 @@ var WrWindow = class WrWindow {
|
|
|
498
474
|
});
|
|
499
475
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
500
476
|
minVersion: "17.0.0",
|
|
501
|
-
version: "22.2.
|
|
477
|
+
version: "22.2.4",
|
|
502
478
|
type: WrWindow,
|
|
503
479
|
isStandalone: true,
|
|
504
480
|
selector: "wr-window",
|
|
505
481
|
inputs: {
|
|
506
|
-
|
|
507
|
-
classPropertyName: "
|
|
508
|
-
publicName: "
|
|
482
|
+
model: {
|
|
483
|
+
classPropertyName: "model",
|
|
484
|
+
publicName: "model",
|
|
509
485
|
isSignal: true,
|
|
510
|
-
isRequired:
|
|
486
|
+
isRequired: true,
|
|
511
487
|
transformFunction: null
|
|
512
488
|
},
|
|
513
|
-
|
|
514
|
-
classPropertyName: "
|
|
515
|
-
publicName: "
|
|
489
|
+
windowRef: {
|
|
490
|
+
classPropertyName: "windowRef",
|
|
491
|
+
publicName: "windowRef",
|
|
516
492
|
isSignal: true,
|
|
517
493
|
isRequired: false,
|
|
518
494
|
transformFunction: null
|
|
519
495
|
},
|
|
520
|
-
|
|
521
|
-
classPropertyName: "
|
|
522
|
-
publicName: "
|
|
496
|
+
injector: {
|
|
497
|
+
classPropertyName: "injector",
|
|
498
|
+
publicName: "injector",
|
|
523
499
|
isSignal: true,
|
|
524
500
|
isRequired: false,
|
|
525
501
|
transformFunction: null
|
|
526
502
|
},
|
|
527
|
-
|
|
528
|
-
classPropertyName: "
|
|
529
|
-
publicName: "
|
|
503
|
+
titleExtra: {
|
|
504
|
+
classPropertyName: "titleExtra",
|
|
505
|
+
publicName: "titleExtra",
|
|
530
506
|
isSignal: true,
|
|
531
507
|
isRequired: false,
|
|
532
508
|
transformFunction: null
|
|
533
509
|
},
|
|
534
|
-
|
|
535
|
-
classPropertyName: "
|
|
536
|
-
publicName: "
|
|
537
|
-
isSignal: true,
|
|
538
|
-
isRequired: false,
|
|
539
|
-
transformFunction: null
|
|
540
|
-
},
|
|
541
|
-
size: {
|
|
542
|
-
classPropertyName: "size",
|
|
543
|
-
publicName: "size",
|
|
544
|
-
isSignal: true,
|
|
545
|
-
isRequired: false,
|
|
546
|
-
transformFunction: null
|
|
547
|
-
},
|
|
548
|
-
initialWidth: {
|
|
549
|
-
classPropertyName: "initialWidth",
|
|
550
|
-
publicName: "initialWidth",
|
|
551
|
-
isSignal: true,
|
|
552
|
-
isRequired: false,
|
|
553
|
-
transformFunction: null
|
|
554
|
-
},
|
|
555
|
-
initialHeight: {
|
|
556
|
-
classPropertyName: "initialHeight",
|
|
557
|
-
publicName: "initialHeight",
|
|
558
|
-
isSignal: true,
|
|
559
|
-
isRequired: false,
|
|
560
|
-
transformFunction: null
|
|
561
|
-
},
|
|
562
|
-
os: {
|
|
563
|
-
classPropertyName: "os",
|
|
564
|
-
publicName: "os",
|
|
565
|
-
isSignal: true,
|
|
566
|
-
isRequired: false,
|
|
567
|
-
transformFunction: null
|
|
568
|
-
},
|
|
569
|
-
chromeSize: {
|
|
570
|
-
classPropertyName: "chromeSize",
|
|
571
|
-
publicName: "chromeSize",
|
|
572
|
-
isSignal: true,
|
|
573
|
-
isRequired: false,
|
|
574
|
-
transformFunction: null
|
|
575
|
-
},
|
|
576
|
-
animations: {
|
|
577
|
-
classPropertyName: "animations",
|
|
578
|
-
publicName: "animations",
|
|
579
|
-
isSignal: true,
|
|
580
|
-
isRequired: false,
|
|
581
|
-
transformFunction: null
|
|
582
|
-
},
|
|
583
|
-
minWidth: {
|
|
584
|
-
classPropertyName: "minWidth",
|
|
585
|
-
publicName: "minWidth",
|
|
586
|
-
isSignal: true,
|
|
587
|
-
isRequired: false,
|
|
588
|
-
transformFunction: null
|
|
589
|
-
},
|
|
590
|
-
minHeight: {
|
|
591
|
-
classPropertyName: "minHeight",
|
|
592
|
-
publicName: "minHeight",
|
|
593
|
-
isSignal: true,
|
|
594
|
-
isRequired: false,
|
|
595
|
-
transformFunction: null
|
|
596
|
-
},
|
|
597
|
-
maxWidth: {
|
|
598
|
-
classPropertyName: "maxWidth",
|
|
599
|
-
publicName: "maxWidth",
|
|
600
|
-
isSignal: true,
|
|
601
|
-
isRequired: false,
|
|
602
|
-
transformFunction: null
|
|
603
|
-
},
|
|
604
|
-
maxHeight: {
|
|
605
|
-
classPropertyName: "maxHeight",
|
|
606
|
-
publicName: "maxHeight",
|
|
607
|
-
isSignal: true,
|
|
608
|
-
isRequired: false,
|
|
609
|
-
transformFunction: null
|
|
610
|
-
},
|
|
611
|
-
movable: {
|
|
612
|
-
classPropertyName: "movable",
|
|
613
|
-
publicName: "movable",
|
|
614
|
-
isSignal: true,
|
|
615
|
-
isRequired: false,
|
|
616
|
-
transformFunction: null
|
|
617
|
-
},
|
|
618
|
-
resizable: {
|
|
619
|
-
classPropertyName: "resizable",
|
|
620
|
-
publicName: "resizable",
|
|
621
|
-
isSignal: true,
|
|
622
|
-
isRequired: false,
|
|
623
|
-
transformFunction: null
|
|
624
|
-
},
|
|
625
|
-
keepInViewport: {
|
|
626
|
-
classPropertyName: "keepInViewport",
|
|
627
|
-
publicName: "keepInViewport",
|
|
628
|
-
isSignal: true,
|
|
629
|
-
isRequired: false,
|
|
630
|
-
transformFunction: null
|
|
631
|
-
},
|
|
632
|
-
snap: {
|
|
633
|
-
classPropertyName: "snap",
|
|
634
|
-
publicName: "snap",
|
|
635
|
-
isSignal: true,
|
|
636
|
-
isRequired: false,
|
|
637
|
-
transformFunction: null
|
|
638
|
-
},
|
|
639
|
-
dragHandle: {
|
|
640
|
-
classPropertyName: "dragHandle",
|
|
641
|
-
publicName: "dragHandle",
|
|
642
|
-
isSignal: true,
|
|
643
|
-
isRequired: false,
|
|
644
|
-
transformFunction: null
|
|
645
|
-
},
|
|
646
|
-
showMinimize: {
|
|
647
|
-
classPropertyName: "showMinimize",
|
|
648
|
-
publicName: "showMinimize",
|
|
649
|
-
isSignal: true,
|
|
650
|
-
isRequired: false,
|
|
651
|
-
transformFunction: null
|
|
652
|
-
},
|
|
653
|
-
showMaximize: {
|
|
654
|
-
classPropertyName: "showMaximize",
|
|
655
|
-
publicName: "showMaximize",
|
|
656
|
-
isSignal: true,
|
|
657
|
-
isRequired: false,
|
|
658
|
-
transformFunction: null
|
|
659
|
-
},
|
|
660
|
-
showClose: {
|
|
661
|
-
classPropertyName: "showClose",
|
|
662
|
-
publicName: "showClose",
|
|
510
|
+
statusBar: {
|
|
511
|
+
classPropertyName: "statusBar",
|
|
512
|
+
publicName: "statusBar",
|
|
663
513
|
isSignal: true,
|
|
664
514
|
isRequired: false,
|
|
665
515
|
transformFunction: null
|
|
666
516
|
}
|
|
667
517
|
},
|
|
668
|
-
outputs: {
|
|
669
|
-
open: "openChange",
|
|
670
|
-
state: "stateChange",
|
|
671
|
-
closed: "closed",
|
|
672
|
-
moved: "moved",
|
|
673
|
-
resized: "resized",
|
|
674
|
-
minimizedWithFocus: "minimizedWithFocus"
|
|
675
|
-
},
|
|
518
|
+
outputs: { closed: "closed" },
|
|
676
519
|
host: {
|
|
677
520
|
attributes: {
|
|
678
521
|
"role": "dialog",
|
|
679
522
|
"tabindex": "-1"
|
|
680
523
|
},
|
|
681
|
-
listeners: {
|
|
524
|
+
listeners: {
|
|
525
|
+
"pointerdown": "onPointerDown($event)",
|
|
526
|
+
"dblclick": "onBodyDblClick($event)",
|
|
527
|
+
"keydown": "onKeydown($event)",
|
|
528
|
+
"focusin": "onFocusIn($event)",
|
|
529
|
+
"focusout": "onFocusOut($event)"
|
|
530
|
+
},
|
|
682
531
|
properties: {
|
|
683
|
-
"attr.title": "null",
|
|
684
532
|
"class": "classes()",
|
|
685
|
-
"style.left.px": "
|
|
686
|
-
"style.top.px": "
|
|
687
|
-
"style.width.px": "
|
|
688
|
-
"style.height.px": "
|
|
689
|
-
"style.z-index": "z()",
|
|
690
|
-
"attr.aria-hidden": "!open()",
|
|
533
|
+
"style.left.px": "rect().left",
|
|
534
|
+
"style.top.px": "rect().top",
|
|
535
|
+
"style.width.px": "rect().width",
|
|
536
|
+
"style.height.px": "rect().height",
|
|
537
|
+
"style.z-index": "model().z()",
|
|
691
538
|
"attr.aria-labelledby": "titleId"
|
|
692
539
|
}
|
|
693
540
|
},
|
|
694
541
|
ngImport: i0,
|
|
695
|
-
template: "<!--\n
|
|
542
|
+
template: "<!--\n No pointerdown here: the host takes every press, so a `dragHandle` in the body\n can start a move as well as the title bar, and a press anywhere activates the\n window. The double-click is bound here and on the host; see `onChromeDblClick`.\n The action count is for the macOS chrome, which pads its title as wide as the\n cluster so the title centres on the whole bar.\n-->\n<div\n class=\"wr-window__chrome\"\n [style.--wr-window-chrome-action-count]=\"actionCount()\"\n (dblclick)=\"onChromeDblClick($event)\"\n>\n <div class=\"wr-window__title\" [attr.id]=\"titleId\">{{ displayTitle() }}</div>\n <div class=\"wr-window__title-extra\">\n @if (titleExtraTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: slotContext(); injector: injector()\" />\n } @else if (titleExtraComponent(); as component) {\n <ng-container *ngComponentOutlet=\"component; injector: injector()\" />\n }\n </div>\n\n <div class=\"wr-window__chrome-actions\">\n @if (resolvedOs() === 'macos') {\n <!--\n macOS traffic lights: close, minimize, zoom, in that order from the frame\n edge. The button is the hit target and the coloured dot is its\n `::before`, so the box can be big enough to press while the dot stays\n the platform's size. The glyphs sit on an 8px grid and appear only while\n the cluster is hovered or holds keyboard focus, as they do on macOS.\n Zoom draws the full-screen arrows of Big Sur and later: pointing out to\n maximize, pointing in to restore. Every straight edge of both sits on a\n whole pixel, so the filled triangles stay hard at 1x.\n -->\n @if (showClose()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"close()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" aria-hidden=\"true\">\n <path d=\"M1.5 1.5l5 5m0-5l-5 5\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" />\n </svg>\n </button>\n }\n @if (minimizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--minimize\"\n [attr.aria-label]=\"minimizeActionLabel()\"\n (click)=\"minimize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" aria-hidden=\"true\">\n <path d=\"M1.5 3.5h5\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" />\n </svg>\n </button>\n }\n @if (maximizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--maximize\"\n [attr.aria-label]=\"maximizeActionLabel()\"\n (click)=\"maximize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" aria-hidden=\"true\">\n @if (state() === 'maximized') {\n <path d=\"M3 3V.5L.5 3zM5 5v2.5L7.5 5z\" fill=\"currentColor\" />\n } @else {\n <path d=\"M1 1h4L1 5zm6 6H3l4-4z\" fill=\"currentColor\" />\n }\n </svg>\n </button>\n }\n } @else if (resolvedOs() === 'linux') {\n <!--\n GNOME (libadwaita) window controls: round buttons with Adwaita's 16px\n symbolic glyphs, 2px strokes on whole pixels. Restore is the SMALLER\n square, the way Adwaita draws it, not a second overlapping one. Close-only\n is the DEFAULT here, not a rule: `minimizeVisible()` resolves the input\n first, so `[showMinimize]=\"true\"` puts the button back, which is the only\n way a user on Linux can reach `<wr-window-taskbar>` at all.\n -->\n @if (minimizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--minimize\"\n [attr.aria-label]=\"minimizeActionLabel()\"\n (click)=\"minimize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M4 11h8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n </button>\n }\n @if (maximizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--maximize\"\n [attr.aria-label]=\"maximizeActionLabel()\"\n (click)=\"maximize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n @if (state() === 'maximized') {\n <rect x=\"6\" y=\"6\" width=\"4\" height=\"4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n } @else {\n <rect x=\"5\" y=\"5\" width=\"6\" height=\"6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n }\n </svg>\n </button>\n }\n @if (showClose()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"close()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M5 5l6 6m0-6l-6 6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </button>\n }\n } @else {\n <!--\n Windows 11 caption buttons: 10px glyphs in the full-height, 46px-wide\n buttons, drawn the way Segoe Fluent Icons draws them. 1px strokes on half\n pixels, so they land on whole device pixels at 1x and 2x, and the corners\n of maximize and restore are rounded by 1px.\n -->\n @if (minimizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--minimize\"\n [attr.aria-label]=\"minimizeActionLabel()\"\n (click)=\"minimize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M0 4.5h10\" fill=\"none\" stroke=\"currentColor\" />\n </svg>\n </button>\n }\n @if (maximizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--maximize\"\n [attr.aria-label]=\"maximizeActionLabel()\"\n (click)=\"maximize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n @if (state() === 'maximized') {\n <g fill=\"none\" stroke=\"currentColor\">\n <rect x=\".5\" y=\"2.5\" width=\"7\" height=\"7\" rx=\"1\" />\n <path d=\"M2.5 2.5v-1a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1h-1\" />\n </g>\n } @else {\n <rect x=\".5\" y=\".5\" width=\"9\" height=\"9\" rx=\"1\" fill=\"none\" stroke=\"currentColor\" />\n }\n </svg>\n </button>\n }\n @if (showClose()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"close()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M.5.5l9 9m0-9l-9 9\" fill=\"none\" stroke=\"currentColor\" />\n </svg>\n </button>\n }\n }\n </div>\n</div>\n\n<div class=\"wr-window__body\">\n <ng-content />\n</div>\n\n<div class=\"wr-window__status-bar\">\n @if (statusBarTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: slotContext(); injector: injector()\" />\n } @else if (statusBarComponent(); as component) {\n <ng-container *ngComponentOutlet=\"component; injector: injector()\" />\n }\n</div>\n\n<!--\n Keyboard move and resize say what they did here: the mode on entry, the\n landing on Enter or Escape. Not each step — that would flood the region.\n-->\n<p class=\"wr-window__sr-only\" role=\"status\">{{ announcement() }}</p>\n\n@if (resizeHandles()) {\n <span class=\"wr-window__handle wr-window__handle--t\" (pointerdown)=\"resizeT($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--r\" (pointerdown)=\"resizeR($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--b\" (pointerdown)=\"resizeB($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--l\" (pointerdown)=\"resizeL($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--tl\" (pointerdown)=\"resizeTL($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--tr\" (pointerdown)=\"resizeTR($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--bl\" (pointerdown)=\"resizeBL($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--br\" (pointerdown)=\"resizeBR($event)\"></span>\n}\n",
|
|
543
|
+
dependencies: [{
|
|
544
|
+
kind: "directive",
|
|
545
|
+
type: NgTemplateOutlet,
|
|
546
|
+
selector: "[ngTemplateOutlet]",
|
|
547
|
+
inputs: [
|
|
548
|
+
"ngTemplateOutletContext",
|
|
549
|
+
"ngTemplateOutlet",
|
|
550
|
+
"ngTemplateOutletInjector"
|
|
551
|
+
]
|
|
552
|
+
}, {
|
|
553
|
+
kind: "directive",
|
|
554
|
+
type: NgComponentOutlet,
|
|
555
|
+
selector: "[ngComponentOutlet]",
|
|
556
|
+
inputs: [
|
|
557
|
+
"ngComponentOutlet",
|
|
558
|
+
"ngComponentOutletInputs",
|
|
559
|
+
"ngComponentOutletInjector",
|
|
560
|
+
"ngComponentOutletEnvironmentInjector",
|
|
561
|
+
"ngComponentOutletContent",
|
|
562
|
+
"ngComponentOutletNgModule"
|
|
563
|
+
],
|
|
564
|
+
exportAs: ["ngComponentOutlet"]
|
|
565
|
+
}],
|
|
696
566
|
encapsulation: i0.ViewEncapsulation.None
|
|
697
567
|
});
|
|
698
568
|
};
|
|
699
569
|
i0.ɵɵngDeclareClassMetadata({
|
|
700
570
|
minVersion: "12.0.0",
|
|
701
|
-
version: "22.2.
|
|
571
|
+
version: "22.2.4",
|
|
702
572
|
ngImport: i0,
|
|
703
573
|
type: WrWindow,
|
|
704
574
|
decorators: [{
|
|
@@ -706,230 +576,71 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
706
576
|
args: [{
|
|
707
577
|
selector: "wr-window",
|
|
708
578
|
encapsulation: ViewEncapsulation.None,
|
|
579
|
+
imports: [NgTemplateOutlet, NgComponentOutlet],
|
|
709
580
|
host: {
|
|
710
|
-
"[attr.title]": "null",
|
|
711
581
|
role: "dialog",
|
|
712
582
|
tabindex: "-1",
|
|
713
583
|
"[class]": "classes()",
|
|
714
|
-
"[style.left.px]": "
|
|
715
|
-
"[style.top.px]": "
|
|
716
|
-
"[style.width.px]": "
|
|
717
|
-
"[style.height.px]": "
|
|
718
|
-
"[style.z-index]": "z()",
|
|
719
|
-
"[attr.aria-
|
|
720
|
-
"
|
|
721
|
-
"(
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
alias: "open",
|
|
733
|
-
required: false
|
|
734
|
-
}]
|
|
735
|
-
}, {
|
|
736
|
-
type: i0.Output,
|
|
737
|
-
args: ["openChange"]
|
|
738
|
-
}],
|
|
739
|
-
state: [{
|
|
740
|
-
type: i0.Input,
|
|
741
|
-
args: [{
|
|
742
|
-
isSignal: true,
|
|
743
|
-
alias: "state",
|
|
744
|
-
required: false
|
|
745
|
-
}]
|
|
746
|
-
}, {
|
|
747
|
-
type: i0.Output,
|
|
748
|
-
args: ["stateChange"]
|
|
749
|
-
}],
|
|
750
|
-
title: [{
|
|
751
|
-
type: i0.Input,
|
|
752
|
-
args: [{
|
|
753
|
-
isSignal: true,
|
|
754
|
-
alias: "title",
|
|
755
|
-
required: false
|
|
756
|
-
}]
|
|
757
|
-
}],
|
|
758
|
-
initialX: [{
|
|
759
|
-
type: i0.Input,
|
|
760
|
-
args: [{
|
|
761
|
-
isSignal: true,
|
|
762
|
-
alias: "initialX",
|
|
763
|
-
required: false
|
|
764
|
-
}]
|
|
765
|
-
}],
|
|
766
|
-
initialY: [{
|
|
767
|
-
type: i0.Input,
|
|
768
|
-
args: [{
|
|
769
|
-
isSignal: true,
|
|
770
|
-
alias: "initialY",
|
|
771
|
-
required: false
|
|
772
|
-
}]
|
|
773
|
-
}],
|
|
774
|
-
size: [{
|
|
775
|
-
type: i0.Input,
|
|
776
|
-
args: [{
|
|
777
|
-
isSignal: true,
|
|
778
|
-
alias: "size",
|
|
779
|
-
required: false
|
|
780
|
-
}]
|
|
781
|
-
}],
|
|
782
|
-
initialWidth: [{
|
|
783
|
-
type: i0.Input,
|
|
784
|
-
args: [{
|
|
785
|
-
isSignal: true,
|
|
786
|
-
alias: "initialWidth",
|
|
787
|
-
required: false
|
|
788
|
-
}]
|
|
789
|
-
}],
|
|
790
|
-
initialHeight: [{
|
|
791
|
-
type: i0.Input,
|
|
792
|
-
args: [{
|
|
793
|
-
isSignal: true,
|
|
794
|
-
alias: "initialHeight",
|
|
795
|
-
required: false
|
|
796
|
-
}]
|
|
797
|
-
}],
|
|
798
|
-
os: [{
|
|
799
|
-
type: i0.Input,
|
|
800
|
-
args: [{
|
|
801
|
-
isSignal: true,
|
|
802
|
-
alias: "os",
|
|
803
|
-
required: false
|
|
804
|
-
}]
|
|
805
|
-
}],
|
|
806
|
-
chromeSize: [{
|
|
807
|
-
type: i0.Input,
|
|
808
|
-
args: [{
|
|
809
|
-
isSignal: true,
|
|
810
|
-
alias: "chromeSize",
|
|
811
|
-
required: false
|
|
812
|
-
}]
|
|
813
|
-
}],
|
|
814
|
-
animations: [{
|
|
815
|
-
type: i0.Input,
|
|
816
|
-
args: [{
|
|
817
|
-
isSignal: true,
|
|
818
|
-
alias: "animations",
|
|
819
|
-
required: false
|
|
820
|
-
}]
|
|
821
|
-
}],
|
|
822
|
-
minWidth: [{
|
|
823
|
-
type: i0.Input,
|
|
824
|
-
args: [{
|
|
825
|
-
isSignal: true,
|
|
826
|
-
alias: "minWidth",
|
|
827
|
-
required: false
|
|
828
|
-
}]
|
|
829
|
-
}],
|
|
830
|
-
minHeight: [{
|
|
831
|
-
type: i0.Input,
|
|
832
|
-
args: [{
|
|
833
|
-
isSignal: true,
|
|
834
|
-
alias: "minHeight",
|
|
835
|
-
required: false
|
|
836
|
-
}]
|
|
837
|
-
}],
|
|
838
|
-
maxWidth: [{
|
|
839
|
-
type: i0.Input,
|
|
840
|
-
args: [{
|
|
841
|
-
isSignal: true,
|
|
842
|
-
alias: "maxWidth",
|
|
843
|
-
required: false
|
|
844
|
-
}]
|
|
845
|
-
}],
|
|
846
|
-
maxHeight: [{
|
|
847
|
-
type: i0.Input,
|
|
848
|
-
args: [{
|
|
849
|
-
isSignal: true,
|
|
850
|
-
alias: "maxHeight",
|
|
851
|
-
required: false
|
|
852
|
-
}]
|
|
853
|
-
}],
|
|
854
|
-
movable: [{
|
|
855
|
-
type: i0.Input,
|
|
856
|
-
args: [{
|
|
857
|
-
isSignal: true,
|
|
858
|
-
alias: "movable",
|
|
859
|
-
required: false
|
|
860
|
-
}]
|
|
861
|
-
}],
|
|
862
|
-
resizable: [{
|
|
863
|
-
type: i0.Input,
|
|
864
|
-
args: [{
|
|
865
|
-
isSignal: true,
|
|
866
|
-
alias: "resizable",
|
|
867
|
-
required: false
|
|
868
|
-
}]
|
|
869
|
-
}],
|
|
870
|
-
keepInViewport: [{
|
|
871
|
-
type: i0.Input,
|
|
872
|
-
args: [{
|
|
873
|
-
isSignal: true,
|
|
874
|
-
alias: "keepInViewport",
|
|
875
|
-
required: false
|
|
876
|
-
}]
|
|
877
|
-
}],
|
|
878
|
-
snap: [{
|
|
584
|
+
"[style.left.px]": "rect().left",
|
|
585
|
+
"[style.top.px]": "rect().top",
|
|
586
|
+
"[style.width.px]": "rect().width",
|
|
587
|
+
"[style.height.px]": "rect().height",
|
|
588
|
+
"[style.z-index]": "model().z()",
|
|
589
|
+
"[attr.aria-labelledby]": "titleId",
|
|
590
|
+
"(pointerdown)": "onPointerDown($event)",
|
|
591
|
+
"(dblclick)": "onBodyDblClick($event)",
|
|
592
|
+
"(keydown)": "onKeydown($event)",
|
|
593
|
+
"(focusin)": "onFocusIn($event)",
|
|
594
|
+
"(focusout)": "onFocusOut($event)"
|
|
595
|
+
},
|
|
596
|
+
template: "<!--\n No pointerdown here: the host takes every press, so a `dragHandle` in the body\n can start a move as well as the title bar, and a press anywhere activates the\n window. The double-click is bound here and on the host; see `onChromeDblClick`.\n The action count is for the macOS chrome, which pads its title as wide as the\n cluster so the title centres on the whole bar.\n-->\n<div\n class=\"wr-window__chrome\"\n [style.--wr-window-chrome-action-count]=\"actionCount()\"\n (dblclick)=\"onChromeDblClick($event)\"\n>\n <div class=\"wr-window__title\" [attr.id]=\"titleId\">{{ displayTitle() }}</div>\n <div class=\"wr-window__title-extra\">\n @if (titleExtraTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: slotContext(); injector: injector()\" />\n } @else if (titleExtraComponent(); as component) {\n <ng-container *ngComponentOutlet=\"component; injector: injector()\" />\n }\n </div>\n\n <div class=\"wr-window__chrome-actions\">\n @if (resolvedOs() === 'macos') {\n <!--\n macOS traffic lights: close, minimize, zoom, in that order from the frame\n edge. The button is the hit target and the coloured dot is its\n `::before`, so the box can be big enough to press while the dot stays\n the platform's size. The glyphs sit on an 8px grid and appear only while\n the cluster is hovered or holds keyboard focus, as they do on macOS.\n Zoom draws the full-screen arrows of Big Sur and later: pointing out to\n maximize, pointing in to restore. Every straight edge of both sits on a\n whole pixel, so the filled triangles stay hard at 1x.\n -->\n @if (showClose()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"close()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" aria-hidden=\"true\">\n <path d=\"M1.5 1.5l5 5m0-5l-5 5\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" />\n </svg>\n </button>\n }\n @if (minimizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--minimize\"\n [attr.aria-label]=\"minimizeActionLabel()\"\n (click)=\"minimize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" aria-hidden=\"true\">\n <path d=\"M1.5 3.5h5\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" />\n </svg>\n </button>\n }\n @if (maximizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--maximize\"\n [attr.aria-label]=\"maximizeActionLabel()\"\n (click)=\"maximize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" aria-hidden=\"true\">\n @if (state() === 'maximized') {\n <path d=\"M3 3V.5L.5 3zM5 5v2.5L7.5 5z\" fill=\"currentColor\" />\n } @else {\n <path d=\"M1 1h4L1 5zm6 6H3l4-4z\" fill=\"currentColor\" />\n }\n </svg>\n </button>\n }\n } @else if (resolvedOs() === 'linux') {\n <!--\n GNOME (libadwaita) window controls: round buttons with Adwaita's 16px\n symbolic glyphs, 2px strokes on whole pixels. Restore is the SMALLER\n square, the way Adwaita draws it, not a second overlapping one. Close-only\n is the DEFAULT here, not a rule: `minimizeVisible()` resolves the input\n first, so `[showMinimize]=\"true\"` puts the button back, which is the only\n way a user on Linux can reach `<wr-window-taskbar>` at all.\n -->\n @if (minimizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--minimize\"\n [attr.aria-label]=\"minimizeActionLabel()\"\n (click)=\"minimize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M4 11h8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n </button>\n }\n @if (maximizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--maximize\"\n [attr.aria-label]=\"maximizeActionLabel()\"\n (click)=\"maximize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n @if (state() === 'maximized') {\n <rect x=\"6\" y=\"6\" width=\"4\" height=\"4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n } @else {\n <rect x=\"5\" y=\"5\" width=\"6\" height=\"6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n }\n </svg>\n </button>\n }\n @if (showClose()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"close()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M5 5l6 6m0-6l-6 6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </button>\n }\n } @else {\n <!--\n Windows 11 caption buttons: 10px glyphs in the full-height, 46px-wide\n buttons, drawn the way Segoe Fluent Icons draws them. 1px strokes on half\n pixels, so they land on whole device pixels at 1x and 2x, and the corners\n of maximize and restore are rounded by 1px.\n -->\n @if (minimizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--minimize\"\n [attr.aria-label]=\"minimizeActionLabel()\"\n (click)=\"minimize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M0 4.5h10\" fill=\"none\" stroke=\"currentColor\" />\n </svg>\n </button>\n }\n @if (maximizeVisible()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--maximize\"\n [attr.aria-label]=\"maximizeActionLabel()\"\n (click)=\"maximize()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n @if (state() === 'maximized') {\n <g fill=\"none\" stroke=\"currentColor\">\n <rect x=\".5\" y=\"2.5\" width=\"7\" height=\"7\" rx=\"1\" />\n <path d=\"M2.5 2.5v-1a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1h-1\" />\n </g>\n } @else {\n <rect x=\".5\" y=\".5\" width=\"9\" height=\"9\" rx=\"1\" fill=\"none\" stroke=\"currentColor\" />\n }\n </svg>\n </button>\n }\n @if (showClose()) {\n <button\n type=\"button\"\n class=\"wr-window__chrome-action wr-window__chrome-action--close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"close()\"\n >\n <svg class=\"wr-window__chrome-action-glyph\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M.5.5l9 9m0-9l-9 9\" fill=\"none\" stroke=\"currentColor\" />\n </svg>\n </button>\n }\n }\n </div>\n</div>\n\n<div class=\"wr-window__body\">\n <ng-content />\n</div>\n\n<div class=\"wr-window__status-bar\">\n @if (statusBarTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: slotContext(); injector: injector()\" />\n } @else if (statusBarComponent(); as component) {\n <ng-container *ngComponentOutlet=\"component; injector: injector()\" />\n }\n</div>\n\n<!--\n Keyboard move and resize say what they did here: the mode on entry, the\n landing on Enter or Escape. Not each step — that would flood the region.\n-->\n<p class=\"wr-window__sr-only\" role=\"status\">{{ announcement() }}</p>\n\n@if (resizeHandles()) {\n <span class=\"wr-window__handle wr-window__handle--t\" (pointerdown)=\"resizeT($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--r\" (pointerdown)=\"resizeR($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--b\" (pointerdown)=\"resizeB($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--l\" (pointerdown)=\"resizeL($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--tl\" (pointerdown)=\"resizeTL($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--tr\" (pointerdown)=\"resizeTR($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--bl\" (pointerdown)=\"resizeBL($event)\"></span>\n <span class=\"wr-window__handle wr-window__handle--br\" (pointerdown)=\"resizeBR($event)\"></span>\n}\n"
|
|
597
|
+
}]
|
|
598
|
+
}],
|
|
599
|
+
ctorParameters: () => [],
|
|
600
|
+
propDecorators: {
|
|
601
|
+
model: [{
|
|
879
602
|
type: i0.Input,
|
|
880
603
|
args: [{
|
|
881
604
|
isSignal: true,
|
|
882
|
-
alias: "
|
|
883
|
-
required:
|
|
605
|
+
alias: "model",
|
|
606
|
+
required: true
|
|
884
607
|
}]
|
|
885
608
|
}],
|
|
886
|
-
|
|
609
|
+
windowRef: [{
|
|
887
610
|
type: i0.Input,
|
|
888
611
|
args: [{
|
|
889
612
|
isSignal: true,
|
|
890
|
-
alias: "
|
|
613
|
+
alias: "windowRef",
|
|
891
614
|
required: false
|
|
892
615
|
}]
|
|
893
616
|
}],
|
|
894
|
-
|
|
617
|
+
injector: [{
|
|
895
618
|
type: i0.Input,
|
|
896
619
|
args: [{
|
|
897
620
|
isSignal: true,
|
|
898
|
-
alias: "
|
|
621
|
+
alias: "injector",
|
|
899
622
|
required: false
|
|
900
623
|
}]
|
|
901
624
|
}],
|
|
902
|
-
|
|
625
|
+
titleExtra: [{
|
|
903
626
|
type: i0.Input,
|
|
904
627
|
args: [{
|
|
905
628
|
isSignal: true,
|
|
906
|
-
alias: "
|
|
629
|
+
alias: "titleExtra",
|
|
907
630
|
required: false
|
|
908
631
|
}]
|
|
909
632
|
}],
|
|
910
|
-
|
|
633
|
+
statusBar: [{
|
|
911
634
|
type: i0.Input,
|
|
912
635
|
args: [{
|
|
913
636
|
isSignal: true,
|
|
914
|
-
alias: "
|
|
637
|
+
alias: "statusBar",
|
|
915
638
|
required: false
|
|
916
639
|
}]
|
|
917
640
|
}],
|
|
918
641
|
closed: [{
|
|
919
642
|
type: i0.Output,
|
|
920
643
|
args: ["closed"]
|
|
921
|
-
}],
|
|
922
|
-
moved: [{
|
|
923
|
-
type: i0.Output,
|
|
924
|
-
args: ["moved"]
|
|
925
|
-
}],
|
|
926
|
-
resized: [{
|
|
927
|
-
type: i0.Output,
|
|
928
|
-
args: ["resized"]
|
|
929
|
-
}],
|
|
930
|
-
minimizedWithFocus: [{
|
|
931
|
-
type: i0.Output,
|
|
932
|
-
args: ["minimizedWithFocus"]
|
|
933
644
|
}]
|
|
934
645
|
}
|
|
935
646
|
});
|
|
@@ -952,6 +663,11 @@ var WrWindowContainer = class WrWindowContainer {
|
|
|
952
663
|
wrWindow = viewChild.required(WrWindow, ...ngDevMode ? [{ debugName: "wrWindow" }] : /* istanbul ignore next */ []);
|
|
953
664
|
constructor() {
|
|
954
665
|
afterNextRender(() => this.attach());
|
|
666
|
+
effect(() => {
|
|
667
|
+
const model = this.ref._model;
|
|
668
|
+
model.workArea();
|
|
669
|
+
untracked(() => model.clamp());
|
|
670
|
+
});
|
|
955
671
|
this.destroyRef.onDestroy(() => {
|
|
956
672
|
if (this.persistTimer !== null) clearTimeout(this.persistTimer);
|
|
957
673
|
});
|
|
@@ -960,86 +676,64 @@ var WrWindowContainer = class WrWindowContainer {
|
|
|
960
676
|
const componentRef = this.contentVcr().createComponent(this.componentType, { injector: this.childInjector });
|
|
961
677
|
this.ref.componentRef = componentRef;
|
|
962
678
|
const w = this.wrWindow();
|
|
963
|
-
this.ref.
|
|
964
|
-
this.ref.
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
this.ref.
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
effect(() => {
|
|
985
|
-
const host = this.ref._overlayRef?.hostElement;
|
|
986
|
-
if (host) host.style.zIndex = String(w.z());
|
|
987
|
-
});
|
|
679
|
+
const model = this.ref._model;
|
|
680
|
+
this.ref._focusWindow = (mode) => afterNextRender(() => {
|
|
681
|
+
if (mode === "initial") {
|
|
682
|
+
w.focusInitial();
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
if (this.manager.active() === this.ref) w.focusLast();
|
|
686
|
+
}, { injector: this.hostInjector });
|
|
687
|
+
this.ref._startKeyboard = (mode) => {
|
|
688
|
+
if (model.state() !== "minimized") {
|
|
689
|
+
w.startKeyboard(mode);
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
model.unminimize();
|
|
693
|
+
afterNextRender(() => w.startKeyboard(mode), { injector: this.hostInjector });
|
|
694
|
+
};
|
|
695
|
+
model.onMinimizedWithFocus = () => this.onMinimizedWithFocus();
|
|
696
|
+
this.destroyRef.onDestroy(() => {
|
|
697
|
+
this.ref._focusWindow = null;
|
|
698
|
+
this.ref._startKeyboard = null;
|
|
699
|
+
model.onMinimizedWithFocus = null;
|
|
988
700
|
});
|
|
989
|
-
|
|
990
|
-
if (this.
|
|
991
|
-
|
|
992
|
-
this.installAutosave(w);
|
|
993
|
-
}
|
|
994
|
-
const pending = this.ref.pendingStateOnMount;
|
|
701
|
+
if (this.config.storage) this.installAutosave();
|
|
702
|
+
if (this.autoFocus && model.state() !== "minimized") this.ref._focusWindow("initial");
|
|
703
|
+
const pending = this.ref._pendingKeyboard;
|
|
995
704
|
if (pending) {
|
|
996
|
-
this.ref.
|
|
997
|
-
|
|
998
|
-
else if (pending === "maximized") this.ref.maximize();
|
|
705
|
+
this.ref._pendingKeyboard = null;
|
|
706
|
+
this.ref._startKeyboard(pending);
|
|
999
707
|
}
|
|
1000
|
-
if (this.autoFocus && w.state() !== "minimized") this.ref._doFocusInitial();
|
|
1001
708
|
}
|
|
1002
709
|
onMinimizedWithFocus() {
|
|
1003
710
|
afterNextRender(() => this.manager._focusAfterMinimize(this.ref), { injector: this.hostInjector });
|
|
1004
711
|
}
|
|
1005
|
-
|
|
1006
|
-
const cfg = this.config.storage;
|
|
1007
|
-
if (!cfg) return;
|
|
1008
|
-
const saved = this.storage.get(storageKey(cfg));
|
|
1009
|
-
if (!saved) return;
|
|
1010
|
-
const persist = cfg.persist ?? "all";
|
|
1011
|
-
if (persist !== "size") {
|
|
1012
|
-
if (typeof saved.x === "number") w.x_.set(saved.x);
|
|
1013
|
-
if (typeof saved.y === "number") w.y_.set(saved.y);
|
|
1014
|
-
}
|
|
1015
|
-
if (persist !== "position") {
|
|
1016
|
-
if (typeof saved.width === "number") w.width_.set(saved.width);
|
|
1017
|
-
if (typeof saved.height === "number") w.height_.set(saved.height);
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
installAutosave(w) {
|
|
712
|
+
installAutosave() {
|
|
1021
713
|
const cfg = this.config.storage;
|
|
1022
714
|
if (!cfg) return;
|
|
1023
715
|
const persist = cfg.persist ?? "all";
|
|
1024
716
|
const key = storageKey(cfg);
|
|
717
|
+
const model = this.ref._model;
|
|
1025
718
|
runInInjectionContext(this.hostInjector, () => {
|
|
1026
719
|
effect(() => {
|
|
1027
|
-
const x =
|
|
1028
|
-
const y =
|
|
1029
|
-
const width =
|
|
1030
|
-
const height =
|
|
720
|
+
const x = model.x();
|
|
721
|
+
const y = model.y();
|
|
722
|
+
const width = model.width();
|
|
723
|
+
const height = model.height();
|
|
1031
724
|
if (this.persistTimer !== null) clearTimeout(this.persistTimer);
|
|
1032
725
|
this.persistTimer = setTimeout(() => {
|
|
1033
726
|
this.persistTimer = null;
|
|
1034
|
-
const payload = {
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
727
|
+
const payload = {
|
|
728
|
+
...persist !== "size" ? {
|
|
729
|
+
x,
|
|
730
|
+
y
|
|
731
|
+
} : {},
|
|
732
|
+
...persist !== "position" ? {
|
|
733
|
+
width,
|
|
734
|
+
height
|
|
735
|
+
} : {}
|
|
736
|
+
};
|
|
1043
737
|
this.storage.set(key, payload);
|
|
1044
738
|
}, PERSIST_DEBOUNCE_MS);
|
|
1045
739
|
});
|
|
@@ -1047,7 +741,7 @@ var WrWindowContainer = class WrWindowContainer {
|
|
|
1047
741
|
}
|
|
1048
742
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
1049
743
|
minVersion: "12.0.0",
|
|
1050
|
-
version: "22.2.
|
|
744
|
+
version: "22.2.4",
|
|
1051
745
|
ngImport: i0,
|
|
1052
746
|
type: WrWindowContainer,
|
|
1053
747
|
deps: [],
|
|
@@ -1055,7 +749,7 @@ var WrWindowContainer = class WrWindowContainer {
|
|
|
1055
749
|
});
|
|
1056
750
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
1057
751
|
minVersion: "17.0.0",
|
|
1058
|
-
version: "22.2.
|
|
752
|
+
version: "22.2.4",
|
|
1059
753
|
type: WrWindowContainer,
|
|
1060
754
|
isStandalone: true,
|
|
1061
755
|
selector: "wr-window-container",
|
|
@@ -1074,44 +768,19 @@ var WrWindowContainer = class WrWindowContainer {
|
|
|
1074
768
|
isSignal: true
|
|
1075
769
|
}],
|
|
1076
770
|
ngImport: i0,
|
|
1077
|
-
template: "<wr-window\n [
|
|
771
|
+
template: "<wr-window\n [model]=\"ref._model\"\n [windowRef]=\"ref\"\n [injector]=\"childInjector\"\n [titleExtra]=\"config.titleExtra ?? null\"\n [statusBar]=\"config.statusBar ?? null\"\n (closed)=\"ref.close()\"\n #window\n>\n <ng-container #content />\n</wr-window>\n\n<!--\n The snap hint lives here, not inside `<wr-window>`: `.wr-window` clips, and a\n fixed child is clipped with it while the open animation's transform is on.\n It takes the exact box the drop will give the window, from the same model\n arithmetic, so the hint and the landing cannot disagree — they did when the\n hint was a CSS 50% of the layout viewport and the snap was half of\n `innerWidth`, 7.5px apart with a classic scrollbar showing.\n-->\n@if (ref._model.previewRect(); as box) {\n <div\n class=\"wr-window__snap-hint\"\n [attr.data-target]=\"ref._model.dragTarget()\"\n [style.left.px]=\"box.left\"\n [style.top.px]=\"box.top\"\n [style.width.px]=\"box.width\"\n [style.height.px]=\"box.height\"\n [style.z-index]=\"ref._model.z() + 1\"\n aria-hidden=\"true\"\n ></div>\n}\n",
|
|
1078
772
|
dependencies: [{
|
|
1079
773
|
kind: "component",
|
|
1080
774
|
type: WrWindow,
|
|
1081
775
|
selector: "wr-window",
|
|
1082
776
|
inputs: [
|
|
1083
|
-
"
|
|
1084
|
-
"
|
|
1085
|
-
"
|
|
1086
|
-
"
|
|
1087
|
-
"
|
|
1088
|
-
"size",
|
|
1089
|
-
"initialWidth",
|
|
1090
|
-
"initialHeight",
|
|
1091
|
-
"os",
|
|
1092
|
-
"chromeSize",
|
|
1093
|
-
"animations",
|
|
1094
|
-
"minWidth",
|
|
1095
|
-
"minHeight",
|
|
1096
|
-
"maxWidth",
|
|
1097
|
-
"maxHeight",
|
|
1098
|
-
"movable",
|
|
1099
|
-
"resizable",
|
|
1100
|
-
"keepInViewport",
|
|
1101
|
-
"snap",
|
|
1102
|
-
"dragHandle",
|
|
1103
|
-
"showMinimize",
|
|
1104
|
-
"showMaximize",
|
|
1105
|
-
"showClose"
|
|
777
|
+
"model",
|
|
778
|
+
"windowRef",
|
|
779
|
+
"injector",
|
|
780
|
+
"titleExtra",
|
|
781
|
+
"statusBar"
|
|
1106
782
|
],
|
|
1107
|
-
outputs: [
|
|
1108
|
-
"openChange",
|
|
1109
|
-
"stateChange",
|
|
1110
|
-
"closed",
|
|
1111
|
-
"moved",
|
|
1112
|
-
"resized",
|
|
1113
|
-
"minimizedWithFocus"
|
|
1114
|
-
]
|
|
783
|
+
outputs: ["closed"]
|
|
1115
784
|
}],
|
|
1116
785
|
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
1117
786
|
encapsulation: i0.ViewEncapsulation.None
|
|
@@ -1119,7 +788,7 @@ var WrWindowContainer = class WrWindowContainer {
|
|
|
1119
788
|
};
|
|
1120
789
|
i0.ɵɵngDeclareClassMetadata({
|
|
1121
790
|
minVersion: "12.0.0",
|
|
1122
|
-
version: "22.2.
|
|
791
|
+
version: "22.2.4",
|
|
1123
792
|
ngImport: i0,
|
|
1124
793
|
type: WrWindowContainer,
|
|
1125
794
|
decorators: [{
|
|
@@ -1129,7 +798,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1129
798
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1130
799
|
encapsulation: ViewEncapsulation.None,
|
|
1131
800
|
imports: [WrWindow],
|
|
1132
|
-
template: "<wr-window\n [
|
|
801
|
+
template: "<wr-window\n [model]=\"ref._model\"\n [windowRef]=\"ref\"\n [injector]=\"childInjector\"\n [titleExtra]=\"config.titleExtra ?? null\"\n [statusBar]=\"config.statusBar ?? null\"\n (closed)=\"ref.close()\"\n #window\n>\n <ng-container #content />\n</wr-window>\n\n<!--\n The snap hint lives here, not inside `<wr-window>`: `.wr-window` clips, and a\n fixed child is clipped with it while the open animation's transform is on.\n It takes the exact box the drop will give the window, from the same model\n arithmetic, so the hint and the landing cannot disagree — they did when the\n hint was a CSS 50% of the layout viewport and the snap was half of\n `innerWidth`, 7.5px apart with a classic scrollbar showing.\n-->\n@if (ref._model.previewRect(); as box) {\n <div\n class=\"wr-window__snap-hint\"\n [attr.data-target]=\"ref._model.dragTarget()\"\n [style.left.px]=\"box.left\"\n [style.top.px]=\"box.top\"\n [style.width.px]=\"box.width\"\n [style.height.px]=\"box.height\"\n [style.z-index]=\"ref._model.z() + 1\"\n aria-hidden=\"true\"\n ></div>\n}\n"
|
|
1133
802
|
}]
|
|
1134
803
|
}],
|
|
1135
804
|
ctorParameters: () => [],
|
|
@@ -1153,47 +822,444 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1153
822
|
* Use of this source code is governed by an MIT-style license that can be
|
|
1154
823
|
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
1155
824
|
*/
|
|
825
|
+
const MINIMIZED_HEIGHT = 40;
|
|
826
|
+
function num(value, fallback) {
|
|
827
|
+
return typeof value === "number" && !Number.isNaN(value) ? value : fallback;
|
|
828
|
+
}
|
|
829
|
+
const SIZE_PRESETS = {
|
|
830
|
+
sm: {
|
|
831
|
+
width: 320,
|
|
832
|
+
height: 200
|
|
833
|
+
},
|
|
834
|
+
md: {
|
|
835
|
+
width: 480,
|
|
836
|
+
height: 320
|
|
837
|
+
},
|
|
838
|
+
lg: {
|
|
839
|
+
width: 720,
|
|
840
|
+
height: 480
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
function resolveOptions(config) {
|
|
844
|
+
return {
|
|
845
|
+
os: config.os ?? "auto",
|
|
846
|
+
chromeSize: config.chromeSize ?? "md",
|
|
847
|
+
animations: config.animations ?? true,
|
|
848
|
+
minWidth: num(config.minWidth, 220),
|
|
849
|
+
minHeight: num(config.minHeight, 140),
|
|
850
|
+
maxWidth: num(config.maxWidth, Number.POSITIVE_INFINITY),
|
|
851
|
+
maxHeight: num(config.maxHeight, Number.POSITIVE_INFINITY),
|
|
852
|
+
movable: config.movable ?? true,
|
|
853
|
+
resizable: config.resizable ?? true,
|
|
854
|
+
keepInViewport: config.keepInViewport ?? true,
|
|
855
|
+
snap: config.snap ?? "none",
|
|
856
|
+
restoreOnDrag: config.restoreOnDrag ?? true,
|
|
857
|
+
dragHandle: config.dragHandle ?? null,
|
|
858
|
+
showMinimize: config.showMinimize ?? null,
|
|
859
|
+
showMaximize: config.showMaximize ?? null,
|
|
860
|
+
showClose: config.showClose ?? true,
|
|
861
|
+
closeOnEscape: config.closeOnEscape ?? true,
|
|
862
|
+
keyboard: config.keyboard ?? true,
|
|
863
|
+
keyboardStep: Math.max(1, num(config.keyboardStep, 10))
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
function readViewport() {
|
|
867
|
+
if (typeof window === "undefined" || typeof document === "undefined") return {
|
|
868
|
+
width: 1024,
|
|
869
|
+
height: 768
|
|
870
|
+
};
|
|
871
|
+
const root = document.documentElement;
|
|
872
|
+
return {
|
|
873
|
+
width: root.clientWidth || window.innerWidth,
|
|
874
|
+
height: root.clientHeight || window.innerHeight
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
function cascadeOffset(index) {
|
|
878
|
+
const step = 50 + index % 10 * 30;
|
|
879
|
+
return {
|
|
880
|
+
x: step + Math.floor(index / 10) % 5 * 15,
|
|
881
|
+
y: step
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
function seedGeometry(seed) {
|
|
885
|
+
const { options: o, workArea: wa } = seed;
|
|
886
|
+
const preset = SIZE_PRESETS[seed.size ?? "md"];
|
|
887
|
+
const keep = o.keepInViewport;
|
|
888
|
+
const fit = (size, room) => keep ? Math.min(size, room) : size;
|
|
889
|
+
const width = Math.round(clamp(fit(seed.width ?? preset.width, wa.width), o.minWidth, o.maxWidth));
|
|
890
|
+
const height = Math.round(clamp(fit(seed.height ?? preset.height, wa.height), o.minHeight, o.maxHeight));
|
|
891
|
+
let x = seed.x;
|
|
892
|
+
let y = seed.y;
|
|
893
|
+
let cascaded = false;
|
|
894
|
+
if (x == null || y == null) {
|
|
895
|
+
const offset = seed.cascade();
|
|
896
|
+
cascaded = true;
|
|
897
|
+
x ??= seed.rtl ? wa.left + wa.width - width - offset.x : wa.left + offset.x;
|
|
898
|
+
y ??= wa.top + offset.y;
|
|
899
|
+
}
|
|
900
|
+
const into = cascaded || !!seed.restored;
|
|
901
|
+
if (keep && (into || seed.x == null)) x = clamp(x, wa.left, Math.max(wa.left, wa.left + wa.width - width));
|
|
902
|
+
if (keep && (into || seed.y == null)) y = clamp(y, wa.top, Math.max(wa.top, wa.top + wa.height - height));
|
|
903
|
+
return {
|
|
904
|
+
x: Math.round(x),
|
|
905
|
+
y: Math.round(y),
|
|
906
|
+
width,
|
|
907
|
+
height
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
var WrWindowModel = class {
|
|
911
|
+
options;
|
|
912
|
+
title;
|
|
913
|
+
state;
|
|
914
|
+
snap;
|
|
915
|
+
x;
|
|
916
|
+
y;
|
|
917
|
+
width;
|
|
918
|
+
height;
|
|
919
|
+
z;
|
|
920
|
+
isActive = signal(false, ...ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []);
|
|
921
|
+
keyboardMode = signal(null, ...ngDevMode ? [{ debugName: "keyboardMode" }] : /* istanbul ignore next */ []);
|
|
922
|
+
dragTarget = signal(null, ...ngDevMode ? [{ debugName: "dragTarget" }] : /* istanbul ignore next */ []);
|
|
923
|
+
workArea;
|
|
924
|
+
moved = new Subject();
|
|
925
|
+
resized = new Subject();
|
|
926
|
+
stateChanges = new Subject();
|
|
927
|
+
element = null;
|
|
928
|
+
onMinimizedWithFocus = null;
|
|
929
|
+
restoreTo = "normal";
|
|
930
|
+
keyboardStart = null;
|
|
931
|
+
keyboardOrigin = null;
|
|
932
|
+
rect = computed(() => {
|
|
933
|
+
const state = this.state();
|
|
934
|
+
if (state === "maximized") return this.maximizedRect();
|
|
935
|
+
const raw = {
|
|
936
|
+
left: this.x(),
|
|
937
|
+
top: this.y(),
|
|
938
|
+
width: this.width(),
|
|
939
|
+
height: this.height()
|
|
940
|
+
};
|
|
941
|
+
if (state === "minimized") return {
|
|
942
|
+
...raw,
|
|
943
|
+
height: MINIMIZED_HEIGHT
|
|
944
|
+
};
|
|
945
|
+
const snap = this.snap();
|
|
946
|
+
return snap ? this.snapRect(snap) : raw;
|
|
947
|
+
}, ...ngDevMode ? [{ debugName: "rect" }] : /* istanbul ignore next */ []);
|
|
948
|
+
previewRect = computed(() => {
|
|
949
|
+
const target = this.dragTarget();
|
|
950
|
+
return target ? this.targetRect(target) : null;
|
|
951
|
+
}, ...ngDevMode ? [{ debugName: "previewRect" }] : /* istanbul ignore next */ []);
|
|
952
|
+
constructor(init) {
|
|
953
|
+
this.options = signal(init.options, ...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
|
|
954
|
+
this.title = signal(init.title ?? "", ...ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []);
|
|
955
|
+
this.state = signal(init.state ?? "normal", ...ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []);
|
|
956
|
+
this.snap = signal(init.snap && init.snap !== "top" ? init.snap : null, ...ngDevMode ? [{ debugName: "snap" }] : /* istanbul ignore next */ []);
|
|
957
|
+
const g = init.geometry ?? {
|
|
958
|
+
x: 0,
|
|
959
|
+
y: 0,
|
|
960
|
+
width: SIZE_PRESETS.md.width,
|
|
961
|
+
height: SIZE_PRESETS.md.height
|
|
962
|
+
};
|
|
963
|
+
this.x = signal(g.x, ...ngDevMode ? [{ debugName: "x" }] : /* istanbul ignore next */ []);
|
|
964
|
+
this.y = signal(g.y, ...ngDevMode ? [{ debugName: "y" }] : /* istanbul ignore next */ []);
|
|
965
|
+
this.width = signal(g.width, ...ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []);
|
|
966
|
+
this.height = signal(g.height, ...ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []);
|
|
967
|
+
this.z = signal(init.z ?? 0, ...ngDevMode ? [{ debugName: "z" }] : /* istanbul ignore next */ []);
|
|
968
|
+
this.workArea = init.workArea;
|
|
969
|
+
this.clamp();
|
|
970
|
+
}
|
|
971
|
+
setState(next) {
|
|
972
|
+
const current = this.state();
|
|
973
|
+
if (current === next) return;
|
|
974
|
+
if (next === "minimized") this.restoreTo = current === "maximized" ? "maximized" : "normal";
|
|
975
|
+
this.state.set(next);
|
|
976
|
+
this.stateChanges.next(next);
|
|
977
|
+
}
|
|
978
|
+
minimize() {
|
|
979
|
+
if (this.state() === "minimized") {
|
|
980
|
+
this.unminimize();
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
const hadFocus = this.hasFocus();
|
|
984
|
+
this.setState("minimized");
|
|
985
|
+
if (hadFocus) this.onMinimizedWithFocus?.();
|
|
986
|
+
}
|
|
987
|
+
unminimize() {
|
|
988
|
+
if (this.state() === "minimized") this.setState(this.restoreTo);
|
|
989
|
+
}
|
|
990
|
+
maximize() {
|
|
991
|
+
this.setState(this.state() === "maximized" ? "normal" : "maximized");
|
|
992
|
+
}
|
|
993
|
+
restore() {
|
|
994
|
+
this.snap.set(null);
|
|
995
|
+
this.setState("normal");
|
|
996
|
+
}
|
|
997
|
+
snapTo(target) {
|
|
998
|
+
if (target === "top") {
|
|
999
|
+
this.setState("maximized");
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
this.snap.set(target);
|
|
1003
|
+
this.setState("normal");
|
|
1004
|
+
}
|
|
1005
|
+
setRaw(g) {
|
|
1006
|
+
if (g.x !== void 0) this.x.set(Math.round(g.x));
|
|
1007
|
+
if (g.y !== void 0) this.y.set(Math.round(g.y));
|
|
1008
|
+
if (g.width !== void 0) this.width.set(Math.round(g.width));
|
|
1009
|
+
if (g.height !== void 0) this.height.set(Math.round(g.height));
|
|
1010
|
+
}
|
|
1011
|
+
unsnapInPlace() {
|
|
1012
|
+
if (!this.snap()) return;
|
|
1013
|
+
if (this.state() === "normal") {
|
|
1014
|
+
const r = this.rect();
|
|
1015
|
+
this.setRaw({
|
|
1016
|
+
x: r.left,
|
|
1017
|
+
y: r.top,
|
|
1018
|
+
width: r.width,
|
|
1019
|
+
height: r.height
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
this.snap.set(null);
|
|
1023
|
+
}
|
|
1024
|
+
moveTo(x, y) {
|
|
1025
|
+
this.unsnapInPlace();
|
|
1026
|
+
this.setRaw({
|
|
1027
|
+
x,
|
|
1028
|
+
y
|
|
1029
|
+
});
|
|
1030
|
+
this.clamp();
|
|
1031
|
+
}
|
|
1032
|
+
resizeTo(width, height) {
|
|
1033
|
+
this.unsnapInPlace();
|
|
1034
|
+
const o = this.options();
|
|
1035
|
+
this.setRaw({
|
|
1036
|
+
width: clamp(width, o.minWidth, o.maxWidth),
|
|
1037
|
+
height: clamp(height, o.minHeight, o.maxHeight)
|
|
1038
|
+
});
|
|
1039
|
+
this.clamp();
|
|
1040
|
+
}
|
|
1041
|
+
center() {
|
|
1042
|
+
this.unsnapInPlace();
|
|
1043
|
+
const wa = this.workArea();
|
|
1044
|
+
this.setRaw({
|
|
1045
|
+
x: wa.left + Math.max(0, (wa.width - this.width()) / 2),
|
|
1046
|
+
y: wa.top + Math.max(0, (wa.height - this.height()) / 2)
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
clamp() {
|
|
1050
|
+
if (!this.options().keepInViewport) return;
|
|
1051
|
+
const wa = this.workArea();
|
|
1052
|
+
const w = this.width();
|
|
1053
|
+
this.x.set(Math.round(clamp(this.x(), wa.left + 24 - w, wa.left + wa.width - 24)));
|
|
1054
|
+
this.y.set(Math.round(clamp(this.y(), wa.top, wa.top + wa.height - 24)));
|
|
1055
|
+
}
|
|
1056
|
+
update(patch) {
|
|
1057
|
+
const { title, ...rest } = patch;
|
|
1058
|
+
if (title !== void 0) this.title.set(title);
|
|
1059
|
+
const defined = {};
|
|
1060
|
+
for (const [key, value] of Object.entries(rest)) if (value !== void 0) defined[key] = value;
|
|
1061
|
+
if (Object.keys(defined).length === 0) return;
|
|
1062
|
+
this.options.update((o) => ({
|
|
1063
|
+
...o,
|
|
1064
|
+
...defined
|
|
1065
|
+
}));
|
|
1066
|
+
if ([
|
|
1067
|
+
"minWidth",
|
|
1068
|
+
"minHeight",
|
|
1069
|
+
"maxWidth",
|
|
1070
|
+
"maxHeight"
|
|
1071
|
+
].some((key) => key in defined)) {
|
|
1072
|
+
const o = this.options();
|
|
1073
|
+
this.setRaw({
|
|
1074
|
+
width: clamp(this.width(), o.minWidth, o.maxWidth),
|
|
1075
|
+
height: clamp(this.height(), o.minHeight, o.maxHeight)
|
|
1076
|
+
});
|
|
1077
|
+
this.clamp();
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
maximizedRect() {
|
|
1081
|
+
const wa = this.workArea();
|
|
1082
|
+
const o = this.options();
|
|
1083
|
+
const width = Math.min(wa.width, o.maxWidth);
|
|
1084
|
+
const height = Math.min(wa.height, o.maxHeight);
|
|
1085
|
+
return {
|
|
1086
|
+
left: wa.left + Math.round((wa.width - width) / 2),
|
|
1087
|
+
top: wa.top + Math.round((wa.height - height) / 2),
|
|
1088
|
+
width,
|
|
1089
|
+
height
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
snapRect(target) {
|
|
1093
|
+
const wa = this.workArea();
|
|
1094
|
+
const o = this.options();
|
|
1095
|
+
const halfW = Math.floor(wa.width / 2);
|
|
1096
|
+
const halfH = Math.floor(wa.height / 2);
|
|
1097
|
+
const right = target === "right" || target === "top-right" || target === "bottom-right";
|
|
1098
|
+
const bottom = target === "bottom-left" || target === "bottom-right";
|
|
1099
|
+
const quarter = target !== "left" && target !== "right";
|
|
1100
|
+
const regionW = right ? wa.width - halfW : halfW;
|
|
1101
|
+
const regionH = quarter ? bottom ? wa.height - halfH : halfH : wa.height;
|
|
1102
|
+
const regionL = wa.left + (right ? halfW : 0);
|
|
1103
|
+
const regionT = wa.top + (bottom ? halfH : 0);
|
|
1104
|
+
const width = clamp(regionW, o.minWidth, o.maxWidth);
|
|
1105
|
+
const height = clamp(regionH, o.minHeight, o.maxHeight);
|
|
1106
|
+
const left = right ? regionL + regionW - width : regionL;
|
|
1107
|
+
const top = bottom ? regionT + regionH - height : regionT;
|
|
1108
|
+
return {
|
|
1109
|
+
left: clamp(left, wa.left, Math.max(wa.left, wa.left + wa.width - width)),
|
|
1110
|
+
top: clamp(top, wa.top, Math.max(wa.top, wa.top + wa.height - height)),
|
|
1111
|
+
width,
|
|
1112
|
+
height
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
targetRect(target) {
|
|
1116
|
+
return target === "top" ? this.maximizedRect() : this.snapRect(target);
|
|
1117
|
+
}
|
|
1118
|
+
startKeyboard(mode) {
|
|
1119
|
+
const o = this.options();
|
|
1120
|
+
if (!o.keyboard || this.state() === "minimized") return false;
|
|
1121
|
+
if (mode === "move" ? !o.movable : !o.resizable) return false;
|
|
1122
|
+
this.keyboardOrigin = {
|
|
1123
|
+
geometry: {
|
|
1124
|
+
x: this.x(),
|
|
1125
|
+
y: this.y(),
|
|
1126
|
+
width: this.width(),
|
|
1127
|
+
height: this.height()
|
|
1128
|
+
},
|
|
1129
|
+
state: this.state(),
|
|
1130
|
+
snap: this.snap()
|
|
1131
|
+
};
|
|
1132
|
+
if (this.state() === "maximized") this.setState("normal");
|
|
1133
|
+
this.unsnapInPlace();
|
|
1134
|
+
this.keyboardStart = {
|
|
1135
|
+
x: this.x(),
|
|
1136
|
+
y: this.y(),
|
|
1137
|
+
width: this.width(),
|
|
1138
|
+
height: this.height()
|
|
1139
|
+
};
|
|
1140
|
+
this.keyboardMode.set(mode);
|
|
1141
|
+
return true;
|
|
1142
|
+
}
|
|
1143
|
+
nudge(dx, dy) {
|
|
1144
|
+
this.setRaw({
|
|
1145
|
+
x: this.x() + dx,
|
|
1146
|
+
y: this.y() + dy
|
|
1147
|
+
});
|
|
1148
|
+
this.clamp();
|
|
1149
|
+
}
|
|
1150
|
+
grow(dw, dh, rtl) {
|
|
1151
|
+
const o = this.options();
|
|
1152
|
+
const width = clamp(this.width() + dw, o.minWidth, o.maxWidth);
|
|
1153
|
+
const height = clamp(this.height() + dh, o.minHeight, o.maxHeight);
|
|
1154
|
+
const x = rtl ? this.x() - (width - this.width()) : this.x();
|
|
1155
|
+
this.setRaw({
|
|
1156
|
+
x,
|
|
1157
|
+
width,
|
|
1158
|
+
height
|
|
1159
|
+
});
|
|
1160
|
+
this.clamp();
|
|
1161
|
+
}
|
|
1162
|
+
commitKeyboard() {
|
|
1163
|
+
const mode = this.keyboardMode();
|
|
1164
|
+
if (!mode) return null;
|
|
1165
|
+
this.keyboardMode.set(null);
|
|
1166
|
+
const start = this.keyboardStart;
|
|
1167
|
+
this.keyboardStart = null;
|
|
1168
|
+
this.keyboardOrigin = null;
|
|
1169
|
+
if (mode === "move" && (start?.x !== this.x() || start?.y !== this.y())) this.moved.next({
|
|
1170
|
+
x: this.x(),
|
|
1171
|
+
y: this.y()
|
|
1172
|
+
});
|
|
1173
|
+
if (mode === "resize" && (start?.width !== this.width() || start?.height !== this.height())) this.resized.next({
|
|
1174
|
+
width: this.width(),
|
|
1175
|
+
height: this.height()
|
|
1176
|
+
});
|
|
1177
|
+
return mode;
|
|
1178
|
+
}
|
|
1179
|
+
cancelKeyboard() {
|
|
1180
|
+
const mode = this.keyboardMode();
|
|
1181
|
+
if (!mode) return null;
|
|
1182
|
+
const origin = this.keyboardOrigin;
|
|
1183
|
+
this.keyboardStart = null;
|
|
1184
|
+
this.keyboardOrigin = null;
|
|
1185
|
+
this.keyboardMode.set(null);
|
|
1186
|
+
if (origin) {
|
|
1187
|
+
this.setRaw(origin.geometry);
|
|
1188
|
+
this.snap.set(origin.snap);
|
|
1189
|
+
this.setState(origin.state);
|
|
1190
|
+
}
|
|
1191
|
+
return mode;
|
|
1192
|
+
}
|
|
1193
|
+
hasFocus() {
|
|
1194
|
+
const el = this.element;
|
|
1195
|
+
return !!el && el.contains(el.ownerDocument.activeElement);
|
|
1196
|
+
}
|
|
1197
|
+
complete() {
|
|
1198
|
+
this.moved.complete();
|
|
1199
|
+
this.resized.complete();
|
|
1200
|
+
this.stateChanges.complete();
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
/**
|
|
1204
|
+
* @license
|
|
1205
|
+
*
|
|
1206
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1207
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
1208
|
+
*/
|
|
1156
1209
|
var WrWindowRef = class {
|
|
1157
1210
|
_overlayRef;
|
|
1158
1211
|
id;
|
|
1159
1212
|
_closed = new ReplaySubject(1);
|
|
1160
|
-
|
|
1213
|
+
_model;
|
|
1214
|
+
_stateChanged;
|
|
1161
1215
|
componentRef = null;
|
|
1162
1216
|
taskbarVisible = true;
|
|
1163
|
-
|
|
1164
|
-
_state = signal("normal", ...ngDevMode ? [{ debugName: "_state" }] : /* istanbul ignore next */ []);
|
|
1165
|
-
_x = signal(0, ...ngDevMode ? [{ debugName: "_x" }] : /* istanbul ignore next */ []);
|
|
1166
|
-
_y = signal(0, ...ngDevMode ? [{ debugName: "_y" }] : /* istanbul ignore next */ []);
|
|
1167
|
-
_width = signal(0, ...ngDevMode ? [{ debugName: "_width" }] : /* istanbul ignore next */ []);
|
|
1168
|
-
_height = signal(0, ...ngDevMode ? [{ debugName: "_height" }] : /* istanbul ignore next */ []);
|
|
1169
|
-
_z = signal(0, ...ngDevMode ? [{ debugName: "_z" }] : /* istanbul ignore next */ []);
|
|
1170
|
-
_rawX = signal(0, ...ngDevMode ? [{ debugName: "_rawX" }] : /* istanbul ignore next */ []);
|
|
1171
|
-
_rawY = signal(0, ...ngDevMode ? [{ debugName: "_rawY" }] : /* istanbul ignore next */ []);
|
|
1172
|
-
_rawWidth = signal(0, ...ngDevMode ? [{ debugName: "_rawWidth" }] : /* istanbul ignore next */ []);
|
|
1173
|
-
_rawHeight = signal(0, ...ngDevMode ? [{ debugName: "_rawHeight" }] : /* istanbul ignore next */ []);
|
|
1174
|
-
_title = signal("", ...ngDevMode ? [{ debugName: "_title" }] : /* istanbul ignore next */ []);
|
|
1175
|
-
state = this._state.asReadonly();
|
|
1176
|
-
x = this._x.asReadonly();
|
|
1177
|
-
y = this._y.asReadonly();
|
|
1178
|
-
width = this._width.asReadonly();
|
|
1179
|
-
height = this._height.asReadonly();
|
|
1180
|
-
z = this._z.asReadonly();
|
|
1181
|
-
title = this._title.asReadonly();
|
|
1182
|
-
_beforeCloseHook = null;
|
|
1217
|
+
_host = null;
|
|
1183
1218
|
_doClose = null;
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
_doFocus = null;
|
|
1188
|
-
_doMoveTo = null;
|
|
1189
|
-
_doResizeTo = null;
|
|
1190
|
-
_doCenter = null;
|
|
1191
|
-
_doSetTitle = null;
|
|
1192
|
-
_doFocusInitial = null;
|
|
1219
|
+
_focusWindow = null;
|
|
1220
|
+
_startKeyboard = null;
|
|
1221
|
+
_pendingKeyboard = null;
|
|
1193
1222
|
_returnFocus = null;
|
|
1194
|
-
|
|
1223
|
+
state;
|
|
1224
|
+
x;
|
|
1225
|
+
y;
|
|
1226
|
+
width;
|
|
1227
|
+
height;
|
|
1228
|
+
z;
|
|
1229
|
+
title;
|
|
1230
|
+
snap;
|
|
1231
|
+
isActive;
|
|
1232
|
+
closed;
|
|
1233
|
+
moved;
|
|
1234
|
+
resized;
|
|
1235
|
+
stateChanges;
|
|
1236
|
+
_beforeCloseHook = null;
|
|
1237
|
+
constructor(id, _overlayRef, model) {
|
|
1195
1238
|
this._overlayRef = _overlayRef;
|
|
1196
1239
|
this.id = id;
|
|
1240
|
+
const m = model ?? new WrWindowModel({
|
|
1241
|
+
options: resolveOptions({}),
|
|
1242
|
+
workArea: signal({
|
|
1243
|
+
left: 0,
|
|
1244
|
+
top: 0,
|
|
1245
|
+
...readViewport()
|
|
1246
|
+
})
|
|
1247
|
+
});
|
|
1248
|
+
this._model = m;
|
|
1249
|
+
this._stateChanged = m.stateChanges;
|
|
1250
|
+
this.state = m.state.asReadonly();
|
|
1251
|
+
this.x = computed(() => m.rect().left, ...ngDevMode ? [{ debugName: "x" }] : /* istanbul ignore next */ []);
|
|
1252
|
+
this.y = computed(() => m.rect().top, ...ngDevMode ? [{ debugName: "y" }] : /* istanbul ignore next */ []);
|
|
1253
|
+
this.width = computed(() => m.rect().width, ...ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []);
|
|
1254
|
+
this.height = computed(() => m.rect().height, ...ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []);
|
|
1255
|
+
this.z = m.z.asReadonly();
|
|
1256
|
+
this.title = m.title.asReadonly();
|
|
1257
|
+
this.snap = m.snap.asReadonly();
|
|
1258
|
+
this.isActive = m.isActive.asReadonly();
|
|
1259
|
+
this.closed = this._closed.asObservable();
|
|
1260
|
+
this.moved = m.moved.asObservable();
|
|
1261
|
+
this.resized = m.resized.asObservable();
|
|
1262
|
+
this.stateChanges = m.stateChanges.asObservable();
|
|
1197
1263
|
}
|
|
1198
1264
|
get componentInstance() {
|
|
1199
1265
|
if (!this.componentRef) throw new Error("WrWindowRef: component not yet attached");
|
|
@@ -1212,28 +1278,48 @@ var WrWindowRef = class {
|
|
|
1212
1278
|
if (proceed) this._doClose?.(result);
|
|
1213
1279
|
}
|
|
1214
1280
|
minimize() {
|
|
1215
|
-
this.
|
|
1281
|
+
this._model.minimize();
|
|
1216
1282
|
}
|
|
1217
1283
|
maximize() {
|
|
1218
|
-
this.
|
|
1284
|
+
this._model.maximize();
|
|
1219
1285
|
}
|
|
1220
1286
|
restore() {
|
|
1221
|
-
this.
|
|
1287
|
+
this._model.restore();
|
|
1222
1288
|
}
|
|
1223
1289
|
focus() {
|
|
1224
|
-
this.
|
|
1290
|
+
this._host?._raise(this);
|
|
1291
|
+
}
|
|
1292
|
+
activate() {
|
|
1293
|
+
if (this._host) this._host._activate(this);
|
|
1294
|
+
else this._model.unminimize();
|
|
1225
1295
|
}
|
|
1226
1296
|
moveTo(x, y) {
|
|
1227
|
-
this.
|
|
1297
|
+
this._model.moveTo(x, y);
|
|
1228
1298
|
}
|
|
1229
1299
|
resizeTo(width, height) {
|
|
1230
|
-
this.
|
|
1300
|
+
this._model.resizeTo(width, height);
|
|
1231
1301
|
}
|
|
1232
1302
|
center() {
|
|
1233
|
-
this.
|
|
1303
|
+
this._model.center();
|
|
1304
|
+
}
|
|
1305
|
+
snapTo(target) {
|
|
1306
|
+
this._model.snapTo(target);
|
|
1234
1307
|
}
|
|
1235
1308
|
setTitle(title) {
|
|
1236
|
-
this.
|
|
1309
|
+
this._model.title.set(title);
|
|
1310
|
+
}
|
|
1311
|
+
update(patch) {
|
|
1312
|
+
this._model.update(patch);
|
|
1313
|
+
}
|
|
1314
|
+
startMove() {
|
|
1315
|
+
this.startKeyboard("move");
|
|
1316
|
+
}
|
|
1317
|
+
startResize() {
|
|
1318
|
+
this.startKeyboard("resize");
|
|
1319
|
+
}
|
|
1320
|
+
startKeyboard(mode) {
|
|
1321
|
+
if (this._startKeyboard) this._startKeyboard(mode);
|
|
1322
|
+
else this._pendingKeyboard = mode;
|
|
1237
1323
|
}
|
|
1238
1324
|
beforeClose(hook) {
|
|
1239
1325
|
this._beforeCloseHook = hook;
|
|
@@ -1246,6 +1332,9 @@ var WrWindowRef = class {
|
|
|
1246
1332
|
});
|
|
1247
1333
|
});
|
|
1248
1334
|
}
|
|
1335
|
+
awaitClose() {
|
|
1336
|
+
return this.afterClosed();
|
|
1337
|
+
}
|
|
1249
1338
|
get overlayRef() {
|
|
1250
1339
|
return this._overlayRef;
|
|
1251
1340
|
}
|
|
@@ -1256,58 +1345,111 @@ var WrWindowRef = class {
|
|
|
1256
1345
|
* Use of this source code is governed by an MIT-style license that can be
|
|
1257
1346
|
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
1258
1347
|
*/
|
|
1348
|
+
const NO_RESERVE$1 = {
|
|
1349
|
+
top: 0,
|
|
1350
|
+
bottom: 0
|
|
1351
|
+
};
|
|
1352
|
+
function sameRect(a, b) {
|
|
1353
|
+
return a.left === b.left && a.top === b.top && a.width === b.width && a.height === b.height;
|
|
1354
|
+
}
|
|
1259
1355
|
var WrWindowManager = class WrWindowManager {
|
|
1260
1356
|
overlay = inject(WR_OVERLAY);
|
|
1261
1357
|
parentInjector = inject(EnvironmentInjector);
|
|
1262
1358
|
storage = inject(WrStorage);
|
|
1263
1359
|
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
1264
1360
|
dir = inject(Directionality, { optional: true });
|
|
1361
|
+
defaults = inject(WR_WINDOW_DEFAULTS, { optional: true });
|
|
1362
|
+
destroyRef = inject(DestroyRef);
|
|
1265
1363
|
baseZ = 1e3;
|
|
1266
1364
|
topZ = this.baseZ;
|
|
1267
1365
|
openCount = 0;
|
|
1268
1366
|
_windows = signal([], ...ngDevMode ? [{ debugName: "_windows" }] : /* istanbul ignore next */ []);
|
|
1367
|
+
_active = signal(null, ...ngDevMode ? [{ debugName: "_active" }] : /* istanbul ignore next */ []);
|
|
1269
1368
|
pendingRestores = /* @__PURE__ */ new Map();
|
|
1270
|
-
taskbars = /*
|
|
1369
|
+
taskbars = signal([], ...ngDevMode ? [{ debugName: "taskbars" }] : /* istanbul ignore next */ []);
|
|
1370
|
+
viewport = signal(readViewport(), {
|
|
1371
|
+
...ngDevMode ? { debugName: "viewport" } : /* istanbul ignore next */ {},
|
|
1372
|
+
equal: (a, b) => a.width === b.width && a.height === b.height
|
|
1373
|
+
});
|
|
1374
|
+
layoutTick = signal(0, ...ngDevMode ? [{ debugName: "layoutTick" }] : /* istanbul ignore next */ []);
|
|
1375
|
+
listening = false;
|
|
1376
|
+
boundsObserver = null;
|
|
1377
|
+
boundElements = /* @__PURE__ */ new Map();
|
|
1378
|
+
bumpLayout = () => this.layoutTick.update((n) => n + 1);
|
|
1379
|
+
reserve = computed(() => {
|
|
1380
|
+
let top = 0;
|
|
1381
|
+
let bottom = 0;
|
|
1382
|
+
for (const taskbar of this.taskbars()) {
|
|
1383
|
+
const r = taskbar.reserve();
|
|
1384
|
+
top = Math.max(top, r.top);
|
|
1385
|
+
bottom = Math.max(bottom, r.bottom);
|
|
1386
|
+
}
|
|
1387
|
+
return top === 0 && bottom === 0 ? NO_RESERVE$1 : {
|
|
1388
|
+
top,
|
|
1389
|
+
bottom
|
|
1390
|
+
};
|
|
1391
|
+
}, ...ngDevMode ? [{ debugName: "reserve" }] : /* istanbul ignore next */ []);
|
|
1271
1392
|
windows = this._windows.asReadonly();
|
|
1393
|
+
active = this._active.asReadonly();
|
|
1272
1394
|
minimized = computed(() => this._windows().filter((w) => w.taskbarVisible && w.state() === "minimized"), ...ngDevMode ? [{ debugName: "minimized" }] : /* istanbul ignore next */ []);
|
|
1273
1395
|
bringToFront() {
|
|
1274
1396
|
this.topZ += 1;
|
|
1275
1397
|
return this.topZ;
|
|
1276
1398
|
}
|
|
1277
1399
|
nextStartOffset() {
|
|
1278
|
-
const offset = this.openCount
|
|
1400
|
+
const offset = cascadeOffset(this.openCount);
|
|
1279
1401
|
this.openCount += 1;
|
|
1280
|
-
return
|
|
1281
|
-
x: 50 + offset,
|
|
1282
|
-
y: 50 + offset
|
|
1283
|
-
};
|
|
1402
|
+
return offset;
|
|
1284
1403
|
}
|
|
1285
1404
|
open(component, config = {}) {
|
|
1286
1405
|
const opener = this.focusedElement();
|
|
1287
1406
|
if (config.id) {
|
|
1288
1407
|
const existing = this.findById(config.id);
|
|
1289
1408
|
if (existing) {
|
|
1290
|
-
existing.restore();
|
|
1291
|
-
existing.focus();
|
|
1292
1409
|
if (config.autoFocus !== false) {
|
|
1293
1410
|
if (opener && !existing._overlayRef.overlayElement?.contains(opener)) existing._returnFocus = opener;
|
|
1294
|
-
|
|
1411
|
+
this._activate(existing);
|
|
1412
|
+
} else {
|
|
1413
|
+
existing._model.unminimize();
|
|
1414
|
+
this._raise(existing);
|
|
1295
1415
|
}
|
|
1296
1416
|
return existing;
|
|
1297
1417
|
}
|
|
1298
1418
|
}
|
|
1299
1419
|
const pending = config.id ? this.pendingRestores.get(config.id) : void 0;
|
|
1300
|
-
if (pending)
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1420
|
+
if (pending) this.pendingRestores.delete(config.id);
|
|
1421
|
+
this.listen();
|
|
1422
|
+
const options = resolveOptions(config);
|
|
1423
|
+
const bounds = this.boundsElement(config.bounds ?? this.defaults?.bounds);
|
|
1424
|
+
const workArea = this.workAreaFor(config.bounds ?? this.defaults?.bounds, bounds);
|
|
1425
|
+
const releaseBounds = bounds ? this.observeBounds(bounds) : null;
|
|
1426
|
+
const saved = !pending && config.storage ? this.storage.get(storageKey(config.storage)) : null;
|
|
1427
|
+
const persist = config.storage?.persist ?? "all";
|
|
1428
|
+
const isNum = (v) => typeof v === "number" && !Number.isNaN(v);
|
|
1429
|
+
const savedPos = saved && persist !== "size" && isNum(saved.x) && isNum(saved.y) ? saved : null;
|
|
1430
|
+
const savedSize = saved && persist !== "position" && isNum(saved.width) && isNum(saved.height) ? saved : null;
|
|
1431
|
+
const geometry = untracked(() => seedGeometry({
|
|
1432
|
+
options,
|
|
1433
|
+
workArea: workArea(),
|
|
1434
|
+
size: config.size,
|
|
1435
|
+
x: pending?.x ?? savedPos?.x ?? config.x,
|
|
1436
|
+
y: pending?.y ?? savedPos?.y ?? config.y,
|
|
1437
|
+
width: pending?.width ?? savedSize?.width ?? config.width,
|
|
1438
|
+
height: pending?.height ?? savedSize?.height ?? config.height,
|
|
1439
|
+
restored: !!pending || !!savedPos,
|
|
1440
|
+
cascade: () => this.nextStartOffset(),
|
|
1441
|
+
rtl: this.dir?.value === "rtl"
|
|
1442
|
+
}));
|
|
1443
|
+
const taskbarOptIn = config.taskbar !== false;
|
|
1444
|
+
const model = new WrWindowModel({
|
|
1445
|
+
options,
|
|
1446
|
+
title: [pending?.title, config.title].find((t) => !!t) ?? "",
|
|
1447
|
+
geometry,
|
|
1448
|
+
state: pending?.state,
|
|
1449
|
+
snap: pending?.snap ?? null,
|
|
1450
|
+
z: this.bringToFront(),
|
|
1451
|
+
workArea
|
|
1452
|
+
});
|
|
1311
1453
|
let self = null;
|
|
1312
1454
|
const overlayRef = this.overlay.create({
|
|
1313
1455
|
positionStrategy: this.overlay.position().global(),
|
|
@@ -1316,10 +1458,16 @@ var WrWindowManager = class WrWindowManager {
|
|
|
1316
1458
|
eventPredicate: () => self === null || this.ownsKeyboard(self),
|
|
1317
1459
|
usePopover: false
|
|
1318
1460
|
});
|
|
1461
|
+
overlayRef.hostElement.style.zIndex = String(model.z());
|
|
1319
1462
|
wrFollowDirection(overlayRef, this.dir, this.parentInjector);
|
|
1320
|
-
const ref = new WrWindowRef(config.id ?? randomId("wr-window"), overlayRef);
|
|
1321
|
-
|
|
1322
|
-
|
|
1463
|
+
const ref = new WrWindowRef(config.id ?? randomId("wr-window"), overlayRef, model);
|
|
1464
|
+
const any = ref;
|
|
1465
|
+
self = any;
|
|
1466
|
+
ref._host = this;
|
|
1467
|
+
ref.taskbarVisible = taskbarOptIn;
|
|
1468
|
+
model.stateChanges.subscribe((state) => {
|
|
1469
|
+
if (state === "minimized" && this._active() === any) this.setActive(null);
|
|
1470
|
+
});
|
|
1323
1471
|
const childInjector = Injector.create({
|
|
1324
1472
|
parent: this.parentInjector,
|
|
1325
1473
|
providers: [{
|
|
@@ -1338,47 +1486,172 @@ var WrWindowManager = class WrWindowManager {
|
|
|
1338
1486
|
container.childInjector = childInjector;
|
|
1339
1487
|
container.autoFocus = config.autoFocus ?? !pending;
|
|
1340
1488
|
ref._returnFocus = opener;
|
|
1341
|
-
|
|
1342
|
-
if (event.key
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
}
|
|
1489
|
+
overlayRef.keydownEvents().subscribe((event) => {
|
|
1490
|
+
if (event.key !== "Escape" || event.defaultPrevented || !model.options().closeOnEscape) return;
|
|
1491
|
+
event.preventDefault();
|
|
1492
|
+
ref.close();
|
|
1346
1493
|
});
|
|
1347
1494
|
ref._doClose = (result) => {
|
|
1348
|
-
const back = this.holdsFocus(
|
|
1495
|
+
const back = this.holdsFocus(any) ? ref._returnFocus : null;
|
|
1349
1496
|
ref._returnFocus = null;
|
|
1350
1497
|
overlayRef.dispose();
|
|
1498
|
+
releaseBounds?.();
|
|
1351
1499
|
ref._closed.next(result);
|
|
1352
1500
|
ref._closed.complete();
|
|
1353
|
-
|
|
1501
|
+
model.complete();
|
|
1502
|
+
this._windows.update((list) => list.filter((r) => r !== any));
|
|
1503
|
+
if (this._active() === any) this.setActive(null);
|
|
1354
1504
|
if (back?.isConnected) back.focus();
|
|
1355
1505
|
};
|
|
1356
|
-
this._windows.update((list) => [...list,
|
|
1357
|
-
if (pending && pending.state !== "normal") ref.pendingStateOnMount = pending.state;
|
|
1506
|
+
this._windows.update((list) => [...list, any]);
|
|
1358
1507
|
return ref;
|
|
1359
1508
|
}
|
|
1509
|
+
_activate(ref, options = {}) {
|
|
1510
|
+
if (!this._windows().includes(ref)) return;
|
|
1511
|
+
ref._model.unminimize();
|
|
1512
|
+
this._raise(ref);
|
|
1513
|
+
this.setActive(ref);
|
|
1514
|
+
if (options.focus !== false && !ref._model.hasFocus()) ref._focusWindow?.("last");
|
|
1515
|
+
}
|
|
1516
|
+
_raise(ref) {
|
|
1517
|
+
if (ref.z() >= this.topZ) return;
|
|
1518
|
+
const z = this.bringToFront();
|
|
1519
|
+
ref._model.z.set(z);
|
|
1520
|
+
const host = ref._overlayRef.hostElement;
|
|
1521
|
+
if (host) host.style.zIndex = String(z);
|
|
1522
|
+
}
|
|
1523
|
+
setActive(ref) {
|
|
1524
|
+
const previous = this._active();
|
|
1525
|
+
if (previous === ref) return;
|
|
1526
|
+
previous?._model.isActive.set(false);
|
|
1527
|
+
ref?._model.isActive.set(true);
|
|
1528
|
+
this._active.set(ref);
|
|
1529
|
+
}
|
|
1530
|
+
onFocusIn = (event) => {
|
|
1531
|
+
const target = event.target;
|
|
1532
|
+
if (!(target instanceof Node)) return;
|
|
1533
|
+
const ref = this._windows().find((w) => w._overlayRef.overlayElement?.contains(target));
|
|
1534
|
+
if (ref) {
|
|
1535
|
+
this._raise(ref);
|
|
1536
|
+
this.setActive(ref);
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
if (this.taskbars().some((t) => t.contains(target))) return;
|
|
1540
|
+
if (target instanceof Element && target.closest(".wr-overlay-container, .cdk-overlay-container")) return;
|
|
1541
|
+
this.setActive(null);
|
|
1542
|
+
};
|
|
1543
|
+
listen() {
|
|
1544
|
+
if (this.listening || !this.isBrowser) return;
|
|
1545
|
+
this.listening = true;
|
|
1546
|
+
const measure = () => this.viewport.set(readViewport());
|
|
1547
|
+
measure();
|
|
1548
|
+
window.addEventListener("resize", measure, { passive: true });
|
|
1549
|
+
document.addEventListener("focusin", this.onFocusIn, true);
|
|
1550
|
+
this.destroyRef.onDestroy(() => {
|
|
1551
|
+
window.removeEventListener("resize", measure);
|
|
1552
|
+
document.removeEventListener("focusin", this.onFocusIn, true);
|
|
1553
|
+
document.removeEventListener("scroll", this.bumpLayout, true);
|
|
1554
|
+
this.boundsObserver?.disconnect();
|
|
1555
|
+
});
|
|
1556
|
+
}
|
|
1557
|
+
boundsElement(bounds) {
|
|
1558
|
+
if (!bounds || bounds === "viewport") return null;
|
|
1559
|
+
if (bounds instanceof ElementRef) return bounds.nativeElement;
|
|
1560
|
+
return typeof bounds.getBoundingClientRect === "function" ? bounds : null;
|
|
1561
|
+
}
|
|
1562
|
+
workAreaFor(bounds, element) {
|
|
1563
|
+
const insets = !element && bounds && bounds !== "viewport" ? bounds : null;
|
|
1564
|
+
return computed(() => {
|
|
1565
|
+
const vp = this.viewport();
|
|
1566
|
+
const reserve = this.reserve();
|
|
1567
|
+
let left = 0;
|
|
1568
|
+
let top = 0;
|
|
1569
|
+
let right = vp.width;
|
|
1570
|
+
let bottom = vp.height;
|
|
1571
|
+
if (element && this.isBrowser) {
|
|
1572
|
+
this.layoutTick();
|
|
1573
|
+
const r = element.getBoundingClientRect();
|
|
1574
|
+
left = Math.max(0, r.left);
|
|
1575
|
+
top = Math.max(0, r.top);
|
|
1576
|
+
right = Math.min(vp.width, r.right);
|
|
1577
|
+
bottom = Math.min(vp.height, r.bottom);
|
|
1578
|
+
} else if (insets) {
|
|
1579
|
+
left = insets.left ?? 0;
|
|
1580
|
+
top = insets.top ?? 0;
|
|
1581
|
+
right = vp.width - (insets.right ?? 0);
|
|
1582
|
+
bottom = vp.height - (insets.bottom ?? 0);
|
|
1583
|
+
}
|
|
1584
|
+
top = Math.max(top, reserve.top);
|
|
1585
|
+
bottom = Math.min(bottom, vp.height - reserve.bottom);
|
|
1586
|
+
return {
|
|
1587
|
+
left: Math.round(left),
|
|
1588
|
+
top: Math.round(top),
|
|
1589
|
+
width: Math.max(0, Math.round(right - left)),
|
|
1590
|
+
height: Math.max(0, Math.round(bottom - top))
|
|
1591
|
+
};
|
|
1592
|
+
}, { equal: sameRect });
|
|
1593
|
+
}
|
|
1594
|
+
observeBounds(element) {
|
|
1595
|
+
if (!this.isBrowser) return () => void 0;
|
|
1596
|
+
const count = this.boundElements.get(element) ?? 0;
|
|
1597
|
+
this.boundElements.set(element, count + 1);
|
|
1598
|
+
if (count === 0) {
|
|
1599
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
1600
|
+
this.boundsObserver ??= new ResizeObserver(this.bumpLayout);
|
|
1601
|
+
this.boundsObserver.observe(element);
|
|
1602
|
+
}
|
|
1603
|
+
if (this.boundElements.size === 1) document.addEventListener("scroll", this.bumpLayout, {
|
|
1604
|
+
capture: true,
|
|
1605
|
+
passive: true
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
let released = false;
|
|
1609
|
+
return () => {
|
|
1610
|
+
if (released) return;
|
|
1611
|
+
released = true;
|
|
1612
|
+
const left = (this.boundElements.get(element) ?? 1) - 1;
|
|
1613
|
+
if (left > 0) {
|
|
1614
|
+
this.boundElements.set(element, left);
|
|
1615
|
+
return;
|
|
1616
|
+
}
|
|
1617
|
+
this.boundElements.delete(element);
|
|
1618
|
+
this.boundsObserver?.unobserve(element);
|
|
1619
|
+
if (this.boundElements.size === 0) document.removeEventListener("scroll", this.bumpLayout, true);
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1360
1622
|
ownsKeyboard(ref) {
|
|
1623
|
+
if (!this.isBrowser) return false;
|
|
1361
1624
|
const open = this._windows();
|
|
1362
|
-
const active =
|
|
1625
|
+
const active = document.activeElement;
|
|
1363
1626
|
const focused = active ? open.find((w) => w._overlayRef.overlayElement?.contains(active)) : void 0;
|
|
1364
1627
|
if (focused) return focused === ref;
|
|
1365
|
-
if (active &&
|
|
1366
|
-
|
|
1367
|
-
|
|
1628
|
+
if (active && active !== document.body) return false;
|
|
1629
|
+
const current = this._active();
|
|
1630
|
+
if (current && current.state() !== "minimized") return current === ref;
|
|
1631
|
+
let front = null;
|
|
1632
|
+
for (const w of open) if (w.state() !== "minimized" && (!front || w.z() > front.z())) front = w;
|
|
1633
|
+
return front === ref;
|
|
1368
1634
|
}
|
|
1369
1635
|
_registerTaskbar(taskbar) {
|
|
1370
|
-
this.taskbars.
|
|
1371
|
-
return () => this.taskbars.
|
|
1636
|
+
this.taskbars.update((list) => [...list, taskbar]);
|
|
1637
|
+
return () => this.taskbars.update((list) => list.filter((t) => t !== taskbar));
|
|
1372
1638
|
}
|
|
1373
|
-
_focusAfterMinimize(ref) {
|
|
1374
|
-
|
|
1639
|
+
_focusAfterMinimize(ref, attempt = 0) {
|
|
1640
|
+
if (attempt < 3 && this.taskbars().some((taskbar) => taskbar.settling(ref))) {
|
|
1641
|
+
const active = this.focusedElement();
|
|
1642
|
+
if (active && ref._overlayRef.overlayElement?.contains(active)) active.blur();
|
|
1643
|
+
afterNextRender(() => this._focusAfterMinimize(ref, attempt + 1), { injector: this.parentInjector });
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
const tab = this.taskbarTab(ref);
|
|
1647
|
+
const restore = tab?.matches("button") ? tab : tab?.querySelector("button");
|
|
1375
1648
|
if (restore) restore.focus();
|
|
1376
1649
|
else if (ref._returnFocus?.isConnected) ref._returnFocus.focus();
|
|
1377
1650
|
const active = this.focusedElement();
|
|
1378
1651
|
if (active && ref._overlayRef.overlayElement?.contains(active)) active.blur();
|
|
1379
1652
|
}
|
|
1380
1653
|
taskbarTab(ref) {
|
|
1381
|
-
for (const taskbar of this.taskbars) {
|
|
1654
|
+
for (const taskbar of this.taskbars()) {
|
|
1382
1655
|
const tab = taskbar.tabFor(ref);
|
|
1383
1656
|
if (tab) return tab;
|
|
1384
1657
|
}
|
|
@@ -1395,6 +1668,80 @@ var WrWindowManager = class WrWindowManager {
|
|
|
1395
1668
|
if (!active) return true;
|
|
1396
1669
|
return !!ref._overlayRef.overlayElement?.contains(active) || !!this.taskbarTab(ref)?.contains(active);
|
|
1397
1670
|
}
|
|
1671
|
+
onScreen() {
|
|
1672
|
+
return this._windows().filter((w) => w.state() !== "minimized");
|
|
1673
|
+
}
|
|
1674
|
+
cascade() {
|
|
1675
|
+
const rtl = this.dir?.value === "rtl";
|
|
1676
|
+
this.onScreen().sort((a, b) => a.z() - b.z()).forEach((ref, index) => {
|
|
1677
|
+
const m = ref._model;
|
|
1678
|
+
m.restore();
|
|
1679
|
+
const wa = m.workArea();
|
|
1680
|
+
const o = m.options();
|
|
1681
|
+
const fit = (size, room) => o.keepInViewport ? Math.min(size, room) : size;
|
|
1682
|
+
const width = clamp(fit(m.width(), wa.width), o.minWidth, o.maxWidth);
|
|
1683
|
+
const height = clamp(fit(m.height(), wa.height), o.minHeight, o.maxHeight);
|
|
1684
|
+
const offset = cascadeOffset(index);
|
|
1685
|
+
const x = rtl ? wa.left + wa.width - width - offset.x : wa.left + offset.x;
|
|
1686
|
+
const y = wa.top + offset.y;
|
|
1687
|
+
m.setRaw({
|
|
1688
|
+
x: clamp(x, wa.left, Math.max(wa.left, wa.left + wa.width - width)),
|
|
1689
|
+
y: clamp(y, wa.top, Math.max(wa.top, wa.top + wa.height - height)),
|
|
1690
|
+
width,
|
|
1691
|
+
height
|
|
1692
|
+
});
|
|
1693
|
+
this._raise(ref);
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
tile(mode = "grid") {
|
|
1697
|
+
const list = this.onScreen();
|
|
1698
|
+
const n = list.length;
|
|
1699
|
+
if (n === 0) return;
|
|
1700
|
+
const rtl = this.dir?.value === "rtl";
|
|
1701
|
+
const cols = mode === "columns" ? n : mode === "rows" ? 1 : Math.ceil(Math.sqrt(n));
|
|
1702
|
+
const rows = Math.ceil(n / cols);
|
|
1703
|
+
list.forEach((ref, index) => {
|
|
1704
|
+
const m = ref._model;
|
|
1705
|
+
m.restore();
|
|
1706
|
+
const wa = m.workArea();
|
|
1707
|
+
const o = m.options();
|
|
1708
|
+
const row = Math.floor(index / cols);
|
|
1709
|
+
const inRow = Math.min(cols, n - row * cols);
|
|
1710
|
+
let col = index % cols;
|
|
1711
|
+
if (rtl) col = inRow - 1 - col;
|
|
1712
|
+
const x0 = wa.left + Math.floor(wa.width * col / inRow);
|
|
1713
|
+
const x1 = wa.left + Math.floor(wa.width * (col + 1) / inRow);
|
|
1714
|
+
const y0 = wa.top + Math.floor(wa.height * row / rows);
|
|
1715
|
+
const y1 = wa.top + Math.floor(wa.height * (row + 1) / rows);
|
|
1716
|
+
m.setRaw({
|
|
1717
|
+
x: x0,
|
|
1718
|
+
y: y0,
|
|
1719
|
+
width: clamp(x1 - x0, o.minWidth, o.maxWidth),
|
|
1720
|
+
height: clamp(y1 - y0, o.minHeight, o.maxHeight)
|
|
1721
|
+
});
|
|
1722
|
+
m.clamp();
|
|
1723
|
+
});
|
|
1724
|
+
}
|
|
1725
|
+
minimizeAll() {
|
|
1726
|
+
for (const ref of this.onScreen()) ref._model.minimize();
|
|
1727
|
+
}
|
|
1728
|
+
restoreAll() {
|
|
1729
|
+
for (const ref of this._windows()) ref._model.unminimize();
|
|
1730
|
+
}
|
|
1731
|
+
activateNext() {
|
|
1732
|
+
this.cycle(1);
|
|
1733
|
+
}
|
|
1734
|
+
activatePrevious() {
|
|
1735
|
+
this.cycle(-1);
|
|
1736
|
+
}
|
|
1737
|
+
cycle(step) {
|
|
1738
|
+
const list = this._windows();
|
|
1739
|
+
if (list.length === 0) return;
|
|
1740
|
+
const current = this._active();
|
|
1741
|
+
const index = current ? list.indexOf(current) : -1;
|
|
1742
|
+
const next = index < 0 ? list[step > 0 ? 0 : list.length - 1] : list[(index + step + list.length) % list.length];
|
|
1743
|
+
this._activate(next);
|
|
1744
|
+
}
|
|
1398
1745
|
closeAll() {
|
|
1399
1746
|
for (const ref of [...this._windows()]) ref.close();
|
|
1400
1747
|
}
|
|
@@ -1411,11 +1758,12 @@ var WrWindowManager = class WrWindowManager {
|
|
|
1411
1758
|
const snapshot = this._windows().map((ref) => ({
|
|
1412
1759
|
id: ref.id,
|
|
1413
1760
|
state: ref.state(),
|
|
1414
|
-
x: ref.
|
|
1415
|
-
y: ref.
|
|
1416
|
-
width: ref.
|
|
1417
|
-
height: ref.
|
|
1418
|
-
title: ref.title()
|
|
1761
|
+
x: ref._model.x(),
|
|
1762
|
+
y: ref._model.y(),
|
|
1763
|
+
width: ref._model.width(),
|
|
1764
|
+
height: ref._model.height(),
|
|
1765
|
+
title: ref.title(),
|
|
1766
|
+
snap: ref._model.snap()
|
|
1419
1767
|
}));
|
|
1420
1768
|
this.storage.set(this.layoutKey(name), snapshot);
|
|
1421
1769
|
}
|
|
@@ -1438,19 +1786,20 @@ var WrWindowManager = class WrWindowManager {
|
|
|
1438
1786
|
}
|
|
1439
1787
|
}
|
|
1440
1788
|
applyRestore(ref, snap) {
|
|
1441
|
-
ref.
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1789
|
+
const m = ref._model;
|
|
1790
|
+
m.restore();
|
|
1791
|
+
if (snap.title) m.title.set(snap.title);
|
|
1792
|
+
m.resizeTo(snap.width, snap.height);
|
|
1793
|
+
m.moveTo(snap.x, snap.y);
|
|
1794
|
+
if (snap.snap && snap.snap !== "top") m.snap.set(snap.snap);
|
|
1795
|
+
if (snap.state !== "normal") m.setState(snap.state);
|
|
1447
1796
|
}
|
|
1448
1797
|
clearLayout(name) {
|
|
1449
1798
|
this.storage.remove(this.layoutKey(name));
|
|
1450
1799
|
}
|
|
1451
1800
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
1452
1801
|
minVersion: "12.0.0",
|
|
1453
|
-
version: "22.2.
|
|
1802
|
+
version: "22.2.4",
|
|
1454
1803
|
ngImport: i0,
|
|
1455
1804
|
type: WrWindowManager,
|
|
1456
1805
|
deps: [],
|
|
@@ -1458,14 +1807,14 @@ var WrWindowManager = class WrWindowManager {
|
|
|
1458
1807
|
});
|
|
1459
1808
|
static ɵprov = i0.ɵɵngDeclareService({
|
|
1460
1809
|
minVersion: "22.0.0",
|
|
1461
|
-
version: "22.2.
|
|
1810
|
+
version: "22.2.4",
|
|
1462
1811
|
ngImport: i0,
|
|
1463
1812
|
type: WrWindowManager
|
|
1464
1813
|
});
|
|
1465
1814
|
};
|
|
1466
1815
|
i0.ɵɵngDeclareClassMetadata({
|
|
1467
1816
|
minVersion: "12.0.0",
|
|
1468
|
-
version: "22.2.
|
|
1817
|
+
version: "22.2.4",
|
|
1469
1818
|
ngImport: i0,
|
|
1470
1819
|
type: WrWindowManager,
|
|
1471
1820
|
decorators: [{ type: Service }]
|
|
@@ -1477,38 +1826,239 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1477
1826
|
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
1478
1827
|
*/
|
|
1479
1828
|
const NO_OVERRIDE = signal(null).asReadonly();
|
|
1829
|
+
const NO_RESERVE = {
|
|
1830
|
+
top: 0,
|
|
1831
|
+
bottom: 0
|
|
1832
|
+
};
|
|
1833
|
+
const sameTabs = (a, b) => a.size === b.size && [...a].every(([id, width]) => b.get(id) === width);
|
|
1834
|
+
const sameRoom = (a, b) => a === b || !!a && !!b && a.width === b.width && a.gap === b.gap && a.more === b.more && sameTabs(a.tabs, b.tabs);
|
|
1835
|
+
const maxTabsAttr = (value) => value === null || value === void 0 || value === "" ? null : Math.max(1, Math.trunc(coerceNumberProperty(value, 1)));
|
|
1480
1836
|
var WrWindowTaskbar = class WrWindowTaskbar {
|
|
1481
|
-
|
|
1837
|
+
minimizedLabel = useI18nText(NO_OVERRIDE, "window.taskbar", "Minimized windows");
|
|
1838
|
+
allLabel = useI18nText(NO_OVERRIDE, "window.taskbarAll", "Open windows");
|
|
1482
1839
|
closeLabel = useI18nText(NO_OVERRIDE, "window.closeWindow", "Close window");
|
|
1483
1840
|
untitled = useI18nText(NO_OVERRIDE, "window.untitled", "Untitled");
|
|
1484
1841
|
restoreLabel = useI18nFormatter("window.restoreWindow", "Restore {{title}}");
|
|
1842
|
+
moreLabel = useI18nFormatter("window.taskbarMore", "More windows: {{count}}");
|
|
1485
1843
|
position = input("bottom", ...ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []);
|
|
1844
|
+
show = input("minimized", ...ngDevMode ? [{ debugName: "show" }] : /* istanbul ignore next */ []);
|
|
1845
|
+
maxTabs = input(null, {
|
|
1846
|
+
...ngDevMode ? { debugName: "maxTabs" } : /* istanbul ignore next */ {},
|
|
1847
|
+
transform: maxTabsAttr
|
|
1848
|
+
});
|
|
1486
1849
|
manager = inject(WrWindowManager);
|
|
1487
|
-
|
|
1850
|
+
host = inject(ElementRef).nativeElement;
|
|
1851
|
+
dir = inject(Directionality, { optional: true });
|
|
1852
|
+
railLabel = computed(() => this.show() === "all" ? this.allLabel() : this.minimizedLabel(), ...ngDevMode ? [{ debugName: "railLabel" }] : /* istanbul ignore next */ []);
|
|
1853
|
+
items = computed(() => this.show() === "all" ? this.manager.windows().filter((w) => w.taskbarVisible) : this.manager.minimized(), ...ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []);
|
|
1854
|
+
room = signal(null, {
|
|
1855
|
+
...ngDevMode ? { debugName: "room" } : /* istanbul ignore next */ {},
|
|
1856
|
+
equal: sameRoom
|
|
1857
|
+
});
|
|
1858
|
+
visible = computed(() => {
|
|
1859
|
+
const items = this.items();
|
|
1860
|
+
const max = this.maxTabs() ?? Infinity;
|
|
1861
|
+
const room = this.room();
|
|
1862
|
+
const fits = (shown, more) => {
|
|
1863
|
+
if (room === null) return true;
|
|
1864
|
+
let need = Math.max(0, shown.length - 1) * room.gap + (more ? room.gap + room.more : 0);
|
|
1865
|
+
for (const ref of shown) need += room.tabs.get(ref.id) ?? 0;
|
|
1866
|
+
return need <= room.width + .01;
|
|
1867
|
+
};
|
|
1868
|
+
if (items.length <= max && fits(items, false)) return items;
|
|
1869
|
+
const current = items.find((ref) => this.isCurrent(ref));
|
|
1870
|
+
const first = (count) => {
|
|
1871
|
+
const shown = items.slice(0, count);
|
|
1872
|
+
if (current && !shown.includes(current)) shown[count - 1] = current;
|
|
1873
|
+
return shown;
|
|
1874
|
+
};
|
|
1875
|
+
for (let count = Math.min(max, items.length - 1); count > 1; count--) {
|
|
1876
|
+
const shown = first(count);
|
|
1877
|
+
if (fits(shown, true)) return shown;
|
|
1878
|
+
}
|
|
1879
|
+
return first(1);
|
|
1880
|
+
}, ...ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []);
|
|
1881
|
+
slots = computed(() => new Map(this.visible().map((ref, index) => [ref, index])), ...ngDevMode ? [{ debugName: "slots" }] : /* istanbul ignore next */ []);
|
|
1882
|
+
folded = computed(() => {
|
|
1883
|
+
const visible = this.visible();
|
|
1884
|
+
return this.items().filter((ref) => !visible.includes(ref));
|
|
1885
|
+
}, ...ngDevMode ? [{ debugName: "folded" }] : /* istanbul ignore next */ []);
|
|
1886
|
+
menuPosition = computed(() => this.position() === "top" ? "bottom-end" : "top-end", ...ngDevMode ? [{ debugName: "menuPosition" }] : /* istanbul ignore next */ []);
|
|
1488
1887
|
classes = computed(() => `wr-window-taskbar wr-window-taskbar--${this.position()}`, ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
|
|
1489
1888
|
tabs = viewChildren("tab", ...ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []);
|
|
1889
|
+
more = viewChild("more", ...ngDevMode ? [{ debugName: "more" }] : /* istanbul ignore next */ []);
|
|
1890
|
+
rovingIndex = signal(0, ...ngDevMode ? [{ debugName: "rovingIndex" }] : /* istanbul ignore next */ []);
|
|
1891
|
+
stop = computed(() => {
|
|
1892
|
+
const buttons = this.visible().length * 2 + (this.folded().length > 0 ? 1 : 0);
|
|
1893
|
+
return Math.max(0, Math.min(this.rovingIndex(), buttons - 1));
|
|
1894
|
+
}, ...ngDevMode ? [{ debugName: "stop" }] : /* istanbul ignore next */ []);
|
|
1895
|
+
reserve = signal(NO_RESERVE, {
|
|
1896
|
+
...ngDevMode ? { debugName: "reserve" } : /* istanbul ignore next */ {},
|
|
1897
|
+
equal: (a, b) => a.top === b.top && a.bottom === b.bottom
|
|
1898
|
+
});
|
|
1490
1899
|
constructor() {
|
|
1491
|
-
const unregister = this.manager._registerTaskbar({
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1900
|
+
const unregister = this.manager._registerTaskbar({
|
|
1901
|
+
tabFor: (ref) => {
|
|
1902
|
+
if (this.folded().includes(ref)) return this.more()?.nativeElement ?? null;
|
|
1903
|
+
const index = this.items().indexOf(ref);
|
|
1904
|
+
return index >= 0 ? this.tabs()[index]?.nativeElement ?? null : null;
|
|
1905
|
+
},
|
|
1906
|
+
settling: (ref) => {
|
|
1907
|
+
const room = this.room();
|
|
1908
|
+
const index = this.items().indexOf(ref);
|
|
1909
|
+
if (room === null || index < 0) return false;
|
|
1910
|
+
if (!room.tabs.has(ref.id)) return true;
|
|
1911
|
+
if (this.folded().includes(ref)) return !this.more();
|
|
1912
|
+
return !!this.tabs()[index]?.nativeElement.classList.contains("wr-window-taskbar__tab--folded");
|
|
1913
|
+
},
|
|
1914
|
+
contains: (node) => this.host.contains(node),
|
|
1915
|
+
reserve: this.reserve.asReadonly()
|
|
1916
|
+
});
|
|
1917
|
+
const destroyRef = inject(DestroyRef);
|
|
1918
|
+
destroyRef.onDestroy(unregister);
|
|
1919
|
+
let observer = null;
|
|
1920
|
+
let observedRail = null;
|
|
1921
|
+
afterRenderEffect(() => {
|
|
1922
|
+
for (const ref of this.items()) this.tabTitle(ref);
|
|
1923
|
+
this.folded().length;
|
|
1924
|
+
this.position();
|
|
1925
|
+
const rail = this.host.querySelector(".wr-window-taskbar__rail");
|
|
1926
|
+
if (observer && rail !== observedRail) {
|
|
1927
|
+
if (observedRail) observer.unobserve(observedRail);
|
|
1928
|
+
if (rail) observer.observe(rail);
|
|
1929
|
+
}
|
|
1930
|
+
observedRail = rail;
|
|
1931
|
+
this.measure();
|
|
1932
|
+
});
|
|
1933
|
+
afterNextRender(() => {
|
|
1934
|
+
const measure = () => this.measure();
|
|
1935
|
+
observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measure);
|
|
1936
|
+
observer?.observe(this.host);
|
|
1937
|
+
if (observedRail) observer?.observe(observedRail);
|
|
1938
|
+
window.addEventListener("resize", measure, { passive: true });
|
|
1939
|
+
destroyRef.onDestroy(() => {
|
|
1940
|
+
observer?.disconnect();
|
|
1941
|
+
window.removeEventListener("resize", measure);
|
|
1942
|
+
});
|
|
1943
|
+
});
|
|
1496
1944
|
}
|
|
1497
1945
|
tabTitle(ref) {
|
|
1498
1946
|
return ref.title() || this.untitled();
|
|
1499
1947
|
}
|
|
1500
|
-
|
|
1501
|
-
ref.
|
|
1502
|
-
|
|
1503
|
-
|
|
1948
|
+
isCurrent(ref) {
|
|
1949
|
+
return ref.isActive() && ref.state() !== "minimized";
|
|
1950
|
+
}
|
|
1951
|
+
tabLabel(ref) {
|
|
1952
|
+
const title = this.tabTitle(ref);
|
|
1953
|
+
return this.show() === "all" && ref.state() !== "minimized" ? title : this.restoreLabel({ title });
|
|
1954
|
+
}
|
|
1955
|
+
tabIndex(button) {
|
|
1956
|
+
return button >= 0 && button === this.stop() ? 0 : -1;
|
|
1957
|
+
}
|
|
1958
|
+
press(ref) {
|
|
1959
|
+
if (this.show() === "all" && this.isCurrent(ref)) {
|
|
1960
|
+
ref.minimize();
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
ref.activate();
|
|
1964
|
+
}
|
|
1965
|
+
pick(ref, menu) {
|
|
1966
|
+
menu.close();
|
|
1967
|
+
this.press(ref);
|
|
1504
1968
|
}
|
|
1505
1969
|
close(ref, event) {
|
|
1506
1970
|
event.stopPropagation();
|
|
1507
1971
|
ref.close();
|
|
1508
1972
|
}
|
|
1973
|
+
onKeydown(event) {
|
|
1974
|
+
const buttons = this.buttons();
|
|
1975
|
+
if (buttons.length === 0) return;
|
|
1976
|
+
const current = buttons.indexOf(event.target);
|
|
1977
|
+
if (current < 0) return;
|
|
1978
|
+
const rtl = this.dir?.value === "rtl";
|
|
1979
|
+
let next;
|
|
1980
|
+
switch (event.key) {
|
|
1981
|
+
case "ArrowRight":
|
|
1982
|
+
next = current + (rtl ? -1 : 1);
|
|
1983
|
+
break;
|
|
1984
|
+
case "ArrowLeft":
|
|
1985
|
+
next = current + (rtl ? 1 : -1);
|
|
1986
|
+
break;
|
|
1987
|
+
case "Home":
|
|
1988
|
+
next = 0;
|
|
1989
|
+
break;
|
|
1990
|
+
case "End":
|
|
1991
|
+
next = buttons.length - 1;
|
|
1992
|
+
break;
|
|
1993
|
+
default: return;
|
|
1994
|
+
}
|
|
1995
|
+
event.preventDefault();
|
|
1996
|
+
next = (next + buttons.length) % buttons.length;
|
|
1997
|
+
this.rovingIndex.set(next);
|
|
1998
|
+
buttons[next].focus();
|
|
1999
|
+
}
|
|
2000
|
+
onFocusIn(event) {
|
|
2001
|
+
const index = this.buttons().indexOf(event.target);
|
|
2002
|
+
if (index >= 0) this.rovingIndex.set(index);
|
|
2003
|
+
}
|
|
2004
|
+
buttons() {
|
|
2005
|
+
return [...this.host.querySelectorAll(".wr-window-taskbar__tab:not(.wr-window-taskbar__tab--folded) button, .wr-window-taskbar__more")];
|
|
2006
|
+
}
|
|
2007
|
+
measure() {
|
|
2008
|
+
if (typeof window === "undefined") return;
|
|
2009
|
+
this.measureRoom();
|
|
2010
|
+
const rect = this.host.getBoundingClientRect();
|
|
2011
|
+
if (rect.height <= 0) {
|
|
2012
|
+
this.reserve.set(NO_RESERVE);
|
|
2013
|
+
return;
|
|
2014
|
+
}
|
|
2015
|
+
const vh = document.documentElement.clientHeight || window.innerHeight;
|
|
2016
|
+
this.reserve.set(this.position() === "top" ? {
|
|
2017
|
+
top: Math.ceil(rect.bottom),
|
|
2018
|
+
bottom: 0
|
|
2019
|
+
} : {
|
|
2020
|
+
top: 0,
|
|
2021
|
+
bottom: Math.max(0, Math.ceil(vh - rect.top))
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
measureRoom() {
|
|
2025
|
+
const rail = this.host.querySelector(".wr-window-taskbar__rail");
|
|
2026
|
+
const items = this.items();
|
|
2027
|
+
const tabs = this.tabs().map((tab) => tab.nativeElement);
|
|
2028
|
+
const width = this.host.clientWidth;
|
|
2029
|
+
if (!rail || tabs.length === 0 || width <= 0) {
|
|
2030
|
+
this.room.set(null);
|
|
2031
|
+
return;
|
|
2032
|
+
}
|
|
2033
|
+
if (tabs.length !== items.length) return;
|
|
2034
|
+
const railStyle = getComputedStyle(rail);
|
|
2035
|
+
const px = (value) => parseFloat(value) || 0;
|
|
2036
|
+
const inner = width - px(railStyle.paddingInlineStart) - px(railStyle.paddingInlineEnd) - px(railStyle.borderInlineStartWidth) - px(railStyle.borderInlineEndWidth);
|
|
2037
|
+
const widths = /* @__PURE__ */ new Map();
|
|
2038
|
+
tabs.forEach((tab, index) => {
|
|
2039
|
+
const width = tab.getBoundingClientRect().width;
|
|
2040
|
+
const cap = getComputedStyle(tab).maxWidth;
|
|
2041
|
+
const fixed = cap.endsWith("px");
|
|
2042
|
+
if (!fixed && cap !== "none" && cap !== "") {
|
|
2043
|
+
widths.set(items[index].id, width);
|
|
2044
|
+
return;
|
|
2045
|
+
}
|
|
2046
|
+
const title = tab.querySelector(".wr-window-taskbar__tab-title");
|
|
2047
|
+
const clipped = title ? title.scrollWidth - title.clientWidth : 0;
|
|
2048
|
+
const natural = width + (clipped > 1 ? clipped : 0);
|
|
2049
|
+
widths.set(items[index].id, fixed ? Math.min(natural, parseFloat(cap)) : natural);
|
|
2050
|
+
});
|
|
2051
|
+
const more = this.more()?.nativeElement.getBoundingClientRect().width ?? tabs[0].getBoundingClientRect().height;
|
|
2052
|
+
this.room.set({
|
|
2053
|
+
width: inner,
|
|
2054
|
+
gap: px(railStyle.columnGap),
|
|
2055
|
+
more,
|
|
2056
|
+
tabs: widths
|
|
2057
|
+
});
|
|
2058
|
+
}
|
|
1509
2059
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
1510
2060
|
minVersion: "12.0.0",
|
|
1511
|
-
version: "22.2.
|
|
2061
|
+
version: "22.2.4",
|
|
1512
2062
|
ngImport: i0,
|
|
1513
2063
|
type: WrWindowTaskbar,
|
|
1514
2064
|
deps: [],
|
|
@@ -1516,19 +2066,39 @@ var WrWindowTaskbar = class WrWindowTaskbar {
|
|
|
1516
2066
|
});
|
|
1517
2067
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
1518
2068
|
minVersion: "17.0.0",
|
|
1519
|
-
version: "22.2.
|
|
2069
|
+
version: "22.2.4",
|
|
1520
2070
|
type: WrWindowTaskbar,
|
|
1521
2071
|
isStandalone: true,
|
|
1522
2072
|
selector: "wr-window-taskbar",
|
|
1523
|
-
inputs: {
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
2073
|
+
inputs: {
|
|
2074
|
+
position: {
|
|
2075
|
+
classPropertyName: "position",
|
|
2076
|
+
publicName: "position",
|
|
2077
|
+
isSignal: true,
|
|
2078
|
+
isRequired: false,
|
|
2079
|
+
transformFunction: null
|
|
2080
|
+
},
|
|
2081
|
+
show: {
|
|
2082
|
+
classPropertyName: "show",
|
|
2083
|
+
publicName: "show",
|
|
2084
|
+
isSignal: true,
|
|
2085
|
+
isRequired: false,
|
|
2086
|
+
transformFunction: null
|
|
2087
|
+
},
|
|
2088
|
+
maxTabs: {
|
|
2089
|
+
classPropertyName: "maxTabs",
|
|
2090
|
+
publicName: "maxTabs",
|
|
2091
|
+
isSignal: true,
|
|
2092
|
+
isRequired: false,
|
|
2093
|
+
transformFunction: null
|
|
2094
|
+
}
|
|
2095
|
+
},
|
|
1530
2096
|
host: {
|
|
1531
2097
|
attributes: { "role": "toolbar" },
|
|
2098
|
+
listeners: {
|
|
2099
|
+
"keydown": "onKeydown($event)",
|
|
2100
|
+
"focusin": "onFocusIn($event)"
|
|
2101
|
+
},
|
|
1532
2102
|
properties: {
|
|
1533
2103
|
"class": "classes()",
|
|
1534
2104
|
"attr.aria-label": "railLabel()"
|
|
@@ -1539,30 +2109,71 @@ var WrWindowTaskbar = class WrWindowTaskbar {
|
|
|
1539
2109
|
predicate: ["tab"],
|
|
1540
2110
|
descendants: true,
|
|
1541
2111
|
isSignal: true
|
|
2112
|
+
}, {
|
|
2113
|
+
propertyName: "more",
|
|
2114
|
+
first: true,
|
|
2115
|
+
predicate: ["more"],
|
|
2116
|
+
descendants: true,
|
|
2117
|
+
isSignal: true
|
|
1542
2118
|
}],
|
|
1543
2119
|
ngImport: i0,
|
|
1544
|
-
template: "@if (items().length > 0) {\n <div class=\"wr-window-taskbar__rail\">\n @for (ref of items(); track ref.id) {\n <!--\n Two SIBLING buttons in a plain container, not a close button nested\n inside the tab. The close used to be a `role=\"button\"` span with\n `tabindex=\"0\"` inside the tab's own `<button>` — interactive content\n inside interactive content, which the HTML parser and `nested-interactive`\n both object to. Nothing caught it: a taskbar tab exists only while a\n window is minimized, and the a11y sweep reads prerendered HTML, where the\n rail is not rendered at all.\n -->\n <div
|
|
2120
|
+
template: "@if (items().length > 0) {\n <div class=\"wr-window-taskbar__rail\">\n @for (ref of items(); track ref.id) {\n @let slot = slots().get(ref) ?? -1;\n <!--\n Two SIBLING buttons in a plain container, not a close button nested\n inside the tab. The close used to be a `role=\"button\"` span with\n `tabindex=\"0\"` inside the tab's own `<button>` — interactive content\n inside interactive content, which the HTML parser and `nested-interactive`\n both object to. Nothing caught it: a taskbar tab exists only while a\n window is minimized, and the a11y sweep reads prerendered HTML, where the\n rail is not rendered at all.\n -->\n <!--\n A folded window keeps its tab, hidden and out of the row but laid out,\n so the rail can read the width it would take to draw it again.\n -->\n <div\n #tab\n class=\"wr-window-taskbar__tab\"\n [class.wr-window-taskbar__tab--active]=\"isCurrent(ref)\"\n [class.wr-window-taskbar__tab--minimized]=\"ref.state() === 'minimized'\"\n [class.wr-window-taskbar__tab--folded]=\"slot < 0\"\n [attr.inert]=\"slot < 0 ? '' : null\"\n >\n <button\n type=\"button\"\n class=\"wr-window-taskbar__tab-restore\"\n [attr.aria-label]=\"tabLabel(ref)\"\n [attr.aria-pressed]=\"show() === 'all' ? isCurrent(ref) : null\"\n [attr.tabindex]=\"tabIndex(slot < 0 ? -1 : slot * 2)\"\n (click)=\"press(ref)\"\n >\n <span class=\"wr-window-taskbar__tab-title\">{{ tabTitle(ref) }}</span>\n </button>\n <button\n type=\"button\"\n class=\"wr-window-taskbar__tab-close\"\n [attr.aria-label]=\"closeLabel()\"\n [attr.tabindex]=\"tabIndex(slot < 0 ? -1 : slot * 2 + 1)\"\n (click)=\"close(ref, $event)\"\n >\n <svg width=\"9\" height=\"9\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M1 1 L9 9 M9 1 L1 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n </button>\n </div>\n }\n @if (folded().length > 0) {\n <button\n #more\n #fold=\"wrDropdown\"\n type=\"button\"\n class=\"wr-window-taskbar__more\"\n [wrDropdown]=\"foldMenu\"\n [position]=\"menuPosition()\"\n [attr.aria-label]=\"moreLabel({ count: folded().length })\"\n [attr.tabindex]=\"tabIndex(visible().length * 2)\"\n >\n +{{ folded().length }}\n </button>\n <wr-dropdown-menu #foldMenu>\n @for (ref of folded(); track ref.id) {\n <wr-dropdown-item\n class=\"wr-window-taskbar__fold-item\"\n [class.wr-window-taskbar__fold-item--minimized]=\"ref.state() === 'minimized'\"\n [attr.aria-label]=\"tabLabel(ref)\"\n (click)=\"pick(ref, fold)\"\n >\n {{ tabTitle(ref) }}\n </wr-dropdown-item>\n }\n </wr-dropdown-menu>\n }\n </div>\n}\n",
|
|
2121
|
+
dependencies: [
|
|
2122
|
+
{
|
|
2123
|
+
kind: "directive",
|
|
2124
|
+
type: WrDropdown,
|
|
2125
|
+
selector: "[wrDropdown]",
|
|
2126
|
+
inputs: [
|
|
2127
|
+
"wrDropdown",
|
|
2128
|
+
"trigger",
|
|
2129
|
+
"position",
|
|
2130
|
+
"arrow",
|
|
2131
|
+
"panelClass"
|
|
2132
|
+
],
|
|
2133
|
+
outputs: ["opened", "closed"],
|
|
2134
|
+
exportAs: ["wrDropdown"]
|
|
2135
|
+
},
|
|
2136
|
+
{
|
|
2137
|
+
kind: "component",
|
|
2138
|
+
type: WrDropdownMenu,
|
|
2139
|
+
selector: "wr-dropdown-menu",
|
|
2140
|
+
exportAs: ["wrDropdownMenu"]
|
|
2141
|
+
},
|
|
2142
|
+
{
|
|
2143
|
+
kind: "component",
|
|
2144
|
+
type: WrDropdownItem,
|
|
2145
|
+
selector: "wr-dropdown-item",
|
|
2146
|
+
inputs: ["icon", "disabled"]
|
|
2147
|
+
}
|
|
2148
|
+
],
|
|
1545
2149
|
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
1546
2150
|
encapsulation: i0.ViewEncapsulation.None
|
|
1547
2151
|
});
|
|
1548
2152
|
};
|
|
1549
2153
|
i0.ɵɵngDeclareClassMetadata({
|
|
1550
2154
|
minVersion: "12.0.0",
|
|
1551
|
-
version: "22.2.
|
|
2155
|
+
version: "22.2.4",
|
|
1552
2156
|
ngImport: i0,
|
|
1553
2157
|
type: WrWindowTaskbar,
|
|
1554
2158
|
decorators: [{
|
|
1555
2159
|
type: Component,
|
|
1556
2160
|
args: [{
|
|
1557
2161
|
selector: "wr-window-taskbar",
|
|
2162
|
+
imports: [
|
|
2163
|
+
WrDropdown,
|
|
2164
|
+
WrDropdownMenu,
|
|
2165
|
+
WrDropdownItem
|
|
2166
|
+
],
|
|
1558
2167
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1559
2168
|
encapsulation: ViewEncapsulation.None,
|
|
1560
2169
|
host: {
|
|
1561
2170
|
"[class]": "classes()",
|
|
1562
2171
|
role: "toolbar",
|
|
1563
|
-
"[attr.aria-label]": "railLabel()"
|
|
2172
|
+
"[attr.aria-label]": "railLabel()",
|
|
2173
|
+
"(keydown)": "onKeydown($event)",
|
|
2174
|
+
"(focusin)": "onFocusIn($event)"
|
|
1564
2175
|
},
|
|
1565
|
-
template: "@if (items().length > 0) {\n <div class=\"wr-window-taskbar__rail\">\n @for (ref of items(); track ref.id) {\n <!--\n Two SIBLING buttons in a plain container, not a close button nested\n inside the tab. The close used to be a `role=\"button\"` span with\n `tabindex=\"0\"` inside the tab's own `<button>` — interactive content\n inside interactive content, which the HTML parser and `nested-interactive`\n both object to. Nothing caught it: a taskbar tab exists only while a\n window is minimized, and the a11y sweep reads prerendered HTML, where the\n rail is not rendered at all.\n -->\n <div
|
|
2176
|
+
template: "@if (items().length > 0) {\n <div class=\"wr-window-taskbar__rail\">\n @for (ref of items(); track ref.id) {\n @let slot = slots().get(ref) ?? -1;\n <!--\n Two SIBLING buttons in a plain container, not a close button nested\n inside the tab. The close used to be a `role=\"button\"` span with\n `tabindex=\"0\"` inside the tab's own `<button>` — interactive content\n inside interactive content, which the HTML parser and `nested-interactive`\n both object to. Nothing caught it: a taskbar tab exists only while a\n window is minimized, and the a11y sweep reads prerendered HTML, where the\n rail is not rendered at all.\n -->\n <!--\n A folded window keeps its tab, hidden and out of the row but laid out,\n so the rail can read the width it would take to draw it again.\n -->\n <div\n #tab\n class=\"wr-window-taskbar__tab\"\n [class.wr-window-taskbar__tab--active]=\"isCurrent(ref)\"\n [class.wr-window-taskbar__tab--minimized]=\"ref.state() === 'minimized'\"\n [class.wr-window-taskbar__tab--folded]=\"slot < 0\"\n [attr.inert]=\"slot < 0 ? '' : null\"\n >\n <button\n type=\"button\"\n class=\"wr-window-taskbar__tab-restore\"\n [attr.aria-label]=\"tabLabel(ref)\"\n [attr.aria-pressed]=\"show() === 'all' ? isCurrent(ref) : null\"\n [attr.tabindex]=\"tabIndex(slot < 0 ? -1 : slot * 2)\"\n (click)=\"press(ref)\"\n >\n <span class=\"wr-window-taskbar__tab-title\">{{ tabTitle(ref) }}</span>\n </button>\n <button\n type=\"button\"\n class=\"wr-window-taskbar__tab-close\"\n [attr.aria-label]=\"closeLabel()\"\n [attr.tabindex]=\"tabIndex(slot < 0 ? -1 : slot * 2 + 1)\"\n (click)=\"close(ref, $event)\"\n >\n <svg width=\"9\" height=\"9\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M1 1 L9 9 M9 1 L1 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n </button>\n </div>\n }\n @if (folded().length > 0) {\n <button\n #more\n #fold=\"wrDropdown\"\n type=\"button\"\n class=\"wr-window-taskbar__more\"\n [wrDropdown]=\"foldMenu\"\n [position]=\"menuPosition()\"\n [attr.aria-label]=\"moreLabel({ count: folded().length })\"\n [attr.tabindex]=\"tabIndex(visible().length * 2)\"\n >\n +{{ folded().length }}\n </button>\n <wr-dropdown-menu #foldMenu>\n @for (ref of folded(); track ref.id) {\n <wr-dropdown-item\n class=\"wr-window-taskbar__fold-item\"\n [class.wr-window-taskbar__fold-item--minimized]=\"ref.state() === 'minimized'\"\n [attr.aria-label]=\"tabLabel(ref)\"\n (click)=\"pick(ref, fold)\"\n >\n {{ tabTitle(ref) }}\n </wr-dropdown-item>\n }\n </wr-dropdown-menu>\n }\n </div>\n}\n"
|
|
1566
2177
|
}]
|
|
1567
2178
|
}],
|
|
1568
2179
|
ctorParameters: () => [],
|
|
@@ -1575,12 +2186,44 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1575
2186
|
required: false
|
|
1576
2187
|
}]
|
|
1577
2188
|
}],
|
|
2189
|
+
show: [{
|
|
2190
|
+
type: i0.Input,
|
|
2191
|
+
args: [{
|
|
2192
|
+
isSignal: true,
|
|
2193
|
+
alias: "show",
|
|
2194
|
+
required: false
|
|
2195
|
+
}]
|
|
2196
|
+
}],
|
|
2197
|
+
maxTabs: [{
|
|
2198
|
+
type: i0.Input,
|
|
2199
|
+
args: [{
|
|
2200
|
+
isSignal: true,
|
|
2201
|
+
alias: "maxTabs",
|
|
2202
|
+
required: false
|
|
2203
|
+
}]
|
|
2204
|
+
}],
|
|
1578
2205
|
tabs: [{
|
|
1579
2206
|
type: i0.ViewChildren,
|
|
1580
2207
|
args: ["tab", { isSignal: true }]
|
|
2208
|
+
}],
|
|
2209
|
+
more: [{
|
|
2210
|
+
type: i0.ViewChild,
|
|
2211
|
+
args: ["more", { isSignal: true }]
|
|
1581
2212
|
}]
|
|
1582
2213
|
}
|
|
1583
2214
|
});
|
|
1584
|
-
|
|
2215
|
+
/**
|
|
2216
|
+
* @license
|
|
2217
|
+
*
|
|
2218
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2219
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
2220
|
+
*/
|
|
2221
|
+
function withWindows(defaults) {
|
|
2222
|
+
return wrFeature("windows", [{
|
|
2223
|
+
provide: WR_WINDOW_DEFAULTS,
|
|
2224
|
+
useValue: defaults
|
|
2225
|
+
}]);
|
|
2226
|
+
}
|
|
2227
|
+
export { WR_WINDOW_DATA, WR_WINDOW_REF, WrWindowManager, WrWindowRef, WrWindowTaskbar, withWindows };
|
|
1585
2228
|
|
|
1586
2229
|
//# sourceMappingURL=ngwr-window.mjs.map
|