@koobiq/components 20.4.2 → 21.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/accordion/accordion-trigger.scss +3 -10
- package/accordion/accordion.scss +4 -6
- package/actions-panel/actions-panel-container.scss +45 -1
- package/alert/alert.component.scss +3 -2
- package/app-switcher/_app-switcher-theme.scss +0 -4
- package/app-switcher/app-switcher-dropdown-app.scss +3 -2
- package/app-switcher/app-switcher-dropdown-site.scss +2 -1
- package/app-switcher/{kbq-app-switcher-list-item.scss → app-switcher-list-item.scss} +18 -4
- package/app-switcher/app-switcher-tokens.scss +15 -0
- package/app-switcher/app-switcher.scss +14 -4
- package/autocomplete/autocomplete.scss +7 -6
- package/badge/badge.component.scss +5 -8
- package/breadcrumbs/breadcrumbs.scss +25 -10
- package/button/_button-base.scss +30 -7
- package/button/_button-theme.scss +16 -0
- package/button/button-group.scss +7 -0
- package/button/button-tokens.scss +0 -2
- package/button/button.scss +34 -2
- package/button-toggle/_button-toggle-theme.scss +7 -2
- package/button-toggle/button-toggle.scss +65 -15
- package/checkbox/_checkbox-theme.scss +4 -3
- package/checkbox/checkbox.scss +3 -6
- package/clamped-text/clamped-text.scss +6 -2
- package/code-block/code-block-tokens.scss +0 -224
- package/code-block/code-block.scss +20 -9
- package/content-panel/content-panel-aside.scss +3 -2
- package/content-panel/content-panel-container.scss +37 -0
- package/content-panel/content-panel.scss +4 -3
- package/core/highlight/_highlight-theme.scss +3 -1
- package/core/option/action-container.scss +2 -2
- package/core/option/action.scss +2 -1
- package/core/option/option.scss +2 -1
- package/core/pop-up/_pop-up.scss +0 -37
- package/core/selection/pseudo-checkbox/pseudo-checkbox.scss +5 -10
- package/core/styles/_core.scss +3 -0
- package/core/styles/_koobiq-theme.scss +5 -6
- package/core/styles/common/_animation.scss +44 -16
- package/core/styles/common/_groups-mixins.scss +21 -19
- package/core/styles/common/_groups.scss +4 -32
- package/core/styles/common/_index.scss +0 -2
- package/core/styles/common/_link.scss +117 -0
- package/core/styles/common/_list.scss +0 -26
- package/core/styles/common/_overlay.scss +8 -10
- package/core/styles/common/_rtl.scss +0 -14
- package/core/styles/common/_select.scss +33 -15
- package/core/styles/common/_squircle.scss +63 -0
- package/core/styles/common/_tokens.scss +0 -11
- package/core/styles/common/_vendor-prefixes.scss +0 -20
- package/core/styles/functions/_timing.scss +0 -22
- package/core/styles/theming/_scrollbar-theme.scss +6 -1
- package/core/styles/theming/_theming.scss +13 -65
- package/core/styles/typography/_index.scss +0 -1
- package/core/styles/typography/_typography.scss +0 -143
- package/core/styles/visual/_body.scss +1 -6
- package/core/styles/visual/_layout.scss +0 -12
- package/datepicker/calendar-body.scss +3 -1
- package/datepicker/calendar-header.scss +0 -1
- package/datepicker/datepicker-content.scss +33 -1
- package/datepicker/datepicker-toggle.scss +0 -38
- package/dl/dl-tokens.scss +10 -0
- package/dl/dl.scss +113 -13
- package/dropdown/_dropdown-theme.scss +4 -16
- package/dropdown/dropdown-item.scss +4 -10
- package/dropdown/dropdown.scss +2 -1
- package/empty-state/_empty-state-theme.scss +10 -4
- package/empty-state/empty-state-tokens.scss +4 -4
- package/empty-state/empty-state.scss +4 -0
- package/fesm2022/koobiq-components-accordion.mjs +347 -229
- package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
- package/fesm2022/koobiq-components-actions-panel.mjs +302 -187
- package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
- package/fesm2022/koobiq-components-alert.mjs +39 -39
- package/fesm2022/koobiq-components-alert.mjs.map +1 -1
- package/fesm2022/koobiq-components-app-switcher.mjs +677 -367
- package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
- package/fesm2022/koobiq-components-autocomplete.mjs +620 -253
- package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
- package/fesm2022/koobiq-components-badge.mjs +46 -48
- package/fesm2022/koobiq-components-badge.mjs.map +1 -1
- package/fesm2022/koobiq-components-breadcrumbs.mjs +221 -169
- package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
- package/fesm2022/koobiq-components-button-toggle.mjs +565 -196
- package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
- package/fesm2022/koobiq-components-button.mjs +332 -116
- package/fesm2022/koobiq-components-button.mjs.map +1 -1
- package/fesm2022/koobiq-components-checkbox.mjs +172 -132
- package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
- package/fesm2022/koobiq-components-clamped-text.mjs +165 -158
- package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
- package/fesm2022/koobiq-components-code-block.mjs +791 -609
- package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
- package/fesm2022/koobiq-components-content-panel.mjs +260 -143
- package/fesm2022/koobiq-components-content-panel.mjs.map +1 -1
- package/fesm2022/koobiq-components-core.mjs +4342 -1595
- package/fesm2022/koobiq-components-core.mjs.map +1 -1
- package/fesm2022/koobiq-components-datepicker.mjs +1713 -1606
- package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
- package/fesm2022/koobiq-components-divider.mjs +73 -36
- package/fesm2022/koobiq-components-divider.mjs.map +1 -1
- package/fesm2022/koobiq-components-dl.mjs +447 -89
- package/fesm2022/koobiq-components-dl.mjs.map +1 -1
- package/fesm2022/koobiq-components-dropdown.mjs +703 -599
- package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
- package/fesm2022/koobiq-components-dynamic-translation.mjs +20 -20
- package/fesm2022/koobiq-components-dynamic-translation.mjs.map +1 -1
- package/fesm2022/koobiq-components-ellipsis-center.mjs +46 -31
- package/fesm2022/koobiq-components-ellipsis-center.mjs.map +1 -1
- package/fesm2022/koobiq-components-empty-state.mjs +116 -60
- package/fesm2022/koobiq-components-empty-state.mjs.map +1 -1
- package/fesm2022/koobiq-components-file-upload.mjs +550 -290
- package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
- package/fesm2022/koobiq-components-filter-bar.mjs +2871 -2595
- package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
- package/fesm2022/koobiq-components-flag.mjs +79 -24
- package/fesm2022/koobiq-components-flag.mjs.map +1 -1
- package/fesm2022/koobiq-components-form-field.mjs +389 -525
- package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
- package/fesm2022/koobiq-components-icon.mjs +400 -149
- package/fesm2022/koobiq-components-icon.mjs.map +1 -1
- package/fesm2022/koobiq-components-inline-edit.mjs +429 -212
- package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
- package/fesm2022/koobiq-components-input.mjs +601 -459
- package/fesm2022/koobiq-components-input.mjs.map +1 -1
- package/fesm2022/koobiq-components-link-deprecated.mjs +196 -0
- package/fesm2022/koobiq-components-link-deprecated.mjs.map +1 -0
- package/fesm2022/koobiq-components-link.mjs +328 -125
- package/fesm2022/koobiq-components-link.mjs.map +1 -1
- package/fesm2022/koobiq-components-list.mjs +583 -433
- package/fesm2022/koobiq-components-list.mjs.map +1 -1
- package/fesm2022/koobiq-components-loader-overlay.mjs +167 -68
- package/fesm2022/koobiq-components-loader-overlay.mjs.map +1 -1
- package/fesm2022/koobiq-components-markdown.mjs +55 -78
- package/fesm2022/koobiq-components-markdown.mjs.map +1 -1
- package/fesm2022/koobiq-components-modal.mjs +853 -475
- package/fesm2022/koobiq-components-modal.mjs.map +1 -1
- package/fesm2022/koobiq-components-navbar.mjs +895 -556
- package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
- package/fesm2022/koobiq-components-notification-center.mjs +680 -310
- package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
- package/fesm2022/koobiq-components-overflow-items.mjs +46 -64
- package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
- package/fesm2022/koobiq-components-popover.mjs +684 -285
- package/fesm2022/koobiq-components-popover.mjs.map +1 -1
- package/fesm2022/koobiq-components-progress-bar.mjs +87 -33
- package/fesm2022/koobiq-components-progress-bar.mjs.map +1 -1
- package/fesm2022/koobiq-components-progress-spinner.mjs +52 -43
- package/fesm2022/koobiq-components-progress-spinner.mjs.map +1 -1
- package/fesm2022/koobiq-components-radio.mjs +450 -231
- package/fesm2022/koobiq-components-radio.mjs.map +1 -1
- package/fesm2022/koobiq-components-resizer.mjs +127 -21
- package/fesm2022/koobiq-components-resizer.mjs.map +1 -1
- package/fesm2022/koobiq-components-scrollbar-deprecated.mjs +299 -0
- package/fesm2022/koobiq-components-scrollbar-deprecated.mjs.map +1 -0
- package/fesm2022/koobiq-components-scrollbar.mjs +745 -222
- package/fesm2022/koobiq-components-scrollbar.mjs.map +1 -1
- package/fesm2022/koobiq-components-search-expandable.mjs +288 -126
- package/fesm2022/koobiq-components-search-expandable.mjs.map +1 -1
- package/fesm2022/koobiq-components-select.mjs +883 -693
- package/fesm2022/koobiq-components-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-sidebar.mjs +207 -88
- package/fesm2022/koobiq-components-sidebar.mjs.map +1 -1
- package/fesm2022/koobiq-components-sidepanel.mjs +689 -296
- package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
- package/fesm2022/koobiq-components-skeleton.mjs +815 -41
- package/fesm2022/koobiq-components-skeleton.mjs.map +1 -1
- package/fesm2022/koobiq-components-split-button.mjs +109 -88
- package/fesm2022/koobiq-components-split-button.mjs.map +1 -1
- package/fesm2022/koobiq-components-splitter-deprecated.mjs +591 -0
- package/fesm2022/koobiq-components-splitter-deprecated.mjs.map +1 -0
- package/fesm2022/koobiq-components-splitter.mjs +890 -501
- package/fesm2022/koobiq-components-splitter.mjs.map +1 -1
- package/fesm2022/koobiq-components-table.mjs +63 -49
- package/fesm2022/koobiq-components-table.mjs.map +1 -1
- package/fesm2022/koobiq-components-tabs.mjs +1062 -603
- package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
- package/fesm2022/koobiq-components-tags.mjs +886 -733
- package/fesm2022/koobiq-components-tags.mjs.map +1 -1
- package/fesm2022/koobiq-components-textarea.mjs +213 -185
- package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
- package/fesm2022/koobiq-components-time-range.mjs +299 -147
- package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
- package/fesm2022/koobiq-components-timepicker.mjs +233 -245
- package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
- package/fesm2022/koobiq-components-timezone.mjs +344 -142
- package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
- package/fesm2022/koobiq-components-title.mjs +229 -145
- package/fesm2022/koobiq-components-title.mjs.map +1 -1
- package/fesm2022/koobiq-components-toast.mjs +463 -143
- package/fesm2022/koobiq-components-toast.mjs.map +1 -1
- package/fesm2022/koobiq-components-toggle.mjs +177 -130
- package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
- package/fesm2022/koobiq-components-tooltip.mjs +657 -214
- package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
- package/fesm2022/koobiq-components-top-bar.mjs +61 -32
- package/fesm2022/koobiq-components-top-bar.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree-select.mjs +734 -488
- package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree.mjs +1700 -617
- package/fesm2022/koobiq-components-tree.mjs.map +1 -1
- package/fesm2022/koobiq-components-username.mjs +290 -135
- package/fesm2022/koobiq-components-username.mjs.map +1 -1
- package/file-upload/dropzone.scss +31 -3
- package/file-upload/file-upload-tokens.scss +2 -22
- package/file-upload/file-upload.scss +6 -0
- package/file-upload/multiple-file-upload.component.scss +14 -12
- package/file-upload/single-file-upload.component.scss +3 -2
- package/filter-bar/filters.scss +7 -0
- package/filter-bar/pipes/base-pipe.scss +3 -3
- package/filter-bar/pipes/pipe-date.scss +8 -1
- package/flag/flag-tokens.scss +22 -0
- package/flag/flag.scss +34 -21
- package/form-field/{_fiedset-theme.scss → _fieldset-theme.scss} +1 -5
- package/form-field/_form-field-theme.scss +4 -9
- package/form-field/cleaner.scss +3 -1
- package/form-field/fieldset.scss +3 -4
- package/form-field/form-field.scss +26 -21
- package/form-field/password-toggle.scss +3 -1
- package/icon/_icon-button-theme.scss +7 -0
- package/icon/_icon-theme.scss +10 -7
- package/icon/icon-button.scss +0 -2
- package/icon/icon-tokens.scss +12 -9
- package/inline-edit/inline-edit.scss +40 -54
- package/input/input.scss +4 -0
- package/link/{_link-theme.scss → deprecated/_link-theme.scss} +11 -6
- package/link/deprecated/link-tokens.scss +27 -0
- package/link/link-tokens.scss +6 -25
- package/link/link.scss +137 -0
- package/list/list.scss +3 -2
- package/loader-overlay/_loader-overlay-theme.scss +19 -10
- package/loader-overlay/loader-overlay-tokens.scss +0 -2
- package/loader-overlay/loader-overlay.scss +7 -1
- package/markdown/_markdown-theme.scss +16 -0
- package/markdown/markdown-tokens.scss +5 -0
- package/markdown/markdown.scss +2 -1
- package/modal/_modal-animation.scss +23 -14
- package/modal/modal-tokens.scss +2 -1
- package/modal/modal.scss +35 -31
- package/navbar/_navbar-item_horizontal.scss +8 -6
- package/navbar/_navbar-item_vertical.scss +18 -6
- package/navbar/_navbar-theme.scss +9 -1
- package/navbar/navbar-brand.scss +8 -6
- package/navbar/navbar-divider.scss +1 -1
- package/navbar/navbar-item.scss +8 -9
- package/navbar/navbar-toggle.scss +3 -3
- package/navbar/navbar-tokens.scss +14 -0
- package/navbar/navbar.scss +1 -2
- package/navbar/vertical-navbar.scss +2 -2
- package/notification-center/_notification-center-theme.scss +11 -6
- package/notification-center/notification-center-tokens.scss +33 -0
- package/notification-center/notification-center.scss +58 -20
- package/notification-center/notification-item.scss +15 -6
- package/package.json +112 -81
- package/popover/popover-tokens.scss +0 -2
- package/popover/popover.scss +41 -19
- package/prebuilt-themes/theme.css +1 -1
- package/progress-bar/_progress-bar-theme.scss +20 -3
- package/progress-bar/progress-bar-tokens.scss +3 -0
- package/progress-bar/progress-bar.scss +36 -8
- package/progress-spinner/progress-spinner.scss +4 -3
- package/radio/_radio-theme.scss +21 -4
- package/radio/radio-tokens.scss +7 -3
- package/radio/radio.scss +55 -8
- package/schematics/collection.json +415 -18
- package/schematics/migrations/accordion-state-saving-default/README.md +60 -0
- package/schematics/migrations/accordion-state-saving-default/data.cjs +75 -0
- package/schematics/migrations/accordion-state-saving-default/index.cjs +61 -0
- package/schematics/migrations/accordion-state-saving-default/schema.json +15 -0
- package/schematics/migrations/actions-panel-overlay-container/README.md +35 -0
- package/schematics/migrations/actions-panel-overlay-container/data.cjs +47 -0
- package/schematics/migrations/actions-panel-overlay-container/index.cjs +55 -0
- package/schematics/migrations/actions-panel-overlay-container/schema.json +15 -0
- package/schematics/migrations/alert-signals/README.md +13 -7
- package/schematics/migrations/alert-signals/{data.js → data.cjs} +3 -0
- package/schematics/migrations/alert-signals/index.cjs +221 -0
- package/schematics/migrations/angular-animations-removal/README.md +46 -0
- package/schematics/migrations/angular-animations-removal/data.cjs +150 -0
- package/schematics/migrations/angular-animations-removal/index.cjs +21 -0
- package/schematics/migrations/angular-animations-removal/schema.json +15 -0
- package/schematics/migrations/app-switcher-signals/README.md +88 -0
- package/schematics/migrations/app-switcher-signals/data.cjs +136 -0
- package/schematics/migrations/app-switcher-signals/index.cjs +366 -0
- package/schematics/migrations/app-switcher-signals/schema.json +20 -0
- package/schematics/migrations/autocomplete-panel-width-auto/README.md +2 -2
- package/schematics/migrations/autocomplete-panel-width-auto/{index.js → index.cjs} +6 -5
- package/schematics/migrations/autocomplete-signals/README.md +92 -0
- package/schematics/migrations/autocomplete-signals/data.cjs +149 -0
- package/schematics/migrations/autocomplete-signals/index.cjs +707 -0
- package/schematics/migrations/autocomplete-signals/schema.json +20 -0
- package/schematics/migrations/badge-signals/README.md +77 -0
- package/schematics/migrations/badge-signals/data.cjs +109 -0
- package/schematics/migrations/badge-signals/index.cjs +694 -0
- package/schematics/migrations/badge-signals/schema.json +20 -0
- package/schematics/migrations/button-state-and-styles/README.md +129 -0
- package/schematics/migrations/button-state-and-styles/data.cjs +136 -0
- package/schematics/migrations/button-state-and-styles/index.cjs +221 -0
- package/schematics/migrations/button-state-and-styles/schema.json +20 -0
- package/schematics/migrations/button-supported-colors/README.md +73 -0
- package/schematics/migrations/button-supported-colors/data.cjs +106 -0
- package/schematics/migrations/button-supported-colors/index.cjs +261 -0
- package/schematics/migrations/button-supported-colors/schema.json +20 -0
- package/schematics/migrations/button-toggle-signals-and-aria/README.md +137 -0
- package/schematics/migrations/button-toggle-signals-and-aria/data.cjs +200 -0
- package/schematics/migrations/button-toggle-signals-and-aria/index.cjs +497 -0
- package/schematics/migrations/button-toggle-signals-and-aria/schema.json +20 -0
- package/schematics/migrations/button-truncation/README.md +110 -0
- package/schematics/migrations/button-truncation/data.cjs +88 -0
- package/schematics/migrations/button-truncation/index.cjs +270 -0
- package/schematics/migrations/button-truncation/schema.json +20 -0
- package/schematics/migrations/checkbox-signals/README.md +76 -0
- package/schematics/migrations/checkbox-signals/data.cjs +114 -0
- package/schematics/migrations/checkbox-signals/index.cjs +635 -0
- package/schematics/migrations/checkbox-signals/schema.json +20 -0
- package/schematics/migrations/clamped-text-disclosure/README.md +62 -0
- package/schematics/migrations/clamped-text-disclosure/data.cjs +101 -0
- package/schematics/migrations/clamped-text-disclosure/index.cjs +60 -0
- package/schematics/migrations/clamped-text-disclosure/schema.json +15 -0
- package/schematics/migrations/code-block-highlight-js-core/README.md +53 -0
- package/schematics/migrations/code-block-highlight-js-core/data.cjs +64 -0
- package/schematics/migrations/code-block-highlight-js-core/index.cjs +319 -0
- package/schematics/migrations/code-block-highlight-js-core/schema.json +20 -0
- package/schematics/migrations/code-block-signals/README.md +84 -0
- package/schematics/migrations/code-block-signals/data.cjs +121 -0
- package/schematics/migrations/code-block-signals/index.cjs +701 -0
- package/schematics/migrations/code-block-signals/schema.json +20 -0
- package/schematics/migrations/color-signals/README.md +46 -0
- package/schematics/migrations/color-signals/data.cjs +131 -0
- package/schematics/migrations/color-signals/index.cjs +20 -0
- package/schematics/migrations/color-signals/schema.json +20 -0
- package/schematics/migrations/core-mixins-removal/README.md +20 -0
- package/schematics/migrations/core-mixins-removal/data.cjs +27 -0
- package/schematics/migrations/core-mixins-removal/index.cjs +18 -0
- package/schematics/migrations/core-mixins-removal/schema.json +15 -0
- package/schematics/migrations/css-selectors/README.md +2 -2
- package/schematics/migrations/css-selectors/{index.js → index.cjs} +4 -3
- package/schematics/migrations/datepicker-signals/README.md +24 -0
- package/schematics/migrations/datepicker-signals/data.cjs +49 -0
- package/schematics/migrations/datepicker-signals/index.cjs +18 -0
- package/schematics/migrations/datepicker-signals/schema.json +15 -0
- package/schematics/migrations/deprecated-icons/README.md +2 -2
- package/schematics/migrations/deprecated-icons/{index.js → index.cjs} +8 -7
- package/schematics/migrations/design-tokens-v4/README.md +75 -0
- package/schematics/migrations/design-tokens-v4/index.cjs +60 -0
- package/schematics/migrations/design-tokens-v4/schema.json +15 -0
- package/schematics/migrations/divider-signals-and-aria/README.md +47 -0
- package/schematics/migrations/divider-signals-and-aria/data.cjs +62 -0
- package/schematics/migrations/divider-signals-and-aria/index.cjs +212 -0
- package/schematics/migrations/divider-signals-and-aria/schema.json +15 -0
- package/schematics/migrations/dl-attribute-coercion/README.md +59 -0
- package/schematics/migrations/dl-attribute-coercion/data.cjs +85 -0
- package/schematics/migrations/dl-attribute-coercion/index.cjs +162 -0
- package/schematics/migrations/dl-attribute-coercion/schema.json +15 -0
- package/schematics/migrations/dl-standalone-names/README.md +49 -0
- package/schematics/migrations/dl-standalone-names/data.cjs +44 -0
- package/schematics/migrations/dl-standalone-names/index.cjs +322 -0
- package/schematics/migrations/dl-standalone-names/schema.json +20 -0
- package/schematics/migrations/dropdown-demote-overlay/README.md +137 -0
- package/schematics/migrations/dropdown-demote-overlay/data.cjs +84 -0
- package/schematics/migrations/dropdown-demote-overlay/index.cjs +289 -0
- package/schematics/migrations/dropdown-demote-overlay/schema.json +20 -0
- package/schematics/migrations/dropdown-signals/README.md +83 -0
- package/schematics/migrations/dropdown-signals/data.cjs +152 -0
- package/schematics/migrations/dropdown-signals/index.cjs +20 -0
- package/schematics/migrations/dropdown-signals/schema.json +20 -0
- package/schematics/migrations/empty-state-error-color/README.md +84 -0
- package/schematics/migrations/empty-state-error-color/data.cjs +85 -0
- package/schematics/migrations/empty-state-error-color/index.cjs +72 -0
- package/schematics/migrations/empty-state-error-color/schema.json +15 -0
- package/schematics/migrations/empty-state-size-attr/README.md +2 -2
- package/schematics/migrations/empty-state-size-attr/{index.js → index.cjs} +6 -5
- package/schematics/migrations/file-upload-cva-and-primitives/README.md +70 -0
- package/schematics/migrations/file-upload-cva-and-primitives/data.cjs +97 -0
- package/schematics/migrations/file-upload-cva-and-primitives/index.cjs +61 -0
- package/schematics/migrations/file-upload-cva-and-primitives/schema.json +15 -0
- package/schematics/migrations/file-upload-deprecated-outputs/README.md +90 -0
- package/schematics/migrations/file-upload-deprecated-outputs/data.cjs +20 -0
- package/schematics/migrations/file-upload-deprecated-outputs/index.cjs +71 -0
- package/schematics/migrations/file-upload-deprecated-outputs/schema.json +20 -0
- package/schematics/migrations/filter-bar-rename-action/README.md +183 -0
- package/schematics/migrations/filter-bar-rename-action/data.cjs +151 -0
- package/schematics/migrations/filter-bar-rename-action/index.cjs +178 -0
- package/schematics/migrations/filter-bar-rename-action/schema.json +20 -0
- package/schematics/migrations/filter-bar-signals/README.md +27 -16
- package/schematics/migrations/filter-bar-signals/{data.js → data.cjs} +1 -2
- package/schematics/migrations/filter-bar-signals/index.cjs +225 -0
- package/schematics/migrations/filter-bar-state-saving-default/README.md +53 -0
- package/schematics/migrations/filter-bar-state-saving-default/data.cjs +87 -0
- package/schematics/migrations/filter-bar-state-saving-default/index.cjs +62 -0
- package/schematics/migrations/filter-bar-state-saving-default/schema.json +15 -0
- package/schematics/migrations/flag-inner-html/README.md +67 -0
- package/schematics/migrations/flag-inner-html/data.cjs +58 -0
- package/schematics/migrations/flag-inner-html/index.cjs +62 -0
- package/schematics/migrations/flag-inner-html/schema.json +15 -0
- package/schematics/migrations/form-field-signals/README.md +125 -0
- package/schematics/migrations/form-field-signals/data.cjs +288 -0
- package/schematics/migrations/form-field-signals/index.cjs +383 -0
- package/schematics/migrations/form-field-signals/schema.json +20 -0
- package/schematics/migrations/icon-semantics-and-api/README.md +65 -0
- package/schematics/migrations/icon-semantics-and-api/data.cjs +97 -0
- package/schematics/migrations/icon-semantics-and-api/index.cjs +65 -0
- package/schematics/migrations/icon-semantics-and-api/schema.json +15 -0
- package/schematics/migrations/icons-replacement/README.md +5 -5
- package/schematics/migrations/icons-replacement/{index.js → index.cjs} +4 -3
- package/schematics/migrations/inline-edit-a11y-and-types/README.md +82 -0
- package/schematics/migrations/inline-edit-a11y-and-types/data.cjs +117 -0
- package/schematics/migrations/inline-edit-a11y-and-types/index.cjs +98 -0
- package/schematics/migrations/inline-edit-a11y-and-types/schema.json +20 -0
- package/schematics/migrations/input-number-surface/README.md +140 -0
- package/schematics/migrations/input-number-surface/data.cjs +135 -0
- package/schematics/migrations/input-number-surface/index.cjs +293 -0
- package/schematics/migrations/input-number-surface/schema.json +20 -0
- package/schematics/migrations/input-signals/README.md +20 -0
- package/schematics/migrations/input-signals/data.cjs +30 -0
- package/schematics/migrations/input-signals/index.cjs +18 -0
- package/schematics/migrations/input-signals/schema.json +15 -0
- package/schematics/migrations/link-deprecated-path/README.md +144 -0
- package/schematics/migrations/link-deprecated-path/index.cjs +20 -0
- package/schematics/migrations/link-deprecated-path/schema.json +20 -0
- package/schematics/migrations/link-signals/README.md +71 -0
- package/schematics/migrations/link-signals/data.cjs +116 -0
- package/schematics/migrations/link-signals/index.cjs +416 -0
- package/schematics/migrations/link-signals/schema.json +20 -0
- package/schematics/migrations/list-signals/README.md +22 -0
- package/schematics/migrations/list-signals/data.cjs +35 -0
- package/schematics/migrations/list-signals/index.cjs +18 -0
- package/schematics/migrations/list-signals/schema.json +15 -0
- package/schematics/migrations/list-tree-multiple-input/README.md +105 -0
- package/schematics/migrations/list-tree-multiple-input/data.cjs +74 -0
- package/schematics/migrations/list-tree-multiple-input/index.cjs +222 -0
- package/schematics/migrations/list-tree-multiple-input/schema.json +20 -0
- package/schematics/migrations/loader-overlay-signals/README.md +62 -0
- package/schematics/migrations/loader-overlay-signals/data.cjs +101 -0
- package/schematics/migrations/loader-overlay-signals/index.cjs +698 -0
- package/schematics/migrations/loader-overlay-signals/schema.json +20 -0
- package/schematics/migrations/loader-overlay-size-attr/README.md +2 -2
- package/schematics/migrations/loader-overlay-size-attr/{index.js → index.cjs} +6 -5
- package/schematics/migrations/locale-configuration-providers/README.md +163 -0
- package/schematics/migrations/locale-configuration-providers/data.cjs +257 -0
- package/schematics/migrations/locale-configuration-providers/index.cjs +295 -0
- package/schematics/migrations/locale-configuration-providers/schema.json +20 -0
- package/schematics/migrations/mandatory-peer-dependencies/README.md +70 -0
- package/schematics/migrations/mandatory-peer-dependencies/index.cjs +43 -0
- package/schematics/migrations/mandatory-peer-dependencies/schema.json +15 -0
- package/schematics/migrations/markdown-signals/README.md +58 -0
- package/schematics/migrations/markdown-signals/data.cjs +79 -0
- package/schematics/migrations/markdown-signals/index.cjs +640 -0
- package/schematics/migrations/markdown-signals/schema.json +20 -0
- package/schematics/migrations/modal-dialog-semantics/README.md +106 -0
- package/schematics/migrations/modal-dialog-semantics/data.cjs +110 -0
- package/schematics/migrations/modal-dialog-semantics/index.cjs +59 -0
- package/schematics/migrations/modal-dialog-semantics/schema.json +15 -0
- package/schematics/migrations/modal-signals/README.md +88 -0
- package/schematics/migrations/modal-signals/data.cjs +132 -0
- package/schematics/migrations/modal-signals/index.cjs +20 -0
- package/schematics/migrations/modal-signals/schema.json +20 -0
- package/schematics/migrations/navbar-signals-and-aria/README.md +111 -0
- package/schematics/migrations/navbar-signals-and-aria/data.cjs +198 -0
- package/schematics/migrations/navbar-signals-and-aria/index.cjs +569 -0
- package/schematics/migrations/navbar-signals-and-aria/schema.json +20 -0
- package/schematics/migrations/new-icons-pack/README.md +10 -10
- package/schematics/migrations/new-icons-pack/{index.js → index.cjs} +8 -7
- package/schematics/migrations/notification-center-signals/README.md +67 -0
- package/schematics/migrations/notification-center-signals/data.cjs +66 -0
- package/schematics/migrations/notification-center-signals/index.cjs +62 -0
- package/schematics/migrations/notification-center-signals/schema.json +15 -0
- package/schematics/migrations/option-signals/README.md +37 -0
- package/schematics/migrations/option-signals/data.cjs +86 -0
- package/schematics/migrations/option-signals/index.cjs +20 -0
- package/schematics/migrations/option-signals/schema.json +20 -0
- package/schematics/migrations/popover-leave-delay/README.md +51 -0
- package/schematics/migrations/popover-leave-delay/data.cjs +61 -0
- package/schematics/migrations/popover-leave-delay/index.cjs +55 -0
- package/schematics/migrations/popover-leave-delay/schema.json +15 -0
- package/schematics/migrations/progress-bar-percentage-and-aria/README.md +54 -0
- package/schematics/migrations/progress-bar-percentage-and-aria/data.cjs +76 -0
- package/schematics/migrations/progress-bar-percentage-and-aria/index.cjs +59 -0
- package/schematics/migrations/progress-bar-percentage-and-aria/schema.json +15 -0
- package/schematics/migrations/progress-spinner-signals/README.md +72 -0
- package/schematics/migrations/progress-spinner-signals/data.cjs +83 -0
- package/schematics/migrations/progress-spinner-signals/index.cjs +695 -0
- package/schematics/migrations/progress-spinner-signals/schema.json +20 -0
- package/schematics/migrations/query-list-signals/README.md +32 -0
- package/schematics/migrations/query-list-signals/data.cjs +70 -0
- package/schematics/migrations/query-list-signals/index.cjs +18 -0
- package/schematics/migrations/query-list-signals/schema.json +15 -0
- package/schematics/migrations/radio-signals-and-aria/README.md +82 -0
- package/schematics/migrations/radio-signals-and-aria/data.cjs +163 -0
- package/schematics/migrations/radio-signals-and-aria/index.cjs +40 -0
- package/schematics/migrations/radio-signals-and-aria/schema.json +20 -0
- package/schematics/migrations/read-state-dwell-handlers/README.md +125 -0
- package/schematics/migrations/read-state-dwell-handlers/data.cjs +45 -0
- package/schematics/migrations/read-state-dwell-handlers/index.cjs +216 -0
- package/schematics/migrations/read-state-dwell-handlers/schema.json +20 -0
- package/schematics/migrations/scrollbar-deprecated-path/README.md +128 -0
- package/schematics/migrations/scrollbar-deprecated-path/index.cjs +21 -0
- package/schematics/migrations/scrollbar-deprecated-path/schema.json +20 -0
- package/schematics/migrations/select-signal-inputs/README.md +61 -0
- package/schematics/migrations/select-signal-inputs/data.cjs +99 -0
- package/schematics/migrations/select-signal-inputs/index.cjs +58 -0
- package/schematics/migrations/select-signal-inputs/schema.json +15 -0
- package/schematics/migrations/sidepanel-non-modal-behavior/README.md +57 -0
- package/schematics/migrations/sidepanel-non-modal-behavior/data.cjs +111 -0
- package/schematics/migrations/sidepanel-non-modal-behavior/index.cjs +58 -0
- package/schematics/migrations/sidepanel-non-modal-behavior/schema.json +15 -0
- package/schematics/migrations/signal-inputs-subclasses/README.md +28 -0
- package/schematics/migrations/signal-inputs-subclasses/data.cjs +69 -0
- package/schematics/migrations/signal-inputs-subclasses/index.cjs +18 -0
- package/schematics/migrations/signal-inputs-subclasses/schema.json +15 -0
- package/schematics/migrations/split-button-optional-disabled/README.md +47 -0
- package/schematics/migrations/split-button-optional-disabled/data.cjs +53 -0
- package/schematics/migrations/split-button-optional-disabled/index.cjs +58 -0
- package/schematics/migrations/split-button-optional-disabled/schema.json +15 -0
- package/schematics/migrations/splitter-deprecated-path/README.md +136 -0
- package/schematics/migrations/splitter-deprecated-path/index.cjs +21 -0
- package/schematics/migrations/splitter-deprecated-path/schema.json +20 -0
- package/schematics/migrations/state-saving-default/README.md +67 -0
- package/schematics/migrations/state-saving-default/data.cjs +88 -0
- package/schematics/migrations/state-saving-default/index.cjs +63 -0
- package/schematics/migrations/state-saving-default/schema.json +15 -0
- package/schematics/migrations/table-cell-content/README.md +55 -0
- package/schematics/migrations/table-cell-content/data.cjs +66 -0
- package/schematics/migrations/table-cell-content/index.cjs +67 -0
- package/schematics/migrations/table-cell-content/schema.json +15 -0
- package/schematics/migrations/tabs-signals-and-aria/README.md +93 -0
- package/schematics/migrations/tabs-signals-and-aria/data.cjs +139 -0
- package/schematics/migrations/tabs-signals-and-aria/index.cjs +66 -0
- package/schematics/migrations/tabs-signals-and-aria/schema.json +15 -0
- package/schematics/migrations/tag-list-cleaner/README.md +58 -0
- package/schematics/migrations/tag-list-cleaner/data.cjs +42 -0
- package/schematics/migrations/tag-list-cleaner/index.cjs +197 -0
- package/schematics/migrations/tag-list-cleaner/schema.json +20 -0
- package/schematics/migrations/tag-slots/README.md +41 -0
- package/schematics/migrations/tag-slots/index.cjs +191 -0
- package/schematics/migrations/tag-slots/schema.json +20 -0
- package/schematics/migrations/tags-signals/README.md +85 -0
- package/schematics/migrations/tags-signals/data.cjs +103 -0
- package/schematics/migrations/tags-signals/index.cjs +674 -0
- package/schematics/migrations/tags-signals/schema.json +20 -0
- package/schematics/migrations/textarea-signals/README.md +72 -0
- package/schematics/migrations/textarea-signals/data.cjs +121 -0
- package/schematics/migrations/textarea-signals/index.cjs +380 -0
- package/schematics/migrations/textarea-signals/schema.json +20 -0
- package/schematics/migrations/time-range-title-for/README.md +164 -0
- package/schematics/migrations/time-range-title-for/data.cjs +139 -0
- package/schematics/migrations/time-range-title-for/index.cjs +164 -0
- package/schematics/migrations/time-range-title-for/schema.json +20 -0
- package/schematics/migrations/timepicker-signals/README.md +78 -0
- package/schematics/migrations/timepicker-signals/data.cjs +82 -0
- package/schematics/migrations/timepicker-signals/index.cjs +710 -0
- package/schematics/migrations/timepicker-signals/schema.json +20 -0
- package/schematics/migrations/timezone-grouping-utils/README.md +73 -0
- package/schematics/migrations/timezone-grouping-utils/data.cjs +101 -0
- package/schematics/migrations/timezone-grouping-utils/index.cjs +65 -0
- package/schematics/migrations/timezone-grouping-utils/schema.json +15 -0
- package/schematics/migrations/title-encapsulation/README.md +49 -0
- package/schematics/migrations/title-encapsulation/data.cjs +69 -0
- package/schematics/migrations/title-encapsulation/index.cjs +58 -0
- package/schematics/migrations/title-encapsulation/schema.json +15 -0
- package/schematics/migrations/toast-stack-and-defaults/README.md +102 -0
- package/schematics/migrations/toast-stack-and-defaults/data.cjs +79 -0
- package/schematics/migrations/toast-stack-and-defaults/index.cjs +54 -0
- package/schematics/migrations/toast-stack-and-defaults/schema.json +15 -0
- package/schematics/migrations/tooltip-pointer-events-and-types/README.md +53 -0
- package/schematics/migrations/tooltip-pointer-events-and-types/data.cjs +89 -0
- package/schematics/migrations/tooltip-pointer-events-and-types/index.cjs +61 -0
- package/schematics/migrations/tooltip-pointer-events-and-types/schema.json +15 -0
- package/schematics/migrations/top-bar-container-selectors/README.md +111 -0
- package/schematics/migrations/top-bar-container-selectors/data.cjs +56 -0
- package/schematics/migrations/top-bar-container-selectors/index.cjs +85 -0
- package/schematics/migrations/top-bar-container-selectors/schema.json +20 -0
- package/schematics/migrations/tree-select-signals/README.md +61 -0
- package/schematics/migrations/tree-select-signals/data.cjs +106 -0
- package/schematics/migrations/tree-select-signals/index.cjs +59 -0
- package/schematics/migrations/tree-select-signals/schema.json +15 -0
- package/schematics/migrations/tree-signals/README.md +82 -0
- package/schematics/migrations/tree-signals/data.cjs +123 -0
- package/schematics/migrations/tree-signals/index.cjs +55 -0
- package/schematics/migrations/tree-signals/schema.json +15 -0
- package/schematics/migrations/tree-state-saving-default/README.md +66 -0
- package/schematics/migrations/tree-state-saving-default/data.cjs +78 -0
- package/schematics/migrations/tree-state-saving-default/index.cjs +61 -0
- package/schematics/migrations/tree-state-saving-default/schema.json +15 -0
- package/schematics/migrations/username-pipe-injection/README.md +59 -0
- package/schematics/migrations/username-pipe-injection/data.cjs +78 -0
- package/schematics/migrations/username-pipe-injection/index.cjs +59 -0
- package/schematics/migrations/username-pipe-injection/schema.json +15 -0
- package/schematics/migrations/v20-upgrade/README.md +36 -16
- package/schematics/migrations/v20-upgrade/{data.js → data.cjs} +124 -77
- package/schematics/migrations/v20-upgrade/index.cjs +19 -0
- package/schematics/migrations/v21-upgrade/README.md +271 -0
- package/schematics/migrations/v21-upgrade/data.cjs +1371 -0
- package/schematics/migrations/v21-upgrade/index.cjs +95 -0
- package/schematics/migrations/v21-upgrade/schema.json +20 -0
- package/schematics/migrations/zoneless-change-detection/README.md +30 -0
- package/schematics/migrations/zoneless-change-detection/data.cjs +29 -0
- package/schematics/migrations/zoneless-change-detection/index.cjs +21 -0
- package/schematics/migrations/zoneless-change-detection/schema.json +15 -0
- package/schematics/migrations.json +401 -6
- package/schematics/ng-add/index.cjs +266 -0
- package/schematics/ng-add/schema.json +15 -0
- package/schematics/utils/{angular-parsing.js → angular-parsing.cjs} +2 -2
- package/schematics/utils/deprecated-path-migration.cjs +62 -0
- package/schematics/utils/html-config.cjs +148 -0
- package/schematics/utils/{icon-migration.js → icon-migration.cjs} +2 -2
- package/schematics/utils/list-item-pattern.cjs +16 -0
- package/schematics/utils/{package-config.js → package-config.cjs} +3 -32
- package/schematics/utils/project-files.cjs +25 -0
- package/schematics/utils/replacement-driver.cjs +337 -0
- package/schematics/utils/safe-rule.cjs +23 -0
- package/schematics/utils/signal-members-migration.cjs +779 -0
- package/schematics/utils/tag-patterns.cjs +21 -0
- package/schematics/utils/template-ref-access.cjs +155 -0
- package/schematics/utils/{typescript.js → typescript.cjs} +1 -1
- package/schematics/utils/warn-only-migration.cjs +52 -0
- package/schematics/utils/workspace-styles.cjs +123 -0
- package/scrollbar/{_scrollbar-component-theme.scss → deprecated/_scrollbar-component-theme.scss} +1 -1
- package/scrollbar/{scrollbar.component.scss → deprecated/scrollbar.component.scss} +1 -1
- package/scrollbar/native-scrollbar.scss +68 -0
- package/scrollbar/scrollbar-tokens.scss +13 -22
- package/scrollbar/scrollbar-track.scss +94 -0
- package/scrollbar/scrollbar-viewport.scss +33 -0
- package/scrollbar/scrollbar.scss +24 -0
- package/search-expandable/search-expandable-tokens.scss +4 -0
- package/search-expandable/search-expandable.scss +4 -2
- package/select/_select-theme.scss +3 -16
- package/select/select.scss +0 -6
- package/sidebar/sidebar.scss +20 -0
- package/sidepanel/_sidepanel-theme.scss +1 -1
- package/sidepanel/sidepanel-tokens.scss +7 -1
- package/sidepanel/sidepanel.scss +41 -5
- package/skeleton/skeleton-presets.scss +350 -0
- package/skeleton/skeleton-tokens.scss +127 -0
- package/skeleton/skeleton.scss +53 -45
- package/split-button/_split-button-theme.scss +4 -4
- package/split-button/split-button.scss +2 -6
- package/splitter/{_splitter-theme.scss → deprecated/_splitter-theme.scss} +1 -1
- package/splitter/deprecated/splitter.scss +51 -0
- package/splitter/splitter-tokens.scss +19 -0
- package/splitter/splitter.scss +148 -28
- package/table/_table-theme.scss +13 -12
- package/table/table-tokens.scss +8 -0
- package/table/table.scss +47 -22
- package/tabs/_tabs-common.scss +14 -14
- package/tabs/_tabs-theme.scss +4 -5
- package/tabs/tab-body.scss +49 -1
- package/tabs/tab-header.scss +2 -1
- package/tags/tag-list.scss +4 -0
- package/tags/tag.scss +19 -1
- package/time-range/time-range.scss +9 -0
- package/timezone/timezone-option.component.scss +4 -7
- package/timezone/timezone-select.component.scss +3 -0
- package/toast/_toast-theme.scss +1 -4
- package/toast/toast-container.component.scss +19 -13
- package/toast/toast-tokens.scss +12 -6
- package/toast/toast.component.scss +42 -19
- package/toggle/_toggle-theme.scss +4 -10
- package/toggle/toggle.scss +67 -26
- package/tooltip/_tooltip-theme.scss +7 -1
- package/tooltip/tooltip-tokens.scss +1 -2
- package/tooltip/tooltip.scss +55 -9
- package/top-bar/top-bar-tokens.scss +13 -2
- package/top-bar/top-bar.scss +24 -19
- package/tree/_tree-theme.scss +0 -1
- package/tree/toggle.scss +5 -9
- package/tree/tree-option.scss +2 -4
- package/tree/tree-tokens.scss +2 -1
- package/tree/tree.scss +3 -5
- package/tree-select/_tree-select-theme.scss +4 -15
- package/tree-select/tree-select-tokens.scss +16 -0
- package/tree-select/tree-select.scss +0 -6
- package/{accordion/index.d.ts → types/koobiq-components-accordion.d.ts} +102 -84
- package/{actions-panel/index.d.ts → types/koobiq-components-actions-panel.d.ts} +44 -59
- package/{alert/index.d.ts → types/koobiq-components-alert.d.ts} +8 -3
- package/types/koobiq-components-app-switcher.d.ts +406 -0
- package/types/koobiq-components-autocomplete.d.ts +443 -0
- package/{badge/index.d.ts → types/koobiq-components-badge.d.ts} +25 -20
- package/{breadcrumbs/index.d.ts → types/koobiq-components-breadcrumbs.d.ts} +97 -46
- package/types/koobiq-components-button-toggle.d.ts +340 -0
- package/types/koobiq-components-button.d.ts +296 -0
- package/types/koobiq-components-checkbox.d.ts +172 -0
- package/types/koobiq-components-clamped-text.d.ts +184 -0
- package/{code-block/index.d.ts → types/koobiq-components-code-block.d.ts} +150 -88
- package/{content-panel/index.d.ts → types/koobiq-components-content-panel.d.ts} +81 -25
- package/{core/index.d.ts → types/koobiq-components-core.d.ts} +2827 -865
- package/{datepicker/index.d.ts → types/koobiq-components-datepicker.d.ts} +161 -116
- package/types/koobiq-components-divider.d.ts +43 -0
- package/types/koobiq-components-dl.d.ts +235 -0
- package/{dropdown/index.d.ts → types/koobiq-components-dropdown.d.ts} +245 -239
- package/types/koobiq-components-ellipsis-center.d.ts +85 -0
- package/types/koobiq-components-empty-state.d.ts +106 -0
- package/{file-upload/index.d.ts → types/koobiq-components-file-upload.d.ts} +214 -107
- package/{filter-bar/index.d.ts → types/koobiq-components-filter-bar.d.ts} +410 -495
- package/types/koobiq-components-flag.d.ts +68 -0
- package/{form-field/index.d.ts → types/koobiq-components-form-field.d.ts} +167 -191
- package/types/koobiq-components-icon.d.ts +333 -0
- package/{inline-edit/index.d.ts → types/koobiq-components-inline-edit.d.ts} +109 -46
- package/types/koobiq-components-input.d.ts +477 -0
- package/types/koobiq-components-link-deprecated.d.ts +101 -0
- package/types/koobiq-components-link.d.ts +176 -0
- package/{list/index.d.ts → types/koobiq-components-list.d.ts} +162 -99
- package/types/koobiq-components-loader-overlay.d.ts +101 -0
- package/{markdown/index.d.ts → types/koobiq-components-markdown.d.ts} +16 -24
- package/types/koobiq-components-modal.d.ts +666 -0
- package/types/koobiq-components-navbar.d.ts +569 -0
- package/types/koobiq-components-notification-center.d.ts +500 -0
- package/{overflow-items/index.d.ts → types/koobiq-components-overflow-items.d.ts} +8 -22
- package/types/koobiq-components-popover.d.ts +468 -0
- package/types/koobiq-components-progress-bar.d.ts +67 -0
- package/{progress-spinner/index.d.ts → types/koobiq-components-progress-spinner.d.ts} +33 -10
- package/types/koobiq-components-radio.d.ts +294 -0
- package/{resizer/index.d.ts → types/koobiq-components-resizer.d.ts} +37 -2
- package/{scrollbar/index.d.ts → types/koobiq-components-scrollbar-deprecated.d.ts} +18 -1
- package/types/koobiq-components-scrollbar.d.ts +154 -0
- package/types/koobiq-components-search-expandable.d.ts +164 -0
- package/{select/index.d.ts → types/koobiq-components-select.d.ts} +360 -167
- package/types/koobiq-components-sidebar.d.ts +152 -0
- package/types/koobiq-components-sidepanel.d.ts +436 -0
- package/types/koobiq-components-skeleton.d.ts +234 -0
- package/types/koobiq-components-split-button.d.ts +65 -0
- package/{splitter/index.d.ts → types/koobiq-components-splitter-deprecated.d.ts} +44 -1
- package/types/koobiq-components-splitter.d.ts +406 -0
- package/types/koobiq-components-table.d.ts +44 -0
- package/types/koobiq-components-tabs.d.ts +888 -0
- package/{tags/index.d.ts → types/koobiq-components-tags.d.ts} +249 -133
- package/types/koobiq-components-textarea.d.ts +178 -0
- package/{time-range/index.d.ts → types/koobiq-components-time-range.d.ts} +135 -62
- package/types/koobiq-components-timepicker.d.ts +223 -0
- package/types/koobiq-components-timezone.d.ts +266 -0
- package/types/koobiq-components-title.d.ts +184 -0
- package/types/koobiq-components-toast.d.ts +289 -0
- package/types/koobiq-components-toggle.d.ts +121 -0
- package/types/koobiq-components-tooltip.d.ts +610 -0
- package/types/koobiq-components-top-bar.d.ts +61 -0
- package/types/koobiq-components-tree-select.d.ts +670 -0
- package/types/koobiq-components-tree.d.ts +1339 -0
- package/types/koobiq-components-username.d.ts +340 -0
- package/username/_username-theme.scss +35 -0
- package/username/username.scss +10 -34
- package/app-switcher/index.d.ts +0 -276
- package/autocomplete/index.d.ts +0 -286
- package/button/index.d.ts +0 -153
- package/button-toggle/index.d.ts +0 -162
- package/checkbox/index.d.ts +0 -163
- package/clamped-text/index.d.ts +0 -146
- package/core/styles/_tokens.scss +0 -7
- package/core/styles/common/_clearfix.scss +0 -13
- package/core/styles/common/_popup.scss +0 -6
- package/core/styles/functions/_index.scss +0 -3
- package/core/styles/functions/_number.scss +0 -60
- package/core/styles/functions/_string.scss +0 -18
- package/core/styles/theming/scrollbar-tokens.scss +0 -25
- package/core/styles/typography/_typography-utils.scss +0 -84
- package/divider/index.d.ts +0 -20
- package/dl/index.d.ts +0 -45
- package/ellipsis-center/index.d.ts +0 -71
- package/empty-state/index.d.ts +0 -45
- package/flag/index.d.ts +0 -44
- package/icon/index.d.ts +0 -200
- package/input/index.d.ts +0 -354
- package/link/index.d.ts +0 -56
- package/loader-overlay/index.d.ts +0 -57
- package/modal/index.d.ts +0 -339
- package/navbar/index.d.ts +0 -372
- package/notification-center/index.d.ts +0 -323
- package/popover/index.d.ts +0 -182
- package/prebuilt-themes/dark-theme.css +0 -1
- package/prebuilt-themes/light-theme.css +0 -1
- package/progress-bar/index.d.ts +0 -31
- package/radio/index.d.ts +0 -203
- package/schematics/migrations/alert-signals/index.js +0 -353
- package/schematics/migrations/filter-bar-signals/index.js +0 -319
- package/schematics/migrations/v20-upgrade/index.js +0 -225
- package/schematics/ng-add/index.js +0 -39
- package/search-expandable/index.d.ts +0 -101
- package/sidebar/index.d.ts +0 -94
- package/sidepanel/index.d.ts +0 -272
- package/skeleton/index.d.ts +0 -26
- package/split-button/index.d.ts +0 -46
- package/table/index.d.ts +0 -25
- package/tabs/index.d.ts +0 -677
- package/textarea/index.d.ts +0 -138
- package/timepicker/index.d.ts +0 -197
- package/timezone/index.d.ts +0 -125
- package/title/index.d.ts +0 -139
- package/toast/index.d.ts +0 -178
- package/toggle/index.d.ts +0 -104
- package/tooltip/index.d.ts +0 -335
- package/top-bar/index.d.ts +0 -33
- package/tree/index.d.ts +0 -802
- package/tree-select/index.d.ts +0 -475
- package/username/index.d.ts +0 -194
- /package/schematics/migrations/css-selectors/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/deprecated-icons/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/icons-replacement/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/new-icons-pack/{data.js → data.cjs} +0 -0
- /package/schematics/utils/{ast.js → ast.cjs} +0 -0
- /package/schematics/utils/{messages.js → messages.cjs} +0 -0
- /package/{dynamic-translation/index.d.ts → types/koobiq-components-dynamic-translation.d.ts} +0 -0
- /package/{index.d.ts → types/koobiq-components.d.ts} +0 -0
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { SelectionModel, DataSource } from '@angular/cdk/collections';
|
|
2
2
|
import { BehaviorSubject, merge, Observable, of, Subject, asyncScheduler } from 'rxjs';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
3
|
+
import * as i1 from '@koobiq/components/core';
|
|
4
|
+
import { escapeRegExp, KbqStateSaving, KbqPseudoCheckbox, KbqOptionActionComponent, kbqFocusAndReveal, kbqGetElementHeight, kbqFocusOptionActionOnTab, hasModifierKey, KbqActionContainer, KBQ_TITLE_TEXT_REF, KBQ_OPTION_ACTION_PARENT, MultipleMode, getSelectAllState, kbqQueryListFrom, KbqLocaleOverridesDirective, KBQ_SELECT_LOCALE_CONFIGURATION, kbqOptionalNumberAttribute, kbqSelectAllHandlerTransform, resolveMultipleMode, FocusKeyManager, kbqLeaveTabOrderOnTabOut, SPACE, LEFT_ARROW, RIGHT_ARROW, isVerticalMovement, isSelectAll, isCopy, TAB, DOWN_ARROW, UP_ARROW, ENTER, HOME, END, PAGE_UP, PAGE_DOWN, toggleSelectAll, getKbqSelectNonArrayValueError, KbqPseudoCheckboxModule } from '@koobiq/components/core';
|
|
5
|
+
import { take, map, delay, filter } from 'rxjs/operators';
|
|
5
6
|
import * as i0 from '@angular/core';
|
|
6
|
-
import { inject, TemplateRef, input, Directive, ViewContainerRef, ChangeDetectorRef,
|
|
7
|
+
import { signal, inject, TemplateRef, input, Directive, ViewContainerRef, IterableDiffers, ChangeDetectorRef, viewChild, contentChildren, DestroyRef, effect, untracked, isDevMode, ElementRef, booleanAttribute, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, InjectionToken, EnvironmentInjector, NgZone, Renderer2, contentChild, linkedSignal, output, EventEmitter, afterNextRender, forwardRef, Injector, QueryList, NgModule } from '@angular/core';
|
|
7
8
|
import { Directionality } from '@angular/cdk/bidi';
|
|
8
9
|
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
|
|
9
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
10
|
+
import { takeUntilDestroyed, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
|
|
11
|
+
import { _getFocusedElementPierceShadowDom, Platform } from '@angular/cdk/platform';
|
|
10
12
|
import { KbqDropdownTrigger } from '@koobiq/components/dropdown';
|
|
11
13
|
import { KbqTooltipTrigger } from '@koobiq/components/tooltip';
|
|
12
14
|
import { KbqIcon, KbqIconModule } from '@koobiq/components/icon';
|
|
13
15
|
import { FocusMonitor } from '@angular/cdk/a11y';
|
|
14
16
|
import { Clipboard } from '@angular/cdk/clipboard';
|
|
15
|
-
import { Platform } from '@angular/cdk/platform';
|
|
16
17
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
17
18
|
import { KBQ_FORM_FIELD } from '@koobiq/components/form-field';
|
|
18
19
|
import { AsyncScheduler } from 'rxjs/internal/scheduler/AsyncScheduler';
|
|
@@ -20,7 +21,7 @@ import { AsyncScheduler } from 'rxjs/internal/scheduler/AsyncScheduler';
|
|
|
20
21
|
/** Base tree control. It has basic toggle/expand/collapse operations on a single data node. */
|
|
21
22
|
class BaseTreeControl {
|
|
22
23
|
constructor() {
|
|
23
|
-
/** A selection model with multi-selection to track expansion status. */
|
|
24
|
+
/** A selection model with multi-selection to track expansion status: it holds the key of every expanded node. */
|
|
24
25
|
this.expansionModel = new SelectionModel(true);
|
|
25
26
|
this.filterModel = new SelectionModel(true);
|
|
26
27
|
this.filterValue = new BehaviorSubject('');
|
|
@@ -30,29 +31,29 @@ class BaseTreeControl {
|
|
|
30
31
|
if (this.filterValue.value?.length) {
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
|
-
this.expansionModel.toggle(dataNode);
|
|
34
|
+
this.expansionModel.toggle(this.expansionKey(dataNode));
|
|
34
35
|
}
|
|
35
36
|
/** Expands one single data node. */
|
|
36
37
|
expand(dataNode) {
|
|
37
38
|
if (this.filterValue.value?.length) {
|
|
38
39
|
return;
|
|
39
40
|
}
|
|
40
|
-
this.expansionModel.select(dataNode);
|
|
41
|
+
this.expansionModel.select(this.expansionKey(dataNode));
|
|
41
42
|
}
|
|
42
43
|
/** Collapses one single data node. */
|
|
43
44
|
collapse(dataNode) {
|
|
44
45
|
if (this.filterValue.value?.length) {
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
|
-
this.expansionModel.deselect(dataNode);
|
|
48
|
+
this.expansionModel.deselect(this.expansionKey(dataNode));
|
|
48
49
|
}
|
|
49
50
|
/** Whether a given data node is expanded or not. Returns true if the data node is expanded. */
|
|
50
51
|
isExpanded(dataNode) {
|
|
51
|
-
return this.expansionModel.isSelected(dataNode);
|
|
52
|
+
return this.expansionModel.isSelected(this.expansionKey(dataNode));
|
|
52
53
|
}
|
|
53
54
|
/** Toggles a subtree rooted at `node` recursively. */
|
|
54
55
|
toggleDescendants(dataNode) {
|
|
55
|
-
if (this.
|
|
56
|
+
if (this.isExpanded(dataNode)) {
|
|
56
57
|
this.collapseDescendants(dataNode);
|
|
57
58
|
}
|
|
58
59
|
else {
|
|
@@ -67,17 +68,26 @@ class BaseTreeControl {
|
|
|
67
68
|
expandDescendants(dataNode) {
|
|
68
69
|
const toBeProcessed = [dataNode];
|
|
69
70
|
toBeProcessed.push(...this.getDescendants(dataNode));
|
|
70
|
-
this.expansionModel.select(...toBeProcessed);
|
|
71
|
+
this.expansionModel.select(...toBeProcessed.map((node) => this.expansionKey(node)));
|
|
71
72
|
}
|
|
72
73
|
/** Collapses a subtree rooted at given data node recursively. */
|
|
73
74
|
collapseDescendants(dataNode) {
|
|
74
75
|
const toBeProcessed = [dataNode];
|
|
75
76
|
toBeProcessed.push(...this.getDescendants(dataNode));
|
|
76
|
-
this.expansionModel.deselect(...toBeProcessed);
|
|
77
|
+
this.expansionModel.deselect(...toBeProcessed.map((node) => this.expansionKey(node)));
|
|
78
|
+
}
|
|
79
|
+
/** The key `expansionModel` holds for a data node. */
|
|
80
|
+
expansionKey(dataNode) {
|
|
81
|
+
return this.trackBy ? this.trackBy(dataNode) : dataNode;
|
|
77
82
|
}
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
const kbqTreeSelectAllValue = 'selectAll';
|
|
86
|
+
/**
|
|
87
|
+
* Default first stage of the filter pipeline: keeps the nodes whose view value matches the query.
|
|
88
|
+
*
|
|
89
|
+
* @docs-private
|
|
90
|
+
*/
|
|
81
91
|
class FilterByViewValue {
|
|
82
92
|
constructor(control) {
|
|
83
93
|
this.control = control;
|
|
@@ -95,6 +105,12 @@ class FilterByViewValue {
|
|
|
95
105
|
return this.result;
|
|
96
106
|
}
|
|
97
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Default last stage of the filter pipeline: re-adds the ancestors of every matched node so the
|
|
110
|
+
* matches stay reachable in the rendered hierarchy.
|
|
111
|
+
*
|
|
112
|
+
* @docs-private
|
|
113
|
+
*/
|
|
98
114
|
class FilterParentsForNodes {
|
|
99
115
|
constructor(control) {
|
|
100
116
|
this.control = control;
|
|
@@ -124,6 +140,7 @@ class FilterByValues {
|
|
|
124
140
|
this.result = Array.from(new Set([...(prevFilter?.result || []), ...found]));
|
|
125
141
|
return this.result;
|
|
126
142
|
}
|
|
143
|
+
// TODO: nothing in the library uses it; kept as public API at the DS-2196 review. Document or deprecate it.
|
|
127
144
|
getValues() {
|
|
128
145
|
return this.values;
|
|
129
146
|
}
|
|
@@ -148,7 +165,9 @@ class FlatTreeControl extends BaseTreeControl {
|
|
|
148
165
|
/** compareValues will be used to comparing values. */
|
|
149
166
|
compareViewValues = defaultCompareViewValues,
|
|
150
167
|
/** isDisabled will be used to determine if the node is disabled. */
|
|
151
|
-
isDisabled = () => false
|
|
168
|
+
isDisabled = () => false,
|
|
169
|
+
/** Further options: the `trackBy` the nodes are expanded by. */
|
|
170
|
+
options) {
|
|
152
171
|
super();
|
|
153
172
|
this.getLevel = getLevel;
|
|
154
173
|
this.isExpandable = isExpandable;
|
|
@@ -157,8 +176,13 @@ class FlatTreeControl extends BaseTreeControl {
|
|
|
157
176
|
this.compareValues = compareValues;
|
|
158
177
|
this.compareViewValues = compareViewValues;
|
|
159
178
|
this.isDisabled = isDisabled;
|
|
179
|
+
// Positions in each `dataNodes` array: a tree looks up every rendered row, and `indexOf` would make that
|
|
180
|
+
// rows × nodes. Keyed weakly by the array, so replacing `dataNodes` releases the old nodes.
|
|
181
|
+
this.nodeIndexes = new WeakMap();
|
|
182
|
+
this.trackBy = options?.trackBy;
|
|
160
183
|
this.setFilters(new FilterByViewValue(this), new FilterParentsForNodes(this));
|
|
161
184
|
}
|
|
185
|
+
// TODO: nothing in the library uses it; kept as public API at the DS-2196 review. Document or deprecate it.
|
|
162
186
|
getFilters() {
|
|
163
187
|
return this.filters;
|
|
164
188
|
}
|
|
@@ -172,7 +196,7 @@ class FlatTreeControl extends BaseTreeControl {
|
|
|
172
196
|
* with correct levels.
|
|
173
197
|
*/
|
|
174
198
|
getDescendants(dataNode) {
|
|
175
|
-
const startIndex = this.
|
|
199
|
+
const startIndex = this.indexOfNode(dataNode);
|
|
176
200
|
const results = [];
|
|
177
201
|
// Goes through flattened tree nodes in the `dataNodes` array, and get all descendants.
|
|
178
202
|
// The level of descendants of a tree node must be greater than the level of the given
|
|
@@ -192,16 +216,34 @@ class FlatTreeControl extends BaseTreeControl {
|
|
|
192
216
|
* data nodes of the tree.
|
|
193
217
|
*/
|
|
194
218
|
expandAll() {
|
|
195
|
-
this.expansionModel.select(...this.dataNodes);
|
|
219
|
+
this.expansionModel.select(...this.dataNodes.map((node) => this.expansionKey(node)));
|
|
196
220
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
221
|
+
/**
|
|
222
|
+
* Ancestors of a data node, outermost first.
|
|
223
|
+
*
|
|
224
|
+
* Derived from `dataNodes` rather than from a `parent` back-reference: the flattened nodes are in
|
|
225
|
+
* depth-first order, so scanning backwards from the node, the first node of a smaller level is its
|
|
226
|
+
* parent, and repeating with that level yields the whole chain. A data node whose shape carries no
|
|
227
|
+
* `parent` therefore resolves just as well as one that does.
|
|
228
|
+
*
|
|
229
|
+
* @param result Collector the ancestors are prepended to. Provided so callers can accumulate into
|
|
230
|
+
* an existing array; a fresh one is used when omitted.
|
|
231
|
+
*/
|
|
232
|
+
getParents(node, result = []) {
|
|
233
|
+
const startIndex = this.indexOfNode(node);
|
|
234
|
+
if (startIndex === -1) {
|
|
203
235
|
return result;
|
|
204
236
|
}
|
|
237
|
+
let level = this.getLevel(node);
|
|
238
|
+
for (let i = startIndex - 1; i >= 0 && level > 0; i--) {
|
|
239
|
+
const candidate = this.dataNodes[i];
|
|
240
|
+
const candidateLevel = this.getLevel(candidate);
|
|
241
|
+
if (candidateLevel < level) {
|
|
242
|
+
result.unshift(candidate);
|
|
243
|
+
level = candidateLevel;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return result;
|
|
205
247
|
}
|
|
206
248
|
hasValue(value) {
|
|
207
249
|
return this.dataNodes?.find((node) => this.compareValues(this.getValue(node), value));
|
|
@@ -216,7 +258,7 @@ class FlatTreeControl extends BaseTreeControl {
|
|
|
216
258
|
this.filterModel.clear();
|
|
217
259
|
this.filterModel.select(...result);
|
|
218
260
|
// set current expansion state according to filtered tree
|
|
219
|
-
this.expansionModel.setSelection(...result.filter((node) => this.isExpandable(node)));
|
|
261
|
+
this.expansionModel.setSelection(...result.filter((node) => this.isExpandable(node)).map((node) => this.expansionKey(node)));
|
|
220
262
|
this.updateFilterValue(value || result);
|
|
221
263
|
Promise.resolve().then(() => this.restoreExpansionState());
|
|
222
264
|
}
|
|
@@ -233,14 +275,49 @@ class FlatTreeControl extends BaseTreeControl {
|
|
|
233
275
|
this.expansionModel.setSelection(...this.expandedItemsBeforeFiltration);
|
|
234
276
|
}
|
|
235
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Position of the node in `dataNodes`, constant-time while the index matches the array. With `trackBy` a node
|
|
280
|
+
* rebuilt as a new object since is found by its key, as the expansion methods accept it too.
|
|
281
|
+
*/
|
|
282
|
+
indexOfNode(node) {
|
|
283
|
+
const { dataNodes, trackBy } = this;
|
|
284
|
+
if (!dataNodes)
|
|
285
|
+
return -1;
|
|
286
|
+
const cached = this.nodeIndexes.get(dataNodes)?.get(node);
|
|
287
|
+
// Checked against the array: `dataNodes` can be mutated in place.
|
|
288
|
+
if (cached !== undefined && dataNodes[cached] === node)
|
|
289
|
+
return cached;
|
|
290
|
+
const index = dataNodes.indexOf(node);
|
|
291
|
+
// A node that is not there leaves the index as it is.
|
|
292
|
+
if (index === -1) {
|
|
293
|
+
if (!trackBy)
|
|
294
|
+
return index;
|
|
295
|
+
const key = trackBy(node);
|
|
296
|
+
return dataNodes.findIndex((candidate) => trackBy(candidate) === key);
|
|
297
|
+
}
|
|
298
|
+
const positions = new Map();
|
|
299
|
+
dataNodes.forEach((dataNode, position) => {
|
|
300
|
+
if (!positions.has(dataNode))
|
|
301
|
+
positions.set(dataNode, position);
|
|
302
|
+
});
|
|
303
|
+
this.nodeIndexes.set(dataNodes, positions);
|
|
304
|
+
return index;
|
|
305
|
+
}
|
|
236
306
|
}
|
|
237
307
|
|
|
238
308
|
/** Nested tree control. Able to expand/collapse a subtree recursively for NestedNode type. */
|
|
239
309
|
class NestedTreeControl extends BaseTreeControl {
|
|
240
|
-
/**
|
|
241
|
-
|
|
310
|
+
/**
|
|
311
|
+
* Construct with nested tree function getChildren.
|
|
312
|
+
*
|
|
313
|
+
* @param getChildren Must emit **synchronously** (e.g. `of(children)` or a `BehaviorSubject`).
|
|
314
|
+
* `getDescendants` walks the tree with `take(1)` and returns as soon as the recursion unwinds, so
|
|
315
|
+
* an asynchronous source yields an incomplete — usually empty — descendant list.
|
|
316
|
+
*/
|
|
317
|
+
constructor(getChildren, options) {
|
|
242
318
|
super();
|
|
243
319
|
this.getChildren = getChildren;
|
|
320
|
+
this.trackBy = options?.trackBy;
|
|
244
321
|
}
|
|
245
322
|
/**
|
|
246
323
|
* Expands all dataNodes in the tree.
|
|
@@ -251,7 +328,7 @@ class NestedTreeControl extends BaseTreeControl {
|
|
|
251
328
|
expandAll() {
|
|
252
329
|
this.expansionModel.clear();
|
|
253
330
|
const allNodes = this.dataNodes.reduce((accumulator, dataNode) => [...accumulator, ...this.getDescendants(dataNode), dataNode], []);
|
|
254
|
-
this.expansionModel.select(...allNodes);
|
|
331
|
+
this.expansionModel.select(...allNodes.map((node) => this.expansionKey(node)));
|
|
255
332
|
}
|
|
256
333
|
/** Gets a list of descendant dataNodes of a subtree rooted at given data node recursively. */
|
|
257
334
|
getDescendants(dataNode) {
|
|
@@ -278,33 +355,41 @@ class NestedTreeControl extends BaseTreeControl {
|
|
|
278
355
|
* Transform nested nodes of type `T` to flattened nodes of type `F`.
|
|
279
356
|
*
|
|
280
357
|
* For example, the input data of type `T` is nested, and contains its children data:
|
|
281
|
-
*
|
|
358
|
+
*
|
|
359
|
+
* ```ts
|
|
360
|
+
* SomeNode: {
|
|
282
361
|
* key: 'Fruits',
|
|
283
362
|
* children: [
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
363
|
+
* NodeOne: {
|
|
364
|
+
* key: 'Apple'
|
|
365
|
+
* },
|
|
366
|
+
* NodeTwo: {
|
|
367
|
+
* key: 'Pear'
|
|
368
|
+
* }
|
|
369
|
+
* ]
|
|
370
|
+
* }
|
|
371
|
+
* ```
|
|
372
|
+
*
|
|
373
|
+
* After flattener flatten the tree, the structure will become
|
|
374
|
+
*
|
|
375
|
+
* ```ts
|
|
376
|
+
* SomeNode: {
|
|
377
|
+
* key: 'Fruits',
|
|
378
|
+
* expandable: true,
|
|
379
|
+
* level: 1
|
|
380
|
+
* },
|
|
381
|
+
* NodeOne: {
|
|
382
|
+
* key: 'Apple',
|
|
383
|
+
* expandable: false,
|
|
384
|
+
* level: 2
|
|
385
|
+
* },
|
|
386
|
+
* NodeTwo: {
|
|
387
|
+
* key: 'Pear',
|
|
388
|
+
* expandable: false,
|
|
389
|
+
* level: 2
|
|
307
390
|
* }
|
|
391
|
+
* ```
|
|
392
|
+
*
|
|
308
393
|
* and the output flattened type is `F` with additional information.
|
|
309
394
|
*/
|
|
310
395
|
class KbqTreeFlattener {
|
|
@@ -314,6 +399,7 @@ class KbqTreeFlattener {
|
|
|
314
399
|
this.isExpandable = isExpandable;
|
|
315
400
|
this.getChildren = getChildren;
|
|
316
401
|
}
|
|
402
|
+
/** @docs-private */
|
|
317
403
|
flattenNode(node, level, resultNodes, parent) {
|
|
318
404
|
const flatNode = this.transformFunction(node, level, parent);
|
|
319
405
|
resultNodes.push(flatNode);
|
|
@@ -332,6 +418,7 @@ class KbqTreeFlattener {
|
|
|
332
418
|
}
|
|
333
419
|
return resultNodes;
|
|
334
420
|
}
|
|
421
|
+
/** @docs-private */
|
|
335
422
|
flattenChildren(children, level, resultNodes, parent) {
|
|
336
423
|
children.forEach((child) => {
|
|
337
424
|
this.flattenNode(child, level + 1, resultNodes, parent);
|
|
@@ -350,6 +437,8 @@ class KbqTreeFlattener {
|
|
|
350
437
|
/**
|
|
351
438
|
* Expand flattened node with current expansion status.
|
|
352
439
|
* The returned list may have different length.
|
|
440
|
+
*
|
|
441
|
+
* Reads only `isExpanded` of the tree control, so it takes a control of any key type.
|
|
353
442
|
*/
|
|
354
443
|
expandFlattenedNodes(nodes, treeControl) {
|
|
355
444
|
const results = [];
|
|
@@ -379,17 +468,19 @@ var KbqTreeDataSourceChangeTypes;
|
|
|
379
468
|
* Data source for flat tree.
|
|
380
469
|
* The data source need to handle expansion/collapsion of the tree node and change the data feed
|
|
381
470
|
* to `KbqTree`.
|
|
382
|
-
* The nested tree nodes of type `T` are flattened through `
|
|
471
|
+
* The nested tree nodes of type `T` are flattened through `KbqTreeFlattener`, and converted
|
|
383
472
|
* to type `F` for `KbqTree` to consume.
|
|
384
473
|
*/
|
|
385
474
|
class KbqTreeFlatDataSource extends DataSource {
|
|
386
475
|
get data() {
|
|
387
|
-
return this._data
|
|
476
|
+
return this._data();
|
|
388
477
|
}
|
|
389
478
|
set data(value) {
|
|
390
|
-
this._data.
|
|
391
|
-
this.
|
|
392
|
-
|
|
479
|
+
this._data.set(value);
|
|
480
|
+
const flattened = this.treeFlattener.flattenNodes(this.data);
|
|
481
|
+
// Assigned before emitting: the tree renders inside `next`, and its rows look themselves up in `dataNodes`.
|
|
482
|
+
this.treeControl.dataNodes = flattened;
|
|
483
|
+
this.flattenedData.next(flattened);
|
|
393
484
|
}
|
|
394
485
|
constructor(treeControl, treeFlattener, initialData = []) {
|
|
395
486
|
super();
|
|
@@ -398,7 +489,12 @@ class KbqTreeFlatDataSource extends DataSource {
|
|
|
398
489
|
this.flattenedData = new BehaviorSubject([]);
|
|
399
490
|
this.expandedData = new BehaviorSubject([]);
|
|
400
491
|
this.filteredData = new BehaviorSubject([]);
|
|
401
|
-
this._data =
|
|
492
|
+
this._data = signal([], ...(ngDevMode ? [{ debugName: "_data" }] : /* istanbul ignore next */ []));
|
|
493
|
+
this._data.set(initialData);
|
|
494
|
+
// The setter flattens the data for the tree.
|
|
495
|
+
if (initialData.length) {
|
|
496
|
+
this.data = initialData;
|
|
497
|
+
}
|
|
402
498
|
}
|
|
403
499
|
connect(collectionViewer) {
|
|
404
500
|
return merge(collectionViewer.viewChange, this.treeControl.expansionModel.changed.pipe(map((value) => ({ type: KbqTreeDataSourceChangeTypes.Expansion, value }))), this.treeControl.filterValue.pipe(map((value) => ({ type: KbqTreeDataSourceChangeTypes.Filter, value }))), this.flattenedData).pipe(map((changeObj) => {
|
|
@@ -465,12 +561,12 @@ class KbqTreeNodeOutletContext {
|
|
|
465
561
|
class KbqTreeNodeDef {
|
|
466
562
|
constructor() {
|
|
467
563
|
this.template = inject(TemplateRef);
|
|
468
|
-
this.data = input(undefined, ...(ngDevMode ?
|
|
564
|
+
this.data = input(undefined, { ...(ngDevMode ? { debugName: "data" } : /* istanbul ignore next */ {}), alias: 'kbqTreeNode' });
|
|
469
565
|
}
|
|
470
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
471
|
-
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
566
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeDef, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
567
|
+
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: KbqTreeNodeDef, isStandalone: true, selector: "[kbqTreeNodeDef]", inputs: { when: { classPropertyName: "when", publicName: "kbqTreeNodeDefWhen", isSignal: false, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "kbqTreeNode", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
472
568
|
}
|
|
473
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
569
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeDef, decorators: [{
|
|
474
570
|
type: Directive,
|
|
475
571
|
args: [{
|
|
476
572
|
selector: '[kbqTreeNodeDef]',
|
|
@@ -481,12 +577,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
481
577
|
class KbqTreeNodeOutlet {
|
|
482
578
|
constructor() {
|
|
483
579
|
this.viewContainer = inject(ViewContainerRef);
|
|
484
|
-
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
485
580
|
}
|
|
486
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
487
|
-
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
581
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
582
|
+
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.25", type: KbqTreeNodeOutlet, isStandalone: true, selector: "[kbqTreeNodeOutlet]", ngImport: i0 }); }
|
|
488
583
|
}
|
|
489
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
584
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeOutlet, decorators: [{
|
|
490
585
|
type: Directive,
|
|
491
586
|
args: [{
|
|
492
587
|
selector: '[kbqTreeNodeOutlet]'
|
|
@@ -495,6 +590,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
495
590
|
|
|
496
591
|
/**
|
|
497
592
|
* Returns an error to be thrown when there is no usable data.
|
|
593
|
+
*
|
|
498
594
|
* @docs-private
|
|
499
595
|
*/
|
|
500
596
|
function getTreeNoValidDataSourceError() {
|
|
@@ -502,6 +598,7 @@ function getTreeNoValidDataSourceError() {
|
|
|
502
598
|
}
|
|
503
599
|
/**
|
|
504
600
|
* Returns an error to be thrown when there are multiple nodes that are missing a when function.
|
|
601
|
+
*
|
|
505
602
|
* @docs-private
|
|
506
603
|
*/
|
|
507
604
|
function getTreeMultipleDefaultNodeDefsError() {
|
|
@@ -509,6 +606,7 @@ function getTreeMultipleDefaultNodeDefsError() {
|
|
|
509
606
|
}
|
|
510
607
|
/**
|
|
511
608
|
* Returns an error to be thrown when there are no matching node defs for a particular set of data.
|
|
609
|
+
*
|
|
512
610
|
* @docs-private
|
|
513
611
|
*/
|
|
514
612
|
function getTreeMissingMatchingNodeDefError() {
|
|
@@ -516,62 +614,169 @@ function getTreeMissingMatchingNodeDefError() {
|
|
|
516
614
|
}
|
|
517
615
|
/**
|
|
518
616
|
* Returns an error to be thrown when there are tree control.
|
|
617
|
+
*
|
|
519
618
|
* @docs-private
|
|
520
619
|
*/
|
|
521
620
|
function getTreeControlMissingError() {
|
|
522
621
|
return Error(`Could not find a tree control for the tree.`);
|
|
523
622
|
}
|
|
524
623
|
/**
|
|
525
|
-
* Returns an error to be thrown when
|
|
624
|
+
* Returns an error to be thrown when the selection mode of a tree is changed while its `SelectionModel`
|
|
625
|
+
* belongs to a host `KbqTreeSelect`.
|
|
626
|
+
*
|
|
526
627
|
* @docs-private
|
|
527
628
|
*/
|
|
528
|
-
function
|
|
529
|
-
return Error(
|
|
629
|
+
function getKbqTreeSelectionOwnedMultipleError() {
|
|
630
|
+
return Error('Cannot change the multiplicity of `multiple` on a `kbq-tree-selection` rendered inside a ' +
|
|
631
|
+
'`kbq-tree-select`: the select owns the selection model. Set `multiple` on the select instead.');
|
|
530
632
|
}
|
|
531
633
|
|
|
634
|
+
/**
|
|
635
|
+
* Coerces a raw persisted payload into a `KbqTreeState`, returning `null` for anything unrecognizable.
|
|
636
|
+
*
|
|
637
|
+
* Web storage is origin-wide and user-writable, so a payload is never trusted — without this, an entry
|
|
638
|
+
* such as `{"a": null}` would reach `hasValue()` while restoring.
|
|
639
|
+
*/
|
|
640
|
+
const normalizeTreeState = (parsed) => {
|
|
641
|
+
if (!Array.isArray(parsed))
|
|
642
|
+
return null;
|
|
643
|
+
const values = parsed.filter((value) => typeof value === 'string');
|
|
644
|
+
// An array that held nothing usable is somebody else's payload, not "nothing was expanded" — the
|
|
645
|
+
// difference matters, because only the second one is a state worth keeping.
|
|
646
|
+
return values.length || !parsed.length ? values : null;
|
|
647
|
+
};
|
|
648
|
+
/**
|
|
649
|
+
* Rendering core of the tree.
|
|
650
|
+
*
|
|
651
|
+
* Originally forked from `@angular/cdk/tree` and maintained independently since: the node/outlet
|
|
652
|
+
* contract, the option-based selection model and the filtering pipeline have all diverged, so
|
|
653
|
+
* `@angular/cdk/tree` is deliberately not a dependency of this package and upstream fixes have to be
|
|
654
|
+
* ported by hand.
|
|
655
|
+
*
|
|
656
|
+
* `C` narrows the tree control a concrete tree accepts, and so the type its `treeControl` binding is checked against.
|
|
657
|
+
* The bound leaves out `expansionModel` and `trackBy`, the members typed by the control's key, so that it admits
|
|
658
|
+
* a control of any key type: the model makes a control invariant in that type.
|
|
659
|
+
*/
|
|
532
660
|
class KbqTreeBase {
|
|
661
|
+
/** Controls the expanded state and holds the data nodes of the tree. */
|
|
662
|
+
get treeControl() {
|
|
663
|
+
return this.treeControlInput();
|
|
664
|
+
}
|
|
665
|
+
/** {@link treeControl} as state saving reads it: by node value, which only a `FlatTreeControl` has. */
|
|
666
|
+
get flatTreeControl() {
|
|
667
|
+
const treeControl = this.treeControl;
|
|
668
|
+
return treeControl;
|
|
669
|
+
}
|
|
670
|
+
/** Outlet within the tree's template where the data nodes are inserted. */
|
|
671
|
+
get nodeOutlet() {
|
|
672
|
+
return this.nodeOutletQuery();
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Provides a stream containing the latest data array to render. Influenced by the tree's
|
|
676
|
+
* stream of view window (what dataNodes are currently on screen).
|
|
677
|
+
* Data source can be an observable of data array, or a data array to render.
|
|
678
|
+
*/
|
|
679
|
+
get dataSource() {
|
|
680
|
+
return this._dataSource;
|
|
681
|
+
}
|
|
533
682
|
constructor() {
|
|
534
683
|
this.differs = inject(IterableDiffers);
|
|
535
684
|
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
685
|
+
/**
|
|
686
|
+
* Persistence of the expanded state, applied as a host directive by the concrete tree components.
|
|
687
|
+
* Optional because `KbqTreeBase` is exported: a tree without the directive persists nothing.
|
|
688
|
+
*/
|
|
689
|
+
this.stateSaving = inject(KbqStateSaving, { optional: true });
|
|
690
|
+
/** @docs-private */
|
|
691
|
+
this.treeControlInput = input(undefined, { ...(ngDevMode ? { debugName: "treeControlInput" } : /* istanbul ignore next */ {}), alias: 'treeControl' });
|
|
536
692
|
/**
|
|
537
693
|
* Tracking function that will be used to check the differences in data changes. Used similarly
|
|
538
694
|
* to `ngFor` `trackBy` function. Optimize node operations by identifying a node based on its data
|
|
539
695
|
* relative to the function to know if a node should be added/removed/moved.
|
|
540
696
|
* Accepts a function that takes two parameters, `index` and `item`.
|
|
697
|
+
*
|
|
698
|
+
* Views are reused for nodes the function reports as unchanged, which a data source that rebuilds
|
|
699
|
+
* its node objects on every emission — a flattener among them — otherwise cannot get.
|
|
700
|
+
*
|
|
701
|
+
* Defaults to the `trackBy` of the tree control, read when the tree initializes and when the data source changes.
|
|
541
702
|
*/
|
|
542
|
-
this.trackBy = input(undefined, ...(ngDevMode ? [{ debugName: "trackBy" }] : []));
|
|
543
|
-
|
|
544
|
-
|
|
703
|
+
this.trackBy = input(undefined, ...(ngDevMode ? [{ debugName: "trackBy" }] : /* istanbul ignore next */ []));
|
|
704
|
+
this.nodeOutletQuery = viewChild(KbqTreeNodeOutlet, ...(ngDevMode ? [{ debugName: "nodeOutletQuery" }] : /* istanbul ignore next */ []));
|
|
705
|
+
/** The tree node template for the tree */
|
|
706
|
+
this.nodeDefs = contentChildren(KbqTreeNodeDef, ...(ngDevMode ? [{ debugName: "nodeDefs" }] : /* istanbul ignore next */ []));
|
|
545
707
|
/**
|
|
546
708
|
* Stream containing the latest information on what rows are being displayed on screen.
|
|
547
709
|
* Can be used by the data source to as a heuristic of what data should be provided.
|
|
710
|
+
*
|
|
711
|
+
* The tree renders every expanded node eagerly, so the window is the whole data set; a data source
|
|
712
|
+
* cannot use it to page or virtualize. Windowing would have to emit a real range from a scroll
|
|
713
|
+
* listener here first.
|
|
548
714
|
*/
|
|
549
715
|
this.viewChange = new BehaviorSubject({ start: 0, end: Number.MAX_VALUE });
|
|
550
716
|
/** Level of nodes */
|
|
551
717
|
this.levels = new Map();
|
|
718
|
+
/** Most recently constructed node of this tree, see `registerNode`. */
|
|
719
|
+
this.recentNode = null;
|
|
720
|
+
/** Node rendered for a given outlet context, so a reused view can be handed its new data. */
|
|
721
|
+
this.nodesByContext = new WeakMap();
|
|
722
|
+
/**
|
|
723
|
+
* Values from the persisted state whose node has not appeared in `treeControl.dataNodes` yet —
|
|
724
|
+
* applied as the nodes show up, and dropped the first time each node is seen.
|
|
725
|
+
*/
|
|
726
|
+
this.pendingValues = new Set();
|
|
727
|
+
/** The `dataNodes` the last restore ran against, so an unchanged list is not walked again. */
|
|
728
|
+
this.lastRestoredDataNodes = null;
|
|
729
|
+
/**
|
|
730
|
+
* Whether the persisted state has been read. `KbqTreeSelect` calls `ngAfterContentInit()` by hand on
|
|
731
|
+
* the tree it projects into its panel, and a second read would resurrect values the user dismissed.
|
|
732
|
+
*/
|
|
733
|
+
this.hasRead = false;
|
|
734
|
+
/** Whether the dev-mode warnings below have already been logged, so each is logged once. */
|
|
735
|
+
this.warnedAboutTreeControl = false;
|
|
736
|
+
this.warnedAboutValues = false;
|
|
737
|
+
/** @docs-private */
|
|
738
|
+
this.dataSourceInput = input(undefined, { ...(ngDevMode ? { debugName: "dataSourceInput" } : /* istanbul ignore next */ {}), alias: 'dataSource' });
|
|
739
|
+
this._dataSource = null;
|
|
552
740
|
this.destroyRef = inject(DestroyRef);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
set dataSource(dataSource) {
|
|
565
|
-
if (this._dataSource !== dataSource) {
|
|
566
|
-
this.switchDataSource(dataSource);
|
|
567
|
-
}
|
|
741
|
+
/** Whether `ngAfterContentChecked` has run, i.e. the node definitions the first render needs are resolved. */
|
|
742
|
+
this.contentChecked = false;
|
|
743
|
+
// Switching the source drops the rendered nodes and resubscribes, which a bound value alone does not do. A
|
|
744
|
+
// binding back to `undefined` clears the tree as `null` does; an unbound input equals the initial `null`.
|
|
745
|
+
effect(() => {
|
|
746
|
+
const dataSource = this.dataSourceInput() ?? null;
|
|
747
|
+
untracked(() => {
|
|
748
|
+
if (dataSource !== this._dataSource)
|
|
749
|
+
this.switchDataSource(dataSource);
|
|
750
|
+
});
|
|
751
|
+
});
|
|
568
752
|
}
|
|
569
753
|
ngOnInit() {
|
|
570
|
-
this.dataDiffer = this.
|
|
754
|
+
this.dataDiffer = this.createDataDiffer();
|
|
571
755
|
if (!this.treeControl) {
|
|
572
756
|
throw getTreeControlMissingError();
|
|
573
757
|
}
|
|
574
758
|
}
|
|
759
|
+
ngAfterContentInit() {
|
|
760
|
+
// Before `ngAfterContentChecked` connects the data source, so the restored nodes are expanded
|
|
761
|
+
// ahead of the first render rather than causing a second one.
|
|
762
|
+
if (this.hasRead || !this.persists)
|
|
763
|
+
return;
|
|
764
|
+
this.hasRead = true;
|
|
765
|
+
// The state lives under the new key now, so restore from it.
|
|
766
|
+
this.stateSaving.keyChanges.subscribe(() => this.restoreState());
|
|
767
|
+
this.restoreState();
|
|
768
|
+
}
|
|
769
|
+
/** Reads the persisted expansion and applies it. Runs while initializing, and again on a key change. */
|
|
770
|
+
restoreState() {
|
|
771
|
+
if (!this.persists)
|
|
772
|
+
return;
|
|
773
|
+
const savedState = this.stateSaving.read(normalizeTreeState);
|
|
774
|
+
this.pendingValues = new Set(savedState ?? []);
|
|
775
|
+
// The memo that keeps one batch of nodes from being examined twice. A restore from another key
|
|
776
|
+
// has new values to match against the same nodes, so it has to be allowed to look again.
|
|
777
|
+
this.lastRestoredDataNodes = null;
|
|
778
|
+
this.restorePending();
|
|
779
|
+
}
|
|
575
780
|
ngOnDestroy() {
|
|
576
781
|
this.nodeOutlet.viewContainer.clear();
|
|
577
782
|
if (this._dataSource && typeof this.dataSource.disconnect === 'function') {
|
|
@@ -583,20 +788,65 @@ class KbqTreeBase {
|
|
|
583
788
|
}
|
|
584
789
|
}
|
|
585
790
|
ngAfterContentChecked() {
|
|
586
|
-
const defaultNodeDefs = this.nodeDefs.filter((def) => !def.when);
|
|
791
|
+
const defaultNodeDefs = this.nodeDefs().filter((def) => !def.when);
|
|
587
792
|
if (defaultNodeDefs.length > 1) {
|
|
588
793
|
throw getTreeMultipleDefaultNodeDefsError();
|
|
589
794
|
}
|
|
590
795
|
this.defaultNodeDef = defaultNodeDefs[0];
|
|
591
|
-
|
|
796
|
+
this.contentChecked = true;
|
|
797
|
+
if (this.dataSource && this.nodeDefs().length && !this.dataSubscription) {
|
|
592
798
|
this.observeRenderChanges();
|
|
593
799
|
}
|
|
594
800
|
}
|
|
801
|
+
/**
|
|
802
|
+
* Persists the values of the currently expanded nodes.
|
|
803
|
+
*
|
|
804
|
+
* Called for every expansion and collapse a user performs. Expansion driven by the application —
|
|
805
|
+
* `treeControl.expandAll()`, or writing to `expansionModel` — is not persisted; call this to record it.
|
|
806
|
+
*
|
|
807
|
+
* A no-op while a filter is active: what is expanded then is the result set, not a chosen state.
|
|
808
|
+
*/
|
|
809
|
+
saveState() {
|
|
810
|
+
// Untracked, as in `clearSavedState()`: called from a consumer's `effect()`, the inputs read on the way would
|
|
811
|
+
// make the effect run again whenever they change.
|
|
812
|
+
untracked(() => {
|
|
813
|
+
if (!this.persists || this.treeControl.filterValue.value?.length)
|
|
814
|
+
return;
|
|
815
|
+
this.stateSaving.write(this.expandedValues());
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Removes the state persisted for this tree.
|
|
820
|
+
*
|
|
821
|
+
* Persistence itself stays on — the next expansion is written again.
|
|
822
|
+
*/
|
|
823
|
+
clearSavedState() {
|
|
824
|
+
untracked(() => this.stateSaving?.clear());
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* Whether state is currently persisted for this tree — restored on init, or written since.
|
|
828
|
+
* Always `false` while `useStateSaving` is unset, and `false` again after `clearSavedState()`.
|
|
829
|
+
*/
|
|
830
|
+
get hasSavedState() {
|
|
831
|
+
return this.stateSaving?.state != null;
|
|
832
|
+
}
|
|
595
833
|
/** Check for changes made in the data and render each change (node added/removed/moved). */
|
|
596
834
|
renderNodeChanges(data, dataDiffer = this.dataDiffer, viewContainer = this.nodeOutlet.viewContainer, parentData) {
|
|
835
|
+
if (this.applyNodeChanges(data, dataDiffer, viewContainer, parentData)) {
|
|
836
|
+
this.changeDetectorRef.detectChanges();
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Applies the data changes to the view container without running change detection, and reports
|
|
841
|
+
* whether anything moved. Split out of `renderNodeChanges` so a subclass can update the state its
|
|
842
|
+
* own template reads before the single change-detection pass, instead of running a second one.
|
|
843
|
+
*
|
|
844
|
+
* @docs-private
|
|
845
|
+
*/
|
|
846
|
+
applyNodeChanges(data, dataDiffer, viewContainer, parentData) {
|
|
597
847
|
const changes = dataDiffer.diff(data);
|
|
598
848
|
if (!changes) {
|
|
599
|
-
return;
|
|
849
|
+
return false;
|
|
600
850
|
}
|
|
601
851
|
changes.forEachOperation((item, adjustedPreviousIndex, currentIndex) => {
|
|
602
852
|
if (item.previousIndex == null) {
|
|
@@ -611,7 +861,30 @@ class KbqTreeBase {
|
|
|
611
861
|
viewContainer.move(view, currentIndex);
|
|
612
862
|
}
|
|
613
863
|
});
|
|
614
|
-
|
|
864
|
+
// A node kept its identity but is a different object — what a data source that rebuilds its
|
|
865
|
+
// nodes on every emission produces, a flattener among them. The view is reused, so the object
|
|
866
|
+
// it and its `KbqTreeNode` still hold is gone from `dataNodes`, and every lookup keyed on the
|
|
867
|
+
// node reference (`getDescendants`, `isExpanded`, the selection) would miss it.
|
|
868
|
+
changes.forEachIdentityChange((record) => {
|
|
869
|
+
this.refreshNodeData(viewContainer, record.currentIndex, record.item);
|
|
870
|
+
});
|
|
871
|
+
return true;
|
|
872
|
+
}
|
|
873
|
+
refreshNodeData(viewContainer, index, nodeData) {
|
|
874
|
+
const view = viewContainer.get(index);
|
|
875
|
+
if (!view) {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
const { context } = view;
|
|
879
|
+
const previousData = context.$implicit;
|
|
880
|
+
context.$implicit = nodeData;
|
|
881
|
+
this.levels.delete(previousData);
|
|
882
|
+
this.levels.set(nodeData, context.level);
|
|
883
|
+
const node = this.nodesByContext.get(context);
|
|
884
|
+
if (node) {
|
|
885
|
+
node.data = nodeData;
|
|
886
|
+
node.refresh();
|
|
887
|
+
}
|
|
615
888
|
}
|
|
616
889
|
/**
|
|
617
890
|
* Finds the matching node definition that should be used for this node data. If there is only
|
|
@@ -620,10 +893,11 @@ class KbqTreeBase {
|
|
|
620
893
|
* definition.
|
|
621
894
|
*/
|
|
622
895
|
getNodeDef(data, i) {
|
|
623
|
-
|
|
624
|
-
|
|
896
|
+
const nodeDefs = this.nodeDefs();
|
|
897
|
+
if (nodeDefs.length === 1) {
|
|
898
|
+
return nodeDefs[0];
|
|
625
899
|
}
|
|
626
|
-
const nodeDef =
|
|
900
|
+
const nodeDef = nodeDefs.find((def) => def.when && def.when(i, data)) || this.defaultNodeDef;
|
|
627
901
|
if (!nodeDef) {
|
|
628
902
|
throw getTreeMissingMatchingNodeDefError();
|
|
629
903
|
}
|
|
@@ -637,6 +911,7 @@ class KbqTreeBase {
|
|
|
637
911
|
const node = this.getNodeDef(nodeData, index);
|
|
638
912
|
// Node context that will be provided to created embedded view
|
|
639
913
|
const context = new KbqTreeNodeOutletContext(nodeData);
|
|
914
|
+
context.index = index;
|
|
640
915
|
// If the tree is flat tree, then use the `getLevel` function in flat tree control
|
|
641
916
|
// Otherwise, use the level of parent node.
|
|
642
917
|
const treeControl = this.treeControl;
|
|
@@ -653,12 +928,106 @@ class KbqTreeBase {
|
|
|
653
928
|
// Use default tree nodeOutlet, or nested node's nodeOutlet
|
|
654
929
|
const container = viewContainer ? viewContainer : this.nodeOutlet.viewContainer;
|
|
655
930
|
container.createEmbeddedView(node.template, context, index);
|
|
656
|
-
//
|
|
657
|
-
//
|
|
658
|
-
//
|
|
659
|
-
if (
|
|
660
|
-
|
|
931
|
+
// The `KbqTreeNode` instantiated by `createEmbeddedView` registers itself here on construction,
|
|
932
|
+
// which is the only handle onto it — the embedded view exposes its context, not its directives.
|
|
933
|
+
// It is remembered against that context so a later re-render can reach it again.
|
|
934
|
+
if (this.recentNode) {
|
|
935
|
+
this.recentNode.data = nodeData;
|
|
936
|
+
this.nodesByContext.set(context, this.recentNode);
|
|
937
|
+
this.recentNode = null;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Called by a `KbqTreeNode` while it is being constructed, so `insertNode` can hand it its data.
|
|
942
|
+
*
|
|
943
|
+
* @docs-private
|
|
944
|
+
*/
|
|
945
|
+
registerNode(node) {
|
|
946
|
+
this.recentNode = node;
|
|
947
|
+
}
|
|
948
|
+
/** Whether this tree reads and writes its expanded state at all. */
|
|
949
|
+
get persists() {
|
|
950
|
+
if (!this.stateSaving?.useStateSaving())
|
|
951
|
+
return false;
|
|
952
|
+
// A tree that is not in the document has no stable key — the default resolver derives one from
|
|
953
|
+
// the path to `<body>`. That is the ordinary state of a tree projected into an overlay, such as
|
|
954
|
+
// the one `kbq-tree-select` renders into its panel, whose expansion is transient UI rather than
|
|
955
|
+
// a setting worth carrying to the next visit.
|
|
956
|
+
if (!this.stateSaving.host?.isConnected)
|
|
957
|
+
return false;
|
|
958
|
+
if (typeof this.flatTreeControl.getValue !== 'function') {
|
|
959
|
+
if (isDevMode() && !this.warnedAboutTreeControl) {
|
|
960
|
+
this.warnedAboutTreeControl = true;
|
|
961
|
+
// eslint-disable-next-line no-console
|
|
962
|
+
console.warn('kbq-tree: state saving is enabled, but the tree control has no `getValue`. ' +
|
|
963
|
+
'Expansion is persisted by node value, and a node object does not survive a ' +
|
|
964
|
+
'reload, so nothing is persisted. Use `FlatTreeControl`, or unset ' +
|
|
965
|
+
'`useStateSaving`.');
|
|
966
|
+
}
|
|
967
|
+
return false;
|
|
661
968
|
}
|
|
969
|
+
return true;
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Expands every pending value whose node is present, and stops tracking it.
|
|
973
|
+
*
|
|
974
|
+
* Idempotent, and safe to call on every render: the pending set only shrinks, so a tree that has
|
|
975
|
+
* restored everything does no work at all.
|
|
976
|
+
*/
|
|
977
|
+
restorePending() {
|
|
978
|
+
if (!this.pendingValues.size)
|
|
979
|
+
return;
|
|
980
|
+
const currentNodes = this.treeControl.dataNodes;
|
|
981
|
+
// Nothing new to match against. Deliberately does not record an empty list, so the first real
|
|
982
|
+
// batch of an asynchronously loaded tree is still examined.
|
|
983
|
+
if (currentNodes === this.lastRestoredDataNodes || !currentNodes?.length)
|
|
984
|
+
return;
|
|
985
|
+
this.lastRestoredDataNodes = currentNodes;
|
|
986
|
+
const treeControl = this.flatTreeControl;
|
|
987
|
+
const found = [];
|
|
988
|
+
for (const value of this.pendingValues) {
|
|
989
|
+
const node = treeControl.hasValue(value);
|
|
990
|
+
if (node) {
|
|
991
|
+
found.push(node);
|
|
992
|
+
this.pendingValues.delete(value);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
// Straight at the model rather than through `expand()`, which is a no-op while a filter is
|
|
996
|
+
// active — restoring must not depend on what the user happens to be searching for.
|
|
997
|
+
if (found.length) {
|
|
998
|
+
const { trackBy } = treeControl;
|
|
999
|
+
const keys = trackBy ? found.map((node) => trackBy(node)) : found;
|
|
1000
|
+
this.stateSaving.applying(() => treeControl.expansionModel.select(...keys));
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
/** The values of the nodes that are currently expanded, plus the ones still waiting to appear. */
|
|
1004
|
+
expandedValues() {
|
|
1005
|
+
const treeControl = this.flatTreeControl;
|
|
1006
|
+
const expanded = [];
|
|
1007
|
+
let skipped = false;
|
|
1008
|
+
// With `trackBy` the model holds keys, which have no value: only the current nodes map back to them.
|
|
1009
|
+
const expandedNodes = treeControl.trackBy
|
|
1010
|
+
? (treeControl.dataNodes ?? []).filter((node) => treeControl.isExpanded(node))
|
|
1011
|
+
: treeControl.expansionModel.selected;
|
|
1012
|
+
for (const node of expandedNodes) {
|
|
1013
|
+
const value = treeControl.getValue(node);
|
|
1014
|
+
if (typeof value === 'string') {
|
|
1015
|
+
expanded.push(value);
|
|
1016
|
+
}
|
|
1017
|
+
else {
|
|
1018
|
+
skipped = true;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
if (skipped && isDevMode() && !this.warnedAboutValues) {
|
|
1022
|
+
this.warnedAboutValues = true;
|
|
1023
|
+
// eslint-disable-next-line no-console
|
|
1024
|
+
console.warn('kbq-tree: `getValue` returned a value that is not a string for at least one node. ' +
|
|
1025
|
+
'Expansion is persisted as JSON keyed by that value, so those nodes are left out.');
|
|
1026
|
+
}
|
|
1027
|
+
// Union with what is still pending: on a tree whose data arrives in batches the expanded nodes
|
|
1028
|
+
// are only part of what was saved, and writing the snapshot alone would drop every branch that
|
|
1029
|
+
// has not been loaded yet.
|
|
1030
|
+
return [...new Set([...expanded, ...this.pendingValues])];
|
|
662
1031
|
}
|
|
663
1032
|
/** Set up a subscription for the data provided by the data source. */
|
|
664
1033
|
observeRenderChanges() {
|
|
@@ -675,9 +1044,15 @@ class KbqTreeBase {
|
|
|
675
1044
|
dataStream = of(this._dataSource);
|
|
676
1045
|
}
|
|
677
1046
|
if (dataStream) {
|
|
678
|
-
this.dataSubscription = dataStream
|
|
679
|
-
.
|
|
680
|
-
|
|
1047
|
+
this.dataSubscription = dataStream.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => {
|
|
1048
|
+
this.renderNodeChanges(data);
|
|
1049
|
+
// On a microtask, and only while something is still pending: expanding re-enters this
|
|
1050
|
+
// very subscription — the flat data source merges `expansionModel.changed` — and
|
|
1051
|
+
// `renderNodeChanges` has just run `detectChanges()`.
|
|
1052
|
+
if (this.pendingValues.size) {
|
|
1053
|
+
Promise.resolve().then(() => this.restorePending());
|
|
1054
|
+
}
|
|
1055
|
+
});
|
|
681
1056
|
}
|
|
682
1057
|
else {
|
|
683
1058
|
throw getTreeNoValidDataSourceError();
|
|
@@ -696,35 +1071,48 @@ class KbqTreeBase {
|
|
|
696
1071
|
this.dataSubscription.unsubscribe();
|
|
697
1072
|
this.dataSubscription = null;
|
|
698
1073
|
}
|
|
699
|
-
//
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
1074
|
+
// Every rendered node belongs to the previous source, so none of them survives the switch. The
|
|
1075
|
+
// differ is reset below and no longer reports them as removals, which makes these two the only
|
|
1076
|
+
// things that drop the old nodes — for a null source and for a replacement source alike. Left
|
|
1077
|
+
// to the differ, `levels` would keep an entry, and with it a strong reference, for every node
|
|
1078
|
+
// of every source the tree has ever been given.
|
|
1079
|
+
this.nodeOutlet.viewContainer.clear();
|
|
1080
|
+
this.levels.clear();
|
|
703
1081
|
this._dataSource = dataSource;
|
|
704
|
-
|
|
1082
|
+
// The differ remembers the nodes of the previous source. Left in place, the first diff against
|
|
1083
|
+
// the new source is computed as a delta from data that is no longer rendered, so views are
|
|
1084
|
+
// reused for unrelated nodes or dropped entirely.
|
|
1085
|
+
this.dataDiffer = this.createDataDiffer();
|
|
1086
|
+
// Not before the first `ngAfterContentChecked`: that is where the default node definition is resolved,
|
|
1087
|
+
// and a render ahead of it finds no definition for the nodes and throws, taking the subscription down
|
|
1088
|
+
// with it and leaving the tree permanently empty. The initial render is picked up there; a later
|
|
1089
|
+
// source swap is observed here right away.
|
|
1090
|
+
if (dataSource && this.contentChecked && this.nodeDefs().length) {
|
|
705
1091
|
this.observeRenderChanges();
|
|
706
1092
|
}
|
|
707
1093
|
}
|
|
708
|
-
|
|
709
|
-
|
|
1094
|
+
createDataDiffer() {
|
|
1095
|
+
// The bound of `C` leaves `trackBy` out; the key type is the control's own, so it is read as `unknown` here.
|
|
1096
|
+
const controlTrackBy = this.treeControl?.trackBy;
|
|
1097
|
+
const trackBy = this.trackBy() ?? (controlTrackBy && ((_, node) => controlTrackBy(node)));
|
|
1098
|
+
return this.differs.find([]).create(trackBy);
|
|
1099
|
+
}
|
|
1100
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeBase, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1101
|
+
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.25", type: KbqTreeBase, isStandalone: true, inputs: { treeControlInput: { classPropertyName: "treeControlInput", publicName: "treeControl", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, dataSourceInput: { classPropertyName: "dataSourceInput", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "nodeDefs", predicate: KbqTreeNodeDef, isSignal: true }], viewQueries: [{ propertyName: "nodeOutletQuery", first: true, predicate: KbqTreeNodeOutlet, descendants: true, isSignal: true }], ngImport: i0 }); }
|
|
710
1102
|
}
|
|
711
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1103
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeBase, decorators: [{
|
|
712
1104
|
type: Directive
|
|
713
|
-
}], propDecorators: { treeControl: [{
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
}], nodeDefs: [{
|
|
719
|
-
type: ContentChildren,
|
|
720
|
-
args: [KbqTreeNodeDef]
|
|
721
|
-
}], dataSource: [{
|
|
722
|
-
type: Input
|
|
723
|
-
}] } });
|
|
1105
|
+
}], ctorParameters: () => [], propDecorators: { treeControlInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeControl", required: false }] }], trackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackBy", required: false }] }], nodeOutletQuery: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqTreeNodeOutlet), { isSignal: true }] }], nodeDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KbqTreeNodeDef), { isSignal: true }] }], dataSourceInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: false }] }] } });
|
|
1106
|
+
// `KbqTree` declares `role="tree"`, whose owned elements have to be `treeitem`s — and a bare
|
|
1107
|
+
// `kbq-tree-node` is the only kind of row it can render, since `KbqTreeOption` needs a parent only
|
|
1108
|
+
// `KbqTreeSelection` provides. The nodes are rendered flat into a single outlet, so the depth an AT
|
|
1109
|
+
// reports comes from `aria-level` rather than from the DOM.
|
|
724
1110
|
class KbqTreeNode {
|
|
725
1111
|
/**
|
|
726
|
-
* The most recently created `KbqTreeNode
|
|
727
|
-
*
|
|
1112
|
+
* The most recently created `KbqTreeNode`, across every tree on the page.
|
|
1113
|
+
*
|
|
1114
|
+
* @deprecated Kept for backwards compatibility only — the tree hands a node its data through
|
|
1115
|
+
* `KbqTreeBase.registerNode`, which is scoped to the tree that owns the node. Will be removed in 22.0.0.
|
|
728
1116
|
*/
|
|
729
1117
|
static { this.mostRecentTreeNode = null; }
|
|
730
1118
|
get data() {
|
|
@@ -744,89 +1132,102 @@ class KbqTreeNode {
|
|
|
744
1132
|
this.elementRef = inject(ElementRef);
|
|
745
1133
|
this.tree = inject(KbqTreeBase);
|
|
746
1134
|
this.destroyed = new Subject();
|
|
1135
|
+
/**
|
|
1136
|
+
* Emits after the tree reused this node's view for a different data object, so a directive on the
|
|
1137
|
+
* same element can re-derive what it computed from the previous one.
|
|
1138
|
+
*
|
|
1139
|
+
* @docs-private
|
|
1140
|
+
*/
|
|
1141
|
+
this.refreshed = new Subject();
|
|
747
1142
|
KbqTreeNode.mostRecentTreeNode = this;
|
|
1143
|
+
this.tree.registerNode(this);
|
|
748
1144
|
}
|
|
749
1145
|
ngOnDestroy() {
|
|
750
1146
|
this.destroyed.next();
|
|
751
1147
|
this.destroyed.complete();
|
|
1148
|
+
this.refreshed.complete();
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Called by the tree once `data` has been replaced on a reused view. State a subclass derived from
|
|
1152
|
+
* the previous node — its value, its level — is stale at this point and has to be recomputed.
|
|
1153
|
+
*
|
|
1154
|
+
* @docs-private
|
|
1155
|
+
*/
|
|
1156
|
+
refresh() {
|
|
1157
|
+
this.refreshed.next();
|
|
752
1158
|
}
|
|
753
1159
|
focus() {
|
|
754
1160
|
this.elementRef.nativeElement.focus();
|
|
755
1161
|
}
|
|
756
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
757
|
-
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1162
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNode, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1163
|
+
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.25", type: KbqTreeNode, isStandalone: true, selector: "kbq-tree-node", host: { attributes: { "role": "treeitem" }, properties: { "attr.aria-level": "level + 1" } }, exportAs: ["kbqTreeNode"], ngImport: i0 }); }
|
|
758
1164
|
}
|
|
759
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1165
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNode, decorators: [{
|
|
760
1166
|
type: Directive,
|
|
761
1167
|
args: [{
|
|
762
1168
|
selector: 'kbq-tree-node',
|
|
1169
|
+
host: {
|
|
1170
|
+
role: 'treeitem',
|
|
1171
|
+
'[attr.aria-level]': 'level + 1'
|
|
1172
|
+
},
|
|
763
1173
|
exportAs: 'kbqTreeNode'
|
|
764
1174
|
}]
|
|
765
1175
|
}], ctorParameters: () => [] });
|
|
766
1176
|
|
|
767
1177
|
/** @docs-private */
|
|
768
1178
|
class KbqTreeNodeToggleBaseDirective {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
1179
|
+
constructor() {
|
|
1180
|
+
this.tree = inject(KbqTreeBase);
|
|
1181
|
+
this.treeNode = inject(KbqTreeNode);
|
|
1182
|
+
this.node = input(undefined, ...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
|
|
1183
|
+
/** Whether toggling expands or collapses the whole subtree instead of the node alone. */
|
|
1184
|
+
this.recursive = input(false, { ...(ngDevMode ? { debugName: "recursive" } : /* istanbul ignore next */ {}), alias: 'kbqTreeNodeToggleRecursive', transform: booleanAttribute });
|
|
1185
|
+
/**
|
|
1186
|
+
* Backing input of `disabled`. Bind through the `disabled` attribute; read the `disabled` getter,
|
|
1187
|
+
* which also reports the toggle disabled while a filter is active.
|
|
1188
|
+
*
|
|
1189
|
+
* @docs-private
|
|
1190
|
+
*/
|
|
1191
|
+
this.disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled', transform: booleanAttribute });
|
|
1192
|
+
/** Set while a filter is active: filtering already decides what is expanded. */
|
|
1193
|
+
this.filterDisabled = toSignal(this.tree.treeControl.filterValue.pipe(map((value) => !!value?.length)), { initialValue: false });
|
|
1194
|
+
this.disabledState = computed(() => this.disabledInput() || this.filterDisabled(), ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
776
1195
|
}
|
|
777
|
-
// TODO: Skipped for migration because:
|
|
778
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
779
1196
|
get disabled() {
|
|
780
|
-
return this.
|
|
781
|
-
}
|
|
782
|
-
set disabled(value) {
|
|
783
|
-
if (value !== this.disabled) {
|
|
784
|
-
this._disabled = value;
|
|
785
|
-
}
|
|
1197
|
+
return this.disabledState();
|
|
786
1198
|
}
|
|
787
1199
|
get iconState() {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
this.tree = inject(KbqTreeBase);
|
|
792
|
-
this.treeNode = inject(KbqTreeNode);
|
|
793
|
-
this.node = input(undefined, ...(ngDevMode ? [{ debugName: "node" }] : []));
|
|
794
|
-
this._recursive = false;
|
|
795
|
-
this._disabled = false;
|
|
796
|
-
this.tree.treeControl.filterValue.subscribe((value) => (this.disabled = !!value?.length));
|
|
1200
|
+
// The node `toggle()` acts on when `node` is not bound: an unbound `node` would reach the control's
|
|
1201
|
+
// `trackBy` as `undefined`.
|
|
1202
|
+
return this.tree.treeControl.isExpanded(this.node() ?? this.treeNode.data);
|
|
797
1203
|
}
|
|
798
1204
|
toggle(event) {
|
|
799
1205
|
if (this.disabled)
|
|
800
1206
|
return;
|
|
801
|
-
if (this.recursive) {
|
|
1207
|
+
if (this.recursive()) {
|
|
802
1208
|
this.tree.treeControl.toggleDescendants(this.treeNode.data);
|
|
803
1209
|
}
|
|
804
1210
|
else {
|
|
805
1211
|
this.tree.treeControl.toggle(this.treeNode.data);
|
|
806
1212
|
}
|
|
1213
|
+
this.tree.saveState();
|
|
807
1214
|
event.stopPropagation();
|
|
808
1215
|
}
|
|
809
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
810
|
-
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
1216
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeToggleBaseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1217
|
+
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: KbqTreeNodeToggleBaseDirective, isStandalone: true, inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: false, transformFunction: null }, recursive: { classPropertyName: "recursive", publicName: "kbqTreeNodeToggleRecursive", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
811
1218
|
}
|
|
812
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1219
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeToggleBaseDirective, decorators: [{
|
|
813
1220
|
type: Directive
|
|
814
|
-
}],
|
|
815
|
-
type: Input,
|
|
816
|
-
args: ['kbqTreeNodeToggleRecursive']
|
|
817
|
-
}], disabled: [{
|
|
818
|
-
type: Input,
|
|
819
|
-
args: [{ transform: booleanAttribute }]
|
|
820
|
-
}] } });
|
|
1221
|
+
}], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: false }] }], recursive: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqTreeNodeToggleRecursive", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
821
1222
|
class KbqTreeNodeToggleComponent extends KbqTreeNodeToggleBaseDirective {
|
|
822
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
823
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
1223
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeToggleComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1224
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: KbqTreeNodeToggleComponent, isStandalone: true, selector: "kbq-tree-node-toggle", host: { attributes: { "aria-hidden": "true" }, listeners: { "click": "toggle($event)" }, properties: { "class.kbq-expanded": "iconState", "attr.disabled": "disabled || null", "attr.aria-disabled": "disabled || null" }, classAttribute: "kbq-tree-node-toggle" }, exportAs: ["kbqTreeNodeToggle"], usesInheritance: true, ngImport: i0, template: `
|
|
824
1225
|
<ng-content>
|
|
825
1226
|
<i kbq-icon="kbq-chevron-down-s_16" [color]="'contrast-fade'"></i>
|
|
826
1227
|
</ng-content>
|
|
827
|
-
`, isInline: true, styles: [".kbq-tree-node-toggle{display:flex;align-items:center;justify-content:center;flex-shrink:0;height:100%;padding-left:var(--kbq-tree-size-toggle-padding);padding-right:var(--kbq-tree-size-toggle-padding);cursor:pointer}.kbq-tree-node-toggle .kbq-icon{transform:rotate(-90deg)}.kbq-tree-node-toggle.kbq-expanded .kbq-icon{transform:rotate(0)}.kbq-tree-node-toggle[disabled]{cursor:default}.kbq-tree-node-toggle[disabled] .kbq-icon{color:var(--kbq-tree-states-disabled-tree-toggle-color)}.kbq-tree-selection:focus{outline:none}.kbq-tree-option{--kbq-option-background: var(--kbq-tree-default-container-background);background:var(--kbq-tree-default-container-background)}.kbq-tree-option .kbq-option-text{color:var(--kbq-tree-default-text-color)}.kbq-tree-option .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-default-action-button-color)}.kbq-tree-option .kbq-option-caption{color:var(--kbq-tree-default-caption-color)}.kbq-tree-option:not(.kbq-disabled):hover,.kbq-tree-option:not(.kbq-disabled).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused{--kbq-option-background: var(--kbq-tree-states-hover-container-background);background:var(--kbq-tree-states-hover-container-background)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-text{color:var(--kbq-tree-states-hover-text-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-caption{color:var(--kbq-tree-states-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled):active,.kbq-tree-option:not(.kbq-disabled).kbq-active{--kbq-option-background: var(--kbq-tree-states-active-container-background);background:var(--kbq-tree-states-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected{--kbq-option-background: var(--kbq-tree-states-selected-container-background);background:var(--kbq-tree-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-text{color:var(--kbq-tree-states-selected-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-caption{color:var(--kbq-tree-states-selected-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-states-selected-hover-container-background);background:var(--kbq-tree-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-text{color:var(--kbq-tree-states-selected-hover-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-caption{color:var(--kbq-tree-states-selected-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);background:var(--kbq-tree-states-selected-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected),.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected{--kbq-option-background: var(--kbq-tree-multiple-states-selected-container-background);background:var(--kbq-tree-multiple-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):hover,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-multiple-states-selected-hover-container-background);background:var(--kbq-tree-multiple-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):active,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);background:var(--kbq-tree-multiple-states-selected-active-container-background)}.kbq-tree-option.kbq-disabled{--kbq-option-background: var(--kbq-tree-states-disabled-container-background);background:var(--kbq-tree-states-disabled-container-background)}.kbq-tree-option.kbq-disabled .kbq-option-text{color:var(--kbq-tree-states-disabled-text-color)}.kbq-tree-option.kbq-disabled .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-disabled-action-button-color)}.kbq-tree-option.kbq-disabled .kbq-option-caption{color:var(--kbq-tree-states-disabled-caption-color)}.kbq-tree-option.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-tree-node-toggle .kbq-icon){color:var(--kbq-states-icon-disabled)}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option.kbq-focused:not(.kbq-action-button-focused){border-color:var(--kbq-tree-states-focused-focus-outline-color)}.kbq-tree-option{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-option-caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-content-gap-vertical: 0px;--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "component", type: KbqIcon, selector: "[kbq-icon]", inputs: ["small", "autoColor", "kbq-icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1228
|
+
`, isInline: true, styles: [".kbq-tree-node-toggle{display:flex;align-items:center;justify-content:center;flex-shrink:0;height:100%;cursor:pointer}.kbq-tree-node-toggle .kbq-icon{transform:rotate(-90deg)}.kbq-tree-node-toggle.kbq-expanded .kbq-icon{transform:rotate(0)}.kbq-tree-node-toggle[disabled]{cursor:default}.kbq-tree-node-toggle[disabled] .kbq-icon{color:var(--kbq-tree-states-disabled-tree-toggle-color)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "component", type: KbqIcon, selector: "[kbq-icon]", inputs: ["aria-hidden", "iconSize", "autoColor", "kbq-icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
828
1229
|
}
|
|
829
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1230
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeToggleComponent, decorators: [{
|
|
830
1231
|
type: Component,
|
|
831
1232
|
args: [{ selector: 'kbq-tree-node-toggle', imports: [KbqIcon], template: `
|
|
832
1233
|
<ng-content>
|
|
@@ -834,16 +1235,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
834
1235
|
</ng-content>
|
|
835
1236
|
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
836
1237
|
class: 'kbq-tree-node-toggle',
|
|
1238
|
+
// The expanded state is announced on the owning `treeitem` through `aria-expanded`, and the
|
|
1239
|
+
// Left/Right arrow keys drive it, so exposing the chevron as a second control would only add
|
|
1240
|
+
// a duplicate stop for assistive tech.
|
|
1241
|
+
'aria-hidden': 'true',
|
|
837
1242
|
'[class.kbq-expanded]': 'iconState',
|
|
838
1243
|
'[attr.disabled]': 'disabled || null',
|
|
1244
|
+
'[attr.aria-disabled]': 'disabled || null',
|
|
839
1245
|
'(click)': 'toggle($event)'
|
|
840
|
-
}, exportAs: 'kbqTreeNodeToggle', styles: [".kbq-tree-node-toggle{display:flex;align-items:center;justify-content:center;flex-shrink:0;height:100%;padding-left:var(--kbq-tree-size-toggle-padding);padding-right:var(--kbq-tree-size-toggle-padding);cursor:pointer}.kbq-tree-node-toggle .kbq-icon{transform:rotate(-90deg)}.kbq-tree-node-toggle.kbq-expanded .kbq-icon{transform:rotate(0)}.kbq-tree-node-toggle[disabled]{cursor:default}.kbq-tree-node-toggle[disabled] .kbq-icon{color:var(--kbq-tree-states-disabled-tree-toggle-color)}.kbq-tree-selection:focus{outline:none}.kbq-tree-option{--kbq-option-background: var(--kbq-tree-default-container-background);background:var(--kbq-tree-default-container-background)}.kbq-tree-option .kbq-option-text{color:var(--kbq-tree-default-text-color)}.kbq-tree-option .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-default-action-button-color)}.kbq-tree-option .kbq-option-caption{color:var(--kbq-tree-default-caption-color)}.kbq-tree-option:not(.kbq-disabled):hover,.kbq-tree-option:not(.kbq-disabled).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused{--kbq-option-background: var(--kbq-tree-states-hover-container-background);background:var(--kbq-tree-states-hover-container-background)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-text{color:var(--kbq-tree-states-hover-text-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-caption{color:var(--kbq-tree-states-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled):active,.kbq-tree-option:not(.kbq-disabled).kbq-active{--kbq-option-background: var(--kbq-tree-states-active-container-background);background:var(--kbq-tree-states-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected{--kbq-option-background: var(--kbq-tree-states-selected-container-background);background:var(--kbq-tree-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-text{color:var(--kbq-tree-states-selected-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-caption{color:var(--kbq-tree-states-selected-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-states-selected-hover-container-background);background:var(--kbq-tree-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-text{color:var(--kbq-tree-states-selected-hover-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-caption{color:var(--kbq-tree-states-selected-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);background:var(--kbq-tree-states-selected-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected),.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected{--kbq-option-background: var(--kbq-tree-multiple-states-selected-container-background);background:var(--kbq-tree-multiple-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):hover,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-multiple-states-selected-hover-container-background);background:var(--kbq-tree-multiple-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):active,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);background:var(--kbq-tree-multiple-states-selected-active-container-background)}.kbq-tree-option.kbq-disabled{--kbq-option-background: var(--kbq-tree-states-disabled-container-background);background:var(--kbq-tree-states-disabled-container-background)}.kbq-tree-option.kbq-disabled .kbq-option-text{color:var(--kbq-tree-states-disabled-text-color)}.kbq-tree-option.kbq-disabled .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-disabled-action-button-color)}.kbq-tree-option.kbq-disabled .kbq-option-caption{color:var(--kbq-tree-states-disabled-caption-color)}.kbq-tree-option.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-tree-node-toggle .kbq-icon){color:var(--kbq-states-icon-disabled)}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option.kbq-focused:not(.kbq-action-button-focused){border-color:var(--kbq-tree-states-focused-focus-outline-color)}.kbq-tree-option{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-option-caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-content-gap-vertical: 0px;--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"] }]
|
|
1246
|
+
}, exportAs: 'kbqTreeNodeToggle', styles: [".kbq-tree-node-toggle{display:flex;align-items:center;justify-content:center;flex-shrink:0;height:100%;cursor:pointer}.kbq-tree-node-toggle .kbq-icon{transform:rotate(-90deg)}.kbq-tree-node-toggle.kbq-expanded .kbq-icon{transform:rotate(0)}.kbq-tree-node-toggle[disabled]{cursor:default}.kbq-tree-node-toggle[disabled] .kbq-icon{color:var(--kbq-tree-states-disabled-tree-toggle-color)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"] }]
|
|
841
1247
|
}] });
|
|
1248
|
+
// No ARIA on this host: the directive is routinely applied to the `kbq-tree-option` element itself,
|
|
1249
|
+
// where the option already owns `role`, `aria-disabled` and the rest of the treeitem semantics.
|
|
842
1250
|
class KbqTreeNodeToggleDirective extends KbqTreeNodeToggleBaseDirective {
|
|
843
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
844
|
-
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1251
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeToggleDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1252
|
+
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.25", type: KbqTreeNodeToggleDirective, isStandalone: true, selector: "[kbq-tree-node-toggle], [kbqTreeNodeToggle]", host: { listeners: { "click": "toggle($event)" }, properties: { "attr.disabled": "disabled || null" } }, exportAs: ["kbqTreeNodeToggle"], usesInheritance: true, ngImport: i0 }); }
|
|
845
1253
|
}
|
|
846
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1254
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodeToggleDirective, decorators: [{
|
|
847
1255
|
type: Directive,
|
|
848
1256
|
args: [{
|
|
849
1257
|
selector: '[kbq-tree-node-toggle], [kbqTreeNodeToggle]',
|
|
@@ -857,24 +1265,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
857
1265
|
|
|
858
1266
|
/** Injection token used to provide the parent component to options. */
|
|
859
1267
|
const KBQ_TREE_OPTION_PARENT_COMPONENT = new InjectionToken('KBQ_TREE_OPTION_PARENT_COMPONENT');
|
|
860
|
-
/**
|
|
861
|
-
* Represents a change event for a tree option.
|
|
862
|
-
*
|
|
863
|
-
* @param source - The tree option that has been modified or selected.
|
|
864
|
-
* @param isUserInput - DEPRECATED Will be removed in version 20.
|
|
865
|
-
*/
|
|
1268
|
+
/** Represents a change event for a tree option. */
|
|
866
1269
|
class KbqTreeOptionChange {
|
|
867
|
-
constructor(
|
|
1270
|
+
constructor(
|
|
1271
|
+
/** The tree option that has been modified or selected. */
|
|
1272
|
+
source) {
|
|
868
1273
|
this.source = source;
|
|
869
|
-
this.isUserInput = isUserInput;
|
|
870
1274
|
}
|
|
871
1275
|
}
|
|
872
1276
|
let uniqueIdCounter = 0;
|
|
1277
|
+
const samePredicates = (a, b) => a.disabled === b.disabled && a.expanded === b.expanded;
|
|
873
1278
|
class KbqTreeOption extends KbqTreeNode {
|
|
1279
|
+
/** Container of the option text, measured by `kbq-title`. */
|
|
1280
|
+
get parentTextElement() {
|
|
1281
|
+
return this.titleContainer();
|
|
1282
|
+
}
|
|
874
1283
|
// Same element as `parentTextElement` — `.kbq-option-text` clips the text, so it is measured against itself.
|
|
875
1284
|
get textElement() {
|
|
876
1285
|
return this.parentTextElement;
|
|
877
1286
|
}
|
|
1287
|
+
// Getters rather than the signal queries themselves: `KbqOptionActionComponent` reads the triggers as
|
|
1288
|
+
// directive instances through KBQ_OPTION_ACTION_PARENT — see #DS-5079.
|
|
1289
|
+
/** Tooltip trigger projected into the option. */
|
|
1290
|
+
get tooltipTrigger() {
|
|
1291
|
+
return this.tooltipTriggerQuery();
|
|
1292
|
+
}
|
|
1293
|
+
/** Dropdown trigger projected into the option. */
|
|
1294
|
+
get dropdownTrigger() {
|
|
1295
|
+
return this.dropdownTriggerQuery();
|
|
1296
|
+
}
|
|
878
1297
|
get externalPseudoCheckbox() {
|
|
879
1298
|
return !!this.pseudoCheckbox();
|
|
880
1299
|
}
|
|
@@ -884,34 +1303,23 @@ class KbqTreeOption extends KbqTreeNode {
|
|
|
884
1303
|
set value(value) {
|
|
885
1304
|
this._value = value;
|
|
886
1305
|
}
|
|
887
|
-
|
|
888
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
1306
|
+
/** Whether the option is disabled: through its own input, the tree, or the tree control's `isDisabled`. */
|
|
889
1307
|
get disabled() {
|
|
890
1308
|
if (this.selectAllRow()) {
|
|
891
|
-
return this.
|
|
1309
|
+
return this.disabledInput() || this.tree.disabled;
|
|
892
1310
|
}
|
|
893
|
-
return this.
|
|
1311
|
+
return this.disabledInput() || this.tree.disabled || this.tree.treeControl.isDisabled(this.data);
|
|
894
1312
|
}
|
|
895
|
-
|
|
896
|
-
const newValue = coerceBooleanProperty(value);
|
|
897
|
-
if (newValue !== this._disabled) {
|
|
898
|
-
this._disabled = newValue;
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
// TODO: Skipped for migration because:
|
|
902
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
1313
|
+
/** Whether the option renders a pseudo-checkbox. Falls back to the tree's own mode until bound. */
|
|
903
1314
|
get showCheckbox() {
|
|
904
|
-
return this.
|
|
905
|
-
}
|
|
906
|
-
set showCheckbox(value) {
|
|
907
|
-
this._showCheckbox = coerceBooleanProperty(value);
|
|
1315
|
+
return this.showCheckboxInput() ?? this.tree.showCheckbox;
|
|
908
1316
|
}
|
|
909
1317
|
get selected() {
|
|
910
|
-
return this.
|
|
1318
|
+
return this.selectedState();
|
|
911
1319
|
}
|
|
912
1320
|
set selected(value) {
|
|
913
1321
|
const isSelected = coerceBooleanProperty(value);
|
|
914
|
-
if (isSelected !== this.
|
|
1322
|
+
if (isSelected !== this.selectedState()) {
|
|
915
1323
|
this.setSelected(isSelected);
|
|
916
1324
|
}
|
|
917
1325
|
}
|
|
@@ -922,6 +1330,12 @@ class KbqTreeOption extends KbqTreeNode {
|
|
|
922
1330
|
// TODO: Add input property alternative for node envs.
|
|
923
1331
|
return (this.getHostElement().textContent || '').trim();
|
|
924
1332
|
}
|
|
1333
|
+
get hasFocus() {
|
|
1334
|
+
return this.focused();
|
|
1335
|
+
}
|
|
1336
|
+
set hasFocus(value) {
|
|
1337
|
+
this.focused.set(value);
|
|
1338
|
+
}
|
|
925
1339
|
get isExpandable() {
|
|
926
1340
|
if (this.selectAllRow()) {
|
|
927
1341
|
return false;
|
|
@@ -938,28 +1352,86 @@ class KbqTreeOption extends KbqTreeNode {
|
|
|
938
1352
|
get isToggleInDefaultPlace() {
|
|
939
1353
|
return !!(this.toggleElementDirective() || this.toggleElementComponent());
|
|
940
1354
|
}
|
|
1355
|
+
get checkboxState() {
|
|
1356
|
+
return this.checkbox();
|
|
1357
|
+
}
|
|
1358
|
+
set checkboxState(value) {
|
|
1359
|
+
this.checkbox.set(value);
|
|
1360
|
+
}
|
|
1361
|
+
/**
|
|
1362
|
+
* `aria-expanded` of the row as of the last check, reported for every branch and omitted on a leaf.
|
|
1363
|
+
*
|
|
1364
|
+
* Deliberately not `isExpandable`, which also asks whether the toggle is operable: filtering
|
|
1365
|
+
* disables every toggle while leaving the matched branches expanded, and a branch that stops
|
|
1366
|
+
* reporting `aria-expanded` is announced as a leaf while its children are on screen.
|
|
1367
|
+
*/
|
|
1368
|
+
get ariaExpanded() {
|
|
1369
|
+
// The one tracked read of `predicates`, which subscribes the row to the signals the predicates read: the
|
|
1370
|
+
// other bindings read the snapshot `ngDoCheck` takes along with it, as a second read of this row's own signal
|
|
1371
|
+
// would walk the producers of every row checked before it.
|
|
1372
|
+
return this.predicates().expanded;
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* `aria-checked` of the row: tri-state for a checkbox option, and the "select all" state for the
|
|
1376
|
+
* row that drives it. `null` for a plain option, which reports `aria-selected` instead.
|
|
1377
|
+
*/
|
|
1378
|
+
get ariaChecked() {
|
|
1379
|
+
// The checkbox state is read here rather than in `ngDoCheck`: this read is what brings the row back once the
|
|
1380
|
+
// state changes.
|
|
1381
|
+
return this.checkedCheckboxRow ? this.toAriaChecked(this.checkboxState) : this.checkedSelectAllState;
|
|
1382
|
+
}
|
|
1383
|
+
/** `aria-selected` of the row as of the last check. Options with a checkbox report `aria-checked` instead. */
|
|
1384
|
+
get ariaSelected() {
|
|
1385
|
+
return this.checkedAriaSelected;
|
|
1386
|
+
}
|
|
941
1387
|
constructor() {
|
|
942
1388
|
const tree = inject(KBQ_TREE_OPTION_PARENT_COMPONENT);
|
|
943
1389
|
super();
|
|
944
1390
|
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
945
|
-
this.
|
|
1391
|
+
this.environmentInjector = inject(EnvironmentInjector);
|
|
946
1392
|
this.destroyRef = inject(DestroyRef);
|
|
947
|
-
this.
|
|
948
|
-
this.
|
|
1393
|
+
this.ngZone = inject(NgZone);
|
|
1394
|
+
this.renderer = inject(Renderer2);
|
|
1395
|
+
this.focusEvents = new Subject();
|
|
1396
|
+
this.blurEvents = new Subject();
|
|
1397
|
+
/** Emits when the option takes focus. */
|
|
1398
|
+
this.onFocus = this.focusEvents.asObservable();
|
|
1399
|
+
/** Emits when the option loses focus. */
|
|
1400
|
+
this.onBlur = this.blurEvents.asObservable();
|
|
949
1401
|
this.preventBlur = false;
|
|
950
|
-
this.
|
|
951
|
-
this.
|
|
952
|
-
this.
|
|
953
|
-
this.
|
|
954
|
-
this.
|
|
955
|
-
this.
|
|
1402
|
+
this.titleContainer = viewChild('kbqTitleContainer', ...(ngDevMode ? [{ debugName: "titleContainer" }] : /* istanbul ignore next */ []));
|
|
1403
|
+
this.toggleElementDirective = contentChild(KbqTreeNodeToggleDirective, ...(ngDevMode ? [{ debugName: "toggleElementDirective" }] : /* istanbul ignore next */ []));
|
|
1404
|
+
this.toggleElementComponent = contentChild(KbqTreeNodeToggleComponent, ...(ngDevMode ? [{ debugName: "toggleElementComponent" }] : /* istanbul ignore next */ []));
|
|
1405
|
+
this.pseudoCheckbox = contentChild(KbqPseudoCheckbox, ...(ngDevMode ? [{ debugName: "pseudoCheckbox" }] : /* istanbul ignore next */ []));
|
|
1406
|
+
this.actionButton = contentChild(KbqOptionActionComponent, ...(ngDevMode ? [{ debugName: "actionButton" }] : /* istanbul ignore next */ []));
|
|
1407
|
+
this.tooltipTriggerQuery = contentChild(KbqTooltipTrigger, ...(ngDevMode ? [{ debugName: "tooltipTriggerQuery" }] : /* istanbul ignore next */ []));
|
|
1408
|
+
this.dropdownTriggerQuery = contentChild(KbqDropdownTrigger, ...(ngDevMode ? [{ debugName: "dropdownTriggerQuery" }] : /* istanbul ignore next */ []));
|
|
1409
|
+
this.checkboxThirdState = input(false, ...(ngDevMode ? [{ debugName: "checkboxThirdState" }] : /* istanbul ignore next */ []));
|
|
1410
|
+
/** @docs-private */
|
|
1411
|
+
this.disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
|
|
1412
|
+
transform: booleanAttribute });
|
|
1413
|
+
/**
|
|
1414
|
+
* `disabled` as of the last check, which the host bindings read: the tree control's `isDisabled` predicate gives
|
|
1415
|
+
* no notice of a change and may be costly, so a check asks it once.
|
|
1416
|
+
*/
|
|
1417
|
+
this.checkedDisabled = false;
|
|
1418
|
+
/**
|
|
1419
|
+
* What the tree control's `isDisabled` and `isExpandable` say about the row. Derived, so a predicate reading a
|
|
1420
|
+
* signal brings the row back once that signal changes; `ngDoCheck` sets it on every check for one reading plain
|
|
1421
|
+
* state. Read by a single host binding, see `ariaExpanded`.
|
|
1422
|
+
*/
|
|
1423
|
+
this.predicates = linkedSignal(() => this.resolvePredicates(), { ...(ngDevMode ? { debugName: "predicates" } : /* istanbul ignore next */ {}), equal: samePredicates });
|
|
1424
|
+
// Values of the ARIA host bindings as of the last check, resolved by `ngDoCheck`.
|
|
1425
|
+
this.checkedAriaSelected = null;
|
|
1426
|
+
this.checkedSelectAllState = null;
|
|
1427
|
+
this.checkedCheckboxRow = false;
|
|
956
1428
|
/**
|
|
957
1429
|
* Whether the option can be selected by user interaction (click, keyboard, select all).
|
|
958
1430
|
* A non-selectable option remains focusable, navigable and expandable.
|
|
959
1431
|
* Programmatic selection (`setSelected`, `select`, value accessor) is not affected.
|
|
960
1432
|
* Options that are not rendered (e.g. collapsed) are not checked by "select all".
|
|
961
1433
|
*/
|
|
962
|
-
this.selectable = input(true, ...(ngDevMode ?
|
|
1434
|
+
this.selectable = input(true, { ...(ngDevMode ? { debugName: "selectable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
963
1435
|
/**
|
|
964
1436
|
* Whether this option is the tree's "select all" row rather than a rendered data node.
|
|
965
1437
|
*
|
|
@@ -967,40 +1439,90 @@ class KbqTreeOption extends KbqTreeNode {
|
|
|
967
1439
|
* (`getValue`, `isDisabled`, `isExpandable`, descendants) is skipped — those accessors belong to the
|
|
968
1440
|
* consumer and must never be handed a node their data source has never seen. Its checkbox state and
|
|
969
1441
|
* selection are driven from the outside instead.
|
|
1442
|
+
*
|
|
970
1443
|
* @docs-private
|
|
971
1444
|
*/
|
|
972
|
-
this.selectAllRow = input(false, ...(ngDevMode ?
|
|
973
|
-
|
|
1445
|
+
this.selectAllRow = input(false, { ...(ngDevMode ? { debugName: "selectAllRow" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1446
|
+
/** @docs-private */
|
|
1447
|
+
this.showCheckboxInput = input(undefined, { ...(ngDevMode ? { debugName: "showCheckboxInput" } : /* istanbul ignore next */ {}), alias: 'showCheckbox',
|
|
1448
|
+
transform: booleanAttribute });
|
|
1449
|
+
/** Emits whenever the selected state of the option changes. */
|
|
1450
|
+
this.selectionChange = output();
|
|
1451
|
+
/** @deprecated Use `selectionChange` instead. Will be removed in 22.0.0. */
|
|
1452
|
+
this.onSelectionChange = output({ alias: 'onSelectionChange' });
|
|
1453
|
+
// Not an `output()`: `KbqTreeSelect` merges this stream with rxjs, which an `OutputEmitterRef`
|
|
1454
|
+
// cannot feed without wrapping every call site in `outputToObservable`.
|
|
974
1455
|
this.userInteraction = new EventEmitter();
|
|
975
|
-
this.
|
|
1456
|
+
this.selectedState = signal(false, ...(ngDevMode ? [{ debugName: "selectedState" }] : /* istanbul ignore next */ []));
|
|
976
1457
|
this._id = `kbq-tree-option-${uniqueIdCounter++}`;
|
|
977
|
-
this.
|
|
1458
|
+
this.focused = signal(false, ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
|
|
1459
|
+
// Raised from reporting a focus until `hasFocus` is: `kbqFocusAndReveal` fires `focusin` synchronously, and its
|
|
1460
|
+
// listener calls back into `focus()` while `hasFocus` is still false.
|
|
1461
|
+
this.focusReported = false;
|
|
1462
|
+
this.checkbox = signal('unchecked', ...(ngDevMode ? [{ debugName: "checkbox" }] : /* istanbul ignore next */ []));
|
|
978
1463
|
this.updateCheckboxState = () => {
|
|
979
1464
|
if (this.selectAllRow())
|
|
980
1465
|
return;
|
|
981
|
-
|
|
982
|
-
if (this.descendantsAllSelected()) {
|
|
983
|
-
this.checkboxState = 'checked';
|
|
984
|
-
}
|
|
985
|
-
else if (this.descendantsPartiallySelected()) {
|
|
986
|
-
this.checkboxState = 'indeterminate';
|
|
987
|
-
}
|
|
988
|
-
else {
|
|
989
|
-
this.checkboxState = this.selected ? 'checked' : 'unchecked';
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
else {
|
|
993
|
-
this.checkboxState = this.selected ? 'checked' : 'unchecked';
|
|
994
|
-
}
|
|
1466
|
+
this.syncCheckboxState();
|
|
995
1467
|
this.updateParentsCheckboxState(this.data);
|
|
996
1468
|
};
|
|
997
1469
|
this.tree = tree;
|
|
1470
|
+
// Not a host listener: one would check the views on every row the pointer crosses, and only a tree in a select
|
|
1471
|
+
// reacts to it.
|
|
1472
|
+
const unlisten = this.ngZone.runOutsideAngular(() => this.renderer.listen(this.elementRef.nativeElement, 'mouseenter', () => this.onMouseenter()));
|
|
1473
|
+
this.destroyRef.onDestroy(unlisten);
|
|
1474
|
+
}
|
|
1475
|
+
ngOnInit() {
|
|
1476
|
+
// Selected from its first check: the tree's sweep reaches a new row a macrotask later, and a row it marked
|
|
1477
|
+
// would render unselected first and then report a selection nobody made.
|
|
1478
|
+
if (!this.selectAllRow())
|
|
1479
|
+
this.selectedState.set(!!this.tree.selectionModel?.isSelected(this.data));
|
|
1480
|
+
}
|
|
1481
|
+
ngDoCheck() {
|
|
1482
|
+
// Asked once per check, for a predicate reading plain state; a set to an equal value does nothing.
|
|
1483
|
+
const predicates = this.resolvePredicates();
|
|
1484
|
+
this.predicates.set(predicates);
|
|
1485
|
+
if (predicates.disabled !== this.checkedDisabled) {
|
|
1486
|
+
this.checkedDisabled = predicates.disabled;
|
|
1487
|
+
this.changeDetectorRef.markForCheck();
|
|
1488
|
+
}
|
|
1489
|
+
// Resolved here, untracked: a tree checks its rows under the one reactive consumer of its view, where a signal
|
|
1490
|
+
// read again costs a walk over every signal read before it. The host bindings read each signal of the row once
|
|
1491
|
+
// (`selected`, `checkboxState`, `predicates`, the mode through `tree.multiple`), which brings the row back here
|
|
1492
|
+
// on a change.
|
|
1493
|
+
if (this.selectAllRow()) {
|
|
1494
|
+
this.checkedAriaSelected = null;
|
|
1495
|
+
this.checkedCheckboxRow = false;
|
|
1496
|
+
this.checkedSelectAllState = this.toAriaChecked(this.tree.selectAllState);
|
|
1497
|
+
}
|
|
1498
|
+
else {
|
|
1499
|
+
const showCheckbox = this.showCheckbox;
|
|
1500
|
+
this.checkedAriaSelected = showCheckbox ? null : this.selected;
|
|
1501
|
+
this.checkedCheckboxRow = showCheckbox;
|
|
1502
|
+
this.checkedSelectAllState = null;
|
|
1503
|
+
}
|
|
998
1504
|
}
|
|
999
1505
|
ngAfterContentInit() {
|
|
1000
1506
|
if (this.selectAllRow())
|
|
1001
1507
|
return;
|
|
1002
|
-
|
|
1508
|
+
// Its own state only: rendering a row changes no ancestor's, and the tree recomputes every row once the data
|
|
1509
|
+
// nodes change.
|
|
1510
|
+
Promise.resolve().then(() => this.syncCheckboxState());
|
|
1511
|
+
this.value = this.tree.treeControl.getValue(this.data);
|
|
1512
|
+
}
|
|
1513
|
+
/**
|
|
1514
|
+
* The value and the checkbox state were derived from the node this view held before it was reused,
|
|
1515
|
+
* and `ngAfterContentInit` does not run again. A stale `value` drops the row out of the tree's
|
|
1516
|
+
* `renderedOptions`, so it renders but can no longer be focused, selected or copied.
|
|
1517
|
+
*
|
|
1518
|
+
* @docs-private
|
|
1519
|
+
*/
|
|
1520
|
+
refresh() {
|
|
1521
|
+
super.refresh();
|
|
1522
|
+
if (this.selectAllRow())
|
|
1523
|
+
return;
|
|
1003
1524
|
this.value = this.tree.treeControl.getValue(this.data);
|
|
1525
|
+
this.markForCheck();
|
|
1004
1526
|
}
|
|
1005
1527
|
descendantsAllSelected() {
|
|
1006
1528
|
const descendants = this.tree.treeControl.getDescendants(this.data);
|
|
@@ -1011,132 +1533,202 @@ class KbqTreeOption extends KbqTreeNode {
|
|
|
1011
1533
|
return descendants.some((child) => this.tree?.selectionModel.isSelected(child));
|
|
1012
1534
|
}
|
|
1013
1535
|
updateParentsCheckboxState(node) {
|
|
1014
|
-
this.tree.treeControl.getParents(node, [])
|
|
1015
|
-
|
|
1016
|
-
|
|
1536
|
+
const parents = new Set(this.tree.treeControl.getParents(node, []));
|
|
1537
|
+
if (!parents.size)
|
|
1538
|
+
return;
|
|
1539
|
+
// Each ancestor reads its state off the selection rather than off its children, so recomputing it is enough.
|
|
1540
|
+
this.tree.unorderedOptions.forEach((option) => {
|
|
1541
|
+
if (parents.has(option.data))
|
|
1542
|
+
option.syncCheckboxState();
|
|
1017
1543
|
});
|
|
1018
1544
|
}
|
|
1019
1545
|
toggle() {
|
|
1020
|
-
|
|
1546
|
+
// Untracked, like the other imperative methods: called from a consumer's `effect()`, the state read on the
|
|
1547
|
+
// way — `selected`, focus, `disabled`, the inputs — would make the effect run again whenever it changes.
|
|
1548
|
+
untracked(() => (this.selected = !this.selected));
|
|
1021
1549
|
}
|
|
1022
1550
|
setSelected(selected) {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
this.
|
|
1035
|
-
|
|
1036
|
-
|
|
1551
|
+
untracked(() => {
|
|
1552
|
+
if (this.selectAllRow() || this.selectedState() === selected || !this.tree.selectionModel) {
|
|
1553
|
+
return;
|
|
1554
|
+
}
|
|
1555
|
+
this.selectedState.set(selected);
|
|
1556
|
+
if (selected) {
|
|
1557
|
+
this.tree.selectionModel.select(this.data);
|
|
1558
|
+
}
|
|
1559
|
+
else {
|
|
1560
|
+
this.tree.selectionModel.deselect(this.data);
|
|
1561
|
+
}
|
|
1562
|
+
if (this.showCheckbox) {
|
|
1563
|
+
this.updateCheckboxState();
|
|
1564
|
+
}
|
|
1565
|
+
});
|
|
1037
1566
|
}
|
|
1038
1567
|
focus(focusOrigin) {
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
this.
|
|
1045
|
-
|
|
1046
|
-
this.
|
|
1047
|
-
this.
|
|
1048
|
-
|
|
1049
|
-
|
|
1568
|
+
untracked(() => {
|
|
1569
|
+
if (focusOrigin === 'program' || this.disabled || this.actionButton()?.hasFocus)
|
|
1570
|
+
return;
|
|
1571
|
+
// With the pointer already on this node, revealing it would shift the tree out from under it.
|
|
1572
|
+
kbqFocusAndReveal(this.elementRef.nativeElement, focusOrigin === 'mouse');
|
|
1573
|
+
if (!this.hasFocus && !this.focusReported) {
|
|
1574
|
+
const event = { option: this };
|
|
1575
|
+
this.focusReported = true;
|
|
1576
|
+
this.focusEvents.next(event);
|
|
1577
|
+
this.tree.reportOptionFocus?.(event);
|
|
1578
|
+
Promise.resolve().then(() => {
|
|
1579
|
+
this.focusReported = false;
|
|
1580
|
+
this.hasFocus = true;
|
|
1581
|
+
// The view only: focus changes no checkbox state.
|
|
1582
|
+
this.changeDetectorRef.markForCheck();
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
});
|
|
1050
1586
|
}
|
|
1051
1587
|
blur() {
|
|
1052
1588
|
if (this.preventBlur) {
|
|
1053
1589
|
return;
|
|
1054
1590
|
}
|
|
1055
|
-
//
|
|
1056
|
-
//
|
|
1057
|
-
//
|
|
1058
|
-
//
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
this.
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
|
|
1591
|
+
// Deferred until the focus has settled: whatever takes it — this option's action button, or another option,
|
|
1592
|
+
// which marks itself focused on a microtask — records it only after this blur. Reported before that, the move
|
|
1593
|
+
// reads as the focus leaving the options: the option would drop its focused state while its own action button
|
|
1594
|
+
// holds the focus, and the tree its active option.
|
|
1595
|
+
afterNextRender(() => {
|
|
1596
|
+
// Focus can be back by the time this runs (a blur and a focus in the same task): then nothing was lost.
|
|
1597
|
+
if (_getFocusedElementPierceShadowDom() === this.elementRef.nativeElement)
|
|
1598
|
+
return;
|
|
1599
|
+
if (this.actionButton()?.hasFocus || this.tree.optionShouldHoldFocusOnBlur) {
|
|
1600
|
+
return;
|
|
1601
|
+
}
|
|
1602
|
+
this.hasFocus = false;
|
|
1603
|
+
const event = { option: this };
|
|
1604
|
+
this.blurEvents.next(event);
|
|
1605
|
+
this.tree.reportOptionBlur?.(event);
|
|
1606
|
+
},
|
|
1607
|
+
// The environment injector, not the option's: an option removed while focused is blurred as its view is
|
|
1608
|
+
// destroyed, and the tree still has to hear about it to move focus.
|
|
1609
|
+
{ injector: this.environmentInjector });
|
|
1610
|
+
}
|
|
1611
|
+
/** @docs-private */
|
|
1073
1612
|
getHeight() {
|
|
1074
1613
|
return kbqGetElementHeight(this.elementRef.nativeElement);
|
|
1075
1614
|
}
|
|
1615
|
+
/**
|
|
1616
|
+
* Label the key manager's type-ahead matches against.
|
|
1617
|
+
*
|
|
1618
|
+
* The "select all" row is navigable but is not a data node, and its label is a localized phrase —
|
|
1619
|
+
* answering type-ahead with it would hijack every query starting with that letter.
|
|
1620
|
+
*
|
|
1621
|
+
* @docs-private
|
|
1622
|
+
*/
|
|
1623
|
+
getLabel() {
|
|
1624
|
+
return this.selectAllRow() ? '' : this.viewValue;
|
|
1625
|
+
}
|
|
1076
1626
|
select(setFocus = true) {
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
this.
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1627
|
+
untracked(() => {
|
|
1628
|
+
if (this.selectAllRow() || this.selectedState()) {
|
|
1629
|
+
return;
|
|
1630
|
+
}
|
|
1631
|
+
this.selectedState.set(true);
|
|
1632
|
+
if (setFocus && !this.hasFocus) {
|
|
1633
|
+
this.focus();
|
|
1634
|
+
}
|
|
1635
|
+
// Its own state only: an ancestor's reads the selection model, which this leaves as it is.
|
|
1636
|
+
this.syncCheckboxState();
|
|
1637
|
+
this.emitSelectionChangeEvent();
|
|
1638
|
+
});
|
|
1087
1639
|
}
|
|
1088
1640
|
deselect() {
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1641
|
+
untracked(() => {
|
|
1642
|
+
if (this.selectAllRow() || !this.selectedState()) {
|
|
1643
|
+
return;
|
|
1644
|
+
}
|
|
1645
|
+
this.selectedState.set(false);
|
|
1646
|
+
// Its own state only, as in `select`.
|
|
1647
|
+
this.syncCheckboxState();
|
|
1648
|
+
this.emitSelectionChangeEvent();
|
|
1649
|
+
});
|
|
1096
1650
|
}
|
|
1097
1651
|
onKeydown($event) {
|
|
1098
1652
|
kbqFocusOptionActionOnTab($event, this.actionButton());
|
|
1099
1653
|
}
|
|
1100
1654
|
selectViaInteraction($event) {
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1655
|
+
untracked(() => {
|
|
1656
|
+
if (this.disabled || !this.selectable()) {
|
|
1657
|
+
return;
|
|
1658
|
+
}
|
|
1659
|
+
this.userInteraction.emit();
|
|
1660
|
+
const shiftKey = $event ? hasModifierKey($event, 'shiftKey') : false;
|
|
1661
|
+
// ctrlKey is for Windows, metaKey is for MacOS
|
|
1662
|
+
const ctrlKey = $event ? hasModifierKey($event, 'ctrlKey', 'metaKey') : false;
|
|
1663
|
+
this.tree.setSelectedOptionsByClick(this, shiftKey, ctrlKey);
|
|
1664
|
+
});
|
|
1110
1665
|
}
|
|
1111
1666
|
emitSelectionChangeEvent() {
|
|
1112
1667
|
// The tree can still hold an option whose node was re-rendered away until it rebuilds its list.
|
|
1113
1668
|
if (this.destroyRef.destroyed)
|
|
1114
1669
|
return;
|
|
1115
|
-
|
|
1670
|
+
const event = new KbqTreeOptionChange(this);
|
|
1671
|
+
this.selectionChange.emit(event);
|
|
1672
|
+
this.onSelectionChange.emit(event);
|
|
1116
1673
|
}
|
|
1117
1674
|
getHostElement() {
|
|
1118
1675
|
return this.elementRef.nativeElement;
|
|
1119
1676
|
}
|
|
1120
1677
|
markForCheck() {
|
|
1121
1678
|
this.changeDetectorRef.markForCheck();
|
|
1122
|
-
|
|
1123
|
-
|
|
1679
|
+
// Its own state only: after a selection, data or mode change the tree calls this on every option. A projected
|
|
1680
|
+
// checkbox shows the state while the tree's own is hidden.
|
|
1681
|
+
if (this.showCheckbox || this.externalPseudoCheckbox) {
|
|
1682
|
+
this.syncCheckboxState();
|
|
1124
1683
|
}
|
|
1125
1684
|
}
|
|
1126
1685
|
/** @docs-private */
|
|
1127
1686
|
onMouseenter() {
|
|
1128
1687
|
if (this.disabled || !this.tree.inSelect)
|
|
1129
1688
|
return;
|
|
1130
|
-
|
|
1689
|
+
// Focusing the option it already holds would only run change detection.
|
|
1690
|
+
if (this.hasFocus && _getFocusedElementPierceShadowDom() === this.elementRef.nativeElement)
|
|
1691
|
+
return;
|
|
1692
|
+
this.ngZone.run(() => this.focus('mouse'));
|
|
1693
|
+
}
|
|
1694
|
+
/** Recomputes the option's own checkbox state, leaving its ancestors as they are. */
|
|
1695
|
+
syncCheckboxState() {
|
|
1696
|
+
if (this.selectAllRow())
|
|
1697
|
+
return;
|
|
1698
|
+
if (this.checkboxThirdState() && this.isExpandable) {
|
|
1699
|
+
// One descendant walk, not two: each walk covers the whole subtree, and the roll-up runs this method for
|
|
1700
|
+
// every ancestor.
|
|
1701
|
+
const descendants = this.tree.treeControl.getDescendants(this.data);
|
|
1702
|
+
const selectedCount = descendants.filter((child) => this.tree.selectionModel.isSelected(child)).length;
|
|
1703
|
+
if (selectedCount === descendants.length) {
|
|
1704
|
+
this.checkboxState = 'checked';
|
|
1705
|
+
}
|
|
1706
|
+
else if (selectedCount > 0) {
|
|
1707
|
+
this.checkboxState = 'indeterminate';
|
|
1708
|
+
}
|
|
1709
|
+
else {
|
|
1710
|
+
this.checkboxState = this.selected ? 'checked' : 'unchecked';
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
else {
|
|
1714
|
+
this.checkboxState = this.selected ? 'checked' : 'unchecked';
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
toAriaChecked(state) {
|
|
1718
|
+
return state === 'indeterminate' ? 'mixed' : `${state === 'checked'}`;
|
|
1131
1719
|
}
|
|
1132
|
-
|
|
1133
|
-
|
|
1720
|
+
resolvePredicates() {
|
|
1721
|
+
const branch = !this.selectAllRow() && this.tree.treeControl.isExpandable(this.data);
|
|
1722
|
+
return { disabled: this.disabled, expanded: branch ? this.isExpanded : null };
|
|
1723
|
+
}
|
|
1724
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeOption, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1725
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: KbqTreeOption, isStandalone: true, selector: "kbq-tree-option", inputs: { checkboxThirdState: { classPropertyName: "checkboxThirdState", publicName: "checkboxThirdState", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, selectAllRow: { classPropertyName: "selectAllRow", publicName: "selectAllRow", isSignal: true, isRequired: false, transformFunction: null }, showCheckboxInput: { classPropertyName: "showCheckboxInput", publicName: "showCheckbox", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", onSelectionChange: "onSelectionChange" }, host: { attributes: { "role": "treeitem" }, listeners: { "focusin": "focus()", "blur": "blur()", "click": "selectViaInteraction($event)", "keydown": "onKeydown($event)" }, properties: { "class.kbq-tree-option_multiple": "tree.multiple", "class.kbq-selected": "selected", "class.kbq-focused": "hasFocus", "class.kbq-disabled": "checkedDisabled", "class.kbq-action-button-focused": "actionButton()?.active", "attr.id": "id", "attr.tabindex": "-1", "attr.aria-disabled": "checkedDisabled || null", "attr.aria-expanded": "ariaExpanded", "attr.aria-checked": "ariaChecked", "attr.aria-selected": "ariaSelected" }, classAttribute: "kbq-tree-option" }, providers: [
|
|
1134
1726
|
{ provide: KbqTreeNode, useExisting: KbqTreeOption },
|
|
1135
1727
|
{ provide: KBQ_TITLE_TEXT_REF, useExisting: KbqTreeOption },
|
|
1136
1728
|
{ provide: KBQ_OPTION_ACTION_PARENT, useExisting: KbqTreeOption }
|
|
1137
|
-
], queries: [{ propertyName: "toggleElementDirective", first: true, predicate: KbqTreeNodeToggleDirective, descendants: true, isSignal: true }, { propertyName: "toggleElementComponent", first: true, predicate: KbqTreeNodeToggleComponent, descendants: true, isSignal: true }, { propertyName: "pseudoCheckbox", first: true, predicate: KbqPseudoCheckbox, descendants: true, isSignal: true }, { propertyName: "actionButton", first: true, predicate: KbqOptionActionComponent, descendants: true, isSignal: true }, { propertyName: "tooltipTrigger", first: true, predicate: KbqTooltipTrigger, descendants: true }, { propertyName: "dropdownTrigger", first: true, predicate: KbqDropdownTrigger, descendants: true }], viewQueries: [{ propertyName: "parentTextElement", first: true, predicate: ["kbqTitleContainer"], descendants: true }], exportAs: ["kbqTreeOption"], usesInheritance: true, ngImport: i0, template: "<ng-content select=\"kbq-tree-node-toggle, [kbq-tree-node-toggle], [kbqTreeNodeToggle]\" />\n\n@if (externalPseudoCheckbox) {\n <ng-content select=\"kbq-pseudo-checkbox\" />\n} @else if (showCheckbox) {\n <kbq-pseudo-checkbox [disabled]=\"disabled\" [state]=\"checkboxState\" />\n}\n\n<ng-content select=\"kbq-checkbox\" />\n\n<ng-content select=\"[kbq-icon]\" />\n\n<ng-content select=\"kbq-progress-spinner\" />\n\n<span #kbqTitleContainer class=\"kbq-option-text\">\n <ng-content />\n</span>\n\n@if (actionButton()) {\n <kbq-action-container>\n <ng-content select=\"kbq-option-action\" />\n </kbq-action-container>\n}\n", styles: ["@keyframes kbq-progress{0%{background-position:0 0}to{background-position:64px 0}}.kbq-progress{position:relative}.kbq-progress:after{content:\"\";position:absolute;border-radius:inherit;inset:0;background:linear-gradient(135deg,#0000000a 12px,#ffffff1a 12px 22px,#0000000a 22px 34px,#ffffff1a 34px) repeat;background-size:32px 32px;animation:kbq-progress 1s linear infinite}@media(prefers-reduced-motion:reduce){.kbq-progress:after{animation:none}}.kbq-group{display:flex;flex-direction:row}.kbq-group_justified>.kbq-group-item{width:100%}.kbq-group .kbq-group-item+.kbq-group-item{margin-left:calc(-1 * var(--kbq-size-border-width))}.kbq-group>.kbq-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.kbq-group>.kbq-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.kbq-group>.kbq-group-item:not(:first-child):not(:last-child){border-radius:0}.kbq-group>.kbq-group-item:first-child:not(:last-child) .kbq-form-field__container{border-bottom-right-radius:0;border-top-right-radius:0}.kbq-group>.kbq-group-item:last-child:not(:first-child) .kbq-form-field__container{border-bottom-left-radius:0;border-top-left-radius:0}.kbq-group>.kbq-group-item:not(:first-child):not(:last-child) .kbq-form-field__container{border-radius:0}.kbq-vertical-group{display:flex;flex-direction:column}.kbq-vertical-group>.kbq-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--kbq-size-border-radius)}.kbq-vertical-group>.kbq-group-item:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:var(--kbq-size-border-radius)}.kbq-vertical-group>.kbq-group-item:not(:first-child):not(:last-child){border-radius:0}.kbq-vertical-group .kbq-group-item+.kbq-group-item{margin-top:calc(-1 * var(--kbq-size-border-width))}.kbq-vertical-group>.kbq-group-item:first-child:not(:last-child) .kbq-form-field__container{border-bottom-right-radius:0;border-bottom-left-radius:0}.kbq-vertical-group>.kbq-group-item:last-child:not(:first-child) .kbq-form-field__container{border-top-right-radius:0;border-top-left-radius:0}.kbq-vertical-group>.kbq-group-item:not(:first-child):not(:last-child) .kbq-form-field__container{border-radius:0}.kbq-truncate-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-no-select,.kbq-tree-option{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.kbq-tree-option:not(.kbq-disabled):hover .kbq-action-container,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-action-container,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-action-container{display:flex}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option:not(.kbq-disabled).kbq-focused .kbq-action-container{display:flex}.kbq-tree-option{position:relative;box-sizing:border-box;display:flex;align-items:center;min-height:32px;overflow-wrap:break-word;border-width:var(--kbq-tree-size-container-focus-outline-width);border-style:solid;border-color:transparent;border-radius:var(--kbq-tree-option-border-radius);padding-top:calc(var(--kbq-tree-size-container-padding-vertical) - var(--kbq-tree-size-container-focus-outline-width));padding-right:calc(var(--kbq-tree-size-container-padding-right) - var(--kbq-tree-size-container-focus-outline-width));padding-bottom:calc(var(--kbq-tree-size-container-padding-vertical) - var(--kbq-tree-size-container-focus-outline-width));gap:var(--kbq-tree-size-container-content-gap-horizontal)}.kbq-tree-option .kbq-option-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-tree-option .kbq-option-text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;overflow:hidden}.kbq-tree-option .kbq-option-text:empty{display:none}.kbq-tree-option .kbq-option-text{display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-top:var(--kbq-list-size-text-padding-vertical, 0);padding-bottom:var(--kbq-list-size-text-padding-vertical, 0)}.kbq-tree-option:has(.kbq-option-caption)>[kbq-tree-node-toggle],.kbq-tree-option:has(.kbq-option-caption)>[kbqTreeNodeToggle],.kbq-tree-option:has(.kbq-option-caption)>.kbq-tree-node-toggle,.kbq-tree-option:has(.kbq-option-caption)>.kbq-pseudo-checkbox,.kbq-tree-option:has(.kbq-option-caption)>kbq-checkbox,.kbq-tree-option:has(.kbq-option-caption)>[kbq-icon],.kbq-tree-option:has(.kbq-option-caption)>kbq-progress-spinner{align-self:flex-start;margin-top:var(--kbq-size-3xs)}.kbq-tree-option:has(.kbq-option-caption)>.kbq-tree-node-toggle{height:var(--kbq-typography-text-normal-line-height);margin-top:0}.kbq-tree-option:focus{outline:none}.kbq-tree-option:not(.kbq-disabled){cursor:pointer}.kbq-tree-option:is(.kbq-checked,.kbq-selected,.kbq-focused):has(+:is(.kbq-checked,.kbq-selected,.kbq-focused)){border-bottom-left-radius:0;border-bottom-right-radius:0}.kbq-tree-option:is(.kbq-checked,.kbq-selected,.kbq-focused)+:is(.kbq-checked,.kbq-selected,.kbq-focused){border-top-left-radius:0;border-top-right-radius:0}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-content-gap-vertical: 0px;--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "component", type: KbqPseudoCheckbox, selector: "kbq-pseudo-checkbox", inputs: ["big", "state", "disabled"] }, { kind: "component", type: KbqActionContainer, selector: "kbq-action-container", exportAs: ["kbqActionContainer"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1729
|
+
], queries: [{ propertyName: "toggleElementDirective", first: true, predicate: KbqTreeNodeToggleDirective, descendants: true, isSignal: true }, { propertyName: "toggleElementComponent", first: true, predicate: KbqTreeNodeToggleComponent, descendants: true, isSignal: true }, { propertyName: "pseudoCheckbox", first: true, predicate: KbqPseudoCheckbox, descendants: true, isSignal: true }, { propertyName: "actionButton", first: true, predicate: KbqOptionActionComponent, descendants: true, isSignal: true }, { propertyName: "tooltipTriggerQuery", first: true, predicate: KbqTooltipTrigger, descendants: true, isSignal: true }, { propertyName: "dropdownTriggerQuery", first: true, predicate: KbqDropdownTrigger, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "titleContainer", first: true, predicate: ["kbqTitleContainer"], descendants: true, isSignal: true }], exportAs: ["kbqTreeOption"], usesInheritance: true, ngImport: i0, template: "<ng-content select=\"kbq-tree-node-toggle, [kbq-tree-node-toggle], [kbqTreeNodeToggle]\" />\n\n@if (externalPseudoCheckbox) {\n <ng-content select=\"kbq-pseudo-checkbox\" />\n} @else if (showCheckbox) {\n <kbq-pseudo-checkbox [disabled]=\"disabled\" [state]=\"checkboxState\" />\n}\n\n<ng-content select=\"kbq-checkbox\" />\n\n<ng-content select=\"[kbq-icon]\" />\n\n<ng-content select=\"kbq-progress-spinner\" />\n\n<span #kbqTitleContainer class=\"kbq-option-text\">\n <ng-content />\n</span>\n\n@if (actionButton()) {\n <kbq-action-container>\n <ng-content select=\"kbq-option-action\" />\n </kbq-action-container>\n}\n", styles: ["@charset \"UTF-8\";.kbq-group{display:flex;flex-direction:row}.kbq-group_justified>.kbq-group-item{width:100%}.kbq-group .kbq-group-item+.kbq-group-item{margin-inline-start:calc(-1 * var(--kbq-size-border-width))}.kbq-group>.kbq-group-item:first-child:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.kbq-group>.kbq-group-item:last-child:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.kbq-group>.kbq-group-item:not(:first-child):not(:last-child){border-radius:0}.kbq-group>.kbq-group-item:first-child:not(:last-child) .kbq-form-field__container{border-start-end-radius:0;border-end-end-radius:0}.kbq-group>.kbq-group-item:last-child:not(:first-child) .kbq-form-field__container{border-start-start-radius:0;border-end-start-radius:0}.kbq-group>.kbq-group-item:not(:first-child):not(:last-child) .kbq-form-field__container{border-radius:0}.kbq-vertical-group{display:flex;flex-direction:column}.kbq-vertical-group>.kbq-group-item:first-child:not(:last-child){border-end-start-radius:0;border-end-end-radius:0;border-start-end-radius:var(--kbq-size-border-radius)}@supports (corner-shape: squircle){.kbq-vertical-group>.kbq-group-item:first-child:not(:last-child){corner-shape:squircle;border-start-end-radius:clamp(var(--kbq-size-border-radius) * 1.85,var(--kbq-size-border-radius) * 2.3 - 3.6px,var(--kbq-size-border-radius) * 2)}}.kbq-vertical-group>.kbq-group-item:last-child:not(:first-child){border-start-start-radius:0;border-start-end-radius:0;border-end-start-radius:var(--kbq-size-border-radius)}@supports (corner-shape: squircle){.kbq-vertical-group>.kbq-group-item:last-child:not(:first-child){corner-shape:squircle;border-end-start-radius:clamp(var(--kbq-size-border-radius) * 1.85,var(--kbq-size-border-radius) * 2.3 - 3.6px,var(--kbq-size-border-radius) * 2)}}.kbq-vertical-group>.kbq-group-item:not(:first-child):not(:last-child){border-radius:0}.kbq-vertical-group .kbq-group-item+.kbq-group-item{margin-top:calc(-1 * var(--kbq-size-border-width))}.kbq-vertical-group>.kbq-group-item:first-child:not(:last-child) .kbq-form-field__container{border-end-start-radius:0;border-end-end-radius:0}.kbq-vertical-group>.kbq-group-item:last-child:not(:first-child) .kbq-form-field__container{border-start-start-radius:0;border-start-end-radius:0}.kbq-vertical-group>.kbq-group-item:not(:first-child):not(:last-child) .kbq-form-field__container{border-radius:0}.kbq-truncate-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-tree-option{-webkit-user-select:none;user-select:none}.kbq-tree-option:not(.kbq-disabled):hover .kbq-action-container,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-action-container,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-action-container{display:flex}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option:not(.kbq-disabled).kbq-focused .kbq-action-container{display:flex}.kbq-tree-option{position:relative;box-sizing:border-box;display:flex;align-items:center;min-height:32px;overflow-wrap:break-word;border-width:var(--kbq-tree-size-container-focus-outline-width);border-style:solid;border-color:transparent;border-radius:var(--kbq-tree-option-border-radius)}@supports (corner-shape: squircle){.kbq-tree-option{corner-shape:squircle;border-radius:clamp(var(--kbq-tree-option-border-radius) * 1.85,var(--kbq-tree-option-border-radius) * 2.3 - 3.6px,var(--kbq-tree-option-border-radius) * 2)}}.kbq-tree-option{padding-top:calc(var(--kbq-tree-size-container-padding-vertical) - var(--kbq-tree-size-container-focus-outline-width));padding-right:calc(var(--kbq-tree-size-container-padding-right) - var(--kbq-tree-size-container-focus-outline-width));padding-bottom:calc(var(--kbq-tree-size-container-padding-vertical) - var(--kbq-tree-size-container-focus-outline-width));gap:var(--kbq-tree-size-container-content-gap-horizontal)}.kbq-tree-option .kbq-option-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-tree-option .kbq-option-text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;overflow:hidden}.kbq-tree-option .kbq-option-text:empty{display:none}.kbq-tree-option .kbq-option-text{display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-tree-option:has(.kbq-option-caption)>[kbq-tree-node-toggle],.kbq-tree-option:has(.kbq-option-caption)>[kbqTreeNodeToggle],.kbq-tree-option:has(.kbq-option-caption)>.kbq-tree-node-toggle,.kbq-tree-option:has(.kbq-option-caption)>.kbq-pseudo-checkbox,.kbq-tree-option:has(.kbq-option-caption)>kbq-checkbox,.kbq-tree-option:has(.kbq-option-caption)>[kbq-icon],.kbq-tree-option:has(.kbq-option-caption)>kbq-progress-spinner{align-self:flex-start;margin-top:var(--kbq-size-3xs)}.kbq-tree-option:has(.kbq-option-caption)>.kbq-tree-node-toggle{height:var(--kbq-typography-text-normal-line-height);margin-top:0}.kbq-tree-option:focus{outline:none}.kbq-tree-option:not(.kbq-disabled){cursor:pointer}.kbq-tree-option:is(.kbq-checked,.kbq-selected,.kbq-focused):has(+:is(.kbq-checked,.kbq-selected,.kbq-focused)){border-bottom-left-radius:0;border-bottom-right-radius:0}.kbq-tree-option:is(.kbq-checked,.kbq-selected,.kbq-focused)+:is(.kbq-checked,.kbq-selected,.kbq-focused){border-top-left-radius:0;border-top-right-radius:0}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "component", type: KbqPseudoCheckbox, selector: "kbq-pseudo-checkbox", inputs: ["big", "state", "disabled"] }, { kind: "component", type: KbqActionContainer, selector: "kbq-action-container", exportAs: ["kbqActionContainer"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1138
1730
|
}
|
|
1139
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1731
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeOption, decorators: [{
|
|
1140
1732
|
type: Component,
|
|
1141
1733
|
args: [{ selector: 'kbq-tree-option', imports: [
|
|
1142
1734
|
KbqPseudoCheckbox,
|
|
@@ -1147,34 +1739,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
1147
1739
|
{ provide: KBQ_OPTION_ACTION_PARENT, useExisting: KbqTreeOption }
|
|
1148
1740
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
1149
1741
|
class: 'kbq-tree-option',
|
|
1742
|
+
// The "select all" row is a treeitem too: `role="checkbox"` would be an invalid child of
|
|
1743
|
+
// `role="tree"`, and `aria-checked` already carries its state.
|
|
1744
|
+
role: 'treeitem',
|
|
1150
1745
|
'[class.kbq-tree-option_multiple]': 'tree.multiple',
|
|
1151
1746
|
'[class.kbq-selected]': 'selected',
|
|
1152
1747
|
'[class.kbq-focused]': 'hasFocus',
|
|
1153
|
-
'[class.kbq-disabled]': '
|
|
1748
|
+
'[class.kbq-disabled]': 'checkedDisabled',
|
|
1154
1749
|
'[class.kbq-action-button-focused]': 'actionButton()?.active',
|
|
1155
1750
|
'[attr.id]': 'id',
|
|
1156
1751
|
'[attr.tabindex]': '-1',
|
|
1157
|
-
'[attr.disabled]': '
|
|
1752
|
+
'[attr.aria-disabled]': 'checkedDisabled || null',
|
|
1753
|
+
'[attr.aria-expanded]': 'ariaExpanded',
|
|
1754
|
+
// `aria-level` comes from `KbqTreeNode`: a second binding here would read `level` twice.
|
|
1755
|
+
'[attr.aria-checked]': 'ariaChecked',
|
|
1756
|
+
'[attr.aria-selected]': 'ariaSelected',
|
|
1158
1757
|
'(focusin)': 'focus()',
|
|
1159
|
-
'(mouseenter)': 'onMouseenter()',
|
|
1160
1758
|
'(blur)': 'blur()',
|
|
1161
1759
|
'(click)': 'selectViaInteraction($event)',
|
|
1162
1760
|
'(keydown)': 'onKeydown($event)'
|
|
1163
|
-
}, exportAs: 'kbqTreeOption', template: "<ng-content select=\"kbq-tree-node-toggle, [kbq-tree-node-toggle], [kbqTreeNodeToggle]\" />\n\n@if (externalPseudoCheckbox) {\n <ng-content select=\"kbq-pseudo-checkbox\" />\n} @else if (showCheckbox) {\n <kbq-pseudo-checkbox [disabled]=\"disabled\" [state]=\"checkboxState\" />\n}\n\n<ng-content select=\"kbq-checkbox\" />\n\n<ng-content select=\"[kbq-icon]\" />\n\n<ng-content select=\"kbq-progress-spinner\" />\n\n<span #kbqTitleContainer class=\"kbq-option-text\">\n <ng-content />\n</span>\n\n@if (actionButton()) {\n <kbq-action-container>\n <ng-content select=\"kbq-option-action\" />\n </kbq-action-container>\n}\n", styles: ["@
|
|
1164
|
-
}], ctorParameters: () => [], propDecorators: {
|
|
1165
|
-
type: ViewChild,
|
|
1166
|
-
args: ['kbqTitleContainer']
|
|
1167
|
-
}], toggleElementDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqTreeNodeToggleDirective), { isSignal: true }] }], toggleElementComponent: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqTreeNodeToggleComponent), { isSignal: true }] }], pseudoCheckbox: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqPseudoCheckbox), { isSignal: true }] }], actionButton: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqOptionActionComponent), { isSignal: true }] }], tooltipTrigger: [{
|
|
1168
|
-
type: ContentChild,
|
|
1169
|
-
args: [KbqTooltipTrigger]
|
|
1170
|
-
}], dropdownTrigger: [{
|
|
1171
|
-
type: ContentChild,
|
|
1172
|
-
args: [KbqDropdownTrigger]
|
|
1173
|
-
}], checkboxThirdState: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkboxThirdState", required: false }] }], disabled: [{
|
|
1174
|
-
type: Input
|
|
1175
|
-
}], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selectAllRow: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllRow", required: false }] }], showCheckbox: [{
|
|
1176
|
-
type: Input
|
|
1177
|
-
}], onSelectionChange: [{ type: i0.Output, args: ["onSelectionChange"] }] } });
|
|
1761
|
+
}, exportAs: 'kbqTreeOption', template: "<ng-content select=\"kbq-tree-node-toggle, [kbq-tree-node-toggle], [kbqTreeNodeToggle]\" />\n\n@if (externalPseudoCheckbox) {\n <ng-content select=\"kbq-pseudo-checkbox\" />\n} @else if (showCheckbox) {\n <kbq-pseudo-checkbox [disabled]=\"disabled\" [state]=\"checkboxState\" />\n}\n\n<ng-content select=\"kbq-checkbox\" />\n\n<ng-content select=\"[kbq-icon]\" />\n\n<ng-content select=\"kbq-progress-spinner\" />\n\n<span #kbqTitleContainer class=\"kbq-option-text\">\n <ng-content />\n</span>\n\n@if (actionButton()) {\n <kbq-action-container>\n <ng-content select=\"kbq-option-action\" />\n </kbq-action-container>\n}\n", styles: ["@charset \"UTF-8\";.kbq-group{display:flex;flex-direction:row}.kbq-group_justified>.kbq-group-item{width:100%}.kbq-group .kbq-group-item+.kbq-group-item{margin-inline-start:calc(-1 * var(--kbq-size-border-width))}.kbq-group>.kbq-group-item:first-child:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.kbq-group>.kbq-group-item:last-child:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.kbq-group>.kbq-group-item:not(:first-child):not(:last-child){border-radius:0}.kbq-group>.kbq-group-item:first-child:not(:last-child) .kbq-form-field__container{border-start-end-radius:0;border-end-end-radius:0}.kbq-group>.kbq-group-item:last-child:not(:first-child) .kbq-form-field__container{border-start-start-radius:0;border-end-start-radius:0}.kbq-group>.kbq-group-item:not(:first-child):not(:last-child) .kbq-form-field__container{border-radius:0}.kbq-vertical-group{display:flex;flex-direction:column}.kbq-vertical-group>.kbq-group-item:first-child:not(:last-child){border-end-start-radius:0;border-end-end-radius:0;border-start-end-radius:var(--kbq-size-border-radius)}@supports (corner-shape: squircle){.kbq-vertical-group>.kbq-group-item:first-child:not(:last-child){corner-shape:squircle;border-start-end-radius:clamp(var(--kbq-size-border-radius) * 1.85,var(--kbq-size-border-radius) * 2.3 - 3.6px,var(--kbq-size-border-radius) * 2)}}.kbq-vertical-group>.kbq-group-item:last-child:not(:first-child){border-start-start-radius:0;border-start-end-radius:0;border-end-start-radius:var(--kbq-size-border-radius)}@supports (corner-shape: squircle){.kbq-vertical-group>.kbq-group-item:last-child:not(:first-child){corner-shape:squircle;border-end-start-radius:clamp(var(--kbq-size-border-radius) * 1.85,var(--kbq-size-border-radius) * 2.3 - 3.6px,var(--kbq-size-border-radius) * 2)}}.kbq-vertical-group>.kbq-group-item:not(:first-child):not(:last-child){border-radius:0}.kbq-vertical-group .kbq-group-item+.kbq-group-item{margin-top:calc(-1 * var(--kbq-size-border-width))}.kbq-vertical-group>.kbq-group-item:first-child:not(:last-child) .kbq-form-field__container{border-end-start-radius:0;border-end-end-radius:0}.kbq-vertical-group>.kbq-group-item:last-child:not(:first-child) .kbq-form-field__container{border-start-start-radius:0;border-start-end-radius:0}.kbq-vertical-group>.kbq-group-item:not(:first-child):not(:last-child) .kbq-form-field__container{border-radius:0}.kbq-truncate-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-tree-option{-webkit-user-select:none;user-select:none}.kbq-tree-option:not(.kbq-disabled):hover .kbq-action-container,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-action-container,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-action-container{display:flex}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option:not(.kbq-disabled).kbq-focused .kbq-action-container{display:flex}.kbq-tree-option{position:relative;box-sizing:border-box;display:flex;align-items:center;min-height:32px;overflow-wrap:break-word;border-width:var(--kbq-tree-size-container-focus-outline-width);border-style:solid;border-color:transparent;border-radius:var(--kbq-tree-option-border-radius)}@supports (corner-shape: squircle){.kbq-tree-option{corner-shape:squircle;border-radius:clamp(var(--kbq-tree-option-border-radius) * 1.85,var(--kbq-tree-option-border-radius) * 2.3 - 3.6px,var(--kbq-tree-option-border-radius) * 2)}}.kbq-tree-option{padding-top:calc(var(--kbq-tree-size-container-padding-vertical) - var(--kbq-tree-size-container-focus-outline-width));padding-right:calc(var(--kbq-tree-size-container-padding-right) - var(--kbq-tree-size-container-focus-outline-width));padding-bottom:calc(var(--kbq-tree-size-container-padding-vertical) - var(--kbq-tree-size-container-focus-outline-width));gap:var(--kbq-tree-size-container-content-gap-horizontal)}.kbq-tree-option .kbq-option-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-tree-option .kbq-option-text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;overflow:hidden}.kbq-tree-option .kbq-option-text:empty{display:none}.kbq-tree-option .kbq-option-text{display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-tree-option:has(.kbq-option-caption)>[kbq-tree-node-toggle],.kbq-tree-option:has(.kbq-option-caption)>[kbqTreeNodeToggle],.kbq-tree-option:has(.kbq-option-caption)>.kbq-tree-node-toggle,.kbq-tree-option:has(.kbq-option-caption)>.kbq-pseudo-checkbox,.kbq-tree-option:has(.kbq-option-caption)>kbq-checkbox,.kbq-tree-option:has(.kbq-option-caption)>[kbq-icon],.kbq-tree-option:has(.kbq-option-caption)>kbq-progress-spinner{align-self:flex-start;margin-top:var(--kbq-size-3xs)}.kbq-tree-option:has(.kbq-option-caption)>.kbq-tree-node-toggle{height:var(--kbq-typography-text-normal-line-height);margin-top:0}.kbq-tree-option:focus{outline:none}.kbq-tree-option:not(.kbq-disabled){cursor:pointer}.kbq-tree-option:is(.kbq-checked,.kbq-selected,.kbq-focused):has(+:is(.kbq-checked,.kbq-selected,.kbq-focused)){border-bottom-left-radius:0;border-bottom-right-radius:0}.kbq-tree-option:is(.kbq-checked,.kbq-selected,.kbq-focused)+:is(.kbq-checked,.kbq-selected,.kbq-focused){border-top-left-radius:0;border-top-right-radius:0}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"] }]
|
|
1762
|
+
}], ctorParameters: () => [], propDecorators: { titleContainer: [{ type: i0.ViewChild, args: ['kbqTitleContainer', { isSignal: true }] }], toggleElementDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqTreeNodeToggleDirective), { isSignal: true }] }], toggleElementComponent: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqTreeNodeToggleComponent), { isSignal: true }] }], pseudoCheckbox: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqPseudoCheckbox), { isSignal: true }] }], actionButton: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqOptionActionComponent), { isSignal: true }] }], tooltipTriggerQuery: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqTooltipTrigger), { isSignal: true }] }], dropdownTriggerQuery: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqDropdownTrigger), { isSignal: true }] }], checkboxThirdState: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkboxThirdState", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selectAllRow: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllRow", required: false }] }], showCheckboxInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCheckbox", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], onSelectionChange: [{ type: i0.Output, args: ["onSelectionChange"] }] } });
|
|
1178
1763
|
|
|
1179
1764
|
/** Regex used to split a string on its CSS units. */
|
|
1180
1765
|
const cssUnitPattern = /([A-Za-z%]+)$/;
|
|
@@ -1185,49 +1770,65 @@ class KbqTreeNodePadding {
|
|
|
1185
1770
|
set level(value) {
|
|
1186
1771
|
this.setLevelInput(value);
|
|
1187
1772
|
}
|
|
1188
|
-
// TODO: Skipped for migration because:
|
|
1189
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
1190
|
-
get indent() {
|
|
1191
|
-
return this._indent;
|
|
1192
|
-
}
|
|
1193
|
-
set indent(indent) {
|
|
1194
|
-
this.setIndentInput(indent);
|
|
1195
|
-
}
|
|
1196
1773
|
get leftPadding() {
|
|
1197
|
-
return (this.withIcon ? 0 : this.iconWidth) + this.
|
|
1774
|
+
return (this.withIcon ? 0 : this.iconWidth) + this.parsedIndent().value;
|
|
1198
1775
|
}
|
|
1199
1776
|
get leftPaddingForFirstLevel() {
|
|
1200
1777
|
const border = 2;
|
|
1201
|
-
return (this.withIcon ? 0 : this.iconWidth) + this.
|
|
1778
|
+
return (this.withIcon ? 0 : this.iconWidth) + this.parsedIndent().value - border;
|
|
1779
|
+
}
|
|
1780
|
+
/** CSS units used for the indentation value. */
|
|
1781
|
+
get indentUnits() {
|
|
1782
|
+
return this.parsedIndent().units;
|
|
1202
1783
|
}
|
|
1203
1784
|
constructor() {
|
|
1204
1785
|
this.treeNode = inject(KbqTreeNode);
|
|
1205
1786
|
this.tree = inject(KbqTreeBase);
|
|
1206
1787
|
this.renderer = inject(Renderer2);
|
|
1207
1788
|
this.element = inject(ElementRef);
|
|
1208
|
-
|
|
1789
|
+
// Optional so the directive also works on a bare `kbq-tree-node`, which has no option around it.
|
|
1790
|
+
this.option = inject(KbqTreeOption, { optional: true });
|
|
1209
1791
|
this.dir = inject(Directionality, { optional: true });
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
this.
|
|
1792
|
+
/** Indentation added per nesting level. Accepts a bare number (px) or a value with CSS units. */
|
|
1793
|
+
this.indent = input(12, { ...(ngDevMode ? { debugName: "indent" } : /* istanbul ignore next */ {}), alias: 'kbqTreeNodePaddingIndent' });
|
|
1794
|
+
this.parsedIndent = computed(() => {
|
|
1795
|
+
const indent = this.indent();
|
|
1796
|
+
if (typeof indent !== 'string') {
|
|
1797
|
+
return { value: coerceNumberProperty(indent), units: 'px' };
|
|
1798
|
+
}
|
|
1799
|
+
const [value, units] = indent.split(cssUnitPattern);
|
|
1800
|
+
return { value: coerceNumberProperty(value), units: units || 'px' };
|
|
1801
|
+
}, ...(ngDevMode ? [{ debugName: "parsedIndent" }] : /* istanbul ignore next */ []));
|
|
1802
|
+
/**
|
|
1803
|
+
* Horizontal room a toggle takes up in a row: its own 16px box plus the option's 8px `gap`. A node
|
|
1804
|
+
* without a toggle reserves the same amount so its content lines up with a sibling that has one —
|
|
1805
|
+
* which is why widening the toggle itself pushes every branch row out of line.
|
|
1806
|
+
*/
|
|
1213
1807
|
this.iconWidth = 24;
|
|
1214
1808
|
this.dir?.change?.pipe(takeUntilDestroyed()).subscribe(() => this.setPadding());
|
|
1809
|
+
// The node the padding was computed from is gone once its view is reused, and the replacement
|
|
1810
|
+
// can sit at a different level.
|
|
1811
|
+
this.treeNode.refreshed.pipe(takeUntilDestroyed()).subscribe(() => this.setPadding());
|
|
1812
|
+
effect(() => {
|
|
1813
|
+
this.parsedIndent();
|
|
1814
|
+
this.setPadding();
|
|
1815
|
+
});
|
|
1215
1816
|
}
|
|
1216
1817
|
ngAfterViewInit() {
|
|
1217
|
-
this.withIcon = this.option
|
|
1818
|
+
this.withIcon = this.option?.isToggleInDefaultPlace ?? false;
|
|
1218
1819
|
this.setPadding();
|
|
1219
1820
|
}
|
|
1220
1821
|
paddingIndent() {
|
|
1221
1822
|
const treeControl = this.tree.treeControl;
|
|
1222
1823
|
const nodeLevel = this.treeNode.data && treeControl.getLevel ? treeControl.getLevel(this.treeNode.data) : 0;
|
|
1223
1824
|
const level = this.level || nodeLevel;
|
|
1224
|
-
|
|
1825
|
+
const { value, units } = this.parsedIndent();
|
|
1826
|
+
return level > 0 ? `${level * value + this.leftPadding}${units}` : `${this.leftPaddingForFirstLevel}${units}`;
|
|
1225
1827
|
}
|
|
1226
1828
|
/**
|
|
1227
1829
|
* This has been extracted to a util because of TS 4 and VE.
|
|
1228
1830
|
* View Engine doesn't support property rename inheritance.
|
|
1229
1831
|
* TS 4.0 doesn't allow properties to override accessors or vice-versa.
|
|
1230
|
-
* @docs-private
|
|
1231
1832
|
*/
|
|
1232
1833
|
setLevelInput(value) {
|
|
1233
1834
|
// Set to null as the fallback value so that _setPadding can fall back to the node level if the
|
|
@@ -1236,58 +1837,40 @@ class KbqTreeNodePadding {
|
|
|
1236
1837
|
this._level = coerceNumberProperty(value, null);
|
|
1237
1838
|
this.setPadding();
|
|
1238
1839
|
}
|
|
1239
|
-
/**
|
|
1240
|
-
* This has been extracted to a util because of TS 4 and VE.
|
|
1241
|
-
* View Engine doesn't support property rename inheritance.
|
|
1242
|
-
* TS 4.0 doesn't allow properties to override accessors or vice-versa.
|
|
1243
|
-
* @docs-private
|
|
1244
|
-
*/
|
|
1245
|
-
setIndentInput(indent) {
|
|
1246
|
-
let value = indent;
|
|
1247
|
-
let units = 'px';
|
|
1248
|
-
if (typeof indent === 'string') {
|
|
1249
|
-
const parts = indent.split(cssUnitPattern);
|
|
1250
|
-
value = parts[0];
|
|
1251
|
-
units = parts[1] || units;
|
|
1252
|
-
}
|
|
1253
|
-
this.indentUnits = units;
|
|
1254
|
-
this._indent = coerceNumberProperty(value);
|
|
1255
|
-
this.setPadding();
|
|
1256
|
-
}
|
|
1257
1840
|
setPadding() {
|
|
1258
1841
|
const padding = this.paddingIndent();
|
|
1259
1842
|
const paddingProp = this.dir?.value === 'rtl' ? 'paddingRight' : 'paddingLeft';
|
|
1260
1843
|
this.renderer.setStyle(this.element.nativeElement, paddingProp, padding);
|
|
1261
1844
|
}
|
|
1262
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1263
|
-
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
1845
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodePadding, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1846
|
+
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: KbqTreeNodePadding, isStandalone: true, selector: "[kbqTreeNodePadding]", inputs: { indent: { classPropertyName: "indent", publicName: "kbqTreeNodePaddingIndent", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["kbqTreeNodePadding"], ngImport: i0 }); }
|
|
1264
1847
|
}
|
|
1265
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1848
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeNodePadding, decorators: [{
|
|
1266
1849
|
type: Directive,
|
|
1267
1850
|
args: [{
|
|
1268
1851
|
selector: '[kbqTreeNodePadding]',
|
|
1269
1852
|
exportAs: 'kbqTreeNodePadding'
|
|
1270
1853
|
}]
|
|
1271
|
-
}], ctorParameters: () => [], propDecorators: { indent: [{
|
|
1272
|
-
type: Input,
|
|
1273
|
-
args: ['kbqTreeNodePaddingIndent']
|
|
1274
|
-
}] } });
|
|
1854
|
+
}], ctorParameters: () => [], propDecorators: { indent: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqTreeNodePaddingIndent", required: false }] }] } });
|
|
1275
1855
|
|
|
1276
1856
|
class KbqTree extends KbqTreeBase {
|
|
1277
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1278
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
1857
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTree, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1858
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: KbqTree, isStandalone: true, selector: "kbq-tree", host: { attributes: { "role": "tree" }, classAttribute: "kbq-tree" }, providers: [{ provide: KbqTreeBase, useExisting: KbqTree }], exportAs: ["kbqTree"], usesInheritance: true, hostDirectives: [{ directive: i1.KbqStateSaving, inputs: ["useStateSaving", "useStateSaving", "stateSavingKey", "stateSavingKey"] }], ngImport: i0, template: `
|
|
1279
1859
|
<ng-container kbqTreeNodeOutlet />
|
|
1280
|
-
`, isInline: true, styles: [".kbq-tree{display:block}.kbq-tree-selection:focus{outline:none}.kbq-tree-option{--kbq-option-background: var(--kbq-tree-default-container-background);background:var(--kbq-tree-default-container-background)}.kbq-tree-option .kbq-option-text{color:var(--kbq-tree-default-text-color)}.kbq-tree-option .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-default-action-button-color)}.kbq-tree-option .kbq-option-caption{color:var(--kbq-tree-default-caption-color)}.kbq-tree-option:not(.kbq-disabled):hover,.kbq-tree-option:not(.kbq-disabled).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused{--kbq-option-background: var(--kbq-tree-states-hover-container-background);background:var(--kbq-tree-states-hover-container-background)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-text{color:var(--kbq-tree-states-hover-text-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-caption{color:var(--kbq-tree-states-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled):active,.kbq-tree-option:not(.kbq-disabled).kbq-active{--kbq-option-background: var(--kbq-tree-states-active-container-background);background:var(--kbq-tree-states-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected{--kbq-option-background: var(--kbq-tree-states-selected-container-background);background:var(--kbq-tree-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-text{color:var(--kbq-tree-states-selected-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-caption{color:var(--kbq-tree-states-selected-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-states-selected-hover-container-background);background:var(--kbq-tree-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-text{color:var(--kbq-tree-states-selected-hover-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-caption{color:var(--kbq-tree-states-selected-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);background:var(--kbq-tree-states-selected-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected),.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected{--kbq-option-background: var(--kbq-tree-multiple-states-selected-container-background);background:var(--kbq-tree-multiple-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):hover,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-multiple-states-selected-hover-container-background);background:var(--kbq-tree-multiple-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):active,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);background:var(--kbq-tree-multiple-states-selected-active-container-background)}.kbq-tree-option.kbq-disabled{--kbq-option-background: var(--kbq-tree-states-disabled-container-background);background:var(--kbq-tree-states-disabled-container-background)}.kbq-tree-option.kbq-disabled .kbq-option-text{color:var(--kbq-tree-states-disabled-text-color)}.kbq-tree-option.kbq-disabled .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-disabled-action-button-color)}.kbq-tree-option.kbq-disabled .kbq-option-caption{color:var(--kbq-tree-states-disabled-caption-color)}.kbq-tree-option.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-tree-node-toggle .kbq-icon){color:var(--kbq-states-icon-disabled)}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option.kbq-focused:not(.kbq-action-button-focused){border-color:var(--kbq-tree-states-focused-focus-outline-color)}.kbq-tree-option{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-option-caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-content-gap-vertical: 0px;--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "directive", type: KbqTreeNodeOutlet, selector: "[kbqTreeNodeOutlet]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1860
|
+
`, isInline: true, styles: [".kbq-tree{display:block}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "directive", type: KbqTreeNodeOutlet, selector: "[kbqTreeNodeOutlet]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1281
1861
|
}
|
|
1282
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1862
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTree, decorators: [{
|
|
1283
1863
|
type: Component,
|
|
1284
1864
|
args: [{ selector: 'kbq-tree', imports: [
|
|
1285
1865
|
KbqTreeNodeOutlet
|
|
1286
1866
|
], template: `
|
|
1287
1867
|
<ng-container kbqTreeNodeOutlet />
|
|
1288
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
1289
|
-
class: 'kbq-tree'
|
|
1290
|
-
}, exportAs: 'kbqTree', styles: [".kbq-tree{display:block}.kbq-tree-selection:focus{outline:none}.kbq-tree-option{--kbq-option-background: var(--kbq-tree-default-container-background);background:var(--kbq-tree-default-container-background)}.kbq-tree-option .kbq-option-text{color:var(--kbq-tree-default-text-color)}.kbq-tree-option .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-default-action-button-color)}.kbq-tree-option .kbq-option-caption{color:var(--kbq-tree-default-caption-color)}.kbq-tree-option:not(.kbq-disabled):hover,.kbq-tree-option:not(.kbq-disabled).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused{--kbq-option-background: var(--kbq-tree-states-hover-container-background);background:var(--kbq-tree-states-hover-container-background)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-text{color:var(--kbq-tree-states-hover-text-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-caption{color:var(--kbq-tree-states-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled):active,.kbq-tree-option:not(.kbq-disabled).kbq-active{--kbq-option-background: var(--kbq-tree-states-active-container-background);background:var(--kbq-tree-states-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected{--kbq-option-background: var(--kbq-tree-states-selected-container-background);background:var(--kbq-tree-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-text{color:var(--kbq-tree-states-selected-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-caption{color:var(--kbq-tree-states-selected-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-states-selected-hover-container-background);background:var(--kbq-tree-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-text{color:var(--kbq-tree-states-selected-hover-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-caption{color:var(--kbq-tree-states-selected-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);background:var(--kbq-tree-states-selected-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected),.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected{--kbq-option-background: var(--kbq-tree-multiple-states-selected-container-background);background:var(--kbq-tree-multiple-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):hover,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-multiple-states-selected-hover-container-background);background:var(--kbq-tree-multiple-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):active,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);background:var(--kbq-tree-multiple-states-selected-active-container-background)}.kbq-tree-option.kbq-disabled{--kbq-option-background: var(--kbq-tree-states-disabled-container-background);background:var(--kbq-tree-states-disabled-container-background)}.kbq-tree-option.kbq-disabled .kbq-option-text{color:var(--kbq-tree-states-disabled-text-color)}.kbq-tree-option.kbq-disabled .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-disabled-action-button-color)}.kbq-tree-option.kbq-disabled .kbq-option-caption{color:var(--kbq-tree-states-disabled-caption-color)}.kbq-tree-option.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-tree-node-toggle .kbq-icon){color:var(--kbq-states-icon-disabled)}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option.kbq-focused:not(.kbq-action-button-focused){border-color:var(--kbq-tree-states-focused-focus-outline-color)}.kbq-tree-option{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-option-caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-content-gap-vertical: 0px;--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"] }]
|
|
1868
|
+
`, providers: [{ provide: KbqTreeBase, useExisting: KbqTree }], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
1869
|
+
class: 'kbq-tree',
|
|
1870
|
+
role: 'tree'
|
|
1871
|
+
}, hostDirectives: [
|
|
1872
|
+
{ directive: KbqStateSaving, inputs: ['useStateSaving', 'stateSavingKey'] }
|
|
1873
|
+
], exportAs: 'kbqTree', styles: [".kbq-tree{display:block}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"] }]
|
|
1291
1874
|
}] });
|
|
1292
1875
|
|
|
1293
1876
|
const KBQ_SELECTION_TREE_VALUE_ACCESSOR = {
|
|
@@ -1295,6 +1878,8 @@ const KBQ_SELECTION_TREE_VALUE_ACCESSOR = {
|
|
|
1295
1878
|
useExisting: forwardRef(() => KbqTreeSelection),
|
|
1296
1879
|
multi: true
|
|
1297
1880
|
};
|
|
1881
|
+
/** How long the key manager collects keystrokes before matching them against the option labels. */
|
|
1882
|
+
const typeAheadDebounce = 200;
|
|
1298
1883
|
class KbqTreeSelectAllEvent {
|
|
1299
1884
|
constructor(source, options) {
|
|
1300
1885
|
this.source = source;
|
|
@@ -1330,30 +1915,95 @@ class KbqTreeSelectionChange {
|
|
|
1330
1915
|
}
|
|
1331
1916
|
}
|
|
1332
1917
|
class KbqTreeSelection extends KbqTreeBase {
|
|
1333
|
-
|
|
1334
|
-
|
|
1918
|
+
/**
|
|
1919
|
+
* Accessible name written to the host.
|
|
1920
|
+
*
|
|
1921
|
+
* The host is the very element the consumer writes, and a host binding runs after their own
|
|
1922
|
+
* `[attr.aria-label]` binding on that element — an unset input reporting `null` would erase the name
|
|
1923
|
+
* they just set, because `[attr.]` never reaches the aliased input. Whatever is already on the
|
|
1924
|
+
* element therefore stands in for an unset input.
|
|
1925
|
+
*/
|
|
1926
|
+
get resolvedAriaLabel() {
|
|
1927
|
+
return this.ariaLabel() || this.elementRef.nativeElement.getAttribute('aria-label');
|
|
1928
|
+
}
|
|
1929
|
+
/** Labelling element of the host. Falls back to the element's own attribute, see `resolvedAriaLabel`. */
|
|
1930
|
+
get resolvedAriaLabelledby() {
|
|
1931
|
+
return this.ariaLabelledby() || this.elementRef.nativeElement.getAttribute('aria-labelledby');
|
|
1932
|
+
}
|
|
1933
|
+
get unorderedOptions() {
|
|
1934
|
+
return this.unorderedOptionsList();
|
|
1935
|
+
}
|
|
1936
|
+
/**
|
|
1937
|
+
* Whether clicking a node clears the rest of the selection. Defaults to `true`, and to `false` for
|
|
1938
|
+
* `multiple="checkbox"`.
|
|
1939
|
+
*
|
|
1940
|
+
* Assigning it — from a template binding or imperatively, as `KbqTreeSelect` does — replaces the
|
|
1941
|
+
* derived default, so a later {@link multiple} change leaves the value alone.
|
|
1942
|
+
*/
|
|
1335
1943
|
get autoSelect() {
|
|
1336
|
-
return this.
|
|
1944
|
+
return this.autoSelectState() ?? this.mode() !== MultipleMode.CHECKBOX;
|
|
1337
1945
|
}
|
|
1338
1946
|
set autoSelect(value) {
|
|
1339
|
-
this.
|
|
1947
|
+
this.autoSelectState.set(coerceBooleanProperty(value));
|
|
1340
1948
|
}
|
|
1949
|
+
/** Emits when an option of the tree takes focus. */
|
|
1341
1950
|
get optionFocusChanges() {
|
|
1342
|
-
return
|
|
1951
|
+
return this.optionFocusEvents.asObservable();
|
|
1343
1952
|
}
|
|
1953
|
+
/** Emits when an option of the tree loses focus. */
|
|
1344
1954
|
get optionBlurChanges() {
|
|
1345
|
-
return
|
|
1955
|
+
return this.optionBlurEvents.asObservable();
|
|
1346
1956
|
}
|
|
1957
|
+
/**
|
|
1958
|
+
* Selection mode of the tree.
|
|
1959
|
+
*
|
|
1960
|
+
* `checkbox` renders a checkbox in every node, `keyboard` selects without one. A bare `multiple` and
|
|
1961
|
+
* `true` both mean `checkbox`; `single`, `false` and an absent attribute mean single selection. The mode
|
|
1962
|
+
* can be changed at any time — narrowing it to single selection keeps the first selected node and
|
|
1963
|
+
* reports the shortened value through the `ControlValueAccessor`.
|
|
1964
|
+
*
|
|
1965
|
+
* A tree rendered inside a `kbq-tree-select` shares its `SelectionModel` with the select, so the
|
|
1966
|
+
* select decides how many nodes may be selected: switching this input between single and multiple
|
|
1967
|
+
* selection there throws. Switching between `checkbox` and `keyboard` only changes the presentation
|
|
1968
|
+
* and is allowed.
|
|
1969
|
+
*
|
|
1970
|
+
* The getter reports whether more than one node can be selected; read {@link multipleMode} for the mode
|
|
1971
|
+
* itself.
|
|
1972
|
+
*/
|
|
1347
1973
|
get multiple() {
|
|
1348
|
-
return !!this.
|
|
1974
|
+
return !!this.mode();
|
|
1349
1975
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1976
|
+
/** Resolved selection mode, or `null` when only one node can be selected. */
|
|
1977
|
+
get multipleMode() {
|
|
1978
|
+
return this.mode();
|
|
1979
|
+
}
|
|
1980
|
+
set multipleMode(value) {
|
|
1981
|
+
this.setMultipleMode(value);
|
|
1982
|
+
}
|
|
1983
|
+
/**
|
|
1984
|
+
* Whether the last selected node can be deselected.
|
|
1985
|
+
* Derived from the mode until assigned, like {@link autoSelect}.
|
|
1986
|
+
*/
|
|
1352
1987
|
get noUnselectLast() {
|
|
1353
|
-
return this.
|
|
1988
|
+
return this.noUnselectLastState() ?? this.mode() !== MultipleMode.CHECKBOX;
|
|
1354
1989
|
}
|
|
1355
1990
|
set noUnselectLast(value) {
|
|
1356
|
-
this.
|
|
1991
|
+
this.noUnselectLastState.set(coerceBooleanProperty(value));
|
|
1992
|
+
}
|
|
1993
|
+
/**
|
|
1994
|
+
* Whether typing printable characters moves the focus to the next option whose label starts with
|
|
1995
|
+
* them. On by default.
|
|
1996
|
+
*
|
|
1997
|
+
* Turn it off wherever the tree shares its keystrokes with a text field: an embedder such as
|
|
1998
|
+
* `KbqTreeSelect` routes everything the user types — the search query included — into this key
|
|
1999
|
+
* manager, and type-ahead would move the active option out from under the query.
|
|
2000
|
+
*/
|
|
2001
|
+
get typeAhead() {
|
|
2002
|
+
return this.typeAheadState();
|
|
2003
|
+
}
|
|
2004
|
+
// Written imperatively by `KbqTreeSelect`, like `autoSelect` and `noUnselectLast`.
|
|
2005
|
+
set typeAhead(value) {
|
|
2006
|
+
this.typeAheadState.set(value);
|
|
1357
2007
|
}
|
|
1358
2008
|
/**
|
|
1359
2009
|
* Whether to render the "select all" master checkbox above the nodes. Multiple selection only.
|
|
@@ -1361,11 +2011,10 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1361
2011
|
* Enabling it also makes Ctrl/Cmd + A a two-way toggle, so the shortcut and the checkbox never
|
|
1362
2012
|
* disagree (`selectAllToggle` is implied).
|
|
1363
2013
|
*/
|
|
1364
|
-
// Written imperatively by `KbqTreeSelect`, like `autoSelect` and `noUnselectLast`, so it cannot be a
|
|
1365
|
-
// signal input; the signal behind it is what keeps the template in step.
|
|
1366
2014
|
get selectAll() {
|
|
1367
2015
|
return this.selectAllEnabled();
|
|
1368
2016
|
}
|
|
2017
|
+
// Written imperatively by `KbqTreeSelect`, like `autoSelect` and `noUnselectLast`.
|
|
1369
2018
|
set selectAll(value) {
|
|
1370
2019
|
this.selectAllEnabled.set(value);
|
|
1371
2020
|
}
|
|
@@ -1384,6 +2033,10 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1384
2033
|
get selectAllState() {
|
|
1385
2034
|
return getSelectAllState(this.selectAllAdapter);
|
|
1386
2035
|
}
|
|
2036
|
+
/** Label of the "select all" row. Follows the active locale. */
|
|
2037
|
+
get selectAllText() {
|
|
2038
|
+
return this.localeConfiguration().selectAll;
|
|
2039
|
+
}
|
|
1387
2040
|
/**
|
|
1388
2041
|
* Data nodes "select all" acts on, and the ones its checkbox state is derived from.
|
|
1389
2042
|
*
|
|
@@ -1391,27 +2044,24 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1391
2044
|
* is looking at, and selecting them would contradict a master checkbox that can only report on what
|
|
1392
2045
|
* is on screen. Without a filter the whole data set qualifies, collapsed branches included.
|
|
1393
2046
|
*/
|
|
1394
|
-
// `any`, not `unknown`: `treeControl`/`selectionModel` are themselves `any`-typed data-node generics
|
|
1395
|
-
// pre-dating this feature (`KbqTreeBase<any>`, `SelectionModel<SelectionModelOption>`), so `unknown`
|
|
1396
|
-
// here would only relocate the unsafety into a cast at every call site, not remove it.
|
|
1397
2047
|
get selectAllTargets() {
|
|
1398
|
-
// `treeControl` is an
|
|
2048
|
+
// `treeControl` is an input, so it is still unset on the change-detection pass that sets it:
|
|
1399
2049
|
// a consumer reading `allOptionsSelected`/`selectAllState` off a template reference — which is
|
|
1400
2050
|
// exactly how the docs suggest swapping the trigger label — would otherwise get a TypeError
|
|
1401
2051
|
// before the tree is wired up. Nothing is selectable yet at that point, so an empty set is right.
|
|
1402
2052
|
if (!this.treeControl) {
|
|
1403
2053
|
return [];
|
|
1404
2054
|
}
|
|
1405
|
-
const nonSelectableDataNodes = this.renderedOptions
|
|
2055
|
+
const nonSelectableDataNodes = new Set(this.renderedOptions
|
|
1406
2056
|
.filter((option) => option.disabled || !option.selectable())
|
|
1407
|
-
.map((option) => option.data);
|
|
2057
|
+
.map((option) => option.data));
|
|
1408
2058
|
const candidates = this.treeControl.filterValue.value?.length
|
|
1409
2059
|
? this.renderedOptions.map((option) => option.data)
|
|
1410
2060
|
: (this.treeControl.dataNodes ?? []);
|
|
1411
|
-
// The `
|
|
2061
|
+
// The `has` check comes first on purpose: the "select all" row is itself a non-selectable
|
|
1412
2062
|
// rendered option with no `data`, and `isDisabled` belongs to the consumer — it must never be
|
|
1413
2063
|
// handed a node their data source has never seen.
|
|
1414
|
-
return candidates.filter((node) => !nonSelectableDataNodes.
|
|
2064
|
+
return candidates.filter((node) => !nonSelectableDataNodes.has(node) && !this.treeControl.isDisabled(node));
|
|
1415
2065
|
}
|
|
1416
2066
|
/** Adapter shared by the master checkbox and the Ctrl/Cmd + A handler, so the two cannot drift apart. */
|
|
1417
2067
|
get selectAllAdapter() {
|
|
@@ -1422,29 +2072,16 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1422
2072
|
setSelected: (node, selected) => selected ? this.selectionModel.select(node) : this.selectionModel.deselect(node)
|
|
1423
2073
|
};
|
|
1424
2074
|
}
|
|
1425
|
-
|
|
1426
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
2075
|
+
/** Whether the tree is disabled, bound with `[disabled]` or set by a form control. */
|
|
1427
2076
|
get disabled() {
|
|
1428
|
-
return this.
|
|
2077
|
+
return this.disabledState();
|
|
1429
2078
|
}
|
|
1430
|
-
|
|
1431
|
-
const value = coerceBooleanProperty(rawValue);
|
|
1432
|
-
if (this._disabled !== value) {
|
|
1433
|
-
this._disabled = value;
|
|
1434
|
-
this.markOptionsForCheck();
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
// TODO: Skipped for migration because:
|
|
1438
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
2079
|
+
/** Tab index of the tree, `-1` while it is disabled. */
|
|
1439
2080
|
get tabIndex() {
|
|
1440
|
-
return this.disabled ? -1 : this.
|
|
1441
|
-
}
|
|
1442
|
-
set tabIndex(value) {
|
|
1443
|
-
this._tabIndex = value;
|
|
1444
|
-
this.userTabIndex = value;
|
|
2081
|
+
return this.disabled ? -1 : this.tabIndexState();
|
|
1445
2082
|
}
|
|
1446
2083
|
get showCheckbox() {
|
|
1447
|
-
return this.
|
|
2084
|
+
return this.mode() === MultipleMode.CHECKBOX;
|
|
1448
2085
|
}
|
|
1449
2086
|
get isEmpty() {
|
|
1450
2087
|
return this.sortedNodes.length === 0;
|
|
@@ -1457,13 +2094,23 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1457
2094
|
get nodesCount() {
|
|
1458
2095
|
return this.sortedNodes.length;
|
|
1459
2096
|
}
|
|
2097
|
+
/**
|
|
2098
|
+
* Whether the tree is changing the selection model itself — to a value the form wrote, or onto the nodes of
|
|
2099
|
+
* reloaded data — rather than acting on the user. A host sharing the model, such as `KbqTreeSelect`, reports
|
|
2100
|
+
* no such change.
|
|
2101
|
+
*
|
|
2102
|
+
* @docs-private
|
|
2103
|
+
*/
|
|
2104
|
+
get syncingSelection() {
|
|
2105
|
+
return this.writingValue;
|
|
2106
|
+
}
|
|
1460
2107
|
constructor() {
|
|
1461
|
-
const multiple = inject(new HostAttributeToken('multiple'), { optional: true });
|
|
1462
2108
|
super();
|
|
1463
2109
|
this.elementRef = inject(ElementRef);
|
|
1464
2110
|
this.scheduler = inject(AsyncScheduler);
|
|
1465
2111
|
this.clipboard = inject(Clipboard, { optional: true });
|
|
1466
2112
|
this.platform = inject(Platform);
|
|
2113
|
+
this.injector = inject(Injector);
|
|
1467
2114
|
this.focusMonitor = inject(FocusMonitor);
|
|
1468
2115
|
/**
|
|
1469
2116
|
* Whether this tree-selection is rendered inside a select panel (enables option
|
|
@@ -1473,38 +2120,122 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1473
2120
|
*/
|
|
1474
2121
|
this.inSelect = !!inject(KBQ_FORM_FIELD, { optional: true, host: true });
|
|
1475
2122
|
this.renderedOptions = new QueryList();
|
|
2123
|
+
/**
|
|
2124
|
+
* Accessible name of the tree. Set it whenever the tree has no visible label of its own; a tree
|
|
2125
|
+
* embedded in a `kbq-tree-select` is labelled by the select instead.
|
|
2126
|
+
*/
|
|
2127
|
+
this.ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
2128
|
+
/** Id of the element that labels the tree, for when the label is rendered next to it. */
|
|
2129
|
+
this.ariaLabelledby = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabelledby" } : /* istanbul ignore next */ {}), alias: 'aria-labelledby' });
|
|
1476
2130
|
this.resetFocusedItemOnBlur = true;
|
|
1477
|
-
this.multipleMode = null;
|
|
1478
2131
|
this.userTabIndex = null;
|
|
1479
2132
|
// this parameter used when select has a search field
|
|
1480
2133
|
this.optionShouldHoldFocusOnBlur = false;
|
|
2134
|
+
/**
|
|
2135
|
+
* Whether the tree acts on keyboard input itself. Turned off by an embedding host that owns the
|
|
2136
|
+
* keyboard, such as `KbqTreeSelect`.
|
|
2137
|
+
*/
|
|
2138
|
+
this.ownsKeyboard = true;
|
|
1481
2139
|
/** Reference to the built-in "select all" row, rendered only while `selectAll` is on. */
|
|
1482
|
-
this.selectAllOption = viewChild(KbqTreeOption, ...(ngDevMode ? [{ debugName: "selectAllOption" }] : []));
|
|
2140
|
+
this.selectAllOption = viewChild(KbqTreeOption, ...(ngDevMode ? [{ debugName: "selectAllOption" }] : /* istanbul ignore next */ []));
|
|
2141
|
+
this.unorderedOptionsQuery = contentChildren(KbqTreeOption, ...(ngDevMode ? [{ debugName: "unorderedOptionsQuery" }] : /* istanbul ignore next */ []));
|
|
2142
|
+
this.unorderedOptionsList = kbqQueryListFrom(this.unorderedOptionsQuery);
|
|
1483
2143
|
this.navigationChange = output();
|
|
2144
|
+
/**
|
|
2145
|
+
* Emits when the selection changes. A stream rather than an `output()`: `KbqTreeSelect` pipes it with rxjs.
|
|
2146
|
+
*/
|
|
1484
2147
|
this.selectionChange = new EventEmitter();
|
|
1485
|
-
|
|
2148
|
+
/** @docs-private */
|
|
2149
|
+
this.selectionChangeOutput = outputFromObservable(this.selectionChange, { alias: 'selectionChange' });
|
|
2150
|
+
/** Emits after "select all" ran, with the options it could act on. */
|
|
2151
|
+
this.selectAllChange = output();
|
|
2152
|
+
/** @deprecated Use `selectAllChange` instead. Will be removed in 22.0.0. */
|
|
2153
|
+
this.onSelectAll = output({ alias: 'onSelectAll' });
|
|
2154
|
+
/**
|
|
2155
|
+
* Emits when the active option is copied with Ctrl/Cmd + C. Subscribing replaces the built-in
|
|
2156
|
+
* clipboard handler, so the event has to stay an `EventEmitter`: the decision is made by reading
|
|
2157
|
+
* `observed`, which `OutputEmitterRef` does not have. A template listener subscribes to it through
|
|
2158
|
+
* the output below.
|
|
2159
|
+
*/
|
|
2160
|
+
this.copyChange = new EventEmitter();
|
|
2161
|
+
/** @docs-private */
|
|
2162
|
+
this.copyChangeOutput = outputFromObservable(this.copyChange, { alias: 'copyChange' });
|
|
2163
|
+
/** @deprecated Use `copyChange` instead. Will be removed in 22.0.0. */
|
|
1486
2164
|
this.onCopy = new EventEmitter();
|
|
2165
|
+
/** @docs-private */
|
|
2166
|
+
this.onCopyOutput = outputFromObservable(this.onCopy, { alias: 'onCopy' });
|
|
1487
2167
|
this.sortedNodes = [];
|
|
1488
2168
|
this.lastSyncedDataNodes = null;
|
|
1489
|
-
|
|
1490
|
-
this.
|
|
2169
|
+
/** @docs-private */
|
|
2170
|
+
this.autoSelectInput = input(undefined, { ...(ngDevMode ? { debugName: "autoSelectInput" } : /* istanbul ignore next */ {}), alias: 'autoSelect',
|
|
2171
|
+
transform: booleanAttribute });
|
|
2172
|
+
/** `undefined` while the value is derived from the mode. Written by `KbqTreeSelect` as well. */
|
|
2173
|
+
this.autoSelectState = linkedSignal(() => this.autoSelectInput(), ...(ngDevMode ? [{ debugName: "autoSelectState" }] : /* istanbul ignore next */ []));
|
|
2174
|
+
// Options report here, so a subscriber also hears the rows rendered after it subscribed.
|
|
2175
|
+
this.optionFocusEvents = new Subject();
|
|
2176
|
+
this.optionBlurEvents = new Subject();
|
|
2177
|
+
/** @docs-private */
|
|
2178
|
+
this.multipleInput = input(undefined, { ...(ngDevMode ? { debugName: "multipleInput" } : /* istanbul ignore next */ {}), alias: 'multiple' });
|
|
2179
|
+
/**
|
|
2180
|
+
* Backing signal of {@link multipleMode}. A signal rather than a field because the mode is also written
|
|
2181
|
+
* from inside the component and by `KbqTreeSelect`: options read it through `multiple` and
|
|
2182
|
+
* `showCheckbox`, and only a signal read re-runs their `OnPush` views and host bindings.
|
|
2183
|
+
*/
|
|
2184
|
+
this.mode = signal(null, ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
2185
|
+
/** @docs-private */
|
|
2186
|
+
this.noUnselectLastInput = input(undefined, { ...(ngDevMode ? { debugName: "noUnselectLastInput" } : /* istanbul ignore next */ {}), alias: 'noUnselectLast',
|
|
2187
|
+
transform: booleanAttribute });
|
|
2188
|
+
/** `undefined` while the value is derived from the mode. Written by `KbqTreeSelect` as well. */
|
|
2189
|
+
this.noUnselectLastState = linkedSignal(() => this.noUnselectLastInput(), ...(ngDevMode ? [{ debugName: "noUnselectLastState" }] : /* istanbul ignore next */ []));
|
|
2190
|
+
/** @docs-private */
|
|
2191
|
+
this.typeAheadInput = input(true, { ...(ngDevMode ? { debugName: "typeAheadInput" } : /* istanbul ignore next */ {}), alias: 'typeAhead',
|
|
2192
|
+
transform: booleanAttribute });
|
|
2193
|
+
this.typeAheadState = linkedSignal(() => this.typeAheadInput(), ...(ngDevMode ? [{ debugName: "typeAheadState" }] : /* istanbul ignore next */ []));
|
|
1491
2194
|
/** When `true`, a repeated Ctrl/Cmd+A deselects all options. Off by default (Ctrl+A only selects). */
|
|
1492
|
-
this.selectAllToggle = input(false, ...(ngDevMode ?
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
this.
|
|
1497
|
-
this.
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
2195
|
+
this.selectAllToggle = input(false, { ...(ngDevMode ? { debugName: "selectAllToggle" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
2196
|
+
/** @docs-private */
|
|
2197
|
+
this.selectAllInput = input(false, { ...(ngDevMode ? { debugName: "selectAllInput" } : /* istanbul ignore next */ {}), alias: 'selectAll',
|
|
2198
|
+
transform: booleanAttribute });
|
|
2199
|
+
this.selectAllEnabled = linkedSignal(() => this.selectAllInput(), ...(ngDevMode ? [{ debugName: "selectAllEnabled" }] : /* istanbul ignore next */ []));
|
|
2200
|
+
this.localeConfiguration = inject(KbqLocaleOverridesDirective, { self: true }).read('select', KBQ_SELECT_LOCALE_CONFIGURATION);
|
|
2201
|
+
/** @docs-private */
|
|
2202
|
+
this.disabledInput = input(undefined, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
|
|
2203
|
+
transform: booleanAttribute });
|
|
2204
|
+
this.disabledState = signal(false, ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
2205
|
+
/** @docs-private */
|
|
2206
|
+
this.tabIndexInput = input(undefined, { ...(ngDevMode ? { debugName: "tabIndexInput" } : /* istanbul ignore next */ {}), alias: 'tabIndex',
|
|
2207
|
+
transform: kbqOptionalNumberAttribute });
|
|
2208
|
+
this.tabIndexState = signal(0, ...(ngDevMode ? [{ debugName: "tabIndexState" }] : /* istanbul ignore next */ []));
|
|
2209
|
+
this.selectionModelSubscription = null;
|
|
2210
|
+
// A selection change asks for a sweep here, not through `renderedOptions.changes`: the key manager and an
|
|
2211
|
+
// embedding select listen to that, and no row changed.
|
|
2212
|
+
this.selectionSweeps = new Subject();
|
|
2213
|
+
/** Whether a value report is queued for the end of the current tick. Cleared by `writeValue` to cancel it. */
|
|
2214
|
+
this.pendingValueReport = false;
|
|
2215
|
+
/** Backs {@link syncingSelection}: a change of the selection made by code is no change to report back. */
|
|
2216
|
+
this.writingValue = false;
|
|
2217
|
+
/**
|
|
2218
|
+
* The last value the form wrote while some of the nodes it names were not in the data yet. Applied again as the
|
|
2219
|
+
* data changes, until every node is found or the selection is reported to the form.
|
|
2220
|
+
*/
|
|
2221
|
+
this.unresolvedValue = null;
|
|
2222
|
+
this.destroyed = false;
|
|
2223
|
+
/** `treeControl.dataNodes` the options' checkbox states were last recomputed against. */
|
|
2224
|
+
this.checkboxSyncedDataNodes = null;
|
|
2225
|
+
/** @docs-private */
|
|
2226
|
+
this.selectAllHandlerInput = input(undefined, { ...(ngDevMode ? { debugName: "selectAllHandlerInput" } : /* istanbul ignore next */ {}), alias: 'selectAllHandler',
|
|
2227
|
+
transform: kbqSelectAllHandlerTransform });
|
|
2228
|
+
/**
|
|
2229
|
+
* Called when the value changes. Needed to properly implement `ControlValueAccessor`.
|
|
2230
|
+
*
|
|
2231
|
+
* @docs-private
|
|
2232
|
+
*/
|
|
1506
2233
|
this.onChange = () => { };
|
|
1507
|
-
/**
|
|
2234
|
+
/**
|
|
2235
|
+
* Called when the control is blurred. Needed to properly implement `ControlValueAccessor`.
|
|
2236
|
+
*
|
|
2237
|
+
* @docs-private
|
|
2238
|
+
*/
|
|
1508
2239
|
this.onTouched = () => { };
|
|
1509
2240
|
this.updateRenderedOptions = () => {
|
|
1510
2241
|
const orderedOptions = [];
|
|
@@ -1515,8 +2246,19 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1515
2246
|
if (selectAllOption) {
|
|
1516
2247
|
orderedOptions.push(selectAllOption);
|
|
1517
2248
|
}
|
|
2249
|
+
// Indexed once per render, as a search per node is quadratic in the rows. The first option wins in both maps.
|
|
2250
|
+
const optionsByNode = new Map();
|
|
2251
|
+
const optionsByValue = new Map();
|
|
2252
|
+
this.unorderedOptions.forEach((option) => {
|
|
2253
|
+
if (!optionsByNode.has(option.data))
|
|
2254
|
+
optionsByNode.set(option.data, option);
|
|
2255
|
+
if (!optionsByValue.has(option.value))
|
|
2256
|
+
optionsByValue.set(option.value, option);
|
|
2257
|
+
});
|
|
1518
2258
|
this.sortedNodes.forEach((node) => {
|
|
1519
|
-
|
|
2259
|
+
// By node first: nodes do not have to carry distinct values, and a value match would hand every node with
|
|
2260
|
+
// the same value the first option holding it.
|
|
2261
|
+
const found = optionsByNode.get(node) ?? optionsByValue.get(this.treeControl.getValue(node));
|
|
1520
2262
|
if (found) {
|
|
1521
2263
|
orderedOptions.push(found);
|
|
1522
2264
|
}
|
|
@@ -1525,24 +2267,45 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1525
2267
|
this.renderedOptions.notifyOnChanges();
|
|
1526
2268
|
this.updateScrollSize();
|
|
1527
2269
|
};
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
this.
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
2270
|
+
this.destroyRef.onDestroy(() => (this.destroyed = true));
|
|
2271
|
+
// Single selection until the `multiple` input says otherwise. A model has to exist this early
|
|
2272
|
+
// because `KbqTreeOption.setSelected` refuses to touch the selection without one, and a static
|
|
2273
|
+
// `multiple` attribute reaches the input right after the constructor, before any node exists.
|
|
2274
|
+
this.selectionModel = this.ownSelectionModel = new SelectionModel(false);
|
|
2275
|
+
effect(() => {
|
|
2276
|
+
this.multipleInput();
|
|
2277
|
+
untracked(() => this.applyMultipleInput());
|
|
2278
|
+
});
|
|
2279
|
+
effect(() => {
|
|
2280
|
+
this.disabledInput();
|
|
2281
|
+
untracked(() => this.applyDisabledInput());
|
|
2282
|
+
});
|
|
2283
|
+
// Unbound, the input leaves the default, which follows the rendered options; bound back to `undefined` or
|
|
2284
|
+
// `null`, it restores that default.
|
|
2285
|
+
effect(() => {
|
|
2286
|
+
const tabIndex = this.tabIndexInput();
|
|
2287
|
+
untracked(() => {
|
|
2288
|
+
if (tabIndex !== undefined) {
|
|
2289
|
+
this.userTabIndex = tabIndex;
|
|
2290
|
+
this.tabIndexState.set(tabIndex);
|
|
2291
|
+
}
|
|
2292
|
+
else if (this.userTabIndex !== null) {
|
|
2293
|
+
this.userTabIndex = null;
|
|
2294
|
+
this.updateTabIndex();
|
|
2295
|
+
}
|
|
2296
|
+
});
|
|
2297
|
+
});
|
|
2298
|
+
effect(() => {
|
|
2299
|
+
this.typeAheadState();
|
|
2300
|
+
untracked(() => this.applyTypeAhead());
|
|
2301
|
+
});
|
|
1540
2302
|
// `unorderedOptions.changes` never fires for the "select all" row — it is a view child — so the
|
|
1541
2303
|
// rendered list has to be rebuilt whenever the view query resolves or drops it.
|
|
1542
2304
|
effect(() => {
|
|
1543
2305
|
this.selectAllOption();
|
|
1544
2306
|
if (this.renderedOptions) {
|
|
1545
|
-
|
|
2307
|
+
// Untracked: the options are read too, and their changes come through `unorderedOptions.changes`.
|
|
2308
|
+
untracked(() => this.updateRenderedOptions());
|
|
1546
2309
|
}
|
|
1547
2310
|
});
|
|
1548
2311
|
}
|
|
@@ -1550,14 +2313,144 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1550
2313
|
toggleSelectAll() {
|
|
1551
2314
|
this.selectAllOptions(true);
|
|
1552
2315
|
}
|
|
2316
|
+
/**
|
|
2317
|
+
* Sets the mode from the `multiple` binding, once per bound value: an unbound input leaves what
|
|
2318
|
+
* `KbqTreeSelect` or the {@link multipleMode} setter wrote, and a value bound back to `undefined` means
|
|
2319
|
+
* single selection.
|
|
2320
|
+
*
|
|
2321
|
+
* Called by an effect, and by `writeValue` ahead of it: a forms directive on this element writes the
|
|
2322
|
+
* value from its own `ngOnChanges`, which runs before any effect of the view.
|
|
2323
|
+
*/
|
|
2324
|
+
applyMultipleInput() {
|
|
2325
|
+
const multiple = this.multipleInput();
|
|
2326
|
+
if (multiple === this.appliedMultipleInput)
|
|
2327
|
+
return;
|
|
2328
|
+
this.appliedMultipleInput = multiple;
|
|
2329
|
+
this.setMultipleMode(resolveMultipleMode(multiple));
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Sets the disabled state from the `disabled` binding, once per bound value, so that whichever of the binding
|
|
2333
|
+
* and the form control changed last wins. An unbound input leaves what the form control wrote.
|
|
2334
|
+
*
|
|
2335
|
+
* Called by an effect, and by `setDisabledState` ahead of it: a forms directive on this element calls that
|
|
2336
|
+
* from its own `ngOnChanges`, after the binding is set but before any effect of the view runs.
|
|
2337
|
+
*/
|
|
2338
|
+
applyDisabledInput() {
|
|
2339
|
+
const disabled = this.disabledInput();
|
|
2340
|
+
if (disabled === this.appliedDisabledInput)
|
|
2341
|
+
return;
|
|
2342
|
+
this.appliedDisabledInput = disabled;
|
|
2343
|
+
this.disabledState.set(!!disabled);
|
|
2344
|
+
}
|
|
2345
|
+
/**
|
|
2346
|
+
* Applies a new selection mode, rebuilding the `SelectionModel` when the multiplicity itself changes —
|
|
2347
|
+
* CDK freezes that flag at construction, so the model has to be replaced rather than reconfigured.
|
|
2348
|
+
*/
|
|
2349
|
+
setMultipleMode(next) {
|
|
2350
|
+
if (next === this.mode()) {
|
|
2351
|
+
return;
|
|
2352
|
+
}
|
|
2353
|
+
const rebuildNeeded = this.selectionModel.isMultipleSelection() !== !!next;
|
|
2354
|
+
// `KbqTreeSelect` hands the tree its own model and subscribes to it as well, so the multiplicity is
|
|
2355
|
+
// the select's to decide; replacing a model we do not own would drop those subscriptions. Thrown
|
|
2356
|
+
// rather than ignored: Angular caches the bound value either way, so a silently dropped write
|
|
2357
|
+
// leaves the binding and the tree permanently out of step with no way to retry.
|
|
2358
|
+
if (rebuildNeeded && this.selectionModel !== this.ownSelectionModel) {
|
|
2359
|
+
throw getKbqTreeSelectionOwnedMultipleError();
|
|
2360
|
+
}
|
|
2361
|
+
this.mode.set(next);
|
|
2362
|
+
// While the checkbox is hidden, the options leave its state as it was.
|
|
2363
|
+
if (next === MultipleMode.CHECKBOX)
|
|
2364
|
+
this.scheduleCheckboxSync(true);
|
|
2365
|
+
if (rebuildNeeded) {
|
|
2366
|
+
this.rebuildSelectionModel(!!next);
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
/** Replaces the `SelectionModel` with one of the given multiplicity, keeping what the new one can hold. */
|
|
2370
|
+
rebuildSelectionModel(multiple) {
|
|
2371
|
+
// Copied because CDK hands back its own cached array.
|
|
2372
|
+
const selected = [...this.selectionModel.selected];
|
|
2373
|
+
// Narrowing keeps one node: the first selected one in render order, falling back to the model's own
|
|
2374
|
+
// order when every selected node sits inside a collapsed branch and is therefore not rendered.
|
|
2375
|
+
// Asked of the model rather than of the option, whose mirror is only re-synced a macrotask later.
|
|
2376
|
+
const rendered = this.renderedOptions?.find((option) => this.selectionModel.isSelected(option.data))?.data;
|
|
2377
|
+
const kept = multiple ? selected : selected.slice(0, 1);
|
|
2378
|
+
if (!multiple && rendered !== undefined && selected.includes(rendered)) {
|
|
2379
|
+
kept[0] = rendered;
|
|
2380
|
+
}
|
|
2381
|
+
const dropped = selected.filter((node) => !kept.includes(node));
|
|
2382
|
+
const droppedOptions = (this.renderedOptions?.toArray() ?? []).filter((option) => dropped.includes(option.data));
|
|
2383
|
+
// `initiallySelectedValues` seeds the model without emitting.
|
|
2384
|
+
this.selectionModel = this.ownSelectionModel = new SelectionModel(multiple, kept);
|
|
2385
|
+
this.bindSelectionModel();
|
|
2386
|
+
// Reconciles both directions against the model that is actually in use now, so no node is left
|
|
2387
|
+
// painted by a stale mirror — a node whose option was created while it was already selected has
|
|
2388
|
+
// one, and so does every node the narrowing just dropped.
|
|
2389
|
+
this.renderedOptions?.forEach((option) => option.setSelected(this.selectionModel.isSelected(option.data)));
|
|
2390
|
+
if (droppedOptions.length) {
|
|
2391
|
+
// The nodes lost their selection without going through the model, so nothing else would
|
|
2392
|
+
// announce it.
|
|
2393
|
+
this.selectionChange.emit(new KbqTreeSelectionChange(this, droppedOptions[0], droppedOptions));
|
|
2394
|
+
}
|
|
2395
|
+
// Reported on every multiplicity change, not only when the selection shrank: `getSelectedValues`
|
|
2396
|
+
// returns a bare value in single selection and an array in multiple, so widening changes the shape
|
|
2397
|
+
// the form control has to hold even though nothing was dropped.
|
|
2398
|
+
this.scheduleValueReport();
|
|
2399
|
+
}
|
|
2400
|
+
/**
|
|
2401
|
+
* Reports the value once the current change-detection pass is over: a bound `[multiple]` is written
|
|
2402
|
+
* during change detection, and reporting straight back to the form control there would raise
|
|
2403
|
+
* "Expression has changed after it was checked". Coalesced so that several mode changes in one tick
|
|
2404
|
+
* produce one notification, and dropped if the form writes a value or the tree is gone by the time it runs.
|
|
2405
|
+
*/
|
|
2406
|
+
scheduleValueReport() {
|
|
2407
|
+
if (this.pendingValueReport) {
|
|
2408
|
+
return;
|
|
2409
|
+
}
|
|
2410
|
+
this.pendingValueReport = true;
|
|
2411
|
+
Promise.resolve().then(() => {
|
|
2412
|
+
if (!this.pendingValueReport)
|
|
2413
|
+
return;
|
|
2414
|
+
this.pendingValueReport = false;
|
|
2415
|
+
if (!this.destroyed) {
|
|
2416
|
+
this.reportValue();
|
|
2417
|
+
}
|
|
2418
|
+
});
|
|
2419
|
+
}
|
|
2420
|
+
/** Reports the selection to the form, which then holds it instead of a value still waiting for its nodes. */
|
|
2421
|
+
reportValue() {
|
|
2422
|
+
this.unresolvedValue = null;
|
|
2423
|
+
this.onChange(this.getSelectedValues());
|
|
2424
|
+
}
|
|
2425
|
+
/** (Re)points the change subscription at the current {@link selectionModel}. */
|
|
2426
|
+
bindSelectionModel() {
|
|
2427
|
+
this.selectionModelSubscription?.unsubscribe();
|
|
2428
|
+
this.selectionModelSubscription = this.selectionModel.changed
|
|
2429
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
2430
|
+
.subscribe(() => {
|
|
2431
|
+
if (!this.writingValue) {
|
|
2432
|
+
this.reportValue();
|
|
2433
|
+
}
|
|
2434
|
+
this.selectionSweeps.next();
|
|
2435
|
+
// The "select all" row renders the selection state.
|
|
2436
|
+
this.changeDetectorRef.markForCheck();
|
|
2437
|
+
});
|
|
2438
|
+
}
|
|
1553
2439
|
ngAfterContentInit() {
|
|
2440
|
+
super.ngAfterContentInit();
|
|
1554
2441
|
if (this.platform.isBrowser) {
|
|
1555
|
-
this.unorderedOptions.changes
|
|
2442
|
+
this.unorderedOptions.changes
|
|
2443
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
2444
|
+
.subscribe(this.updateRenderedOptions);
|
|
1556
2445
|
}
|
|
1557
2446
|
this.keyManager = new FocusKeyManager(this.renderedOptions)
|
|
1558
2447
|
.withVerticalOrientation(true)
|
|
1559
2448
|
.withHorizontalOrientation(null);
|
|
2449
|
+
this.applyTypeAhead();
|
|
1560
2450
|
this.keyManager.change.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
|
2451
|
+
// `aria-activedescendant` is bound to the active option, and nothing else in this view
|
|
2452
|
+
// changes when the key manager moves.
|
|
2453
|
+
this.changeDetectorRef.markForCheck();
|
|
1561
2454
|
if (this.keyManager.activeItem) {
|
|
1562
2455
|
this.emitNavigationEvent(this.keyManager.activeItem);
|
|
1563
2456
|
// todo need check this logic
|
|
@@ -1566,21 +2459,22 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1566
2459
|
}
|
|
1567
2460
|
}
|
|
1568
2461
|
});
|
|
1569
|
-
this.keyManager.tabOut
|
|
1570
|
-
this.
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
.
|
|
1577
|
-
|
|
2462
|
+
kbqLeaveTabOrderOnTabOut(this.keyManager.tabOut, this.elementRef.nativeElement, () => this.tabIndex, this.destroyRef);
|
|
2463
|
+
this.bindSelectionModel();
|
|
2464
|
+
this.listenToOptionsFocus();
|
|
2465
|
+
// A render and the selection changes of one task each notify, each with its own timer: the first to fire sweeps
|
|
2466
|
+
// for all of them and the rest are dropped. `auditTime` would tie the later ones to the first one's timer.
|
|
2467
|
+
let sweeps = 0;
|
|
2468
|
+
merge(this.renderedOptions.changes, this.selectionSweeps)
|
|
2469
|
+
.pipe(map(() => sweeps), delay(0, this.scheduler), filter((sweepsWhenNotified) => sweepsWhenNotified === sweeps), takeUntilDestroyed(this.destroyRef))
|
|
2470
|
+
.subscribe(() => {
|
|
2471
|
+
sweeps++;
|
|
1578
2472
|
// Check to see if we need to update our tab index
|
|
1579
2473
|
this.updateTabIndex();
|
|
1580
2474
|
this.syncSelectionModelToDataNodes();
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
if (
|
|
2475
|
+
this.renderedOptions.forEach((option) => {
|
|
2476
|
+
// By node rather than by value: rows may share a value.
|
|
2477
|
+
if (this.selectionModel.isSelected(option.data)) {
|
|
1584
2478
|
option.select(false);
|
|
1585
2479
|
}
|
|
1586
2480
|
else {
|
|
@@ -1590,11 +2484,39 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1590
2484
|
});
|
|
1591
2485
|
});
|
|
1592
2486
|
}
|
|
2487
|
+
/**
|
|
2488
|
+
* Rebuilds the tree around a selection model owned by an embedding host, such as `KbqTreeSelect`.
|
|
2489
|
+
*
|
|
2490
|
+
* The host has to take the model over before the tree starts reacting to it, and re-running
|
|
2491
|
+
* `ngAfterContentInit()` is not a way to do that: neither `unorderedOptions` nor `renderedOptions` is
|
|
2492
|
+
* ever re-created, so a second run would only leave a second set of subscribers on both — every options
|
|
2493
|
+
* change handled twice, and the whole option sweep run twice per emission. Only the subscription that
|
|
2494
|
+
* depends on the model has to move, which is exactly what `bindSelectionModel` does.
|
|
2495
|
+
*/
|
|
2496
|
+
initializeForEmbedding(selectionModel) {
|
|
2497
|
+
this.selectionModel = selectionModel;
|
|
2498
|
+
this.bindSelectionModel();
|
|
2499
|
+
}
|
|
2500
|
+
ngAfterContentChecked() {
|
|
2501
|
+
// Syncs the list here so `changes` emits after the projected items are bound and before the host bindings.
|
|
2502
|
+
this.unorderedOptionsList();
|
|
2503
|
+
super.ngAfterContentChecked();
|
|
2504
|
+
}
|
|
1593
2505
|
ngAfterViewInit() {
|
|
1594
|
-
|
|
2506
|
+
// Reports the focus leaving only when it lands outside the tree (or nowhere): the host hands it to an option
|
|
2507
|
+
// on entry, and options hand it on to each other or to their action buttons, none of which blurs the tree.
|
|
2508
|
+
this.focusMonitor
|
|
2509
|
+
.monitor(this.elementRef, true)
|
|
2510
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
2511
|
+
.subscribe((origin) => {
|
|
2512
|
+
if (!origin)
|
|
2513
|
+
this.blur();
|
|
2514
|
+
});
|
|
1595
2515
|
}
|
|
1596
2516
|
ngOnDestroy() {
|
|
1597
2517
|
super.ngOnDestroy();
|
|
2518
|
+
this.optionFocusEvents.complete();
|
|
2519
|
+
this.optionBlurEvents.complete();
|
|
1598
2520
|
this.focusMonitor.stopMonitoring(this.elementRef);
|
|
1599
2521
|
}
|
|
1600
2522
|
focus($event) {
|
|
@@ -1610,17 +2532,45 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1610
2532
|
}
|
|
1611
2533
|
this.keyManager.setFocusOrigin('program');
|
|
1612
2534
|
}
|
|
2535
|
+
/** @docs-private */
|
|
1613
2536
|
highlightSelectedOption() {
|
|
1614
|
-
|
|
2537
|
+
untracked(() => {
|
|
2538
|
+
// The selection can hold nodes that are not rendered — collapsed branches, or references left
|
|
2539
|
+
// over from a data replacement. Falling back keeps `focus()` from ending with nothing focused
|
|
2540
|
+
// at all, since it already took the branch that skips `setFirstItemActive`.
|
|
2541
|
+
const target = this.renderedOptions.find((item) => item.data === this.selectionModel.selected[0]) ??
|
|
2542
|
+
this.keyManager.activeItem;
|
|
2543
|
+
if (target) {
|
|
2544
|
+
target.focus();
|
|
2545
|
+
}
|
|
2546
|
+
else {
|
|
2547
|
+
this.keyManager.setFirstItemActive();
|
|
2548
|
+
}
|
|
2549
|
+
});
|
|
1615
2550
|
}
|
|
1616
2551
|
blur() {
|
|
1617
|
-
|
|
1618
|
-
this.
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
2552
|
+
untracked(() => {
|
|
2553
|
+
if (!this.hasFocusedOption() && this.resetFocusedItemOnBlur) {
|
|
2554
|
+
this.keyManager.setActiveItem(-1);
|
|
2555
|
+
}
|
|
2556
|
+
this.onTouched();
|
|
2557
|
+
this.changeDetectorRef.markForCheck();
|
|
2558
|
+
});
|
|
1622
2559
|
}
|
|
2560
|
+
/**
|
|
2561
|
+
* Host listener for keyboard input.
|
|
2562
|
+
*
|
|
2563
|
+
* Does nothing while an embedding host owns the keyboard — `KbqTreeSelect` routes every key through
|
|
2564
|
+
* its own panel handler and calls back into `handleKeydown` for the parts it delegates, so without
|
|
2565
|
+
* this guard the same event would be acted on twice.
|
|
2566
|
+
*/
|
|
1623
2567
|
onKeyDown(event) {
|
|
2568
|
+
if (!this.ownsKeyboard)
|
|
2569
|
+
return;
|
|
2570
|
+
this.handleKeydown(event);
|
|
2571
|
+
}
|
|
2572
|
+
/** Runs the tree's own keyboard handling, whether or not it owns the keyboard. */
|
|
2573
|
+
handleKeydown(event) {
|
|
1624
2574
|
this.keyManager.setFocusOrigin('keyboard');
|
|
1625
2575
|
const keyCode = event.keyCode;
|
|
1626
2576
|
if ([SPACE, LEFT_ARROW, RIGHT_ARROW].includes(keyCode) || isVerticalMovement(event)) {
|
|
@@ -1642,14 +2592,22 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1642
2592
|
const activeItem = this.keyManager.activeItem;
|
|
1643
2593
|
if (activeItem.isExpandable && activeItem.isExpanded) {
|
|
1644
2594
|
this.treeControl.collapse(activeItem.data);
|
|
2595
|
+
this.saveState();
|
|
1645
2596
|
}
|
|
1646
2597
|
else {
|
|
1647
2598
|
this.setActiveParentOption(activeItem);
|
|
1648
2599
|
}
|
|
1649
2600
|
return;
|
|
1650
2601
|
}
|
|
1651
|
-
else if (keyCode === RIGHT_ARROW && this.keyManager.activeItem
|
|
1652
|
-
this.
|
|
2602
|
+
else if (keyCode === RIGHT_ARROW && this.keyManager.activeItem) {
|
|
2603
|
+
const activeItem = this.keyManager.activeItem;
|
|
2604
|
+
if (activeItem.isExpandable && !activeItem.isExpanded) {
|
|
2605
|
+
this.treeControl.expand(activeItem.data);
|
|
2606
|
+
this.saveState();
|
|
2607
|
+
}
|
|
2608
|
+
else if (activeItem.isExpandable) {
|
|
2609
|
+
this.setActiveFirstChildOption(activeItem);
|
|
2610
|
+
}
|
|
1653
2611
|
return;
|
|
1654
2612
|
}
|
|
1655
2613
|
else if (keyCode === DOWN_ARROW) {
|
|
@@ -1674,12 +2632,26 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1674
2632
|
else if (keyCode === PAGE_DOWN) {
|
|
1675
2633
|
this.keyManager.setNextPageItemActive();
|
|
1676
2634
|
}
|
|
2635
|
+
else {
|
|
2636
|
+
// Whatever is left is either a printable character, which the key manager turns into a
|
|
2637
|
+
// type-ahead query, or a key nothing here reacts to. Every key handled above returns or is
|
|
2638
|
+
// matched before this point, so the manager only ever sees the leftovers.
|
|
2639
|
+
//
|
|
2640
|
+
// Ctrl/Cmd/Alt combinations are the application's shortcuts, not text: the key manager feeds
|
|
2641
|
+
// its letter stream from the `default` branch without a modifier guard of its own, so Ctrl+S
|
|
2642
|
+
// would otherwise type-ahead to the first option starting with "S" and move focus there.
|
|
2643
|
+
if (!hasModifierKey(event, 'ctrlKey', 'metaKey', 'altKey')) {
|
|
2644
|
+
this.keyManager.onKeydown(event);
|
|
2645
|
+
}
|
|
2646
|
+
return;
|
|
2647
|
+
}
|
|
1677
2648
|
if (this.keyManager.activeItem && isVerticalMovement(event)) {
|
|
1678
2649
|
this.setSelectedOptionsByKey(this.keyManager.activeItem, hasModifierKey(event, 'shiftKey'),
|
|
1679
2650
|
// ctrlKey is for Windows, metaKey is for MacOS
|
|
1680
2651
|
hasModifierKey(event, 'ctrlKey', 'metaKey'));
|
|
1681
2652
|
}
|
|
1682
2653
|
}
|
|
2654
|
+
/** @docs-private */
|
|
1683
2655
|
updateScrollSize() {
|
|
1684
2656
|
if (!this.renderedOptions.first) {
|
|
1685
2657
|
return;
|
|
@@ -1692,6 +2664,7 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1692
2664
|
}
|
|
1693
2665
|
this.keyManager.withScrollSize(Math.floor(this.getHeight() / optionHeight));
|
|
1694
2666
|
}
|
|
2667
|
+
/** @docs-private */
|
|
1695
2668
|
setSelectedOptionsByKey(option, shiftKey, ctrlKey) {
|
|
1696
2669
|
if (shiftKey && this.multiple) {
|
|
1697
2670
|
this.selectActiveOptions();
|
|
@@ -1708,6 +2681,15 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1708
2681
|
this.emitChangeEvent(option);
|
|
1709
2682
|
}
|
|
1710
2683
|
}
|
|
2684
|
+
/** @docs-private */
|
|
2685
|
+
reportOptionFocus(event) {
|
|
2686
|
+
this.optionFocusEvents.next(event);
|
|
2687
|
+
}
|
|
2688
|
+
/** @docs-private */
|
|
2689
|
+
reportOptionBlur(event) {
|
|
2690
|
+
this.optionBlurEvents.next(event);
|
|
2691
|
+
}
|
|
2692
|
+
/** @docs-private */
|
|
1711
2693
|
setSelectedOptionsByClick(option, shiftKey, ctrlKey) {
|
|
1712
2694
|
if (option.disabled || !option.selectable()) {
|
|
1713
2695
|
return;
|
|
@@ -1734,11 +2716,13 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1734
2716
|
}
|
|
1735
2717
|
this.emitChangeEvent(option);
|
|
1736
2718
|
}
|
|
2719
|
+
/** @docs-private */
|
|
1737
2720
|
selectActiveOptions() {
|
|
1738
2721
|
const options = this.renderedOptions.toArray();
|
|
1739
2722
|
let fromIndex = this.keyManager.previousActiveItemIndex;
|
|
1740
2723
|
let toIndex = (this.keyManager.previousActiveItemIndex = this.keyManager.activeItemIndex);
|
|
1741
|
-
|
|
2724
|
+
// Asked of the model: an option's own state lags it until the next sweep.
|
|
2725
|
+
const selectedOptionState = this.selectionModel.isSelected(options[fromIndex]?.data);
|
|
1742
2726
|
if (toIndex === fromIndex || fromIndex === -1) {
|
|
1743
2727
|
if (options[toIndex]?.selectable()) {
|
|
1744
2728
|
options[toIndex].toggle();
|
|
@@ -1748,19 +2732,23 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1748
2732
|
if (fromIndex > toIndex) {
|
|
1749
2733
|
[fromIndex, toIndex] = [toIndex, fromIndex];
|
|
1750
2734
|
}
|
|
1751
|
-
options
|
|
2735
|
+
const nodes = options
|
|
1752
2736
|
.slice(fromIndex, toIndex + 1)
|
|
1753
2737
|
.filter((item) => !item.disabled && item.selectable())
|
|
1754
|
-
.
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
}
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
this.
|
|
2738
|
+
.map((item) => item.data);
|
|
2739
|
+
// One write for the range, so the selection changes once rather than once per row.
|
|
2740
|
+
if (selectedOptionState) {
|
|
2741
|
+
this.selectionModel.select(...nodes);
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2744
|
+
const selected = nodes.filter((node) => this.selectionModel.isSelected(node));
|
|
2745
|
+
// With `noUnselectLast` the last selected node stays, the range giving up its own in order until then.
|
|
2746
|
+
const released = this.noUnselectLast
|
|
2747
|
+
? Math.max(0, Math.min(selected.length, this.selectionModel.selected.length - 1))
|
|
2748
|
+
: selected.length;
|
|
2749
|
+
this.selectionModel.deselect(...selected.slice(0, released));
|
|
1763
2750
|
}
|
|
2751
|
+
/** @docs-private */
|
|
1764
2752
|
toggleFocusedOption() {
|
|
1765
2753
|
const focusedOption = this.keyManager.activeItem;
|
|
1766
2754
|
// The row is not selectable, so nothing below would act on it. Handling it here covers both focus
|
|
@@ -1776,14 +2764,51 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1776
2764
|
this.emitChangeEvent(focusedOption);
|
|
1777
2765
|
}
|
|
1778
2766
|
}
|
|
2767
|
+
/** @docs-private */
|
|
1779
2768
|
renderNodeChanges(data, dataDiffer = this.dataDiffer, viewContainer = this.nodeOutlet.viewContainer, parentData) {
|
|
1780
|
-
super.renderNodeChanges
|
|
2769
|
+
// Not `super.renderNodeChanges`: that would run change detection over this very view before
|
|
2770
|
+
// `sortedNodes` is refreshed, so the "select all" row — which is rendered off `isEmpty` — would
|
|
2771
|
+
// need a second pass to catch up. One pass, after the state its template reads is current.
|
|
2772
|
+
const changed = this.applyNodeChanges(data, dataDiffer, viewContainer, parentData);
|
|
1781
2773
|
this.sortedNodes = this.getSortedNodes(viewContainer);
|
|
1782
|
-
this.
|
|
2774
|
+
this.changeDetectorRef.detectChanges();
|
|
2775
|
+
// The options query lists the options in the order their views were created, not in the order of the rows, so
|
|
2776
|
+
// rows that only moved (reused through `trackBy`) never make it emit.
|
|
2777
|
+
if (changed && this.renderedOptionsOutOfOrder())
|
|
2778
|
+
this.updateRenderedOptions();
|
|
2779
|
+
this.scheduleCheckboxSync(false);
|
|
2780
|
+
// The "select all" row is rendered ahead of what its state reads: new rows bind their inputs after it and join
|
|
2781
|
+
// `renderedOptions` only once bound, and a consumer's data source can assign `dataNodes` after it emits.
|
|
2782
|
+
// Nothing else in the tree reads that state but the checkbox sync above, so a tree without the row is done in
|
|
2783
|
+
// this one pass. Marked for check, which reaches the views above too: a template reading `allOptionsSelected`
|
|
2784
|
+
// by reference reads the same state.
|
|
2785
|
+
if (!this.showSelectAll)
|
|
2786
|
+
return;
|
|
2787
|
+
const dataNodes = this.treeControl.dataNodes;
|
|
2788
|
+
afterNextRender(() => {
|
|
2789
|
+
if (changed || this.treeControl.dataNodes !== dataNodes)
|
|
2790
|
+
this.changeDetectorRef.markForCheck();
|
|
2791
|
+
}, { injector: this.injector });
|
|
2792
|
+
}
|
|
2793
|
+
/**
|
|
2794
|
+
* Recomputes every option's checkbox state where no selection change follows to do it: after `dataNodes` is
|
|
2795
|
+
* replaced, which moves the descendants a branch counts, and once a hidden checkbox appears. A microtask later, as
|
|
2796
|
+
* a consumer's data source can assign `dataNodes` after it emits.
|
|
2797
|
+
*/
|
|
2798
|
+
scheduleCheckboxSync(force) {
|
|
2799
|
+
Promise.resolve().then(() => {
|
|
2800
|
+
const dataNodes = this.treeControl?.dataNodes ?? null;
|
|
2801
|
+
if (this.destroyed || (!force && dataNodes === this.checkboxSyncedDataNodes))
|
|
2802
|
+
return;
|
|
2803
|
+
this.checkboxSyncedDataNodes = dataNodes;
|
|
2804
|
+
this.unorderedOptions.forEach((option) => option.markForCheck());
|
|
2805
|
+
});
|
|
1783
2806
|
}
|
|
2807
|
+
/** @docs-private */
|
|
1784
2808
|
emitNavigationEvent(option) {
|
|
1785
2809
|
this.navigationChange.emit(new KbqTreeNavigationChange(this, option));
|
|
1786
2810
|
}
|
|
2811
|
+
/** @docs-private */
|
|
1787
2812
|
emitChangeEvent(option) {
|
|
1788
2813
|
this.selectionChange.emit(new KbqTreeSelectionChange(this, option, [option]));
|
|
1789
2814
|
}
|
|
@@ -1792,46 +2817,63 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1792
2817
|
* which toggles the selection of all non-disabled, selectable options.
|
|
1793
2818
|
*/
|
|
1794
2819
|
get selectAllHandler() {
|
|
1795
|
-
return this.
|
|
1796
|
-
}
|
|
1797
|
-
set selectAllHandler(fn) {
|
|
1798
|
-
if (typeof fn !== 'function') {
|
|
1799
|
-
throw Error('`selectAllHandler` must be a function.');
|
|
1800
|
-
}
|
|
1801
|
-
this._selectAllHandler = fn;
|
|
2820
|
+
return this.selectAllHandlerInput() ?? this.defaultSelectAllHandler;
|
|
1802
2821
|
}
|
|
1803
|
-
|
|
2822
|
+
defaultSelectAllHandler(event, tree) {
|
|
1804
2823
|
event.preventDefault();
|
|
1805
2824
|
tree.selectAllOptions();
|
|
1806
2825
|
}
|
|
1807
|
-
selectAllOptions(allowDeselect
|
|
1808
|
-
//
|
|
1809
|
-
//
|
|
1810
|
-
//
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
2826
|
+
selectAllOptions(allowDeselect) {
|
|
2827
|
+
// Untracked, its default included, like the other imperative methods: called from a consumer's `effect()`,
|
|
2828
|
+
// the state read on the way — the options, `disabled`, the mode, the inputs — would make the effect run
|
|
2829
|
+
// again whenever it changes.
|
|
2830
|
+
untracked(() => {
|
|
2831
|
+
// The row's own `(click)` and the Ctrl/Cmd + A shortcut both funnel through here, so this is the
|
|
2832
|
+
// single place to refuse acting while the whole tree is disabled — mirrors the guard every other
|
|
2833
|
+
// row already gets via `KbqTreeOption.selectViaInteraction()`.
|
|
2834
|
+
if (this.disabled)
|
|
2835
|
+
return;
|
|
2836
|
+
// Selection is applied at the data-node level (incl. collapsed/non-rendered nodes unless a filter
|
|
2837
|
+
// is active), while the emitted events carry the selectable rendered options.
|
|
2838
|
+
const selectableOptions = this.renderedOptions.filter((option) => !option.disabled && option.selectable());
|
|
2839
|
+
// A multiple selection takes the nodes in one write, so it changes once rather than once per node. A single
|
|
2840
|
+
// one cannot hold them, and keeps the node-by-node writes it always had.
|
|
2841
|
+
const batched = this.selectionModel.isMultipleSelection();
|
|
2842
|
+
const adapter = this.selectAllAdapter;
|
|
2843
|
+
// `toggleSelectAll` returns the data nodes whose selection actually flipped — the source of
|
|
2844
|
+
// truth, unlike the cached `option.selected` which lags until change detection.
|
|
2845
|
+
const changed = toggleSelectAll(batched ? { ...adapter, setSelected: () => { } } : adapter, {
|
|
2846
|
+
allowDeselect: allowDeselect ?? (this.selectAll || this.selectAllToggle())
|
|
2847
|
+
});
|
|
2848
|
+
if (batched && changed.length) {
|
|
2849
|
+
if (this.selectionModel.isSelected(changed[0])) {
|
|
2850
|
+
this.selectionModel.deselect(...changed);
|
|
2851
|
+
}
|
|
2852
|
+
else {
|
|
2853
|
+
this.selectionModel.select(...changed);
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2856
|
+
const changedData = new Set(changed);
|
|
2857
|
+
const changedOptions = selectableOptions.filter((option) => changedData.has(option.data));
|
|
2858
|
+
// Skip `selectionChange` on a no-op (e.g. Ctrl+A while everything is already selected and
|
|
2859
|
+
// `allowDeselect` is off) so `KbqTreeSelectionChange.option` is never `undefined`.
|
|
2860
|
+
if (changedOptions.length > 0) {
|
|
2861
|
+
this.selectionChange.emit(new KbqTreeSelectionChange(this, changedOptions[0], changedOptions));
|
|
2862
|
+
}
|
|
2863
|
+
const selectAllEvent = new KbqTreeSelectAllEvent(this, selectableOptions);
|
|
2864
|
+
this.selectAllChange.emit(selectAllEvent);
|
|
2865
|
+
this.onSelectAll.emit(selectAllEvent);
|
|
2866
|
+
});
|
|
1827
2867
|
}
|
|
1828
2868
|
copyActiveOption(event) {
|
|
1829
2869
|
if (!this.keyManager.activeItem)
|
|
1830
2870
|
return;
|
|
1831
2871
|
const option = this.keyManager.activeItem;
|
|
1832
2872
|
option.preventBlur = true;
|
|
1833
|
-
if (this.onCopy.observed) {
|
|
1834
|
-
|
|
2873
|
+
if (this.copyChange.observed || this.onCopy.observed) {
|
|
2874
|
+
const copyEvent = new KbqTreeCopyEvent(this, option, event);
|
|
2875
|
+
this.copyChange.emit(copyEvent);
|
|
2876
|
+
this.onCopy.emit(copyEvent);
|
|
1835
2877
|
}
|
|
1836
2878
|
else {
|
|
1837
2879
|
this.onCopyDefaultHandler();
|
|
@@ -1840,20 +2882,44 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1840
2882
|
option.preventBlur = false;
|
|
1841
2883
|
}
|
|
1842
2884
|
writeValue(value) {
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
this.
|
|
2885
|
+
untracked(() => {
|
|
2886
|
+
this.applyMultipleInput();
|
|
2887
|
+
if (this.multiple && value && !Array.isArray(value)) {
|
|
2888
|
+
throw getKbqSelectNonArrayValueError();
|
|
2889
|
+
}
|
|
2890
|
+
// The form holds the value it writes, so a mode change has nothing left to report.
|
|
2891
|
+
this.pendingValueReport = false;
|
|
2892
|
+
this.applyWrittenValue(value);
|
|
2893
|
+
});
|
|
2894
|
+
}
|
|
2895
|
+
/** Selects the nodes of a value the form wrote, and keeps the value for the data still to come if any is missing. */
|
|
2896
|
+
applyWrittenValue(value) {
|
|
2897
|
+
// A node value can be falsy, `0` or `''`: only a missing value clears the single selection.
|
|
2898
|
+
const values = this.multiple
|
|
2899
|
+
? Array.isArray(value)
|
|
2900
|
+
? value
|
|
2901
|
+
: null
|
|
2902
|
+
: value === null || value === undefined
|
|
2903
|
+
? null
|
|
2904
|
+
: [value];
|
|
2905
|
+
this.syncSelection(() => (values ? this.setOptionsFromValues(values) : this.selectionModel.clear()));
|
|
2906
|
+
this.unresolvedValue = values?.some((item) => !this.treeControl.hasValue(item)) ? { value } : null;
|
|
2907
|
+
}
|
|
2908
|
+
/** Runs a change of the selection made by code, which reports nothing back to the form or to a host. */
|
|
2909
|
+
syncSelection(change) {
|
|
2910
|
+
// Restored rather than cleared: a value written while this one is applied must not end the outer write.
|
|
2911
|
+
const wasWritingValue = this.writingValue;
|
|
2912
|
+
this.writingValue = true;
|
|
2913
|
+
try {
|
|
2914
|
+
change();
|
|
2915
|
+
}
|
|
2916
|
+
finally {
|
|
2917
|
+
this.writingValue = wasWritingValue;
|
|
1851
2918
|
}
|
|
1852
2919
|
}
|
|
1853
2920
|
registerOnChange(fn) {
|
|
1854
2921
|
this.onChange = fn;
|
|
1855
2922
|
}
|
|
1856
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
1857
2923
|
registerOnTouched(fn) {
|
|
1858
2924
|
this.onTouched = fn;
|
|
1859
2925
|
}
|
|
@@ -1861,20 +2927,28 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1861
2927
|
* Sets the disabled state of the control. Implemented as a part of ControlValueAccessor.
|
|
1862
2928
|
*/
|
|
1863
2929
|
setDisabledState(isDisabled) {
|
|
1864
|
-
|
|
1865
|
-
|
|
2930
|
+
untracked(() => {
|
|
2931
|
+
this.applyDisabledInput();
|
|
2932
|
+
this.disabledState.set(isDisabled);
|
|
2933
|
+
});
|
|
1866
2934
|
}
|
|
2935
|
+
/** @docs-private */
|
|
1867
2936
|
setOptionsFromValues(values) {
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
2937
|
+
untracked(() => {
|
|
2938
|
+
this.selectionModel.clear();
|
|
2939
|
+
const valuesToSelect = values.reduce((result, value) => {
|
|
2940
|
+
return this.treeControl.hasValue(value) ? [...result, this.treeControl.hasValue(value)] : [...result];
|
|
2941
|
+
}, []);
|
|
2942
|
+
this.selectionModel.select(...valuesToSelect);
|
|
2943
|
+
});
|
|
1873
2944
|
}
|
|
1874
2945
|
/**
|
|
1875
2946
|
* Rebinds orphan node references in selectionModel to current treeControl.dataNodes by value.
|
|
1876
2947
|
* Needed after dataSource.data is replaced — selectionModel holds references to old node
|
|
1877
2948
|
* objects, but options render with new ones, so toggle()/isSelected() break on identity.
|
|
2949
|
+
*
|
|
2950
|
+
* A value the form wrote ahead of its nodes is applied again instead, which resolves every node anew.
|
|
2951
|
+
* Either way the selection only follows the data, so nothing is reported.
|
|
1878
2952
|
*/
|
|
1879
2953
|
syncSelectionModelToDataNodes() {
|
|
1880
2954
|
const currentNodes = this.treeControl.dataNodes;
|
|
@@ -1883,6 +2957,10 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1883
2957
|
if (currentNodes === this.lastSyncedDataNodes)
|
|
1884
2958
|
return;
|
|
1885
2959
|
this.lastSyncedDataNodes = currentNodes;
|
|
2960
|
+
if (this.unresolvedValue) {
|
|
2961
|
+
this.applyWrittenValue(this.unresolvedValue.value);
|
|
2962
|
+
return;
|
|
2963
|
+
}
|
|
1886
2964
|
if (this.selectionModel.isEmpty() || !currentNodes?.length)
|
|
1887
2965
|
return;
|
|
1888
2966
|
const selected = this.selectionModel.selected;
|
|
@@ -1902,23 +2980,23 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1902
2980
|
const replacement = this.treeControl.hasValue(this.treeControl.getValue(node));
|
|
1903
2981
|
return replacement ?? node;
|
|
1904
2982
|
});
|
|
1905
|
-
this.selectionModel.setSelection(...reconciled);
|
|
2983
|
+
this.syncSelection(() => this.selectionModel.setSelection(...reconciled));
|
|
1906
2984
|
}
|
|
2985
|
+
/** @docs-private */
|
|
1907
2986
|
getSelectedValues() {
|
|
1908
2987
|
const selectedValues = this.selectionModel.selected.map((selected) => this.treeControl.getValue(selected));
|
|
1909
2988
|
return this.multiple ? selectedValues : selectedValues[0];
|
|
1910
2989
|
}
|
|
1911
|
-
getItemHeight() {
|
|
1912
|
-
return this.renderedOptions.first ? this.renderedOptions.first.getHeight() : 0;
|
|
1913
|
-
}
|
|
1914
2990
|
setStateChildren(option, state) {
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
2991
|
+
untracked(() => {
|
|
2992
|
+
const valuesToChange = this.treeControl.getDescendants(option.data);
|
|
2993
|
+
if (state) {
|
|
2994
|
+
this.selectionModel.select(...valuesToChange);
|
|
2995
|
+
}
|
|
2996
|
+
else {
|
|
2997
|
+
this.selectionModel.deselect(...valuesToChange);
|
|
2998
|
+
}
|
|
2999
|
+
});
|
|
1922
3000
|
}
|
|
1923
3001
|
onCopyDefaultHandler() {
|
|
1924
3002
|
this.clipboard?.copy(this.keyManager.activeItem.value);
|
|
@@ -1951,11 +3029,48 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1951
3029
|
level = option.level;
|
|
1952
3030
|
}
|
|
1953
3031
|
}
|
|
3032
|
+
/** `-1` is the key manager's way of keeping the letter stream running but never matching on it. */
|
|
3033
|
+
applyTypeAhead() {
|
|
3034
|
+
this.keyManager?.withTypeAhead(typeAheadDebounce, this.typeAhead ? 0 : -1);
|
|
3035
|
+
}
|
|
3036
|
+
/**
|
|
3037
|
+
* Moves focus to the first child of an already-expanded option — ArrowRight on an expanded node.
|
|
3038
|
+
*
|
|
3039
|
+
* The mirror of `setActiveParentOption`: the first rendered option after the active one is its
|
|
3040
|
+
* first child whenever its level is greater, so nothing has to be re-derived from `treeControl`.
|
|
3041
|
+
* A disabled child cannot take focus, so the walk continues while the options stay inside the
|
|
3042
|
+
* subtree, and stops as soon as the level falls back to the active option's own.
|
|
3043
|
+
*/
|
|
3044
|
+
setActiveFirstChildOption(activeOption) {
|
|
3045
|
+
const options = this.renderedOptions.toArray();
|
|
3046
|
+
for (let index = this.keyManager.activeItemIndex + 1; index < options.length; index++) {
|
|
3047
|
+
const option = options[index];
|
|
3048
|
+
if (option.level <= activeOption.level) {
|
|
3049
|
+
return;
|
|
3050
|
+
}
|
|
3051
|
+
if (!option.disabled) {
|
|
3052
|
+
this.keyManager.setActiveItem(index);
|
|
3053
|
+
return;
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
1954
3057
|
getHeight() {
|
|
1955
3058
|
return kbqGetElementHeight(this.elementRef.nativeElement);
|
|
1956
3059
|
}
|
|
3060
|
+
/** A tree with nothing rendered leaves the tab order, unless a tab index other than `0` is bound. */
|
|
1957
3061
|
updateTabIndex() {
|
|
1958
|
-
this.
|
|
3062
|
+
this.tabIndexState.set(this.userTabIndex || (this.renderedOptions.length === 0 ? -1 : 0));
|
|
3063
|
+
}
|
|
3064
|
+
/**
|
|
3065
|
+
* Whether the same options as before now stand for the rows in another order. A different count means rows were
|
|
3066
|
+
* added or removed, which the options query reports itself.
|
|
3067
|
+
*/
|
|
3068
|
+
renderedOptionsOutOfOrder() {
|
|
3069
|
+
const options = this.renderedOptions.toArray();
|
|
3070
|
+
const offset = this.selectAllOption() ? 1 : 0;
|
|
3071
|
+
if (options.length - offset !== this.sortedNodes.length)
|
|
3072
|
+
return false;
|
|
3073
|
+
return this.sortedNodes.some((node, index) => options[index + offset].data !== node);
|
|
1959
3074
|
}
|
|
1960
3075
|
getSortedNodes(viewContainer) {
|
|
1961
3076
|
const array = [];
|
|
@@ -1965,41 +3080,29 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
1965
3080
|
}
|
|
1966
3081
|
return array;
|
|
1967
3082
|
}
|
|
1968
|
-
allowFocusEscape() {
|
|
1969
|
-
if (this._tabIndex !== -1) {
|
|
1970
|
-
this._tabIndex = -1;
|
|
1971
|
-
setTimeout(() => {
|
|
1972
|
-
this._tabIndex = this.userTabIndex || 0;
|
|
1973
|
-
this.changeDetectorRef.markForCheck();
|
|
1974
|
-
});
|
|
1975
|
-
}
|
|
1976
|
-
}
|
|
1977
|
-
resetOptions() {
|
|
1978
|
-
this.dropSubscriptions();
|
|
1979
|
-
this.listenToOptionsFocus();
|
|
1980
|
-
}
|
|
1981
|
-
dropSubscriptions() {
|
|
1982
|
-
if (this.optionFocusSubscription) {
|
|
1983
|
-
this.optionFocusSubscription.unsubscribe();
|
|
1984
|
-
this.optionFocusSubscription = null;
|
|
1985
|
-
}
|
|
1986
|
-
if (this.optionBlurSubscription) {
|
|
1987
|
-
this.optionBlurSubscription.unsubscribe();
|
|
1988
|
-
this.optionBlurSubscription = null;
|
|
1989
|
-
}
|
|
1990
|
-
}
|
|
1991
3083
|
listenToOptionsFocus() {
|
|
1992
|
-
|
|
3084
|
+
// Both streams complete with the tree.
|
|
3085
|
+
this.optionFocusEvents.subscribe((event) => {
|
|
1993
3086
|
const index = this.renderedOptions.toArray().indexOf(event.option);
|
|
1994
3087
|
this.renderedOptions.filter((option) => option.hasFocus).forEach((option) => (option.hasFocus = false));
|
|
1995
3088
|
if (this.isValidIndex(index)) {
|
|
1996
3089
|
this.keyManager.updateActiveItem(index);
|
|
1997
3090
|
}
|
|
1998
3091
|
});
|
|
1999
|
-
|
|
3092
|
+
// Moving the active option blurs the one being left, so an option blur alone does not mean the
|
|
3093
|
+
// options lost the focus — and resetting here would drop the active option the key manager has just
|
|
3094
|
+
// set, because `KbqTreeOption.hasFocus` is cleared synchronously but only raised a microtask later, so
|
|
3095
|
+
// `hasFocusedOption()` reports nothing focused for the whole move. Only a blur of the option the
|
|
3096
|
+
// key manager still points at is the focus actually leaving the options.
|
|
3097
|
+
this.optionBlurEvents.subscribe(({ option }) => {
|
|
3098
|
+
if (option === this.keyManager.activeItem && !this.hasFocusedOption() && this.resetFocusedItemOnBlur) {
|
|
3099
|
+
this.keyManager.setActiveItem(-1);
|
|
3100
|
+
}
|
|
3101
|
+
});
|
|
2000
3102
|
}
|
|
2001
3103
|
/**
|
|
2002
3104
|
* Utility to ensure all indexes are valid.
|
|
3105
|
+
*
|
|
2003
3106
|
* @param index The index to be checked.
|
|
2004
3107
|
* @returns True if the index is valid for our list of options.
|
|
2005
3108
|
*/
|
|
@@ -2010,9 +3113,6 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
2010
3113
|
hasFocusedOption() {
|
|
2011
3114
|
return this.renderedOptions.some((option) => option.hasFocus);
|
|
2012
3115
|
}
|
|
2013
|
-
markOptionsForCheck() {
|
|
2014
|
-
this.renderedOptions.forEach((option) => option.markForCheck());
|
|
2015
|
-
}
|
|
2016
3116
|
updateOptionsFocus() {
|
|
2017
3117
|
this.renderedOptions.filter((option) => option.hasFocus).forEach((option) => (option.hasFocus = false));
|
|
2018
3118
|
}
|
|
@@ -2025,28 +3125,27 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
2025
3125
|
}
|
|
2026
3126
|
return $event.relatedTarget.classList.contains('kbq-tree-option');
|
|
2027
3127
|
}
|
|
2028
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2029
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3128
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeSelection, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3129
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: KbqTreeSelection, isStandalone: true, selector: "kbq-tree-selection", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, autoSelectInput: { classPropertyName: "autoSelectInput", publicName: "autoSelect", isSignal: true, isRequired: false, transformFunction: null }, multipleInput: { classPropertyName: "multipleInput", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, noUnselectLastInput: { classPropertyName: "noUnselectLastInput", publicName: "noUnselectLast", isSignal: true, isRequired: false, transformFunction: null }, typeAheadInput: { classPropertyName: "typeAheadInput", publicName: "typeAhead", isSignal: true, isRequired: false, transformFunction: null }, selectAllToggle: { classPropertyName: "selectAllToggle", publicName: "selectAllToggle", isSignal: true, isRequired: false, transformFunction: null }, selectAllInput: { classPropertyName: "selectAllInput", publicName: "selectAll", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, tabIndexInput: { classPropertyName: "tabIndexInput", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, selectAllHandlerInput: { classPropertyName: "selectAllHandlerInput", publicName: "selectAllHandler", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { navigationChange: "navigationChange", selectionChangeOutput: "selectionChange", selectAllChange: "selectAllChange", onSelectAll: "onSelectAll", copyChangeOutput: "copyChange", onCopyOutput: "onCopy" }, host: { attributes: { "role": "tree" }, listeners: { "focus": "focus($event)", "keydown": "onKeyDown($event)", "window:resize": "updateScrollSize()" }, properties: { "attr.tabindex": "tabIndex", "attr.disabled": "disabled || null", "attr.aria-disabled": "disabled || null", "attr.aria-multiselectable": "multiple || null", "attr.aria-label": "resolvedAriaLabel", "attr.aria-labelledby": "resolvedAriaLabelledby", "attr.aria-activedescendant": "keyManager?.activeItem?.id" }, classAttribute: "kbq-tree-selection" }, providers: [
|
|
2030
3130
|
KBQ_SELECTION_TREE_VALUE_ACCESSOR,
|
|
2031
3131
|
{ provide: KBQ_TREE_OPTION_PARENT_COMPONENT, useExisting: KbqTreeSelection },
|
|
2032
3132
|
{ provide: KbqTreeBase, useExisting: KbqTreeSelection }
|
|
2033
|
-
], queries: [{ propertyName: "
|
|
3133
|
+
], queries: [{ propertyName: "unorderedOptionsQuery", predicate: KbqTreeOption, isSignal: true }], viewQueries: [{ propertyName: "selectAllOption", first: true, predicate: KbqTreeOption, descendants: true, isSignal: true }], exportAs: ["kbqTreeSelection"], usesInheritance: true, hostDirectives: [{ directive: i1.KbqStateSaving, inputs: ["useStateSaving", "useStateSaving", "stateSavingKey", "stateSavingKey"] }, { directive: i1.KbqLocaleOverridesDirective, inputs: ["kbqLocaleOverrides", "localeOverrides"] }], ngImport: i0, template: `
|
|
2034
3134
|
@if (showSelectAll) {
|
|
2035
|
-
<!-- Every read of selectAllState re-filters the rendered nodes against the data set,
|
|
2036
|
-
|
|
2037
|
-
|
|
3135
|
+
<!-- Every read of selectAllState re-filters the rendered nodes against the data set, so the
|
|
3136
|
+
two bindings below share one through @let. The row's own aria-checked host binding walks
|
|
3137
|
+
it a second time: Ivy evaluates that binding after this template, and the option reads
|
|
3138
|
+
the state through KBQ_TREE_OPTION_PARENT_COMPONENT rather than from here. -->
|
|
2038
3139
|
@let selectAllCheckboxState = selectAllState;
|
|
2039
3140
|
|
|
3141
|
+
<!-- role and aria-checked come from the option's own host bindings: a host binding runs
|
|
3142
|
+
after the parent template's, so an override here would be the one that loses. -->
|
|
2040
3143
|
<kbq-tree-option
|
|
2041
3144
|
class="kbq-tree-option_select-all"
|
|
2042
3145
|
kbqTreeNodePadding
|
|
2043
3146
|
[selectAllRow]="true"
|
|
2044
3147
|
[selectable]="false"
|
|
2045
3148
|
[class.kbq-selected]="selectAllCheckboxState === 'checked'"
|
|
2046
|
-
[attr.role]="'checkbox'"
|
|
2047
|
-
[attr.aria-checked]="
|
|
2048
|
-
selectAllCheckboxState === 'indeterminate' ? 'mixed' : selectAllCheckboxState === 'checked'
|
|
2049
|
-
"
|
|
2050
3149
|
(click)="toggleSelectAll()"
|
|
2051
3150
|
>
|
|
2052
3151
|
<kbq-pseudo-checkbox [state]="selectAllCheckboxState" />
|
|
@@ -2054,9 +3153,9 @@ class KbqTreeSelection extends KbqTreeBase {
|
|
|
2054
3153
|
</kbq-tree-option>
|
|
2055
3154
|
}
|
|
2056
3155
|
<ng-container kbqTreeNodeOutlet />
|
|
2057
|
-
`, isInline: true, styles: [".kbq-tree-selection{display:block}.kbq-tree-selection:focus{outline:none}.kbq-tree-option{--kbq-option-background: var(--kbq-tree-default-container-background);background:var(--kbq-tree-default-container-background)}.kbq-tree-option .kbq-option-text{color:var(--kbq-tree-default-text-color)}.kbq-tree-option .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-default-action-button-color)}.kbq-tree-option .kbq-option-caption{color:var(--kbq-tree-default-caption-color)}.kbq-tree-option:not(.kbq-disabled):hover,.kbq-tree-option:not(.kbq-disabled).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused{--kbq-option-background: var(--kbq-tree-states-hover-container-background);background:var(--kbq-tree-states-hover-container-background)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-text{color:var(--kbq-tree-states-hover-text-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-caption{color:var(--kbq-tree-states-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled):active,.kbq-tree-option:not(.kbq-disabled).kbq-active{--kbq-option-background: var(--kbq-tree-states-active-container-background);background:var(--kbq-tree-states-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected{--kbq-option-background: var(--kbq-tree-states-selected-container-background);background:var(--kbq-tree-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-text{color:var(--kbq-tree-states-selected-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-caption{color:var(--kbq-tree-states-selected-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-states-selected-hover-container-background);background:var(--kbq-tree-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-text{color:var(--kbq-tree-states-selected-hover-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-caption{color:var(--kbq-tree-states-selected-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);background:var(--kbq-tree-states-selected-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected),.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected{--kbq-option-background: var(--kbq-tree-multiple-states-selected-container-background);background:var(--kbq-tree-multiple-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):hover,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-multiple-states-selected-hover-container-background);background:var(--kbq-tree-multiple-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):active,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);background:var(--kbq-tree-multiple-states-selected-active-container-background)}.kbq-tree-option.kbq-disabled{--kbq-option-background: var(--kbq-tree-states-disabled-container-background);background:var(--kbq-tree-states-disabled-container-background)}.kbq-tree-option.kbq-disabled .kbq-option-text{color:var(--kbq-tree-states-disabled-text-color)}.kbq-tree-option.kbq-disabled .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-disabled-action-button-color)}.kbq-tree-option.kbq-disabled .kbq-option-caption{color:var(--kbq-tree-states-disabled-caption-color)}.kbq-tree-option.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-tree-node-toggle .kbq-icon){color:var(--kbq-states-icon-disabled)}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option.kbq-focused:not(.kbq-action-button-focused){border-color:var(--kbq-tree-states-focused-focus-outline-color)}.kbq-tree-option{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-option-caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-content-gap-vertical: 0px;--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "directive", type: KbqTreeNodeOutlet, selector: "[kbqTreeNodeOutlet]" }, { kind: "component", type: KbqTreeOption, selector: "kbq-tree-option", inputs: ["checkboxThirdState", "disabled", "selectable", "selectAllRow", "showCheckbox"], outputs: ["onSelectionChange"], exportAs: ["kbqTreeOption"] }, { kind: "directive", type: KbqTreeNodePadding, selector: "[kbqTreeNodePadding]", inputs: ["kbqTreeNodePaddingIndent"], exportAs: ["kbqTreeNodePadding"] }, { kind: "component", type: KbqPseudoCheckbox, selector: "kbq-pseudo-checkbox", inputs: ["big", "state", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
3156
|
+
`, isInline: true, styles: [".kbq-tree-selection{display:block}.kbq-tree-selection:focus{outline:none}.kbq-tree-option{--kbq-option-background: var(--kbq-tree-default-container-background);background:var(--kbq-tree-default-container-background)}.kbq-tree-option .kbq-option-text{color:var(--kbq-tree-default-text-color)}.kbq-tree-option .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-default-action-button-color)}.kbq-tree-option .kbq-option-caption{color:var(--kbq-tree-default-caption-color)}.kbq-tree-option:not(.kbq-disabled):hover,.kbq-tree-option:not(.kbq-disabled).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused{--kbq-option-background: var(--kbq-tree-states-hover-container-background);background:var(--kbq-tree-states-hover-container-background)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-text{color:var(--kbq-tree-states-hover-text-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-caption{color:var(--kbq-tree-states-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled):active,.kbq-tree-option:not(.kbq-disabled).kbq-active{--kbq-option-background: var(--kbq-tree-states-active-container-background);background:var(--kbq-tree-states-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected{--kbq-option-background: var(--kbq-tree-states-selected-container-background);background:var(--kbq-tree-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-text{color:var(--kbq-tree-states-selected-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-caption{color:var(--kbq-tree-states-selected-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-states-selected-hover-container-background);background:var(--kbq-tree-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-text{color:var(--kbq-tree-states-selected-hover-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-caption{color:var(--kbq-tree-states-selected-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);background:var(--kbq-tree-states-selected-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected),.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected{--kbq-option-background: var(--kbq-tree-multiple-states-selected-container-background);background:var(--kbq-tree-multiple-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):hover,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-multiple-states-selected-hover-container-background);background:var(--kbq-tree-multiple-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):active,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);background:var(--kbq-tree-multiple-states-selected-active-container-background)}.kbq-tree-option.kbq-disabled{--kbq-option-background: var(--kbq-tree-states-disabled-container-background);background:var(--kbq-tree-states-disabled-container-background)}.kbq-tree-option.kbq-disabled .kbq-option-text{color:var(--kbq-tree-states-disabled-text-color)}.kbq-tree-option.kbq-disabled .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-disabled-action-button-color)}.kbq-tree-option.kbq-disabled .kbq-option-caption{color:var(--kbq-tree-states-disabled-caption-color)}.kbq-tree-option.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-tree-node-toggle .kbq-icon){color:var(--kbq-states-icon-disabled)}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option.kbq-focused:not(.kbq-action-button-focused){border-color:var(--kbq-tree-states-focused-focus-outline-color)}.kbq-tree-option{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-option-caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "directive", type: KbqTreeNodeOutlet, selector: "[kbqTreeNodeOutlet]" }, { kind: "component", type: KbqTreeOption, selector: "kbq-tree-option", inputs: ["checkboxThirdState", "disabled", "selectable", "selectAllRow", "showCheckbox"], outputs: ["selectionChange", "onSelectionChange"], exportAs: ["kbqTreeOption"] }, { kind: "directive", type: KbqTreeNodePadding, selector: "[kbqTreeNodePadding]", inputs: ["kbqTreeNodePaddingIndent"], exportAs: ["kbqTreeNodePadding"] }, { kind: "component", type: KbqPseudoCheckbox, selector: "kbq-pseudo-checkbox", inputs: ["big", "state", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2058
3157
|
}
|
|
2059
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3158
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeSelection, decorators: [{
|
|
2060
3159
|
type: Component,
|
|
2061
3160
|
args: [{ selector: 'kbq-tree-selection', imports: [
|
|
2062
3161
|
KbqTreeNodeOutlet,
|
|
@@ -2065,21 +3164,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
2065
3164
|
KbqPseudoCheckbox
|
|
2066
3165
|
], template: `
|
|
2067
3166
|
@if (showSelectAll) {
|
|
2068
|
-
<!-- Every read of selectAllState re-filters the rendered nodes against the data set,
|
|
2069
|
-
|
|
2070
|
-
|
|
3167
|
+
<!-- Every read of selectAllState re-filters the rendered nodes against the data set, so the
|
|
3168
|
+
two bindings below share one through @let. The row's own aria-checked host binding walks
|
|
3169
|
+
it a second time: Ivy evaluates that binding after this template, and the option reads
|
|
3170
|
+
the state through KBQ_TREE_OPTION_PARENT_COMPONENT rather than from here. -->
|
|
2071
3171
|
@let selectAllCheckboxState = selectAllState;
|
|
2072
3172
|
|
|
3173
|
+
<!-- role and aria-checked come from the option's own host bindings: a host binding runs
|
|
3174
|
+
after the parent template's, so an override here would be the one that loses. -->
|
|
2073
3175
|
<kbq-tree-option
|
|
2074
3176
|
class="kbq-tree-option_select-all"
|
|
2075
3177
|
kbqTreeNodePadding
|
|
2076
3178
|
[selectAllRow]="true"
|
|
2077
3179
|
[selectable]="false"
|
|
2078
3180
|
[class.kbq-selected]="selectAllCheckboxState === 'checked'"
|
|
2079
|
-
[attr.role]="'checkbox'"
|
|
2080
|
-
[attr.aria-checked]="
|
|
2081
|
-
selectAllCheckboxState === 'indeterminate' ? 'mixed' : selectAllCheckboxState === 'checked'
|
|
2082
|
-
"
|
|
2083
3181
|
(click)="toggleSelectAll()"
|
|
2084
3182
|
>
|
|
2085
3183
|
<kbq-pseudo-checkbox [state]="selectAllCheckboxState" />
|
|
@@ -2093,39 +3191,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
2093
3191
|
{ provide: KbqTreeBase, useExisting: KbqTreeSelection }
|
|
2094
3192
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
2095
3193
|
class: 'kbq-tree-selection',
|
|
3194
|
+
role: 'tree',
|
|
2096
3195
|
'[attr.tabindex]': 'tabIndex',
|
|
2097
3196
|
'[attr.disabled]': 'disabled || null',
|
|
2098
|
-
'
|
|
3197
|
+
'[attr.aria-disabled]': 'disabled || null',
|
|
3198
|
+
'[attr.aria-multiselectable]': 'multiple || null',
|
|
3199
|
+
'[attr.aria-label]': 'resolvedAriaLabel',
|
|
3200
|
+
'[attr.aria-labelledby]': 'resolvedAriaLabelledby',
|
|
3201
|
+
// The active option takes real DOM focus (`KbqTreeOption.focus`) and is advertised here on top
|
|
3202
|
+
// of that, so an AT that follows either model reports the same row.
|
|
3203
|
+
'[attr.aria-activedescendant]': 'keyManager?.activeItem?.id',
|
|
2099
3204
|
'(focus)': 'focus($event)',
|
|
2100
3205
|
'(keydown)': 'onKeyDown($event)',
|
|
2101
3206
|
'(window:resize)': 'updateScrollSize()'
|
|
2102
|
-
}, exportAs: 'kbqTreeSelection', styles: [".kbq-tree-selection{display:block}.kbq-tree-selection:focus{outline:none}.kbq-tree-option{--kbq-option-background: var(--kbq-tree-default-container-background);background:var(--kbq-tree-default-container-background)}.kbq-tree-option .kbq-option-text{color:var(--kbq-tree-default-text-color)}.kbq-tree-option .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-default-action-button-color)}.kbq-tree-option .kbq-option-caption{color:var(--kbq-tree-default-caption-color)}.kbq-tree-option:not(.kbq-disabled):hover,.kbq-tree-option:not(.kbq-disabled).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused{--kbq-option-background: var(--kbq-tree-states-hover-container-background);background:var(--kbq-tree-states-hover-container-background)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-text{color:var(--kbq-tree-states-hover-text-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-caption{color:var(--kbq-tree-states-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled):active,.kbq-tree-option:not(.kbq-disabled).kbq-active{--kbq-option-background: var(--kbq-tree-states-active-container-background);background:var(--kbq-tree-states-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected{--kbq-option-background: var(--kbq-tree-states-selected-container-background);background:var(--kbq-tree-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-text{color:var(--kbq-tree-states-selected-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-caption{color:var(--kbq-tree-states-selected-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-states-selected-hover-container-background);background:var(--kbq-tree-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-text{color:var(--kbq-tree-states-selected-hover-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-caption{color:var(--kbq-tree-states-selected-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);background:var(--kbq-tree-states-selected-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected),.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected{--kbq-option-background: var(--kbq-tree-multiple-states-selected-container-background);background:var(--kbq-tree-multiple-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):hover,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-multiple-states-selected-hover-container-background);background:var(--kbq-tree-multiple-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):active,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);background:var(--kbq-tree-multiple-states-selected-active-container-background)}.kbq-tree-option.kbq-disabled{--kbq-option-background: var(--kbq-tree-states-disabled-container-background);background:var(--kbq-tree-states-disabled-container-background)}.kbq-tree-option.kbq-disabled .kbq-option-text{color:var(--kbq-tree-states-disabled-text-color)}.kbq-tree-option.kbq-disabled .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-disabled-action-button-color)}.kbq-tree-option.kbq-disabled .kbq-option-caption{color:var(--kbq-tree-states-disabled-caption-color)}.kbq-tree-option.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-tree-node-toggle .kbq-icon){color:var(--kbq-states-icon-disabled)}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option.kbq-focused:not(.kbq-action-button-focused){border-color:var(--kbq-tree-states-focused-focus-outline-color)}.kbq-tree-option{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-option-caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-content-gap-vertical: 0px;--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"] }]
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
args: [KbqTreeNodeOutlet, { static: true }]
|
|
2106
|
-
|
|
2107
|
-
type: ContentChildren,
|
|
2108
|
-
args: [KbqTreeOption]
|
|
2109
|
-
}], treeControl: [{
|
|
2110
|
-
type: Input
|
|
2111
|
-
}], navigationChange: [{ type: i0.Output, args: ["navigationChange"] }], selectionChange: [{
|
|
2112
|
-
type: Output
|
|
2113
|
-
}], onSelectAll: [{ type: i0.Output, args: ["onSelectAll"] }], onCopy: [{
|
|
2114
|
-
type: Output
|
|
2115
|
-
}], autoSelect: [{
|
|
2116
|
-
type: Input
|
|
2117
|
-
}], noUnselectLast: [{
|
|
2118
|
-
type: Input
|
|
2119
|
-
}], selectAllToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllToggle", required: false }] }], selectAll: [{
|
|
2120
|
-
type: Input,
|
|
2121
|
-
args: [{ transform: booleanAttribute }]
|
|
2122
|
-
}], disabled: [{
|
|
2123
|
-
type: Input
|
|
2124
|
-
}], tabIndex: [{
|
|
2125
|
-
type: Input
|
|
2126
|
-
}], selectAllHandler: [{
|
|
2127
|
-
type: Input
|
|
2128
|
-
}] } });
|
|
3207
|
+
}, hostDirectives: [
|
|
3208
|
+
{ directive: KbqStateSaving, inputs: ['useStateSaving', 'stateSavingKey'] },
|
|
3209
|
+
{ directive: KbqLocaleOverridesDirective, inputs: ['kbqLocaleOverrides: localeOverrides'] }
|
|
3210
|
+
], exportAs: 'kbqTreeSelection', styles: [".kbq-tree-selection{display:block}.kbq-tree-selection:focus{outline:none}.kbq-tree-option{--kbq-option-background: var(--kbq-tree-default-container-background);background:var(--kbq-tree-default-container-background)}.kbq-tree-option .kbq-option-text{color:var(--kbq-tree-default-text-color)}.kbq-tree-option .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-default-action-button-color)}.kbq-tree-option .kbq-option-caption{color:var(--kbq-tree-default-caption-color)}.kbq-tree-option:not(.kbq-disabled):hover,.kbq-tree-option:not(.kbq-disabled).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused{--kbq-option-background: var(--kbq-tree-states-hover-container-background);background:var(--kbq-tree-states-hover-container-background)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-text{color:var(--kbq-tree-states-hover-text-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled):hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-hovered .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-action-button-focused .kbq-option-caption{color:var(--kbq-tree-states-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled):active,.kbq-tree-option:not(.kbq-disabled).kbq-active{--kbq-option-background: var(--kbq-tree-states-active-container-background);background:var(--kbq-tree-states-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected{--kbq-option-background: var(--kbq-tree-states-selected-container-background);background:var(--kbq-tree-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-text{color:var(--kbq-tree-states-selected-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected .kbq-option-caption{color:var(--kbq-tree-states-selected-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-states-selected-hover-container-background);background:var(--kbq-tree-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-text,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-text{color:var(--kbq-tree-states-selected-hover-text-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-action .kbq-icon.kbq-empty,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-selected-hover-action-button-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:hover .kbq-option-caption,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-hovered .kbq-option-caption{color:var(--kbq-tree-states-selected-hover-caption-color)}.kbq-tree-option:not(.kbq-disabled).kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);background:var(--kbq-tree-states-selected-active-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected),.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected{--kbq-option-background: var(--kbq-tree-multiple-states-selected-container-background);background:var(--kbq-tree-multiple-states-selected-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):hover,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-hovered,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:hover,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-hovered{--kbq-option-background: var(--kbq-tree-multiple-states-selected-hover-container-background);background:var(--kbq-tree-multiple-states-selected-hover-container-background)}.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected):active,.kbq-tree-option:not(.kbq-disabled).kbq-checked:not(.kbq-selected).kbq-active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected:active,.kbq-tree-option:not(.kbq-disabled).kbq-tree-option_multiple.kbq-selected.kbq-active{--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);background:var(--kbq-tree-multiple-states-selected-active-container-background)}.kbq-tree-option.kbq-disabled{--kbq-option-background: var(--kbq-tree-states-disabled-container-background);background:var(--kbq-tree-states-disabled-container-background)}.kbq-tree-option.kbq-disabled .kbq-option-text{color:var(--kbq-tree-states-disabled-text-color)}.kbq-tree-option.kbq-disabled .kbq-option-action .kbq-icon.kbq-empty{color:var(--kbq-tree-states-disabled-action-button-color)}.kbq-tree-option.kbq-disabled .kbq-option-caption{color:var(--kbq-tree-states-disabled-caption-color)}.kbq-tree-option.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-tree-node-toggle .kbq-icon){color:var(--kbq-states-icon-disabled)}.kbq-tree-selection.cdk-keyboard-focused .kbq-tree-option.kbq-focused:not(.kbq-action-button-focused){border-color:var(--kbq-tree-states-focused-focus-outline-color)}.kbq-tree-option{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-option-caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}\n", ".kbq-tree,.kbq-tree-selection{--kbq-tree-size-indent-level: var(--kbq-size-xxl);--kbq-tree-size-container-padding-right: var(--kbq-size-s);--kbq-tree-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-tree-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-tree-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-tree-size-text-padding-vertical: var(--kbq-size-3xs);--kbq-tree-option-border-radius: var(--kbq-size-border-radius);--kbq-tree-default-container-background: transparent;--kbq-tree-default-text-color: var(--kbq-foreground-contrast);--kbq-tree-default-icon-color: var(--kbq-icon-contrast);--kbq-tree-default-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-tree-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-tree-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-tree-states-selected-container-background: var(--kbq-background-theme-less);--kbq-tree-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-tree-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-tree-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-tree-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-tree-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-tree-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-tree-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-tree-states-selected-hover-tree-toggle-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-action-button-color: var(--kbq-icon-contrast-fade);--kbq-tree-states-selected-hover-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-tree-states-disabled-container-background: transparent;--kbq-tree-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-tree-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-tree-toggle-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-action-button-color: var(--kbq-states-icon-disabled);--kbq-tree-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"] }]
|
|
3211
|
+
}], ctorParameters: () => [], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], selectAllOption: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqTreeOption), { isSignal: true }] }], unorderedOptionsQuery: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KbqTreeOption), { isSignal: true }] }], navigationChange: [{ type: i0.Output, args: ["navigationChange"] }], selectionChangeOutput: [{ type: i0.Output, args: ["selectionChange"] }], selectAllChange: [{ type: i0.Output, args: ["selectAllChange"] }], onSelectAll: [{ type: i0.Output, args: ["onSelectAll"] }], copyChangeOutput: [{ type: i0.Output, args: ["copyChange"] }], onCopyOutput: [{ type: i0.Output, args: ["onCopy"] }], autoSelectInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoSelect", required: false }] }], multipleInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], noUnselectLastInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "noUnselectLast", required: false }] }], typeAheadInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeAhead", required: false }] }], selectAllToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllToggle", required: false }] }], selectAllInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAll", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], tabIndexInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], selectAllHandlerInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllHandler", required: false }] }] } });
|
|
2129
3212
|
|
|
2130
3213
|
const KBQ_TREE_DIRECTIVES = [
|
|
2131
3214
|
KbqTreeNodeOutlet,
|
|
@@ -2139,8 +3222,8 @@ const KBQ_TREE_DIRECTIVES = [
|
|
|
2139
3222
|
KbqTreeNodeToggleDirective
|
|
2140
3223
|
];
|
|
2141
3224
|
class KbqTreeModule {
|
|
2142
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2143
|
-
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
3225
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
3226
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeModule, imports: [KbqPseudoCheckboxModule,
|
|
2144
3227
|
KbqIconModule,
|
|
2145
3228
|
KbqActionContainer, KbqTreeNodeOutlet,
|
|
2146
3229
|
KbqTreeNodeDef,
|
|
@@ -2159,13 +3242,13 @@ class KbqTreeModule {
|
|
|
2159
3242
|
KbqTreeOption,
|
|
2160
3243
|
KbqTreeNodeToggleComponent,
|
|
2161
3244
|
KbqTreeNodeToggleDirective] }); }
|
|
2162
|
-
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
3245
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeModule, providers: [{ provide: AsyncScheduler, useValue: asyncScheduler }], imports: [KbqPseudoCheckboxModule,
|
|
2163
3246
|
KbqIconModule,
|
|
2164
3247
|
KbqActionContainer, KbqTreeSelection,
|
|
2165
3248
|
KbqTreeOption,
|
|
2166
3249
|
KbqTreeNodeToggleComponent] }); }
|
|
2167
3250
|
}
|
|
2168
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3251
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTreeModule, decorators: [{
|
|
2169
3252
|
type: NgModule,
|
|
2170
3253
|
args: [{
|
|
2171
3254
|
imports: [
|