@inera/ids-react 9.2.2 → 9.4.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/components/accordion/accordion-base.d.ts +1 -1
- package/components/accordion/accordion.d.ts +1 -1
- package/components/accordion/accordion.js +1 -1
- package/components/alert/alert-base.d.ts +1 -1
- package/components/alert/alert-base.js +2 -2
- package/components/alert/alert.d.ts +1 -1
- package/components/badge/badge.js +1 -1
- package/components/breadcrumbs/breadcrumbs.d.ts +1 -1
- package/components/breadcrumbs/breadcrumbs.js +10 -6
- package/components/button/button-group.d.ts +1 -1
- package/components/button/button.d.ts +1 -0
- package/components/button/button.js +7 -2
- package/components/button/control-button.d.ts +6 -0
- package/components/button/control-button.js +10 -0
- package/components/card/card.d.ts +1 -1
- package/components/carousel/carousel-item.d.ts +1 -1
- package/components/carousel/carousel.d.ts +1 -1
- package/components/carousel/carousel.js +8 -6
- package/components/date-label/date-label.d.ts +3 -2
- package/components/date-label/date-label.js +4 -2
- package/components/dialog/dialog-base.js +1 -1
- package/components/dialog/dialog.d.ts +1 -1
- package/components/dialog/dialog.js +1 -1
- package/components/district-selector/district-selector.d.ts +10 -0
- package/components/district-selector/district-selector.js +11 -0
- package/components/dropdown/dropdown-base.d.ts +2 -2
- package/components/dropdown/dropdown-base.js +1 -1
- package/components/dropdown/dropdown.d.ts +2 -1
- package/components/dropdown/dropdown.js +2 -0
- package/components/footer-1177/footer-1177-columns.d.ts +10 -0
- package/components/footer-1177/footer-1177-columns.js +18 -0
- package/components/footer-1177/footer-1177-headline.d.ts +10 -0
- package/components/footer-1177/footer-1177-headline.js +11 -0
- package/components/footer-1177/footer-1177.d.ts +1 -1
- package/components/footer-1177/footer-1177.js +4 -20
- package/components/footer-1177-admin/footer-1177-admin-columns.d.ts +10 -0
- package/components/footer-1177-admin/footer-1177-admin-columns.js +18 -0
- package/components/footer-1177-admin/footer-1177-admin-headline.d.ts +9 -0
- package/components/footer-1177-admin/footer-1177-admin-headline.js +11 -0
- package/components/footer-1177-admin/footer-1177-admin.d.ts +1 -1
- package/components/footer-1177-admin/footer-1177-admin.js +4 -20
- package/components/footer-1177-pro/footer-1177-pro-columns.d.ts +13 -0
- package/components/footer-1177-pro/footer-1177-pro-columns.js +18 -0
- package/components/footer-1177-pro/footer-1177-pro-headline.d.ts +9 -0
- package/components/footer-1177-pro/footer-1177-pro-headline.js +11 -0
- package/components/footer-1177-pro/footer-1177-pro.d.ts +1 -1
- package/components/footer-1177-pro/footer-1177-pro.js +4 -20
- package/components/footer-inera/footer-inera-columns.d.ts +10 -0
- package/components/footer-inera/footer-inera-columns.js +18 -0
- package/components/footer-inera/footer-inera-headline.d.ts +9 -0
- package/components/footer-inera/footer-inera-headline.js +11 -0
- package/components/footer-inera/footer-inera.d.ts +1 -1
- package/components/footer-inera/footer-inera.js +4 -20
- package/components/footer-inera-admin/footer-inera-admin-columns.d.ts +10 -0
- package/components/footer-inera-admin/footer-inera-admin-columns.js +18 -0
- package/components/footer-inera-admin/footer-inera-admin-headline.d.ts +9 -0
- package/components/footer-inera-admin/footer-inera-admin-headline.js +11 -0
- package/components/footer-inera-admin/footer-inera-admin.d.ts +1 -1
- package/components/footer-inera-admin/footer-inera-admin.js +4 -20
- package/components/footer-inera-general/footer-inera-general-columns.d.ts +10 -0
- package/components/footer-inera-general/footer-inera-general-columns.js +18 -0
- package/components/footer-inera-general/footer-inera-general-headline.d.ts +9 -0
- package/components/footer-inera-general/footer-inera-general-headline.js +11 -0
- package/components/footer-inera-general/footer-inera-general.d.ts +1 -1
- package/components/footer-inera-general/footer-inera-general.js +4 -20
- package/components/form/checkbox/checkbox-base.js +2 -3
- package/components/form/checkbox/checkbox-group-base.d.ts +2 -1
- package/components/form/checkbox/checkbox-group-base.js +3 -3
- package/components/form/checkbox/checkbox-group.d.ts +3 -2
- package/components/form/checkbox/checkbox-group.js +2 -2
- package/components/form/checkbox/checkbox.js +3 -4
- package/components/form/datepicker/datepicker.d.ts +3 -1
- package/components/form/datepicker/datepicker.js +143 -111
- package/components/form/error-message/error-message.d.ts +1 -1
- package/components/form/form-hooks/useAriaDescribedBy.js +1 -4
- package/components/form/form-hooks/useInputValidity.d.ts +1 -1
- package/components/form/form-hooks/useInputValidity.js +28 -12
- package/components/form/form-props/form-props.d.ts +1 -0
- package/components/form/input/input-base.d.ts +4 -2
- package/components/form/input/input-base.js +14 -9
- package/components/form/input/input.d.ts +3 -0
- package/components/form/input/input.js +1 -1
- package/components/form/radio/radio-base.d.ts +1 -1
- package/components/form/radio/radio-base.js +1 -2
- package/components/form/radio/radio-group-base.d.ts +2 -1
- package/components/form/radio/radio-group-base.js +3 -3
- package/components/form/radio/radio-group.d.ts +3 -2
- package/components/form/radio/radio-group.js +2 -2
- package/components/form/radio-button/radio-button-group-base.d.ts +1 -1
- package/components/form/radio-button/radio-button-group.d.ts +2 -1
- package/components/form/range/range-base.d.ts +1 -1
- package/components/form/range/range-base.js +2 -2
- package/components/form/select/select-base.d.ts +3 -3
- package/components/form/select/select-base.js +3 -5
- package/components/form/select/select.d.ts +2 -2
- package/components/form/select/select.js +1 -1
- package/components/form/select-multiple/select-multiple-base.d.ts +2 -2
- package/components/form/select-multiple/select-multiple-base.js +3 -3
- package/components/form/select-multiple/select-multiple.d.ts +2 -2
- package/components/form/select-multiple/select-multiple.js +1 -1
- package/components/form/spinner/spinner.d.ts +1 -1
- package/components/form/textarea/textarea-base.d.ts +1 -1
- package/components/form/textarea/textarea-base.js +3 -5
- package/components/form/textarea/textarea.js +1 -1
- package/components/form/time/time-base.d.ts +1 -1
- package/components/form/time/time-base.js +2 -4
- package/components/form/time/time.js +4 -5
- package/components/global-alert/global-alert-base.d.ts +1 -1
- package/components/global-alert/global-alert.d.ts +1 -1
- package/components/header-1177/header-1177-avatar-base.d.ts +1 -1
- package/components/header-1177/header-1177-avatar.d.ts +1 -1
- package/components/header-1177/header-1177-base.d.ts +2 -2
- package/components/header-1177/header-1177-base.js +3 -5
- package/components/header-1177/header-1177-item-base.d.ts +1 -1
- package/components/header-1177/header-1177-item-base.js +1 -2
- package/components/header-1177/header-1177-item.d.ts +1 -1
- package/components/header-1177/header-1177-logo.d.ts +12 -0
- package/components/header-1177/header-1177-logo.js +8 -0
- package/components/header-1177/header-1177-menu-mobile-base.d.ts +1 -1
- package/components/header-1177/header-1177-menu-mobile.d.ts +1 -1
- package/components/header-1177/header-1177-nav-base.d.ts +1 -1
- package/components/header-1177/header-1177-nav-base.js +1 -1
- package/components/header-1177/header-1177-nav-item-base.d.ts +1 -1
- package/components/header-1177/header-1177-nav-item-base.js +3 -12
- package/components/header-1177/header-1177-nav-item-link.d.ts +10 -0
- package/components/header-1177/header-1177-nav-item-link.js +19 -0
- package/components/header-1177/header-1177-nav-item-mobile-base.d.ts +1 -1
- package/components/header-1177/header-1177-nav-item-mobile.d.ts +1 -1
- package/components/header-1177/header-1177-nav-item.d.ts +1 -1
- package/components/header-1177/header-1177-nav.d.ts +1 -1
- package/components/header-1177/header-1177-region-picker-base.d.ts +4 -2
- package/components/header-1177/header-1177-region-picker-base.js +8 -3
- package/components/header-1177/header-1177-region-picker-mobile-base.d.ts +4 -2
- package/components/header-1177/header-1177-region-picker-mobile-base.js +8 -3
- package/components/header-1177/header-1177-region-picker-mobile.d.ts +3 -1
- package/components/header-1177/header-1177-region-picker.d.ts +3 -1
- package/components/header-1177/header-1177.d.ts +2 -1
- package/components/header-1177/header-1177.js +2 -2
- package/components/header-1177-admin/header-1177-admin-avatar-base.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-avatar-mobile-base.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-avatar-mobile.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-avatar.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-base.d.ts +2 -2
- package/components/header-1177-admin/header-1177-admin-base.js +3 -5
- package/components/header-1177-admin/header-1177-admin-item-base.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-item-base.js +1 -2
- package/components/header-1177-admin/header-1177-admin-item.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-logo.d.ts +12 -0
- package/components/header-1177-admin/header-1177-admin-logo.js +8 -0
- package/components/header-1177-admin/header-1177-admin-menu-mobile-base.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-menu-mobile.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-nav-base.d.ts +2 -1
- package/components/header-1177-admin/header-1177-admin-nav-base.js +4 -3
- package/components/header-1177-admin/header-1177-admin-nav-item-base.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-nav-item-base.js +3 -12
- package/components/header-1177-admin/header-1177-admin-nav-item-link.d.ts +10 -0
- package/components/header-1177-admin/header-1177-admin-nav-item-link.js +19 -0
- package/components/header-1177-admin/header-1177-admin-nav-item-mobile-base.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-nav-item-mobile.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-nav-item.d.ts +1 -1
- package/components/header-1177-admin/header-1177-admin-nav.d.ts +2 -1
- package/components/header-1177-admin/header-1177-admin-nav.js +2 -2
- package/components/header-1177-admin/header-1177-admin.d.ts +2 -1
- package/components/header-1177-admin/header-1177-admin.js +2 -2
- package/components/header-1177-pro/header-1177-pro-avatar-base.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-avatar-mobile-base.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-avatar-mobile-base.js +0 -1
- package/components/header-1177-pro/header-1177-pro-avatar-mobile.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-avatar.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-base.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-base.js +2 -1
- package/components/header-1177-pro/header-1177-pro-item-base.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-item-base.js +1 -2
- package/components/header-1177-pro/header-1177-pro-item.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-logo.d.ts +12 -0
- package/components/header-1177-pro/header-1177-pro-logo.js +8 -0
- package/components/header-1177-pro/header-1177-pro-menu-mobile-base.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-menu-mobile.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-nav-base.d.ts +2 -1
- package/components/header-1177-pro/header-1177-pro-nav-base.js +3 -2
- package/components/header-1177-pro/header-1177-pro-nav-item-base.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-nav-item-base.js +3 -12
- package/components/header-1177-pro/header-1177-pro-nav-item-link.d.ts +10 -0
- package/components/header-1177-pro/header-1177-pro-nav-item-link.js +19 -0
- package/components/header-1177-pro/header-1177-pro-nav-item-mobile-base.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-nav-item-mobile.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-nav-item.d.ts +1 -1
- package/components/header-1177-pro/header-1177-pro-nav.d.ts +2 -1
- package/components/header-1177-pro/header-1177-pro-nav.js +2 -2
- package/components/header-1177-pro/header-1177-pro-region-picker-base.d.ts +3 -1
- package/components/header-1177-pro/header-1177-pro-region-picker-base.js +8 -3
- package/components/header-1177-pro/header-1177-pro-region-picker-mobile-base.d.ts +3 -1
- package/components/header-1177-pro/header-1177-pro-region-picker-mobile-base.js +8 -3
- package/components/header-1177-pro/header-1177-pro-region-picker-mobile.d.ts +3 -1
- package/components/header-1177-pro/header-1177-pro-region-picker-mobile.js +1 -1
- package/components/header-1177-pro/header-1177-pro-region-picker.d.ts +3 -1
- package/components/header-1177-pro/header-1177-pro-region-picker.js +1 -1
- package/components/header-1177-pro/header-1177-pro.d.ts +1 -1
- package/components/header-inera/header-inera-base.d.ts +2 -2
- package/components/header-inera/header-inera-base.js +3 -2
- package/components/header-inera/header-inera-item-base.d.ts +1 -1
- package/components/header-inera/header-inera-item-base.js +1 -2
- package/components/header-inera/header-inera-item.d.ts +1 -1
- package/components/header-inera/header-inera-logo.d.ts +12 -0
- package/components/header-inera/header-inera-logo.js +8 -0
- package/components/header-inera/header-inera-menu-mobile-base.d.ts +1 -1
- package/components/header-inera/header-inera-menu-mobile.d.ts +1 -1
- package/components/header-inera/header-inera-nav-base.d.ts +1 -1
- package/components/header-inera/header-inera-nav-base.js +1 -1
- package/components/header-inera/header-inera-nav-item-base.d.ts +1 -1
- package/components/header-inera/header-inera-nav-item-base.js +4 -13
- package/components/header-inera/header-inera-nav-item-link.d.ts +10 -0
- package/components/header-inera/header-inera-nav-item-link.js +19 -0
- package/components/header-inera/header-inera-nav-item.d.ts +1 -1
- package/components/header-inera/header-inera-nav.d.ts +1 -1
- package/components/header-inera/header-inera.d.ts +2 -1
- package/components/header-inera/header-inera.js +2 -2
- package/components/header-inera-admin/header-inera-admin-avatar-base.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-avatar-mobile-base.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-avatar-mobile.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-avatar.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-base.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-base.js +1 -10
- package/components/header-inera-admin/header-inera-admin-item-base.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-item-base.js +2 -3
- package/components/header-inera-admin/header-inera-admin-item.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-menu-mobile-base.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-menu-mobile.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-nav-base.d.ts +2 -1
- package/components/header-inera-admin/header-inera-admin-nav-base.js +4 -3
- package/components/header-inera-admin/header-inera-admin-nav-item-base.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-nav-item-base.js +3 -12
- package/components/header-inera-admin/header-inera-admin-nav-item-link.d.ts +10 -0
- package/components/header-inera-admin/header-inera-admin-nav-item-link.js +19 -0
- package/components/header-inera-admin/header-inera-admin-nav-item-mobile-base.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-nav-item-mobile.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-nav-item.d.ts +1 -1
- package/components/header-inera-admin/header-inera-admin-nav.d.ts +2 -1
- package/components/header-inera-admin/header-inera-admin-nav.js +2 -2
- package/components/header-inera-admin/header-inera-admin.d.ts +1 -1
- package/components/header-inera-general/header-inera-general-avatar-base.d.ts +18 -0
- package/components/header-inera-general/header-inera-general-avatar-base.js +24 -0
- package/components/header-inera-general/header-inera-general-avatar-mobile-base.d.ts +17 -0
- package/components/header-inera-general/header-inera-general-avatar-mobile-base.js +24 -0
- package/components/header-inera-general/header-inera-general-avatar-mobile.d.ts +12 -0
- package/components/header-inera-general/header-inera-general-avatar-mobile.js +28 -0
- package/components/header-inera-general/header-inera-general-avatar.d.ts +12 -0
- package/components/header-inera-general/header-inera-general-avatar.js +29 -0
- package/components/header-inera-general/header-inera-general-base.d.ts +2 -1
- package/components/header-inera-general/header-inera-general-base.js +2 -2
- package/components/header-inera-general/header-inera-general-item-base.d.ts +1 -1
- package/components/header-inera-general/header-inera-general-item-base.js +2 -2
- package/components/header-inera-general/header-inera-general-item.d.ts +1 -1
- package/components/header-inera-general/header-inera-general-item.js +1 -1
- package/components/header-inera-general/header-inera-general-menu-mobile-base.d.ts +1 -1
- package/components/header-inera-general/header-inera-general-menu-mobile.d.ts +1 -1
- package/components/header-inera-general/header-inera-general-nav-base.d.ts +1 -1
- package/components/header-inera-general/header-inera-general-nav-base.js +1 -1
- package/components/header-inera-general/header-inera-general-nav-item-base.d.ts +1 -1
- package/components/header-inera-general/header-inera-general-nav-item-base.js +4 -13
- package/components/header-inera-general/header-inera-general-nav-item-link.d.ts +10 -0
- package/components/header-inera-general/header-inera-general-nav-item-link.js +19 -0
- package/components/header-inera-general/header-inera-general-nav-item-mobile-base.d.ts +10 -0
- package/components/header-inera-general/header-inera-general-nav-item-mobile-base.js +11 -0
- package/components/header-inera-general/header-inera-general-nav-item-mobile.d.ts +10 -0
- package/components/header-inera-general/header-inera-general-nav-item-mobile.js +12 -0
- package/components/header-inera-general/header-inera-general-nav-item.d.ts +1 -1
- package/components/header-inera-general/header-inera-general-nav-mobile.d.ts +10 -0
- package/components/header-inera-general/header-inera-general-nav-mobile.js +8 -0
- package/components/header-inera-general/header-inera-general-nav.d.ts +1 -1
- package/components/header-inera-general/header-inera-general.d.ts +3 -1
- package/components/header-inera-general/header-inera-general.js +2 -2
- package/components/header-patient/header-patient.d.ts +1 -1
- package/components/link/action-link.d.ts +1 -1
- package/components/link/box-link.d.ts +1 -1
- package/components/list-pagination/list-pagination-links.d.ts +3 -2
- package/components/list-pagination/list-pagination-links.js +3 -20
- package/components/list-pagination/list-pagination-summary.d.ts +13 -0
- package/components/list-pagination/list-pagination-summary.js +9 -0
- package/components/list-pagination/list-pagination.d.ts +3 -2
- package/components/list-pagination/list-pagination.js +3 -20
- package/components/message-avatar/message-avatar.d.ts +12 -0
- package/components/message-avatar/message-avatar.js +10 -0
- package/components/mobile-menu/mobile-item-base.d.ts +1 -1
- package/components/mobile-menu/mobile-item-base.js +4 -24
- package/components/mobile-menu/mobile-item-link.d.ts +16 -0
- package/components/mobile-menu/mobile-item-link.js +27 -0
- package/components/mobile-menu/mobile-item.d.ts +1 -1
- package/components/mobile-menu/mobile-menu.d.ts +1 -1
- package/components/navigation-content/navigation-content-item-base.d.ts +12 -0
- package/components/navigation-content/navigation-content-item-base.js +17 -0
- package/components/navigation-content/navigation-content-item.d.ts +11 -0
- package/components/navigation-content/navigation-content-item.js +25 -0
- package/components/navigation-content/navigation-content.d.ts +1 -1
- package/components/navigation-content/navigation-content.js +10 -6
- package/components/navigation-local/navigation-local.d.ts +1 -1
- package/components/notification-badge/notification-badge.js +1 -1
- package/components/popover/popover-base.d.ts +1 -1
- package/components/popover/popover-caret.d.ts +9 -0
- package/components/popover/popover-caret.js +8 -0
- package/components/popover/popover-content.d.ts +1 -1
- package/components/popover/popover-content.js +2 -2
- package/components/popover/popover.d.ts +2 -1
- package/components/popover/popover.js +28 -14
- package/components/progressbar/progressbar.d.ts +1 -1
- package/components/puff-list/puff-list-item-date.d.ts +1 -1
- package/components/puff-list/puff-list-item-header.d.ts +2 -2
- package/components/puff-list/puff-list-item-info.d.ts +1 -1
- package/components/puff-list/puff-list-item.d.ts +2 -1
- package/components/puff-list/puff-list-item.js +2 -2
- package/components/puff-list/puff-list.d.ts +1 -1
- package/components/region-icon/region-icon.d.ts +5 -2
- package/components/region-icon/region-icon.js +6 -3
- package/components/side-menu/side-menu-base.d.ts +1 -1
- package/components/side-menu/side-menu-base.js +6 -24
- package/components/side-menu/side-menu-label.d.ts +17 -0
- package/components/side-menu/side-menu-label.js +14 -0
- package/components/side-menu/side-menu-toggle.d.ts +15 -0
- package/components/side-menu/side-menu-toggle.js +14 -0
- package/components/side-menu/side-menu.d.ts +1 -1
- package/components/side-panel/side-panel-base.js +4 -8
- package/components/side-panel/side-panel-footer.d.ts +10 -0
- package/components/side-panel/side-panel-footer.js +8 -0
- package/components/side-panel/side-panel-provider.d.ts +1 -1
- package/components/side-panel/side-panel.d.ts +1 -1
- package/components/side-panel/side-panel.js +2 -18
- package/components/stepper/step-base.d.ts +1 -1
- package/components/stepper/step-base.js +6 -9
- package/components/stepper/step-indicator.d.ts +11 -0
- package/components/stepper/step-indicator.js +8 -0
- package/components/stepper/step.d.ts +1 -1
- package/components/stepper/step.js +2 -11
- package/components/stepper/stepper.d.ts +1 -1
- package/components/tabs/tab-link.js +1 -1
- package/components/tabs/tab.js +1 -1
- package/components/tabs/tabs-base.d.ts +1 -1
- package/components/tabs/tabs.d.ts +1 -1
- package/components/tag/tag.js +9 -2
- package/components/tooltip/tooltip-base.d.ts +1 -3
- package/components/tooltip/tooltip-base.js +14 -10
- package/components/tooltip/tooltip.d.ts +1 -1
- package/components/tooltip/tooltip.js +1 -41
- package/components/utils/utils.js +0 -1
- package/index.d.ts +12 -0
- package/index.js +12 -0
- package/package.json +4 -3
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useId, useRef, useState, useEffect } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { getWeek, isValid, format, subMonths, addMonths } from 'date-fns';
|
|
4
4
|
import { sv } from 'react-day-picker/locale';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import { IDSErrorMessage } from '../error-message/error-message.js';
|
|
7
|
-
import { DayPicker,
|
|
7
|
+
import { DayPicker, YearsDropdown, MonthsDropdown, WeekNumberHeader, useDayPicker, DropdownNav } from 'react-day-picker';
|
|
8
8
|
import { useFocusTrap } from '../../utils/hooks/useFocusTrap.js';
|
|
9
9
|
import { useAriaDescribedBy } from '../form-hooks/useAriaDescribedBy.js';
|
|
10
10
|
import { useClickOutside } from '../../utils/hooks/useClickOutside.js';
|
|
11
11
|
|
|
12
12
|
const locale = { locale: sv };
|
|
13
|
+
const datePattern = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;
|
|
14
|
+
const datePatternString = "\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])";
|
|
13
15
|
const createNewDate = (dateString) => {
|
|
14
16
|
return new Date(dateString + "T00:00:00Z");
|
|
15
17
|
};
|
|
@@ -25,7 +27,17 @@ const getPrevMonthYear = (date) => {
|
|
|
25
27
|
const getNextMonthYear = (date) => {
|
|
26
28
|
return `${getSweMonth(addMonths(date, 1))} ${getSweYear(addMonths(date, 1))}`;
|
|
27
29
|
};
|
|
28
|
-
|
|
30
|
+
const parseDateValue = (value) => {
|
|
31
|
+
if (!datePattern.test(value))
|
|
32
|
+
return undefined;
|
|
33
|
+
const parsedDate = createNewDate(value);
|
|
34
|
+
if (!isValid(parsedDate))
|
|
35
|
+
return undefined;
|
|
36
|
+
const [year, month, day] = value.split("-").map(Number);
|
|
37
|
+
const isSameDate = parsedDate.getUTCFullYear() === year && parsedDate.getUTCMonth() === month - 1 && parsedDate.getUTCDate() === day;
|
|
38
|
+
return isSameDate ? parsedDate : undefined;
|
|
39
|
+
};
|
|
40
|
+
function IDSDatePicker({ label, id, value, light = false, placeholder = "åååå-mm-dd", subtitle, dataTestId, errorMsg = "", missingDateErrorMsg = "Datum saknas", invalidDateErrorMsg = "Ogiltigt datum", calendarHeader = "Välj datum", srOpenText = "Öppna kalendern", srCloseText = "Stäng kalendern", validationOnBlur = false, defaultMonth, startMonth = new Date(1900, 0, 1), endMonth = new Date(2050, 0, 1), noValidation = false, disabled = false, required, invalid = false, readOnly = false, tooltip, disableNavigation = false, modifiers, focusedDay, onChange, onFocus, onBlur, onOpen, onClose, onDayClick, className, ...props }) {
|
|
29
41
|
const reactId = useId();
|
|
30
42
|
const dialogId = `datepicker-dialog-${reactId}`;
|
|
31
43
|
const headerId = `datepicker-header-${reactId}`;
|
|
@@ -38,24 +50,82 @@ function IDSDatePicker({ label, id, value, light = false, placeholder = "ååå
|
|
|
38
50
|
const headerRef = useRef(null);
|
|
39
51
|
const prevMonthButtonRef = useRef(null);
|
|
40
52
|
const nextMonthButtonRef = useRef(null);
|
|
53
|
+
const wasValidationEnabledRef = useRef(false);
|
|
54
|
+
const shouldRunRequiredValidation = required === true && !noValidation && !disabled;
|
|
55
|
+
const shouldShowCustomError = invalid === true && !!errorMsg && !noValidation && !disabled;
|
|
41
56
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
42
|
-
const [inputValue, setInputValue] = useState(value);
|
|
43
|
-
const initialSelectedDate =
|
|
57
|
+
const [inputValue, setInputValue] = useState(value ?? "");
|
|
58
|
+
const initialSelectedDate = value ? parseDateValue(value) : undefined;
|
|
44
59
|
const [selectedDate, setSelectedDate] = useState(initialSelectedDate || defaultMonth);
|
|
45
60
|
const [month, setMonth] = useState(initialSelectedDate || defaultMonth || new Date());
|
|
46
|
-
const [
|
|
47
|
-
const [
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
const [showValidationErrors, setShowValidationErrors] = useState(false);
|
|
62
|
+
const [validationError, setValidationError] = useState(null);
|
|
63
|
+
const hasValidationError = showValidationErrors && validationError !== null;
|
|
64
|
+
const hasCustomError = shouldShowCustomError;
|
|
65
|
+
const hasError = hasValidationError || hasCustomError;
|
|
66
|
+
const getValidationError = (nextValue) => {
|
|
67
|
+
if (noValidation || disabled)
|
|
68
|
+
return null;
|
|
69
|
+
const trimmedValue = nextValue.trim();
|
|
70
|
+
if (shouldRunRequiredValidation) {
|
|
71
|
+
if (!trimmedValue)
|
|
72
|
+
return "missing";
|
|
73
|
+
if (!parseDateValue(trimmedValue))
|
|
74
|
+
return "invalid";
|
|
75
|
+
}
|
|
76
|
+
if (shouldShowCustomError)
|
|
77
|
+
return "custom";
|
|
78
|
+
return null;
|
|
79
|
+
};
|
|
80
|
+
const getErrorMessage = (error) => {
|
|
81
|
+
if (error === "missing")
|
|
82
|
+
return missingDateErrorMsg;
|
|
83
|
+
if (error === "invalid")
|
|
84
|
+
return invalidDateErrorMsg;
|
|
85
|
+
if (error === "custom")
|
|
86
|
+
return errorMsg;
|
|
87
|
+
return "";
|
|
88
|
+
};
|
|
89
|
+
const syncNativeValidity = (nextValue) => {
|
|
90
|
+
if (!shouldRunRequiredValidation || !inputRef.current)
|
|
91
|
+
return;
|
|
92
|
+
const nextError = getValidationError(nextValue);
|
|
93
|
+
inputRef.current.setCustomValidity(getErrorMessage(nextError));
|
|
94
|
+
};
|
|
95
|
+
const updateVisibleValidation = (nextValue, shouldShow) => {
|
|
96
|
+
if (!shouldRunRequiredValidation) {
|
|
97
|
+
setValidationError(null);
|
|
98
|
+
setShowValidationErrors(false);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const nextError = getValidationError(nextValue);
|
|
102
|
+
setValidationError(nextError);
|
|
103
|
+
setShowValidationErrors(shouldShow);
|
|
104
|
+
};
|
|
105
|
+
const resetVisibleValidation = () => {
|
|
106
|
+
setValidationError(null);
|
|
107
|
+
setShowValidationErrors(false);
|
|
108
|
+
};
|
|
109
|
+
useAriaDescribedBy(inputRef, errorMsgId, hasError, hasError);
|
|
54
110
|
useFocusTrap(dialogRef.current, isDialogOpen);
|
|
55
111
|
useClickOutside(() => {
|
|
56
112
|
setIsDialogOpen(false);
|
|
57
113
|
onClose?.();
|
|
58
114
|
}, [dialogRef, triggerRef], triggerRef, isDialogOpen);
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
if (!inputRef.current)
|
|
117
|
+
return;
|
|
118
|
+
if (!shouldRunRequiredValidation) {
|
|
119
|
+
if (wasValidationEnabledRef.current) {
|
|
120
|
+
inputRef.current.setCustomValidity("");
|
|
121
|
+
}
|
|
122
|
+
wasValidationEnabledRef.current = false;
|
|
123
|
+
resetVisibleValidation();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
wasValidationEnabledRef.current = true;
|
|
127
|
+
syncNativeValidity(inputValue);
|
|
128
|
+
}, [shouldRunRequiredValidation, inputValue, invalid, errorMsg, missingDateErrorMsg, invalidDateErrorMsg]);
|
|
59
129
|
const handleOpenDialog = (e) => {
|
|
60
130
|
e.preventDefault();
|
|
61
131
|
setIsDialogOpen(true);
|
|
@@ -63,7 +133,7 @@ function IDSDatePicker({ label, id, value, light = false, placeholder = "ååå
|
|
|
63
133
|
};
|
|
64
134
|
const closeDialog = () => {
|
|
65
135
|
setIsDialogOpen(false);
|
|
66
|
-
triggerRef.current
|
|
136
|
+
triggerRef.current?.focus();
|
|
67
137
|
onClose?.();
|
|
68
138
|
};
|
|
69
139
|
useEffect(() => {
|
|
@@ -79,113 +149,78 @@ function IDSDatePicker({ label, id, value, light = false, placeholder = "ååå
|
|
|
79
149
|
document.addEventListener("keydown", handleKeyDown);
|
|
80
150
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
81
151
|
}, [isDialogOpen]);
|
|
152
|
+
const emitValue = (nextValue, parsedDate) => {
|
|
153
|
+
const trimmedValue = nextValue.trim();
|
|
154
|
+
const isMissing = shouldRunRequiredValidation && !trimmedValue;
|
|
155
|
+
const isInvalidDate = shouldRunRequiredValidation && !!trimmedValue && !parsedDate;
|
|
156
|
+
onChange?.({
|
|
157
|
+
value: nextValue,
|
|
158
|
+
valueAsDate: parsedDate,
|
|
159
|
+
invalidDate: isInvalidDate,
|
|
160
|
+
missingDate: isMissing
|
|
161
|
+
});
|
|
162
|
+
};
|
|
82
163
|
const handleDayPickerSelect = (date) => {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
else {
|
|
90
|
-
setSelectedDate(date);
|
|
91
|
-
setInputValue(dateString);
|
|
164
|
+
const nextValue = date ? format(date, "yyyy-MM-dd") : "";
|
|
165
|
+
resetVisibleValidation();
|
|
166
|
+
setInputValue(nextValue);
|
|
167
|
+
setSelectedDate(date);
|
|
168
|
+
if (date) {
|
|
169
|
+
setMonth(date);
|
|
92
170
|
}
|
|
171
|
+
emitValue(nextValue, date);
|
|
93
172
|
requestAnimationFrame(() => {
|
|
94
|
-
if (inputRef.current)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
173
|
+
if (!inputRef.current)
|
|
174
|
+
return;
|
|
175
|
+
if (shouldRunRequiredValidation) {
|
|
176
|
+
syncNativeValidity(nextValue);
|
|
98
177
|
}
|
|
178
|
+
inputRef.current.dispatchEvent(new Event("input", { bubbles: true }));
|
|
179
|
+
inputRef.current.dispatchEvent(new Event("change", { bubbles: true }));
|
|
99
180
|
});
|
|
100
|
-
emitValue(dateString, date);
|
|
101
181
|
closeDialog();
|
|
102
182
|
};
|
|
103
|
-
const updateErrors = (validity, isNotADate) => {
|
|
104
|
-
if (!noValidation) {
|
|
105
|
-
setHasMissingError(validity.valueMissing);
|
|
106
|
-
setHasOtherError(!validity.valid);
|
|
107
|
-
if (validity.valueMissing) {
|
|
108
|
-
setHasDateError(false);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
setHasDateError(!!isNotADate || validity.patternMismatch);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
const resetErrors = () => {
|
|
116
|
-
setHasMissingError(false);
|
|
117
|
-
setHasDateError(false);
|
|
118
|
-
setHasOtherError(false);
|
|
119
|
-
};
|
|
120
183
|
const handleInputChange = (e) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
184
|
+
const nextValue = e.currentTarget.value;
|
|
185
|
+
const parsedDate = parseDateValue(nextValue.trim());
|
|
186
|
+
resetVisibleValidation();
|
|
187
|
+
setInputValue(nextValue);
|
|
188
|
+
setSelectedDate(parsedDate);
|
|
189
|
+
if (parsedDate) {
|
|
127
190
|
setMonth(parsedDate);
|
|
128
191
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
setSelectedDate(undefined);
|
|
192
|
+
if (shouldRunRequiredValidation) {
|
|
193
|
+
syncNativeValidity(nextValue);
|
|
132
194
|
}
|
|
133
|
-
emitValue(
|
|
195
|
+
emitValue(nextValue, parsedDate);
|
|
134
196
|
};
|
|
135
|
-
// if the input value is changed programmatically
|
|
136
197
|
useEffect(() => {
|
|
137
|
-
if (value
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
setSelectedDate(undefined);
|
|
149
|
-
setHasDateError(true);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
198
|
+
if (value === inputValue)
|
|
199
|
+
return;
|
|
200
|
+
const nextValue = value ?? "";
|
|
201
|
+
const parsedDate = nextValue ? parseDateValue(nextValue.trim()) : undefined;
|
|
202
|
+
resetVisibleValidation();
|
|
203
|
+
setInputValue(nextValue);
|
|
204
|
+
setSelectedDate(parsedDate);
|
|
205
|
+
if (parsedDate) {
|
|
206
|
+
setMonth(parsedDate);
|
|
152
207
|
}
|
|
153
|
-
}, [value
|
|
154
|
-
const emitValue = (val, parsedDate) => {
|
|
155
|
-
const isMissing = required && !val;
|
|
156
|
-
const isValidDate = parsedDate && parsedDate instanceof Date && isValid(parsedDate);
|
|
157
|
-
onChange?.({
|
|
158
|
-
value: val,
|
|
159
|
-
valueAsDate: isValidDate ? createNewDate(val) : undefined,
|
|
160
|
-
invalidDate: !isValid(parsedDate),
|
|
161
|
-
missingDate: isMissing
|
|
162
|
-
});
|
|
163
|
-
};
|
|
208
|
+
}, [value]);
|
|
164
209
|
const handleInvalid = (e) => {
|
|
165
|
-
|
|
210
|
+
if (!shouldRunRequiredValidation)
|
|
211
|
+
return;
|
|
212
|
+
e.preventDefault();
|
|
213
|
+
syncNativeValidity(e.currentTarget.value);
|
|
214
|
+
updateVisibleValidation(e.currentTarget.value, true);
|
|
166
215
|
};
|
|
167
216
|
const handleBlur = (e) => {
|
|
168
|
-
if (validationOnBlur) {
|
|
169
|
-
|
|
217
|
+
if (shouldRunRequiredValidation && validationOnBlur) {
|
|
218
|
+
syncNativeValidity(e.currentTarget.value);
|
|
219
|
+
updateVisibleValidation(e.currentTarget.value, true);
|
|
170
220
|
}
|
|
171
221
|
onBlur?.(e);
|
|
172
222
|
};
|
|
173
|
-
useEffect(() => {
|
|
174
|
-
const form = inputRef.current?.form;
|
|
175
|
-
if (!form)
|
|
176
|
-
return;
|
|
177
|
-
const handleSubmit = (_e) => {
|
|
178
|
-
if (!noValidation) {
|
|
179
|
-
requestAnimationFrame(() => {
|
|
180
|
-
updateErrors(inputRef.current.validity, !isValid(createNewDate(inputRef.current.value)));
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
form.addEventListener("submit", handleSubmit);
|
|
185
|
-
return () => form.removeEventListener("submit", handleSubmit);
|
|
186
|
-
}, []);
|
|
187
223
|
function CustomNav(props) {
|
|
188
|
-
// Add the nav buttons after the dropdowns for correct tab order
|
|
189
224
|
const { children } = props;
|
|
190
225
|
const { goToMonth, previousMonth, nextMonth } = useDayPicker();
|
|
191
226
|
const currentMonth = "aktuell månad";
|
|
@@ -193,28 +228,25 @@ function IDSDatePicker({ label, id, value, light = false, placeholder = "ååå
|
|
|
193
228
|
const goToPrevMonth = () => {
|
|
194
229
|
previousMonth && goToMonth(previousMonth);
|
|
195
230
|
requestAnimationFrame(() => {
|
|
196
|
-
|
|
197
|
-
prevMonthButtonRef.current.focus();
|
|
198
|
-
}
|
|
231
|
+
prevMonthButtonRef.current?.focus();
|
|
199
232
|
});
|
|
200
233
|
};
|
|
201
234
|
const goToNextMonth = () => {
|
|
202
235
|
nextMonth && goToMonth(nextMonth);
|
|
203
236
|
requestAnimationFrame(() => {
|
|
204
|
-
|
|
205
|
-
nextMonthButtonRef.current.focus();
|
|
206
|
-
}
|
|
237
|
+
nextMonthButtonRef.current?.focus();
|
|
207
238
|
});
|
|
208
239
|
};
|
|
209
240
|
return (jsxs(DropdownNav, { className: "ids-datepicker__nav", ...props, children: [jsx("div", { className: "ids-datepicker__nav-dropdowns", children: children }), jsxs("div", { className: "ids-datepicker__nav-buttons", children: [jsx("button", { type: "button", ref: prevMonthButtonRef, className: "ids-datepicker__nav-prev", onClick: goToPrevMonth, disabled: !previousMonth || disableNavigation, "aria-label": `${currentMonth} ${getSweMonth(month)}. ${goTo} ${getPrevMonthYear(month)}` }), jsx("button", { type: "button", ref: nextMonthButtonRef, className: "ids-datepicker__nav-next", onClick: goToNextMonth, disabled: !nextMonth || disableNavigation, "aria-label": `${currentMonth} ${getSweMonth(month)}. ${goTo} ${getNextMonthYear(month)}` })] })] }));
|
|
210
241
|
}
|
|
211
242
|
useEffect(() => {
|
|
212
|
-
|
|
213
|
-
if (!header)
|
|
243
|
+
if (!isDialogOpen)
|
|
214
244
|
return;
|
|
215
|
-
|
|
245
|
+
headerRef.current?.focus();
|
|
216
246
|
}, [isDialogOpen]);
|
|
217
|
-
|
|
247
|
+
const visibleErrorType = hasValidationError ? validationError : hasCustomError ? "custom" : null;
|
|
248
|
+
const visibleErrorMessage = visibleErrorType ? getErrorMessage(visibleErrorType) : "";
|
|
249
|
+
return (jsxs("div", { className: clsx("ids-datepicker", { "ids-datepicker--invalid": hasError }, className), "data-testid": dataTestId, children: [isDialogOpen && jsx("div", { className: "ids-datepicker__overlay" }), label && (jsxs("div", { className: "ids-label-wrapper ids-label-wrapper--margin-bottom", children: [jsx("label", { htmlFor: inputId, className: clsx("ids-label", { "ids-label--disabled": disabled }), children: label }), tooltip && jsx("span", { className: "ids-label__tooltip", children: tooltip })] })), subtitle && jsx("div", { className: clsx("ids-subtitle", { "ids-subtitle--disabled": disabled }), children: subtitle }), jsxs("div", { className: "ids-datepicker__input-wrapper", children: [jsx("input", { className: clsx("ids-datepicker__input", { "ids-input--light": light }), ref: inputRef, style: { fontSize: "inherit" }, id: inputId, type: "text", value: inputValue, required: shouldRunRequiredValidation || undefined, pattern: shouldRunRequiredValidation ? datePatternString : undefined, "aria-invalid": hasError || undefined, disabled: disabled, readOnly: readOnly, placeholder: placeholder, onChange: handleInputChange, onFocus: onFocus, onInvalid: handleInvalid, onBlur: handleBlur, ...props }), jsx("button", { ref: triggerRef, type: "button", className: "ids-datepicker__trigger", style: { fontSize: "inherit" }, disabled: disabled || readOnly, onClick: handleOpenDialog, "aria-controls": dialogId, "aria-haspopup": "dialog", "aria-expanded": isDialogOpen, "aria-label": srOpenText }), jsxs("div", { className: clsx("ids-datepicker__dialog", { "ids-datepicker__dialog--show": isDialogOpen }), role: "dialog", ref: dialogRef, id: dialogId, "aria-modal": true, "aria-labelledby": headerId, children: [jsxs("div", { className: "ids-datepicker__dialog-bar", children: [jsx("div", { className: "ids-datepicker__dialog-header", id: headerId, ref: headerRef, tabIndex: -1, children: calendarHeader }), jsx("button", { className: "ids-datepicker__dialog-close-button", type: "button", onClick: closeDialog, "aria-label": srCloseText })] }), jsx(DayPicker, { mode: "single", locale: sv, labels: {
|
|
218
250
|
labelWeekNumberHeader: () => "Veckonumer",
|
|
219
251
|
labelWeekNumber: (_weekNumber) => `vecka`,
|
|
220
252
|
labelDayButton(date, _modifiers, _options, dateLib) {
|
|
@@ -235,7 +267,7 @@ function IDSDatePicker({ label, id, value, light = false, placeholder = "ååå
|
|
|
235
267
|
WeekNumberHeader: props => (jsx(WeekNumberHeader, { ...props, className: "ids-datepicker__week-number-header", children: shortWeek })),
|
|
236
268
|
MonthsDropdown: props => (jsx(MonthsDropdown, { ...props, disabled: disableNavigation, className: "ids-datepicker__month-select" })),
|
|
237
269
|
YearsDropdown: props => (jsx(YearsDropdown, { ...props, disabled: disableNavigation, className: "ids-datepicker__year-select" }))
|
|
238
|
-
}, startMonth: startMonth, endMonth: endMonth, month: month, onMonthChange: setMonth, defaultMonth: defaultMonth, selected: selectedDate, onSelect: handleDayPickerSelect, onDayClick: onDayClick })] })] }),
|
|
270
|
+
}, startMonth: startMonth, endMonth: endMonth, month: month, onMonthChange: setMonth, defaultMonth: defaultMonth, selected: selectedDate, onSelect: handleDayPickerSelect, onDayClick: onDayClick })] })] }), visibleErrorMessage && (jsx(IDSErrorMessage, { id: errorMsgId, show: true, children: visibleErrorMessage }))] }));
|
|
239
271
|
}
|
|
240
272
|
IDSDatePicker.displayName = "IDSDatePicker";
|
|
241
273
|
|
|
@@ -5,7 +5,7 @@ interface IDSErrorMessageProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
5
5
|
compact?: boolean;
|
|
6
6
|
children?: ReactNode;
|
|
7
7
|
}
|
|
8
|
-
export declare function IDSErrorMessage({ show, compact, id, children, className, ...props }: IDSErrorMessageProps):
|
|
8
|
+
export declare function IDSErrorMessage({ show, compact, id, children, className, ...props }: IDSErrorMessageProps): React.JSX.Element;
|
|
9
9
|
export declare namespace IDSErrorMessage {
|
|
10
10
|
var displayName: string;
|
|
11
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function useInputValidity(ref: React.RefObject<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>, validateOnBlur?: boolean): boolean;
|
|
1
|
+
export declare function useInputValidity(ref: React.RefObject<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>, validateOnBlur?: boolean, skipValidation?: boolean): boolean;
|
|
@@ -1,30 +1,46 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
1
|
+
import { useState, useRef, useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
function useInputValidity(ref, validateOnBlur) {
|
|
3
|
+
function useInputValidity(ref, validateOnBlur, skipValidation) {
|
|
4
4
|
const [isValid, setIsValid] = useState(true);
|
|
5
|
+
const validationStartedRef = useRef(false);
|
|
5
6
|
useEffect(() => {
|
|
7
|
+
if (skipValidation) {
|
|
8
|
+
validationStartedRef.current = false;
|
|
9
|
+
setIsValid(true);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
6
12
|
const inputEl = ref.current;
|
|
7
13
|
if (!inputEl)
|
|
8
14
|
return;
|
|
9
15
|
const updateValidity = () => {
|
|
10
|
-
|
|
16
|
+
const isOptionalEmpty = !inputEl.required && inputEl.value === "";
|
|
17
|
+
setIsValid(isOptionalEmpty || inputEl.validity.valid);
|
|
18
|
+
};
|
|
19
|
+
const startValidation = () => {
|
|
20
|
+
validationStartedRef.current = true;
|
|
21
|
+
updateValidity();
|
|
22
|
+
};
|
|
23
|
+
const updateValidityAfterValidationStarted = () => {
|
|
24
|
+
if (validationStartedRef.current) {
|
|
25
|
+
updateValidity();
|
|
26
|
+
}
|
|
11
27
|
};
|
|
12
28
|
const form = inputEl.closest("form");
|
|
13
|
-
form?.addEventListener("submit",
|
|
29
|
+
form?.addEventListener("submit", startValidation);
|
|
30
|
+
inputEl.addEventListener("invalid", startValidation);
|
|
31
|
+
inputEl.addEventListener("change", updateValidityAfterValidationStarted);
|
|
14
32
|
if (validateOnBlur) {
|
|
15
|
-
inputEl.addEventListener("blur",
|
|
33
|
+
inputEl.addEventListener("blur", startValidation);
|
|
16
34
|
}
|
|
17
|
-
inputEl.addEventListener("change", updateValidity);
|
|
18
|
-
inputEl.addEventListener("invalid", updateValidity);
|
|
19
35
|
return () => {
|
|
20
|
-
form?.removeEventListener("submit",
|
|
36
|
+
form?.removeEventListener("submit", startValidation);
|
|
37
|
+
inputEl.removeEventListener("invalid", startValidation);
|
|
38
|
+
inputEl.removeEventListener("change", updateValidityAfterValidationStarted);
|
|
21
39
|
if (validateOnBlur) {
|
|
22
|
-
inputEl.removeEventListener("blur",
|
|
40
|
+
inputEl.removeEventListener("blur", startValidation);
|
|
23
41
|
}
|
|
24
|
-
inputEl.removeEventListener("change", updateValidity);
|
|
25
|
-
inputEl.removeEventListener("invalid", updateValidity);
|
|
26
42
|
};
|
|
27
|
-
}, [ref]);
|
|
43
|
+
}, [ref, validateOnBlur, skipValidation]);
|
|
28
44
|
return isValid;
|
|
29
45
|
}
|
|
30
46
|
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import React, { ReactNode, CSSProperties } from "react";
|
|
2
2
|
import { CommonFormPropsWithReadOnly } from "../form-props/form-props";
|
|
3
3
|
export interface IDSInputBaseProps extends React.InputHTMLAttributes<HTMLInputElement>, CommonFormPropsWithReadOnly {
|
|
4
|
-
icon?: string;
|
|
5
4
|
unit?: string;
|
|
5
|
+
subtitle?: string;
|
|
6
6
|
showSearchLabel?: boolean;
|
|
7
7
|
submitButton?: ReactNode;
|
|
8
8
|
hintId?: string;
|
|
9
9
|
errorMsgId?: string;
|
|
10
10
|
inputRef?: React.Ref<HTMLInputElement>;
|
|
11
11
|
style?: CSSProperties;
|
|
12
|
+
icon?: string;
|
|
13
|
+
clearButton?: ReactNode;
|
|
12
14
|
}
|
|
13
|
-
export declare function IDSInputBase({ label, type, icon, hint, unit, showSearchLabel, errorMsg, dataTestId, disabled, invalid, required, focusAnchor, light, readOnly, tooltip, submitButton, className, id, hintId, errorMsgId, inputRef, ...props }: IDSInputBaseProps):
|
|
15
|
+
export declare function IDSInputBase({ label, type, icon, clearButton, hint, unit, subtitle, showSearchLabel, errorMsg, dataTestId, disabled, invalid, required, focusAnchor, light, readOnly, tooltip, submitButton, className, id, hintId, errorMsgId, inputRef, ...props }: IDSInputBaseProps): React.JSX.Element;
|
|
14
16
|
export declare namespace IDSInputBase {
|
|
15
17
|
var displayName: string;
|
|
16
18
|
}
|
|
@@ -3,7 +3,7 @@ import { useId } from 'react';
|
|
|
3
3
|
import clsx from 'clsx';
|
|
4
4
|
import { IDSErrorMessage } from '../error-message/error-message.js';
|
|
5
5
|
|
|
6
|
-
function IDSInputBase({ label, type = "text", icon, hint, unit, showSearchLabel = false, errorMsg, dataTestId, disabled = false, invalid = false, required = false, focusAnchor = false, light = false, readOnly = false, tooltip, submitButton, className, id, hintId, errorMsgId, inputRef, ...props }) {
|
|
6
|
+
function IDSInputBase({ label, type = "text", icon, clearButton, hint, unit, subtitle, showSearchLabel = false, errorMsg, dataTestId, disabled = false, invalid = false, required = false, focusAnchor = false, light = false, readOnly = false, tooltip, submitButton, className, id, hintId, errorMsgId, inputRef, ...props }) {
|
|
7
7
|
const reactId = useId();
|
|
8
8
|
const inputId = id ?? `input-base-${reactId}`;
|
|
9
9
|
const baseHintId = hintId ?? `input-base-hint-${reactId}`;
|
|
@@ -17,15 +17,20 @@ function IDSInputBase({ label, type = "text", icon, hint, unit, showSearchLabel
|
|
|
17
17
|
if (type === "search" && !showSearchLabel && label) {
|
|
18
18
|
ariaHandler["aria-label"] = label;
|
|
19
19
|
}
|
|
20
|
-
return (jsxs(Fragment, { children: [jsxs("div", { className: clsx("ids-input", {
|
|
21
|
-
|
|
20
|
+
return (jsxs(Fragment, { children: [jsxs("div", { className: clsx("ids-input", {
|
|
21
|
+
"ids-input--search": type === "search",
|
|
22
|
+
"ids-input--icon": !!icon && !clearButton,
|
|
23
|
+
"ids-input--clear-button": !!clearButton,
|
|
24
|
+
"ids-input--unit": !!unit
|
|
25
|
+
}, className), "data-testid": dataTestId, children: [jsxs("div", { className: "ids-input__wrapper", children: [label && (jsxs("div", { className: clsx("ids-label-wrapper", "ids-label-wrapper--margin-bottom", {
|
|
26
|
+
"ids-label-wrapper--sr-only": type === "search" && !showSearchLabel
|
|
22
27
|
}), children: [jsx("label", { className: clsx("ids-label", {
|
|
23
|
-
"ids-label--
|
|
24
|
-
}), htmlFor: inputId, children: label }), tooltip && jsx("span", { className: "ids-label__tooltip", children: tooltip })] })),
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
"ids-label--sr-only": type === "search" && !showSearchLabel
|
|
29
|
+
}), htmlFor: inputId, children: label }), tooltip && jsx("span", { className: "ids-label__tooltip", children: tooltip })] })), subtitle && jsx("div", { className: "ids-subtitle", children: subtitle }), jsxs("div", { className: "ids-input__input-wrapper", children: [type === "search" && jsx("span", { className: "ids-input__search-icon", "aria-hidden": "true" }), jsx("input", { ref: inputRef, id: inputId, type: type, readOnly: readOnly, className: clsx("ids-input__input", {
|
|
30
|
+
"ids-input--light": light,
|
|
31
|
+
"ids-input--invalid": invalid,
|
|
32
|
+
"ids-focus-anchor": focusAnchor
|
|
33
|
+
}), "aria-invalid": invalid, required: required, disabled: disabled, ...ariaHandler, ...props }), icon && !clearButton && jsx("span", { className: `ids-input__icon ids-icon-${icon}` }), clearButton && jsx("span", { className: "ids-input__clear-button", children: clearButton }), unit && (jsx("div", { className: "ids-input__unit", "aria-hidden": "true", children: unit }))] }), hint && (jsx("div", { className: "ids-input__hint", id: baseHintId, children: hint }))] }), !!submitButton && submitButton] }), showErrorMsg && (jsx(IDSErrorMessage, { id: baseErrorMsgId, show: true, children: errorMsg }))] }));
|
|
29
34
|
}
|
|
30
35
|
IDSInputBase.displayName = "IDSInputBase";
|
|
31
36
|
|
|
@@ -2,7 +2,10 @@ import { ReactNode } from "react";
|
|
|
2
2
|
import { CommonFormPropsWithReadOnly } from "../form-props/form-props";
|
|
3
3
|
interface IDSInputProps extends React.InputHTMLAttributes<HTMLInputElement>, CommonFormPropsWithReadOnly {
|
|
4
4
|
icon?: string;
|
|
5
|
+
clearButton?: ReactNode;
|
|
5
6
|
unit?: string;
|
|
7
|
+
hint?: string | ReactNode;
|
|
8
|
+
subtitle?: string;
|
|
6
9
|
showSearchLabel?: boolean;
|
|
7
10
|
submitButton?: ReactNode;
|
|
8
11
|
}
|
|
@@ -6,7 +6,7 @@ import { IDSInputBase } from './input-base.js';
|
|
|
6
6
|
|
|
7
7
|
const IDSInput = forwardRef(({ invalid = false, noValidation = false, style, validationOnBlur = false, ...props }, ref) => {
|
|
8
8
|
const inputRef = useRef(null);
|
|
9
|
-
const hasValidValue = useInputValidity(inputRef, validationOnBlur);
|
|
9
|
+
const hasValidValue = useInputValidity(inputRef, validationOnBlur, noValidation);
|
|
10
10
|
const computedInvalid = (invalid || !hasValidValue) && !noValidation;
|
|
11
11
|
// Merge forwarded + local ref
|
|
12
12
|
const mergedRef = (node) => {
|
|
@@ -4,7 +4,7 @@ interface IDSRadioBaseProps extends React.InputHTMLAttributes<HTMLInputElement>,
|
|
|
4
4
|
errorMsgId?: string;
|
|
5
5
|
inputRef?: React.Ref<HTMLInputElement>;
|
|
6
6
|
}
|
|
7
|
-
export declare function IDSRadioBase({ id, name, light, disabled, focusAnchor, tooltip, dataTestId, children, className, inputRef, invalid, errorMsgId, ...props }: IDSRadioBaseProps):
|
|
7
|
+
export declare function IDSRadioBase({ id, name, light, disabled, focusAnchor, tooltip, dataTestId, children, className, inputRef, invalid, errorMsgId, ...props }: IDSRadioBaseProps): React.JSX.Element;
|
|
8
8
|
export declare namespace IDSRadioBase {
|
|
9
9
|
var displayName: string;
|
|
10
10
|
}
|
|
@@ -13,8 +13,7 @@ function IDSRadioBase({ id, name, light, disabled, focusAnchor, tooltip, dataTes
|
|
|
13
13
|
"ids-input--light": light,
|
|
14
14
|
"ids-focus-anchor": focusAnchor
|
|
15
15
|
}), name: name, disabled: disabled, "aria-invalid": invalid, ...ariaHandler, ...props }), !!children && (jsxs("div", { className: "ids-label-wrapper", children: [jsx("label", { htmlFor: inputId, className: clsx("ids-radio__label ids-label", {
|
|
16
|
-
"ids-label--clickable": !disabled
|
|
17
|
-
"ids-label--disabled": disabled
|
|
16
|
+
"ids-label--clickable": !disabled
|
|
18
17
|
}), children: children }), tooltip && jsx("span", { className: "ids-label__tooltip", children: tooltip })] }))] }));
|
|
19
18
|
}
|
|
20
19
|
IDSRadioBase.displayName = "IDSRadioBase";
|
|
@@ -7,10 +7,11 @@ interface IDSRadioGroupBaseProps extends FieldsetHTMLAttributes<HTMLFieldSetElem
|
|
|
7
7
|
required?: boolean;
|
|
8
8
|
tooltip?: ReactNode;
|
|
9
9
|
invalid?: boolean;
|
|
10
|
+
subtitle?: string | ReactNode;
|
|
10
11
|
errorMsgId?: string;
|
|
11
12
|
groupRef?: React.Ref<HTMLFieldSetElement>;
|
|
12
13
|
}
|
|
13
|
-
export declare function IDSRadioGroupBase({ legend, hideLegend, errorMsg, errorMsgId, compact, required, tooltip, className, children, invalid, groupRef, ...props }: IDSRadioGroupBaseProps):
|
|
14
|
+
export declare function IDSRadioGroupBase({ legend, hideLegend, errorMsg, errorMsgId, compact, required, tooltip, subtitle, className, children, invalid, groupRef, ...props }: IDSRadioGroupBaseProps): React.JSX.Element;
|
|
14
15
|
export declare namespace IDSRadioGroupBase {
|
|
15
16
|
var displayName: string;
|
|
16
17
|
}
|
|
@@ -2,11 +2,11 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { IDSErrorMessage } from '../error-message/error-message.js';
|
|
3
3
|
import clsx from 'clsx';
|
|
4
4
|
|
|
5
|
-
function IDSRadioGroupBase({ legend, hideLegend, errorMsg, errorMsgId, compact = false, required = false, tooltip, className, children, invalid, groupRef, ...props }) {
|
|
5
|
+
function IDSRadioGroupBase({ legend, hideLegend, errorMsg, errorMsgId, compact = false, required = false, tooltip, subtitle, className, children, invalid, groupRef, ...props }) {
|
|
6
6
|
const showErrorMsg = invalid && !!errorMsg && !!errorMsgId;
|
|
7
|
-
return (jsxs("fieldset", { ref: groupRef, "aria-required": required, className: clsx("ids-form-group__fieldset", { "ids-form-group__fieldset--compact": compact }, className), ...props, children: [legend && (
|
|
7
|
+
return (jsxs("fieldset", { ref: groupRef, "aria-required": required, className: clsx("ids-form-group__fieldset", { "ids-form-group__fieldset--compact": compact }, className), ...props, children: [legend && (jsxs("div", { className: clsx("ids-label-wrapper", {
|
|
8
8
|
"ids-label-wrapper--sr-only": hideLegend
|
|
9
|
-
}, className), children: jsxs("legend", { children: [legend, tooltip && jsx("span", { className: "ids-legend__tooltip", children: tooltip })] }) })), children, showErrorMsg && (jsx(IDSErrorMessage, { id: errorMsgId, show: true, style: { marginTop: compact ? "0.75rem" : "auto" }, children: errorMsg }))] }));
|
|
9
|
+
}, className), children: [jsxs("legend", { children: [legend, tooltip && jsx("span", { className: "ids-legend__tooltip", children: tooltip })] }), subtitle && jsx("div", { className: "ids-subtitle ids-subtitle--group", children: subtitle })] })), children, showErrorMsg && (jsx(IDSErrorMessage, { id: errorMsgId, show: true, style: { marginTop: compact ? "0.75rem" : "auto" }, children: errorMsg }))] }));
|
|
10
10
|
}
|
|
11
11
|
IDSRadioGroupBase.displayName = "IDSRadioGroupBase";
|
|
12
12
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeEvent, ReactNode, FieldsetHTMLAttributes } from "react";
|
|
1
|
+
import React, { ChangeEvent, ReactNode, FieldsetHTMLAttributes } from "react";
|
|
2
2
|
interface IDSRadioGroupProps extends FieldsetHTMLAttributes<HTMLFieldSetElement> {
|
|
3
3
|
name?: string;
|
|
4
4
|
legend?: string;
|
|
@@ -7,11 +7,12 @@ interface IDSRadioGroupProps extends FieldsetHTMLAttributes<HTMLFieldSetElement>
|
|
|
7
7
|
compact?: boolean;
|
|
8
8
|
invalid?: boolean;
|
|
9
9
|
required?: boolean;
|
|
10
|
+
subtitle?: string | ReactNode;
|
|
10
11
|
tooltip?: ReactNode;
|
|
11
12
|
noValidation?: boolean;
|
|
12
13
|
onRadioChange?: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
13
14
|
}
|
|
14
|
-
export declare function IDSRadioGroup({ name, required, noValidation, invalid, errorMsg, children, onRadioChange, ...props }: IDSRadioGroupProps):
|
|
15
|
+
export declare function IDSRadioGroup({ name, required, noValidation, invalid, errorMsg, subtitle, children, onRadioChange, ...props }: IDSRadioGroupProps): React.JSX.Element;
|
|
15
16
|
export declare namespace IDSRadioGroup {
|
|
16
17
|
var displayName: string;
|
|
17
18
|
}
|