@koobiq/components 20.4.2 → 21.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +755 -601
- 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 +2810 -2538
- 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 +366 -136
- 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 +719 -488
- package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree.mjs +1506 -558
- 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 +399 -7
- package/schematics/migrations/accordion-state-saving-default/README.md +60 -0
- package/schematics/migrations/accordion-state-saving-default/data.js +75 -0
- package/schematics/migrations/accordion-state-saving-default/index.js +60 -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.js +47 -0
- package/schematics/migrations/actions-panel-overlay-container/index.js +54 -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 +3 -0
- package/schematics/migrations/alert-signals/index.js +70 -203
- package/schematics/migrations/angular-animations-removal/README.md +46 -0
- package/schematics/migrations/angular-animations-removal/data.js +150 -0
- package/schematics/migrations/angular-animations-removal/index.js +20 -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.js +136 -0
- package/schematics/migrations/app-switcher-signals/index.js +365 -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 +1 -1
- package/schematics/migrations/autocomplete-signals/README.md +92 -0
- package/schematics/migrations/autocomplete-signals/data.js +149 -0
- package/schematics/migrations/autocomplete-signals/index.js +706 -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.js +109 -0
- package/schematics/migrations/badge-signals/index.js +693 -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.js +136 -0
- package/schematics/migrations/button-state-and-styles/index.js +220 -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.js +106 -0
- package/schematics/migrations/button-supported-colors/index.js +260 -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.js +200 -0
- package/schematics/migrations/button-toggle-signals-and-aria/index.js +496 -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.js +88 -0
- package/schematics/migrations/button-truncation/index.js +269 -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.js +114 -0
- package/schematics/migrations/checkbox-signals/index.js +634 -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.js +101 -0
- package/schematics/migrations/clamped-text-disclosure/index.js +59 -0
- package/schematics/migrations/clamped-text-disclosure/schema.json +15 -0
- package/schematics/migrations/code-block-signals/README.md +84 -0
- package/schematics/migrations/code-block-signals/data.js +121 -0
- package/schematics/migrations/code-block-signals/index.js +700 -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.js +131 -0
- package/schematics/migrations/color-signals/index.js +19 -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.js +27 -0
- package/schematics/migrations/core-mixins-removal/index.js +17 -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 +1 -1
- package/schematics/migrations/datepicker-signals/README.md +24 -0
- package/schematics/migrations/datepicker-signals/data.js +49 -0
- package/schematics/migrations/datepicker-signals/index.js +17 -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 +1 -1
- package/schematics/migrations/design-tokens-v4/README.md +75 -0
- package/schematics/migrations/design-tokens-v4/index.js +59 -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.js +62 -0
- package/schematics/migrations/divider-signals-and-aria/index.js +211 -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.js +85 -0
- package/schematics/migrations/dl-attribute-coercion/index.js +161 -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.js +44 -0
- package/schematics/migrations/dl-standalone-names/index.js +321 -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.js +84 -0
- package/schematics/migrations/dropdown-demote-overlay/index.js +288 -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.js +152 -0
- package/schematics/migrations/dropdown-signals/index.js +19 -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.js +85 -0
- package/schematics/migrations/empty-state-error-color/index.js +71 -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 +1 -1
- package/schematics/migrations/file-upload-cva-and-primitives/README.md +70 -0
- package/schematics/migrations/file-upload-cva-and-primitives/data.js +97 -0
- package/schematics/migrations/file-upload-cva-and-primitives/index.js +60 -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.js +20 -0
- package/schematics/migrations/file-upload-deprecated-outputs/index.js +70 -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.js +151 -0
- package/schematics/migrations/filter-bar-rename-action/index.js +177 -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 +1 -2
- package/schematics/migrations/filter-bar-signals/index.js +100 -195
- package/schematics/migrations/filter-bar-state-saving-default/README.md +53 -0
- package/schematics/migrations/filter-bar-state-saving-default/data.js +87 -0
- package/schematics/migrations/filter-bar-state-saving-default/index.js +61 -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.js +58 -0
- package/schematics/migrations/flag-inner-html/index.js +61 -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.js +288 -0
- package/schematics/migrations/form-field-signals/index.js +382 -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.js +97 -0
- package/schematics/migrations/icon-semantics-and-api/index.js +64 -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 +1 -1
- package/schematics/migrations/inline-edit-a11y-and-types/README.md +82 -0
- package/schematics/migrations/inline-edit-a11y-and-types/data.js +117 -0
- package/schematics/migrations/inline-edit-a11y-and-types/index.js +97 -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.js +135 -0
- package/schematics/migrations/input-number-surface/index.js +292 -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.js +30 -0
- package/schematics/migrations/input-signals/index.js +17 -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.js +19 -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.js +116 -0
- package/schematics/migrations/link-signals/index.js +415 -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.js +35 -0
- package/schematics/migrations/list-signals/index.js +17 -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.js +74 -0
- package/schematics/migrations/list-tree-multiple-input/index.js +221 -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.js +101 -0
- package/schematics/migrations/loader-overlay-signals/index.js +697 -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 +1 -1
- package/schematics/migrations/locale-configuration-providers/README.md +163 -0
- package/schematics/migrations/locale-configuration-providers/data.js +257 -0
- package/schematics/migrations/locale-configuration-providers/index.js +294 -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.js +42 -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.js +79 -0
- package/schematics/migrations/markdown-signals/index.js +639 -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.js +110 -0
- package/schematics/migrations/modal-dialog-semantics/index.js +58 -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.js +132 -0
- package/schematics/migrations/modal-signals/index.js +19 -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.js +198 -0
- package/schematics/migrations/navbar-signals-and-aria/index.js +568 -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 +1 -1
- package/schematics/migrations/notification-center-signals/README.md +67 -0
- package/schematics/migrations/notification-center-signals/data.js +66 -0
- package/schematics/migrations/notification-center-signals/index.js +61 -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.js +86 -0
- package/schematics/migrations/option-signals/index.js +19 -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.js +61 -0
- package/schematics/migrations/popover-leave-delay/index.js +54 -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.js +76 -0
- package/schematics/migrations/progress-bar-percentage-and-aria/index.js +58 -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.js +83 -0
- package/schematics/migrations/progress-spinner-signals/index.js +694 -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.js +70 -0
- package/schematics/migrations/query-list-signals/index.js +17 -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.js +163 -0
- package/schematics/migrations/radio-signals-and-aria/index.js +39 -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.js +45 -0
- package/schematics/migrations/read-state-dwell-handlers/index.js +215 -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.js +20 -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.js +99 -0
- package/schematics/migrations/select-signal-inputs/index.js +57 -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.js +111 -0
- package/schematics/migrations/sidepanel-non-modal-behavior/index.js +57 -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.js +69 -0
- package/schematics/migrations/signal-inputs-subclasses/index.js +17 -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.js +53 -0
- package/schematics/migrations/split-button-optional-disabled/index.js +57 -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.js +20 -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.js +88 -0
- package/schematics/migrations/state-saving-default/index.js +62 -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.js +66 -0
- package/schematics/migrations/table-cell-content/index.js +66 -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.js +139 -0
- package/schematics/migrations/tabs-signals-and-aria/index.js +65 -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.js +42 -0
- package/schematics/migrations/tag-list-cleaner/index.js +196 -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.js +190 -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.js +103 -0
- package/schematics/migrations/tags-signals/index.js +673 -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.js +121 -0
- package/schematics/migrations/textarea-signals/index.js +379 -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.js +139 -0
- package/schematics/migrations/time-range-title-for/index.js +163 -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.js +82 -0
- package/schematics/migrations/timepicker-signals/index.js +709 -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.js +101 -0
- package/schematics/migrations/timezone-grouping-utils/index.js +64 -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.js +69 -0
- package/schematics/migrations/title-encapsulation/index.js +57 -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.js +79 -0
- package/schematics/migrations/toast-stack-and-defaults/index.js +53 -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.js +89 -0
- package/schematics/migrations/tooltip-pointer-events-and-types/index.js +60 -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.js +56 -0
- package/schematics/migrations/top-bar-container-selectors/index.js +84 -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.js +106 -0
- package/schematics/migrations/tree-select-signals/index.js +58 -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.js +123 -0
- package/schematics/migrations/tree-signals/index.js +54 -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.js +78 -0
- package/schematics/migrations/tree-state-saving-default/index.js +60 -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.js +78 -0
- package/schematics/migrations/username-pipe-injection/index.js +58 -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 +124 -77
- package/schematics/migrations/v20-upgrade/index.js +6 -213
- package/schematics/migrations/v21-upgrade/README.md +271 -0
- package/schematics/migrations/v21-upgrade/data.js +1371 -0
- package/schematics/migrations/v21-upgrade/index.js +94 -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.js +29 -0
- package/schematics/migrations/zoneless-change-detection/index.js +20 -0
- package/schematics/migrations/zoneless-change-detection/schema.json +15 -0
- package/schematics/migrations.json +392 -2
- package/schematics/ng-add/index.js +515 -14
- package/schematics/ng-add/schema.json +15 -0
- package/schematics/utils/deprecated-path-migration.js +61 -0
- package/schematics/utils/package-config.js +9 -105
- 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} +114 -79
- 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 +667 -0
- package/types/koobiq-components-tree.d.ts +1290 -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/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/{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,29 +1,29 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, output, ViewEncapsulation, ChangeDetectionStrategy, Component, inject,
|
|
2
|
+
import { input, output, ViewEncapsulation, ChangeDetectionStrategy, Component, inject, ChangeDetectorRef, viewChild, forwardRef, InjectionToken, ElementRef, Renderer2, signal, EventEmitter, computed, booleanAttribute, linkedSignal, effect, untracked, Directive, Injector, ViewContainerRef, afterNextRender, NgModule } from '@angular/core';
|
|
3
3
|
import { TitleCasePipe, DOCUMENT } from '@angular/common';
|
|
4
4
|
import * as i1 from '@koobiq/components/button';
|
|
5
5
|
import { KbqButtonModule } from '@koobiq/components/button';
|
|
6
6
|
import * as i4 from '@koobiq/components/core';
|
|
7
|
-
import { DateAdapter, KbqOptionModule, KbqDateTimezoneService,
|
|
7
|
+
import { DateAdapter, kbqInjectA11yLocaleConfiguration, KbqOptionModule, KbqDateTimezoneService, ruRULocaleData, KBQ_DEFAULT_LOCALE_DATA_FACTORY, KBQ_DATE_LOCALE, KBQ_DATE_FORMATS, kbqLocaleConfigurationOverrideProvider, validationTooltipShowDelay, validationTooltipHideDelay, KbqLocaleOverridesDirective, KbqErrorStateTracker, ErrorStateMatcher, TAB, SPACE, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, HOME, PAGE_UP, END, PAGE_DOWN, ESCAPE, isLetterKey, hasModifierKey, isVerticalMovement, isHorizontalMovement, DELETE, BACKSPACE, kbqRevealSelection, kbqSetSelectionRange, kbqSiblingPopupProvider, kbqAnimationsDisabled, kbqAfterAnimations, KBQ_OVERLAY_LAYERS, KBQ_CONNECTED_OVERLAY_BELOW_CLASS, KBQ_CONNECTED_OVERLAY_ABOVE_CLASS } from '@koobiq/components/core';
|
|
8
8
|
import * as i2 from '@koobiq/components/icon';
|
|
9
9
|
import { KbqIconModule } from '@koobiq/components/icon';
|
|
10
10
|
import * as i3 from '@koobiq/components/select';
|
|
11
11
|
import { KbqSelectModule } from '@koobiq/components/select';
|
|
12
12
|
import { Subject, Subscription, merge } from 'rxjs';
|
|
13
13
|
import { takeUntilDestroyed, toObservable, outputToObservable } from '@angular/core/rxjs-interop';
|
|
14
|
-
import {
|
|
14
|
+
import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormGroupDirective, NgForm, Validators } from '@angular/forms';
|
|
15
|
+
import { KBQ_FORM_FIELD, KbqFormFieldControl, KbqFormFieldModule } from '@koobiq/components/form-field';
|
|
16
|
+
import { A11yModule } from '@angular/cdk/a11y';
|
|
17
|
+
import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
|
|
18
|
+
import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
|
|
15
19
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
16
|
-
import {
|
|
17
|
-
import { KbqFormFieldControl, KBQ_FORM_FIELD, KbqFormFieldModule } from '@koobiq/components/form-field';
|
|
20
|
+
import { filter, switchMap, map, take } from 'rxjs/operators';
|
|
18
21
|
import { Directionality } from '@angular/cdk/bidi';
|
|
19
|
-
import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
|
|
20
22
|
import { _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';
|
|
21
|
-
import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
|
|
22
|
-
import { take, filter, switchMap, map } from 'rxjs/operators';
|
|
23
|
-
import { A11yModule } from '@angular/cdk/a11y';
|
|
24
23
|
|
|
25
24
|
/**
|
|
26
25
|
* An internal class that represents the data corresponding to a single calendar cell.
|
|
26
|
+
*
|
|
27
27
|
* @docs-private
|
|
28
28
|
*/
|
|
29
29
|
class KbqCalendarCell {
|
|
@@ -36,27 +36,28 @@ class KbqCalendarCell {
|
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* An internal component used to display calendar data in a table.
|
|
39
|
+
*
|
|
39
40
|
* @docs-private
|
|
40
41
|
*/
|
|
41
42
|
class KbqCalendarBody {
|
|
42
43
|
constructor() {
|
|
43
44
|
/** The cells to display in the table. */
|
|
44
|
-
this.rows = input(undefined, ...(ngDevMode ? [{ debugName: "rows" }] : []));
|
|
45
|
+
this.rows = input(undefined, ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
45
46
|
/** The value in the table that corresponds to today. */
|
|
46
|
-
this.todayValue = input(undefined, ...(ngDevMode ? [{ debugName: "todayValue" }] : []));
|
|
47
|
+
this.todayValue = input(undefined, ...(ngDevMode ? [{ debugName: "todayValue" }] : /* istanbul ignore next */ []));
|
|
47
48
|
/** The value in the table that is currently selected. */
|
|
48
|
-
this.selectedValue = input(undefined, ...(ngDevMode ? [{ debugName: "selectedValue" }] : []));
|
|
49
|
+
this.selectedValue = input(undefined, ...(ngDevMode ? [{ debugName: "selectedValue" }] : /* istanbul ignore next */ []));
|
|
49
50
|
/** The minimum number of free cells needed to fit the label in the first row. */
|
|
50
|
-
this.labelMinRequiredCells = input(undefined, ...(ngDevMode ? [{ debugName: "labelMinRequiredCells" }] : []));
|
|
51
|
+
this.labelMinRequiredCells = input(undefined, ...(ngDevMode ? [{ debugName: "labelMinRequiredCells" }] : /* istanbul ignore next */ []));
|
|
51
52
|
/** The number of columns in the table. */
|
|
52
|
-
this.numCols = input(7, ...(ngDevMode ? [{ debugName: "numCols" }] : []));
|
|
53
|
+
this.numCols = input(7, ...(ngDevMode ? [{ debugName: "numCols" }] : /* istanbul ignore next */ []));
|
|
53
54
|
/** The cell number of the active cell in the table. */
|
|
54
|
-
this.activeCell = input(0, ...(ngDevMode ? [{ debugName: "activeCell" }] : []));
|
|
55
|
+
this.activeCell = input(0, ...(ngDevMode ? [{ debugName: "activeCell" }] : /* istanbul ignore next */ []));
|
|
55
56
|
/**
|
|
56
57
|
* The aspect ratio (width / height) to use for the cells in the table. This aspect ratio will be
|
|
57
58
|
* maintained even as the table resizes.
|
|
58
59
|
*/
|
|
59
|
-
this.cellAspectRatio = input(1, ...(ngDevMode ? [{ debugName: "cellAspectRatio" }] : []));
|
|
60
|
+
this.cellAspectRatio = input(1, ...(ngDevMode ? [{ debugName: "cellAspectRatio" }] : /* istanbul ignore next */ []));
|
|
60
61
|
/** Emits when a new value is selected. */
|
|
61
62
|
this.selectedValueChange = output();
|
|
62
63
|
}
|
|
@@ -90,14 +91,14 @@ class KbqCalendarBody {
|
|
|
90
91
|
}
|
|
91
92
|
return cellNumber === this.activeCell();
|
|
92
93
|
}
|
|
93
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
94
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
94
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqCalendarBody, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
95
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: KbqCalendarBody, isStandalone: true, selector: "[kbq-calendar-body]", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, todayValue: { classPropertyName: "todayValue", publicName: "todayValue", isSignal: true, isRequired: false, transformFunction: null }, selectedValue: { classPropertyName: "selectedValue", publicName: "selectedValue", isSignal: true, isRequired: false, transformFunction: null }, labelMinRequiredCells: { classPropertyName: "labelMinRequiredCells", publicName: "labelMinRequiredCells", isSignal: true, isRequired: false, transformFunction: null }, numCols: { classPropertyName: "numCols", publicName: "numCols", isSignal: true, isRequired: false, transformFunction: null }, activeCell: { classPropertyName: "activeCell", publicName: "activeCell", isSignal: true, isRequired: false, transformFunction: null }, cellAspectRatio: { classPropertyName: "cellAspectRatio", publicName: "cellAspectRatio", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedValueChange: "selectedValueChange" }, host: { classAttribute: "kbq-calendar__body" }, exportAs: ["kbqCalendarBody"], usesOnChanges: true, ngImport: i0, template: "<!-- Create the first row separately so we can include a special spacer cell. -->\n@for (row of rows(); track $index; let rowIndex = $index) {\n <tr>\n <!-- We mark this cell as aria-hidden so it doesn't get read out as one of the days in the week.\n The aspect ratio of the table cells is maintained by setting the top and bottom padding as a\n percentage of the width (a variant of the trick described here:\n https://www.w3schools.com/howto/howto_css_aspect_ratio.asp). -->\n @if (rowIndex === 0 && firstRowOffset) {\n <td class=\"kbq-calendar__body-label\" [attr.colspan]=\"firstRowOffset\"></td>\n }\n @for (item of row; track item.displayValue; let colIndex = $index) {\n <td\n class=\"kbq-calendar__body-cell\"\n [class.kbq-calendar__body_active]=\"isActiveCell(rowIndex, colIndex)\"\n [class]=\"item.cssClasses!\"\n [style.paddingBottom]=\"cellPadding\"\n [style.paddingTop]=\"cellPadding\"\n [style.width]=\"cellWidth\"\n [tabindex]=\"-1\"\n (click)=\"cellClicked(item)\"\n >\n <div\n class=\"kbq-calendar__body-cell-content\"\n [class.kbq-calendar__body-today]=\"todayValue() === item.value\"\n [class.kbq-disabled]=\"!item.enabled\"\n [class.kbq-selected]=\"selectedValue() === item.value\"\n >\n {{ item.displayValue }}\n </div>\n </td>\n }\n </tr>\n}\n", styles: [".kbq-calendar__body-cell{position:relative;height:0;line-height:0;text-align:center;outline:none;cursor:pointer;padding:0}.kbq-disabled{cursor:default}.kbq-calendar__body-cell-content{display:flex;align-items:center;justify-content:center;box-sizing:border-box;height:32px;line-height:1;border-radius:var(--kbq-datepicker-size-grid-cell-border-radius)}@supports (corner-shape: squircle){.kbq-calendar__body-cell-content{corner-shape:squircle;border-radius:clamp(var(--kbq-datepicker-size-grid-cell-border-radius) * 1.85,var(--kbq-datepicker-size-grid-cell-border-radius) * 2.3 - 3.6px,var(--kbq-datepicker-size-grid-cell-border-radius) * 2)}}.kbq-calendar__body-cell-content{margin-bottom:var(--kbq-datepicker-size-grid-content-gap-vertical)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
95
96
|
}
|
|
96
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
97
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqCalendarBody, decorators: [{
|
|
97
98
|
type: Component,
|
|
98
99
|
args: [{ selector: '[kbq-calendar-body]', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
99
100
|
class: 'kbq-calendar__body'
|
|
100
|
-
}, exportAs: 'kbqCalendarBody', template: "<!-- Create the first row separately so we can include a special spacer cell. -->\n@for (row of rows(); track $index; let rowIndex = $index) {\n <tr>\n <!-- We mark this cell as aria-hidden so it doesn't get read out as one of the days in the week.\n The aspect ratio of the table cells is maintained by setting the top and bottom padding as a\n percentage of the width (a variant of the trick described here:\n https://www.w3schools.com/howto/howto_css_aspect_ratio.asp). -->\n @if (rowIndex === 0 && firstRowOffset) {\n <td class=\"kbq-calendar__body-label\" [attr.colspan]=\"firstRowOffset\"></td>\n }\n @for (item of row; track item.displayValue; let colIndex = $index) {\n <td\n class=\"kbq-calendar__body-cell\"\n [class.kbq-calendar__body_active]=\"isActiveCell(rowIndex, colIndex)\"\n [class]=\"item.cssClasses!\"\n [style.paddingBottom]=\"cellPadding\"\n [style.paddingTop]=\"cellPadding\"\n [style.width]=\"cellWidth\"\n [tabindex]=\"-1\"\n (click)=\"cellClicked(item)\"\n >\n <div\n class=\"kbq-calendar__body-cell-content\"\n [class.kbq-calendar__body-today]=\"todayValue() === item.value\"\n [class.kbq-disabled]=\"!item.enabled\"\n [class.kbq-selected]=\"selectedValue() === item.value\"\n >\n {{ item.displayValue }}\n </div>\n </td>\n }\n </tr>\n}\n", styles: [".kbq-calendar__body-cell{position:relative;height:0;line-height:0;text-align:center;outline:none;cursor:pointer;padding:0}.kbq-disabled{cursor:default}.kbq-calendar__body-cell-content{display:flex;align-items:center;justify-content:center;box-sizing:border-box;height:32px;line-height:1;border-radius:var(--kbq-datepicker-size-grid-cell-border-radius);margin-bottom:var(--kbq-datepicker-size-grid-content-gap-vertical)}\n"] }]
|
|
101
|
+
}, exportAs: 'kbqCalendarBody', template: "<!-- Create the first row separately so we can include a special spacer cell. -->\n@for (row of rows(); track $index; let rowIndex = $index) {\n <tr>\n <!-- We mark this cell as aria-hidden so it doesn't get read out as one of the days in the week.\n The aspect ratio of the table cells is maintained by setting the top and bottom padding as a\n percentage of the width (a variant of the trick described here:\n https://www.w3schools.com/howto/howto_css_aspect_ratio.asp). -->\n @if (rowIndex === 0 && firstRowOffset) {\n <td class=\"kbq-calendar__body-label\" [attr.colspan]=\"firstRowOffset\"></td>\n }\n @for (item of row; track item.displayValue; let colIndex = $index) {\n <td\n class=\"kbq-calendar__body-cell\"\n [class.kbq-calendar__body_active]=\"isActiveCell(rowIndex, colIndex)\"\n [class]=\"item.cssClasses!\"\n [style.paddingBottom]=\"cellPadding\"\n [style.paddingTop]=\"cellPadding\"\n [style.width]=\"cellWidth\"\n [tabindex]=\"-1\"\n (click)=\"cellClicked(item)\"\n >\n <div\n class=\"kbq-calendar__body-cell-content\"\n [class.kbq-calendar__body-today]=\"todayValue() === item.value\"\n [class.kbq-disabled]=\"!item.enabled\"\n [class.kbq-selected]=\"selectedValue() === item.value\"\n >\n {{ item.displayValue }}\n </div>\n </td>\n }\n </tr>\n}\n", styles: [".kbq-calendar__body-cell{position:relative;height:0;line-height:0;text-align:center;outline:none;cursor:pointer;padding:0}.kbq-disabled{cursor:default}.kbq-calendar__body-cell-content{display:flex;align-items:center;justify-content:center;box-sizing:border-box;height:32px;line-height:1;border-radius:var(--kbq-datepicker-size-grid-cell-border-radius)}@supports (corner-shape: squircle){.kbq-calendar__body-cell-content{corner-shape:squircle;border-radius:clamp(var(--kbq-datepicker-size-grid-cell-border-radius) * 1.85,var(--kbq-datepicker-size-grid-cell-border-radius) * 2.3 - 3.6px,var(--kbq-datepicker-size-grid-cell-border-radius) * 2)}}.kbq-calendar__body-cell-content{margin-bottom:var(--kbq-datepicker-size-grid-content-gap-vertical)}\n"] }]
|
|
101
102
|
}], propDecorators: { rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], todayValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "todayValue", required: false }] }], selectedValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedValue", required: false }] }], labelMinRequiredCells: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelMinRequiredCells", required: false }] }], numCols: [{ type: i0.Input, args: [{ isSignal: true, alias: "numCols", required: false }] }], activeCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeCell", required: false }] }], cellAspectRatio: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellAspectRatio", required: false }] }], selectedValueChange: [{ type: i0.Output, args: ["selectedValueChange"] }] } });
|
|
102
103
|
|
|
103
104
|
/** @docs-private */
|
|
@@ -118,8 +119,6 @@ const defaultMinYear = 1900;
|
|
|
118
119
|
const defaultMaxYear = 2099;
|
|
119
120
|
/** Default header for KbqCalendar */
|
|
120
121
|
class KbqCalendarHeader {
|
|
121
|
-
// TODO: Skipped for migration because:
|
|
122
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
123
122
|
get activeDate() {
|
|
124
123
|
return this._activeDate;
|
|
125
124
|
}
|
|
@@ -128,8 +127,6 @@ class KbqCalendarHeader {
|
|
|
128
127
|
this.updateSelectedValues();
|
|
129
128
|
this.updateSelectionOptions();
|
|
130
129
|
}
|
|
131
|
-
// TODO: Skipped for migration because:
|
|
132
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
133
130
|
get maxDate() {
|
|
134
131
|
return this._maxDate;
|
|
135
132
|
}
|
|
@@ -140,8 +137,6 @@ class KbqCalendarHeader {
|
|
|
140
137
|
this._maxDate = value;
|
|
141
138
|
this.updateSelectionOptions();
|
|
142
139
|
}
|
|
143
|
-
// TODO: Skipped for migration because:
|
|
144
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
145
140
|
get minDate() {
|
|
146
141
|
return this._minDate;
|
|
147
142
|
}
|
|
@@ -164,9 +159,17 @@ class KbqCalendarHeader {
|
|
|
164
159
|
}
|
|
165
160
|
constructor() {
|
|
166
161
|
this.adapter = injectRequiredDateAdapter();
|
|
162
|
+
/** Accessible names for the icon-only month navigation buttons. */
|
|
163
|
+
this.a11yLocaleConfiguration = kbqInjectA11yLocaleConfiguration();
|
|
167
164
|
this.years = [];
|
|
168
165
|
this._maxDate = this.adapter.createDate(defaultMaxYear, 11);
|
|
169
166
|
this._minDate = this.adapter.createDate(defaultMinYear, 1);
|
|
167
|
+
/** @docs-private */
|
|
168
|
+
this.activeDateInput = input(undefined, { ...(ngDevMode ? { debugName: "activeDateInput" } : /* istanbul ignore next */ {}), alias: 'activeDate' });
|
|
169
|
+
/** @docs-private */
|
|
170
|
+
this.maxDateInput = input(undefined, { ...(ngDevMode ? { debugName: "maxDateInput" } : /* istanbul ignore next */ {}), alias: 'maxDate' });
|
|
171
|
+
/** @docs-private */
|
|
172
|
+
this.minDateInput = input(undefined, { ...(ngDevMode ? { debugName: "minDateInput" } : /* istanbul ignore next */ {}), alias: 'minDate' });
|
|
170
173
|
/** Emits when any date is activated. */
|
|
171
174
|
this.activeDateChange = output();
|
|
172
175
|
this.monthSelected = output();
|
|
@@ -175,6 +178,24 @@ class KbqCalendarHeader {
|
|
|
175
178
|
return { name, nameShort: this.adapter.getMonthNames('short')[i], value: i, disabled: false };
|
|
176
179
|
});
|
|
177
180
|
}
|
|
181
|
+
ngOnChanges(changes) {
|
|
182
|
+
// A bound input is handed to its member; unbound, it leaves what code wrote.
|
|
183
|
+
if (changes['maxDateInput']) {
|
|
184
|
+
const maxDate = this.maxDateInput();
|
|
185
|
+
if (maxDate !== undefined)
|
|
186
|
+
this.maxDate = maxDate;
|
|
187
|
+
}
|
|
188
|
+
if (changes['minDateInput']) {
|
|
189
|
+
const minDate = this.minDateInput();
|
|
190
|
+
if (minDate !== undefined)
|
|
191
|
+
this.minDate = minDate;
|
|
192
|
+
}
|
|
193
|
+
if (changes['activeDateInput']) {
|
|
194
|
+
const activeDate = this.activeDateInput();
|
|
195
|
+
if (activeDate !== undefined)
|
|
196
|
+
this.activeDate = activeDate;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
178
199
|
ngAfterContentInit() {
|
|
179
200
|
this.updateYearsOptions();
|
|
180
201
|
this.updateMonthOptions();
|
|
@@ -253,10 +274,10 @@ class KbqCalendarHeader {
|
|
|
253
274
|
this.monthNames.forEach((month) => (month.disabled = false));
|
|
254
275
|
}
|
|
255
276
|
}
|
|
256
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
257
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
277
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqCalendarHeader, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
278
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: KbqCalendarHeader, isStandalone: true, selector: "kbq-calendar-header", inputs: { activeDateInput: { classPropertyName: "activeDateInput", publicName: "activeDate", isSignal: true, isRequired: false, transformFunction: null }, maxDateInput: { classPropertyName: "maxDateInput", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, minDateInput: { classPropertyName: "minDateInput", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeDateChange: "activeDateChange", monthSelected: "monthSelected", yearSelected: "yearSelected" }, host: { classAttribute: "kbq-calendar-header" }, exportAs: ["kbqCalendarHeader"], usesOnChanges: true, ngImport: i0, template: "<div class=\"kbq-calendar-header__select-group\">\n <kbq-select\n #monthSelect=\"kbqSelect\"\n class=\"kbq-calendar-header__select\"\n [panelClass]=\"'kbq-calendar-select-panel'\"\n [tabIndex]=\"-1\"\n [value]=\"selectedMonth\"\n (selectionChange)=\"onMonthSelected($event.value)\"\n >\n <button\n kbq-button\n kbq-select-matcher\n class=\"layout-padding-right-xs\"\n [class.kbq-active]=\"monthSelect.panelOpen\"\n [color]=\"'contrast'\"\n [kbqStyle]=\"'transparent'\"\n >\n {{ monthNames[selectedMonth].nameShort | titlecase }}\n\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"layout-padding-left-3xs\" [color]=\"'contrast'\"></i>\n </button>\n\n @for (month of monthNames; track month.nameShort) {\n <kbq-option [disabled]=\"month.disabled\" [kbqTooltipDisabled]=\"true\" [value]=\"month.value\">\n {{ month.name }}\n </kbq-option>\n }\n </kbq-select>\n\n <kbq-select\n #yearSelect=\"kbqSelect\"\n [panelClass]=\"'kbq-calendar-select-panel'\"\n [tabIndex]=\"-1\"\n [value]=\"selectedYear\"\n (selectionChange)=\"onYearSelected($event.value)\"\n >\n <button\n kbq-button\n kbq-select-matcher\n class=\"layout-padding-right-xs\"\n [class.kbq-active]=\"yearSelect.panelOpen\"\n [color]=\"'contrast'\"\n [kbqStyle]=\"'transparent'\"\n >\n {{ selectedYear }}\n\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"layout-padding-left-3xs\"></i>\n </button>\n\n @for (year of years; track year) {\n <kbq-option [kbqTooltipDisabled]=\"true\" [value]=\"year\">\n {{ year }}\n </kbq-option>\n }\n </kbq-select>\n</div>\n\n<div class=\"kbq-calendar-header__button-group\">\n <button\n kbq-button\n class=\"kbq-calendar-header__previous-button\"\n [attr.aria-label]=\"a11yLocaleConfiguration().previousMonth\"\n [color]=\"'contrast'\"\n [disabled]=\"previousDisabled\"\n [kbqStyle]=\"'transparent'\"\n [tabindex]=\"-1\"\n (click)=\"selectPreviousMonth()\"\n >\n <i kbq-icon=\"kbq-chevron-left_16\"></i>\n </button>\n\n <button\n kbq-button\n [attr.aria-label]=\"a11yLocaleConfiguration().currentDate\"\n [color]=\"'contrast'\"\n [disabled]=\"currentDisabled\"\n [kbqStyle]=\"'transparent'\"\n [tabindex]=\"-1\"\n (click)=\"selectCurrentDate()\"\n >\n <i kbq-icon=\"kbq-circle-xs_16\"></i>\n </button>\n\n <button\n kbq-button\n class=\"kbq-calendar-header__next-button\"\n [attr.aria-label]=\"a11yLocaleConfiguration().nextMonth\"\n [color]=\"'contrast'\"\n [disabled]=\"nextDisabled\"\n [kbqStyle]=\"'transparent'\"\n [tabindex]=\"-1\"\n (click)=\"selectNextMonth()\"\n >\n <i kbq-icon=\"kbq-chevron-right_16\"></i>\n </button>\n</div>\n", styles: [".kbq-calendar-header{display:flex;flex-direction:row;justify-content:space-between;padding-right:var(--kbq-datepicker-size-header-padding-horizontal);padding-left:var(--kbq-datepicker-size-header-padding-horizontal);margin-bottom:var(--kbq-datepicker-size-header-margin-bottom)}.kbq-calendar-header__select{width:auto!important}.kbq-calendar-header__button-group,.kbq-calendar-header__select-group{display:flex;flex-direction:row}.kbq-calendar-select-panel{margin-top:2px;min-width:98%!important}.kbq-calendar-select-panel .kbq-select__content{max-height:384px;overflow-x:hidden;scrollbar-gutter:auto}.kbq-calendar-select-panel .kbq-select__content .kbq-option{min-width:65px}\n"], dependencies: [{ kind: "ngmodule", type: KbqButtonModule }, { kind: "component", type: i1.KbqButton, selector: "[kbq-button]", inputs: ["kbqStyle", "disabled", "tabIndex"] }, { kind: "directive", type: i1.KbqButtonCssStyler, selector: "[kbq-button]" }, { kind: "ngmodule", type: KbqIconModule }, { kind: "component", type: i2.KbqIcon, selector: "[kbq-icon]", inputs: ["aria-hidden", "iconSize", "autoColor", "kbq-icon"] }, { kind: "ngmodule", type: KbqSelectModule }, { kind: "component", type: i3.KbqSelect, selector: "kbq-select", inputs: ["hiddenItemsText", "hiddenItemsTextFormatter", "aria-label", "showPreselectedValues", "triggerValuesLimit", "panelClass", "backdropClass", "errorStateMatcher", "sortComparator", "multiline", "searchMinOptionsThreshold", "scrolledToBottomOffset", "hasBackdrop", "placeholder", "required", "multiple", "compareWith", "virtualOptionFactory", "clearPredicate", "selectAllToggle", "selectAll", "selectAllHandler", "panelWidth", "panelMinWidth", "panelMaxWidth", "panelMaxHeight", "value", "id", "tabIndex", "disabled"], outputs: ["openedChange", "beforeOpened", "opened", "closed", "selectionChange", "onSelectAll", "valueChange", "scrolledToBottom"], exportAs: ["kbqSelect"] }, { kind: "directive", type: i3.KbqOptionTooltip, selector: "kbq-option", inputs: ["ignoreTooltipPointerEvents"] }, { kind: "component", type: i4.KbqOption, selector: "kbq-option", inputs: ["value", "selectable", "userSelect", "showCheckbox", "viewValue", "disabled"], outputs: ["onSelectionChange"], exportAs: ["kbqOption"] }, { kind: "directive", type: i4.KbqSelectMatcher, selector: "kbq-select-matcher, [kbq-select-matcher]", inputs: ["useDefaultHandlers"] }, { kind: "ngmodule", type: KbqOptionModule }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
258
279
|
}
|
|
259
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
280
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqCalendarHeader, decorators: [{
|
|
260
281
|
type: Component,
|
|
261
282
|
args: [{ selector: 'kbq-calendar-header', imports: [
|
|
262
283
|
TitleCasePipe,
|
|
@@ -266,63 +287,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
266
287
|
KbqOptionModule
|
|
267
288
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
268
289
|
class: 'kbq-calendar-header'
|
|
269
|
-
}, exportAs: 'kbqCalendarHeader', template: "<div class=\"kbq-calendar-header__select-group\">\n <kbq-select\n #monthSelect=\"kbqSelect\"\n class=\"kbq-calendar-header__select\"\n [panelClass]=\"'kbq-calendar-select-panel'\"\n [tabIndex]=\"-1\"\n [value]=\"selectedMonth\"\n (selectionChange)=\"onMonthSelected($event.value)\"\n >\n <button\n kbq-button\n kbq-select-matcher\n class=\"layout-padding-right-xs\"\n [class.kbq-active]=\"monthSelect.panelOpen\"\n [color]=\"'contrast'\"\n [kbqStyle]=\"'transparent'\"\n >\n {{ monthNames[selectedMonth].nameShort | titlecase }}\n\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"layout-padding-left-3xs\" [color]=\"'contrast'\"></i>\n </button>\n\n @for (month of monthNames; track month.nameShort) {\n <kbq-option [disabled]=\"month.disabled\" [kbqTooltipDisabled]=\"true\" [value]=\"month.value\">\n {{ month.name }}\n </kbq-option>\n }\n </kbq-select>\n\n <kbq-select\n #yearSelect=\"kbqSelect\"\n [panelClass]=\"'kbq-calendar-select-panel'\"\n [tabIndex]=\"-1\"\n [value]=\"selectedYear\"\n (selectionChange)=\"onYearSelected($event.value)\"\n >\n <button\n kbq-button\n kbq-select-matcher\n class=\"layout-padding-right-xs\"\n [class.kbq-active]=\"yearSelect.panelOpen\"\n [color]=\"'contrast'\"\n [kbqStyle]=\"'transparent'\"\n >\n {{ selectedYear }}\n\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"layout-padding-left-3xs\"></i>\n </button>\n\n @for (year of years; track year) {\n <kbq-option [kbqTooltipDisabled]=\"true\" [value]=\"year\">\n {{ year }}\n </kbq-option>\n }\n </kbq-select>\n</div>\n\n<div class=\"kbq-calendar-header__button-group\">\n <button\n kbq-button\n class=\"kbq-calendar-header__previous-button\"\n [color]=\"'contrast'\"\n [disabled]=\"previousDisabled\"\n [kbqStyle]=\"'transparent'\"\n [tabindex]=\"-1\"\n (click)=\"selectPreviousMonth()\"\n >\n <i kbq-icon=\"kbq-chevron-left_16\"></i>\n </button>\n\n <button\n kbq-button\n [color]=\"'contrast'\"\n [disabled]=\"currentDisabled\"\n [kbqStyle]=\"'transparent'\"\n [tabindex]=\"-1\"\n (click)=\"selectCurrentDate()\"\n >\n <i kbq-icon=\"kbq-circle-xs_16\"></i>\n </button>\n\n <button\n kbq-button\n class=\"kbq-calendar-header__next-button\"\n [color]=\"'contrast'\"\n [disabled]=\"nextDisabled\"\n [kbqStyle]=\"'transparent'\"\n [tabindex]=\"-1\"\n (click)=\"selectNextMonth()\"\n >\n <i kbq-icon=\"kbq-chevron-right_16\"></i>\n </button>\n</div>\n", styles: [".kbq-calendar-header{display:flex;flex-direction:row;justify-content:space-between;padding-right:var(--kbq-datepicker-size-header-padding-horizontal);padding-left:var(--kbq-datepicker-size-header-padding-horizontal);margin-bottom:var(--kbq-datepicker-size-header-margin-bottom)}.kbq-calendar-header__select{width:auto!important}.kbq-calendar-header__button-group,.kbq-calendar-header__select-group{display:flex;flex-direction:row}.kbq-calendar-select-panel{margin-top:2px;min-width:98%!important}.kbq-calendar-select-panel .kbq-select__content{max-height:384px;overflow-x:hidden;scrollbar-gutter:auto}.kbq-calendar-select-panel .kbq-select__content .kbq-option{min-width:65px}\n"] }]
|
|
270
|
-
}], ctorParameters: () => [], propDecorators: { activeDate: [{
|
|
271
|
-
type: Input
|
|
272
|
-
}], maxDate: [{
|
|
273
|
-
type: Input
|
|
274
|
-
}], minDate: [{
|
|
275
|
-
type: Input
|
|
276
|
-
}], activeDateChange: [{ type: i0.Output, args: ["activeDateChange"] }], monthSelected: [{ type: i0.Output, args: ["monthSelected"] }], yearSelected: [{ type: i0.Output, args: ["yearSelected"] }] } });
|
|
277
|
-
|
|
278
|
-
/** Datepicker data that requires internationalization. */
|
|
279
|
-
class KbqDatepickerIntl {
|
|
280
|
-
constructor() {
|
|
281
|
-
/**
|
|
282
|
-
* Stream that emits whenever the labels here are changed. Use this to notify
|
|
283
|
-
* components if the labels have changed after initialization.
|
|
284
|
-
*/
|
|
285
|
-
this.changes = new Subject();
|
|
286
|
-
/** A label for the calendar popup (used by screen readers). */
|
|
287
|
-
this.calendarLabel = 'Calendar';
|
|
288
|
-
/** A label for the button used to open the calendar popup (used by screen readers). */
|
|
289
|
-
this.openCalendarLabel = 'Open calendar';
|
|
290
|
-
/** A label for the previous month button (used by screen readers). */
|
|
291
|
-
this.prevMonthLabel = 'Previous month';
|
|
292
|
-
/** A label for the next month button (used by screen readers). */
|
|
293
|
-
this.nextMonthLabel = 'Next month';
|
|
294
|
-
/** A label for the previous year button (used by screen readers). */
|
|
295
|
-
this.prevYearLabel = 'Previous year';
|
|
296
|
-
/** A label for the next year button (used by screen readers). */
|
|
297
|
-
this.nextYearLabel = 'Next year';
|
|
298
|
-
/** A label for the previous multi-year button (used by screen readers). */
|
|
299
|
-
this.prevMultiYearLabel = 'Previous 20 years';
|
|
300
|
-
/** A label for the next multi-year button (used by screen readers). */
|
|
301
|
-
this.nextMultiYearLabel = 'Next 20 years';
|
|
302
|
-
/** A label for the 'switch to month view' button (used by screen readers). */
|
|
303
|
-
this.switchToMonthViewLabel = 'Choose date';
|
|
304
|
-
/** A label for the 'switch to year view' button (used by screen readers). */
|
|
305
|
-
this.switchToMultiYearViewLabel = 'Choose month and year';
|
|
306
|
-
}
|
|
307
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqDatepickerIntl, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
308
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqDatepickerIntl, providedIn: 'root' }); }
|
|
309
|
-
}
|
|
310
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqDatepickerIntl, decorators: [{
|
|
311
|
-
type: Injectable,
|
|
312
|
-
args: [{ providedIn: 'root' }]
|
|
313
|
-
}] });
|
|
290
|
+
}, exportAs: 'kbqCalendarHeader', template: "<div class=\"kbq-calendar-header__select-group\">\n <kbq-select\n #monthSelect=\"kbqSelect\"\n class=\"kbq-calendar-header__select\"\n [panelClass]=\"'kbq-calendar-select-panel'\"\n [tabIndex]=\"-1\"\n [value]=\"selectedMonth\"\n (selectionChange)=\"onMonthSelected($event.value)\"\n >\n <button\n kbq-button\n kbq-select-matcher\n class=\"layout-padding-right-xs\"\n [class.kbq-active]=\"monthSelect.panelOpen\"\n [color]=\"'contrast'\"\n [kbqStyle]=\"'transparent'\"\n >\n {{ monthNames[selectedMonth].nameShort | titlecase }}\n\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"layout-padding-left-3xs\" [color]=\"'contrast'\"></i>\n </button>\n\n @for (month of monthNames; track month.nameShort) {\n <kbq-option [disabled]=\"month.disabled\" [kbqTooltipDisabled]=\"true\" [value]=\"month.value\">\n {{ month.name }}\n </kbq-option>\n }\n </kbq-select>\n\n <kbq-select\n #yearSelect=\"kbqSelect\"\n [panelClass]=\"'kbq-calendar-select-panel'\"\n [tabIndex]=\"-1\"\n [value]=\"selectedYear\"\n (selectionChange)=\"onYearSelected($event.value)\"\n >\n <button\n kbq-button\n kbq-select-matcher\n class=\"layout-padding-right-xs\"\n [class.kbq-active]=\"yearSelect.panelOpen\"\n [color]=\"'contrast'\"\n [kbqStyle]=\"'transparent'\"\n >\n {{ selectedYear }}\n\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"layout-padding-left-3xs\"></i>\n </button>\n\n @for (year of years; track year) {\n <kbq-option [kbqTooltipDisabled]=\"true\" [value]=\"year\">\n {{ year }}\n </kbq-option>\n }\n </kbq-select>\n</div>\n\n<div class=\"kbq-calendar-header__button-group\">\n <button\n kbq-button\n class=\"kbq-calendar-header__previous-button\"\n [attr.aria-label]=\"a11yLocaleConfiguration().previousMonth\"\n [color]=\"'contrast'\"\n [disabled]=\"previousDisabled\"\n [kbqStyle]=\"'transparent'\"\n [tabindex]=\"-1\"\n (click)=\"selectPreviousMonth()\"\n >\n <i kbq-icon=\"kbq-chevron-left_16\"></i>\n </button>\n\n <button\n kbq-button\n [attr.aria-label]=\"a11yLocaleConfiguration().currentDate\"\n [color]=\"'contrast'\"\n [disabled]=\"currentDisabled\"\n [kbqStyle]=\"'transparent'\"\n [tabindex]=\"-1\"\n (click)=\"selectCurrentDate()\"\n >\n <i kbq-icon=\"kbq-circle-xs_16\"></i>\n </button>\n\n <button\n kbq-button\n class=\"kbq-calendar-header__next-button\"\n [attr.aria-label]=\"a11yLocaleConfiguration().nextMonth\"\n [color]=\"'contrast'\"\n [disabled]=\"nextDisabled\"\n [kbqStyle]=\"'transparent'\"\n [tabindex]=\"-1\"\n (click)=\"selectNextMonth()\"\n >\n <i kbq-icon=\"kbq-chevron-right_16\"></i>\n </button>\n</div>\n", styles: [".kbq-calendar-header{display:flex;flex-direction:row;justify-content:space-between;padding-right:var(--kbq-datepicker-size-header-padding-horizontal);padding-left:var(--kbq-datepicker-size-header-padding-horizontal);margin-bottom:var(--kbq-datepicker-size-header-margin-bottom)}.kbq-calendar-header__select{width:auto!important}.kbq-calendar-header__button-group,.kbq-calendar-header__select-group{display:flex;flex-direction:row}.kbq-calendar-select-panel{margin-top:2px;min-width:98%!important}.kbq-calendar-select-panel .kbq-select__content{max-height:384px;overflow-x:hidden;scrollbar-gutter:auto}.kbq-calendar-select-panel .kbq-select__content .kbq-option{min-width:65px}\n"] }]
|
|
291
|
+
}], ctorParameters: () => [], propDecorators: { activeDateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeDate", required: false }] }], maxDateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], minDateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], activeDateChange: [{ type: i0.Output, args: ["activeDateChange"] }], monthSelected: [{ type: i0.Output, args: ["monthSelected"] }], yearSelected: [{ type: i0.Output, args: ["yearSelected"] }] } });
|
|
314
292
|
|
|
315
293
|
const DAYS_PER_WEEK = 7;
|
|
316
294
|
/**
|
|
317
295
|
* An internal component used to display a single month in the datepicker.
|
|
296
|
+
*
|
|
318
297
|
* @docs-private
|
|
319
298
|
*/
|
|
320
299
|
class KbqMonthView {
|
|
321
300
|
/**
|
|
322
301
|
* The date to display in this month view (everything other than the month and year is ignored).
|
|
323
302
|
*/
|
|
324
|
-
// TODO: Skipped for migration because:
|
|
325
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
326
303
|
get activeDate() {
|
|
327
304
|
return this._activeDate;
|
|
328
305
|
}
|
|
@@ -334,8 +311,6 @@ class KbqMonthView {
|
|
|
334
311
|
}
|
|
335
312
|
}
|
|
336
313
|
/** The currently selected date. */
|
|
337
|
-
// TODO: Skipped for migration because:
|
|
338
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
339
314
|
get selected() {
|
|
340
315
|
return this._selected;
|
|
341
316
|
}
|
|
@@ -347,14 +322,18 @@ class KbqMonthView {
|
|
|
347
322
|
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
348
323
|
this.timezoneService = inject(KbqDateTimezoneService);
|
|
349
324
|
this.adapter = injectRequiredDateAdapter();
|
|
325
|
+
/** @docs-private */
|
|
326
|
+
this.activeDateInput = input(undefined, { ...(ngDevMode ? { debugName: "activeDateInput" } : /* istanbul ignore next */ {}), alias: 'activeDate' });
|
|
327
|
+
/** @docs-private */
|
|
328
|
+
this.selectedInput = input(undefined, { ...(ngDevMode ? { debugName: "selectedInput" } : /* istanbul ignore next */ {}), alias: 'selected' });
|
|
350
329
|
/** The minimum selectable date. */
|
|
351
|
-
this.minDate = input(undefined, ...(ngDevMode ? [{ debugName: "minDate" }] : []));
|
|
330
|
+
this.minDate = input(undefined, ...(ngDevMode ? [{ debugName: "minDate" }] : /* istanbul ignore next */ []));
|
|
352
331
|
/** The maximum selectable date. */
|
|
353
|
-
this.maxDate = input(undefined, ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
|
|
332
|
+
this.maxDate = input(undefined, ...(ngDevMode ? [{ debugName: "maxDate" }] : /* istanbul ignore next */ []));
|
|
354
333
|
/** Function used to filter which dates are selectable. */
|
|
355
|
-
this.dateFilter = input(undefined, ...(ngDevMode ? [{ debugName: "dateFilter" }] : []));
|
|
334
|
+
this.dateFilter = input(undefined, ...(ngDevMode ? [{ debugName: "dateFilter" }] : /* istanbul ignore next */ []));
|
|
356
335
|
/** Function that can be used to add custom CSS classes to dates. */
|
|
357
|
-
this.dateClass = input(undefined, ...(ngDevMode ? [{ debugName: "dateClass" }] : []));
|
|
336
|
+
this.dateClass = input(undefined, ...(ngDevMode ? [{ debugName: "dateClass" }] : /* istanbul ignore next */ []));
|
|
358
337
|
/** Emits when a new date is selected. */
|
|
359
338
|
this.selectedChange = output();
|
|
360
339
|
/** Emits when any date is selected. */
|
|
@@ -376,9 +355,21 @@ class KbqMonthView {
|
|
|
376
355
|
// `todayDate` and the cell dates are resolved once, in `init()`, against the zone that was
|
|
377
356
|
// active then; a new one can move which cell is today.
|
|
378
357
|
this.init();
|
|
379
|
-
this.changeDetectorRef.markForCheck();
|
|
380
358
|
});
|
|
381
359
|
}
|
|
360
|
+
ngOnChanges(changes) {
|
|
361
|
+
// A bound input is handed to its member; unbound, it leaves what code wrote.
|
|
362
|
+
if (changes['selectedInput']) {
|
|
363
|
+
const selected = this.selectedInput();
|
|
364
|
+
if (selected !== undefined)
|
|
365
|
+
this.selected = selected;
|
|
366
|
+
}
|
|
367
|
+
if (changes['activeDateInput']) {
|
|
368
|
+
const activeDate = this.activeDateInput();
|
|
369
|
+
if (activeDate !== undefined)
|
|
370
|
+
this.activeDate = activeDate;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
382
373
|
ngAfterContentInit() {
|
|
383
374
|
this.init();
|
|
384
375
|
}
|
|
@@ -390,7 +381,6 @@ class KbqMonthView {
|
|
|
390
381
|
const selectedDate = this.adapter.createDate(selectedYear, selectedMonth, date);
|
|
391
382
|
this.selectedChange.emit(selectedDate);
|
|
392
383
|
}
|
|
393
|
-
// TODO: The 'emit' function requires a mandatory void argument
|
|
394
384
|
this.userSelection.emit();
|
|
395
385
|
}
|
|
396
386
|
/** Initializes this month view. */
|
|
@@ -445,28 +435,61 @@ class KbqMonthView {
|
|
|
445
435
|
this.adapter.getMonth(d1) === this.adapter.getMonth(d2) &&
|
|
446
436
|
this.adapter.getYear(d1) === this.adapter.getYear(d2));
|
|
447
437
|
}
|
|
448
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
449
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
438
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqMonthView, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
439
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: KbqMonthView, isStandalone: true, selector: "kbq-month-view", inputs: { activeDateInput: { classPropertyName: "activeDateInput", publicName: "activeDate", isSignal: true, isRequired: false, transformFunction: null }, selectedInput: { classPropertyName: "selectedInput", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, dateFilter: { classPropertyName: "dateFilter", publicName: "dateFilter", isSignal: true, isRequired: false, transformFunction: null }, dateClass: { classPropertyName: "dateClass", publicName: "dateClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedChange: "selectedChange", userSelection: "userSelection", activeDateChange: "activeDateChange" }, viewQueries: [{ propertyName: "kbqCalendarBody", first: true, predicate: KbqCalendarBody, descendants: true, isSignal: true }], exportAs: ["kbqMonthView"], usesOnChanges: true, ngImport: i0, template: "<table class=\"kbq-calendar__table\">\n <thead class=\"kbq-calendar__table-header\">\n <tr>\n @for (day of weekdays; track day) {\n <th [attr.aria-label]=\"day.long\">\n {{ day.narrow }}\n </th>\n }\n </tr>\n <tr>\n <th colspan=\"7\" class=\"kbq-calendar__table-header-divider\"></th>\n </tr>\n </thead>\n <tbody\n kbq-calendar-body\n [activeCell]=\"adapter.getDate(activeDate) - 1\"\n [labelMinRequiredCells]=\"3\"\n [rows]=\"weeks\"\n [selectedValue]=\"selectedDate!\"\n [todayValue]=\"todayDate!\"\n (selectedValueChange)=\"dateSelected($event)\"\n ></tbody>\n</table>\n", dependencies: [{ kind: "component", type: KbqCalendarBody, selector: "[kbq-calendar-body]", inputs: ["rows", "todayValue", "selectedValue", "labelMinRequiredCells", "numCols", "activeCell", "cellAspectRatio"], outputs: ["selectedValueChange"], exportAs: ["kbqCalendarBody"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
450
440
|
}
|
|
451
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
441
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqMonthView, decorators: [{
|
|
452
442
|
type: Component,
|
|
453
443
|
args: [{ selector: 'kbq-month-view', imports: [
|
|
454
444
|
KbqCalendarBody
|
|
455
445
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'kbqMonthView', template: "<table class=\"kbq-calendar__table\">\n <thead class=\"kbq-calendar__table-header\">\n <tr>\n @for (day of weekdays; track day) {\n <th [attr.aria-label]=\"day.long\">\n {{ day.narrow }}\n </th>\n }\n </tr>\n <tr>\n <th colspan=\"7\" class=\"kbq-calendar__table-header-divider\"></th>\n </tr>\n </thead>\n <tbody\n kbq-calendar-body\n [activeCell]=\"adapter.getDate(activeDate) - 1\"\n [labelMinRequiredCells]=\"3\"\n [rows]=\"weeks\"\n [selectedValue]=\"selectedDate!\"\n [todayValue]=\"todayDate!\"\n (selectedValueChange)=\"dateSelected($event)\"\n ></tbody>\n</table>\n" }]
|
|
456
|
-
}], ctorParameters: () => [], propDecorators: { activeDate: [{
|
|
457
|
-
type: Input
|
|
458
|
-
}], selected: [{
|
|
459
|
-
type: Input
|
|
460
|
-
}], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], dateFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFilter", required: false }] }], dateClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateClass", required: false }] }], selectedChange: [{ type: i0.Output, args: ["selectedChange"] }], userSelection: [{ type: i0.Output, args: ["userSelection"] }], activeDateChange: [{ type: i0.Output, args: ["activeDateChange"] }], kbqCalendarBody: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqCalendarBody), { isSignal: true }] }] } });
|
|
446
|
+
}], ctorParameters: () => [], propDecorators: { activeDateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeDate", required: false }] }], selectedInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], dateFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFilter", required: false }] }], dateClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateClass", required: false }] }], selectedChange: [{ type: i0.Output, args: ["selectedChange"] }], userSelection: [{ type: i0.Output, args: ["userSelection"] }], activeDateChange: [{ type: i0.Output, args: ["activeDateChange"] }], kbqCalendarBody: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqCalendarBody), { isSignal: true }] }] } });
|
|
461
447
|
|
|
462
448
|
/**
|
|
463
449
|
* A calendar that is used as part of the datepicker.
|
|
450
|
+
*
|
|
464
451
|
* @docs-private
|
|
465
452
|
*/
|
|
466
453
|
class KbqCalendar {
|
|
454
|
+
constructor() {
|
|
455
|
+
this.adapter = injectRequiredDateAdapter();
|
|
456
|
+
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
457
|
+
/** @docs-private */
|
|
458
|
+
this.startAtInput = input(undefined, { ...(ngDevMode ? { debugName: "startAtInput" } : /* istanbul ignore next */ {}), alias: 'startAt' });
|
|
459
|
+
/** @docs-private */
|
|
460
|
+
this.selectedInput = input(undefined, { ...(ngDevMode ? { debugName: "selectedInput" } : /* istanbul ignore next */ {}), alias: 'selected' });
|
|
461
|
+
/** @docs-private */
|
|
462
|
+
this.minDateInput = input(undefined, { ...(ngDevMode ? { debugName: "minDateInput" } : /* istanbul ignore next */ {}), alias: 'minDate' });
|
|
463
|
+
/** @docs-private */
|
|
464
|
+
this.maxDateInput = input(undefined, { ...(ngDevMode ? { debugName: "maxDateInput" } : /* istanbul ignore next */ {}), alias: 'maxDate' });
|
|
465
|
+
/** Function used to filter which dates are selectable. */
|
|
466
|
+
this.dateFilter = input(undefined, ...(ngDevMode ? [{ debugName: "dateFilter" }] : /* istanbul ignore next */ []));
|
|
467
|
+
/** Function that can be used to add custom CSS classes to dates. */
|
|
468
|
+
this.dateClass = input(undefined, ...(ngDevMode ? [{ debugName: "dateClass" }] : /* istanbul ignore next */ []));
|
|
469
|
+
/** Emits when the currently selected date changes. */
|
|
470
|
+
this.selectedChange = output();
|
|
471
|
+
/**
|
|
472
|
+
* Emits the year chosen in multiyear view.
|
|
473
|
+
* This doesn't imply a change on the selected date.
|
|
474
|
+
*/
|
|
475
|
+
this.yearSelected = output();
|
|
476
|
+
/**
|
|
477
|
+
* Emits the month chosen in year view.
|
|
478
|
+
* This doesn't imply a change on the selected date.
|
|
479
|
+
*/
|
|
480
|
+
this.monthSelected = output();
|
|
481
|
+
/** Emits when any date is selected. */
|
|
482
|
+
this.userSelection = output();
|
|
483
|
+
/** Reference to the current month view component. */
|
|
484
|
+
this.monthView = viewChild.required(KbqMonthView);
|
|
485
|
+
/**
|
|
486
|
+
* Emits whenever there is a state change that the header may need to respond to.
|
|
487
|
+
*/
|
|
488
|
+
this.stateChanges = new Subject();
|
|
489
|
+
/** Subscription to value changes in the associated input element. */
|
|
490
|
+
this.inputSubscription = Subscription.EMPTY;
|
|
491
|
+
}
|
|
467
492
|
/** A date representing the period (month or year) to start the calendar in. */
|
|
468
|
-
// TODO: Skipped for migration because:
|
|
469
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
470
493
|
get startAt() {
|
|
471
494
|
return this._startAt;
|
|
472
495
|
}
|
|
@@ -476,8 +499,6 @@ class KbqCalendar {
|
|
|
476
499
|
deserializedValue !== null ? this.adapter.clampDate(deserializedValue, this.minDate, this.maxDate) : null;
|
|
477
500
|
}
|
|
478
501
|
/** The currently selected date. */
|
|
479
|
-
// TODO: Skipped for migration because:
|
|
480
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
481
502
|
get selected() {
|
|
482
503
|
return this._selected;
|
|
483
504
|
}
|
|
@@ -485,8 +506,6 @@ class KbqCalendar {
|
|
|
485
506
|
this._selected = this.adapter.deserialize(value);
|
|
486
507
|
}
|
|
487
508
|
/** The minimum selectable date. */
|
|
488
|
-
// TODO: Skipped for migration because:
|
|
489
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
490
509
|
get minDate() {
|
|
491
510
|
return this._minDate;
|
|
492
511
|
}
|
|
@@ -495,8 +514,6 @@ class KbqCalendar {
|
|
|
495
514
|
this.startAt = this._startAt;
|
|
496
515
|
}
|
|
497
516
|
/** The maximum selectable date. */
|
|
498
|
-
// TODO: Skipped for migration because:
|
|
499
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
500
517
|
get maxDate() {
|
|
501
518
|
return this._maxDate;
|
|
502
519
|
}
|
|
@@ -515,44 +532,19 @@ class KbqCalendar {
|
|
|
515
532
|
this._activeDate = this.adapter.clampDate(value || this.getActiveDateDefault(), this.minDate, this.maxDate);
|
|
516
533
|
this.stateChanges.next();
|
|
517
534
|
}
|
|
518
|
-
constructor() {
|
|
519
|
-
this.adapter = injectRequiredDateAdapter();
|
|
520
|
-
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
521
|
-
/** Function used to filter which dates are selectable. */
|
|
522
|
-
this.dateFilter = input(undefined, ...(ngDevMode ? [{ debugName: "dateFilter" }] : []));
|
|
523
|
-
/** Function that can be used to add custom CSS classes to dates. */
|
|
524
|
-
this.dateClass = input(undefined, ...(ngDevMode ? [{ debugName: "dateClass" }] : []));
|
|
525
|
-
/** Emits when the currently selected date changes. */
|
|
526
|
-
this.selectedChange = output();
|
|
527
|
-
/**
|
|
528
|
-
* Emits the year chosen in multiyear view.
|
|
529
|
-
* This doesn't imply a change on the selected date.
|
|
530
|
-
*/
|
|
531
|
-
this.yearSelected = output();
|
|
532
|
-
/**
|
|
533
|
-
* Emits the month chosen in year view.
|
|
534
|
-
* This doesn't imply a change on the selected date.
|
|
535
|
-
*/
|
|
536
|
-
this.monthSelected = output();
|
|
537
|
-
/** Emits when any date is selected. */
|
|
538
|
-
this.userSelection = output();
|
|
539
|
-
/** Reference to the current month view component. */
|
|
540
|
-
this.monthView = viewChild.required(KbqMonthView);
|
|
541
|
-
/**
|
|
542
|
-
* Emits whenever there is a state change that the header may need to respond to.
|
|
543
|
-
*/
|
|
544
|
-
this.stateChanges = new Subject();
|
|
545
|
-
/** Subscription to value changes in the associated input element. */
|
|
546
|
-
this.inputSubscription = Subscription.EMPTY;
|
|
547
|
-
const intl = inject(KbqDatepickerIntl);
|
|
548
|
-
const changeDetectorRef = this.changeDetectorRef;
|
|
549
|
-
this.intlChanges = intl.changes.subscribe(() => {
|
|
550
|
-
changeDetectorRef.markForCheck();
|
|
551
|
-
this.stateChanges.next();
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
535
|
ngOnChanges(changes) {
|
|
555
|
-
|
|
536
|
+
// A bound input is handed to its member; unbound, it leaves what code wrote. A
|
|
537
|
+
// bound `undefined` is handed over too, as an unset date: a bound that becomes unset lifts its restriction.
|
|
538
|
+
if (changes['minDateInput'])
|
|
539
|
+
this.minDate = this.minDateInput() ?? null;
|
|
540
|
+
if (changes['maxDateInput'])
|
|
541
|
+
this.maxDate = this.maxDateInput() ?? null;
|
|
542
|
+
if (changes['selectedInput'])
|
|
543
|
+
this.selected = this.selectedInput() ?? null;
|
|
544
|
+
// After the bounds, which `startAt` is clamped to.
|
|
545
|
+
if (changes['startAtInput'])
|
|
546
|
+
this.startAt = this.startAtInput() ?? null;
|
|
547
|
+
const change = changes['minDateInput'] || changes['maxDateInput'] || changes['dateFilter'];
|
|
556
548
|
if (change && !change.firstChange) {
|
|
557
549
|
const monthView = this.monthView();
|
|
558
550
|
if (monthView) {
|
|
@@ -568,12 +560,12 @@ class KbqCalendar {
|
|
|
568
560
|
this.activeDate = this.getActiveDateDefault();
|
|
569
561
|
}
|
|
570
562
|
ngOnDestroy() {
|
|
571
|
-
this.intlChanges.unsubscribe();
|
|
572
563
|
this.inputSubscription.unsubscribe();
|
|
573
564
|
this.stateChanges.complete();
|
|
574
565
|
}
|
|
575
566
|
/**
|
|
576
567
|
* Register an input with this calendar.
|
|
568
|
+
*
|
|
577
569
|
* @param input The calendar input to register with this calendar.
|
|
578
570
|
*/
|
|
579
571
|
registerInput(input) {
|
|
@@ -599,7 +591,6 @@ class KbqCalendar {
|
|
|
599
591
|
}
|
|
600
592
|
}
|
|
601
593
|
userSelected() {
|
|
602
|
-
// TODO: The 'emit' function requires a mandatory void argument
|
|
603
594
|
this.userSelection.emit();
|
|
604
595
|
}
|
|
605
596
|
/**
|
|
@@ -613,10 +604,10 @@ class KbqCalendar {
|
|
|
613
604
|
getActiveDateDefault() {
|
|
614
605
|
return this.startAt || this.adapter.today();
|
|
615
606
|
}
|
|
616
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
617
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "
|
|
607
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqCalendar, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
608
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.25", type: KbqCalendar, isStandalone: true, selector: "kbq-calendar", inputs: { startAtInput: { classPropertyName: "startAtInput", publicName: "startAt", isSignal: true, isRequired: false, transformFunction: null }, selectedInput: { classPropertyName: "selectedInput", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, minDateInput: { classPropertyName: "minDateInput", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDateInput: { classPropertyName: "maxDateInput", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, dateFilter: { classPropertyName: "dateFilter", publicName: "dateFilter", isSignal: true, isRequired: false, transformFunction: null }, dateClass: { classPropertyName: "dateClass", publicName: "dateClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedChange: "selectedChange", yearSelected: "yearSelected", monthSelected: "monthSelected", userSelection: "userSelection" }, host: { classAttribute: "kbq-calendar" }, viewQueries: [{ propertyName: "monthView", first: true, predicate: KbqMonthView, descendants: true, isSignal: true }], exportAs: ["kbqCalendar"], usesOnChanges: true, ngImport: i0, template: "<kbq-calendar-header\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n [(activeDate)]=\"activeDate\"\n (monthSelected)=\"monthSelected.emit(activeDate)\"\n (yearSelected)=\"yearSelected.emit(activeDate)\"\n/>\n\n<div class=\"kbq-calendar__content\">\n <kbq-month-view\n [dateClass]=\"dateClass()\"\n [dateFilter]=\"dateFilter()\"\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n [selected]=\"selected\"\n [(activeDate)]=\"activeDate\"\n (selectedChange)=\"dateSelected($event!)\"\n (userSelection)=\"userSelected()\"\n />\n</div>\n", styles: [".kbq-calendar{display:block;box-sizing:initial}.kbq-calendar__content{padding-right:var(--kbq-datepicker-size-grid-padding-horizontal);padding-left:var(--kbq-datepicker-size-grid-padding-horizontal);outline:none}.kbq-calendar__table{border-spacing:0;border-collapse:collapse;width:100%}.kbq-calendar__table-header th{text-align:center;height:30px}.kbq-calendar__table-header th.kbq-calendar__table-header-divider{position:relative;box-sizing:border-box;height:var(--kbq-datepicker-size-grid-content-gap-vertical)}.kbq-calendar__table-header th.kbq-calendar__table-header-divider:after{content:\"\";position:absolute;top:0;left:calc(-1 * var(--kbq-datepicker-size-grid-padding-horizontal));right:calc(-1 * var(--kbq-datepicker-size-grid-padding-horizontal));height:var(--kbq-datepicker-size-grid-divider-height)}\n"], dependencies: [{ kind: "component", type: KbqCalendarHeader, selector: "kbq-calendar-header", inputs: ["activeDate", "maxDate", "minDate"], outputs: ["activeDateChange", "monthSelected", "yearSelected"], exportAs: ["kbqCalendarHeader"] }, { kind: "component", type: KbqMonthView, selector: "kbq-month-view", inputs: ["activeDate", "selected", "minDate", "maxDate", "dateFilter", "dateClass"], outputs: ["selectedChange", "userSelection", "activeDateChange"], exportAs: ["kbqMonthView"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
618
609
|
}
|
|
619
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
610
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqCalendar, decorators: [{
|
|
620
611
|
type: Component,
|
|
621
612
|
args: [{ selector: 'kbq-calendar', imports: [
|
|
622
613
|
KbqCalendarHeader,
|
|
@@ -624,1653 +615,1770 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
624
615
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
625
616
|
class: 'kbq-calendar'
|
|
626
617
|
}, exportAs: 'kbqCalendar', template: "<kbq-calendar-header\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n [(activeDate)]=\"activeDate\"\n (monthSelected)=\"monthSelected.emit(activeDate)\"\n (yearSelected)=\"yearSelected.emit(activeDate)\"\n/>\n\n<div class=\"kbq-calendar__content\">\n <kbq-month-view\n [dateClass]=\"dateClass()\"\n [dateFilter]=\"dateFilter()\"\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n [selected]=\"selected\"\n [(activeDate)]=\"activeDate\"\n (selectedChange)=\"dateSelected($event!)\"\n (userSelection)=\"userSelected()\"\n />\n</div>\n", styles: [".kbq-calendar{display:block;box-sizing:initial}.kbq-calendar__content{padding-right:var(--kbq-datepicker-size-grid-padding-horizontal);padding-left:var(--kbq-datepicker-size-grid-padding-horizontal);outline:none}.kbq-calendar__table{border-spacing:0;border-collapse:collapse;width:100%}.kbq-calendar__table-header th{text-align:center;height:30px}.kbq-calendar__table-header th.kbq-calendar__table-header-divider{position:relative;box-sizing:border-box;height:var(--kbq-datepicker-size-grid-content-gap-vertical)}.kbq-calendar__table-header th.kbq-calendar__table-header-divider:after{content:\"\";position:absolute;top:0;left:calc(-1 * var(--kbq-datepicker-size-grid-padding-horizontal));right:calc(-1 * var(--kbq-datepicker-size-grid-padding-horizontal));height:var(--kbq-datepicker-size-grid-divider-height)}\n"] }]
|
|
627
|
-
}],
|
|
628
|
-
type: Input
|
|
629
|
-
}], selected: [{
|
|
630
|
-
type: Input
|
|
631
|
-
}], minDate: [{
|
|
632
|
-
type: Input
|
|
633
|
-
}], maxDate: [{
|
|
634
|
-
type: Input
|
|
635
|
-
}], dateFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFilter", required: false }] }], dateClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateClass", required: false }] }], selectedChange: [{ type: i0.Output, args: ["selectedChange"] }], yearSelected: [{ type: i0.Output, args: ["yearSelected"] }], monthSelected: [{ type: i0.Output, args: ["monthSelected"] }], userSelection: [{ type: i0.Output, args: ["userSelection"] }], monthView: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqMonthView), { isSignal: true }] }] } });
|
|
618
|
+
}], propDecorators: { startAtInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAt", required: false }] }], selectedInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], minDateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], dateFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFilter", required: false }] }], dateClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateClass", required: false }] }], selectedChange: [{ type: i0.Output, args: ["selectedChange"] }], yearSelected: [{ type: i0.Output, args: ["yearSelected"] }], monthSelected: [{ type: i0.Output, args: ["monthSelected"] }], userSelection: [{ type: i0.Output, args: ["userSelection"] }], monthView: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqMonthView), { isSignal: true }] }] } });
|
|
636
619
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
};
|
|
662
|
-
|
|
663
|
-
/** Used to generate a unique ID for each datepicker instance. */
|
|
664
|
-
let datepickerUid = 0;
|
|
665
|
-
/**
|
|
666
|
-
* Injection token that determines the scroll handling while the calendar is open. The root default keeps the
|
|
667
|
-
* datepicker usable outside `KbqDatepickerModule`'s injector; providing the token anywhere still wins over it.
|
|
668
|
-
*/
|
|
669
|
-
const KBQ_DATEPICKER_SCROLL_STRATEGY = new InjectionToken('kbq-datepicker-scroll-strategy', {
|
|
670
|
-
providedIn: 'root',
|
|
671
|
-
factory: () => KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY(inject(Overlay))
|
|
672
|
-
});
|
|
673
|
-
/** @docs-private */
|
|
674
|
-
function KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY(overlay) {
|
|
675
|
-
return () => overlay.scrollStrategies.reposition();
|
|
676
|
-
}
|
|
677
|
-
/** @docs-private */
|
|
678
|
-
const KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = {
|
|
679
|
-
provide: KBQ_DATEPICKER_SCROLL_STRATEGY,
|
|
680
|
-
deps: [Overlay],
|
|
681
|
-
useFactory: KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY
|
|
682
|
-
};
|
|
683
|
-
/**
|
|
684
|
-
* Component used as the content for the datepicker dialog and popup. We use this instead of using
|
|
685
|
-
* KbqCalendar directly as the content so we can control the initial focus. This also gives us a
|
|
686
|
-
* place to put additional features of the popup that are not part of the calendar itself in the
|
|
687
|
-
* future. (e.g. confirmation buttons).
|
|
688
|
-
* @docs-private
|
|
689
|
-
*/
|
|
690
|
-
class KbqDatepickerContent {
|
|
691
|
-
constructor() {
|
|
692
|
-
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
693
|
-
/** Emits when an animation has finished. */
|
|
694
|
-
this.animationDone = new Subject();
|
|
695
|
-
/** Reference to the internal calendar component. */
|
|
696
|
-
this.calendar = viewChild.required(KbqCalendar);
|
|
697
|
-
this.subscriptions = new Subscription();
|
|
698
|
-
}
|
|
699
|
-
ngAfterViewInit() {
|
|
700
|
-
this.subscriptions.add(this.datepicker.stateChanges.subscribe(() => {
|
|
701
|
-
this.changeDetectorRef.markForCheck();
|
|
702
|
-
}));
|
|
703
|
-
}
|
|
704
|
-
ngOnDestroy() {
|
|
705
|
-
this.subscriptions.unsubscribe();
|
|
706
|
-
this.animationDone.complete();
|
|
707
|
-
}
|
|
708
|
-
startExitAnimation() {
|
|
709
|
-
this.animationState = 'void';
|
|
710
|
-
this.changeDetectorRef.markForCheck();
|
|
711
|
-
}
|
|
712
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqDatepickerContent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
713
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.30", type: KbqDatepickerContent, isStandalone: true, selector: "kbq-datepicker__content", host: { listeners: { "@transformPanel.done": "animationDone.next()" }, properties: { "@transformPanel": "animationState" }, classAttribute: "kbq-datepicker__content" }, viewQueries: [{ propertyName: "calendar", first: true, predicate: KbqCalendar, descendants: true, isSignal: true }], exportAs: ["kbqDatepickerContent"], ngImport: i0, template: "<kbq-calendar\n [dateClass]=\"datepicker.dateClass()\"\n [dateFilter]=\"datepicker.dateFilter\"\n [id]=\"datepicker.id\"\n [maxDate]=\"datepicker.maxDate()\"\n [minDate]=\"datepicker.minDate()\"\n [class]=\"datepicker.panelClass()\"\n [selected]=\"datepicker.selected\"\n [startAt]=\"datepicker.startAt\"\n [@fadeInCalendar]=\"'enter'\"\n (monthSelected)=\"datepicker.selectMonth($event)\"\n (selectedChange)=\"datepicker.select($event)\"\n (userSelection)=\"datepicker.close()\"\n (yearSelected)=\"datepicker.selectYear($event)\"\n/>\n", styles: [".kbq-datepicker__content{display:block;border-radius:var(--kbq-datepicker-size-container-border-radius)}.kbq-datepicker__content .kbq-calendar{width:calc(280px + var(--kbq-datepicker-size-grid-padding-horizontal) * 2);height:270px;padding-top:var(--kbq-datepicker-size-container-padding-vertical);padding-bottom:var(--kbq-datepicker-size-container-padding-vertical)}.kbq-datepicker__content{background:var(--kbq-datepicker-container-background);box-shadow:var(--kbq-datepicker-container-shadow)}.kbq-calendar__table-header{color:var(--kbq-datepicker-header-text)}.kbq-calendar__table-header-divider:after{background:var(--kbq-datepicker-header-divider)}.kbq-calendar__body-cell-content{background:var(--kbq-datepicker-grid-cell-default-background);color:var(--kbq-datepicker-grid-cell-default-text)}.kbq-calendar__body-cell-content.kbq-calendar__body-today{background:var(--kbq-datepicker-grid-cell-today-background);color:var(--kbq-datepicker-grid-cell-today-text)}.kbq-calendar__body-cell-content:hover:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-hover-background)}.kbq-calendar__body-cell-content:active:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-active-background)}.kbq-calendar__body-cell-content.kbq-selected:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-selected-background);color:var(--kbq-datepicker-grid-cell-states-selected-text)}.kbq-calendar__body-cell-content.kbq-selected:not(.kbq-disabled):hover{background:var(--kbq-datepicker-grid-cell-states-selected-hover-background)}.kbq-calendar__body-cell-content.kbq-disabled{color:var(--kbq-datepicker-grid-cell-states-disabled-text);background:var(--kbq-datepicker-grid-cell-states-disabled-background)}.kbq-calendar,.kbq-calendar__table-header th{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)}\n", ".kbq-datepicker__content{--kbq-datepicker-size-container-padding-vertical: var(--kbq-size-m);--kbq-datepicker-size-container-border-radius: var(--kbq-size-s);--kbq-datepicker-size-header-padding-horizontal: var(--kbq-size-xxs);--kbq-datepicker-size-header-margin-bottom: var(--kbq-size-3xs);--kbq-datepicker-size-grid-padding-horizontal: var(--kbq-size-m);--kbq-datepicker-size-grid-content-gap-vertical: var(--kbq-size-3xs);--kbq-datepicker-size-grid-divider-height: 1px;--kbq-datepicker-size-grid-cell-padding-horizontal: var(--kbq-size-s);--kbq-datepicker-size-grid-cell-padding-vertical: var(--kbq-size-s);--kbq-datepicker-size-grid-cell-border-radius: var(--kbq-size-s);--kbq-datepicker-container-background: var(--kbq-background-card);--kbq-datepicker-container-shadow: var(--kbq-shadow-popup);--kbq-datepicker-header-text: var(--kbq-foreground-contrast-tertiary);--kbq-datepicker-header-divider: var(--kbq-line-contrast-less);--kbq-datepicker-grid-cell-default-background: transparent;--kbq-datepicker-grid-cell-default-text: var(--kbq-foreground-contrast);--kbq-datepicker-grid-cell-today-background: transparent;--kbq-datepicker-grid-cell-today-text: var(--kbq-foreground-theme);--kbq-datepicker-grid-cell-states-hover-background: var(--kbq-states-background-transparent-hover);--kbq-datepicker-grid-cell-states-active-background: var(--kbq-states-background-transparent-active);--kbq-datepicker-grid-cell-states-selected-background: var(--kbq-background-contrast);--kbq-datepicker-grid-cell-states-selected-text: var(--kbq-foreground-on-contrast);--kbq-datepicker-grid-cell-states-selected-hover-background: var(--kbq-states-background-contrast-active);--kbq-datepicker-grid-cell-states-disabled-background: transparent;--kbq-datepicker-grid-cell-states-disabled-text: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "component", type: KbqCalendar, selector: "kbq-calendar", inputs: ["startAt", "selected", "minDate", "maxDate", "dateFilter", "dateClass"], outputs: ["selectedChange", "yearSelected", "monthSelected", "userSelection"], exportAs: ["kbqCalendar"] }], animations: [
|
|
714
|
-
kbqDatepickerAnimations.transformPanel,
|
|
715
|
-
kbqDatepickerAnimations.fadeInCalendar
|
|
716
|
-
], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
717
|
-
}
|
|
718
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqDatepickerContent, decorators: [{
|
|
719
|
-
type: Component,
|
|
720
|
-
args: [{ selector: 'kbq-datepicker__content', imports: [
|
|
721
|
-
KbqCalendar
|
|
722
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
723
|
-
class: 'kbq-datepicker__content',
|
|
724
|
-
'[@transformPanel]': 'animationState',
|
|
725
|
-
'(@transformPanel.done)': 'animationDone.next()'
|
|
726
|
-
}, animations: [
|
|
727
|
-
kbqDatepickerAnimations.transformPanel,
|
|
728
|
-
kbqDatepickerAnimations.fadeInCalendar
|
|
729
|
-
], exportAs: 'kbqDatepickerContent', template: "<kbq-calendar\n [dateClass]=\"datepicker.dateClass()\"\n [dateFilter]=\"datepicker.dateFilter\"\n [id]=\"datepicker.id\"\n [maxDate]=\"datepicker.maxDate()\"\n [minDate]=\"datepicker.minDate()\"\n [class]=\"datepicker.panelClass()\"\n [selected]=\"datepicker.selected\"\n [startAt]=\"datepicker.startAt\"\n [@fadeInCalendar]=\"'enter'\"\n (monthSelected)=\"datepicker.selectMonth($event)\"\n (selectedChange)=\"datepicker.select($event)\"\n (userSelection)=\"datepicker.close()\"\n (yearSelected)=\"datepicker.selectYear($event)\"\n/>\n", styles: [".kbq-datepicker__content{display:block;border-radius:var(--kbq-datepicker-size-container-border-radius)}.kbq-datepicker__content .kbq-calendar{width:calc(280px + var(--kbq-datepicker-size-grid-padding-horizontal) * 2);height:270px;padding-top:var(--kbq-datepicker-size-container-padding-vertical);padding-bottom:var(--kbq-datepicker-size-container-padding-vertical)}.kbq-datepicker__content{background:var(--kbq-datepicker-container-background);box-shadow:var(--kbq-datepicker-container-shadow)}.kbq-calendar__table-header{color:var(--kbq-datepicker-header-text)}.kbq-calendar__table-header-divider:after{background:var(--kbq-datepicker-header-divider)}.kbq-calendar__body-cell-content{background:var(--kbq-datepicker-grid-cell-default-background);color:var(--kbq-datepicker-grid-cell-default-text)}.kbq-calendar__body-cell-content.kbq-calendar__body-today{background:var(--kbq-datepicker-grid-cell-today-background);color:var(--kbq-datepicker-grid-cell-today-text)}.kbq-calendar__body-cell-content:hover:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-hover-background)}.kbq-calendar__body-cell-content:active:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-active-background)}.kbq-calendar__body-cell-content.kbq-selected:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-selected-background);color:var(--kbq-datepicker-grid-cell-states-selected-text)}.kbq-calendar__body-cell-content.kbq-selected:not(.kbq-disabled):hover{background:var(--kbq-datepicker-grid-cell-states-selected-hover-background)}.kbq-calendar__body-cell-content.kbq-disabled{color:var(--kbq-datepicker-grid-cell-states-disabled-text);background:var(--kbq-datepicker-grid-cell-states-disabled-background)}.kbq-calendar,.kbq-calendar__table-header th{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)}\n", ".kbq-datepicker__content{--kbq-datepicker-size-container-padding-vertical: var(--kbq-size-m);--kbq-datepicker-size-container-border-radius: var(--kbq-size-s);--kbq-datepicker-size-header-padding-horizontal: var(--kbq-size-xxs);--kbq-datepicker-size-header-margin-bottom: var(--kbq-size-3xs);--kbq-datepicker-size-grid-padding-horizontal: var(--kbq-size-m);--kbq-datepicker-size-grid-content-gap-vertical: var(--kbq-size-3xs);--kbq-datepicker-size-grid-divider-height: 1px;--kbq-datepicker-size-grid-cell-padding-horizontal: var(--kbq-size-s);--kbq-datepicker-size-grid-cell-padding-vertical: var(--kbq-size-s);--kbq-datepicker-size-grid-cell-border-radius: var(--kbq-size-s);--kbq-datepicker-container-background: var(--kbq-background-card);--kbq-datepicker-container-shadow: var(--kbq-shadow-popup);--kbq-datepicker-header-text: var(--kbq-foreground-contrast-tertiary);--kbq-datepicker-header-divider: var(--kbq-line-contrast-less);--kbq-datepicker-grid-cell-default-background: transparent;--kbq-datepicker-grid-cell-default-text: var(--kbq-foreground-contrast);--kbq-datepicker-grid-cell-today-background: transparent;--kbq-datepicker-grid-cell-today-text: var(--kbq-foreground-theme);--kbq-datepicker-grid-cell-states-hover-background: var(--kbq-states-background-transparent-hover);--kbq-datepicker-grid-cell-states-active-background: var(--kbq-states-background-transparent-active);--kbq-datepicker-grid-cell-states-selected-background: var(--kbq-background-contrast);--kbq-datepicker-grid-cell-states-selected-text: var(--kbq-foreground-on-contrast);--kbq-datepicker-grid-cell-states-selected-hover-background: var(--kbq-states-background-contrast-active);--kbq-datepicker-grid-cell-states-disabled-background: transparent;--kbq-datepicker-grid-cell-states-disabled-text: var(--kbq-states-foreground-disabled)}\n"] }]
|
|
730
|
-
}], propDecorators: { calendar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqCalendar), { isSignal: true }] }] } });
|
|
731
|
-
// TODO: We use a component instead of a directive here so the user can use implicit
|
|
732
|
-
// template reference variables (e.g. #d vs #d="kbqDatepicker"). We can change this to a directive
|
|
733
|
-
// if angular adds support for `exportAs: '$implicit'` on directives.
|
|
734
|
-
/** Component responsible for managing the datepicker popup/dialog. */
|
|
735
|
-
class KbqDatepicker {
|
|
736
|
-
// TODO: Skipped for migration because:
|
|
737
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
738
|
-
get hasBackdrop() {
|
|
739
|
-
return this._hasBackdrop;
|
|
620
|
+
var DateParts;
|
|
621
|
+
(function (DateParts) {
|
|
622
|
+
DateParts["year"] = "y";
|
|
623
|
+
DateParts["month"] = "m";
|
|
624
|
+
DateParts["day"] = "d";
|
|
625
|
+
})(DateParts || (DateParts = {}));
|
|
626
|
+
const MAX_YEAR = 9999;
|
|
627
|
+
const YEAR_LENGTH = 4;
|
|
628
|
+
class DateDigit {
|
|
629
|
+
constructor(value, start, length) {
|
|
630
|
+
this.value = value;
|
|
631
|
+
this.start = start;
|
|
632
|
+
this.length = length;
|
|
633
|
+
this.maxDays = 31;
|
|
634
|
+
this.maxMonth = 12;
|
|
635
|
+
if (value === DateParts.day) {
|
|
636
|
+
this.parse = this.parseDay;
|
|
637
|
+
}
|
|
638
|
+
else if (value === DateParts.month) {
|
|
639
|
+
this.parse = this.parseMonth;
|
|
640
|
+
}
|
|
641
|
+
else if (value === DateParts.year) {
|
|
642
|
+
this.parse = this.parseYear;
|
|
643
|
+
}
|
|
740
644
|
}
|
|
741
|
-
|
|
742
|
-
this.
|
|
645
|
+
get end() {
|
|
646
|
+
return this.start + this.length;
|
|
743
647
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
747
|
-
get startAt() {
|
|
748
|
-
// If an explicit startAt is set we start there, otherwise we start at whatever the currently
|
|
749
|
-
// selected value is.
|
|
750
|
-
return this._startAt || this.datepickerInput?.value;
|
|
648
|
+
get isDay() {
|
|
649
|
+
return this.value === DateParts.day;
|
|
751
650
|
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
this._startAt =
|
|
755
|
-
deserializedValue !== null
|
|
756
|
-
? this.dateAdapter.clampDate(deserializedValue, this.minDate(), this.maxDate())
|
|
757
|
-
: null;
|
|
651
|
+
get isMonth() {
|
|
652
|
+
return this.value === DateParts.month;
|
|
758
653
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
762
|
-
get disabled() {
|
|
763
|
-
return this._disabled === undefined && this.datepickerInput ? this.datepickerInput.disabled : this._disabled;
|
|
654
|
+
get isYear() {
|
|
655
|
+
return this.value === DateParts.year;
|
|
764
656
|
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
this._disabled = newValue;
|
|
769
|
-
this.disabledChange.next(newValue);
|
|
657
|
+
get fullName() {
|
|
658
|
+
if (this.isDay) {
|
|
659
|
+
return 'date';
|
|
770
660
|
}
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
// TODO: Skipped for migration because:
|
|
774
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
775
|
-
get opened() {
|
|
776
|
-
return this._opened;
|
|
777
|
-
}
|
|
778
|
-
set opened(value) {
|
|
779
|
-
if (coerceBooleanProperty(value)) {
|
|
780
|
-
this.open();
|
|
661
|
+
if (this.isMonth) {
|
|
662
|
+
return 'month';
|
|
781
663
|
}
|
|
782
|
-
|
|
783
|
-
|
|
664
|
+
if (this.isYear) {
|
|
665
|
+
return 'year';
|
|
784
666
|
}
|
|
667
|
+
return '';
|
|
785
668
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
this.
|
|
669
|
+
parseDay(value) {
|
|
670
|
+
const parsedValue = parseInt(value);
|
|
671
|
+
if (parsedValue === 0) {
|
|
672
|
+
return 1;
|
|
673
|
+
}
|
|
674
|
+
if (parsedValue > this.maxDays) {
|
|
675
|
+
return this.maxDays;
|
|
676
|
+
}
|
|
677
|
+
return parsedValue;
|
|
792
678
|
}
|
|
793
|
-
|
|
794
|
-
|
|
679
|
+
parseMonth(value) {
|
|
680
|
+
const parsedValue = parseInt(value);
|
|
681
|
+
if (parsedValue === 0) {
|
|
682
|
+
return 1;
|
|
683
|
+
}
|
|
684
|
+
if (parsedValue > this.maxMonth) {
|
|
685
|
+
return this.maxMonth;
|
|
686
|
+
}
|
|
687
|
+
return parsedValue;
|
|
795
688
|
}
|
|
796
|
-
|
|
797
|
-
|
|
689
|
+
parseYear(value) {
|
|
690
|
+
const parsedValue = parseInt(value);
|
|
691
|
+
if (parsedValue === 0) {
|
|
692
|
+
return 1;
|
|
693
|
+
}
|
|
694
|
+
if (parsedValue > MAX_YEAR) {
|
|
695
|
+
return parseInt(value.substring(0, YEAR_LENGTH));
|
|
696
|
+
}
|
|
697
|
+
return parsedValue;
|
|
798
698
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
this.selectedChanged = new Subject();
|
|
836
|
-
/** The id for the datepicker calendar. */
|
|
837
|
-
this.id = `kbq-datepicker-${datepickerUid++}`;
|
|
838
|
-
this.validSelected = null;
|
|
839
|
-
/** The element that was focused before the datepicker was opened. */
|
|
840
|
-
this.focusedElementBeforeOpen = null;
|
|
841
|
-
/** Subscription to value changes in the associated input element. */
|
|
842
|
-
this.inputSubscription = Subscription.EMPTY;
|
|
843
|
-
this.closeSubscription = Subscription.EMPTY;
|
|
844
|
-
this.scrollStrategy = inject(KBQ_DATEPICKER_SCROLL_STRATEGY);
|
|
699
|
+
}
|
|
700
|
+
/** @docs-private */
|
|
701
|
+
const KBQ_DATEPICKER_VALUE_ACCESSOR = {
|
|
702
|
+
provide: NG_VALUE_ACCESSOR,
|
|
703
|
+
useExisting: forwardRef(() => KbqDatepickerInput),
|
|
704
|
+
multi: true
|
|
705
|
+
};
|
|
706
|
+
/** @docs-private */
|
|
707
|
+
const KBQ_DATEPICKER_VALIDATORS = {
|
|
708
|
+
provide: NG_VALIDATORS,
|
|
709
|
+
useExisting: forwardRef(() => KbqDatepickerInput),
|
|
710
|
+
multi: true
|
|
711
|
+
};
|
|
712
|
+
/** default configuration of datepicker */
|
|
713
|
+
/** @docs-private */
|
|
714
|
+
const KBQ_DATEPICKER_DEFAULT_LOCALE_CONFIGURATION = ruRULocaleData.datepicker;
|
|
715
|
+
/** The `datepicker` section of the shipped locale `localeId`, if the library ships one. */
|
|
716
|
+
const shippedDatepickerLocaleConfiguration = (localeId) => {
|
|
717
|
+
const shipped = KBQ_DEFAULT_LOCALE_DATA_FACTORY();
|
|
718
|
+
const locale = shipped[localeId];
|
|
719
|
+
// A shipped locale is complete, its sections included.
|
|
720
|
+
return locale && !Array.isArray(locale) ? locale.datepicker : undefined;
|
|
721
|
+
};
|
|
722
|
+
/** The values of the token's own factory, told apart from strings an application provides for the token. */
|
|
723
|
+
const factoryDefaults = new WeakSet();
|
|
724
|
+
/** Injection Token for providing configuration of datepicker */
|
|
725
|
+
/** @docs-private */
|
|
726
|
+
const KBQ_DATEPICKER_LOCALE_CONFIGURATION = new InjectionToken('KbqDatepickerLocaleConfiguration', {
|
|
727
|
+
factory: () => {
|
|
728
|
+
// A copy: the shipped section itself may also be provided on purpose.
|
|
729
|
+
const configuration = {
|
|
730
|
+
...(shippedDatepickerLocaleConfiguration(inject(KBQ_DATE_LOCALE)) ??
|
|
731
|
+
KBQ_DATEPICKER_DEFAULT_LOCALE_CONFIGURATION)
|
|
732
|
+
};
|
|
733
|
+
factoryDefaults.add(configuration);
|
|
734
|
+
return configuration;
|
|
845
735
|
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
736
|
+
});
|
|
737
|
+
/** The default strings of one input. */
|
|
738
|
+
const KBQ_DATEPICKER_INPUT_LOCALE_CONFIGURATION = new InjectionToken('KbqDatepickerInputLocaleConfiguration');
|
|
739
|
+
/**
|
|
740
|
+
* Unless strings are provided for the token, those of the format the input parses: the token's own default resolves
|
|
741
|
+
* in the root injector, which knows only the date locale of the application, not the date adapter of the input.
|
|
742
|
+
*/
|
|
743
|
+
const datepickerInputLocaleConfiguration = () => {
|
|
744
|
+
const configuration = inject(KBQ_DATEPICKER_LOCALE_CONFIGURATION);
|
|
745
|
+
const adapter = inject(DateAdapter, { optional: true });
|
|
746
|
+
if (!factoryDefaults.has(configuration) || !adapter?.config)
|
|
747
|
+
return configuration;
|
|
748
|
+
const format = inject(KBQ_DATE_FORMATS, { optional: true })?.dateInput || adapter.config.dateInput;
|
|
749
|
+
// The shipped placeholders name the locale's own format, lower-cased and translated.
|
|
750
|
+
const shipped = format === adapter.config.dateInput && shippedDatepickerLocaleConfiguration(adapter.config.name);
|
|
751
|
+
return shipped || { placeholder: format.toLowerCase() };
|
|
752
|
+
};
|
|
753
|
+
/**
|
|
754
|
+
* Utility provider for `KBQ_DATEPICKER_LOCALE_CONFIGURATION`. Only the strings you pass are overridden; the rest
|
|
755
|
+
* keep following the active locale.
|
|
756
|
+
*/
|
|
757
|
+
const kbqDatepickerLocaleConfigurationProvider = (configuration) => kbqLocaleConfigurationOverrideProvider('datepicker', configuration);
|
|
758
|
+
/** @deprecated Use {@link KBQ_DATEPICKER_DEFAULT_LOCALE_CONFIGURATION}. Will be removed in 22.0.0. */
|
|
759
|
+
const KBQ_DATEPICKER_DEFAULT_CONFIGURATION = KBQ_DATEPICKER_DEFAULT_LOCALE_CONFIGURATION;
|
|
760
|
+
/** @deprecated Use {@link KBQ_DATEPICKER_LOCALE_CONFIGURATION}. Will be removed in 22.0.0. */
|
|
761
|
+
const KBQ_DATEPICKER_CONFIGURATION = KBQ_DATEPICKER_LOCALE_CONFIGURATION;
|
|
762
|
+
/**
|
|
763
|
+
* An event used for datepicker input and change events. We don't always have access to a native
|
|
764
|
+
* input or change event because the event may have been triggered by the user clicking on the
|
|
765
|
+
* calendar popup. For consistency, we always use KbqDatepickerInputEvent instead.
|
|
766
|
+
*/
|
|
767
|
+
class KbqDatepickerInputEvent {
|
|
768
|
+
constructor(
|
|
769
|
+
/** Reference to the datepicker input component that emitted the event. */
|
|
770
|
+
target,
|
|
771
|
+
/** Reference to the native input element associated with the datepicker input. */
|
|
772
|
+
targetElement) {
|
|
773
|
+
this.target = target;
|
|
774
|
+
this.targetElement = targetElement;
|
|
775
|
+
this.value = this.target.value();
|
|
852
776
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
777
|
+
}
|
|
778
|
+
let uniqueComponentIdSuffix = 0;
|
|
779
|
+
/** Directive used to connect an input to a KbqDatepicker. */
|
|
780
|
+
class KbqDatepickerInput {
|
|
781
|
+
/** The datepicker that this input is associated with. */
|
|
782
|
+
set kbqDatepicker(value) {
|
|
783
|
+
if (!value) {
|
|
784
|
+
return;
|
|
859
785
|
}
|
|
786
|
+
this.datepicker = value;
|
|
787
|
+
this.datepicker.registerInput(this);
|
|
788
|
+
this.datepickerSubscription.unsubscribe();
|
|
789
|
+
this.datepickerSubscription = this.datepicker.selectedChanged.subscribe((selected) => {
|
|
790
|
+
const newValue = this.saveTimePart(selected);
|
|
791
|
+
this.setValue(newValue);
|
|
792
|
+
this.cvaOnChange(newValue);
|
|
793
|
+
this.onTouched();
|
|
794
|
+
this.dateChange.emit(new KbqDatepickerInputEvent(this, this.elementRef.nativeElement));
|
|
795
|
+
});
|
|
860
796
|
}
|
|
861
|
-
/**
|
|
862
|
-
|
|
863
|
-
|
|
797
|
+
/** The calendar that this input is associated with. */
|
|
798
|
+
set kbqCalendar(value) {
|
|
799
|
+
if (!value) {
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
this.calendar = value;
|
|
803
|
+
this.calendar.registerInput(this);
|
|
864
804
|
}
|
|
865
|
-
/**
|
|
866
|
-
|
|
867
|
-
|
|
805
|
+
/** Function that can be used to filter out dates within the datepicker. `undefined` removes the filter. */
|
|
806
|
+
set kbqDatepickerFilter(value) {
|
|
807
|
+
// `dateFilter` is unset until a filter is given; `undefined` returns it there.
|
|
808
|
+
this.dateFilter = value;
|
|
809
|
+
this.validatorOnChange();
|
|
868
810
|
}
|
|
869
811
|
/**
|
|
870
|
-
*
|
|
871
|
-
*
|
|
812
|
+
* The minimum valid date. Drives validation only — including dates typed or pasted into the
|
|
813
|
+
* input — and reports `kbqDatepickerMin`. The calendar is restricted separately, by `minDate`
|
|
814
|
+
* on the associated `<kbq-datepicker>`.
|
|
815
|
+
*
|
|
816
|
+
* Compared down to the millisecond, not by calendar day: the input keeps the time part of the
|
|
817
|
+
* value it parses, and the comparison is made on wall-clock components rather than on absolute
|
|
818
|
+
* time.
|
|
872
819
|
*/
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
throw Error('A KbqDatepicker can only be associated with a single input.');
|
|
876
|
-
}
|
|
877
|
-
this.datepickerInput = input;
|
|
878
|
-
this.inputSubscription = this.datepickerInput.valueChange.subscribe((value) => {
|
|
879
|
-
this.selected = value;
|
|
880
|
-
if (this.popupComponentRef) {
|
|
881
|
-
const calendar = this.popupComponentRef.instance.calendar();
|
|
882
|
-
calendar.monthView()?.init();
|
|
883
|
-
calendar.activeDate = value;
|
|
884
|
-
}
|
|
885
|
-
});
|
|
820
|
+
get min() {
|
|
821
|
+
return this._min;
|
|
886
822
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
return;
|
|
891
|
-
}
|
|
892
|
-
if (!this.datepickerInput) {
|
|
893
|
-
throw Error('Attempted to open an KbqDatepicker with no associated input.');
|
|
894
|
-
}
|
|
895
|
-
if (this.document) {
|
|
896
|
-
this.focusedElementBeforeOpen = _getFocusedElementPierceShadowDom();
|
|
897
|
-
}
|
|
898
|
-
this.openAsPopup();
|
|
899
|
-
this._opened = true;
|
|
900
|
-
// TODO: The 'emit' function requires a mandatory void argument
|
|
901
|
-
this.openedStream.emit();
|
|
823
|
+
set min(value) {
|
|
824
|
+
this._min = this.getValidDateOrNull(this.adapter.deserialize(value));
|
|
825
|
+
this.validatorOnChange();
|
|
902
826
|
}
|
|
903
|
-
/**
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
this.focusedElementBeforeOpen.focus();
|
|
915
|
-
}
|
|
916
|
-
this._opened = false;
|
|
917
|
-
// TODO: The 'emit' function requires a mandatory void argument
|
|
918
|
-
this.closedStream.emit();
|
|
919
|
-
this.focusedElementBeforeOpen = null;
|
|
827
|
+
/**
|
|
828
|
+
* The maximum valid date. Drives validation only — including dates typed or pasted into the
|
|
829
|
+
* input — and reports `kbqDatepickerMax`. The calendar is restricted separately, by `maxDate`
|
|
830
|
+
* on the associated `<kbq-datepicker>`.
|
|
831
|
+
*
|
|
832
|
+
* Compared down to the millisecond, not by calendar day: the input keeps the time part of the
|
|
833
|
+
* value it parses, so an upper bound meant to include its whole day has to be the end of that
|
|
834
|
+
* day.
|
|
835
|
+
*/
|
|
836
|
+
get max() {
|
|
837
|
+
return this._max;
|
|
920
838
|
}
|
|
921
|
-
|
|
922
|
-
|
|
839
|
+
set max(value) {
|
|
840
|
+
this._max = this.getValidDateOrNull(this.adapter.deserialize(value));
|
|
841
|
+
this.validatorOnChange();
|
|
842
|
+
}
|
|
843
|
+
set kbqValidationTooltip(tooltip) {
|
|
844
|
+
if (!tooltip) {
|
|
923
845
|
return;
|
|
924
846
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
847
|
+
tooltip.enterDelay = validationTooltipShowDelay;
|
|
848
|
+
tooltip.trigger = 'manual';
|
|
849
|
+
tooltip.initListeners();
|
|
850
|
+
this.incorrectInput.subscribe(() => {
|
|
851
|
+
if (tooltip.isOpen) {
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
tooltip.show();
|
|
855
|
+
setTimeout(() => tooltip.hide(), validationTooltipHideDelay);
|
|
856
|
+
});
|
|
931
857
|
}
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
if (this.popupRef) {
|
|
935
|
-
this.popupRef.dispose();
|
|
936
|
-
this.popupRef = this.popupComponentRef = null;
|
|
937
|
-
}
|
|
858
|
+
get viewValue() {
|
|
859
|
+
return this.elementRef.nativeElement.value;
|
|
938
860
|
}
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
if (!this.calendarPortal) {
|
|
942
|
-
this.calendarPortal = new ComponentPortal(KbqDatepickerContent, this.viewContainerRef);
|
|
943
|
-
}
|
|
944
|
-
if (!this.popupRef) {
|
|
945
|
-
this.createPopup();
|
|
946
|
-
}
|
|
947
|
-
if (!this.popupRef.hasAttached()) {
|
|
948
|
-
this.popupComponentRef = this.popupRef.attach(this.calendarPortal);
|
|
949
|
-
this.popupComponentRef.instance.datepicker = this;
|
|
950
|
-
// Update the position once the calendar has rendered.
|
|
951
|
-
this.ngZone.onStable
|
|
952
|
-
.asObservable()
|
|
953
|
-
.pipe(take(1))
|
|
954
|
-
.subscribe(() => this.popupRef?.updatePosition());
|
|
955
|
-
}
|
|
861
|
+
get ngControl() {
|
|
862
|
+
return this.control;
|
|
956
863
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
const overlayConfig = new OverlayConfig({
|
|
960
|
-
positionStrategy: this.createPopupPositionStrategy(),
|
|
961
|
-
hasBackdrop: this.hasBackdrop,
|
|
962
|
-
backdropClass: this.backdropClass(),
|
|
963
|
-
direction: this.dir,
|
|
964
|
-
scrollStrategy: this.scrollStrategy(),
|
|
965
|
-
panelClass: 'kbq-datepicker__popup'
|
|
966
|
-
});
|
|
967
|
-
this.popupRef = this.overlay.create(overlayConfig);
|
|
968
|
-
this.closeSubscription = this.closingActions().subscribe(() => this.close(this.restoreFocus()));
|
|
864
|
+
get isReadOnly() {
|
|
865
|
+
return this.elementRef.nativeElement.readOnly;
|
|
969
866
|
}
|
|
970
|
-
|
|
971
|
-
return this.
|
|
867
|
+
get dateInputFormat() {
|
|
868
|
+
return this.dateFormats?.dateInput || this.adapter.config.dateInput;
|
|
972
869
|
}
|
|
973
|
-
|
|
974
|
-
return
|
|
870
|
+
get readyForParse() {
|
|
871
|
+
return !!(this.firstDigit && this.secondDigit && this.thirdDigit);
|
|
975
872
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
873
|
+
get selectionStart() {
|
|
874
|
+
return this.elementRef.nativeElement.selectionStart;
|
|
875
|
+
}
|
|
876
|
+
get selectionEnd() {
|
|
877
|
+
return this.elementRef.nativeElement.selectionEnd;
|
|
878
|
+
}
|
|
879
|
+
constructor() {
|
|
880
|
+
this.elementRef = inject(ElementRef);
|
|
881
|
+
this.renderer = inject(Renderer2);
|
|
882
|
+
this.adapter = injectRequiredDateAdapter();
|
|
883
|
+
this.timezoneService = inject(KbqDateTimezoneService);
|
|
884
|
+
this.dateFormats = inject(KBQ_DATE_FORMATS, { optional: true });
|
|
885
|
+
/** @docs-private */
|
|
886
|
+
this.formField = inject(KBQ_FORM_FIELD, { optional: true, host: true });
|
|
887
|
+
this.localeConfiguration = inject(KbqLocaleOverridesDirective, { self: true }).read('datepicker', KBQ_DATEPICKER_INPUT_LOCALE_CONFIGURATION);
|
|
888
|
+
this.errorStateTracker = new KbqErrorStateTracker(inject(ErrorStateMatcher),
|
|
889
|
+
// update ngControl later, so it will be initialized
|
|
890
|
+
null, inject(FormGroupDirective, { optional: true }), inject(NgForm, { optional: true }));
|
|
891
|
+
/** Whether the input is in an error state. */
|
|
892
|
+
this.errorState = this.errorStateTracker.errorState;
|
|
893
|
+
this.controlType = 'datepicker';
|
|
894
|
+
this.focusedValue = signal(false, ...(ngDevMode ? [{ debugName: "focusedValue" }] : /* istanbul ignore next */ []));
|
|
895
|
+
/** Whether the input has focus. */
|
|
896
|
+
this.focused = this.focusedValue.asReadonly();
|
|
897
|
+
/** Emits when the value changes (either due to user input or programmatic change). */
|
|
898
|
+
this.valueChange = new EventEmitter();
|
|
899
|
+
/** Emits when the disabled state has changed */
|
|
900
|
+
this.disabledChange = new EventEmitter();
|
|
901
|
+
/** Object used to control when error messages are shown. */
|
|
902
|
+
this.errorStateMatcher = input(...(ngDevMode ? [undefined, { debugName: "errorStateMatcher" }] : /* istanbul ignore next */ []));
|
|
903
|
+
/** @docs-private */
|
|
904
|
+
this.placeholderInput = input(undefined, { ...(ngDevMode ? { debugName: "placeholderInput" } : /* istanbul ignore next */ {}), alias: 'placeholder' });
|
|
905
|
+
/** Placeholder of the input. Defaults to the localized date pattern. */
|
|
906
|
+
this.placeholder = computed(() => this.placeholderInput() || this.localeConfiguration().placeholder, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
907
|
+
/** Whether the input is required. */
|
|
908
|
+
this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
909
|
+
/** @docs-private */
|
|
910
|
+
this.kbqDatepickerInput = input(undefined, { ...(ngDevMode ? { debugName: "kbqDatepickerInput" } : /* istanbul ignore next */ {}), alias: 'kbqDatepicker' });
|
|
911
|
+
/** @docs-private */
|
|
912
|
+
this.kbqCalendarInput = input(undefined, { ...(ngDevMode ? { debugName: "kbqCalendarInput" } : /* istanbul ignore next */ {}), alias: 'kbqCalendar' });
|
|
913
|
+
/** @docs-private */
|
|
914
|
+
this.kbqDatepickerFilterInput = input(undefined, { ...(ngDevMode ? { debugName: "kbqDatepickerFilterInput" } : /* istanbul ignore next */ {}), alias: 'kbqDatepickerFilter' });
|
|
915
|
+
/** @docs-private */
|
|
916
|
+
this.valueInput = input(undefined, { ...(ngDevMode ? { debugName: "valueInput" } : /* istanbul ignore next */ {}), alias: 'value' });
|
|
917
|
+
this.valueState = signal(null, ...(ngDevMode ? [{ debugName: "valueState" }] : /* istanbul ignore next */ []));
|
|
918
|
+
/** The date the input holds: set with `[value]`, by the form control, by typing and by the calendar. */
|
|
919
|
+
this.value = this.valueState.asReadonly();
|
|
920
|
+
/** @docs-private */
|
|
921
|
+
this.minInput = input(undefined, { ...(ngDevMode ? { debugName: "minInput" } : /* istanbul ignore next */ {}), alias: 'min' });
|
|
922
|
+
/** @docs-private */
|
|
923
|
+
this.maxInput = input(undefined, { ...(ngDevMode ? { debugName: "maxInput" } : /* istanbul ignore next */ {}), alias: 'max' });
|
|
924
|
+
/** @docs-private */
|
|
925
|
+
this.disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
|
|
926
|
+
transform: booleanAttribute });
|
|
927
|
+
/** Whether the datepicker-input is disabled. Also set by the bound form control. */
|
|
928
|
+
this.disabled = linkedSignal(() => this.disabledInput(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
929
|
+
/** @docs-private */
|
|
930
|
+
this.idInput = input(undefined, { ...(ngDevMode ? { debugName: "idInput" } : /* istanbul ignore next */ {}), alias: 'id' });
|
|
931
|
+
/** Unique id of the element, generated when not provided. */
|
|
932
|
+
this.id = computed(() => this.idInput() || this.uid, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
933
|
+
/** @docs-private */
|
|
934
|
+
this.kbqValidationTooltipInput = input(undefined, { ...(ngDevMode ? { debugName: "kbqValidationTooltipInput" } : /* istanbul ignore next */ {}), alias: 'kbqValidationTooltip' });
|
|
935
|
+
this.incorrectInput = output();
|
|
936
|
+
/** Emits when a `change` event is fired on this `<input>`. */
|
|
937
|
+
this.dateChange = output();
|
|
938
|
+
/** Emits when an `input` event is fired on this `<input>`. */
|
|
939
|
+
this.dateInput = output();
|
|
940
|
+
this.emptyValue = signal(true, ...(ngDevMode ? [{ debugName: "emptyValue" }] : /* istanbul ignore next */ []));
|
|
941
|
+
/** Whether the input renders no text. */
|
|
942
|
+
this.empty = this.emptyValue.asReadonly();
|
|
943
|
+
this.uid = `kbq-datepicker-input-${uniqueComponentIdSuffix++}`;
|
|
944
|
+
this.datepickerSubscription = Subscription.EMPTY;
|
|
945
|
+
/** Whether the last value set on the input was valid. */
|
|
946
|
+
this.lastValueValid = false;
|
|
947
|
+
this.firstDigit = null;
|
|
948
|
+
this.secondDigit = null;
|
|
949
|
+
this.thirdDigit = null;
|
|
950
|
+
/** Work the keys left to timers, in the order the timers run. */
|
|
951
|
+
this.deferred = new Map();
|
|
952
|
+
/**
|
|
953
|
+
* Called when the control is blurred. Needed to properly implement `ControlValueAccessor`.
|
|
954
|
+
*
|
|
955
|
+
* @docs-private
|
|
956
|
+
*/
|
|
957
|
+
this.onTouched = () => { };
|
|
958
|
+
this.onInput = () => {
|
|
959
|
+
const cursorPosition = this.correctedCursorPosition();
|
|
960
|
+
const formattedValue = this.replaceSymbols(this.viewValue);
|
|
961
|
+
const newTimeObj = this.getDateFromString(formattedValue);
|
|
962
|
+
this.lastValueValid = !!newTimeObj;
|
|
963
|
+
if (!newTimeObj) {
|
|
964
|
+
if (!this.viewValue) {
|
|
965
|
+
this.lastValueValid = false;
|
|
966
|
+
this.updateValue(newTimeObj);
|
|
967
|
+
}
|
|
968
|
+
else {
|
|
969
|
+
this.control?.updateValueAndValidity();
|
|
970
|
+
}
|
|
971
|
+
return;
|
|
1014
972
|
}
|
|
1015
|
-
|
|
973
|
+
this.setViewValue(this.getTimeStringFromDate(newTimeObj, this.dateInputFormat), true);
|
|
974
|
+
this.selectNextDigitByCursor(cursorPosition);
|
|
975
|
+
this.updateValue(newTimeObj);
|
|
976
|
+
};
|
|
977
|
+
this.parseOnBlur = () => {
|
|
978
|
+
if (!this.viewValue || !this.readyForParse) {
|
|
979
|
+
return null;
|
|
980
|
+
}
|
|
981
|
+
const date = this.getDefaultValue();
|
|
982
|
+
const viewDigits = this.viewValue
|
|
983
|
+
.split(this.separator)
|
|
984
|
+
.map((value) => value)
|
|
985
|
+
.filter((value) => value);
|
|
986
|
+
const [firsViewDigit, secondViewDigit, thirdViewDigit] = viewDigits;
|
|
987
|
+
if (viewDigits.length !== 3) {
|
|
988
|
+
this.lastValueValid = false;
|
|
989
|
+
this.valueState.set(null);
|
|
990
|
+
return setTimeout(() => this.control?.updateValueAndValidity());
|
|
991
|
+
}
|
|
992
|
+
date[this.firstDigit.fullName] = this.firstDigit.parse(firsViewDigit);
|
|
993
|
+
date[this.secondDigit.fullName] = this.secondDigit.parse(secondViewDigit);
|
|
994
|
+
date[this.thirdDigit.fullName] = this.thirdDigit.parse(thirdViewDigit);
|
|
995
|
+
const [digitWithYear, viewDigitWithYear] = [this.firstDigit, this.secondDigit, this.thirdDigit].reduce((acc, digit, index) => (digit.value === DateParts.year ? [digit, viewDigits[index]] : acc), []);
|
|
996
|
+
if (viewDigitWithYear.length < 3) {
|
|
997
|
+
date.year += date.year < 30 ? 2000 : 1900;
|
|
998
|
+
}
|
|
999
|
+
else if (viewDigitWithYear.length < digitWithYear.length) {
|
|
1000
|
+
this.lastValueValid = false;
|
|
1001
|
+
this.valueState.set(null);
|
|
1002
|
+
return setTimeout(() => this.control?.updateValueAndValidity());
|
|
1003
|
+
}
|
|
1004
|
+
const newTimeObj = this.createDateTime(date);
|
|
1005
|
+
if (!newTimeObj) {
|
|
1006
|
+
this.lastValueValid = false;
|
|
1007
|
+
this.valueState.set(null);
|
|
1008
|
+
this.cvaOnChange(null);
|
|
1009
|
+
return setTimeout(() => this.control?.updateValueAndValidity());
|
|
1010
|
+
}
|
|
1011
|
+
/* Check if the number of days entered does not match the entered month */
|
|
1012
|
+
if (!this.getValidDateOrNull(newTimeObj)) {
|
|
1013
|
+
return null;
|
|
1014
|
+
}
|
|
1015
|
+
this.lastValueValid = !!newTimeObj;
|
|
1016
|
+
this.setViewValue(this.getTimeStringFromDate(newTimeObj, this.dateInputFormat), true);
|
|
1017
|
+
this.updateValue(newTimeObj);
|
|
1018
|
+
};
|
|
1019
|
+
this.cvaOnChange = () => { };
|
|
1020
|
+
this.validatorOnChange = () => { };
|
|
1021
|
+
/** The form control validator for whether the input parses. */
|
|
1022
|
+
this.parseValidator = () => {
|
|
1023
|
+
return this.focused() || this.isEmpty() || this.lastValueValid
|
|
1024
|
+
? null
|
|
1025
|
+
: { kbqDatepickerParse: { text: this.elementRef.nativeElement.value } };
|
|
1026
|
+
};
|
|
1027
|
+
/** The form control validator for the min date. */
|
|
1028
|
+
this.minValidator = (control) => {
|
|
1029
|
+
// An unparseable value compares as NaN against any bound, which fails both `<= 0` and
|
|
1030
|
+
// `>= 0` and would report the value as simultaneously too early and too late.
|
|
1031
|
+
const controlValue = this.getValidDateOrNull(this.adapter.deserialize(control.value));
|
|
1032
|
+
return !this.min || !controlValue || this.adapter.compareDateTime(this.min, controlValue) <= 0
|
|
1033
|
+
? null
|
|
1034
|
+
: { kbqDatepickerMin: { min: this.min, actual: controlValue } };
|
|
1035
|
+
};
|
|
1036
|
+
/** The form control validator for the max date. */
|
|
1037
|
+
this.maxValidator = (control) => {
|
|
1038
|
+
const controlValue = this.getValidDateOrNull(this.adapter.deserialize(control.value));
|
|
1039
|
+
return !this.max || !controlValue || this.adapter.compareDateTime(this.max, controlValue) >= 0
|
|
1040
|
+
? null
|
|
1041
|
+
: { kbqDatepickerMax: { max: this.max, actual: controlValue } };
|
|
1042
|
+
};
|
|
1043
|
+
/** The form control validator for the date filter. */
|
|
1044
|
+
this.filterValidator = (control) => {
|
|
1045
|
+
const controlValue = this.adapter.deserialize(control.value);
|
|
1046
|
+
return !this.dateFilter || !controlValue || this.dateFilter(controlValue)
|
|
1047
|
+
? null
|
|
1048
|
+
: { kbqDatepickerFilter: true };
|
|
1049
|
+
};
|
|
1050
|
+
this.validator = Validators.compose([
|
|
1051
|
+
this.parseValidator,
|
|
1052
|
+
this.minValidator,
|
|
1053
|
+
this.maxValidator,
|
|
1054
|
+
this.filterValidator
|
|
1055
|
+
]);
|
|
1056
|
+
this.setFormat(this.dateInputFormat);
|
|
1057
|
+
// A bound value is applied whenever the binding changes; an unbound one leaves the value to the form.
|
|
1058
|
+
let bound = false;
|
|
1059
|
+
effect(() => {
|
|
1060
|
+
const value = this.valueInput();
|
|
1061
|
+
if (!bound && value === undefined)
|
|
1062
|
+
return;
|
|
1063
|
+
bound = true;
|
|
1064
|
+
untracked(() => this.setValue(value ?? null));
|
|
1065
|
+
});
|
|
1066
|
+
let wasDisabled = false;
|
|
1067
|
+
effect(() => {
|
|
1068
|
+
const disabled = this.disabled();
|
|
1069
|
+
untracked(() => {
|
|
1070
|
+
if (disabled !== wasDisabled) {
|
|
1071
|
+
wasDisabled = disabled;
|
|
1072
|
+
this.disabledChange.emit(disabled);
|
|
1073
|
+
}
|
|
1074
|
+
const element = this.elementRef.nativeElement;
|
|
1075
|
+
// We need to null check the `blur` method, because it's undefined during SSR.
|
|
1076
|
+
if (disabled && element.blur) {
|
|
1077
|
+
// Normally, native input elements automatically blur if they turn disabled. This behavior
|
|
1078
|
+
// is problematic, because it would mean that it triggers another change detection cycle,
|
|
1079
|
+
// which then causes a changed after checked error if the input element was focused before.
|
|
1080
|
+
element.blur();
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
});
|
|
1084
|
+
let isFirstRun = true;
|
|
1085
|
+
effect(() => {
|
|
1086
|
+
this.localeConfiguration();
|
|
1087
|
+
// Nothing to re-format on the first run: `setFormat` above already ran against the active
|
|
1088
|
+
// locale, while re-assigning `value` here would emit `valueChange` at a point where the
|
|
1089
|
+
// datepicker and the calendar are already subscribed to it.
|
|
1090
|
+
if (isFirstRun) {
|
|
1091
|
+
isFirstRun = false;
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
// The date adapter follows the same locale, so its input format may have changed with it: the
|
|
1095
|
+
// digit layout has to be re-derived and the rendered value re-formatted.
|
|
1096
|
+
untracked(() => {
|
|
1097
|
+
this.setFormat(this.dateInputFormat);
|
|
1098
|
+
this.setValue(this.valueState());
|
|
1099
|
+
});
|
|
1100
|
+
});
|
|
1101
|
+
this.timezoneService.changes.pipe(takeUntilDestroyed()).subscribe(() => {
|
|
1102
|
+
// The rendered text names a wall clock in the zone it was formatted in. Left as it is, the
|
|
1103
|
+
// next keystroke re-parses it against the new zone and emits a different instant.
|
|
1104
|
+
this.setValue(this.valueState());
|
|
1105
|
+
});
|
|
1016
1106
|
}
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
DateParts["year"] = "y";
|
|
1043
|
-
DateParts["month"] = "m";
|
|
1044
|
-
DateParts["day"] = "d";
|
|
1045
|
-
})(DateParts || (DateParts = {}));
|
|
1046
|
-
const MAX_YEAR = 9999;
|
|
1047
|
-
const YEAR_LENGTH = 4;
|
|
1048
|
-
class DateDigit {
|
|
1049
|
-
constructor(value, start, length) {
|
|
1050
|
-
this.value = value;
|
|
1051
|
-
this.start = start;
|
|
1052
|
-
this.length = length;
|
|
1053
|
-
this.maxDays = 31;
|
|
1054
|
-
this.maxMonth = 12;
|
|
1055
|
-
if (value === DateParts.day) {
|
|
1056
|
-
this.parse = this.parseDay;
|
|
1107
|
+
ngOnChanges(changes) {
|
|
1108
|
+
// A bound input is handed to its member; unbound, it leaves what code wrote.
|
|
1109
|
+
// Not in an effect, which runs too late: `min`, `max` and the filter revalidate the form control before the
|
|
1110
|
+
// template reads its errors.
|
|
1111
|
+
if (changes['kbqDatepickerInput']) {
|
|
1112
|
+
const datepicker = this.kbqDatepickerInput();
|
|
1113
|
+
if (datepicker !== undefined)
|
|
1114
|
+
this.kbqDatepicker = datepicker;
|
|
1115
|
+
}
|
|
1116
|
+
if (changes['kbqCalendarInput']) {
|
|
1117
|
+
const calendar = this.kbqCalendarInput();
|
|
1118
|
+
if (calendar !== undefined)
|
|
1119
|
+
this.kbqCalendar = calendar;
|
|
1120
|
+
}
|
|
1121
|
+
// A bound `undefined` is handed over too: it removes the filter.
|
|
1122
|
+
if (changes['kbqDatepickerFilterInput'])
|
|
1123
|
+
this.kbqDatepickerFilter = this.kbqDatepickerFilterInput();
|
|
1124
|
+
if (changes['minInput'])
|
|
1125
|
+
this.min = this.minInput() ?? null;
|
|
1126
|
+
if (changes['maxInput'])
|
|
1127
|
+
this.max = this.maxInput() ?? null;
|
|
1128
|
+
if (changes['kbqValidationTooltipInput']) {
|
|
1129
|
+
const tooltip = this.kbqValidationTooltipInput();
|
|
1130
|
+
if (tooltip !== undefined)
|
|
1131
|
+
this.kbqValidationTooltip = tooltip;
|
|
1057
1132
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1133
|
+
}
|
|
1134
|
+
ngDoCheck() {
|
|
1135
|
+
if (this.ngControl) {
|
|
1136
|
+
// We need to re-evaluate this on every change detection cycle, because there are some
|
|
1137
|
+
// error triggers that we can't subscribe to (e.g. parent form submissions). This means
|
|
1138
|
+
// that whatever logic is in here has to be super lean or we risk destroying the performance.
|
|
1139
|
+
this.updateErrorState();
|
|
1060
1140
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1141
|
+
// The browser changes the rendered text without notice as the user types; `setViewValue()` covers the rest.
|
|
1142
|
+
this.emptyValue.set(this.isEmpty());
|
|
1143
|
+
}
|
|
1144
|
+
onContainerClick() {
|
|
1145
|
+
this.focus();
|
|
1146
|
+
}
|
|
1147
|
+
focus() {
|
|
1148
|
+
this.elementRef.nativeElement.focus();
|
|
1149
|
+
}
|
|
1150
|
+
focusChanged(isFocused) {
|
|
1151
|
+
if (isFocused !== this.focused()) {
|
|
1152
|
+
this.focusedValue.set(isFocused);
|
|
1153
|
+
this.onTouched();
|
|
1063
1154
|
}
|
|
1064
1155
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1156
|
+
ngAfterContentInit() {
|
|
1157
|
+
this.updateErrorState();
|
|
1067
1158
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1159
|
+
ngOnDestroy() {
|
|
1160
|
+
this.datepickerSubscription.unsubscribe();
|
|
1161
|
+
this.valueChange.complete();
|
|
1162
|
+
this.disabledChange.complete();
|
|
1070
1163
|
}
|
|
1071
|
-
|
|
1072
|
-
|
|
1164
|
+
/** @docs-private */
|
|
1165
|
+
registerOnValidatorChange(fn) {
|
|
1166
|
+
this.validatorOnChange = fn;
|
|
1073
1167
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1168
|
+
/** @docs-private */
|
|
1169
|
+
validate(control) {
|
|
1170
|
+
this.setControl(control);
|
|
1171
|
+
// Untracked, as `writeValue()`: a form control set from a consumer's `effect()` writes and validates on the
|
|
1172
|
+
// spot, and the state read on the way — `focused`, the value — would make the effect run again.
|
|
1173
|
+
return this.validator ? untracked(() => this.validator(control)) : null;
|
|
1076
1174
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1175
|
+
// Implemented as part of ControlValueAccessor.
|
|
1176
|
+
writeValue(value) {
|
|
1177
|
+
untracked(() => this.setValue(value));
|
|
1178
|
+
}
|
|
1179
|
+
// Implemented as part of ControlValueAccessor.
|
|
1180
|
+
registerOnChange(fn) {
|
|
1181
|
+
this.cvaOnChange = fn;
|
|
1182
|
+
}
|
|
1183
|
+
// Implemented as part of ControlValueAccessor.
|
|
1184
|
+
registerOnTouched(fn) {
|
|
1185
|
+
this.onTouched = fn;
|
|
1186
|
+
}
|
|
1187
|
+
// Implemented as part of ControlValueAccessor.
|
|
1188
|
+
setDisabledState(isDisabled) {
|
|
1189
|
+
this.disabled.set(isDisabled);
|
|
1190
|
+
}
|
|
1191
|
+
onKeyDown(event) {
|
|
1192
|
+
if (this.isReadOnly) {
|
|
1193
|
+
return;
|
|
1080
1194
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1195
|
+
// Keys from a scanner, an autotype or a busy page arrive before the timers the previous ones set. Run that
|
|
1196
|
+
// work first, so that each key acts on the value and selection a slower typist's would.
|
|
1197
|
+
this.runDeferred();
|
|
1198
|
+
const keyCode = event.keyCode;
|
|
1199
|
+
if (this.isLetterKey(event)) {
|
|
1200
|
+
event.preventDefault();
|
|
1201
|
+
this.incorrectInput.emit();
|
|
1083
1202
|
}
|
|
1084
|
-
if (this.
|
|
1085
|
-
|
|
1203
|
+
else if (this.isKeyForOpen(event)) {
|
|
1204
|
+
event.preventDefault();
|
|
1205
|
+
this.datepicker?.open();
|
|
1086
1206
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1207
|
+
else if (this.isKeyForClose(event)) {
|
|
1208
|
+
// Consumed only when there is a calendar to close, so a dialog around the input still takes the key.
|
|
1209
|
+
if (!this.datepicker?.opened)
|
|
1210
|
+
return;
|
|
1211
|
+
event.preventDefault();
|
|
1212
|
+
this.datepicker.close();
|
|
1093
1213
|
}
|
|
1094
|
-
if (
|
|
1095
|
-
|
|
1214
|
+
else if (keyCode === TAB) {
|
|
1215
|
+
this.datepicker?.close(false);
|
|
1096
1216
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
parseMonth(value) {
|
|
1100
|
-
const parsedValue = parseInt(value);
|
|
1101
|
-
if (parsedValue === 0) {
|
|
1102
|
-
return 1;
|
|
1217
|
+
else if (this.isKeyForByPass(event)) {
|
|
1218
|
+
return;
|
|
1103
1219
|
}
|
|
1104
|
-
if (
|
|
1105
|
-
|
|
1220
|
+
else if (keyCode === SPACE) {
|
|
1221
|
+
this.spaceKeyHandler(event);
|
|
1106
1222
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
const parsedValue = parseInt(value);
|
|
1111
|
-
if (parsedValue === 0) {
|
|
1112
|
-
return 1;
|
|
1223
|
+
else if ([UP_ARROW, DOWN_ARROW].includes(keyCode)) {
|
|
1224
|
+
event.preventDefault();
|
|
1225
|
+
this.verticalArrowKeyHandler(keyCode);
|
|
1113
1226
|
}
|
|
1114
|
-
if (
|
|
1115
|
-
|
|
1227
|
+
else if ([LEFT_ARROW, RIGHT_ARROW, HOME, PAGE_UP, END, PAGE_DOWN].includes(keyCode)) {
|
|
1228
|
+
event.preventDefault();
|
|
1229
|
+
this.changeCaretPosition(keyCode);
|
|
1230
|
+
}
|
|
1231
|
+
else if (/^\D$/.test(event.key)) {
|
|
1232
|
+
event.preventDefault();
|
|
1233
|
+
const newValue = this.getNewValue(event.key, this.selectionStart);
|
|
1234
|
+
const formattedValue = this.replaceSymbols(newValue);
|
|
1235
|
+
if (newValue !== formattedValue) {
|
|
1236
|
+
this.setViewValue(formattedValue, true);
|
|
1237
|
+
this.defer(this.onInput);
|
|
1238
|
+
}
|
|
1239
|
+
else {
|
|
1240
|
+
this.incorrectInput.emit();
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
else {
|
|
1244
|
+
this.defer(this.onInput);
|
|
1116
1245
|
}
|
|
1117
|
-
return parsedValue;
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
/** @docs-private */
|
|
1121
|
-
const KBQ_DATEPICKER_VALUE_ACCESSOR = {
|
|
1122
|
-
provide: NG_VALUE_ACCESSOR,
|
|
1123
|
-
useExisting: forwardRef(() => KbqDatepickerInput),
|
|
1124
|
-
multi: true
|
|
1125
|
-
};
|
|
1126
|
-
/** @docs-private */
|
|
1127
|
-
const KBQ_DATEPICKER_VALIDATORS = {
|
|
1128
|
-
provide: NG_VALIDATORS,
|
|
1129
|
-
useExisting: forwardRef(() => KbqDatepickerInput),
|
|
1130
|
-
multi: true
|
|
1131
|
-
};
|
|
1132
|
-
/** default configuration of datepicker */
|
|
1133
|
-
/** @docs-private */
|
|
1134
|
-
const KBQ_DATEPICKER_DEFAULT_CONFIGURATION = ruRULocaleData.datepicker;
|
|
1135
|
-
/** Injection Token for providing configuration of datepicker */
|
|
1136
|
-
/** @docs-private */
|
|
1137
|
-
const KBQ_DATEPICKER_CONFIGURATION = new InjectionToken('KbqDatepickerConfiguration');
|
|
1138
|
-
/**
|
|
1139
|
-
* An event used for datepicker input and change events. We don't always have access to a native
|
|
1140
|
-
* input or change event because the event may have been triggered by the user clicking on the
|
|
1141
|
-
* calendar popup. For consistency, we always use KbqDatepickerInputEvent instead.
|
|
1142
|
-
*/
|
|
1143
|
-
class KbqDatepickerInputEvent {
|
|
1144
|
-
constructor(
|
|
1145
|
-
/** Reference to the datepicker input component that emitted the event. */
|
|
1146
|
-
target,
|
|
1147
|
-
/** Reference to the native input element associated with the datepicker input. */
|
|
1148
|
-
targetElement) {
|
|
1149
|
-
this.target = target;
|
|
1150
|
-
this.targetElement = targetElement;
|
|
1151
|
-
this.value = this.target.value;
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
let uniqueComponentIdSuffix = 0;
|
|
1155
|
-
/** Directive used to connect an input to a KbqDatepicker. */
|
|
1156
|
-
class KbqDatepickerInput {
|
|
1157
|
-
/** Object used to control when error messages are shown. */
|
|
1158
|
-
// TODO: Skipped for migration because:
|
|
1159
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
1160
|
-
get errorStateMatcher() {
|
|
1161
|
-
return this.errorStateTracker.errorStateMatcher;
|
|
1162
1246
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
1247
|
+
onChange() {
|
|
1248
|
+
setTimeout(() => {
|
|
1249
|
+
this.dateChange.emit(new KbqDatepickerInputEvent(this, this.elementRef.nativeElement));
|
|
1250
|
+
});
|
|
1165
1251
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1252
|
+
/** Handles blur events on the input. */
|
|
1253
|
+
onBlur() {
|
|
1254
|
+
// Reformat the input only if we have a valid value.
|
|
1255
|
+
this.parseOnBlur();
|
|
1256
|
+
this.focusChanged(false);
|
|
1257
|
+
this.onInput();
|
|
1170
1258
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1259
|
+
onPaste($event) {
|
|
1260
|
+
$event.preventDefault();
|
|
1261
|
+
let rawValue = $event.clipboardData.getData('text');
|
|
1262
|
+
if (rawValue.match(/^\d\D/)) {
|
|
1263
|
+
rawValue = `0${rawValue}`;
|
|
1264
|
+
}
|
|
1265
|
+
rawValue.replace(/[^A-Za-z0-9]+/g, this.separator);
|
|
1266
|
+
if (/[a-z]/gi.test(rawValue)) {
|
|
1267
|
+
this.incorrectInput.emit();
|
|
1268
|
+
}
|
|
1269
|
+
const match = rawValue.match(/^(?<first>\d+)\W(?<second>\d+)\W(?<third>\d+)$/);
|
|
1270
|
+
if (!match?.groups?.first || !match?.groups?.second || !match?.groups?.third) {
|
|
1271
|
+
this.setViewValue(rawValue);
|
|
1272
|
+
return rawValue;
|
|
1273
|
+
}
|
|
1274
|
+
const value = [match.groups.first, match.groups.second, match.groups.third].join(this.separator);
|
|
1275
|
+
const newTimeObj = this.getDateFromString(value);
|
|
1276
|
+
if (!newTimeObj) {
|
|
1277
|
+
this.setViewValue(value);
|
|
1278
|
+
return value;
|
|
1279
|
+
}
|
|
1280
|
+
this.setViewValue(this.getTimeStringFromDate(newTimeObj, this.dateInputFormat));
|
|
1281
|
+
this.updateValue(newTimeObj);
|
|
1173
1282
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
get required() {
|
|
1177
|
-
return this._required;
|
|
1283
|
+
toISO8601(value) {
|
|
1284
|
+
return this.adapter.toIso8601(value);
|
|
1178
1285
|
}
|
|
1179
|
-
|
|
1180
|
-
|
|
1286
|
+
/** Refreshes the error state of the input. */
|
|
1287
|
+
updateErrorState() {
|
|
1288
|
+
this.errorStateTracker.errorStateMatcher = this.errorStateMatcher();
|
|
1289
|
+
this.errorStateTracker.updateErrorState();
|
|
1181
1290
|
}
|
|
1182
|
-
/**
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
set kbqDatepicker(value) {
|
|
1186
|
-
if (!value) {
|
|
1187
|
-
return;
|
|
1188
|
-
}
|
|
1189
|
-
this.datepicker = value;
|
|
1190
|
-
this.datepicker.registerInput(this);
|
|
1191
|
-
this.datepickerSubscription.unsubscribe();
|
|
1192
|
-
this.datepickerSubscription = this.datepicker.selectedChanged.subscribe((selected) => {
|
|
1193
|
-
const newValue = this.saveTimePart(selected);
|
|
1194
|
-
this.value = newValue;
|
|
1195
|
-
this.cvaOnChange(newValue);
|
|
1196
|
-
this.onTouched();
|
|
1197
|
-
this.dateChange.emit(new KbqDatepickerInputEvent(this, this.elementRef.nativeElement));
|
|
1198
|
-
});
|
|
1291
|
+
/** Returns the ElementRef of the formField if it exists; otherwise, returns the ElementRef of the input. */
|
|
1292
|
+
getOrigin() {
|
|
1293
|
+
return this.formField ? this.formField.getConnectedOverlayOrigin() : this.elementRef;
|
|
1199
1294
|
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
1203
|
-
set kbqCalendar(value) {
|
|
1295
|
+
saveTimePart(selected) {
|
|
1296
|
+
const value = this.value();
|
|
1204
1297
|
if (!value) {
|
|
1205
|
-
return;
|
|
1298
|
+
return selected;
|
|
1206
1299
|
}
|
|
1207
|
-
|
|
1208
|
-
this.
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
this.
|
|
1215
|
-
this.validatorOnChange();
|
|
1300
|
+
const years = this.adapter.getYear(selected);
|
|
1301
|
+
const month = this.adapter.getMonth(selected);
|
|
1302
|
+
const day = this.adapter.getDate(selected);
|
|
1303
|
+
const hours = this.adapter.getHours(value);
|
|
1304
|
+
const minutes = this.adapter.getMinutes(value);
|
|
1305
|
+
const seconds = this.adapter.getSeconds(value);
|
|
1306
|
+
const milliseconds = this.adapter.getMilliseconds(value);
|
|
1307
|
+
return this.adapter.createDateTime(years, month, day, hours, minutes, seconds, milliseconds);
|
|
1216
1308
|
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1309
|
+
setFormat(format) {
|
|
1310
|
+
// `[a-zA-Z]`, not `[aA-zZ]`: the latter reads as `a`, the range `A-z` and `Z`, and that range
|
|
1311
|
+
// takes in the six characters ASCII puts between the two alphabets — opening bracket,
|
|
1312
|
+
// backslash, closing bracket, caret, underscore and backtick. A format escaping a literal in
|
|
1313
|
+
// brackets could therefore have had that bracket counted as part of a placeholder.
|
|
1314
|
+
this.separator = format.match(/[a-zA-Z]+(?<separator>\W|\D)[a-zA-Z]+/).groups.separator;
|
|
1315
|
+
this.separatorPositions = format
|
|
1316
|
+
.split('')
|
|
1317
|
+
.reduce((acc, item, index) => (this.separator === item ? [...acc, index + 1] : acc), []);
|
|
1318
|
+
this.getDigitPositions(format);
|
|
1222
1319
|
}
|
|
1223
|
-
|
|
1320
|
+
/** Takes a value from any source, re-rendering the element with it. */
|
|
1321
|
+
setValue(value) {
|
|
1224
1322
|
let newValue = this.adapter.deserialize(value);
|
|
1225
1323
|
this.lastValueValid = !newValue || this.adapter.isValid(newValue);
|
|
1226
1324
|
newValue = this.getValidDateOrNull(newValue);
|
|
1227
|
-
const oldDate = this.
|
|
1228
|
-
this.
|
|
1325
|
+
const oldDate = this.valueState();
|
|
1326
|
+
this.valueState.set(newValue);
|
|
1229
1327
|
this.formatValue(newValue);
|
|
1230
1328
|
if (!this.adapter.sameDate(oldDate, newValue)) {
|
|
1231
1329
|
this.valueChange.emit(newValue);
|
|
1232
1330
|
}
|
|
1233
1331
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
*/
|
|
1243
|
-
// TODO: Skipped for migration because:
|
|
1244
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
1245
|
-
get min() {
|
|
1246
|
-
return this._min;
|
|
1332
|
+
updateValue(newValue) {
|
|
1333
|
+
if (!this.adapter.sameDate(newValue, this.value())) {
|
|
1334
|
+
this.valueState.set(newValue);
|
|
1335
|
+
this.cvaOnChange(newValue);
|
|
1336
|
+
this.valueChange.emit(newValue);
|
|
1337
|
+
this.dateInput.emit(new KbqDatepickerInputEvent(this, this.elementRef.nativeElement));
|
|
1338
|
+
}
|
|
1339
|
+
this.control?.updateValueAndValidity({ emitEvent: false });
|
|
1247
1340
|
}
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
this.validatorOnChange();
|
|
1341
|
+
isKeyForClose(event) {
|
|
1342
|
+
return (event.altKey && event.keyCode === UP_ARROW) || event.keyCode === ESCAPE;
|
|
1251
1343
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
* input — and reports `kbqDatepickerMax`. The calendar is restricted separately, by `maxDate`
|
|
1255
|
-
* on the associated `<kbq-datepicker>`.
|
|
1256
|
-
*
|
|
1257
|
-
* Compared down to the millisecond, not by calendar day: the input keeps the time part of the
|
|
1258
|
-
* value it parses, so an upper bound meant to include its whole day has to be the end of that
|
|
1259
|
-
* day.
|
|
1260
|
-
*/
|
|
1261
|
-
// TODO: Skipped for migration because:
|
|
1262
|
-
// Accessor inputs cannot be migrated as they are too complex.
|
|
1263
|
-
get max() {
|
|
1264
|
-
return this._max;
|
|
1344
|
+
isKeyForOpen(event) {
|
|
1345
|
+
return event.altKey && event.keyCode === DOWN_ARROW;
|
|
1265
1346
|
}
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
this.validatorOnChange();
|
|
1347
|
+
isLetterKey(event) {
|
|
1348
|
+
return isLetterKey(event) && !event.ctrlKey && !event.metaKey;
|
|
1269
1349
|
}
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1350
|
+
isKeyForByPass(event) {
|
|
1351
|
+
return ((hasModifierKey(event) && (isVerticalMovement(event) || isHorizontalMovement(event))) ||
|
|
1352
|
+
event.ctrlKey ||
|
|
1353
|
+
event.metaKey ||
|
|
1354
|
+
[DELETE, BACKSPACE, TAB].includes(event.keyCode));
|
|
1275
1355
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1356
|
+
spaceKeyHandler(event) {
|
|
1357
|
+
event.preventDefault();
|
|
1358
|
+
const position = this.selectionStart;
|
|
1359
|
+
// Right after a separator the digit group is empty, so a space cannot stand in for one:
|
|
1360
|
+
// advance instead of inserting a character the value can never be parsed with.
|
|
1361
|
+
if (this.selectionStart !== this.selectionEnd || this.separatorPositions.includes(position)) {
|
|
1362
|
+
this.selectNextDigit(position, true);
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
this.setViewValue(this.getNewValue(event.key, position));
|
|
1366
|
+
this.defer(this.onInput);
|
|
1367
|
+
}
|
|
1368
|
+
getNewValue(key, position) {
|
|
1369
|
+
return [this.viewValue.slice(0, position), key, this.viewValue.slice(position)].join('');
|
|
1370
|
+
}
|
|
1371
|
+
setViewValue(value, savePosition = false) {
|
|
1278
1372
|
const element = this.elementRef.nativeElement;
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1373
|
+
const selectionStart = this.selectionStart ?? 0;
|
|
1374
|
+
const selectionEnd = this.selectionEnd ?? 0;
|
|
1375
|
+
this.renderer.setProperty(element, 'value', value);
|
|
1376
|
+
// Right away: a form or a `[value]` binding writes after `ngDoCheck()` has run.
|
|
1377
|
+
this.emptyValue.set(this.isEmpty());
|
|
1378
|
+
if (savePosition) {
|
|
1379
|
+
this.setSelection(selectionStart, selectionEnd);
|
|
1282
1380
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
//
|
|
1286
|
-
|
|
1287
|
-
// which then causes a changed after checked error if the input element was focused before.
|
|
1288
|
-
element.blur();
|
|
1381
|
+
else {
|
|
1382
|
+
// A paste, a model write or a calendar pick replaces the whole value, and the offset the
|
|
1383
|
+
// previous one was left at has to go with it.
|
|
1384
|
+
kbqRevealSelection(element);
|
|
1289
1385
|
}
|
|
1290
1386
|
}
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
get id() {
|
|
1294
|
-
return this._id;
|
|
1387
|
+
setSelection(start, end) {
|
|
1388
|
+
kbqSetSelectionRange(this.elementRef.nativeElement, start, end);
|
|
1295
1389
|
}
|
|
1296
|
-
|
|
1297
|
-
|
|
1390
|
+
replaceSymbols(value) {
|
|
1391
|
+
return value
|
|
1392
|
+
.split(this.separator)
|
|
1393
|
+
.map((part) => part.replace(/^([0-9]+)\W$/, '0$1'))
|
|
1394
|
+
.join(this.separator);
|
|
1298
1395
|
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
if (!tooltip) {
|
|
1303
|
-
return;
|
|
1396
|
+
getDateFromString(timeString) {
|
|
1397
|
+
if (!timeString || timeString.length < this.firstDigit.length) {
|
|
1398
|
+
return null;
|
|
1304
1399
|
}
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
if (
|
|
1310
|
-
return;
|
|
1400
|
+
const date = this.getDefaultValue();
|
|
1401
|
+
const viewDigits = timeString.split(this.separator).map((value) => value);
|
|
1402
|
+
const [firsViewDigit, secondViewDigit, thirdViewDigit] = viewDigits;
|
|
1403
|
+
if (viewDigits.length === 1) {
|
|
1404
|
+
if (/\D/.test(firsViewDigit) || firsViewDigit.length < this.firstDigit.length) {
|
|
1405
|
+
return null;
|
|
1311
1406
|
}
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
}
|
|
1316
|
-
get empty() {
|
|
1317
|
-
return !this.viewValue && !this.isBadInput();
|
|
1318
|
-
}
|
|
1319
|
-
get viewValue() {
|
|
1320
|
-
return this.elementRef.nativeElement.value;
|
|
1321
|
-
}
|
|
1322
|
-
get ngControl() {
|
|
1323
|
-
return this.control;
|
|
1324
|
-
}
|
|
1325
|
-
get isReadOnly() {
|
|
1326
|
-
return this.elementRef.nativeElement.readOnly;
|
|
1327
|
-
}
|
|
1328
|
-
get dateInputFormat() {
|
|
1329
|
-
return this.dateFormats?.dateInput || this.adapter.config.dateInput;
|
|
1330
|
-
}
|
|
1331
|
-
get errorState() {
|
|
1332
|
-
return this.errorStateTracker.errorState;
|
|
1333
|
-
}
|
|
1334
|
-
set errorState(value) {
|
|
1335
|
-
this.errorStateTracker.errorState = value;
|
|
1336
|
-
}
|
|
1337
|
-
get readyForParse() {
|
|
1338
|
-
return !!(this.firstDigit && this.secondDigit && this.thirdDigit);
|
|
1339
|
-
}
|
|
1340
|
-
get selectionStart() {
|
|
1341
|
-
return this.elementRef.nativeElement.selectionStart;
|
|
1342
|
-
}
|
|
1343
|
-
get selectionEnd() {
|
|
1344
|
-
return this.elementRef.nativeElement.selectionEnd;
|
|
1345
|
-
}
|
|
1346
|
-
constructor() {
|
|
1347
|
-
this.elementRef = inject(ElementRef);
|
|
1348
|
-
this.renderer = inject(Renderer2);
|
|
1349
|
-
this.adapter = injectRequiredDateAdapter();
|
|
1350
|
-
this.timezoneService = inject(KbqDateTimezoneService);
|
|
1351
|
-
this.dateFormats = inject(KBQ_DATE_FORMATS, { optional: true });
|
|
1352
|
-
/** @docs-private */
|
|
1353
|
-
this.formField = inject(KBQ_FORM_FIELD, { optional: true, host: true });
|
|
1354
|
-
/** @docs-private */
|
|
1355
|
-
this.localeService = inject(KBQ_LOCALE_SERVICE, { optional: true });
|
|
1356
|
-
/** @docs-private */
|
|
1357
|
-
this.externalConfiguration = inject(KBQ_DATEPICKER_CONFIGURATION, { optional: true });
|
|
1358
|
-
this.stateChanges = new Subject();
|
|
1359
|
-
this.controlType = 'datepicker';
|
|
1360
|
-
this.focused = false;
|
|
1361
|
-
/** Emits when the value changes (either due to user input or programmatic change). */
|
|
1362
|
-
this.valueChange = new EventEmitter();
|
|
1363
|
-
/** Emits when the disabled state has changed */
|
|
1364
|
-
this.disabledChange = new EventEmitter();
|
|
1365
|
-
this._disabled = false;
|
|
1366
|
-
this.incorrectInput = output();
|
|
1367
|
-
/** Emits when a `change` event is fired on this `<input>`. */
|
|
1368
|
-
this.dateChange = output();
|
|
1369
|
-
/** Emits when an `input` event is fired on this `<input>`. */
|
|
1370
|
-
this.dateInput = output();
|
|
1371
|
-
this.uid = `kbq-datepicker-${uniqueComponentIdSuffix++}`;
|
|
1372
|
-
this.datepickerSubscription = Subscription.EMPTY;
|
|
1373
|
-
/** Whether the last value set on the input was valid. */
|
|
1374
|
-
this.lastValueValid = false;
|
|
1375
|
-
this.firstDigit = null;
|
|
1376
|
-
this.secondDigit = null;
|
|
1377
|
-
this.thirdDigit = null;
|
|
1378
|
-
this.onTouched = () => { };
|
|
1379
|
-
this.onInput = () => {
|
|
1380
|
-
const cursorPosition = this.correctedCursorPosition();
|
|
1381
|
-
const formattedValue = this.replaceSymbols(this.viewValue);
|
|
1382
|
-
const newTimeObj = this.getDateFromString(formattedValue);
|
|
1383
|
-
this.lastValueValid = !!newTimeObj;
|
|
1384
|
-
if (!newTimeObj) {
|
|
1385
|
-
if (!this.viewValue) {
|
|
1386
|
-
this.lastValueValid = false;
|
|
1387
|
-
this.updateValue(newTimeObj);
|
|
1388
|
-
}
|
|
1389
|
-
else {
|
|
1390
|
-
this.control?.updateValueAndValidity();
|
|
1391
|
-
}
|
|
1392
|
-
return;
|
|
1407
|
+
date[this.firstDigit.fullName] = this.firstDigit.parse(firsViewDigit);
|
|
1408
|
+
if (this.firstDigit.isDay) {
|
|
1409
|
+
date.month = 1;
|
|
1393
1410
|
}
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
this.
|
|
1397
|
-
};
|
|
1398
|
-
this.parseOnBlur = () => {
|
|
1399
|
-
if (!this.viewValue || !this.readyForParse) {
|
|
1411
|
+
}
|
|
1412
|
+
else if (viewDigits.length === 2) {
|
|
1413
|
+
if (firsViewDigit.length < this.firstDigit.length || secondViewDigit.length < this.secondDigit.length) {
|
|
1400
1414
|
return null;
|
|
1401
1415
|
}
|
|
1402
|
-
const date = this.getDefaultValue();
|
|
1403
|
-
const viewDigits = this.viewValue
|
|
1404
|
-
.split(this.separator)
|
|
1405
|
-
.map((value) => value)
|
|
1406
|
-
.filter((value) => value);
|
|
1407
|
-
const [firsViewDigit, secondViewDigit, thirdViewDigit] = viewDigits;
|
|
1408
|
-
if (viewDigits.length !== 3) {
|
|
1409
|
-
this.lastValueValid = false;
|
|
1410
|
-
this._value = null;
|
|
1411
|
-
return setTimeout(() => this.control?.updateValueAndValidity());
|
|
1412
|
-
}
|
|
1413
1416
|
date[this.firstDigit.fullName] = this.firstDigit.parse(firsViewDigit);
|
|
1414
1417
|
date[this.secondDigit.fullName] = this.secondDigit.parse(secondViewDigit);
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
if (
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
this.lastValueValid = false;
|
|
1422
|
-
this._value = null;
|
|
1423
|
-
return setTimeout(() => this.control?.updateValueAndValidity());
|
|
1418
|
+
}
|
|
1419
|
+
else if (viewDigits.length === 3) {
|
|
1420
|
+
if (firsViewDigit.length < this.firstDigit.length ||
|
|
1421
|
+
secondViewDigit.length < this.secondDigit.length ||
|
|
1422
|
+
thirdViewDigit.length < this.thirdDigit.length) {
|
|
1423
|
+
return null;
|
|
1424
1424
|
}
|
|
1425
|
-
const
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
this.cvaOnChange(null);
|
|
1430
|
-
return setTimeout(() => this.control?.updateValueAndValidity());
|
|
1425
|
+
const digitViewValue = {};
|
|
1426
|
+
const dateDigits = [this.firstDigit, this.secondDigit, this.thirdDigit];
|
|
1427
|
+
for (const [index, dateDigit] of dateDigits.entries()) {
|
|
1428
|
+
digitViewValue[dateDigit.fullName] = parseInt(viewDigits[index]);
|
|
1431
1429
|
}
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
return null;
|
|
1430
|
+
if (this.value() && digitViewValue.month && digitViewValue.month <= this.firstDigit.maxMonth) {
|
|
1431
|
+
dateDigits.forEach((digit) => (digit.maxDays = this.getLastDayFor(digitViewValue.year, digitViewValue.month - 1)));
|
|
1435
1432
|
}
|
|
1436
|
-
this.
|
|
1437
|
-
this.
|
|
1438
|
-
this.
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
// An unparseable value compares as NaN against any bound, which fails both `<= 0` and
|
|
1456
|
-
// `>= 0` and would report the value as simultaneously too early and too late.
|
|
1457
|
-
const controlValue = this.getValidDateOrNull(this.adapter.deserialize(control.value));
|
|
1458
|
-
return !this.min || !controlValue || this.adapter.compareDateTime(this.min, controlValue) <= 0
|
|
1459
|
-
? null
|
|
1460
|
-
: { kbqDatepickerMin: { min: this.min, actual: controlValue } };
|
|
1461
|
-
};
|
|
1462
|
-
/** The form control validator for the max date. */
|
|
1463
|
-
this.maxValidator = (control) => {
|
|
1464
|
-
const controlValue = this.getValidDateOrNull(this.adapter.deserialize(control.value));
|
|
1465
|
-
return !this.max || !controlValue || this.adapter.compareDateTime(this.max, controlValue) >= 0
|
|
1466
|
-
? null
|
|
1467
|
-
: { kbqDatepickerMax: { max: this.max, actual: controlValue } };
|
|
1468
|
-
};
|
|
1469
|
-
/** The form control validator for the date filter. */
|
|
1470
|
-
this.filterValidator = (control) => {
|
|
1471
|
-
const controlValue = this.adapter.deserialize(control.value);
|
|
1472
|
-
return !this.dateFilter || !controlValue || this.dateFilter(controlValue)
|
|
1473
|
-
? null
|
|
1474
|
-
: { kbqDatepickerFilter: true };
|
|
1433
|
+
date[this.firstDigit.fullName] = this.firstDigit.parse(firsViewDigit);
|
|
1434
|
+
date[this.secondDigit.fullName] = this.secondDigit.parse(secondViewDigit);
|
|
1435
|
+
date[this.thirdDigit.fullName] = this.thirdDigit.parse(thirdViewDigit);
|
|
1436
|
+
}
|
|
1437
|
+
else {
|
|
1438
|
+
return null;
|
|
1439
|
+
}
|
|
1440
|
+
return this.getValidDateOrNull(this.createDateTime(date));
|
|
1441
|
+
}
|
|
1442
|
+
getDefaultValue() {
|
|
1443
|
+
const defaultValue = this.value() || this.adapter.today();
|
|
1444
|
+
return {
|
|
1445
|
+
year: this.adapter.getYear(defaultValue),
|
|
1446
|
+
month: this.adapter.getMonth(defaultValue),
|
|
1447
|
+
date: this.adapter.getDate(defaultValue),
|
|
1448
|
+
hours: this.adapter.getHours(defaultValue),
|
|
1449
|
+
minutes: this.adapter.getMinutes(defaultValue),
|
|
1450
|
+
seconds: this.adapter.getSeconds(defaultValue),
|
|
1451
|
+
milliseconds: this.adapter.getMilliseconds(defaultValue)
|
|
1475
1452
|
};
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
this.filterValidator
|
|
1481
|
-
]);
|
|
1482
|
-
this.errorStateTracker = new KbqErrorStateTracker(inject(ErrorStateMatcher),
|
|
1483
|
-
// update ngControl later, so it will be initialized
|
|
1484
|
-
null, inject(FormGroupDirective, { optional: true }), inject(NgForm, { optional: true }), this.stateChanges);
|
|
1485
|
-
this.setFormat(this.dateInputFormat);
|
|
1486
|
-
this.localeService?.changes.pipe(takeUntilDestroyed()).subscribe(this.updateLocaleParams);
|
|
1487
|
-
if (!this.localeService) {
|
|
1488
|
-
this.initDefaultParams();
|
|
1453
|
+
}
|
|
1454
|
+
getTimeStringFromDate(value, timeFormat) {
|
|
1455
|
+
if (!value || !this.adapter.isValid(value)) {
|
|
1456
|
+
return '';
|
|
1489
1457
|
}
|
|
1490
|
-
this.
|
|
1491
|
-
// The rendered text names a wall clock in the zone it was formatted in. Left as it is, the
|
|
1492
|
-
// next keystroke re-parses it against the new zone and emits a different instant.
|
|
1493
|
-
this.value = this.value;
|
|
1494
|
-
});
|
|
1458
|
+
return this.adapter.format(value, timeFormat);
|
|
1495
1459
|
}
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
this.updateErrorState();
|
|
1460
|
+
getDateEditMetrics(cursorPosition) {
|
|
1461
|
+
for (const digit of [this.firstDigit, this.secondDigit, this.thirdDigit]) {
|
|
1462
|
+
if (cursorPosition >= digit.start && cursorPosition <= digit.end) {
|
|
1463
|
+
return [digit.value, digit.start, digit.end];
|
|
1464
|
+
}
|
|
1502
1465
|
}
|
|
1466
|
+
return [this.thirdDigit.value, this.thirdDigit.start, this.thirdDigit.end];
|
|
1503
1467
|
}
|
|
1504
|
-
|
|
1505
|
-
this.
|
|
1468
|
+
isMaxMonth(date) {
|
|
1469
|
+
return this.adapter.getMonth(date) === this.getMaxMonth(date);
|
|
1506
1470
|
}
|
|
1507
|
-
|
|
1508
|
-
this.
|
|
1471
|
+
isMinMonth(date) {
|
|
1472
|
+
return this.adapter.getMonth(date) === this.getMinMonth(date);
|
|
1509
1473
|
}
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1474
|
+
isMaxYear(date) {
|
|
1475
|
+
return this.adapter.getYear(date) === this.getMaxYear();
|
|
1476
|
+
}
|
|
1477
|
+
isMinYear(date) {
|
|
1478
|
+
return this.adapter.getYear(date) === this.getMinYear();
|
|
1479
|
+
}
|
|
1480
|
+
getMaxDate(date) {
|
|
1481
|
+
const maxDate = this.datepicker?.maxDate();
|
|
1482
|
+
if (maxDate && this.isMaxYear(date) && this.isMaxMonth(date)) {
|
|
1483
|
+
return this.adapter.getDate(maxDate);
|
|
1515
1484
|
}
|
|
1485
|
+
return this.adapter.getNumDaysInMonth(date);
|
|
1516
1486
|
}
|
|
1517
|
-
|
|
1518
|
-
this.
|
|
1487
|
+
getMinDate(date) {
|
|
1488
|
+
const minDate = this.datepicker?.minDate();
|
|
1489
|
+
if (minDate && this.isMinYear(date) && this.isMinMonth(date)) {
|
|
1490
|
+
return this.adapter.getDate(minDate);
|
|
1491
|
+
}
|
|
1492
|
+
return 1;
|
|
1519
1493
|
}
|
|
1520
|
-
|
|
1521
|
-
this.
|
|
1522
|
-
this.
|
|
1523
|
-
|
|
1494
|
+
getMaxMonth(date) {
|
|
1495
|
+
const maxDate = this.datepicker?.maxDate();
|
|
1496
|
+
if (maxDate && this.isMaxYear(date)) {
|
|
1497
|
+
return this.adapter.getMonth(maxDate);
|
|
1498
|
+
}
|
|
1499
|
+
return 11;
|
|
1524
1500
|
}
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
this.
|
|
1501
|
+
getMinMonth(date) {
|
|
1502
|
+
const minDate = this.datepicker?.minDate();
|
|
1503
|
+
if (minDate && this.isMinYear(date)) {
|
|
1504
|
+
return this.adapter.getMonth(minDate);
|
|
1505
|
+
}
|
|
1506
|
+
return 0;
|
|
1528
1507
|
}
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1508
|
+
getMaxYear() {
|
|
1509
|
+
const maxDate = this.datepicker?.maxDate();
|
|
1510
|
+
if (maxDate) {
|
|
1511
|
+
return this.adapter.getYear(maxDate);
|
|
1512
|
+
}
|
|
1513
|
+
return MAX_YEAR;
|
|
1533
1514
|
}
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1515
|
+
getMinYear() {
|
|
1516
|
+
const minDate = this.datepicker?.minDate();
|
|
1517
|
+
if (minDate) {
|
|
1518
|
+
return this.adapter.getYear(minDate);
|
|
1519
|
+
}
|
|
1520
|
+
return 1;
|
|
1537
1521
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1522
|
+
incrementDate(date, whatToIncrement) {
|
|
1523
|
+
let year = this.adapter.getYear(date);
|
|
1524
|
+
let month = this.adapter.getMonth(date);
|
|
1525
|
+
let day = this.adapter.getDate(date);
|
|
1526
|
+
switch (whatToIncrement) {
|
|
1527
|
+
case DateParts.day:
|
|
1528
|
+
day++;
|
|
1529
|
+
if (day > this.getMaxDate(date)) {
|
|
1530
|
+
if (this.isMaxYear(date) && this.isMaxMonth(date)) {
|
|
1531
|
+
day = this.getMaxDate(date);
|
|
1532
|
+
}
|
|
1533
|
+
else if (this.isMinYear(date) && this.isMinMonth(date)) {
|
|
1534
|
+
day = this.getMinDate(date);
|
|
1535
|
+
}
|
|
1536
|
+
else {
|
|
1537
|
+
day = 1;
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
break;
|
|
1541
|
+
case DateParts.month: {
|
|
1542
|
+
month++;
|
|
1543
|
+
if (month > this.getMaxMonth(date)) {
|
|
1544
|
+
if (this.isMaxYear(date)) {
|
|
1545
|
+
month = this.getMaxMonth(date);
|
|
1546
|
+
}
|
|
1547
|
+
else if (this.isMinYear(date)) {
|
|
1548
|
+
month = this.getMinMonth(date);
|
|
1549
|
+
}
|
|
1550
|
+
else {
|
|
1551
|
+
month = 0;
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
const lastDay = this.getLastDayFor(year, month);
|
|
1555
|
+
if (day > lastDay) {
|
|
1556
|
+
day = lastDay;
|
|
1557
|
+
}
|
|
1558
|
+
break;
|
|
1559
|
+
}
|
|
1560
|
+
case DateParts.year:
|
|
1561
|
+
year++;
|
|
1562
|
+
if (year > this.getMaxYear()) {
|
|
1563
|
+
year = this.getMaxYear();
|
|
1564
|
+
}
|
|
1565
|
+
break;
|
|
1566
|
+
default:
|
|
1567
|
+
}
|
|
1568
|
+
return this.createDate(year, month, day);
|
|
1541
1569
|
}
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
this.onTouched = fn;
|
|
1570
|
+
getLastDayFor(year, month) {
|
|
1571
|
+
return this.adapter.getNumDaysInMonth(this.createDate(year, month, 1));
|
|
1545
1572
|
}
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1573
|
+
decrementDate(date, whatToDecrement) {
|
|
1574
|
+
let year = this.adapter.getYear(date);
|
|
1575
|
+
let month = this.adapter.getMonth(date);
|
|
1576
|
+
let day = this.adapter.getDate(date);
|
|
1577
|
+
switch (whatToDecrement) {
|
|
1578
|
+
case DateParts.day:
|
|
1579
|
+
day--;
|
|
1580
|
+
if (day < this.getMinDate(date)) {
|
|
1581
|
+
if (this.isMinYear(date) && this.isMinMonth(date)) {
|
|
1582
|
+
day = this.getMinDate(date);
|
|
1583
|
+
}
|
|
1584
|
+
else if (this.isMaxYear(date) && this.isMaxMonth(date)) {
|
|
1585
|
+
day = this.getMaxDate(date);
|
|
1586
|
+
}
|
|
1587
|
+
else {
|
|
1588
|
+
day = this.adapter.getNumDaysInMonth(date);
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
break;
|
|
1592
|
+
case DateParts.month: {
|
|
1593
|
+
month--;
|
|
1594
|
+
if (month < this.getMinMonth(date)) {
|
|
1595
|
+
if (year === this.getMinYear()) {
|
|
1596
|
+
month = this.getMinMonth(date);
|
|
1597
|
+
}
|
|
1598
|
+
else if (this.isMaxYear(date)) {
|
|
1599
|
+
month = this.getMaxMonth(date);
|
|
1600
|
+
}
|
|
1601
|
+
else {
|
|
1602
|
+
month = 11;
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
const lastDay = this.getLastDayFor(year, month);
|
|
1606
|
+
if (day > lastDay) {
|
|
1607
|
+
day = lastDay;
|
|
1608
|
+
}
|
|
1609
|
+
break;
|
|
1610
|
+
}
|
|
1611
|
+
case DateParts.year:
|
|
1612
|
+
year--;
|
|
1613
|
+
if (year < this.getMinYear()) {
|
|
1614
|
+
year = this.getMinYear();
|
|
1615
|
+
}
|
|
1616
|
+
break;
|
|
1617
|
+
default:
|
|
1618
|
+
}
|
|
1619
|
+
return this.createDate(year, month, day);
|
|
1549
1620
|
}
|
|
1550
|
-
|
|
1551
|
-
|
|
1621
|
+
verticalArrowKeyHandler(keyCode) {
|
|
1622
|
+
const value = this.value();
|
|
1623
|
+
if (!value) {
|
|
1552
1624
|
return;
|
|
1553
1625
|
}
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
this.incorrectInput.emit();
|
|
1559
|
-
}
|
|
1560
|
-
else if (this.isKeyForOpen(event)) {
|
|
1561
|
-
event.preventDefault();
|
|
1562
|
-
this.datepicker?.open();
|
|
1563
|
-
}
|
|
1564
|
-
else if (this.isKeyForClose(event)) {
|
|
1565
|
-
event.preventDefault();
|
|
1566
|
-
this.datepicker?.close();
|
|
1626
|
+
let changedTime;
|
|
1627
|
+
const [modifiedTimePart, selectionStart, selectionEnd] = this.getDateEditMetrics(this.selectionStart);
|
|
1628
|
+
if (keyCode === UP_ARROW) {
|
|
1629
|
+
changedTime = this.incrementDate(value, modifiedTimePart);
|
|
1567
1630
|
}
|
|
1568
|
-
|
|
1569
|
-
this.
|
|
1631
|
+
if (keyCode === DOWN_ARROW) {
|
|
1632
|
+
changedTime = this.decrementDate(value, modifiedTimePart);
|
|
1570
1633
|
}
|
|
1571
|
-
|
|
1634
|
+
this.setValue(changedTime);
|
|
1635
|
+
this.setSelection(selectionStart, selectionEnd);
|
|
1636
|
+
this.cvaOnChange(changedTime);
|
|
1637
|
+
this.onChange();
|
|
1638
|
+
}
|
|
1639
|
+
changeCaretPosition(keyCode) {
|
|
1640
|
+
if (!this.value()) {
|
|
1572
1641
|
return;
|
|
1573
1642
|
}
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
else if ([UP_ARROW, DOWN_ARROW].includes(keyCode)) {
|
|
1578
|
-
event.preventDefault();
|
|
1579
|
-
this.verticalArrowKeyHandler(keyCode);
|
|
1643
|
+
let cursorPos = this.selectionStart;
|
|
1644
|
+
if ([HOME, PAGE_UP].includes(keyCode)) {
|
|
1645
|
+
cursorPos = 0;
|
|
1580
1646
|
}
|
|
1581
|
-
else if ([
|
|
1582
|
-
|
|
1583
|
-
this.changeCaretPosition(keyCode);
|
|
1647
|
+
else if ([END, PAGE_DOWN].includes(keyCode)) {
|
|
1648
|
+
cursorPos = this.viewValue.length;
|
|
1584
1649
|
}
|
|
1585
|
-
else if (
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
const formattedValue = this.replaceSymbols(newValue);
|
|
1589
|
-
if (newValue !== formattedValue) {
|
|
1590
|
-
this.setViewValue(formattedValue, true);
|
|
1591
|
-
setTimeout(this.onInput);
|
|
1592
|
-
}
|
|
1593
|
-
else {
|
|
1594
|
-
// TODO: The 'emit' function requires a mandatory void argument
|
|
1595
|
-
this.incorrectInput.emit();
|
|
1596
|
-
}
|
|
1650
|
+
else if (keyCode === LEFT_ARROW) {
|
|
1651
|
+
this.fixEmptyDigit();
|
|
1652
|
+
cursorPos = cursorPos === 0 ? this.viewValue.length : cursorPos - 1;
|
|
1597
1653
|
}
|
|
1598
|
-
else {
|
|
1599
|
-
|
|
1654
|
+
else if (keyCode === RIGHT_ARROW) {
|
|
1655
|
+
this.fixEmptyDigit();
|
|
1656
|
+
const nextSeparatorPos = this.viewValue.indexOf(this.separator, cursorPos);
|
|
1657
|
+
cursorPos = nextSeparatorPos ? nextSeparatorPos + 1 : 0;
|
|
1600
1658
|
}
|
|
1659
|
+
this.selectDigitByCursor(cursorPos);
|
|
1601
1660
|
}
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
}
|
|
1614
|
-
onPaste($event) {
|
|
1615
|
-
$event.preventDefault();
|
|
1616
|
-
let rawValue = $event.clipboardData.getData('text');
|
|
1617
|
-
if (rawValue.match(/^\d\D/)) {
|
|
1618
|
-
rawValue = `0${rawValue}`;
|
|
1619
|
-
}
|
|
1620
|
-
rawValue.replace(/[^A-Za-z0-9]+/g, this.separator);
|
|
1621
|
-
if (/[a-z]/gi.test(rawValue)) {
|
|
1622
|
-
// TODO: The 'emit' function requires a mandatory void argument
|
|
1623
|
-
this.incorrectInput.emit();
|
|
1624
|
-
}
|
|
1625
|
-
const match = rawValue.match(/^(?<first>\d+)\W(?<second>\d+)\W(?<third>\d+)$/);
|
|
1626
|
-
if (!match?.groups?.first || !match?.groups?.second || !match?.groups?.third) {
|
|
1627
|
-
this.setViewValue(rawValue);
|
|
1628
|
-
return rawValue;
|
|
1629
|
-
}
|
|
1630
|
-
const value = [match.groups.first, match.groups.second, match.groups.third].join(this.separator);
|
|
1631
|
-
const newTimeObj = this.getDateFromString(value);
|
|
1632
|
-
if (!newTimeObj) {
|
|
1633
|
-
this.setViewValue(value);
|
|
1634
|
-
return value;
|
|
1661
|
+
fixEmptyDigit() {
|
|
1662
|
+
const hasEmptyDigit = this.viewValue
|
|
1663
|
+
.split(this.separator)
|
|
1664
|
+
.map((part) => part.length)
|
|
1665
|
+
.some((item) => !item);
|
|
1666
|
+
const value = this.value();
|
|
1667
|
+
if (hasEmptyDigit && value) {
|
|
1668
|
+
const year = this.adapter.getYear(value);
|
|
1669
|
+
const month = this.adapter.getMonth(value);
|
|
1670
|
+
const day = this.adapter.getDate(value);
|
|
1671
|
+
this.setValue(this.createDate(year, month, day));
|
|
1635
1672
|
}
|
|
1636
|
-
this.setViewValue(this.getTimeStringFromDate(newTimeObj, this.dateInputFormat));
|
|
1637
|
-
this.updateValue(newTimeObj);
|
|
1638
|
-
}
|
|
1639
|
-
toISO8601(value) {
|
|
1640
|
-
return this.adapter.toIso8601(value);
|
|
1641
1673
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
getOrigin() {
|
|
1648
|
-
return this.formField ? this.formField.getConnectedOverlayOrigin() : this.elementRef;
|
|
1674
|
+
selectDigitByCursor(cursorPos) {
|
|
1675
|
+
this.defer(() => {
|
|
1676
|
+
const [, selectionStart, selectionEnd] = this.getDateEditMetrics(cursorPos);
|
|
1677
|
+
this.setSelection(selectionStart, selectionEnd);
|
|
1678
|
+
});
|
|
1649
1679
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
const day = this.adapter.getDate(selected);
|
|
1657
|
-
const hours = this.adapter.getHours(this.value);
|
|
1658
|
-
const minutes = this.adapter.getMinutes(this.value);
|
|
1659
|
-
const seconds = this.adapter.getSeconds(this.value);
|
|
1660
|
-
const milliseconds = this.adapter.getMilliseconds(this.value);
|
|
1661
|
-
return this.adapter.createDateTime(years, month, day, hours, minutes, seconds, milliseconds);
|
|
1680
|
+
selectNextDigitByCursor(cursorPos) {
|
|
1681
|
+
this.defer(() => {
|
|
1682
|
+
const [, , endPositionOfCurrentDigit] = this.getDateEditMetrics(cursorPos);
|
|
1683
|
+
const [, selectionStart, selectionEnd] = this.getDateEditMetrics(endPositionOfCurrentDigit + 1);
|
|
1684
|
+
this.setSelection(selectionStart, selectionEnd);
|
|
1685
|
+
});
|
|
1662
1686
|
}
|
|
1663
|
-
|
|
1664
|
-
this.
|
|
1687
|
+
selectNextDigit(cursorPos, cycle = false) {
|
|
1688
|
+
this.defer(() => {
|
|
1689
|
+
const lastValue = cycle ? 0 : cursorPos;
|
|
1690
|
+
const nextSeparatorPos = this.viewValue.indexOf(this.separator, cursorPos);
|
|
1691
|
+
const newCursorPos = nextSeparatorPos > 0 ? nextSeparatorPos + 1 : lastValue;
|
|
1692
|
+
const [, selectionStart, selectionEnd] = this.getDateEditMetrics(newCursorPos);
|
|
1693
|
+
this.setSelection(selectionStart, selectionEnd);
|
|
1694
|
+
});
|
|
1665
1695
|
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
this.
|
|
1673
|
-
.split('')
|
|
1674
|
-
.reduce((acc, item, index) => (this.separator === item ? [...acc, index + 1] : acc), []);
|
|
1675
|
-
this.getDigitPositions(format);
|
|
1696
|
+
/** Runs `work` on a timer, or earlier if the next key comes first. */
|
|
1697
|
+
defer(work) {
|
|
1698
|
+
const timer = setTimeout(() => {
|
|
1699
|
+
this.deferred.delete(timer);
|
|
1700
|
+
work();
|
|
1701
|
+
});
|
|
1702
|
+
this.deferred.set(timer, work);
|
|
1676
1703
|
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
this.
|
|
1704
|
+
/** Runs the work still waiting for its timer, including what that work defers in turn. */
|
|
1705
|
+
runDeferred() {
|
|
1706
|
+
// A Map iteration also visits the entries added during it.
|
|
1707
|
+
for (const [timer, work] of this.deferred) {
|
|
1708
|
+
clearTimeout(timer);
|
|
1709
|
+
this.deferred.delete(timer);
|
|
1710
|
+
work();
|
|
1683
1711
|
}
|
|
1684
|
-
this.control?.updateValueAndValidity({ emitEvent: false });
|
|
1685
|
-
}
|
|
1686
|
-
isKeyForClose(event) {
|
|
1687
|
-
return (event.altKey && event.keyCode === UP_ARROW) || event.keyCode === ESCAPE;
|
|
1688
1712
|
}
|
|
1689
|
-
|
|
1690
|
-
|
|
1713
|
+
/** Checks whether the input is invalid based on the native validation. */
|
|
1714
|
+
isBadInput() {
|
|
1715
|
+
const validity = this.elementRef.nativeElement.validity;
|
|
1716
|
+
return validity && validity.badInput;
|
|
1691
1717
|
}
|
|
1692
|
-
|
|
1693
|
-
|
|
1718
|
+
/** Whether the input renders no text, read from the element rather than from the last change detection. */
|
|
1719
|
+
isEmpty() {
|
|
1720
|
+
return !this.viewValue && !this.isBadInput();
|
|
1694
1721
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
[DELETE, BACKSPACE, TAB].includes(event.keyCode));
|
|
1722
|
+
/** Formats a value and sets it on the input element. */
|
|
1723
|
+
formatValue(value) {
|
|
1724
|
+
const formattedValue = value ? this.adapter.format(value, this.dateInputFormat) : '';
|
|
1725
|
+
this.setViewValue(formattedValue);
|
|
1700
1726
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
const position = this.selectionStart;
|
|
1704
|
-
// Right after a separator the digit group is empty, so a space cannot stand in for one:
|
|
1705
|
-
// advance instead of inserting a character the value can never be parsed with.
|
|
1706
|
-
if (this.selectionStart !== this.selectionEnd || this.separatorPositions.includes(position)) {
|
|
1707
|
-
this.selectNextDigit(position, true);
|
|
1727
|
+
setControl(control) {
|
|
1728
|
+
if (this.control) {
|
|
1708
1729
|
return;
|
|
1709
1730
|
}
|
|
1710
|
-
this.
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
return [this.viewValue.slice(0, position), key, this.viewValue.slice(position)].join('');
|
|
1715
|
-
}
|
|
1716
|
-
setViewValue(value, savePosition = false) {
|
|
1717
|
-
const element = this.elementRef.nativeElement;
|
|
1718
|
-
const selectionStart = this.selectionStart ?? 0;
|
|
1719
|
-
const selectionEnd = this.selectionEnd ?? 0;
|
|
1720
|
-
this.renderer.setProperty(element, 'value', value);
|
|
1721
|
-
if (savePosition) {
|
|
1722
|
-
this.setSelection(selectionStart, selectionEnd);
|
|
1723
|
-
}
|
|
1724
|
-
else {
|
|
1725
|
-
// A paste, a model write or a calendar pick replaces the whole value, and the offset the
|
|
1726
|
-
// previous one was left at has to go with it.
|
|
1727
|
-
kbqRevealSelection(element);
|
|
1728
|
-
}
|
|
1729
|
-
}
|
|
1730
|
-
setSelection(start, end) {
|
|
1731
|
-
kbqSetSelectionRange(this.elementRef.nativeElement, start, end);
|
|
1731
|
+
this.control = control;
|
|
1732
|
+
this.control.valueChanges.subscribe((value) => this.valueState.set(value));
|
|
1733
|
+
// @TODO resolve types
|
|
1734
|
+
this.errorStateTracker.ngControl = { control };
|
|
1732
1735
|
}
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1736
|
+
/**
|
|
1737
|
+
* @param obj The object to check.
|
|
1738
|
+
* @returns The given object if it is both a date instance and valid, otherwise null.
|
|
1739
|
+
*/
|
|
1740
|
+
getValidDateOrNull(obj) {
|
|
1741
|
+
return this.adapter.isDateInstance(obj) && this.adapter.isValid(obj) ? obj : null;
|
|
1738
1742
|
}
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
else if (viewDigits.length === 2) {
|
|
1756
|
-
if (firsViewDigit.length < this.firstDigit.length || secondViewDigit.length < this.secondDigit.length) {
|
|
1757
|
-
return null;
|
|
1758
|
-
}
|
|
1759
|
-
date[this.firstDigit.fullName] = this.firstDigit.parse(firsViewDigit);
|
|
1760
|
-
date[this.secondDigit.fullName] = this.secondDigit.parse(secondViewDigit);
|
|
1761
|
-
}
|
|
1762
|
-
else if (viewDigits.length === 3) {
|
|
1763
|
-
if (firsViewDigit.length < this.firstDigit.length ||
|
|
1764
|
-
secondViewDigit.length < this.secondDigit.length ||
|
|
1765
|
-
thirdViewDigit.length < this.thirdDigit.length) {
|
|
1766
|
-
return null;
|
|
1767
|
-
}
|
|
1768
|
-
const digitViewValue = {};
|
|
1769
|
-
const dateDigits = [this.firstDigit, this.secondDigit, this.thirdDigit];
|
|
1770
|
-
for (const [index, dateDigit] of dateDigits.entries()) {
|
|
1771
|
-
digitViewValue[dateDigit.fullName] = parseInt(viewDigits[index]);
|
|
1743
|
+
getDigitPositions(format) {
|
|
1744
|
+
this.firstDigit = this.secondDigit = this.thirdDigit = null;
|
|
1745
|
+
const formatInLowerCase = format.toLowerCase();
|
|
1746
|
+
formatInLowerCase.split('').reduce(({ prev, length, start }, value, index, arr) => {
|
|
1747
|
+
if (value === this.separator || arr.length - 1 === index) {
|
|
1748
|
+
if (!this.firstDigit) {
|
|
1749
|
+
this.firstDigit = new DateDigit(prev, start, length);
|
|
1750
|
+
}
|
|
1751
|
+
else if (!this.secondDigit) {
|
|
1752
|
+
this.secondDigit = new DateDigit(prev, start, length);
|
|
1753
|
+
}
|
|
1754
|
+
else if (!this.thirdDigit) {
|
|
1755
|
+
this.thirdDigit = new DateDigit(prev, start, arr.length - start);
|
|
1756
|
+
}
|
|
1757
|
+
length = 0;
|
|
1758
|
+
start = index + 1;
|
|
1772
1759
|
}
|
|
1773
|
-
|
|
1774
|
-
|
|
1760
|
+
else {
|
|
1761
|
+
length++;
|
|
1775
1762
|
}
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
else {
|
|
1781
|
-
return null;
|
|
1763
|
+
return { prev: value, length, start };
|
|
1764
|
+
}, { length: 0, start: 0 });
|
|
1765
|
+
if (!this.firstDigit || !this.secondDigit || !this.thirdDigit) {
|
|
1766
|
+
Error(`Can' t use this format: ${format}`);
|
|
1782
1767
|
}
|
|
1783
|
-
return this.getValidDateOrNull(this.createDateTime(date));
|
|
1784
|
-
}
|
|
1785
|
-
getDefaultValue() {
|
|
1786
|
-
const defaultValue = this.value || this.adapter.today();
|
|
1787
|
-
return {
|
|
1788
|
-
year: this.adapter.getYear(defaultValue),
|
|
1789
|
-
month: this.adapter.getMonth(defaultValue),
|
|
1790
|
-
date: this.adapter.getDate(defaultValue),
|
|
1791
|
-
hours: this.adapter.getHours(defaultValue),
|
|
1792
|
-
minutes: this.adapter.getMinutes(defaultValue),
|
|
1793
|
-
seconds: this.adapter.getSeconds(defaultValue),
|
|
1794
|
-
milliseconds: this.adapter.getMilliseconds(defaultValue)
|
|
1795
|
-
};
|
|
1796
1768
|
}
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
return '';
|
|
1800
|
-
}
|
|
1801
|
-
return this.adapter.format(value, timeFormat);
|
|
1769
|
+
createDate(year, month, day) {
|
|
1770
|
+
return this.adapter.createDateTime(year, month, day, this.adapter.getHours(this.value()), this.adapter.getMinutes(this.value()), this.adapter.getSeconds(this.value()), this.adapter.getMilliseconds(this.value()));
|
|
1802
1771
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
return [digit.value, digit.start, digit.end];
|
|
1807
|
-
}
|
|
1772
|
+
createDateTime(value) {
|
|
1773
|
+
if (Object.values(value).some(isNaN)) {
|
|
1774
|
+
return null;
|
|
1808
1775
|
}
|
|
1809
|
-
return
|
|
1810
|
-
}
|
|
1811
|
-
isMaxMonth(date) {
|
|
1812
|
-
return this.adapter.getMonth(date) === this.getMaxMonth(date);
|
|
1776
|
+
return this.adapter.createDateTime(value.year, value.month - 1, value.date, value.hours, value.minutes, value.seconds, value.milliseconds);
|
|
1813
1777
|
}
|
|
1814
|
-
|
|
1815
|
-
|
|
1778
|
+
// The position to advance from, with a caret that landed just past a separator pulled back onto
|
|
1779
|
+
// the digit before it. Returned rather than applied to the field: on the paths where the value
|
|
1780
|
+
// cannot be parsed, a moved caret would survive into the next keystroke and change what it does.
|
|
1781
|
+
correctedCursorPosition() {
|
|
1782
|
+
const position = this.selectionStart ?? 0;
|
|
1783
|
+
return this.separatorPositions.includes(position) ? position - 1 : position;
|
|
1816
1784
|
}
|
|
1817
|
-
|
|
1818
|
-
|
|
1785
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerInput, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1786
|
+
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: KbqDatepickerInput, isStandalone: true, selector: "input[kbqDatepicker], input[kbqCalendar]", inputs: { errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null }, placeholderInput: { classPropertyName: "placeholderInput", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, kbqDatepickerInput: { classPropertyName: "kbqDatepickerInput", publicName: "kbqDatepicker", isSignal: true, isRequired: false, transformFunction: null }, kbqCalendarInput: { classPropertyName: "kbqCalendarInput", publicName: "kbqCalendar", isSignal: true, isRequired: false, transformFunction: null }, kbqDatepickerFilterInput: { classPropertyName: "kbqDatepickerFilterInput", publicName: "kbqDatepickerFilter", isSignal: true, isRequired: false, transformFunction: null }, valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, minInput: { classPropertyName: "minInput", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, maxInput: { classPropertyName: "maxInput", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, kbqValidationTooltipInput: { classPropertyName: "kbqValidationTooltipInput", publicName: "kbqValidationTooltip", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { incorrectInput: "incorrectInput", dateChange: "dateChange", dateInput: "dateInput" }, host: { listeners: { "paste": "onPaste($event)", "change": "onChange()", "focus": "focusChanged(true)", "blur": "onBlur()", "keydown": "onKeyDown($event)" }, properties: { "attr.id": "id()", "attr.placeholder": "placeholder()", "attr.required": "required() || null", "attr.disabled": "disabled() || null", "attr.min": "min ? toISO8601(min) : null", "attr.max": "max ? toISO8601(max) : null", "attr.autocomplete": "\"off\"" }, classAttribute: "kbq-input kbq-datepicker" }, providers: [
|
|
1787
|
+
KBQ_DATEPICKER_VALUE_ACCESSOR,
|
|
1788
|
+
KBQ_DATEPICKER_VALIDATORS,
|
|
1789
|
+
{ provide: KbqFormFieldControl, useExisting: KbqDatepickerInput },
|
|
1790
|
+
{ provide: KBQ_DATEPICKER_INPUT_LOCALE_CONFIGURATION, useFactory: datepickerInputLocaleConfiguration }
|
|
1791
|
+
], exportAs: ["kbqDatepickerInput"], usesOnChanges: true, hostDirectives: [{ directive: i4.KbqLocaleOverridesDirective, inputs: ["kbqLocaleOverrides", "localeOverrides"] }], ngImport: i0 }); }
|
|
1792
|
+
}
|
|
1793
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerInput, decorators: [{
|
|
1794
|
+
type: Directive,
|
|
1795
|
+
args: [{
|
|
1796
|
+
selector: 'input[kbqDatepicker], input[kbqCalendar]',
|
|
1797
|
+
providers: [
|
|
1798
|
+
KBQ_DATEPICKER_VALUE_ACCESSOR,
|
|
1799
|
+
KBQ_DATEPICKER_VALIDATORS,
|
|
1800
|
+
{ provide: KbqFormFieldControl, useExisting: KbqDatepickerInput },
|
|
1801
|
+
{ provide: KBQ_DATEPICKER_INPUT_LOCALE_CONFIGURATION, useFactory: datepickerInputLocaleConfiguration }
|
|
1802
|
+
],
|
|
1803
|
+
host: {
|
|
1804
|
+
class: 'kbq-input kbq-datepicker',
|
|
1805
|
+
'[attr.id]': 'id()',
|
|
1806
|
+
'[attr.placeholder]': 'placeholder()',
|
|
1807
|
+
'[attr.required]': 'required() || null',
|
|
1808
|
+
'[attr.disabled]': 'disabled() || null',
|
|
1809
|
+
'[attr.min]': 'min ? toISO8601(min) : null',
|
|
1810
|
+
'[attr.max]': 'max ? toISO8601(max) : null',
|
|
1811
|
+
'[attr.autocomplete]': '"off"',
|
|
1812
|
+
'(paste)': 'onPaste($event)',
|
|
1813
|
+
'(change)': 'onChange()',
|
|
1814
|
+
'(focus)': 'focusChanged(true)',
|
|
1815
|
+
'(blur)': 'onBlur()',
|
|
1816
|
+
'(keydown)': 'onKeyDown($event)'
|
|
1817
|
+
},
|
|
1818
|
+
// Covers the strings this input renders itself. The calendar is created through `<kbq-datepicker>`, a
|
|
1819
|
+
// sibling of this element rather than a descendant, so it carries its own — bind `[localeOverrides]`
|
|
1820
|
+
// there for the pop-up, or put a carrier on an element enclosing both.
|
|
1821
|
+
hostDirectives: [
|
|
1822
|
+
{ directive: KbqLocaleOverridesDirective, inputs: ['kbqLocaleOverrides: localeOverrides'] }
|
|
1823
|
+
],
|
|
1824
|
+
exportAs: 'kbqDatepickerInput'
|
|
1825
|
+
}]
|
|
1826
|
+
}], ctorParameters: () => [], propDecorators: { errorStateMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorStateMatcher", required: false }] }], placeholderInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], kbqDatepickerInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqDatepicker", required: false }] }], kbqCalendarInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqCalendar", required: false }] }], kbqDatepickerFilterInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqDatepickerFilter", required: false }] }], valueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], minInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], maxInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], idInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], kbqValidationTooltipInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqValidationTooltip", required: false }] }], incorrectInput: [{ type: i0.Output, args: ["incorrectInput"] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], dateInput: [{ type: i0.Output, args: ["dateInput"] }] } });
|
|
1827
|
+
|
|
1828
|
+
/** Can be used to override the icon of a `kbqDatepickerToggle`. */
|
|
1829
|
+
class KbqDatepickerToggleIcon {
|
|
1830
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerToggleIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1831
|
+
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.25", type: KbqDatepickerToggleIcon, isStandalone: true, selector: "[kbqDatepickerToggleIcon]", ngImport: i0 }); }
|
|
1832
|
+
}
|
|
1833
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerToggleIcon, decorators: [{
|
|
1834
|
+
type: Directive,
|
|
1835
|
+
args: [{
|
|
1836
|
+
selector: '[kbqDatepickerToggleIcon]'
|
|
1837
|
+
}]
|
|
1838
|
+
}] });
|
|
1839
|
+
class KbqDatepickerToggleIconComponent {
|
|
1840
|
+
constructor() {
|
|
1841
|
+
this.disabledState = signal(false, ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
1842
|
+
/** @docs-private */
|
|
1843
|
+
this.disabledInput = input(undefined, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
|
|
1844
|
+
transform: booleanAttribute });
|
|
1845
|
+
/** Datepicker instance that the button will toggle. */
|
|
1846
|
+
this.datepicker = input(undefined, { ...(ngDevMode ? { debugName: "datepicker" } : /* istanbul ignore next */ {}), alias: 'for' });
|
|
1847
|
+
/**
|
|
1848
|
+
* Emits `true` when the calendar opens and `false` when it closes. Part of the `KbqSiblingPopup`
|
|
1849
|
+
* contract.
|
|
1850
|
+
*
|
|
1851
|
+
* Built on top of the `datepicker` signal rather than read once, because the instance is bound after the
|
|
1852
|
+
* consumers of this stream (a tooltip on the same element subscribes in its constructor) and may be
|
|
1853
|
+
* swapped later.
|
|
1854
|
+
*/
|
|
1855
|
+
this.openedChange = toObservable(this.datepicker).pipe(filter(Boolean), switchMap((datepicker) => merge(outputToObservable(datepicker.openedStream).pipe(map(() => true)), outputToObservable(datepicker.closedStream).pipe(map(() => false)))));
|
|
1856
|
+
/** Whether the calendar was open when the toggle was pressed. */
|
|
1857
|
+
this.openedOnPress = false;
|
|
1819
1858
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1859
|
+
/** Whether the toggle button is disabled. */
|
|
1860
|
+
get disabled() {
|
|
1861
|
+
return this.datepicker().disabled || this.disabledState();
|
|
1822
1862
|
}
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
if (maxDate && this.isMaxYear(date) && this.isMaxMonth(date)) {
|
|
1826
|
-
return this.adapter.getDate(maxDate);
|
|
1827
|
-
}
|
|
1828
|
-
return this.adapter.getNumDaysInMonth(date);
|
|
1863
|
+
set disabled(value) {
|
|
1864
|
+
this.disabledState.set(coerceBooleanProperty(value));
|
|
1829
1865
|
}
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
return this.adapter.getDate(minDate);
|
|
1834
|
-
}
|
|
1835
|
-
return 1;
|
|
1866
|
+
/** Whether the calendar is currently on screen. Part of the `KbqSiblingPopup` contract. */
|
|
1867
|
+
get isAttached() {
|
|
1868
|
+
return !!this.datepicker()?.opened;
|
|
1836
1869
|
}
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
if (
|
|
1840
|
-
|
|
1870
|
+
ngOnChanges(changes) {
|
|
1871
|
+
// A bound input is handed to its member; unbound, it leaves what code wrote.
|
|
1872
|
+
if (changes['disabledInput']) {
|
|
1873
|
+
const disabled = this.disabledInput();
|
|
1874
|
+
if (disabled !== undefined)
|
|
1875
|
+
this.disabled = disabled;
|
|
1841
1876
|
}
|
|
1842
|
-
return 11;
|
|
1843
1877
|
}
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
return 0;
|
|
1878
|
+
/** Opens the calendar, moving the focus to its input; closes it instead when it was open at the press. */
|
|
1879
|
+
open($event) {
|
|
1880
|
+
// Untracked: called from a consumer's `effect()`, the state read on the way — the inputs, `disabled` — would
|
|
1881
|
+
// make the effect run again whenever it changes.
|
|
1882
|
+
untracked(() => this.toggleCalendar($event));
|
|
1850
1883
|
}
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1884
|
+
/** Body of `open()`. */
|
|
1885
|
+
toggleCalendar($event) {
|
|
1886
|
+
const datepicker = this.datepicker();
|
|
1887
|
+
const openedOnPress = this.openedOnPress;
|
|
1888
|
+
this.openedOnPress = false;
|
|
1889
|
+
if (!datepicker || this.disabled)
|
|
1890
|
+
return;
|
|
1891
|
+
$event.stopPropagation();
|
|
1892
|
+
// A click on the toggle of an open calendar closes it. The overlay has usually done so before the click gets
|
|
1893
|
+
// here, taking it for a click outside the calendar.
|
|
1894
|
+
if (openedOnPress) {
|
|
1895
|
+
datepicker.close();
|
|
1896
|
+
return;
|
|
1855
1897
|
}
|
|
1856
|
-
|
|
1898
|
+
// The input, not the icon, handles the keys of the datepicker and gets the focus back once it closes.
|
|
1899
|
+
datepicker.datepickerInput.focus();
|
|
1900
|
+
datepicker.open();
|
|
1857
1901
|
}
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
return 1;
|
|
1902
|
+
/** @internal */
|
|
1903
|
+
onMousedown(event) {
|
|
1904
|
+
// A press on the icon, focusable by its `tabindex`, would take the focus from the input.
|
|
1905
|
+
event.preventDefault();
|
|
1906
|
+
this.openedOnPress = !!this.datepicker()?.opened;
|
|
1864
1907
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1908
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerToggleIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1909
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: KbqDatepickerToggleIconComponent, isStandalone: true, selector: "kbq-datepicker-toggle-icon", inputs: { disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, datepicker: { classPropertyName: "datepicker", publicName: "for", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mousedown": "onMousedown($event)", "click": "open($event)" }, properties: { "attr.aria-expanded": "datepicker().opened", "attr.aria-disabled": "disabled" }, classAttribute: "kbq-datepicker-toggle-icon" }, providers: [kbqSiblingPopupProvider(KbqDatepickerToggleIconComponent)], usesOnChanges: true, ngImport: i0, template: `
|
|
1910
|
+
<ng-content select="[kbqDatepickerToggleIcon]">
|
|
1911
|
+
<i
|
|
1912
|
+
color="contrast-fade"
|
|
1913
|
+
aria-hidden="true"
|
|
1914
|
+
kbq-icon-button="kbq-calendar-o_16"
|
|
1915
|
+
[tabindex]="-1"
|
|
1916
|
+
[class.kbq-active]="datepicker() && datepicker().opened"
|
|
1917
|
+
[disabled]="disabled"
|
|
1918
|
+
[autoColor]="true"
|
|
1919
|
+
></i>
|
|
1920
|
+
</ng-content>
|
|
1921
|
+
`, isInline: true, styles: [".kbq-datepicker-toggle-icon{display:inline-flex;justify-content:center;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: KbqIconModule }, { kind: "component", type: i2.KbqIconButton, selector: "[kbq-icon-button]", inputs: ["size", "kbq-icon-button", "tabindex", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1922
|
+
}
|
|
1923
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerToggleIconComponent, decorators: [{
|
|
1924
|
+
type: Component,
|
|
1925
|
+
args: [{ selector: 'kbq-datepicker-toggle-icon', imports: [KbqIconModule], template: `
|
|
1926
|
+
<ng-content select="[kbqDatepickerToggleIcon]">
|
|
1927
|
+
<i
|
|
1928
|
+
color="contrast-fade"
|
|
1929
|
+
aria-hidden="true"
|
|
1930
|
+
kbq-icon-button="kbq-calendar-o_16"
|
|
1931
|
+
[tabindex]="-1"
|
|
1932
|
+
[class.kbq-active]="datepicker() && datepicker().opened"
|
|
1933
|
+
[disabled]="disabled"
|
|
1934
|
+
[autoColor]="true"
|
|
1935
|
+
></i>
|
|
1936
|
+
</ng-content>
|
|
1937
|
+
`, providers: [kbqSiblingPopupProvider(KbqDatepickerToggleIconComponent)], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
1938
|
+
class: 'kbq-datepicker-toggle-icon',
|
|
1939
|
+
'[attr.aria-expanded]': 'datepicker().opened',
|
|
1940
|
+
'[attr.aria-disabled]': 'disabled',
|
|
1941
|
+
'(mousedown)': 'onMousedown($event)',
|
|
1942
|
+
'(click)': 'open($event)'
|
|
1943
|
+
}, styles: [".kbq-datepicker-toggle-icon{display:inline-flex;justify-content:center;align-items:center}\n"] }]
|
|
1944
|
+
}], propDecorators: { disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], datepicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "for", required: false }] }] } });
|
|
1945
|
+
|
|
1946
|
+
/** Used to generate a unique ID for each datepicker instance. */
|
|
1947
|
+
let datepickerUid = 0;
|
|
1948
|
+
/**
|
|
1949
|
+
* Injection token that determines the scroll handling while the calendar is open. The root default keeps the
|
|
1950
|
+
* datepicker usable outside `KbqDatepickerModule`'s injector; providing the token anywhere still wins over it.
|
|
1951
|
+
*/
|
|
1952
|
+
const KBQ_DATEPICKER_SCROLL_STRATEGY = new InjectionToken('kbq-datepicker-scroll-strategy', {
|
|
1953
|
+
providedIn: 'root',
|
|
1954
|
+
factory: () => KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY(inject(Overlay))
|
|
1955
|
+
});
|
|
1956
|
+
/** @docs-private */
|
|
1957
|
+
function KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY(overlay) {
|
|
1958
|
+
return () => overlay.scrollStrategies.reposition();
|
|
1959
|
+
}
|
|
1960
|
+
/**
|
|
1961
|
+
* Redundant to the root factory of the token; kept so an app can restore the default under its own override (#DS-2196).
|
|
1962
|
+
*
|
|
1963
|
+
* @docs-private
|
|
1964
|
+
*/
|
|
1965
|
+
const KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = {
|
|
1966
|
+
provide: KBQ_DATEPICKER_SCROLL_STRATEGY,
|
|
1967
|
+
deps: [Overlay],
|
|
1968
|
+
useFactory: KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY
|
|
1969
|
+
};
|
|
1970
|
+
/**
|
|
1971
|
+
* Component used as the content for the datepicker dialog and popup. We use this instead of using
|
|
1972
|
+
* KbqCalendar directly as the content so we can control the initial focus. This also gives us a
|
|
1973
|
+
* place to put additional features of the popup that are not part of the calendar itself in the
|
|
1974
|
+
* future. (e.g. confirmation buttons).
|
|
1975
|
+
*
|
|
1976
|
+
* @docs-private
|
|
1977
|
+
*/
|
|
1978
|
+
class KbqDatepickerContent {
|
|
1979
|
+
constructor() {
|
|
1980
|
+
this.elementRef = inject(ElementRef);
|
|
1981
|
+
this.injector = inject(Injector);
|
|
1982
|
+
/** Whether the panel opens and closes without motion. */
|
|
1983
|
+
this.animationsDisabled = kbqAnimationsDisabled();
|
|
1984
|
+
/** Emits when the exit animation has finished. */
|
|
1985
|
+
this.animationDone = new Subject();
|
|
1986
|
+
this.currentAnimationState = signal('enter', ...(ngDevMode ? [{ debugName: "currentAnimationState" }] : /* istanbul ignore next */ []));
|
|
1987
|
+
/** Reference to the internal calendar component. */
|
|
1988
|
+
this.calendar = viewChild.required(KbqCalendar);
|
|
1912
1989
|
}
|
|
1913
|
-
|
|
1914
|
-
|
|
1990
|
+
/** Current state of the animation. */
|
|
1991
|
+
get animationState() {
|
|
1992
|
+
return this.currentAnimationState();
|
|
1915
1993
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
let month = this.adapter.getMonth(date);
|
|
1919
|
-
let day = this.adapter.getDate(date);
|
|
1920
|
-
switch (whatToDecrement) {
|
|
1921
|
-
case DateParts.day:
|
|
1922
|
-
day--;
|
|
1923
|
-
if (day < this.getMinDate(date)) {
|
|
1924
|
-
if (this.isMinYear(date) && this.isMinMonth(date)) {
|
|
1925
|
-
day = this.getMinDate(date);
|
|
1926
|
-
}
|
|
1927
|
-
else if (this.isMaxYear(date) && this.isMaxMonth(date)) {
|
|
1928
|
-
day = this.getMaxDate(date);
|
|
1929
|
-
}
|
|
1930
|
-
else {
|
|
1931
|
-
day = this.adapter.getNumDaysInMonth(date);
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
break;
|
|
1935
|
-
case DateParts.month: {
|
|
1936
|
-
month--;
|
|
1937
|
-
if (month < this.getMinMonth(date)) {
|
|
1938
|
-
if (year === this.getMinYear()) {
|
|
1939
|
-
month = this.getMinMonth(date);
|
|
1940
|
-
}
|
|
1941
|
-
else if (this.isMaxYear(date)) {
|
|
1942
|
-
month = this.getMaxMonth(date);
|
|
1943
|
-
}
|
|
1944
|
-
else {
|
|
1945
|
-
month = 11;
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
const lastDay = this.getLastDayFor(year, month);
|
|
1949
|
-
if (day > lastDay) {
|
|
1950
|
-
day = lastDay;
|
|
1951
|
-
}
|
|
1952
|
-
break;
|
|
1953
|
-
}
|
|
1954
|
-
case DateParts.year:
|
|
1955
|
-
year--;
|
|
1956
|
-
if (year < this.getMinYear()) {
|
|
1957
|
-
year = this.getMinYear();
|
|
1958
|
-
}
|
|
1959
|
-
break;
|
|
1960
|
-
default:
|
|
1961
|
-
}
|
|
1962
|
-
return this.createDate(year, month, day);
|
|
1994
|
+
set animationState(value) {
|
|
1995
|
+
this.currentAnimationState.set(value);
|
|
1963
1996
|
}
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
return;
|
|
1967
|
-
}
|
|
1968
|
-
let changedTime;
|
|
1969
|
-
const [modifiedTimePart, selectionStart, selectionEnd] = this.getDateEditMetrics(this.selectionStart);
|
|
1970
|
-
if (keyCode === UP_ARROW) {
|
|
1971
|
-
changedTime = this.incrementDate(this.value, modifiedTimePart);
|
|
1972
|
-
}
|
|
1973
|
-
if (keyCode === DOWN_ARROW) {
|
|
1974
|
-
changedTime = this.decrementDate(this.value, modifiedTimePart);
|
|
1975
|
-
}
|
|
1976
|
-
this.value = changedTime;
|
|
1977
|
-
this.setSelection(selectionStart, selectionEnd);
|
|
1978
|
-
this.cvaOnChange(changedTime);
|
|
1979
|
-
this.onChange();
|
|
1980
|
-
this.stateChanges.next();
|
|
1997
|
+
ngOnDestroy() {
|
|
1998
|
+
this.animationDone.complete();
|
|
1981
1999
|
}
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
}
|
|
1986
|
-
let cursorPos = this.selectionStart;
|
|
1987
|
-
if ([HOME, PAGE_UP].includes(keyCode)) {
|
|
1988
|
-
cursorPos = 0;
|
|
1989
|
-
}
|
|
1990
|
-
else if ([END, PAGE_DOWN].includes(keyCode)) {
|
|
1991
|
-
cursorPos = this.viewValue.length;
|
|
1992
|
-
}
|
|
1993
|
-
else if (keyCode === LEFT_ARROW) {
|
|
1994
|
-
this.fixEmptyDigit();
|
|
1995
|
-
cursorPos = cursorPos === 0 ? this.viewValue.length : cursorPos - 1;
|
|
1996
|
-
}
|
|
1997
|
-
else if (keyCode === RIGHT_ARROW) {
|
|
1998
|
-
this.fixEmptyDigit();
|
|
1999
|
-
const nextSeparatorPos = this.viewValue.indexOf(this.separator, cursorPos);
|
|
2000
|
-
cursorPos = nextSeparatorPos ? nextSeparatorPos + 1 : 0;
|
|
2001
|
-
}
|
|
2002
|
-
this.selectDigitByCursor(cursorPos);
|
|
2000
|
+
startExitAnimation() {
|
|
2001
|
+
this.animationState = 'void';
|
|
2002
|
+
kbqAfterAnimations(() => this.elementRef.nativeElement, () => this.animationDone.next(), this.injector);
|
|
2003
2003
|
}
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2004
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerContent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2005
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.25", type: KbqDatepickerContent, isStandalone: true, selector: "kbq-datepicker__content", host: { properties: { "class.kbq-datepicker__content_leave": "animationState === 'void'", "class.kbq-animations-disabled": "animationsDisabled" }, classAttribute: "kbq-datepicker__content" }, viewQueries: [{ propertyName: "calendar", first: true, predicate: KbqCalendar, descendants: true, isSignal: true }], exportAs: ["kbqDatepickerContent"], ngImport: i0, template: "<kbq-calendar\n [dateClass]=\"datepicker.dateClass()\"\n [dateFilter]=\"datepicker.dateFilter\"\n [id]=\"datepicker.id\"\n [maxDate]=\"datepicker.maxDate()\"\n [minDate]=\"datepicker.minDate()\"\n [class]=\"datepicker.panelClass()\"\n [selected]=\"datepicker.selected\"\n [startAt]=\"datepicker.startAt\"\n (monthSelected)=\"datepicker.selectMonth($event)\"\n (selectedChange)=\"datepicker.select($event)\"\n (userSelection)=\"datepicker.close()\"\n (yearSelected)=\"datepicker.selectYear($event)\"\n/>\n", styles: ["@charset \"UTF-8\";.kbq-datepicker__content{display:block;border-radius:var(--kbq-datepicker-size-container-border-radius)}@supports (corner-shape: squircle){.kbq-datepicker__content{corner-shape:squircle;border-radius:clamp(var(--kbq-datepicker-size-container-border-radius) * 1.85,var(--kbq-datepicker-size-container-border-radius) * 2.3 - 3.6px,var(--kbq-datepicker-size-container-border-radius) * 2)}}.kbq-datepicker__content .kbq-calendar{width:calc(280px + var(--kbq-datepicker-size-grid-padding-horizontal) * 2);height:270px;padding-top:var(--kbq-datepicker-size-container-padding-vertical);padding-bottom:var(--kbq-datepicker-size-container-padding-vertical);animation:kbq-datepicker-calendar-enter .12s .1s cubic-bezier(.55,0,.55,.2) backwards}.kbq-datepicker__content.kbq-datepicker__content_leave{animation:kbq-datepicker-content-leave .1s linear forwards}.kbq-datepicker__content.kbq-datepicker__content_leave.kbq-animations-disabled{animation:none;transition:none}@media(prefers-reduced-motion:reduce){.kbq-datepicker__content.kbq-datepicker__content_leave{animation:none;transition:none}}.kbq-datepicker__content.kbq-animations-disabled .kbq-calendar{animation:none}@media(prefers-reduced-motion:reduce){.kbq-datepicker__content .kbq-calendar{animation:none}}@keyframes kbq-datepicker-calendar-enter{0%{opacity:0}}@keyframes kbq-datepicker-content-leave{to{opacity:0}}.kbq-datepicker__content{background:var(--kbq-datepicker-container-background);box-shadow:var(--kbq-datepicker-container-shadow)}.kbq-calendar__table-header{color:var(--kbq-datepicker-header-text)}.kbq-calendar__table-header-divider:after{background:var(--kbq-datepicker-header-divider)}.kbq-calendar__body-cell-content{background:var(--kbq-datepicker-grid-cell-default-background);color:var(--kbq-datepicker-grid-cell-default-text)}.kbq-calendar__body-cell-content.kbq-calendar__body-today{background:var(--kbq-datepicker-grid-cell-today-background);color:var(--kbq-datepicker-grid-cell-today-text)}.kbq-calendar__body-cell-content:hover:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-hover-background)}.kbq-calendar__body-cell-content:active:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-active-background)}.kbq-calendar__body-cell-content.kbq-selected:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-selected-background);color:var(--kbq-datepicker-grid-cell-states-selected-text)}.kbq-calendar__body-cell-content.kbq-selected:not(.kbq-disabled):hover{background:var(--kbq-datepicker-grid-cell-states-selected-hover-background)}.kbq-calendar__body-cell-content.kbq-disabled{color:var(--kbq-datepicker-grid-cell-states-disabled-text);background:var(--kbq-datepicker-grid-cell-states-disabled-background)}.kbq-calendar,.kbq-calendar__table-header th{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)}\n", ".kbq-datepicker__content{--kbq-datepicker-size-container-padding-vertical: var(--kbq-size-m);--kbq-datepicker-size-container-border-radius: var(--kbq-size-s);--kbq-datepicker-size-header-padding-horizontal: var(--kbq-size-xxs);--kbq-datepicker-size-header-margin-bottom: var(--kbq-size-3xs);--kbq-datepicker-size-grid-padding-horizontal: var(--kbq-size-m);--kbq-datepicker-size-grid-content-gap-vertical: var(--kbq-size-3xs);--kbq-datepicker-size-grid-divider-height: 1px;--kbq-datepicker-size-grid-cell-padding-horizontal: var(--kbq-size-s);--kbq-datepicker-size-grid-cell-padding-vertical: var(--kbq-size-s);--kbq-datepicker-size-grid-cell-border-radius: var(--kbq-size-s);--kbq-datepicker-container-background: var(--kbq-background-card);--kbq-datepicker-container-shadow: var(--kbq-shadow-popup);--kbq-datepicker-header-text: var(--kbq-foreground-contrast-tertiary);--kbq-datepicker-header-divider: var(--kbq-line-contrast-less);--kbq-datepicker-grid-cell-default-background: transparent;--kbq-datepicker-grid-cell-default-text: var(--kbq-foreground-contrast);--kbq-datepicker-grid-cell-today-background: transparent;--kbq-datepicker-grid-cell-today-text: var(--kbq-foreground-theme);--kbq-datepicker-grid-cell-states-hover-background: var(--kbq-states-background-transparent-hover);--kbq-datepicker-grid-cell-states-active-background: var(--kbq-states-background-transparent-active);--kbq-datepicker-grid-cell-states-selected-background: var(--kbq-background-contrast);--kbq-datepicker-grid-cell-states-selected-text: var(--kbq-foreground-on-contrast);--kbq-datepicker-grid-cell-states-selected-hover-background: var(--kbq-states-background-contrast-active);--kbq-datepicker-grid-cell-states-disabled-background: transparent;--kbq-datepicker-grid-cell-states-disabled-text: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "component", type: KbqCalendar, selector: "kbq-calendar", inputs: ["startAt", "selected", "minDate", "maxDate", "dateFilter", "dateClass"], outputs: ["selectedChange", "yearSelected", "monthSelected", "userSelection"], exportAs: ["kbqCalendar"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2006
|
+
}
|
|
2007
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerContent, decorators: [{
|
|
2008
|
+
type: Component,
|
|
2009
|
+
args: [{ selector: 'kbq-datepicker__content', imports: [
|
|
2010
|
+
KbqCalendar
|
|
2011
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
2012
|
+
class: 'kbq-datepicker__content',
|
|
2013
|
+
'[class.kbq-datepicker__content_leave]': "animationState === 'void'",
|
|
2014
|
+
'[class.kbq-animations-disabled]': 'animationsDisabled'
|
|
2015
|
+
}, exportAs: 'kbqDatepickerContent', template: "<kbq-calendar\n [dateClass]=\"datepicker.dateClass()\"\n [dateFilter]=\"datepicker.dateFilter\"\n [id]=\"datepicker.id\"\n [maxDate]=\"datepicker.maxDate()\"\n [minDate]=\"datepicker.minDate()\"\n [class]=\"datepicker.panelClass()\"\n [selected]=\"datepicker.selected\"\n [startAt]=\"datepicker.startAt\"\n (monthSelected)=\"datepicker.selectMonth($event)\"\n (selectedChange)=\"datepicker.select($event)\"\n (userSelection)=\"datepicker.close()\"\n (yearSelected)=\"datepicker.selectYear($event)\"\n/>\n", styles: ["@charset \"UTF-8\";.kbq-datepicker__content{display:block;border-radius:var(--kbq-datepicker-size-container-border-radius)}@supports (corner-shape: squircle){.kbq-datepicker__content{corner-shape:squircle;border-radius:clamp(var(--kbq-datepicker-size-container-border-radius) * 1.85,var(--kbq-datepicker-size-container-border-radius) * 2.3 - 3.6px,var(--kbq-datepicker-size-container-border-radius) * 2)}}.kbq-datepicker__content .kbq-calendar{width:calc(280px + var(--kbq-datepicker-size-grid-padding-horizontal) * 2);height:270px;padding-top:var(--kbq-datepicker-size-container-padding-vertical);padding-bottom:var(--kbq-datepicker-size-container-padding-vertical);animation:kbq-datepicker-calendar-enter .12s .1s cubic-bezier(.55,0,.55,.2) backwards}.kbq-datepicker__content.kbq-datepicker__content_leave{animation:kbq-datepicker-content-leave .1s linear forwards}.kbq-datepicker__content.kbq-datepicker__content_leave.kbq-animations-disabled{animation:none;transition:none}@media(prefers-reduced-motion:reduce){.kbq-datepicker__content.kbq-datepicker__content_leave{animation:none;transition:none}}.kbq-datepicker__content.kbq-animations-disabled .kbq-calendar{animation:none}@media(prefers-reduced-motion:reduce){.kbq-datepicker__content .kbq-calendar{animation:none}}@keyframes kbq-datepicker-calendar-enter{0%{opacity:0}}@keyframes kbq-datepicker-content-leave{to{opacity:0}}.kbq-datepicker__content{background:var(--kbq-datepicker-container-background);box-shadow:var(--kbq-datepicker-container-shadow)}.kbq-calendar__table-header{color:var(--kbq-datepicker-header-text)}.kbq-calendar__table-header-divider:after{background:var(--kbq-datepicker-header-divider)}.kbq-calendar__body-cell-content{background:var(--kbq-datepicker-grid-cell-default-background);color:var(--kbq-datepicker-grid-cell-default-text)}.kbq-calendar__body-cell-content.kbq-calendar__body-today{background:var(--kbq-datepicker-grid-cell-today-background);color:var(--kbq-datepicker-grid-cell-today-text)}.kbq-calendar__body-cell-content:hover:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-hover-background)}.kbq-calendar__body-cell-content:active:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-active-background)}.kbq-calendar__body-cell-content.kbq-selected:not(.kbq-disabled){background:var(--kbq-datepicker-grid-cell-states-selected-background);color:var(--kbq-datepicker-grid-cell-states-selected-text)}.kbq-calendar__body-cell-content.kbq-selected:not(.kbq-disabled):hover{background:var(--kbq-datepicker-grid-cell-states-selected-hover-background)}.kbq-calendar__body-cell-content.kbq-disabled{color:var(--kbq-datepicker-grid-cell-states-disabled-text);background:var(--kbq-datepicker-grid-cell-states-disabled-background)}.kbq-calendar,.kbq-calendar__table-header th{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)}\n", ".kbq-datepicker__content{--kbq-datepicker-size-container-padding-vertical: var(--kbq-size-m);--kbq-datepicker-size-container-border-radius: var(--kbq-size-s);--kbq-datepicker-size-header-padding-horizontal: var(--kbq-size-xxs);--kbq-datepicker-size-header-margin-bottom: var(--kbq-size-3xs);--kbq-datepicker-size-grid-padding-horizontal: var(--kbq-size-m);--kbq-datepicker-size-grid-content-gap-vertical: var(--kbq-size-3xs);--kbq-datepicker-size-grid-divider-height: 1px;--kbq-datepicker-size-grid-cell-padding-horizontal: var(--kbq-size-s);--kbq-datepicker-size-grid-cell-padding-vertical: var(--kbq-size-s);--kbq-datepicker-size-grid-cell-border-radius: var(--kbq-size-s);--kbq-datepicker-container-background: var(--kbq-background-card);--kbq-datepicker-container-shadow: var(--kbq-shadow-popup);--kbq-datepicker-header-text: var(--kbq-foreground-contrast-tertiary);--kbq-datepicker-header-divider: var(--kbq-line-contrast-less);--kbq-datepicker-grid-cell-default-background: transparent;--kbq-datepicker-grid-cell-default-text: var(--kbq-foreground-contrast);--kbq-datepicker-grid-cell-today-background: transparent;--kbq-datepicker-grid-cell-today-text: var(--kbq-foreground-theme);--kbq-datepicker-grid-cell-states-hover-background: var(--kbq-states-background-transparent-hover);--kbq-datepicker-grid-cell-states-active-background: var(--kbq-states-background-transparent-active);--kbq-datepicker-grid-cell-states-selected-background: var(--kbq-background-contrast);--kbq-datepicker-grid-cell-states-selected-text: var(--kbq-foreground-on-contrast);--kbq-datepicker-grid-cell-states-selected-hover-background: var(--kbq-states-background-contrast-active);--kbq-datepicker-grid-cell-states-disabled-background: transparent;--kbq-datepicker-grid-cell-states-disabled-text: var(--kbq-states-foreground-disabled)}\n"] }]
|
|
2016
|
+
}], propDecorators: { calendar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqCalendar), { isSignal: true }] }] } });
|
|
2017
|
+
/** Component responsible for managing the datepicker popup/dialog. */
|
|
2018
|
+
// TODO: We use a component instead of a directive here so the user can use implicit
|
|
2019
|
+
// template reference variables (e.g. #d vs #d="kbqDatepicker"). We can change this to a directive
|
|
2020
|
+
// if angular adds support for `exportAs: '$implicit'` on directives.
|
|
2021
|
+
class KbqDatepicker {
|
|
2022
|
+
get hasBackdrop() {
|
|
2023
|
+
return this._hasBackdrop;
|
|
2015
2024
|
}
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
const [, selectionStart, selectionEnd] = this.getDateEditMetrics(cursorPos);
|
|
2019
|
-
this.setSelection(selectionStart, selectionEnd);
|
|
2020
|
-
});
|
|
2025
|
+
set hasBackdrop(value) {
|
|
2026
|
+
this._hasBackdrop = coerceBooleanProperty(value);
|
|
2021
2027
|
}
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
});
|
|
2028
|
+
/** The date to open the calendar to initially. */
|
|
2029
|
+
get startAt() {
|
|
2030
|
+
// If an explicit startAt is set we start there, otherwise we start at whatever the currently
|
|
2031
|
+
// selected value is.
|
|
2032
|
+
return this._startAt || this.datepickerInput?.value();
|
|
2028
2033
|
}
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2034
|
+
set startAt(value) {
|
|
2035
|
+
const deserializedValue = this.dateAdapter.deserialize(value);
|
|
2036
|
+
// Untracked, as in the `disabled` setter: an `effect()` that assigns it must not come to depend on the state
|
|
2037
|
+
// read on the way.
|
|
2038
|
+
this._startAt =
|
|
2039
|
+
deserializedValue !== null
|
|
2040
|
+
? this.dateAdapter.clampDate(deserializedValue, untracked(this.minDate), untracked(this.maxDate))
|
|
2041
|
+
: null;
|
|
2037
2042
|
}
|
|
2038
|
-
/**
|
|
2039
|
-
|
|
2040
|
-
const
|
|
2041
|
-
return
|
|
2043
|
+
/** Whether the datepicker pop-up should be disabled. */
|
|
2044
|
+
get disabled() {
|
|
2045
|
+
const disabled = this.disabledState();
|
|
2046
|
+
return disabled === undefined && this.datepickerInput ? this.datepickerInput.disabled() : !!disabled;
|
|
2042
2047
|
}
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2048
|
+
set disabled(value) {
|
|
2049
|
+
const newValue = coerceBooleanProperty(value);
|
|
2050
|
+
if (newValue !== untracked(this.disabledState)) {
|
|
2051
|
+
this.disabledState.set(newValue);
|
|
2052
|
+
this.disabledChange.next(newValue);
|
|
2053
|
+
}
|
|
2047
2054
|
}
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2055
|
+
/** Whether the calendar is open. */
|
|
2056
|
+
get opened() {
|
|
2057
|
+
return this.openedState();
|
|
2058
|
+
}
|
|
2059
|
+
set opened(value) {
|
|
2060
|
+
if (coerceBooleanProperty(value)) {
|
|
2061
|
+
this.open();
|
|
2062
|
+
}
|
|
2063
|
+
else {
|
|
2064
|
+
this.close();
|
|
2051
2065
|
}
|
|
2052
|
-
this.control = control;
|
|
2053
|
-
this.control.valueChanges.subscribe((value) => (this._value = value));
|
|
2054
|
-
// @TODO resolve types
|
|
2055
|
-
this.errorStateTracker.ngControl = { control };
|
|
2056
2066
|
}
|
|
2057
|
-
/**
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
*/
|
|
2061
|
-
getValidDateOrNull(obj) {
|
|
2062
|
-
return this.adapter.isDateInstance(obj) && this.adapter.isValid(obj) ? obj : null;
|
|
2067
|
+
/** The currently selected date. */
|
|
2068
|
+
get selected() {
|
|
2069
|
+
return this.validSelected;
|
|
2063
2070
|
}
|
|
2064
|
-
|
|
2065
|
-
this.
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2071
|
+
set selected(value) {
|
|
2072
|
+
this.validSelected = value;
|
|
2073
|
+
}
|
|
2074
|
+
get dateFilter() {
|
|
2075
|
+
return this.datepickerInput && this.datepickerInput.dateFilter;
|
|
2076
|
+
}
|
|
2077
|
+
get value() {
|
|
2078
|
+
return this.selected;
|
|
2079
|
+
}
|
|
2080
|
+
constructor() {
|
|
2081
|
+
this.overlay = inject(Overlay);
|
|
2082
|
+
this.overlayLayers = inject(KBQ_OVERLAY_LAYERS);
|
|
2083
|
+
this.injector = inject(Injector);
|
|
2084
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
2085
|
+
this.dateAdapter = injectRequiredDateAdapter();
|
|
2086
|
+
this.dir = inject(Directionality, { optional: true });
|
|
2087
|
+
this.document = inject(DOCUMENT);
|
|
2088
|
+
this._hasBackdrop = false;
|
|
2089
|
+
this.disabledState = signal(undefined, ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
2090
|
+
this.openedState = signal(false, ...(ngDevMode ? [{ debugName: "openedState" }] : /* istanbul ignore next */ []));
|
|
2091
|
+
/** @docs-private */
|
|
2092
|
+
this.hasBackdropInput = input(undefined, { ...(ngDevMode ? { debugName: "hasBackdropInput" } : /* istanbul ignore next */ {}), alias: 'hasBackdrop',
|
|
2093
|
+
transform: booleanAttribute });
|
|
2094
|
+
/** @docs-private */
|
|
2095
|
+
this.startAtInput = input(undefined, { ...(ngDevMode ? { debugName: "startAtInput" } : /* istanbul ignore next */ {}), alias: 'startAt' });
|
|
2096
|
+
/** @docs-private */
|
|
2097
|
+
this.disabledInput = input(undefined, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
|
|
2098
|
+
transform: booleanAttribute });
|
|
2099
|
+
/** @docs-private */
|
|
2100
|
+
this.openedInput = input(undefined, { ...(ngDevMode ? { debugName: "openedInput" } : /* istanbul ignore next */ {}), alias: 'opened',
|
|
2101
|
+
transform: booleanAttribute });
|
|
2102
|
+
/** The minimum selectable date. */
|
|
2103
|
+
this.minDate = input(undefined, ...(ngDevMode ? [{ debugName: "minDate" }] : /* istanbul ignore next */ []));
|
|
2104
|
+
/** The maximum selectable date. */
|
|
2105
|
+
this.maxDate = input(undefined, ...(ngDevMode ? [{ debugName: "maxDate" }] : /* istanbul ignore next */ []));
|
|
2106
|
+
/**
|
|
2107
|
+
* Emits selected year in multiyear view.
|
|
2108
|
+
* This doesn't imply a change on the selected date.
|
|
2109
|
+
*/
|
|
2110
|
+
this.yearSelected = output();
|
|
2111
|
+
/**
|
|
2112
|
+
* Emits selected month in year view.
|
|
2113
|
+
* This doesn't imply a change on the selected date.
|
|
2114
|
+
*/
|
|
2115
|
+
this.monthSelected = output();
|
|
2116
|
+
/** Classes to be passed to the date picker panel. Supports the same syntax as the `[class]` binding. */
|
|
2117
|
+
this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
|
|
2118
|
+
/** Function that can be used to add custom CSS classes to dates. */
|
|
2119
|
+
this.dateClass = input(undefined, ...(ngDevMode ? [{ debugName: "dateClass" }] : /* istanbul ignore next */ []));
|
|
2120
|
+
this.backdropClass = input('cdk-overlay-transparent-backdrop', ...(ngDevMode ? [{ debugName: "backdropClass" }] : /* istanbul ignore next */ []));
|
|
2121
|
+
/** Emits when the datepicker has been opened. */
|
|
2122
|
+
this.openedStream = output({ alias: 'opened' });
|
|
2123
|
+
/** Emits when the datepicker has been closed. */
|
|
2124
|
+
this.closedStream = output({ alias: 'closed' });
|
|
2125
|
+
/** Emits when the datepicker is disabled. */
|
|
2126
|
+
this.disabledChange = new Subject();
|
|
2127
|
+
/** Emits new selected date when selected date changes. */
|
|
2128
|
+
this.selectedChanged = new Subject();
|
|
2129
|
+
/** The id for the datepicker calendar. */
|
|
2130
|
+
this.id = `kbq-datepicker-${datepickerUid++}`;
|
|
2131
|
+
this.validSelected = null;
|
|
2132
|
+
/** The element that was focused before the datepicker was opened. */
|
|
2133
|
+
this.focusedElementBeforeOpen = null;
|
|
2134
|
+
/** Subscription to value changes in the associated input element. */
|
|
2135
|
+
this.inputSubscription = Subscription.EMPTY;
|
|
2136
|
+
this.closeSubscription = Subscription.EMPTY;
|
|
2137
|
+
this.scrollStrategy = inject(KBQ_DATEPICKER_SCROLL_STRATEGY);
|
|
2138
|
+
}
|
|
2139
|
+
ngOnChanges(changes) {
|
|
2140
|
+
// A bound input is handed to its member; unbound, it leaves what code wrote.
|
|
2141
|
+
if (changes['hasBackdropInput']) {
|
|
2142
|
+
const hasBackdrop = this.hasBackdropInput();
|
|
2143
|
+
if (hasBackdrop !== undefined)
|
|
2144
|
+
this.hasBackdrop = hasBackdrop;
|
|
2145
|
+
}
|
|
2146
|
+
// A bound `undefined` is handed over too, as an unset date.
|
|
2147
|
+
if (changes['startAtInput'])
|
|
2148
|
+
this.startAt = this.startAtInput() ?? null;
|
|
2149
|
+
if (changes['disabledInput']) {
|
|
2150
|
+
const disabled = this.disabledInput();
|
|
2151
|
+
if (disabled !== undefined)
|
|
2152
|
+
this.disabled = disabled;
|
|
2153
|
+
}
|
|
2154
|
+
if (changes['openedInput']) {
|
|
2155
|
+
const opened = this.openedInput();
|
|
2156
|
+
if (opened !== undefined)
|
|
2157
|
+
this.opened = opened;
|
|
2088
2158
|
}
|
|
2089
2159
|
}
|
|
2090
|
-
|
|
2091
|
-
|
|
2160
|
+
ngOnDestroy() {
|
|
2161
|
+
// Before `close()`: a datepicker going away takes its popup along without playing the exit animation.
|
|
2162
|
+
this.destroyOverlay();
|
|
2163
|
+
this.close();
|
|
2164
|
+
this.inputSubscription.unsubscribe();
|
|
2165
|
+
this.closeSubscription.unsubscribe();
|
|
2166
|
+
this.disabledChange.complete();
|
|
2092
2167
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2168
|
+
/** Selects the given date */
|
|
2169
|
+
select(date) {
|
|
2170
|
+
const oldValue = this.selected;
|
|
2171
|
+
this.selected = date;
|
|
2172
|
+
if (!this.dateAdapter.sameDate(oldValue, this.selected)) {
|
|
2173
|
+
untracked(() => this.selectedChanged.next(date));
|
|
2096
2174
|
}
|
|
2097
|
-
return this.adapter.createDateTime(value.year, value.month - 1, value.date, value.hours, value.minutes, value.seconds, value.milliseconds);
|
|
2098
2175
|
}
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
correctedCursorPosition() {
|
|
2103
|
-
const position = this.selectionStart ?? 0;
|
|
2104
|
-
return this.separatorPositions.includes(position) ? position - 1 : position;
|
|
2176
|
+
/** Emits the selected year in multiyear view */
|
|
2177
|
+
selectYear(normalizedYear) {
|
|
2178
|
+
this.yearSelected.emit(normalizedYear);
|
|
2105
2179
|
}
|
|
2106
|
-
/**
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
KBQ_DATEPICKER_VALIDATORS,
|
|
2110
|
-
{ provide: KbqFormFieldControl, useExisting: KbqDatepickerInput }
|
|
2111
|
-
], exportAs: ["kbqDatepickerInput"], ngImport: i0 }); }
|
|
2112
|
-
}
|
|
2113
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqDatepickerInput, decorators: [{
|
|
2114
|
-
type: Directive,
|
|
2115
|
-
args: [{
|
|
2116
|
-
selector: 'input[kbqDatepicker], input[kbqCalendar]',
|
|
2117
|
-
providers: [
|
|
2118
|
-
KBQ_DATEPICKER_VALUE_ACCESSOR,
|
|
2119
|
-
KBQ_DATEPICKER_VALIDATORS,
|
|
2120
|
-
{ provide: KbqFormFieldControl, useExisting: KbqDatepickerInput }
|
|
2121
|
-
],
|
|
2122
|
-
host: {
|
|
2123
|
-
class: 'kbq-input kbq-datepicker',
|
|
2124
|
-
'[attr.placeholder]': 'placeholder',
|
|
2125
|
-
'[attr.required]': 'required',
|
|
2126
|
-
'[attr.disabled]': 'disabled || null',
|
|
2127
|
-
'[attr.min]': 'min ? toISO8601(min) : null',
|
|
2128
|
-
'[attr.max]': 'max ? toISO8601(max) : null',
|
|
2129
|
-
'[attr.autocomplete]': '"off"',
|
|
2130
|
-
'(paste)': 'onPaste($event)',
|
|
2131
|
-
'(change)': 'onChange()',
|
|
2132
|
-
'(focus)': 'focusChanged(true)',
|
|
2133
|
-
'(blur)': 'onBlur()',
|
|
2134
|
-
'(keydown)': 'onKeyDown($event)'
|
|
2135
|
-
},
|
|
2136
|
-
exportAs: 'kbqDatepickerInput'
|
|
2137
|
-
}]
|
|
2138
|
-
}], ctorParameters: () => [], propDecorators: { errorStateMatcher: [{
|
|
2139
|
-
type: Input
|
|
2140
|
-
}], placeholder: [{
|
|
2141
|
-
type: Input
|
|
2142
|
-
}], required: [{
|
|
2143
|
-
type: Input
|
|
2144
|
-
}], kbqDatepicker: [{
|
|
2145
|
-
type: Input
|
|
2146
|
-
}], kbqCalendar: [{
|
|
2147
|
-
type: Input
|
|
2148
|
-
}], kbqDatepickerFilter: [{
|
|
2149
|
-
type: Input
|
|
2150
|
-
}], value: [{
|
|
2151
|
-
type: Input
|
|
2152
|
-
}], min: [{
|
|
2153
|
-
type: Input
|
|
2154
|
-
}], max: [{
|
|
2155
|
-
type: Input
|
|
2156
|
-
}], disabled: [{
|
|
2157
|
-
type: Input
|
|
2158
|
-
}], id: [{
|
|
2159
|
-
type: Input
|
|
2160
|
-
}], kbqValidationTooltip: [{
|
|
2161
|
-
type: Input
|
|
2162
|
-
}], incorrectInput: [{ type: i0.Output, args: ["incorrectInput"] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], dateInput: [{ type: i0.Output, args: ["dateInput"] }] } });
|
|
2163
|
-
|
|
2164
|
-
/** Can be used to override the icon of a `kbqDatepickerToggle`. */
|
|
2165
|
-
class KbqDatepickerToggleIcon {
|
|
2166
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqDatepickerToggleIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2167
|
-
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.30", type: KbqDatepickerToggleIcon, isStandalone: true, selector: "[kbqDatepickerToggleIcon]", ngImport: i0 }); }
|
|
2168
|
-
}
|
|
2169
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqDatepickerToggleIcon, decorators: [{
|
|
2170
|
-
type: Directive,
|
|
2171
|
-
args: [{
|
|
2172
|
-
selector: '[kbqDatepickerToggleIcon]'
|
|
2173
|
-
}]
|
|
2174
|
-
}] });
|
|
2175
|
-
class KbqDatepickerToggleIconComponent {
|
|
2176
|
-
constructor() {
|
|
2177
|
-
this._disabled = false;
|
|
2178
|
-
/** Datepicker instance that the button will toggle. */
|
|
2179
|
-
this.datepicker = input(undefined, ...(ngDevMode ? [{ debugName: "datepicker", alias: 'for' }] : [{ alias: 'for' }]));
|
|
2180
|
-
/**
|
|
2181
|
-
* Emits `true` when the calendar opens and `false` when it closes. Part of the `KbqSiblingPopup`
|
|
2182
|
-
* contract.
|
|
2183
|
-
*
|
|
2184
|
-
* Built on top of the `datepicker` signal rather than read once, because the instance is bound after the
|
|
2185
|
-
* consumers of this stream (a tooltip on the same element subscribes in its constructor) and may be
|
|
2186
|
-
* swapped later — the same reason `watchStateChanges` is re-run from `ngOnChanges`.
|
|
2187
|
-
*/
|
|
2188
|
-
this.openedChange = toObservable(this.datepicker).pipe(filter(Boolean), switchMap((datepicker) => merge(outputToObservable(datepicker.openedStream).pipe(map(() => true)), outputToObservable(datepicker.closedStream).pipe(map(() => false)))));
|
|
2189
|
-
this.destroyRef = inject(DestroyRef);
|
|
2190
|
-
this.cdr = inject(ChangeDetectorRef);
|
|
2191
|
-
this.stateChangesSubscription = Subscription.EMPTY;
|
|
2180
|
+
/** Emits selected month in year view */
|
|
2181
|
+
selectMonth(normalizedMonth) {
|
|
2182
|
+
this.monthSelected.emit(normalizedMonth);
|
|
2192
2183
|
}
|
|
2193
|
-
/**
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2184
|
+
/**
|
|
2185
|
+
* Register an input with this datepicker.
|
|
2186
|
+
*
|
|
2187
|
+
* @param input The datepicker input to register with this datepicker.
|
|
2188
|
+
*/
|
|
2189
|
+
registerInput(input) {
|
|
2190
|
+
if (this.datepickerInput) {
|
|
2191
|
+
throw Error('A KbqDatepicker can only be associated with a single input.');
|
|
2192
|
+
}
|
|
2193
|
+
this.datepickerInput = input;
|
|
2194
|
+
this.inputSubscription = this.datepickerInput.valueChange.subscribe((value) => {
|
|
2195
|
+
this.selected = value;
|
|
2196
|
+
if (this.popupComponentRef) {
|
|
2197
|
+
const calendar = this.popupComponentRef.instance.calendar();
|
|
2198
|
+
calendar.monthView()?.init();
|
|
2199
|
+
calendar.activeDate = value;
|
|
2200
|
+
}
|
|
2201
|
+
});
|
|
2198
2202
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2203
|
+
/** Open the calendar. */
|
|
2204
|
+
open() {
|
|
2205
|
+
// Untracked, as `close()`, `toggle()` and `select()`: called from a consumer's `effect()`, the state read on
|
|
2206
|
+
// the way — `opened`, `disabled`, the inputs, the value of the input — would make the effect run again on
|
|
2207
|
+
// every open and close.
|
|
2208
|
+
untracked(() => this.openCalendar());
|
|
2201
2209
|
}
|
|
2202
|
-
/**
|
|
2203
|
-
|
|
2204
|
-
|
|
2210
|
+
/** Close the calendar. */
|
|
2211
|
+
close(restoreFocus = true) {
|
|
2212
|
+
untracked(() => this.closeCalendar(restoreFocus));
|
|
2205
2213
|
}
|
|
2206
|
-
|
|
2207
|
-
if (
|
|
2208
|
-
|
|
2214
|
+
toggle() {
|
|
2215
|
+
if (this.datepickerInput.isReadOnly) {
|
|
2216
|
+
return;
|
|
2217
|
+
}
|
|
2218
|
+
if (untracked(this.openedState)) {
|
|
2219
|
+
this.close();
|
|
2220
|
+
}
|
|
2221
|
+
else {
|
|
2222
|
+
this.open();
|
|
2209
2223
|
}
|
|
2210
2224
|
}
|
|
2211
|
-
|
|
2212
|
-
|
|
2225
|
+
/** Body of `open()`. */
|
|
2226
|
+
openCalendar() {
|
|
2227
|
+
if (this.openedState() || this.disabled) {
|
|
2228
|
+
return;
|
|
2229
|
+
}
|
|
2230
|
+
if (!this.datepickerInput) {
|
|
2231
|
+
throw Error('Attempted to open an KbqDatepicker with no associated input.');
|
|
2232
|
+
}
|
|
2233
|
+
if (this.document) {
|
|
2234
|
+
this.focusedElementBeforeOpen = _getFocusedElementPierceShadowDom();
|
|
2235
|
+
}
|
|
2236
|
+
this.openAsPopup();
|
|
2237
|
+
this.openedState.set(true);
|
|
2238
|
+
this.openedStream.emit();
|
|
2213
2239
|
}
|
|
2214
|
-
|
|
2215
|
-
|
|
2240
|
+
/** Body of `close()`. */
|
|
2241
|
+
closeCalendar(restoreFocus) {
|
|
2242
|
+
if (!this.openedState()) {
|
|
2243
|
+
return;
|
|
2244
|
+
}
|
|
2245
|
+
// A popup the overlay has already taken down, e.g. on scroll, has nothing left to animate.
|
|
2246
|
+
if (this.popupComponentRef?.hostView.destroyed) {
|
|
2247
|
+
this.destroyOverlay();
|
|
2248
|
+
}
|
|
2249
|
+
else if (this.popupComponentRef) {
|
|
2250
|
+
const instance = this.popupComponentRef.instance;
|
|
2251
|
+
instance.startExitAnimation();
|
|
2252
|
+
instance.animationDone.pipe(take(1)).subscribe(() => this.destroyOverlay());
|
|
2253
|
+
}
|
|
2254
|
+
if (restoreFocus) {
|
|
2255
|
+
this.focusedElementBeforeOpen.focus();
|
|
2256
|
+
}
|
|
2257
|
+
this.openedState.set(false);
|
|
2258
|
+
this.closedStream.emit();
|
|
2259
|
+
this.focusedElementBeforeOpen = null;
|
|
2216
2260
|
}
|
|
2217
|
-
/**
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
$event.stopPropagation();
|
|
2261
|
+
/** Destroys the current overlay. */
|
|
2262
|
+
destroyOverlay() {
|
|
2263
|
+
if (this.popupRef) {
|
|
2264
|
+
this.popupRef.dispose();
|
|
2265
|
+
this.popupRef = this.popupComponentRef = null;
|
|
2223
2266
|
}
|
|
2224
2267
|
}
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2268
|
+
/** Open the calendar as a popup. */
|
|
2269
|
+
openAsPopup() {
|
|
2270
|
+
if (!this.calendarPortal) {
|
|
2271
|
+
this.calendarPortal = new ComponentPortal(KbqDatepickerContent, this.viewContainerRef);
|
|
2272
|
+
}
|
|
2273
|
+
// The popup of the last opening may still be playing its exit: disposed once that ends, it would close this one.
|
|
2274
|
+
if (this.popupComponentRef?.instance.animationState === 'void') {
|
|
2275
|
+
this.destroyOverlay();
|
|
2276
|
+
}
|
|
2277
|
+
if (!this.popupRef) {
|
|
2278
|
+
this.createPopup();
|
|
2279
|
+
}
|
|
2280
|
+
if (!this.popupRef.hasAttached()) {
|
|
2281
|
+
this.popupComponentRef = this.popupRef.attach(this.calendarPortal);
|
|
2282
|
+
this.popupComponentRef.instance.datepicker = this;
|
|
2283
|
+
// Update the position once the calendar has rendered.
|
|
2284
|
+
afterNextRender(() => this.popupRef?.updatePosition(), { injector: this.injector });
|
|
2285
|
+
}
|
|
2233
2286
|
}
|
|
2234
|
-
/**
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2287
|
+
/** Create the popup. */
|
|
2288
|
+
createPopup() {
|
|
2289
|
+
const overlayConfig = new OverlayConfig({
|
|
2290
|
+
positionStrategy: this.createPopupPositionStrategy(),
|
|
2291
|
+
hasBackdrop: this.hasBackdrop,
|
|
2292
|
+
backdropClass: this.backdropClass(),
|
|
2293
|
+
direction: this.dir,
|
|
2294
|
+
scrollStrategy: this.scrollStrategy(),
|
|
2295
|
+
panelClass: 'kbq-datepicker__popup'
|
|
2296
|
+
});
|
|
2297
|
+
this.popupRef = this.overlay.create(overlayConfig);
|
|
2298
|
+
this.overlayLayers.adopt(this.popupRef, this.datepickerInput.getOrigin().nativeElement);
|
|
2299
|
+
this.closeSubscription = this.closingActions().subscribe(() => this.close(this.restoreFocus()));
|
|
2300
|
+
// The input handles the keys while it has the focus; this covers a focus inside the calendar. CDK hands a key
|
|
2301
|
+
// only to the topmost overlay listening for keys, so a modal underneath no longer closes on the same Escape.
|
|
2302
|
+
this.closeSubscription.add(this.popupRef
|
|
2303
|
+
.keydownEvents()
|
|
2304
|
+
.pipe(filter((event) => event.keyCode === ESCAPE))
|
|
2305
|
+
.subscribe((event) => {
|
|
2306
|
+
event.preventDefault();
|
|
2307
|
+
this.close();
|
|
2308
|
+
}));
|
|
2309
|
+
}
|
|
2310
|
+
/** Whether a close from outside the calendar has to return the focus: unless the press moved it somewhere else. */
|
|
2311
|
+
restoreFocus() {
|
|
2312
|
+
const focused = this.document.activeElement;
|
|
2313
|
+
// A press that keeps the focus where it was, as on the toggle, leaves it in the calendar about to go away.
|
|
2314
|
+
return focused === this.document.body || !!this.popupComponentRef?.location.nativeElement.contains(focused);
|
|
2315
|
+
}
|
|
2316
|
+
closingActions() {
|
|
2317
|
+
return merge(this.popupRef.backdropClick(), this.popupRef.outsidePointerEvents(), this.popupRef.detachments());
|
|
2318
|
+
}
|
|
2319
|
+
/** Create the popup PositionStrategy. */
|
|
2320
|
+
createPopupPositionStrategy() {
|
|
2321
|
+
return (this.overlay
|
|
2322
|
+
.position()
|
|
2323
|
+
.flexibleConnectedTo(this.datepickerInput.getOrigin())
|
|
2324
|
+
.withTransformOriginOn('.kbq-datepicker__content')
|
|
2325
|
+
.withFlexibleDimensions(false)
|
|
2326
|
+
// Also large enough to absorb the trigger↔panel gap padding (kbq-connected-overlay-gap,
|
|
2327
|
+
// defaultOffsetY = 4) that CDK's viewport-fit check can't see, since that padding is applied
|
|
2328
|
+
// via panelClass after the fit decision is made.
|
|
2329
|
+
.withViewportMargin(8)
|
|
2330
|
+
.withLockedPosition()
|
|
2331
|
+
.withPositions([
|
|
2332
|
+
{
|
|
2333
|
+
originX: 'start',
|
|
2334
|
+
originY: 'bottom',
|
|
2335
|
+
overlayX: 'start',
|
|
2336
|
+
overlayY: 'top',
|
|
2337
|
+
panelClass: KBQ_CONNECTED_OVERLAY_BELOW_CLASS
|
|
2338
|
+
},
|
|
2339
|
+
{
|
|
2340
|
+
originX: 'start',
|
|
2341
|
+
originY: 'top',
|
|
2342
|
+
overlayX: 'start',
|
|
2343
|
+
overlayY: 'bottom',
|
|
2344
|
+
panelClass: KBQ_CONNECTED_OVERLAY_ABOVE_CLASS
|
|
2345
|
+
},
|
|
2346
|
+
{
|
|
2347
|
+
originX: 'end',
|
|
2348
|
+
originY: 'bottom',
|
|
2349
|
+
overlayX: 'end',
|
|
2350
|
+
overlayY: 'top'
|
|
2351
|
+
},
|
|
2352
|
+
{
|
|
2353
|
+
originX: 'end',
|
|
2354
|
+
originY: 'top',
|
|
2355
|
+
overlayX: 'end',
|
|
2356
|
+
overlayY: 'bottom'
|
|
2357
|
+
}
|
|
2358
|
+
]));
|
|
2359
|
+
}
|
|
2360
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepicker, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2361
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: KbqDatepicker, isStandalone: true, selector: "kbq-datepicker", inputs: { hasBackdropInput: { classPropertyName: "hasBackdropInput", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, startAtInput: { classPropertyName: "startAtInput", publicName: "startAt", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, openedInput: { classPropertyName: "openedInput", publicName: "opened", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, dateClass: { classPropertyName: "dateClass", publicName: "dateClass", isSignal: true, isRequired: false, transformFunction: null }, backdropClass: { classPropertyName: "backdropClass", publicName: "backdropClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { yearSelected: "yearSelected", monthSelected: "monthSelected", openedStream: "opened", closedStream: "closed" }, exportAs: ["kbqDatepicker"], usesOnChanges: true, hostDirectives: [{ directive: i4.KbqLocaleOverridesDirective, inputs: ["kbqLocaleOverrides", "localeOverrides"] }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2247
2362
|
}
|
|
2248
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2363
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepicker, decorators: [{
|
|
2249
2364
|
type: Component,
|
|
2250
|
-
args: [{
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
'[attr.aria-expanded]': 'datepicker().opened',
|
|
2264
|
-
'[attr.aria-disabled]': 'disabled',
|
|
2265
|
-
'(click)': 'open($event)'
|
|
2266
|
-
}, styles: [".kbq-datepicker-toggle-icon{display:inline-flex;justify-content:center;align-items:center}.kbq-datepicker-toggle:focus{outline:0}.kbq-datepicker-toggle__button.kbq-button-icon{width:var(--kbq-datepicker-toggle-size-width, var(--kbq-size-3xl));height:var(--kbq-datepicker-toggle-size-height, var(--kbq-size-3xl));margin-left:2px}.kbq-form-field-appearance-legacy .kbq-form-field-prefix .kbq-datepicker-toggle__default-icon,.kbq-form-field-appearance-legacy .kbq-form-field-suffix .kbq-datepicker-toggle__default-icon{width:1em}.kbq-form-field:not(.kbq-form-field-appearance-legacy) .kbq-form-field-prefix .kbq-datepicker-toggle__default-icon,.kbq-form-field:not(.kbq-form-field-appearance-legacy) .kbq-form-field-suffix .kbq-datepicker-toggle__default-icon{display:block;width:1.5em;height:1.5em}.kbq-form-field:not(.kbq-form-field-appearance-legacy) .kbq-form-field-prefix .kbq-button-icon .kbq-datepicker-toggle__default-icon,.kbq-form-field:not(.kbq-form-field-appearance-legacy) .kbq-form-field-suffix .kbq-button-icon .kbq-datepicker-toggle__default-icon{margin:auto}\n"] }]
|
|
2267
|
-
}], propDecorators: { disabled: [{
|
|
2268
|
-
type: Input
|
|
2269
|
-
}], datepicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "for", required: false }] }] } });
|
|
2365
|
+
args: [{
|
|
2366
|
+
selector: 'kbq-datepicker',
|
|
2367
|
+
template: '',
|
|
2368
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2369
|
+
encapsulation: ViewEncapsulation.None,
|
|
2370
|
+
// The calendar is created through this component's `ViewContainerRef`, so this is the element whose
|
|
2371
|
+
// carrier it resolves — the one on the input is a sibling of it and never reaches the pop-up.
|
|
2372
|
+
hostDirectives: [
|
|
2373
|
+
{ directive: KbqLocaleOverridesDirective, inputs: ['kbqLocaleOverrides: localeOverrides'] }
|
|
2374
|
+
],
|
|
2375
|
+
exportAs: 'kbqDatepicker'
|
|
2376
|
+
}]
|
|
2377
|
+
}], ctorParameters: () => [], propDecorators: { hasBackdropInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBackdrop", required: false }] }], startAtInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAt", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], openedInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "opened", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], yearSelected: [{ type: i0.Output, args: ["yearSelected"] }], monthSelected: [{ type: i0.Output, args: ["monthSelected"] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], dateClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateClass", required: false }] }], backdropClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdropClass", required: false }] }], openedStream: [{ type: i0.Output, args: ["opened"] }], closedStream: [{ type: i0.Output, args: ["closed"] }] } });
|
|
2270
2378
|
|
|
2271
2379
|
class KbqDatepickerModule {
|
|
2272
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2273
|
-
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
2380
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2381
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerModule, imports: [KbqButtonModule,
|
|
2274
2382
|
OverlayModule,
|
|
2275
2383
|
A11yModule,
|
|
2276
2384
|
PortalModule,
|
|
@@ -2295,7 +2403,7 @@ class KbqDatepickerModule {
|
|
|
2295
2403
|
KbqMonthView,
|
|
2296
2404
|
KbqCalendarHeader,
|
|
2297
2405
|
KbqFormFieldModule] }); }
|
|
2298
|
-
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
2406
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerModule, imports: [KbqButtonModule,
|
|
2299
2407
|
OverlayModule,
|
|
2300
2408
|
A11yModule,
|
|
2301
2409
|
PortalModule,
|
|
@@ -2306,7 +2414,7 @@ class KbqDatepickerModule {
|
|
|
2306
2414
|
KbqDatepickerContent,
|
|
2307
2415
|
KbqCalendarHeader, KbqFormFieldModule] }); }
|
|
2308
2416
|
}
|
|
2309
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2417
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqDatepickerModule, decorators: [{
|
|
2310
2418
|
type: NgModule,
|
|
2311
2419
|
args: [{
|
|
2312
2420
|
imports: [
|
|
@@ -2327,7 +2435,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
2327
2435
|
KbqMonthView,
|
|
2328
2436
|
KbqCalendarHeader
|
|
2329
2437
|
],
|
|
2330
|
-
providers: [KbqDatepickerIntl],
|
|
2331
2438
|
exports: [
|
|
2332
2439
|
KbqCalendar,
|
|
2333
2440
|
KbqCalendarBody,
|
|
@@ -2347,5 +2454,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
2347
2454
|
* Generated bundle index. Do not edit.
|
|
2348
2455
|
*/
|
|
2349
2456
|
|
|
2350
|
-
export { KBQ_DATEPICKER_CONFIGURATION, KBQ_DATEPICKER_DEFAULT_CONFIGURATION, KBQ_DATEPICKER_SCROLL_STRATEGY, KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY, KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER, KBQ_DATEPICKER_VALIDATORS, KBQ_DATEPICKER_VALUE_ACCESSOR, KbqCalendar, KbqCalendarBody, KbqCalendarCell, KbqCalendarHeader, KbqDatepicker, KbqDatepickerContent, KbqDatepickerInput, KbqDatepickerInputEvent,
|
|
2457
|
+
export { KBQ_DATEPICKER_CONFIGURATION, KBQ_DATEPICKER_DEFAULT_CONFIGURATION, KBQ_DATEPICKER_DEFAULT_LOCALE_CONFIGURATION, KBQ_DATEPICKER_LOCALE_CONFIGURATION, KBQ_DATEPICKER_SCROLL_STRATEGY, KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY, KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER, KBQ_DATEPICKER_VALIDATORS, KBQ_DATEPICKER_VALUE_ACCESSOR, KbqCalendar, KbqCalendarBody, KbqCalendarCell, KbqCalendarHeader, KbqDatepicker, KbqDatepickerContent, KbqDatepickerInput, KbqDatepickerInputEvent, KbqDatepickerModule, KbqDatepickerToggleIcon, KbqDatepickerToggleIconComponent, KbqMonthView, MAX_YEAR, kbqDatepickerLocaleConfigurationProvider };
|
|
2351
2458
|
//# sourceMappingURL=koobiq-components-datepicker.mjs.map
|