@salesforce/ui-bundle-template-app-angular-template-b2x 11.60.0 → 11.62.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CHANGELOG.md +24 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/angular.json +2 -7
- package/dist/force-app/main/default/uiBundles/angularextapp/components.json +6 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/eslint.config.js +9 -1
- package/dist/force-app/main/default/uiBundles/angularextapp/package.json +16 -11
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/app.config.ts +4 -6
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/app.routes.ts +2 -2
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/alert/alert.html +9 -13
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/alert/alert.ts +16 -28
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/button/button.html +19 -10
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/button/button.ts +34 -25
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/card/card.ts +40 -50
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/collapsible/collapsible.html +38 -10
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/collapsible/collapsible.ts +6 -11
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/date-picker/date-picker.html +17 -22
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/date-picker/date-picker.ts +29 -21
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/date-range-picker/date-range-picker.html +16 -30
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/date-range-picker/date-range-picker.ts +39 -36
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/dialog/dialog.html +13 -30
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/dialog/dialog.ts +6 -21
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/dropdown-menu/dropdown-menu.html +20 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/dropdown-menu/dropdown-menu.ts +100 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/field/field.html +5 -11
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/field/field.ts +10 -18
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/field-appearance.ts +8 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/icon/icon.ts +62 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/input/input.html +32 -17
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/input/input.ts +57 -14
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/label/label.ts +8 -4
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/paginator/paginator.html +74 -10
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/paginator/paginator.ts +74 -18
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/paginator/types.ts +13 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/popover/popover.html +10 -38
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/popover/popover.ts +12 -15
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/select/select.html +34 -22
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/select/select.ts +25 -34
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/separator/separator.ts +11 -36
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/skeleton/skeleton.ts +5 -9
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/spinner/spinner.ts +14 -21
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/authentication/auth-form/auth-form.html +2 -3
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/authentication/menu/auth-menu/auth-menu.html +31 -21
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/authentication/menu/auth-menu/auth-menu.ts +6 -18
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/authentication/session/session.html +2 -2
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/authentication/submit-button/submit-button.html +8 -4
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/authentication/submit-button/submit-button.ts +4 -16
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/breadcrumb/breadcrumb.html +4 -24
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/breadcrumb/breadcrumb.ts +3 -16
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/date-filter.ts +1 -1
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/date-range-filter.html +2 -1
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/date-range-filter.ts +6 -15
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/filter-field-wrapper.html +2 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/filter-field-wrapper.ts +2 -17
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/multi-select-filter.html +2 -1
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/numeric-range-filter.ts +3 -21
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/search-filter.html +3 -3
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/search-filter.ts +9 -13
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/select-filter.html +2 -5
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/select-filter.ts +1 -15
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/text-filter.html +2 -5
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/filters/text-filter.ts +3 -17
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/pagination/pagination.ts +4 -20
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/search-bar/search-bar.html +10 -59
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/search-bar/search-bar.ts +13 -93
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/sort-control/sort-control.html +3 -29
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/object-search/sort-control/sort-control.ts +5 -12
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/account-detail/account-detail-page.html +1 -23
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/account-detail/account-detail-page.ts +3 -23
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/account-search/account-search-page.html +1 -19
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/account-search/account-search-page.ts +8 -36
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/home/home.html +15 -4
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/home/home.spec.ts +8 -6
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/home/home.ts +56 -4
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/alert/hlm-alert-action.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/alert/hlm-alert-description.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/alert/hlm-alert-title.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/alert/hlm-alert.ts +35 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/alert/index.ts +16 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/button/hlm-button.token.ts +22 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/button/hlm-button.ts +72 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/button/index.ts +6 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/calendar/hlm-calendar-multi.ts +195 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/calendar/hlm-calendar-range.ts +194 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/calendar/hlm-calendar.ts +189 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/calendar/hlm-month-year-calendar.ts +119 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/calendar/index.ts +16 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/hlm-card-action.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/hlm-card-avatar.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/hlm-card-content.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/hlm-card-description.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/hlm-card-footer.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/hlm-card-header.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/hlm-card-title.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/hlm-card.token.ts +19 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/hlm-card.ts +22 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/card/index.ts +28 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/collapsible/hlm-collapsible-content.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/collapsible/hlm-collapsible-trigger.ts +9 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/collapsible/hlm-collapsible.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/collapsible/index.ts +13 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-multi-input.ts +104 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-picker-anchor.ts +23 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-picker-input.ts +118 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-picker-multi.token.ts +109 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-picker-multi.ts +220 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-picker-trigger.ts +104 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-picker.token.ts +69 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-picker.ts +203 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-range-input.ts +120 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-range-picker.token.ts +86 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-date-range-picker.ts +252 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-month-year-input.ts +105 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-month-year-picker.token.ts +89 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/hlm-month-year-picker.ts +196 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/date-picker/index.ts +38 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog-close.ts +9 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog-content.ts +74 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog-description.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog-footer.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog-header.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog-overlay.ts +27 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog-portal.ts +8 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog-title.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog-trigger.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog.service.ts +46 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/hlm-dialog.ts +24 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dialog/index.ts +35 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-checkbox-indicator.ts +21 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-checkbox.ts +54 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-focus-on-hover.ts +35 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-group.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-item-sub-indicator.ts +19 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-item.ts +42 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-label.ts +20 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-radio-indicator.ts +21 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-radio.ts +49 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-separator.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-shortcut.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-sub-trigger.ts +52 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-sub.ts +53 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-token.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu-trigger.ts +46 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/hlm-dropdown-menu.ts +57 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/dropdown-menu/index.ts +49 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field-content.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field-description.ts +53 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field-error.ts +100 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field-group.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field-label.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field-legend.ts +19 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field-separator.ts +24 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field-set.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field-title.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/hlm-field.ts +47 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/field/index.ts +34 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/input/hlm-input.ts +21 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/input/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/input-group/hlm-input-group-addon.ts +40 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/input-group/hlm-input-group-button.ts +47 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/input-group/hlm-input-group-input.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/input-group/hlm-input-group-text.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/input-group/hlm-input-group.ts +18 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/input-group/index.ts +19 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/label/hlm-label.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/label/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/label/label.html +11 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/hlm-numbered-pagination-query-params.ts +191 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/hlm-numbered-pagination.ts +290 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/hlm-pagination-content.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/hlm-pagination-ellipsis.ts +27 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/hlm-pagination-item.ts +7 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/hlm-pagination-link.ts +51 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/hlm-pagination-next.ts +65 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/hlm-pagination-previous.ts +65 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/hlm-pagination.ts +19 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/pagination/index.ts +31 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/popover/hlm-popover-content.ts +25 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/popover/hlm-popover-description.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/popover/hlm-popover-header.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/popover/hlm-popover-portal.ts +8 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/popover/hlm-popover-title.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/popover/hlm-popover-trigger.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/popover/hlm-popover.ts +23 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/popover/index.ts +25 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-content.ts +44 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-group.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-item.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-label.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-multiple.ts +37 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-placeholder.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-portal.ts +8 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-scroll-down.ts +22 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-scroll-up.ts +22 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-separator.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-trigger.ts +59 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-value-template.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-value.ts +18 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-values-content.ts +9 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select-values.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/hlm-select.ts +37 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/select/index.ts +52 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/separator/hlm-separator.ts +19 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/separator/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/skeleton/hlm-skeleton.ts +14 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/skeleton/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/spinner/hlm-spinner.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/spinner/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/utils/hlm.ts +313 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/utils/index.ts +2 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/shared/utils/provide-spartan-hlm.ts +34 -0
- package/dist/force-app/main/default/uiBundles/angularextapp/src/index.html +0 -1
- package/dist/force-app/main/default/uiBundles/angularextapp/src/{styles.scss → styles.css} +7 -38
- package/dist/force-app/main/default/uiBundles/angularextapp/tsconfig.json +4 -1
- package/dist/package-lock.json +2 -2
- package/dist/package.json +1 -1
- package/package.json +1 -1
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/_field-size.scss +0 -42
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/button/button.scss +0 -112
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/card/card.scss +0 -34
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/date-picker/date-picker.scss +0 -36
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/date-range-picker/date-range-picker.scss +0 -33
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/input/input.scss +0 -35
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/label/label.html +0 -3
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/select/select.scss +0 -35
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/separator/separator.html +0 -1
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/separator/separator.scss +0 -23
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/skeleton/skeleton.html +0 -1
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/components/ui/skeleton/skeleton.scss +0 -28
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/features/authentication/submit-button/submit-button.scss +0 -17
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/account-detail/account-detail-page.scss +0 -7
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/home/home-page.html +0 -18
- package/dist/force-app/main/default/uiBundles/angularextapp/src/app/pages/home/home-page.ts +0 -47
- package/dist/force-app/main/default/uiBundles/angularextapp/src/theme.scss +0 -39
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { inject, InjectionToken, type ValueProvider } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
export interface HlmDatePickerMultiConfig<T> {
|
|
4
|
+
/**
|
|
5
|
+
* If true, the date picker will close when the max selection of dates is reached.
|
|
6
|
+
*/
|
|
7
|
+
autoCloseOnMaxSelection: boolean;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Defines how the date should be displayed in the UI.
|
|
11
|
+
*
|
|
12
|
+
* @param dates
|
|
13
|
+
* @returns formatted date
|
|
14
|
+
*/
|
|
15
|
+
formatDates: (dates: T[]) => string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Defines how the dates should be displayed while the input is focused,
|
|
19
|
+
* i.e. the format the user is expected to type in.
|
|
20
|
+
*
|
|
21
|
+
* @param dates
|
|
22
|
+
* @returns formatted dates in the input/edit format
|
|
23
|
+
*/
|
|
24
|
+
formatInputDates: (dates: T[]) => string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Defines how the date should be transformed before saving to model/form.
|
|
28
|
+
*
|
|
29
|
+
* @param dates
|
|
30
|
+
* @returns transformed date
|
|
31
|
+
*/
|
|
32
|
+
transformDates: (dates: T[]) => T[];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Parse a user-entered string into a date.
|
|
36
|
+
*
|
|
37
|
+
* @param value the raw string from the input
|
|
38
|
+
* @returns the parsed date, or `null` when the value can't be parsed
|
|
39
|
+
*/
|
|
40
|
+
parseDate: (value: string) => T[] | null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getDefaultConfig<T>(): HlmDatePickerMultiConfig<T> {
|
|
44
|
+
return {
|
|
45
|
+
formatDates: (dates) =>
|
|
46
|
+
dates.map((date) => (date instanceof Date ? date.toDateString() : `${date}`)).join(', '),
|
|
47
|
+
formatInputDates: (dates) =>
|
|
48
|
+
dates
|
|
49
|
+
.map((date) => {
|
|
50
|
+
if (!(date instanceof Date)) return `${date}`;
|
|
51
|
+
|
|
52
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
53
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
54
|
+
const year = date.getFullYear();
|
|
55
|
+
|
|
56
|
+
return `${day}/${month}/${year}`;
|
|
57
|
+
})
|
|
58
|
+
.join(', '),
|
|
59
|
+
transformDates: (dates) => dates,
|
|
60
|
+
autoCloseOnMaxSelection: false,
|
|
61
|
+
parseDate: (value) => {
|
|
62
|
+
if (typeof value !== 'string') return null;
|
|
63
|
+
|
|
64
|
+
const parts = value.split(',').map((v) => v.trim());
|
|
65
|
+
const result: Date[] = [];
|
|
66
|
+
|
|
67
|
+
for (const part of parts) {
|
|
68
|
+
const match = part.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
|
|
69
|
+
if (!match) return null;
|
|
70
|
+
|
|
71
|
+
const day = Number(match[1]);
|
|
72
|
+
const month = Number(match[2]);
|
|
73
|
+
const year = Number(match[3]);
|
|
74
|
+
|
|
75
|
+
if (month < 1 || month > 12) return null;
|
|
76
|
+
if (day < 1 || day > 31) return null;
|
|
77
|
+
|
|
78
|
+
const date = new Date(year, month - 1, day);
|
|
79
|
+
|
|
80
|
+
if (
|
|
81
|
+
date.getFullYear() !== year ||
|
|
82
|
+
date.getMonth() !== month - 1 ||
|
|
83
|
+
date.getDate() !== day
|
|
84
|
+
) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
result.push(date);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return result as T[];
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const HlmDatePickerMultiConfigToken = new InjectionToken<HlmDatePickerMultiConfig<unknown>>(
|
|
97
|
+
'HlmDatePickerMultiConfig',
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
export function provideHlmDatePickerMultiConfig<T>(
|
|
101
|
+
config: Partial<HlmDatePickerMultiConfig<T>>,
|
|
102
|
+
): ValueProvider {
|
|
103
|
+
return { provide: HlmDatePickerMultiConfigToken, useValue: { ...getDefaultConfig(), ...config } };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function injectHlmDatePickerMultiConfig<T>(): HlmDatePickerMultiConfig<T> {
|
|
107
|
+
const injectedConfig = inject(HlmDatePickerMultiConfigToken, { optional: true });
|
|
108
|
+
return injectedConfig ? (injectedConfig as HlmDatePickerMultiConfig<T>) : getDefaultConfig();
|
|
109
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import type { BooleanInput, NumberInput } from '@angular/cdk/coercion';
|
|
2
|
+
import {
|
|
3
|
+
booleanAttribute,
|
|
4
|
+
ChangeDetectionStrategy,
|
|
5
|
+
Component,
|
|
6
|
+
computed,
|
|
7
|
+
contentChild,
|
|
8
|
+
forwardRef,
|
|
9
|
+
input,
|
|
10
|
+
linkedSignal,
|
|
11
|
+
numberAttribute,
|
|
12
|
+
output,
|
|
13
|
+
signal,
|
|
14
|
+
viewChild,
|
|
15
|
+
} from '@angular/core';
|
|
16
|
+
import { type ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
17
|
+
import {
|
|
18
|
+
type BrnDatePickerBase,
|
|
19
|
+
BrnDatePickerTriggerToken,
|
|
20
|
+
provideBrnDatePicker,
|
|
21
|
+
} from '@spartan-ng/brain/date-picker';
|
|
22
|
+
import { BrnFieldControl, provideBrnLabelable } from '@spartan-ng/brain/field';
|
|
23
|
+
import type { ChangeFn, TouchFn } from '@spartan-ng/brain/forms';
|
|
24
|
+
import type { BrnOverlayState } from '@spartan-ng/brain/overlay';
|
|
25
|
+
import { BrnPopover, type BrnPopoverAlign } from '@spartan-ng/brain/popover';
|
|
26
|
+
import { HlmCalendarMulti } from '@spartan-ng/styles/calendar';
|
|
27
|
+
import { HlmPopoverImports } from '@spartan-ng/styles/popover';
|
|
28
|
+
import { injectHlmDatePickerMultiConfig } from './hlm-date-picker-multi.token';
|
|
29
|
+
|
|
30
|
+
export const HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR = {
|
|
31
|
+
provide: NG_VALUE_ACCESSOR,
|
|
32
|
+
useExisting: forwardRef(() => HlmDatePickerMulti),
|
|
33
|
+
multi: true,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
@Component({
|
|
37
|
+
selector: 'hlm-date-picker-multi',
|
|
38
|
+
imports: [HlmPopoverImports, HlmCalendarMulti],
|
|
39
|
+
providers: [
|
|
40
|
+
HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR,
|
|
41
|
+
provideBrnDatePicker(HlmDatePickerMulti),
|
|
42
|
+
provideBrnLabelable(HlmDatePickerMulti),
|
|
43
|
+
],
|
|
44
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
45
|
+
hostDirectives: [BrnFieldControl],
|
|
46
|
+
host: { class: 'block' },
|
|
47
|
+
template: `
|
|
48
|
+
<hlm-popover
|
|
49
|
+
[align]="align()"
|
|
50
|
+
sideOffset="5"
|
|
51
|
+
[state]="_popoverState()"
|
|
52
|
+
(stateChanged)="_onStateChange($event)"
|
|
53
|
+
>
|
|
54
|
+
<ng-content />
|
|
55
|
+
|
|
56
|
+
<hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
|
|
57
|
+
<ng-content select="[hlmDatePickerHeader]" />
|
|
58
|
+
<hlm-calendar-multi
|
|
59
|
+
class="rounded-none border-0"
|
|
60
|
+
[date]="_mutableDate()"
|
|
61
|
+
[captionLayout]="captionLayout()"
|
|
62
|
+
[min]="minDate()"
|
|
63
|
+
[max]="maxDate()"
|
|
64
|
+
[minSelection]="minSelection()"
|
|
65
|
+
[maxSelection]="maxSelection()"
|
|
66
|
+
[disabled]="_disabled()"
|
|
67
|
+
(dateChange)="_handleChange($event)"
|
|
68
|
+
/>
|
|
69
|
+
<ng-content select="[hlmDatePickerFooter]" />
|
|
70
|
+
</hlm-popover-content>
|
|
71
|
+
</hlm-popover>
|
|
72
|
+
`,
|
|
73
|
+
})
|
|
74
|
+
export class HlmDatePickerMulti<T> implements BrnDatePickerBase<T[]>, ControlValueAccessor {
|
|
75
|
+
private readonly _config = injectHlmDatePickerMultiConfig<T>();
|
|
76
|
+
|
|
77
|
+
public readonly popover = viewChild.required(BrnPopover);
|
|
78
|
+
|
|
79
|
+
private readonly _trigger = contentChild(BrnDatePickerTriggerToken);
|
|
80
|
+
|
|
81
|
+
public readonly align = input<BrnPopoverAlign>('center');
|
|
82
|
+
|
|
83
|
+
/** Show dropdowns to navigate between months or years. */
|
|
84
|
+
public readonly captionLayout = input<
|
|
85
|
+
'dropdown' | 'label' | 'dropdown-months' | 'dropdown-years'
|
|
86
|
+
>('label');
|
|
87
|
+
|
|
88
|
+
/** The minimum date that can be selected.*/
|
|
89
|
+
public readonly minDate = input<T>();
|
|
90
|
+
|
|
91
|
+
/** The maximum date that can be selected. */
|
|
92
|
+
public readonly maxDate = input<T>();
|
|
93
|
+
|
|
94
|
+
/** The minimum selectable dates. */
|
|
95
|
+
public readonly minSelection = input<number, NumberInput>(undefined, {
|
|
96
|
+
transform: numberAttribute,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
/** The maximum selectable dates. */
|
|
100
|
+
public readonly maxSelection = input<number, NumberInput>(undefined, {
|
|
101
|
+
transform: numberAttribute,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
/** Determine if the date picker is disabled. */
|
|
105
|
+
public readonly disabled = input<boolean, BooleanInput>(false, {
|
|
106
|
+
transform: booleanAttribute,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
/** The selected value. */
|
|
110
|
+
public readonly date = input<T[]>();
|
|
111
|
+
|
|
112
|
+
protected readonly _mutableDate = linkedSignal(this.date);
|
|
113
|
+
|
|
114
|
+
/** If true, the date picker will close when the max selection of dates is reached. */
|
|
115
|
+
public readonly autoCloseOnMaxSelection = input<boolean, BooleanInput>(
|
|
116
|
+
this._config.autoCloseOnMaxSelection,
|
|
117
|
+
{
|
|
118
|
+
transform: booleanAttribute,
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
/** Defines how the date should be displayed in the UI. */
|
|
123
|
+
public readonly formatDates = input<(date: T[]) => string>(this._config.formatDates);
|
|
124
|
+
|
|
125
|
+
/** Defines how the date should be transformed before saving to model/form. */
|
|
126
|
+
public readonly transformDates = input<(date: T[]) => T[]>(this._config.transformDates);
|
|
127
|
+
|
|
128
|
+
protected readonly _popoverState = signal<BrnOverlayState | null>(null);
|
|
129
|
+
|
|
130
|
+
protected readonly _disabled = linkedSignal(this.disabled);
|
|
131
|
+
|
|
132
|
+
/** @internal The disabled state as a readonly signal */
|
|
133
|
+
public readonly disabledState = this._disabled.asReadonly();
|
|
134
|
+
|
|
135
|
+
public readonly formattedDate = computed(() => {
|
|
136
|
+
const dates = this._mutableDate();
|
|
137
|
+
return dates ? this.formatDates()(dates) : undefined;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
public readonly dateChange = output<T[]>();
|
|
141
|
+
|
|
142
|
+
public readonly labelableId = computed(() => this._trigger()?.triggerId());
|
|
143
|
+
|
|
144
|
+
public readonly hasDate = computed(() => !!this._mutableDate()?.length);
|
|
145
|
+
|
|
146
|
+
/** @internal The current raw value, used by inputs to reformat on focus. */
|
|
147
|
+
public readonly value = computed(() => this._mutableDate() ?? null);
|
|
148
|
+
|
|
149
|
+
protected _onChange?: ChangeFn<T[]>;
|
|
150
|
+
protected _onTouched?: TouchFn;
|
|
151
|
+
|
|
152
|
+
protected _onStateChange(state: BrnOverlayState) {
|
|
153
|
+
this._popoverState.set(state);
|
|
154
|
+
if (state === 'closed') this._onTouched?.();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
protected _handleChange(value: T[] | undefined) {
|
|
158
|
+
if (value === undefined) return;
|
|
159
|
+
|
|
160
|
+
if (this._disabled()) return;
|
|
161
|
+
const transformedDate = value !== undefined ? this.transformDates()(value) : value;
|
|
162
|
+
|
|
163
|
+
this._mutableDate.set(transformedDate);
|
|
164
|
+
this._onChange?.(transformedDate);
|
|
165
|
+
this.dateChange.emit(transformedDate);
|
|
166
|
+
|
|
167
|
+
if (this.autoCloseOnMaxSelection() && this._mutableDate()?.length === this.maxSelection()) {
|
|
168
|
+
this._popoverState.set('closed');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Commit dates to the picker. Updates the internal model, notifies form
|
|
174
|
+
* controls, and emits `dateChange`. Intended to be called from a text input
|
|
175
|
+
* that parses user-entered values. Pass `null` to clear the selection.
|
|
176
|
+
*/
|
|
177
|
+
public updateDate(value: T[] | null) {
|
|
178
|
+
if (this._disabled()) return;
|
|
179
|
+
const transformedDate = value ? this.transformDates()(value) : undefined;
|
|
180
|
+
|
|
181
|
+
this._mutableDate.set(transformedDate);
|
|
182
|
+
this._onChange?.(transformedDate ?? []);
|
|
183
|
+
this.dateChange.emit(transformedDate ?? []);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public touched(): void {
|
|
187
|
+
this._onTouched?.();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** CONTROL VALUE ACCESSOR */
|
|
191
|
+
public writeValue(value: T[] | null): void {
|
|
192
|
+
this._mutableDate.set(value ? this.transformDates()(value) : undefined);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
public registerOnChange(fn: ChangeFn<T[]>): void {
|
|
196
|
+
this._onChange = fn;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
public registerOnTouched(fn: TouchFn): void {
|
|
200
|
+
this._onTouched = fn;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
public setDisabledState(isDisabled: boolean): void {
|
|
204
|
+
this._disabled.set(isDisabled);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
public open() {
|
|
208
|
+
this._popoverState.set('open');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
public close() {
|
|
212
|
+
this._popoverState.set('closed');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
public reset() {
|
|
216
|
+
this._mutableDate.set(undefined);
|
|
217
|
+
this._onChange?.([]);
|
|
218
|
+
this.dateChange.emit([]);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { BooleanInput } from '@angular/cdk/coercion';
|
|
2
|
+
import {
|
|
3
|
+
booleanAttribute,
|
|
4
|
+
ChangeDetectionStrategy,
|
|
5
|
+
Component,
|
|
6
|
+
computed,
|
|
7
|
+
inject,
|
|
8
|
+
input,
|
|
9
|
+
} from '@angular/core';
|
|
10
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
11
|
+
import { lucideChevronDown } from '@ng-icons/lucide';
|
|
12
|
+
import {
|
|
13
|
+
type BrnDatePickerTriggerBase,
|
|
14
|
+
injectBrnDatePicker,
|
|
15
|
+
provideBrnDatePickerTrigger,
|
|
16
|
+
} from '@spartan-ng/brain/date-picker';
|
|
17
|
+
import { BrnFieldControl, BrnFieldControlDescribedBy } from '@spartan-ng/brain/field';
|
|
18
|
+
import { ButtonVariants, HlmButtonImports } from '@spartan-ng/styles/button';
|
|
19
|
+
import { HlmPopoverTrigger } from '@spartan-ng/styles/popover';
|
|
20
|
+
import { hlm } from '@spartan-ng/styles/utils';
|
|
21
|
+
import { ClassValue } from 'clsx';
|
|
22
|
+
|
|
23
|
+
@Component({
|
|
24
|
+
selector: 'hlm-date-picker-trigger',
|
|
25
|
+
imports: [HlmButtonImports, HlmPopoverTrigger, NgIcon, BrnFieldControlDescribedBy],
|
|
26
|
+
providers: [
|
|
27
|
+
provideIcons({ lucideChevronDown }),
|
|
28
|
+
provideBrnDatePickerTrigger(HlmDatePickerTrigger),
|
|
29
|
+
],
|
|
30
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
31
|
+
host: { 'data-slot': 'date-picker-trigger' },
|
|
32
|
+
template: `
|
|
33
|
+
<button
|
|
34
|
+
[id]="buttonId()"
|
|
35
|
+
type="button"
|
|
36
|
+
[class]="_computedClass()"
|
|
37
|
+
[disabled]="_disabled()"
|
|
38
|
+
[attr.aria-invalid]="_ariaInvalid()"
|
|
39
|
+
[attr.data-invalid]="_ariaInvalid()"
|
|
40
|
+
[attr.data-touched]="_touched?.() ? 'true' : null"
|
|
41
|
+
[attr.data-dirty]="_dirty?.() ? 'true' : null"
|
|
42
|
+
[attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
|
|
43
|
+
hlmBtn
|
|
44
|
+
[variant]="variant()"
|
|
45
|
+
hlmPopoverTrigger
|
|
46
|
+
[hlmPopoverTriggerFor]="_popover()"
|
|
47
|
+
brnFieldControlDescribedBy
|
|
48
|
+
[attr.data-placeholder]="_isPlaceholder() ? '' : null"
|
|
49
|
+
>
|
|
50
|
+
<span class="truncate">
|
|
51
|
+
@if (_formattedDate(); as formattedDate) {
|
|
52
|
+
{{ formattedDate }}
|
|
53
|
+
} @else {
|
|
54
|
+
<ng-content />
|
|
55
|
+
}
|
|
56
|
+
</span>
|
|
57
|
+
|
|
58
|
+
@if (showTrigger()) {
|
|
59
|
+
<ng-icon name="lucideChevronDown" />
|
|
60
|
+
}
|
|
61
|
+
</button>
|
|
62
|
+
`,
|
|
63
|
+
})
|
|
64
|
+
export class HlmDatePickerTrigger implements BrnDatePickerTriggerBase {
|
|
65
|
+
private static _nextId = 0;
|
|
66
|
+
|
|
67
|
+
private readonly _fieldControl = inject(BrnFieldControl, { optional: true });
|
|
68
|
+
private readonly _datePicker = injectBrnDatePicker();
|
|
69
|
+
|
|
70
|
+
private readonly _invalid = this._fieldControl?.invalid;
|
|
71
|
+
protected readonly _spartanInvalid = computed(
|
|
72
|
+
() => this.forceInvalid() || this._fieldControl?.spartanInvalid(),
|
|
73
|
+
);
|
|
74
|
+
protected readonly _dirty = this._fieldControl?.dirty;
|
|
75
|
+
protected readonly _touched = this._fieldControl?.touched;
|
|
76
|
+
|
|
77
|
+
protected readonly _ariaInvalid = computed(() => (this._invalid?.() ? 'true' : null));
|
|
78
|
+
|
|
79
|
+
public readonly userClass = input<ClassValue>('', { alias: 'class' });
|
|
80
|
+
protected readonly _computedClass = computed(() =>
|
|
81
|
+
hlm('data-placeholder:text-muted-foreground justify-between', this.userClass()),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
protected readonly _isPlaceholder = computed(() => !this._datePicker.hasDate());
|
|
85
|
+
|
|
86
|
+
/** The id of the button that opens the date picker. */
|
|
87
|
+
public readonly buttonId = input<string>(`hlm-date-picker-${++HlmDatePickerTrigger._nextId}`);
|
|
88
|
+
|
|
89
|
+
/** @internal The id of the button that opens the date picker, used for labeling. */
|
|
90
|
+
public readonly triggerId = this.buttonId;
|
|
91
|
+
|
|
92
|
+
/** Forces the invalid state visually, regardless of form control state. */
|
|
93
|
+
public readonly forceInvalid = input<boolean, BooleanInput>(false, {
|
|
94
|
+
transform: booleanAttribute,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
public readonly variant = input<ButtonVariants['variant']>('outline');
|
|
98
|
+
|
|
99
|
+
public readonly showTrigger = input<boolean, BooleanInput>(true, { transform: booleanAttribute });
|
|
100
|
+
|
|
101
|
+
protected readonly _popover = this._datePicker.popover;
|
|
102
|
+
protected readonly _disabled = this._datePicker.disabledState;
|
|
103
|
+
protected readonly _formattedDate = this._datePicker.formattedDate;
|
|
104
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { inject, InjectionToken, type ValueProvider } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
export interface HlmDatePickerConfig<T> {
|
|
4
|
+
/**
|
|
5
|
+
* If true, the date picker will close when a date is selected.
|
|
6
|
+
*/
|
|
7
|
+
autoCloseOnSelect: boolean;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Defines how the date should be displayed in the UI.
|
|
11
|
+
*
|
|
12
|
+
* @param date
|
|
13
|
+
* @returns formatted date
|
|
14
|
+
*/
|
|
15
|
+
formatDate: (date: T) => string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Defines how the date should be displayed while the input is focused,
|
|
19
|
+
* i.e. the format the user is expected to type in.
|
|
20
|
+
*
|
|
21
|
+
* @param date
|
|
22
|
+
* @returns formatted date in the input/edit format
|
|
23
|
+
*/
|
|
24
|
+
formatInputDate: (date: T) => string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Defines how the date should be transformed before saving to model/form.
|
|
28
|
+
*
|
|
29
|
+
* @param date
|
|
30
|
+
* @returns transformed date
|
|
31
|
+
*/
|
|
32
|
+
transformDate: (date: T) => T;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Parse a user-entered string into a date.
|
|
36
|
+
*
|
|
37
|
+
* @param value the raw string from the input
|
|
38
|
+
* @returns the parsed date, or `null` when the value can't be parsed
|
|
39
|
+
*/
|
|
40
|
+
parseDate: (value: string) => T | null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getDefaultConfig<T>(): HlmDatePickerConfig<T> {
|
|
44
|
+
return {
|
|
45
|
+
formatDate: (date) => (date instanceof Date ? date.toDateString() : `${date}`),
|
|
46
|
+
formatInputDate: (date) => (date instanceof Date ? date.toDateString() : `${date}`),
|
|
47
|
+
transformDate: (date) => date,
|
|
48
|
+
parseDate: (value) => {
|
|
49
|
+
const date = new Date(value);
|
|
50
|
+
return isNaN(date.getTime()) ? null : (date as T);
|
|
51
|
+
},
|
|
52
|
+
autoCloseOnSelect: false,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const HlmDatePickerConfigToken = new InjectionToken<HlmDatePickerConfig<unknown>>(
|
|
57
|
+
'HlmDatePickerConfig',
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
export function provideHlmDatePickerConfig<T>(
|
|
61
|
+
config: Partial<HlmDatePickerConfig<T>>,
|
|
62
|
+
): ValueProvider {
|
|
63
|
+
return { provide: HlmDatePickerConfigToken, useValue: { ...getDefaultConfig(), ...config } };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function injectHlmDatePickerConfig<T>(): HlmDatePickerConfig<T> {
|
|
67
|
+
const injectedConfig = inject(HlmDatePickerConfigToken, { optional: true });
|
|
68
|
+
return injectedConfig ? (injectedConfig as HlmDatePickerConfig<T>) : getDefaultConfig();
|
|
69
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import type { BooleanInput } from '@angular/cdk/coercion';
|
|
2
|
+
import {
|
|
3
|
+
booleanAttribute,
|
|
4
|
+
ChangeDetectionStrategy,
|
|
5
|
+
Component,
|
|
6
|
+
computed,
|
|
7
|
+
contentChild,
|
|
8
|
+
forwardRef,
|
|
9
|
+
input,
|
|
10
|
+
linkedSignal,
|
|
11
|
+
output,
|
|
12
|
+
signal,
|
|
13
|
+
viewChild,
|
|
14
|
+
} from '@angular/core';
|
|
15
|
+
import { type ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
16
|
+
import {
|
|
17
|
+
type BrnDatePickerBase,
|
|
18
|
+
BrnDatePickerTriggerToken,
|
|
19
|
+
provideBrnDatePicker,
|
|
20
|
+
} from '@spartan-ng/brain/date-picker';
|
|
21
|
+
import { BrnFieldControl, provideBrnLabelable } from '@spartan-ng/brain/field';
|
|
22
|
+
import type { ChangeFn, TouchFn } from '@spartan-ng/brain/forms';
|
|
23
|
+
import type { BrnOverlayState } from '@spartan-ng/brain/overlay';
|
|
24
|
+
import { BrnPopover, type BrnPopoverAlign } from '@spartan-ng/brain/popover';
|
|
25
|
+
import { HlmCalendar } from '@spartan-ng/styles/calendar';
|
|
26
|
+
import { HlmPopoverImports } from '@spartan-ng/styles/popover';
|
|
27
|
+
import { injectHlmDatePickerConfig } from './hlm-date-picker.token';
|
|
28
|
+
|
|
29
|
+
export const HLM_DATE_PICKER_VALUE_ACCESSOR = {
|
|
30
|
+
provide: NG_VALUE_ACCESSOR,
|
|
31
|
+
useExisting: forwardRef(() => HlmDatePicker),
|
|
32
|
+
multi: true,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
@Component({
|
|
36
|
+
selector: 'hlm-date-picker',
|
|
37
|
+
imports: [HlmPopoverImports, HlmCalendar],
|
|
38
|
+
providers: [
|
|
39
|
+
HLM_DATE_PICKER_VALUE_ACCESSOR,
|
|
40
|
+
provideBrnDatePicker(HlmDatePicker),
|
|
41
|
+
provideBrnLabelable(HlmDatePicker),
|
|
42
|
+
],
|
|
43
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
44
|
+
hostDirectives: [BrnFieldControl],
|
|
45
|
+
host: { class: 'block' },
|
|
46
|
+
template: `
|
|
47
|
+
<hlm-popover
|
|
48
|
+
[align]="align()"
|
|
49
|
+
sideOffset="5"
|
|
50
|
+
[state]="_popoverState()"
|
|
51
|
+
(stateChanged)="_onStateChange($event)"
|
|
52
|
+
>
|
|
53
|
+
<ng-content />
|
|
54
|
+
|
|
55
|
+
<hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
|
|
56
|
+
<ng-content select="[hlmDatePickerHeader]" />
|
|
57
|
+
<hlm-calendar
|
|
58
|
+
class="rounded-none border-0"
|
|
59
|
+
[captionLayout]="captionLayout()"
|
|
60
|
+
[date]="_mutableDate()"
|
|
61
|
+
[defaultFocusedDate]="_mutableDate() ?? defaultFocusedDate()"
|
|
62
|
+
[min]="minDate()"
|
|
63
|
+
[max]="maxDate()"
|
|
64
|
+
[disabled]="_disabled()"
|
|
65
|
+
(dateChange)="_handleChange($event)"
|
|
66
|
+
/>
|
|
67
|
+
<ng-content select="[hlmDatePickerFooter]" />
|
|
68
|
+
</hlm-popover-content>
|
|
69
|
+
</hlm-popover>
|
|
70
|
+
`,
|
|
71
|
+
})
|
|
72
|
+
export class HlmDatePicker<T> implements BrnDatePickerBase<T>, ControlValueAccessor {
|
|
73
|
+
private readonly _config = injectHlmDatePickerConfig<T>();
|
|
74
|
+
|
|
75
|
+
public readonly popover = viewChild.required(BrnPopover);
|
|
76
|
+
|
|
77
|
+
private readonly _trigger = contentChild(BrnDatePickerTriggerToken);
|
|
78
|
+
|
|
79
|
+
public readonly align = input<BrnPopoverAlign>('center');
|
|
80
|
+
|
|
81
|
+
/** Show dropdowns to navigate between months or years. */
|
|
82
|
+
public readonly captionLayout = input<
|
|
83
|
+
'dropdown' | 'label' | 'dropdown-months' | 'dropdown-years'
|
|
84
|
+
>('label');
|
|
85
|
+
|
|
86
|
+
/** The minimum date that can be selected. */
|
|
87
|
+
public readonly minDate = input<T>();
|
|
88
|
+
|
|
89
|
+
/** The maximum date that can be selected. */
|
|
90
|
+
public readonly maxDate = input<T>();
|
|
91
|
+
|
|
92
|
+
/** Determine if the date picker is disabled. */
|
|
93
|
+
public readonly disabled = input<boolean, BooleanInput>(false, {
|
|
94
|
+
transform: booleanAttribute,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
/** The selected value. */
|
|
98
|
+
public readonly date = input<T>();
|
|
99
|
+
|
|
100
|
+
/** The date the calendar focuses on first open when no date is selected. */
|
|
101
|
+
public readonly defaultFocusedDate = input<T>();
|
|
102
|
+
|
|
103
|
+
protected readonly _mutableDate = linkedSignal(this.date);
|
|
104
|
+
|
|
105
|
+
/** If true, the date picker will close when a date is selected. */
|
|
106
|
+
public readonly autoCloseOnSelect = input<boolean, BooleanInput>(this._config.autoCloseOnSelect, {
|
|
107
|
+
transform: booleanAttribute,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
/** Defines how the date should be displayed in the UI. */
|
|
111
|
+
public readonly formatDate = input<(date: T) => string>(this._config.formatDate);
|
|
112
|
+
|
|
113
|
+
/** Defines how the date should be transformed before saving to model/form. */
|
|
114
|
+
public readonly transformDate = input<(date: T) => T>(this._config.transformDate);
|
|
115
|
+
|
|
116
|
+
protected readonly _popoverState = signal<BrnOverlayState | null>(null);
|
|
117
|
+
|
|
118
|
+
protected readonly _disabled = linkedSignal(this.disabled);
|
|
119
|
+
|
|
120
|
+
/** @internal The disabled state as a readonly signal */
|
|
121
|
+
public readonly disabledState = this._disabled.asReadonly();
|
|
122
|
+
|
|
123
|
+
public readonly formattedDate = computed(() => {
|
|
124
|
+
const date = this._mutableDate();
|
|
125
|
+
return date ? this.formatDate()(date) : undefined;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
public readonly dateChange = output<T | null>();
|
|
129
|
+
|
|
130
|
+
public readonly labelableId = computed(() => this._trigger()?.triggerId());
|
|
131
|
+
|
|
132
|
+
public readonly hasDate = computed(() => !!this._mutableDate());
|
|
133
|
+
|
|
134
|
+
/** @internal The current raw value, used by inputs to reformat on focus. */
|
|
135
|
+
public readonly value = computed(() => this._mutableDate() ?? null);
|
|
136
|
+
|
|
137
|
+
protected _onChange?: ChangeFn<T | null>;
|
|
138
|
+
protected _onTouched?: TouchFn;
|
|
139
|
+
|
|
140
|
+
protected _onStateChange(state: BrnOverlayState) {
|
|
141
|
+
this._popoverState.set(state);
|
|
142
|
+
if (state === 'closed') this._onTouched?.();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
protected _handleChange(value: T | undefined) {
|
|
146
|
+
if (this._disabled()) return;
|
|
147
|
+
this.updateDate(value ?? null);
|
|
148
|
+
|
|
149
|
+
if (this.autoCloseOnSelect()) {
|
|
150
|
+
this._popoverState.set('closed');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Commit a date to the picker. Updates the internal model, notifies form
|
|
156
|
+
* controls, and emits `dateChange`. Unlike `_handleChange`, this does not
|
|
157
|
+
* close the popover - it's intended to be called from a text input that
|
|
158
|
+
* is parsing user-entered values while typing.
|
|
159
|
+
*/
|
|
160
|
+
public updateDate(value: T | null) {
|
|
161
|
+
if (this._disabled()) return;
|
|
162
|
+
const transformedDate = value != null ? this.transformDate()(value) : undefined;
|
|
163
|
+
|
|
164
|
+
this._mutableDate.set(transformedDate);
|
|
165
|
+
this._onChange?.(transformedDate ?? null);
|
|
166
|
+
this.dateChange.emit(transformedDate ?? null);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** CONTROL VALUE ACCESSOR */
|
|
170
|
+
public writeValue(value: T | null): void {
|
|
171
|
+
this._mutableDate.set(value ? this.transformDate()(value) : undefined);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public registerOnChange(fn: ChangeFn<T | null>): void {
|
|
175
|
+
this._onChange = fn;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
public registerOnTouched(fn: TouchFn): void {
|
|
179
|
+
this._onTouched = fn;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public touched(): void {
|
|
183
|
+
this._onTouched?.();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public setDisabledState(isDisabled: boolean): void {
|
|
187
|
+
this._disabled.set(isDisabled);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public open() {
|
|
191
|
+
this._popoverState.set('open');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public close() {
|
|
195
|
+
this._popoverState.set('closed');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
public reset() {
|
|
199
|
+
this._mutableDate.set(undefined);
|
|
200
|
+
this._onChange?.(null);
|
|
201
|
+
this.dateChange.emit(null);
|
|
202
|
+
}
|
|
203
|
+
}
|