@lifesg/react-design-system 4.0.0-alpha.6 → 4.0.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/accordion/accordion.js.map +1 -1
- package/alert/alert.js.map +1 -1
- package/alert/types.d.ts +2 -0
- package/animations/loading-dots/loading-dots.d.ts +5 -2
- package/animations/loading-dots/loading-dots.js.map +1 -1
- package/animations/loading-dots-spinner/loading-dots-spinner.d.ts +3 -0
- package/animations/loading-dots-spinner/loading-dots-spinner.js.map +1 -1
- package/animations/loading-dots-spinner/lottie-animation.d.ts +2 -2
- package/animations/loading-dots-spinner/lottie-animation.js.map +1 -1
- package/animations/loading-spinner/loading-spinner.d.ts +5 -2
- package/animations/loading-spinner/loading-spinner.js.map +1 -1
- package/animations/themed-loading-spinner/themed-loading-spinner.d.ts +5 -2
- package/animations/themed-loading-spinner/themed-loading-spinner.js.map +1 -1
- package/animations/types.d.ts +13 -6
- package/avatar/avatar.js.map +1 -1
- package/badge/badge.js.map +1 -1
- package/badge/types.d.ts +13 -2
- package/box-container/box-container.js.map +1 -1
- package/box-container/types.d.ts +2 -0
- package/breadcrumb/breadcrumb.js.map +1 -1
- package/breadcrumb/types.d.ts +7 -2
- package/button/button.js +1 -1
- package/button/button.js.map +1 -1
- package/button/button.styles.d.ts +1 -0
- package/button/button.styles.js +1 -1
- package/button/button.styles.js.map +1 -1
- package/button/button.styles_19i4dfq.css +21 -0
- package/button/types.d.ts +5 -0
- package/calendar/calendar.js.map +1 -1
- package/calendar/types.d.ts +3 -3
- package/card/card.js.map +1 -1
- package/checkbox/checkbox.js.map +1 -1
- package/checkbox/types.d.ts +4 -0
- package/cjs/accordion/accordion.js.map +1 -1
- package/cjs/alert/alert.js.map +1 -1
- package/cjs/animations/loading-dots/loading-dots.js.map +1 -1
- package/cjs/animations/loading-dots-spinner/loading-dots-spinner.js.map +1 -1
- package/cjs/animations/loading-dots-spinner/lottie-animation.js.map +1 -1
- package/cjs/animations/loading-spinner/loading-spinner.js.map +1 -1
- package/cjs/animations/themed-loading-spinner/themed-loading-spinner.js.map +1 -1
- package/cjs/avatar/avatar.js.map +1 -1
- package/cjs/badge/badge.js.map +1 -1
- package/cjs/box-container/box-container.js.map +1 -1
- package/cjs/breadcrumb/breadcrumb.js.map +1 -1
- package/cjs/button/button.js +1 -1
- package/cjs/button/button.js.map +1 -1
- package/cjs/button/button.styles.js +1 -1
- package/cjs/button/button.styles.js.map +1 -1
- package/cjs/button/button.styles_19i4dfq.css +21 -0
- package/cjs/calendar/calendar.js.map +1 -1
- package/cjs/card/card.js.map +1 -1
- package/cjs/checkbox/checkbox.js.map +1 -1
- package/cjs/countdown-timer/countdown-timer.js.map +1 -1
- package/cjs/dashed-border/dashed-border.js.map +1 -1
- package/cjs/data-table/data-table.js +1 -1
- package/cjs/data-table/data-table.js.map +1 -1
- package/cjs/data-table/data-table.styles.js +1 -1
- package/cjs/data-table/data-table.styles.js.map +1 -1
- package/cjs/data-table/{data-table.styles_rxganh.css → data-table.styles_1tnlmhe.css} +7 -6
- package/cjs/date-input/date-input.js.map +1 -1
- package/cjs/date-navigator/date-navigator.js.map +1 -1
- package/cjs/date-range-input/date-range-input.js.map +1 -1
- package/cjs/divider/divider.js.map +1 -1
- package/cjs/drawer/drawer.js.map +1 -1
- package/cjs/e-signature/e-signature.js.map +1 -1
- package/cjs/error-display/error-display-data.js +1 -1
- package/cjs/error-display/error-display-data.js.map +1 -1
- package/cjs/error-display/error-display.js.map +1 -1
- package/cjs/feedback-rating/feedback-rating.js.map +1 -1
- package/cjs/file-download/file-download.js.map +1 -1
- package/cjs/file-upload/file-item-edit.js.map +1 -1
- package/cjs/file-upload/file-list/file-list.js.map +1 -1
- package/cjs/file-upload/file-list-item/file-list-item.js.map +1 -1
- package/cjs/file-upload/file-list-item/file-list-item.styles.js +1 -1
- package/cjs/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
- package/{file-upload/file-list-item/file-list-item.styles_o8000f.css → cjs/file-upload/file-list-item/file-list-item.styles_kgtfke.css} +1 -1
- package/cjs/file-upload/file-upload.js.map +1 -1
- package/cjs/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
- package/cjs/filter/addons/filter-item-checkbox.js.map +1 -1
- package/cjs/filter/addons/filter-item-checkbox.styles.js +1 -1
- package/cjs/filter/addons/filter-item-checkbox.styles.js.map +1 -1
- package/cjs/filter/addons/{filter-item-checkbox.styles_7degw7.css → filter-item-checkbox.styles_6nbpdl.css} +1 -1
- package/cjs/filter/filter-item.js +1 -1
- package/cjs/filter/filter-item.js.map +1 -1
- package/cjs/filter/filter-item.styles.js +1 -1
- package/cjs/filter/filter-item.styles.js.map +1 -1
- package/cjs/filter/{filter-item.styles_cphjnj.css → filter-item.styles_1yixp8h.css} +1 -1
- package/cjs/filter/filter-modal.styles.js +1 -1
- package/cjs/filter/filter-modal.styles.js.map +1 -1
- package/{filter/filter-modal.styles_qw3xlg.css → cjs/filter/filter-modal.styles_kuth21.css} +1 -1
- package/cjs/filter/filter-sidebar.styles.js +1 -1
- package/cjs/filter/filter-sidebar.styles.js.map +1 -1
- package/cjs/filter/{filter-sidebar.styles_1otwpjl.css → filter-sidebar.styles_rbfq4f.css} +1 -1
- package/cjs/filter/filter.js.map +1 -1
- package/cjs/footer/footer.js.map +1 -1
- package/cjs/form/form-custom-field/form-custom-field.js +2 -0
- package/cjs/form/form-custom-field/form-custom-field.js.map +1 -0
- package/cjs/form/form-date-input/form-date-input.js +2 -0
- package/cjs/form/form-date-input/form-date-input.js.map +1 -0
- package/cjs/form/form-date-range-input/form-date-range-input.js +2 -0
- package/cjs/form/form-date-range-input/form-date-range-input.js.map +1 -0
- package/cjs/form/form-e-signature/form-e-signature.js +2 -0
- package/cjs/form/form-e-signature/form-e-signature.js.map +1 -0
- package/cjs/form/form-histogram-slider/form-histogram-slider.js +2 -0
- package/cjs/form/form-histogram-slider/form-histogram-slider.js.map +1 -0
- package/cjs/form/form-input/form-input.js +2 -0
- package/cjs/form/form-input/form-input.js.map +1 -0
- package/cjs/form/form-input-group/form-input-group.js +2 -0
- package/cjs/form/form-input-group/form-input-group.js.map +1 -0
- package/cjs/form/form-label/form-label-addon.js +2 -0
- package/cjs/form/form-label/form-label-addon.js.map +1 -0
- package/cjs/form/form-label/form-label-addon.styles.js +2 -0
- package/cjs/form/form-label/form-label-addon.styles.js.map +1 -0
- package/cjs/form/form-label/form-label-addon.styles_aztasj.css +1 -0
- package/cjs/form/form-label/form-label.js +2 -0
- package/cjs/form/form-label/form-label.js.map +1 -0
- package/cjs/form/form-label/form-label.styles.js +2 -0
- package/cjs/form/form-label/form-label.styles.js.map +1 -0
- package/cjs/form/form-label/form-label.styles_180zf7j.css +6 -0
- package/cjs/form/form-masked-input/form-masked-input.js +2 -0
- package/cjs/form/form-masked-input/form-masked-input.js.map +1 -0
- package/cjs/form/form-multi-select/form-multi-select.js +2 -0
- package/cjs/form/form-multi-select/form-multi-select.js.map +1 -0
- package/cjs/form/form-nested-multi-select/form-nested-multi-select.js +2 -0
- package/cjs/form/form-nested-multi-select/form-nested-multi-select.js.map +1 -0
- package/cjs/form/form-nested-select/form-nested-select.js +2 -0
- package/cjs/form/form-nested-select/form-nested-select.js.map +1 -0
- package/cjs/form/form-otp-verification/form-otp-verification.js +2 -0
- package/cjs/form/form-otp-verification/form-otp-verification.js.map +1 -0
- package/cjs/form/form-phone-number-input/form-phone-number-input.js +2 -0
- package/cjs/form/form-phone-number-input/form-phone-number-input.js.map +1 -0
- package/cjs/form/form-predictive-text-input/form-predictive-text-input.js +2 -0
- package/cjs/form/form-predictive-text-input/form-predictive-text-input.js.map +1 -0
- package/cjs/form/form-range-select/form-range-select.js +2 -0
- package/cjs/form/form-range-select/form-range-select.js.map +1 -0
- package/cjs/form/form-range-slider/form-range-slider.js +2 -0
- package/cjs/form/form-range-slider/form-range-slider.js.map +1 -0
- package/cjs/form/form-select/form-select.js +2 -0
- package/cjs/form/form-select/form-select.js.map +1 -0
- package/cjs/form/form-select-histogram/form-select-histogram.js +2 -0
- package/cjs/form/form-select-histogram/form-select-histogram.js.map +1 -0
- package/cjs/form/form-slider/form-slider.js +2 -0
- package/cjs/form/form-slider/form-slider.js.map +1 -0
- package/cjs/form/form-textarea/form-textarea.js +2 -0
- package/cjs/form/form-textarea/form-textarea.js.map +1 -0
- package/cjs/form/form-textarea/form-textarea.styles.js +2 -0
- package/cjs/form/form-textarea/form-textarea.styles.js.map +1 -0
- package/cjs/form/form-textarea/form-textarea.styles_1kneyif.css +3 -0
- package/cjs/form/form-time-range-picker/form-time-range-picker.js +2 -0
- package/cjs/form/form-time-range-picker/form-time-range-picker.js.map +1 -0
- package/cjs/form/form-timepicker/form-timepicker.js +2 -0
- package/cjs/form/form-timepicker/form-timepicker.js.map +1 -0
- package/cjs/form/form-unit-number-input/form-unit-number-input.js +2 -0
- package/cjs/form/form-unit-number-input/form-unit-number-input.js.map +1 -0
- package/cjs/form/form-wrapper.js +1 -1
- package/cjs/form/form-wrapper.js.map +1 -1
- package/cjs/form/index.js +1 -1
- package/cjs/form/index.js.map +1 -1
- package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
- package/cjs/histogram-slider/histogram-slider.js.map +1 -1
- package/cjs/image-button/image-button.js.map +1 -1
- package/cjs/input/input.js.map +1 -1
- package/cjs/input-group/input-group.js.map +1 -1
- package/cjs/input-multi-select/input-multi-select.js.map +1 -1
- package/cjs/input-nested-multi-select/input-nested-multi-select.js.map +1 -1
- package/cjs/input-nested-select/input-nested-select.js.map +1 -1
- package/cjs/input-range-select/input-range-select.js.map +1 -1
- package/cjs/input-range-slider/input-range-slider.js.map +1 -1
- package/cjs/input-select/input-select.js.map +1 -1
- package/cjs/input-slider/input-slider.js.map +1 -1
- package/cjs/input-textarea/textarea.js.map +1 -1
- package/cjs/input-textarea/textarea.styles.js +1 -1
- package/cjs/input-textarea/textarea.styles.js.map +1 -1
- package/cjs/input-textarea/{textarea.styles_22z4n3.css → textarea.styles_q77m5x.css} +1 -1
- package/cjs/language-switcher/language-switcher.js.map +1 -1
- package/cjs/layout/index.js.map +1 -1
- package/cjs/link-list/components/common.js.map +1 -1
- package/cjs/link-list/components/link-list-eager.js.map +1 -1
- package/cjs/link-list/components/link-list-lazy.js.map +1 -1
- package/cjs/link-list/link-list.js.map +1 -1
- package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
- package/cjs/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
- package/cjs/markup/markup.js.map +1 -1
- package/cjs/masked-input/masked-input.js.map +1 -1
- package/cjs/masthead/masthead.js.map +1 -1
- package/cjs/menu/menu.js.map +1 -1
- package/cjs/modal/index.js.map +1 -1
- package/cjs/modal-v2/modal-v2.js.map +1 -1
- package/cjs/navbar/navbar.js.map +1 -1
- package/cjs/notification-banner/notification-banner.js.map +1 -1
- package/cjs/otp-input/otp-input.js +1 -1
- package/cjs/otp-input/otp-input.js.map +1 -1
- package/cjs/otp-verification/contact-input-section.js +1 -1
- package/cjs/otp-verification/contact-input-section.js.map +1 -1
- package/cjs/otp-verification/otp-verification.js.map +1 -1
- package/cjs/otp-verification/verification-section.js +1 -1
- package/cjs/otp-verification/verification-section.js.map +1 -1
- package/cjs/overlay/overlay.js.map +1 -1
- package/cjs/pagination/pagination.js.map +1 -1
- package/cjs/phone-number-input/phone-number-input.js.map +1 -1
- package/cjs/pill/pill.js.map +1 -1
- package/cjs/popover/popover-inline/popover-inline.js.map +1 -1
- package/cjs/popover/popover.js.map +1 -1
- package/cjs/predictive-text-input/predictive-text-input.js +1 -1
- package/cjs/predictive-text-input/predictive-text-input.js.map +1 -1
- package/cjs/progress-indicator/progress-indicator.js.map +1 -1
- package/cjs/radio-button/radio-button.js.map +1 -1
- package/cjs/schedule/schedule.js.map +1 -1
- package/cjs/select-histogram/select-histogram.js.map +1 -1
- package/cjs/shared/dropdown-list/dropdown-list.js +1 -1
- package/cjs/shared/dropdown-list/dropdown-list.js.map +1 -1
- package/cjs/shared/dropdown-wrapper/element-with-dropdown.js +1 -1
- package/cjs/shared/dropdown-wrapper/element-with-dropdown.js.map +1 -1
- package/cjs/sidenav/sidenav.js.map +1 -1
- package/cjs/singpass-button/singpass-button.js.map +1 -1
- package/cjs/singpass-button/singpass-button.styles.js +1 -1
- package/cjs/singpass-button/singpass-button.styles.js.map +1 -1
- package/cjs/singpass-button/{singpass-button.styles_1miyex3.css → singpass-button.styles_1fj2lru.css} +1 -1
- package/cjs/smart-app-banner/smart-app-banner.js.map +1 -1
- package/cjs/smart-app-banner/smart-app-banner.styles.js +1 -1
- package/cjs/smart-app-banner/smart-app-banner.styles.js.map +1 -1
- package/{smart-app-banner/smart-app-banner.styles_15u6yv4.css → cjs/smart-app-banner/smart-app-banner.styles_r6yjq9.css} +1 -1
- package/cjs/tab/tab.js.map +1 -1
- package/cjs/table/table.js.map +1 -1
- package/cjs/tag/tag.js.map +1 -1
- package/cjs/text-list/index.js.map +1 -1
- package/cjs/theme/theme-provider/hooks.js.map +1 -1
- package/cjs/theme/theme-provider/index.js.map +1 -1
- package/cjs/theme/tokens/border.js.map +1 -1
- package/cjs/theme/tokens/breakpoint.js.map +1 -1
- package/cjs/theme/tokens/colour.js.map +1 -1
- package/cjs/theme/tokens/component.js.map +1 -1
- package/cjs/theme/tokens/font.js.map +1 -1
- package/cjs/theme/tokens/media-query.js.map +1 -1
- package/cjs/theme/tokens/motion.js.map +1 -1
- package/cjs/theme/tokens/radius.js.map +1 -1
- package/cjs/theme/tokens/shadow.js.map +1 -1
- package/cjs/theme/tokens/spacing.js.map +1 -1
- package/cjs/theme/utils/use-apply-styles.js.map +1 -1
- package/cjs/theme/utils/use-design-token.js.map +1 -1
- package/cjs/theme/utils/use-media-query.js.map +1 -1
- package/cjs/time-range-picker/combobox-picker/combobox-picker.js +1 -1
- package/cjs/time-range-picker/combobox-picker/combobox-picker.js.map +1 -1
- package/cjs/time-range-picker/time-range-picker.js.map +1 -1
- package/cjs/time-slot-bar/time-slot-bar.js.map +1 -1
- package/cjs/time-slot-bar-week/time-slot-bar-week.js.map +1 -1
- package/cjs/time-slot-week-view/time-slot-week-view.js.map +1 -1
- package/cjs/timeline/timeline.js.map +1 -1
- package/cjs/timepicker/timepicker.js.map +1 -1
- package/cjs/timetable/timetable.js.map +1 -1
- package/cjs/toast/toast.js.map +1 -1
- package/cjs/toast/toast.styles.js +1 -1
- package/cjs/toast/toast.styles.js.map +1 -1
- package/{toast/toast.styles_1e0l60w.css → cjs/toast/toast.styles_57j3lf.css} +1 -1
- package/cjs/toggle/toggle.js.map +1 -1
- package/cjs/typography/index.js.map +1 -1
- package/cjs/uneditable-section/index.js.map +1 -1
- package/cjs/uneditable-section/section-item.js +1 -1
- package/cjs/uneditable-section/section-item.js.map +1 -1
- package/cjs/unit-number/unit-number-input.js.map +1 -1
- package/countdown-timer/countdown-timer.js.map +1 -1
- package/countdown-timer/types.d.ts +3 -3
- package/dashed-border/dashed-border.js.map +1 -1
- package/data-table/data-table.d.ts +1 -1
- package/data-table/data-table.js +1 -1
- package/data-table/data-table.js.map +1 -1
- package/data-table/data-table.styles.d.ts +1 -0
- package/data-table/data-table.styles.js +1 -1
- package/data-table/data-table.styles.js.map +1 -1
- package/data-table/{data-table.styles_rxganh.css → data-table.styles_1tnlmhe.css} +7 -6
- package/data-table/types.d.ts +2 -0
- package/date-input/date-input.js.map +1 -1
- package/date-input/types.d.ts +1 -1
- package/date-navigator/date-navigator.js.map +1 -1
- package/date-navigator/types.d.ts +1 -1
- package/date-range-input/date-range-input.js.map +1 -1
- package/date-range-input/types.d.ts +1 -1
- package/divider/divider.js.map +1 -1
- package/divider/types.d.ts +1 -1
- package/docs/component-catalog.json +644 -0
- package/drawer/drawer.js.map +1 -1
- package/e-signature/e-signature.js.map +1 -1
- package/error-display/error-display-data.js +1 -1
- package/error-display/error-display-data.js.map +1 -1
- package/error-display/error-display.js.map +1 -1
- package/feedback-rating/feedback-rating.js.map +1 -1
- package/file-download/file-download.js.map +1 -1
- package/file-download/types.d.ts +6 -1
- package/file-upload/file-item-edit.d.ts +1 -1
- package/file-upload/file-item-edit.js.map +1 -1
- package/file-upload/file-list/file-list.d.ts +1 -1
- package/file-upload/file-list/file-list.js.map +1 -1
- package/file-upload/file-list-item/file-list-item.d.ts +1 -1
- package/file-upload/file-list-item/file-list-item.js.map +1 -1
- package/file-upload/file-list-item/file-list-item.styles.js +1 -1
- package/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
- package/{cjs/file-upload/file-list-item/file-list-item.styles_o8000f.css → file-upload/file-list-item/file-list-item.styles_kgtfke.css} +1 -1
- package/file-upload/file-upload.js.map +1 -1
- package/file-upload/types.d.ts +6 -2
- package/filter/addons/filter-item-checkbox-helpers.d.ts +2 -2
- package/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
- package/filter/addons/filter-item-checkbox.d.ts +1 -1
- package/filter/addons/filter-item-checkbox.js.map +1 -1
- package/filter/addons/filter-item-checkbox.styles.js +1 -1
- package/filter/addons/filter-item-checkbox.styles.js.map +1 -1
- package/filter/addons/{filter-item-checkbox.styles_7degw7.css → filter-item-checkbox.styles_6nbpdl.css} +1 -1
- package/filter/addons/internal-types.d.ts +12 -0
- package/filter/addons/types.d.ts +60 -9
- package/filter/filter-item.js +1 -1
- package/filter/filter-item.js.map +1 -1
- package/filter/filter-item.styles.js +1 -1
- package/filter/filter-item.styles.js.map +1 -1
- package/filter/{filter-item.styles_cphjnj.css → filter-item.styles_1yixp8h.css} +1 -1
- package/filter/filter-modal.styles.js +1 -1
- package/filter/filter-modal.styles.js.map +1 -1
- package/{cjs/filter/filter-modal.styles_qw3xlg.css → filter/filter-modal.styles_kuth21.css} +1 -1
- package/filter/filter-sidebar.styles.js +1 -1
- package/filter/filter-sidebar.styles.js.map +1 -1
- package/filter/{filter-sidebar.styles_1otwpjl.css → filter-sidebar.styles_rbfq4f.css} +1 -1
- package/filter/filter.d.ts +1 -1
- package/filter/filter.js.map +1 -1
- package/filter/index.d.ts +1 -0
- package/filter/types.d.ts +31 -63
- package/footer/footer.js.map +1 -1
- package/form/form-custom-field/form-custom-field.js +2 -0
- package/form/form-custom-field/form-custom-field.js.map +1 -0
- package/form/form-custom-field/index.d.ts +2 -0
- package/form/form-custom-field/types.d.ts +7 -0
- package/form/form-date-input/form-date-input.js +2 -0
- package/form/form-date-input/form-date-input.js.map +1 -0
- package/form/form-date-input/index.d.ts +2 -0
- package/form/form-date-input/types.d.ts +8 -0
- package/form/form-date-range-input/form-date-range-input.js +2 -0
- package/form/form-date-range-input/form-date-range-input.js.map +1 -0
- package/form/form-date-range-input/index.d.ts +2 -0
- package/form/form-date-range-input/types.d.ts +8 -0
- package/form/form-e-signature/form-e-signature.js +2 -0
- package/form/form-e-signature/form-e-signature.js.map +1 -0
- package/form/form-e-signature/index.d.ts +2 -0
- package/form/form-e-signature/types.d.ts +8 -0
- package/form/form-histogram-slider/form-histogram-slider.js +2 -0
- package/form/form-histogram-slider/form-histogram-slider.js.map +1 -0
- package/form/form-histogram-slider/index.d.ts +2 -0
- package/form/form-histogram-slider/types.d.ts +8 -0
- package/form/form-input/form-input.js +2 -0
- package/form/form-input/form-input.js.map +1 -0
- package/form/form-input/index.d.ts +2 -0
- package/form/form-input/types.d.ts +8 -0
- package/form/form-input-group/form-input-group.js +2 -0
- package/form/form-input-group/form-input-group.js.map +1 -0
- package/form/form-input-group/index.d.ts +2 -0
- package/form/form-input-group/types.d.ts +10 -0
- package/form/form-label/form-label-addon.js +2 -0
- package/form/form-label/form-label-addon.js.map +1 -0
- package/form/form-label/form-label-addon.styles.js +2 -0
- package/form/form-label/form-label-addon.styles.js.map +1 -0
- package/form/form-label/form-label-addon.styles_aztasj.css +1 -0
- package/form/form-label/form-label.js +2 -0
- package/form/form-label/form-label.js.map +1 -0
- package/form/form-label/form-label.styles.js +2 -0
- package/form/form-label/form-label.styles.js.map +1 -0
- package/form/form-label/form-label.styles_180zf7j.css +6 -0
- package/form/form-label/index.d.ts +2 -0
- package/form/form-label/types.d.ts +39 -0
- package/form/form-masked-input/form-masked-input.js +2 -0
- package/form/form-masked-input/form-masked-input.js.map +1 -0
- package/form/form-masked-input/index.d.ts +2 -0
- package/form/form-masked-input/types.d.ts +8 -0
- package/form/form-multi-select/form-multi-select.js +2 -0
- package/form/form-multi-select/form-multi-select.js.map +1 -0
- package/form/form-multi-select/index.d.ts +2 -0
- package/form/form-multi-select/types.d.ts +10 -0
- package/form/form-nested-multi-select/form-nested-multi-select.js +2 -0
- package/form/form-nested-multi-select/form-nested-multi-select.js.map +1 -0
- package/form/form-nested-multi-select/index.d.ts +2 -0
- package/form/form-nested-multi-select/types.d.ts +11 -0
- package/form/form-nested-select/form-nested-select.js +2 -0
- package/form/form-nested-select/form-nested-select.js.map +1 -0
- package/form/form-nested-select/index.d.ts +2 -0
- package/form/form-nested-select/types.d.ts +11 -0
- package/form/{form-otp-verification.d.ts → form-otp-verification/form-otp-verification.d.ts} +1 -1
- package/form/form-otp-verification/form-otp-verification.js +2 -0
- package/form/form-otp-verification/form-otp-verification.js.map +1 -0
- package/form/form-otp-verification/index.d.ts +2 -0
- package/form/form-otp-verification/types.d.ts +1 -0
- package/form/form-phone-number-input/form-phone-number-input.js +2 -0
- package/form/form-phone-number-input/form-phone-number-input.js.map +1 -0
- package/form/form-phone-number-input/index.d.ts +2 -0
- package/form/form-phone-number-input/types.d.ts +8 -0
- package/form/form-predictive-text-input/form-predictive-text-input.js +2 -0
- package/form/form-predictive-text-input/form-predictive-text-input.js.map +1 -0
- package/form/form-predictive-text-input/index.d.ts +2 -0
- package/form/form-predictive-text-input/types.d.ts +10 -0
- package/form/form-range-select/form-range-select.js +2 -0
- package/form/form-range-select/form-range-select.js.map +1 -0
- package/form/form-range-select/index.d.ts +2 -0
- package/form/form-range-select/types.d.ts +10 -0
- package/form/form-range-slider/form-range-slider.js +2 -0
- package/form/form-range-slider/form-range-slider.js.map +1 -0
- package/form/form-range-slider/index.d.ts +2 -0
- package/form/form-range-slider/types.d.ts +8 -0
- package/form/form-select/form-select.js +2 -0
- package/form/form-select/form-select.js.map +1 -0
- package/form/form-select/index.d.ts +2 -0
- package/form/form-select/types.d.ts +10 -0
- package/form/form-select-histogram/form-select-histogram.js +2 -0
- package/form/form-select-histogram/form-select-histogram.js.map +1 -0
- package/form/form-select-histogram/index.d.ts +2 -0
- package/form/form-select-histogram/types.d.ts +8 -0
- package/form/form-slider/form-slider.js +2 -0
- package/form/form-slider/form-slider.js.map +1 -0
- package/form/form-slider/index.d.ts +2 -0
- package/form/form-slider/types.d.ts +8 -0
- package/form/form-textarea/form-textarea.js +2 -0
- package/form/form-textarea/form-textarea.js.map +1 -0
- package/form/form-textarea/form-textarea.styles.js +2 -0
- package/form/form-textarea/form-textarea.styles.js.map +1 -0
- package/form/form-textarea/form-textarea.styles_1kneyif.css +3 -0
- package/form/form-textarea/index.d.ts +2 -0
- package/form/form-textarea/types.d.ts +8 -0
- package/form/form-time-range-picker/form-time-range-picker.js +2 -0
- package/form/form-time-range-picker/form-time-range-picker.js.map +1 -0
- package/form/form-time-range-picker/index.d.ts +2 -0
- package/form/form-time-range-picker/types.d.ts +8 -0
- package/form/form-timepicker/form-timepicker.js +2 -0
- package/form/form-timepicker/form-timepicker.js.map +1 -0
- package/form/form-timepicker/index.d.ts +2 -0
- package/form/form-timepicker/types.d.ts +8 -0
- package/form/form-unit-number-input/form-unit-number-input.js +2 -0
- package/form/form-unit-number-input/form-unit-number-input.js.map +1 -0
- package/form/form-unit-number-input/index.d.ts +2 -0
- package/form/form-unit-number-input/types.d.ts +8 -0
- package/form/form-wrapper.js +1 -1
- package/form/form-wrapper.js.map +1 -1
- package/form/index.d.ts +47 -24
- package/form/index.js +1 -1
- package/form/index.js.map +1 -1
- package/form/types.d.ts +1 -208
- package/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
- package/histogram-slider/histogram-slider.js.map +1 -1
- package/image-button/image-button.js.map +1 -1
- package/input/input.js.map +1 -1
- package/input-group/input-group.js.map +1 -1
- package/input-group/types.d.ts +1 -1
- package/input-multi-select/input-multi-select.js.map +1 -1
- package/input-multi-select/types.d.ts +1 -1
- package/input-nested-multi-select/input-nested-multi-select.js.map +1 -1
- package/input-nested-select/input-nested-select.js.map +1 -1
- package/input-nested-select/types.d.ts +1 -1
- package/input-range-select/input-range-select.js.map +1 -1
- package/input-range-select/types.d.ts +1 -1
- package/input-range-slider/input-range-slider.js.map +1 -1
- package/input-select/input-select.js.map +1 -1
- package/input-select/types.d.ts +1 -1
- package/input-slider/input-slider.js.map +1 -1
- package/input-slider/types.d.ts +1 -1
- package/input-textarea/textarea.js.map +1 -1
- package/input-textarea/textarea.styles.js +1 -1
- package/input-textarea/textarea.styles.js.map +1 -1
- package/input-textarea/{textarea.styles_22z4n3.css → textarea.styles_q77m5x.css} +1 -1
- package/language-switcher/language-switcher.js.map +1 -1
- package/layout/index.js.map +1 -1
- package/link-list/components/common.d.ts +1 -1
- package/link-list/components/common.js.map +1 -1
- package/link-list/components/link-list-eager.d.ts +2 -2
- package/link-list/components/link-list-eager.js.map +1 -1
- package/link-list/components/link-list-lazy.d.ts +2 -2
- package/link-list/components/link-list-lazy.js.map +1 -1
- package/link-list/link-list.js.map +1 -1
- package/link-list/types.d.ts +89 -3
- package/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
- package/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
- package/markup/markup.js.map +1 -1
- package/masked-input/masked-input.js.map +1 -1
- package/masthead/masthead.js.map +1 -1
- package/menu/menu.js.map +1 -1
- package/menu/types.d.ts +17 -1
- package/modal/index.js.map +1 -1
- package/modal/types.d.ts +3 -1
- package/modal-v2/modal-v2.js.map +1 -1
- package/modal-v2/types.d.ts +17 -0
- package/navbar/navbar.js.map +1 -1
- package/navbar/types.d.ts +1 -0
- package/notification-banner/notification-banner.js.map +1 -1
- package/otp-input/otp-input.js +1 -1
- package/otp-input/otp-input.js.map +1 -1
- package/otp-input/types.d.ts +14 -9
- package/otp-verification/contact-input-section.js +1 -1
- package/otp-verification/contact-input-section.js.map +1 -1
- package/otp-verification/otp-verification.js.map +1 -1
- package/otp-verification/verification-section.js +1 -1
- package/otp-verification/verification-section.js.map +1 -1
- package/overlay/overlay.js.map +1 -1
- package/package.json +1 -1
- package/pagination/pagination.js.map +1 -1
- package/phone-number-input/phone-number-input.js.map +1 -1
- package/pill/pill.js.map +1 -1
- package/popover/popover-inline/index.d.ts +1 -0
- package/popover/popover-inline/popover-inline.d.ts +1 -1
- package/popover/popover-inline/popover-inline.js.map +1 -1
- package/popover/popover-inline/types.d.ts +36 -0
- package/popover/popover.js.map +1 -1
- package/popover/types.d.ts +2 -35
- package/predictive-text-input/predictive-text-input.js +1 -1
- package/predictive-text-input/predictive-text-input.js.map +1 -1
- package/predictive-text-input/types.d.ts +1 -1
- package/progress-indicator/progress-indicator.js.map +1 -1
- package/radio-button/radio-button.js.map +1 -1
- package/radio-button/types.d.ts +3 -0
- package/schedule/schedule.js.map +1 -1
- package/select-histogram/select-histogram.js.map +1 -1
- package/select-histogram/types.d.ts +1 -1
- package/shared/dropdown-list/dropdown-list.js +1 -1
- package/shared/dropdown-list/dropdown-list.js.map +1 -1
- package/shared/dropdown-wrapper/element-with-dropdown.d.ts +5 -4
- package/shared/dropdown-wrapper/element-with-dropdown.js +1 -1
- package/shared/dropdown-wrapper/element-with-dropdown.js.map +1 -1
- package/sidenav/sidenav.js.map +1 -1
- package/sidenav/types.d.ts +1 -0
- package/singpass-button/singpass-button.js.map +1 -1
- package/singpass-button/singpass-button.styles.js +1 -1
- package/singpass-button/singpass-button.styles.js.map +1 -1
- package/singpass-button/{singpass-button.styles_1miyex3.css → singpass-button.styles_1fj2lru.css} +1 -1
- package/smart-app-banner/smart-app-banner.js.map +1 -1
- package/smart-app-banner/smart-app-banner.styles.js +1 -1
- package/smart-app-banner/smart-app-banner.styles.js.map +1 -1
- package/{cjs/smart-app-banner/smart-app-banner.styles_15u6yv4.css → smart-app-banner/smart-app-banner.styles_r6yjq9.css} +1 -1
- package/smart-app-banner/types.d.ts +2 -0
- package/tab/tab.js.map +1 -1
- package/table/table.d.ts +9 -8
- package/table/table.js.map +1 -1
- package/table/types.d.ts +35 -0
- package/tag/tag.js.map +1 -1
- package/text-list/index.js.map +1 -1
- package/theme/styles/pa.css +0 -41
- package/theme/theme-provider/hooks.js.map +1 -1
- package/theme/theme-provider/index.js.map +1 -1
- package/theme/tokens/border.d.ts +9 -3
- package/theme/tokens/border.js.map +1 -1
- package/theme/tokens/breakpoint.js.map +1 -1
- package/theme/tokens/colour.d.ts +9 -3
- package/theme/tokens/colour.js.map +1 -1
- package/theme/tokens/component.d.ts +3 -1
- package/theme/tokens/component.js.map +1 -1
- package/theme/tokens/font.d.ts +6 -2
- package/theme/tokens/font.js.map +1 -1
- package/theme/tokens/media-query.d.ts +3 -1
- package/theme/tokens/media-query.js.map +1 -1
- package/theme/tokens/motion.d.ts +3 -1
- package/theme/tokens/motion.js.map +1 -1
- package/theme/tokens/radius.d.ts +3 -1
- package/theme/tokens/radius.js.map +1 -1
- package/theme/tokens/shadow.d.ts +3 -1
- package/theme/tokens/shadow.js.map +1 -1
- package/theme/tokens/spacing.d.ts +3 -1
- package/theme/tokens/spacing.js.map +1 -1
- package/theme/utils/use-apply-styles.js.map +1 -1
- package/theme/utils/use-design-token.js.map +1 -1
- package/theme/utils/use-media-query.js.map +1 -1
- package/time-range-picker/combobox-picker/combobox-picker.js +1 -1
- package/time-range-picker/combobox-picker/combobox-picker.js.map +1 -1
- package/time-range-picker/time-range-picker.js.map +1 -1
- package/time-range-picker/types.d.ts +1 -1
- package/time-slot-bar/time-slot-bar.js.map +1 -1
- package/time-slot-bar/types.d.ts +5 -1
- package/time-slot-bar-week/time-slot-bar-week.js.map +1 -1
- package/time-slot-bar-week/types.d.ts +6 -0
- package/time-slot-week-view/time-slot-week-view.js.map +1 -1
- package/time-slot-week-view/types.d.ts +2 -0
- package/timeline/timeline.js.map +1 -1
- package/timeline/types.d.ts +1 -1
- package/timepicker/timepicker.js.map +1 -1
- package/timepicker/types.d.ts +2 -2
- package/timetable/timetable.js.map +1 -1
- package/toast/toast.js.map +1 -1
- package/toast/toast.styles.js +1 -1
- package/toast/toast.styles.js.map +1 -1
- package/{cjs/toast/toast.styles_1e0l60w.css → toast/toast.styles_57j3lf.css} +1 -1
- package/toast/types.d.ts +2 -0
- package/toggle/toggle.js.map +1 -1
- package/tools/shared/generated-file-formatter.d.ts +6 -0
- package/tools/shared/jsdoc-parser.d.ts +36 -0
- package/tools/shared/ts-morph-project-factory.d.ts +9 -0
- package/tools/shared/typescript-source-provider.d.ts +9 -0
- package/tools/storybook-argtypes/adapters/file-system-adapter.d.ts +69 -0
- package/tools/storybook-argtypes/arg-types-generator.d.ts +85 -0
- package/tools/storybook-argtypes/config/arg-types-config.d.ts +31 -0
- package/tools/storybook-argtypes/index.d.ts +11 -0
- package/tools/storybook-argtypes/services/arg-types-row-builder.d.ts +49 -0
- package/tools/storybook-argtypes/services/file-path-resolver.d.ts +118 -0
- package/tools/storybook-argtypes/services/index.d.ts +6 -0
- package/tools/storybook-argtypes/services/jsdoc-metadata-extractor.d.ts +33 -0
- package/tools/storybook-argtypes/services/story-registry-generator.d.ts +27 -0
- package/tools/storybook-argtypes/services/type-dependency-resolver.d.ts +46 -0
- package/tools/storybook-argtypes/services/type-formatting-service.d.ts +27 -0
- package/tools/storybook-argtypes/types.d.ts +114 -0
- package/typography/index.js.map +1 -1
- package/uneditable-section/index.js.map +1 -1
- package/uneditable-section/section-item.js +1 -1
- package/uneditable-section/section-item.js.map +1 -1
- package/uneditable-section/types.d.ts +2 -2
- package/unit-number/unit-number-input.js.map +1 -1
- package/button/button.styles_1pxy0co.css +0 -20
- package/cjs/button/button.styles_1pxy0co.css +0 -20
- package/cjs/form/form-custom-field.js +0 -2
- package/cjs/form/form-custom-field.js.map +0 -1
- package/cjs/form/form-date-input.js +0 -2
- package/cjs/form/form-date-input.js.map +0 -1
- package/cjs/form/form-date-range-input.js +0 -2
- package/cjs/form/form-date-range-input.js.map +0 -1
- package/cjs/form/form-e-signature.js +0 -2
- package/cjs/form/form-e-signature.js.map +0 -1
- package/cjs/form/form-histogram.js +0 -2
- package/cjs/form/form-histogram.js.map +0 -1
- package/cjs/form/form-input-group.js +0 -2
- package/cjs/form/form-input-group.js.map +0 -1
- package/cjs/form/form-input.js +0 -2
- package/cjs/form/form-input.js.map +0 -1
- package/cjs/form/form-label-addon.js +0 -2
- package/cjs/form/form-label-addon.js.map +0 -1
- package/cjs/form/form-label-addon.styles.js +0 -2
- package/cjs/form/form-label-addon.styles.js.map +0 -1
- package/cjs/form/form-label-addon.styles_b00z8p.css +0 -1
- package/cjs/form/form-label.js +0 -2
- package/cjs/form/form-label.js.map +0 -1
- package/cjs/form/form-label.styles.js +0 -2
- package/cjs/form/form-label.styles.js.map +0 -1
- package/cjs/form/form-label.styles_1nbe0bm.css +0 -6
- package/cjs/form/form-masked-input.js +0 -2
- package/cjs/form/form-masked-input.js.map +0 -1
- package/cjs/form/form-multi-select.js +0 -2
- package/cjs/form/form-multi-select.js.map +0 -1
- package/cjs/form/form-nested-multi-select.js +0 -2
- package/cjs/form/form-nested-multi-select.js.map +0 -1
- package/cjs/form/form-nested-select.js +0 -2
- package/cjs/form/form-nested-select.js.map +0 -1
- package/cjs/form/form-otp-verification.js +0 -2
- package/cjs/form/form-otp-verification.js.map +0 -1
- package/cjs/form/form-phone-number-input.js +0 -2
- package/cjs/form/form-phone-number-input.js.map +0 -1
- package/cjs/form/form-predictive-text-input.js +0 -2
- package/cjs/form/form-predictive-text-input.js.map +0 -1
- package/cjs/form/form-range-select.js +0 -2
- package/cjs/form/form-range-select.js.map +0 -1
- package/cjs/form/form-range-slider.js +0 -2
- package/cjs/form/form-range-slider.js.map +0 -1
- package/cjs/form/form-select-histogram.js +0 -2
- package/cjs/form/form-select-histogram.js.map +0 -1
- package/cjs/form/form-select.js +0 -2
- package/cjs/form/form-select.js.map +0 -1
- package/cjs/form/form-slider.js +0 -2
- package/cjs/form/form-slider.js.map +0 -1
- package/cjs/form/form-textarea.js +0 -2
- package/cjs/form/form-textarea.js.map +0 -1
- package/cjs/form/form-textarea.styles.js +0 -2
- package/cjs/form/form-textarea.styles.js.map +0 -1
- package/cjs/form/form-textarea.styles_3p9qoy.css +0 -3
- package/cjs/form/form-time-range-picker.js +0 -2
- package/cjs/form/form-time-range-picker.js.map +0 -1
- package/cjs/form/form-timepicker.js +0 -2
- package/cjs/form/form-timepicker.js.map +0 -1
- package/cjs/form/form-unit-number-input.js +0 -2
- package/cjs/form/form-unit-number-input.js.map +0 -1
- package/form/form-custom-field.js +0 -2
- package/form/form-custom-field.js.map +0 -1
- package/form/form-date-input.js +0 -2
- package/form/form-date-input.js.map +0 -1
- package/form/form-date-range-input.js +0 -2
- package/form/form-date-range-input.js.map +0 -1
- package/form/form-e-signature.js +0 -2
- package/form/form-e-signature.js.map +0 -1
- package/form/form-histogram.js +0 -2
- package/form/form-histogram.js.map +0 -1
- package/form/form-input-group.js +0 -2
- package/form/form-input-group.js.map +0 -1
- package/form/form-input.js +0 -2
- package/form/form-input.js.map +0 -1
- package/form/form-label-addon.js +0 -2
- package/form/form-label-addon.js.map +0 -1
- package/form/form-label-addon.styles.js +0 -2
- package/form/form-label-addon.styles.js.map +0 -1
- package/form/form-label-addon.styles_b00z8p.css +0 -1
- package/form/form-label.js +0 -2
- package/form/form-label.js.map +0 -1
- package/form/form-label.styles.js +0 -2
- package/form/form-label.styles.js.map +0 -1
- package/form/form-label.styles_1nbe0bm.css +0 -6
- package/form/form-masked-input.js +0 -2
- package/form/form-masked-input.js.map +0 -1
- package/form/form-multi-select.js +0 -2
- package/form/form-multi-select.js.map +0 -1
- package/form/form-nested-multi-select.js +0 -2
- package/form/form-nested-multi-select.js.map +0 -1
- package/form/form-nested-select.js +0 -2
- package/form/form-nested-select.js.map +0 -1
- package/form/form-otp-verification.js +0 -2
- package/form/form-otp-verification.js.map +0 -1
- package/form/form-phone-number-input.js +0 -2
- package/form/form-phone-number-input.js.map +0 -1
- package/form/form-predictive-text-input.js +0 -2
- package/form/form-predictive-text-input.js.map +0 -1
- package/form/form-range-select.js +0 -2
- package/form/form-range-select.js.map +0 -1
- package/form/form-range-slider.js +0 -2
- package/form/form-range-slider.js.map +0 -1
- package/form/form-select-histogram.js +0 -2
- package/form/form-select-histogram.js.map +0 -1
- package/form/form-select.js +0 -2
- package/form/form-select.js.map +0 -1
- package/form/form-slider.js +0 -2
- package/form/form-slider.js.map +0 -1
- package/form/form-textarea.js +0 -2
- package/form/form-textarea.js.map +0 -1
- package/form/form-textarea.styles.js +0 -2
- package/form/form-textarea.styles.js.map +0 -1
- package/form/form-textarea.styles_3p9qoy.css +0 -3
- package/form/form-time-range-picker.js +0 -2
- package/form/form-time-range-picker.js.map +0 -1
- package/form/form-timepicker.js +0 -2
- package/form/form-timepicker.js.map +0 -1
- package/form/form-unit-number-input.js +0 -2
- package/form/form-unit-number-input.js.map +0 -1
- package/link-list/internal-types.d.ts +0 -85
- /package/{codemod-utils.d.ts → codemods/codemod-utils.d.ts} +0 -0
- /package/{migrate-popover → codemods/migrate-popover}/index.d.ts +0 -0
- /package/{run-codemod.d.ts → codemods/run-codemod.d.ts} +0 -0
- /package/form/{form-custom-field.d.ts → form-custom-field/form-custom-field.d.ts} +0 -0
- /package/form/{form-date-input.d.ts → form-date-input/form-date-input.d.ts} +0 -0
- /package/form/{form-date-range-input.d.ts → form-date-range-input/form-date-range-input.d.ts} +0 -0
- /package/form/{form-e-signature.d.ts → form-e-signature/form-e-signature.d.ts} +0 -0
- /package/form/{form-histogram.d.ts → form-histogram-slider/form-histogram-slider.d.ts} +0 -0
- /package/form/{form-input.d.ts → form-input/form-input.d.ts} +0 -0
- /package/form/{form-input-group.d.ts → form-input-group/form-input-group.d.ts} +0 -0
- /package/form/{form-label-addon.d.ts → form-label/form-label-addon.d.ts} +0 -0
- /package/form/{form-label-addon.styles.d.ts → form-label/form-label-addon.styles.d.ts} +0 -0
- /package/form/{form-label.d.ts → form-label/form-label.d.ts} +0 -0
- /package/form/{form-label.styles.d.ts → form-label/form-label.styles.d.ts} +0 -0
- /package/form/{form-masked-input.d.ts → form-masked-input/form-masked-input.d.ts} +0 -0
- /package/form/{form-multi-select.d.ts → form-multi-select/form-multi-select.d.ts} +0 -0
- /package/form/{form-nested-multi-select.d.ts → form-nested-multi-select/form-nested-multi-select.d.ts} +0 -0
- /package/form/{form-nested-select.d.ts → form-nested-select/form-nested-select.d.ts} +0 -0
- /package/form/{form-phone-number-input.d.ts → form-phone-number-input/form-phone-number-input.d.ts} +0 -0
- /package/form/{form-predictive-text-input.d.ts → form-predictive-text-input/form-predictive-text-input.d.ts} +0 -0
- /package/form/{form-range-select.d.ts → form-range-select/form-range-select.d.ts} +0 -0
- /package/form/{form-range-slider.d.ts → form-range-slider/form-range-slider.d.ts} +0 -0
- /package/form/{form-select.d.ts → form-select/form-select.d.ts} +0 -0
- /package/form/{form-select-histogram.d.ts → form-select-histogram/form-select-histogram.d.ts} +0 -0
- /package/form/{form-slider.d.ts → form-slider/form-slider.d.ts} +0 -0
- /package/form/{form-textarea.d.ts → form-textarea/form-textarea.d.ts} +0 -0
- /package/form/{form-textarea.styles.d.ts → form-textarea/form-textarea.styles.d.ts} +0 -0
- /package/form/{form-time-range-picker.d.ts → form-time-range-picker/form-time-range-picker.d.ts} +0 -0
- /package/form/{form-timepicker.d.ts → form-timepicker/form-timepicker.d.ts} +0 -0
- /package/form/{form-unit-number-input.d.ts → form-unit-number-input/form-unit-number-input.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"font.js","sources":["../../../../src/theme/tokens/font.ts"],"sourcesContent":["import { generateFont } from \"../utils/font\";\n\n
|
|
1
|
+
{"version":3,"file":"font.js","sources":["../../../../src/theme/tokens/font.ts"],"sourcesContent":["import { generateFont } from \"../utils/font\";\n\n/**\n * Raw font CSS variable tokens.\n */\nexport const FontSpec = {\n \"font-family-heading\": \"var(--fds-font-family-heading)\",\n \"font-family-body\": \"var(--fds-font-family-body)\",\n \"font-variant\": \"var(--fds-font-variant)\",\n\n \"weight-light\": \"var(--fds-font-weight-light)\",\n \"weight-regular\": \"var(--fds-font-weight-regular)\",\n \"weight-semibold\": \"var(--fds-font-weight-semibold)\",\n \"weight-bold\": \"var(--fds-font-weight-bold)\",\n\n \"heading-size-xxl\": \"var(--fds-font-heading-size-xxl)\",\n \"heading-size-xl\": \"var(--fds-font-heading-size-xl)\",\n \"heading-size-lg\": \"var(--fds-font-heading-size-lg)\",\n \"heading-size-md\": \"var(--fds-font-heading-size-md)\",\n \"heading-size-sm\": \"var(--fds-font-heading-size-sm)\",\n \"heading-size-xs\": \"var(--fds-font-heading-size-xs)\",\n\n \"heading-lh-xxl\": \"var(--fds-font-heading-lh-xxl)\",\n \"heading-lh-xl\": \"var(--fds-font-heading-lh-xl)\",\n \"heading-lh-lg\": \"var(--fds-font-heading-lh-lg)\",\n \"heading-lh-md\": \"var(--fds-font-heading-lh-md)\",\n \"heading-lh-sm\": \"var(--fds-font-heading-lh-sm)\",\n \"heading-lh-xs\": \"var(--fds-font-heading-lh-xs)\",\n\n \"heading-ls-xxl\": \"var(--fds-font-heading-ls-xxl)\",\n \"heading-ls-xl\": \"var(--fds-font-heading-ls-xl)\",\n \"heading-ls-lg\": \"var(--fds-font-heading-ls-lg)\",\n \"heading-ls-md\": \"var(--fds-font-heading-ls-md)\",\n \"heading-ls-sm\": \"var(--fds-font-heading-ls-sm)\",\n \"heading-ls-xs\": \"var(--fds-font-heading-ls-xs)\",\n\n \"body-size-baseline\": \"var(--fds-font-body-size-baseline)\",\n \"body-size-md\": \"var(--fds-font-body-size-md)\",\n \"body-size-sm\": \"var(--fds-font-body-size-sm)\",\n \"body-size-xs\": \"var(--fds-font-body-size-xs)\",\n\n \"body-lh-baseline\": \"var(--fds-font-body-lh-baseline)\",\n \"body-lh-md\": \"var(--fds-font-body-lh-md)\",\n \"body-lh-sm\": \"var(--fds-font-body-lh-sm)\",\n \"body-lh-xs\": \"var(--fds-font-body-lh-xs)\",\n\n \"body-ls-baseline\": \"var(--fds-font-body-ls-baseline)\",\n \"body-ls-md\": \"var(--fds-font-body-ls-md)\",\n \"body-ls-sm\": \"var(--fds-font-body-ls-sm)\",\n \"body-ls-xs\": \"var(--fds-font-body-ls-xs)\",\n\n \"form-label-size\": \"var(--fds-font-form-label-size)\",\n \"form-label-lh\": \"var(--fds-font-form-label-lh)\",\n \"form-label-ls\": \"var(--fds-font-form-label-ls)\",\n\n \"form-description-size\": \"var(--fds-font-form-description-size)\",\n \"form-description-lh\": \"var(--fds-font-form-description-lh)\",\n \"form-description-ls\": \"var(--fds-font-form-description-ls)\",\n} as const;\n\n// @catalog\n/**\n * Pre-composed font declaration strings for all size & weight combinations.\n */\nexport const Font = {\n \"heading-xxl-light\": generateFont(\"heading-xxl\", \"light\"),\n \"heading-xxl-regular\": generateFont(\"heading-xxl\", \"regular\"),\n \"heading-xxl-semibold\": generateFont(\"heading-xxl\", \"semibold\"),\n \"heading-xxl-bold\": generateFont(\"heading-xxl\", \"bold\"),\n\n \"heading-xl-light\": generateFont(\"heading-xl\", \"light\"),\n \"heading-xl-regular\": generateFont(\"heading-xl\", \"regular\"),\n \"heading-xl-semibold\": generateFont(\"heading-xl\", \"semibold\"),\n \"heading-xl-bold\": generateFont(\"heading-xl\", \"bold\"),\n\n \"heading-lg-light\": generateFont(\"heading-lg\", \"light\"),\n \"heading-lg-regular\": generateFont(\"heading-lg\", \"regular\"),\n \"heading-lg-semibold\": generateFont(\"heading-lg\", \"semibold\"),\n \"heading-lg-bold\": generateFont(\"heading-lg\", \"bold\"),\n\n \"heading-md-light\": generateFont(\"heading-md\", \"light\"),\n \"heading-md-regular\": generateFont(\"heading-md\", \"regular\"),\n \"heading-md-semibold\": generateFont(\"heading-md\", \"semibold\"),\n \"heading-md-bold\": generateFont(\"heading-md\", \"bold\"),\n\n \"heading-sm-light\": generateFont(\"heading-sm\", \"light\"),\n \"heading-sm-regular\": generateFont(\"heading-sm\", \"regular\"),\n \"heading-sm-semibold\": generateFont(\"heading-sm\", \"semibold\"),\n \"heading-sm-bold\": generateFont(\"heading-sm\", \"bold\"),\n\n \"heading-xs-light\": generateFont(\"heading-xs\", \"light\"),\n \"heading-xs-regular\": generateFont(\"heading-xs\", \"regular\"),\n \"heading-xs-semibold\": generateFont(\"heading-xs\", \"semibold\"),\n \"heading-xs-bold\": generateFont(\"heading-xs\", \"bold\"),\n\n \"body-baseline-light\": generateFont(\"body-baseline\", \"light\"),\n \"body-baseline-regular\": generateFont(\"body-baseline\", \"regular\"),\n \"body-baseline-semibold\": generateFont(\"body-baseline\", \"semibold\"),\n \"body-baseline-bold\": generateFont(\"body-baseline\", \"bold\"),\n\n \"body-md-light\": generateFont(\"body-md\", \"light\"),\n \"body-md-regular\": generateFont(\"body-md\", \"regular\"),\n \"body-md-semibold\": generateFont(\"body-md\", \"semibold\"),\n \"body-md-bold\": generateFont(\"body-md\", \"bold\"),\n\n \"body-sm-light\": generateFont(\"body-sm\", \"light\"),\n \"body-sm-regular\": generateFont(\"body-sm\", \"regular\"),\n \"body-sm-semibold\": generateFont(\"body-sm\", \"semibold\"),\n \"body-sm-bold\": generateFont(\"body-sm\", \"bold\"),\n\n \"body-xs-light\": generateFont(\"body-xs\", \"light\"),\n \"body-xs-regular\": generateFont(\"body-xs\", \"regular\"),\n \"body-xs-semibold\": generateFont(\"body-xs\", \"semibold\"),\n \"body-xs-bold\": generateFont(\"body-xs\", \"bold\"),\n\n \"form-label\": generateFont(\"form-label\", \"semibold\"),\n \"form-description\": generateFont(\"form-description\", \"regular\"),\n\n Spec: FontSpec,\n} as const;\n"],"names":["FontSpec","Font","generateFont","Spec"],"mappings":"+CAKO,MAAMA,EAAW,CACpB,sBAAuB,iCACvB,mBAAoB,8BACpB,eAAgB,0BAEhB,eAAgB,+BAChB,iBAAkB,iCAClB,kBAAmB,kCACnB,cAAe,8BAEf,mBAAoB,mCACpB,kBAAmB,kCACnB,kBAAmB,kCACnB,kBAAmB,kCACnB,kBAAmB,kCACnB,kBAAmB,kCAEnB,iBAAkB,iCAClB,gBAAiB,gCACjB,gBAAiB,gCACjB,gBAAiB,gCACjB,gBAAiB,gCACjB,gBAAiB,gCAEjB,iBAAkB,iCAClB,gBAAiB,gCACjB,gBAAiB,gCACjB,gBAAiB,gCACjB,gBAAiB,gCACjB,gBAAiB,gCAEjB,qBAAsB,qCACtB,eAAgB,+BAChB,eAAgB,+BAChB,eAAgB,+BAEhB,mBAAoB,mCACpB,aAAc,6BACd,aAAc,6BACd,aAAc,6BAEd,mBAAoB,mCACpB,aAAc,6BACd,aAAc,6BACd,aAAc,6BAEd,kBAAmB,kCACnB,gBAAiB,gCACjB,gBAAiB,gCAEjB,wBAAyB,wCACzB,sBAAuB,sCACvB,sBAAuB,uCAOdC,EAAO,CAChB,oBAAqBC,EAAAA,aAAa,cAAe,SACjD,sBAAuBA,EAAAA,aAAa,cAAe,WACnD,uBAAwBA,EAAAA,aAAa,cAAe,YACpD,mBAAoBA,EAAAA,aAAa,cAAe,QAEhD,mBAAoBA,EAAAA,aAAa,aAAc,SAC/C,qBAAsBA,EAAAA,aAAa,aAAc,WACjD,sBAAuBA,EAAAA,aAAa,aAAc,YAClD,kBAAmBA,EAAAA,aAAa,aAAc,QAE9C,mBAAoBA,EAAAA,aAAa,aAAc,SAC/C,qBAAsBA,EAAAA,aAAa,aAAc,WACjD,sBAAuBA,EAAAA,aAAa,aAAc,YAClD,kBAAmBA,EAAAA,aAAa,aAAc,QAE9C,mBAAoBA,EAAAA,aAAa,aAAc,SAC/C,qBAAsBA,EAAAA,aAAa,aAAc,WACjD,sBAAuBA,EAAAA,aAAa,aAAc,YAClD,kBAAmBA,EAAAA,aAAa,aAAc,QAE9C,mBAAoBA,EAAAA,aAAa,aAAc,SAC/C,qBAAsBA,EAAAA,aAAa,aAAc,WACjD,sBAAuBA,EAAAA,aAAa,aAAc,YAClD,kBAAmBA,EAAAA,aAAa,aAAc,QAE9C,mBAAoBA,EAAAA,aAAa,aAAc,SAC/C,qBAAsBA,EAAAA,aAAa,aAAc,WACjD,sBAAuBA,EAAAA,aAAa,aAAc,YAClD,kBAAmBA,EAAAA,aAAa,aAAc,QAE9C,sBAAuBA,EAAAA,aAAa,gBAAiB,SACrD,wBAAyBA,EAAAA,aAAa,gBAAiB,WACvD,yBAA0BA,EAAAA,aAAa,gBAAiB,YACxD,qBAAsBA,EAAAA,aAAa,gBAAiB,QAEpD,gBAAiBA,EAAAA,aAAa,UAAW,SACzC,kBAAmBA,EAAAA,aAAa,UAAW,WAC3C,mBAAoBA,EAAAA,aAAa,UAAW,YAC5C,eAAgBA,EAAAA,aAAa,UAAW,QAExC,gBAAiBA,EAAAA,aAAa,UAAW,SACzC,kBAAmBA,EAAAA,aAAa,UAAW,WAC3C,mBAAoBA,EAAAA,aAAa,UAAW,YAC5C,eAAgBA,EAAAA,aAAa,UAAW,QAExC,gBAAiBA,EAAAA,aAAa,UAAW,SACzC,kBAAmBA,EAAAA,aAAa,UAAW,WAC3C,mBAAoBA,EAAAA,aAAa,UAAW,YAC5C,eAAgBA,EAAAA,aAAa,UAAW,QAExC,aAAcA,EAAAA,aAAa,aAAc,YACzC,mBAAoBA,EAAAA,aAAa,mBAAoB,WAErDC,KAAMH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media-query.js","sources":["../../../../src/theme/tokens/media-query.ts"],"sourcesContent":["const MAX_WIDTH_BREAKPOINTS = [\"xxs\", \"xs\", \"sm\", \"md\", \"lg\", \"xl\"] as const;\nconst MIN_WIDTH_BREAKPOINTS = [...MAX_WIDTH_BREAKPOINTS, \"xxl\"] as const;\n\ntype WidthConstraint = \"min\" | \"max\";\ntype PseudoMediaQuerySpec<T extends readonly string[]> = Record<\n T[number],\n string\n>;\n\nconst getPseudoMediaQuery = (breakpoint: string, type: WidthConstraint) =>\n `:where(body.fds-breakpoint-${breakpoint}-${type}) &`;\n\nconst getPseudoMediaQuerySpec = <T extends readonly string[]>(\n breakpoints: T,\n type: WidthConstraint\n): PseudoMediaQuerySpec<T> => {\n const spec = {} as Record<T[number], string>;\n\n breakpoints.forEach((breakpoint) => {\n spec[breakpoint as T[number]] = getPseudoMediaQuery(breakpoint, type);\n });\n\n return spec;\n};\n\n
|
|
1
|
+
{"version":3,"file":"media-query.js","sources":["../../../../src/theme/tokens/media-query.ts"],"sourcesContent":["const MAX_WIDTH_BREAKPOINTS = [\"xxs\", \"xs\", \"sm\", \"md\", \"lg\", \"xl\"] as const;\nconst MIN_WIDTH_BREAKPOINTS = [...MAX_WIDTH_BREAKPOINTS, \"xxl\"] as const;\n\ntype WidthConstraint = \"min\" | \"max\";\ntype PseudoMediaQuerySpec<T extends readonly string[]> = Record<\n T[number],\n string\n>;\n\nconst getPseudoMediaQuery = (breakpoint: string, type: WidthConstraint) =>\n `:where(body.fds-breakpoint-${breakpoint}-${type}) &`;\n\nconst getPseudoMediaQuerySpec = <T extends readonly string[]>(\n breakpoints: T,\n type: WidthConstraint\n): PseudoMediaQuerySpec<T> => {\n const spec = {} as Record<T[number], string>;\n\n breakpoints.forEach((breakpoint) => {\n spec[breakpoint as T[number]] = getPseudoMediaQuery(breakpoint, type);\n });\n\n return spec;\n};\n\n// @catalog\n/**\n * CSS class-based pseudo media-query selectors keyed by breakpoint name.\n */\nexport const MediaQuery = {\n MaxWidth: getPseudoMediaQuerySpec(MAX_WIDTH_BREAKPOINTS, \"max\"),\n MinWidth: getPseudoMediaQuerySpec(MIN_WIDTH_BREAKPOINTS, \"min\"),\n} as const;\n"],"names":["MAX_WIDTH_BREAKPOINTS","MIN_WIDTH_BREAKPOINTS","getPseudoMediaQuerySpec","breakpoints","type","spec","forEach","breakpoint","getPseudoMediaQuery","MediaQuery","MaxWidth","MinWidth"],"mappings":"aAAA,MAAMA,EAAwB,CAAC,MAAO,KAAM,KAAM,KAAM,KAAM,MACxDC,EAAwB,IAAID,EAAuB,OAWnDE,EAA0B,CAC5BC,EACAC,KAEA,MAAMC,EAAO,CAAA,EAMb,OAJAF,EAAYG,SAASC,IACjBF,EAAKE,GAVe,EAACA,EAAoBH,IAC7C,8BAA8BG,KAAcH,OASRI,CAAoBD,EAAYH,EAAK,IAGlEC,CAAI,EAOFI,EAAa,CACtBC,SAAUR,EAAwBF,EAAuB,OACzDW,SAAUT,EAAwBD,EAAuB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"motion.js","sources":["../../../../src/theme/tokens/motion.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"motion.js","sources":["../../../../src/theme/tokens/motion.ts"],"sourcesContent":["// @catalog\n/**\n * Animation tokens consisting of durations and easing functions.\n */\nexport const Motion = {\n \"duration-150\": \"var(--fds-motion-duration-150)\",\n \"duration-250\": \"var(--fds-motion-duration-250)\",\n \"duration-350\": \"var(--fds-motion-duration-350)\",\n \"duration-500\": \"var(--fds-motion-duration-500)\",\n \"duration-800\": \"var(--fds-motion-duration-800)\",\n \"duration-1000\": \"var(--fds-motion-duration-1000)\",\n\n \"ease-default\": \"var(--fds-motion-timing-ease-default)\",\n \"ease-standard\": \"var(--fds-motion-timing-ease-standard)\",\n \"ease-entrance\": \"var(--fds-motion-timing-ease-entrance)\",\n \"ease-exit\": \"var(--fds-motion-timing-ease-exit)\",\n} as const;\n"],"names":[],"mappings":"4BAIsB,CAClB,eAAgB,iCAChB,eAAgB,iCAChB,eAAgB,iCAChB,eAAgB,iCAChB,eAAgB,iCAChB,gBAAiB,kCAEjB,eAAgB,wCAChB,gBAAiB,yCACjB,gBAAiB,yCACjB,YAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radius.js","sources":["../../../../src/theme/tokens/radius.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"radius.js","sources":["../../../../src/theme/tokens/radius.ts"],"sourcesContent":["// @catalog\n/**\n * Border radius tokens.\n */\nexport const Radius = {\n none: \"var(--fds-radius-none)\",\n xs: \"var(--fds-radius-xs)\",\n sm: \"var(--fds-radius-sm)\",\n md: \"var(--fds-radius-md)\",\n lg: \"var(--fds-radius-lg)\",\n full: \"var(--fds-radius-full)\",\n} as const;\n"],"names":["none","xs","sm","md","lg","full"],"mappings":"4BAIsB,CAClBA,KAAM,yBACNC,GAAI,uBACJC,GAAI,uBACJC,GAAI,uBACJC,GAAI,uBACJC,KAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow.js","sources":["../../../../src/theme/tokens/shadow.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"shadow.js","sources":["../../../../src/theme/tokens/shadow.ts"],"sourcesContent":["// @catalog\n/**\n * Box-shadow tokens.\n */\nexport const Shadow = {\n \"xs-subtle\": \"var(--fds-shadow-xs-subtle)\",\n \"xs-strong\": \"var(--fds-shadow-xs-strong)\",\n \"xs-focus-strong\": \"var(--fds-shadow-xs-focus-strong)\",\n \"xs-error-strong\": \"var(--fds-shadow-xs-error-strong)\",\n \"sm-subtle\": \"var(--fds-shadow-sm-subtle)\",\n \"sm-strong\": \"var(--fds-shadow-sm-strong)\",\n \"md-subtle\": \"var(--fds-shadow-md-subtle)\",\n \"md-strong\": \"var(--fds-shadow-md-strong)\",\n \"lg-subtle\": \"var(--fds-shadow-lg-subtle)\",\n \"lg-strong\": \"var(--fds-shadow-lg-strong)\",\n} as const;\n"],"names":[],"mappings":"4BAIsB,CAClB,YAAa,8BACb,YAAa,8BACb,kBAAmB,oCACnB,kBAAmB,oCACnB,YAAa,8BACb,YAAa,8BACb,YAAa,8BACb,YAAa,8BACb,YAAa,8BACb,YAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spacing.js","sources":["../../../../src/theme/tokens/spacing.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"spacing.js","sources":["../../../../src/theme/tokens/spacing.ts"],"sourcesContent":["// @catalog\n/**\n * Spacing tokens consisting of component spacing and layout spacing.\n */\nexport const Spacing = {\n \"spacing-0\": \"var(--fds-spacing-0)\",\n \"spacing-4\": \"var(--fds-spacing-4)\",\n \"spacing-8\": \"var(--fds-spacing-8)\",\n \"spacing-12\": \"var(--fds-spacing-12)\",\n \"spacing-16\": \"var(--fds-spacing-16)\",\n \"spacing-20\": \"var(--fds-spacing-20)\",\n \"spacing-24\": \"var(--fds-spacing-24)\",\n \"spacing-32\": \"var(--fds-spacing-32)\",\n \"spacing-40\": \"var(--fds-spacing-40)\",\n \"spacing-48\": \"var(--fds-spacing-48)\",\n \"spacing-64\": \"var(--fds-spacing-64)\",\n \"spacing-72\": \"var(--fds-spacing-72)\",\n\n \"layout-xs\": \"var(--fds-layout-xs)\",\n \"layout-sm\": \"var(--fds-layout-sm)\",\n \"layout-md\": \"var(--fds-layout-md)\",\n \"layout-lg\": \"var(--fds-layout-lg)\",\n \"layout-xl\": \"var(--fds-layout-xl)\",\n \"layout-xxl\": \"var(--fds-layout-xxl)\",\n \"layout-xxxl\": \"var(--fds-layout-xxxl)\",\n} as const;\n"],"names":[],"mappings":"6BAIuB,CACnB,YAAa,uBACb,YAAa,uBACb,YAAa,uBACb,aAAc,wBACd,aAAc,wBACd,aAAc,wBACd,aAAc,wBACd,aAAc,wBACd,aAAc,wBACd,aAAc,wBACd,aAAc,wBACd,aAAc,wBAEd,YAAa,uBACb,YAAa,uBACb,YAAa,uBACb,YAAa,uBACb,YAAa,uBACb,aAAc,wBACd,cAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-apply-styles.js","sources":["../../../../src/theme/utils/use-apply-styles.ts"],"sourcesContent":["import type { CSSProperties, RefObject } from \"react\";\n\nimport { useIsomorphicLayoutEffect } from \"../../util\";\nimport type { CSSVariableString } from \"../types\";\n\ntype StyleValue = string | number | null | undefined;\n\ntype ExtractCleanCSSVariableName<T extends string> =\n T extends `var(${infer Name})` ? Name : never;\ntype CSSVariableKey = ExtractCleanCSSVariableName<CSSVariableString>;\n\n/**\n * Style map accepted by `useApplyStyle`. Supports camelCase CSS properties,\n * theme CSS variable keys, and arbitrary `--custom-property` names.\n */\nexport type ApplyStyleMap =\n | ({\n [K in keyof CSSStyleDeclaration]?: StyleValue;\n } & {\n [K in CSSVariableKey]?: StyleValue;\n } & {\n [K in `--${string}`]?: StyleValue;\n })\n | CSSProperties;\n\n/**\n * List of properties that expect units but can be provided as\n * numbers through React style prop\n */\nconst numericCssStyleProperties: Set<keyof CSSStyleDeclaration> = new Set([\n \"width\",\n \"height\",\n \"top\",\n \"left\",\n \"right\",\n \"bottom\",\n \"margin\",\n \"marginTop\",\n \"marginLeft\",\n \"marginRight\",\n \"marginBottom\",\n \"padding\",\n \"paddingTop\",\n \"paddingLeft\",\n \"paddingRight\",\n \"paddingBottom\",\n]);\n\n/**\n * Normalises standard CSS property names from camelCase to kebab-case\n * - `backgroundColor` → `background-color`\n * - `WebkitLineClamp` → `-webkit-line-clamp`\n * - `--custom-variable` → `--custom-variable`\n *\n * Ref\n * https://github.com/facebook/react/blob/ad5dfc82b7107728da1430dd142f75b97b684dac/packages/react-dom-bindings/src/shared/hyphenateStyleName.js#L26\n */\nfunction normaliseCssProperty(key: string): string {\n if (key.startsWith(\"--\")) return key;\n\n const kebabCased = key.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n\n if (/^(o|moz|ms|webkit)-/.test(kebabCased)) {\n return `-${kebabCased}`;\n }\n\n return kebabCased;\n}\n\nfunction normaliseCssValue(key: string, value: string | number): string {\n if (\n typeof value === \"number\" &&\n numericCssStyleProperties.has(key as keyof CSSStyleDeclaration)\n ) {\n return `${value}px`;\n }\n\n return String(value);\n}\n\n/**\n * Hook to apply styles to a HTML DOM element. Use when you need to apply inline\n * styles but cannot use the inline React `style` prop due to strict CSP rules.\n *\n * @param ref The HTML element to receive the styles\n * @param styles The styles to apply, in the same format as the React `style`\n * prop, or CSS variables. Values will be normalised to strings and numeric\n * values will have \"px\" appended for properties that typically require units.\n */\nexport function useApplyStyle<TElement extends HTMLElement>(\n ref: RefObject<TElement | null>,\n styles: ApplyStyleMap | undefined\n) {\n useIsomorphicLayoutEffect(() => {\n const element = ref?.current;\n if (!element || !styles) return;\n\n Object.entries(styles).forEach(([key, value]: [string, StyleValue]) => {\n const normalisedKey = normaliseCssProperty(key);\n\n if (value == null) {\n element.style.removeProperty(normalisedKey);\n return;\n }\n\n const normalisedValue = normaliseCssValue(key, value);\n element.style.setProperty(normalisedKey, normalisedValue);\n });\n }, [ref, styles]);\n}\n"],"names":["numericCssStyleProperties","Set","ref","styles","useIsomorphicLayoutEffect","element","current","Object","entries","forEach","key","value","normalisedKey","startsWith","kebabCased","replace","toLowerCase","test","normaliseCssProperty","style","removeProperty","normalisedValue","has","String","normaliseCssValue","setProperty"],"mappings":"0SA6BA,MAAMA,EAA4D,IAAIC,IAAI,CACtE,QACA,SACA,MACA,OACA,QACA,SACA,SACA,YACA,aACA,cACA,eACA,UACA,aACA,cACA,eACA,
|
|
1
|
+
{"version":3,"file":"use-apply-styles.js","sources":["../../../../src/theme/utils/use-apply-styles.ts"],"sourcesContent":["import type { CSSProperties, RefObject } from \"react\";\n\nimport { useIsomorphicLayoutEffect } from \"../../util\";\nimport type { CSSVariableString } from \"../types\";\n\ntype StyleValue = string | number | null | undefined;\n\ntype ExtractCleanCSSVariableName<T extends string> =\n T extends `var(${infer Name})` ? Name : never;\ntype CSSVariableKey = ExtractCleanCSSVariableName<CSSVariableString>;\n\n/**\n * Style map accepted by `useApplyStyle`. Supports camelCase CSS properties,\n * theme CSS variable keys, and arbitrary `--custom-property` names.\n */\nexport type ApplyStyleMap =\n | ({\n [K in keyof CSSStyleDeclaration]?: StyleValue;\n } & {\n [K in CSSVariableKey]?: StyleValue;\n } & {\n [K in `--${string}`]?: StyleValue;\n })\n | CSSProperties;\n\n/**\n * List of properties that expect units but can be provided as\n * numbers through React style prop\n */\nconst numericCssStyleProperties: Set<keyof CSSStyleDeclaration> = new Set([\n \"width\",\n \"height\",\n \"top\",\n \"left\",\n \"right\",\n \"bottom\",\n \"margin\",\n \"marginTop\",\n \"marginLeft\",\n \"marginRight\",\n \"marginBottom\",\n \"padding\",\n \"paddingTop\",\n \"paddingLeft\",\n \"paddingRight\",\n \"paddingBottom\",\n]);\n\n/**\n * Normalises standard CSS property names from camelCase to kebab-case\n * - `backgroundColor` → `background-color`\n * - `WebkitLineClamp` → `-webkit-line-clamp`\n * - `--custom-variable` → `--custom-variable`\n *\n * Ref\n * https://github.com/facebook/react/blob/ad5dfc82b7107728da1430dd142f75b97b684dac/packages/react-dom-bindings/src/shared/hyphenateStyleName.js#L26\n */\nfunction normaliseCssProperty(key: string): string {\n if (key.startsWith(\"--\")) return key;\n\n const kebabCased = key.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n\n if (/^(o|moz|ms|webkit)-/.test(kebabCased)) {\n return `-${kebabCased}`;\n }\n\n return kebabCased;\n}\n\nfunction normaliseCssValue(key: string, value: string | number): string {\n if (\n typeof value === \"number\" &&\n numericCssStyleProperties.has(key as keyof CSSStyleDeclaration)\n ) {\n return `${value}px`;\n }\n\n return String(value);\n}\n\n// @catalog\n/**\n * Hook to apply styles to a HTML DOM element. Use when you need to apply inline\n * styles but cannot use the inline React `style` prop due to strict CSP rules.\n *\n * @param ref The HTML element to receive the styles\n * @param styles The styles to apply, in the same format as the React `style`\n * prop, or CSS variables. Values will be normalised to strings and numeric\n * values will have \"px\" appended for properties that typically require units.\n */\nexport function useApplyStyle<TElement extends HTMLElement>(\n ref: RefObject<TElement | null>,\n styles: ApplyStyleMap | undefined\n) {\n useIsomorphicLayoutEffect(() => {\n const element = ref?.current;\n if (!element || !styles) return;\n\n Object.entries(styles).forEach(([key, value]: [string, StyleValue]) => {\n const normalisedKey = normaliseCssProperty(key);\n\n if (value == null) {\n element.style.removeProperty(normalisedKey);\n return;\n }\n\n const normalisedValue = normaliseCssValue(key, value);\n element.style.setProperty(normalisedKey, normalisedValue);\n });\n }, [ref, styles]);\n}\n"],"names":["numericCssStyleProperties","Set","ref","styles","useIsomorphicLayoutEffect","element","current","Object","entries","forEach","key","value","normalisedKey","startsWith","kebabCased","replace","toLowerCase","test","normaliseCssProperty","style","removeProperty","normalisedValue","has","String","normaliseCssValue","setProperty"],"mappings":"0SA6BA,MAAMA,EAA4D,IAAIC,IAAI,CACtE,QACA,SACA,MACA,OACA,QACA,SACA,SACA,YACA,aACA,cACA,eACA,UACA,aACA,cACA,eACA,wCA6CE,SACFC,EACAC,GAEAC,EAAAA,2BAA0B,KACtB,MAAMC,EAAUH,aAAG,EAAHA,EAAKI,QAChBD,GAAYF,GAEjBI,OAAOC,QAAQL,GAAQM,SAAQ,EAAEC,EAAKC,MAClC,MAAMC,EA1ClB,SAA8BF,GAC1B,GAAIA,EAAIG,WAAW,MAAO,OAAOH,EAEjC,MAAMI,EAAaJ,EAAIK,QAAQ,WAAY,OAAOC,cAElD,MAAI,sBAAsBC,KAAKH,GACpB,IAAIA,IAGRA,CACX,CAgCkCI,CAAqBR,GAE3C,GAAa,MAATC,EAEA,YADAN,EAAQc,MAAMC,eAAeR,GAIjC,MAAMS,EArClB,SAA2BX,EAAaC,GACpC,MACqB,iBAAVA,GACPX,EAA0BsB,IAAIZ,GAEvB,GAAGC,MAGPY,OAAOZ,EAClB,CA4BoCa,CAAkBd,EAAKC,GAC/CN,EAAQc,MAAMM,YAAYb,EAAeS,EAAgB,GAC3D,GACH,CAACnB,EAAKC,GACb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-design-token.js","sources":["../../../../src/theme/utils/use-design-token.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nimport { useTheme } from \"../theme-provider/hooks\";\nimport type { CSSVariableString } from \"../types\";\nimport { parseCSSVariableValue } from \"./css-variable\";\n\nconst isEmptyValue = (value: unknown) => {\n return value == null || value === \"\";\n};\n\n/**\n * Resolves a design-token CSS variable to its computed string value within the\n * nearest `ThemeProvider` scope.\n *\n * @param tokenName A `CSSVariableString` token (e.g. `Colour[\"text\"]`), or\n * `undefined` to skip resolution.\n * @returns The computed CSS value, or `undefined` when the provider has not yet\n * mounted or `tokenName` is `undefined`.\n */\nexport const useDesignToken = (\n tokenName: CSSVariableString | undefined\n): string | undefined => {\n const { theme, mode, themeElement } = useTheme();\n const [value, setValue] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n if (!themeElement) return;\n\n setValue(parseCSSVariableValue(tokenName, themeElement));\n }, [theme, mode, themeElement, tokenName]);\n\n return value;\n};\n\nexport interface UseResolvedTokenValueOptions<\n TToken extends CSSVariableString,\n TCustom\n> {\n /** Value used when `value` is empty. */\n fallback: TToken | TCustom;\n /** Type guard to identify token values. */\n isToken: (value: unknown) => value is TToken;\n /** Normalizer for non-token values. */\n normalizeCustom: (value: TCustom) => string;\n /** Candidate token or custom value. */\n value: TToken | TCustom | null | undefined;\n}\n\n/**\n * Resolves token-aware values with consistent fallback behavior.\n * - Empty values (`null`, `undefined`, `\"\"`) use `fallback`.\n * - Token values are resolved through `useDesignToken`.\n * - Non-token values are returned via `normalizeCustom`.\n * @param options Resolution options for token/custom values.\n * @returns Resolved token value or normalized custom/fallback value.\n */\nexport const useResolvedTokenValue = <\n TToken extends CSSVariableString,\n TCustom\n>(\n options: UseResolvedTokenValueOptions<TToken, TCustom>\n) => {\n const { value, fallback, isToken: checkToken, normalizeCustom } = options;\n const isToken = checkToken(value);\n const tokenName = isToken ? value : undefined;\n const resolvedToken = useDesignToken(tokenName);\n const isFallbackToken = checkToken(fallback);\n const fallbackTokenName = isFallbackToken ? fallback : undefined;\n const resolvedFallback = useDesignToken(fallbackTokenName);\n\n if (isToken && !isEmptyValue(resolvedToken)) {\n return resolvedToken;\n }\n\n if (!isToken && !isEmptyValue(value)) {\n return normalizeCustom(value);\n }\n\n if (isFallbackToken && !isEmptyValue(resolvedFallback)) {\n return resolvedFallback;\n }\n\n return normalizeCustom(fallback as TCustom);\n};\n"],"names":["isEmptyValue","value","useDesignToken","tokenName","theme","mode","themeElement","useTheme","setValue","useState","undefined","useEffect","parseCSSVariableValue","options","fallback","isToken","checkToken","normalizeCustom","resolvedToken","isFallbackToken","resolvedFallback"],"mappings":"2GAMA,MAAMA,EAAgBC,GACF,MAATA,GAA2B,KAAVA,
|
|
1
|
+
{"version":3,"file":"use-design-token.js","sources":["../../../../src/theme/utils/use-design-token.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nimport { useTheme } from \"../theme-provider/hooks\";\nimport type { CSSVariableString } from \"../types\";\nimport { parseCSSVariableValue } from \"./css-variable\";\n\nconst isEmptyValue = (value: unknown) => {\n return value == null || value === \"\";\n};\n\n// @catalog\n/**\n * Resolves a design-token CSS variable to its computed string value within the\n * nearest `ThemeProvider` scope.\n *\n * @param tokenName A `CSSVariableString` token (e.g. `Colour[\"text\"]`), or\n * `undefined` to skip resolution.\n * @returns The computed CSS value, or `undefined` when the provider has not yet\n * mounted or `tokenName` is `undefined`.\n */\nexport const useDesignToken = (\n tokenName: CSSVariableString | undefined\n): string | undefined => {\n const { theme, mode, themeElement } = useTheme();\n const [value, setValue] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n if (!themeElement) return;\n\n setValue(parseCSSVariableValue(tokenName, themeElement));\n }, [theme, mode, themeElement, tokenName]);\n\n return value;\n};\n\nexport interface UseResolvedTokenValueOptions<\n TToken extends CSSVariableString,\n TCustom\n> {\n /** Value used when `value` is empty. */\n fallback: TToken | TCustom;\n /** Type guard to identify token values. */\n isToken: (value: unknown) => value is TToken;\n /** Normalizer for non-token values. */\n normalizeCustom: (value: TCustom) => string;\n /** Candidate token or custom value. */\n value: TToken | TCustom | null | undefined;\n}\n\n/**\n * Resolves token-aware values with consistent fallback behavior.\n * - Empty values (`null`, `undefined`, `\"\"`) use `fallback`.\n * - Token values are resolved through `useDesignToken`.\n * - Non-token values are returned via `normalizeCustom`.\n * @param options Resolution options for token/custom values.\n * @returns Resolved token value or normalized custom/fallback value.\n */\nexport const useResolvedTokenValue = <\n TToken extends CSSVariableString,\n TCustom\n>(\n options: UseResolvedTokenValueOptions<TToken, TCustom>\n) => {\n const { value, fallback, isToken: checkToken, normalizeCustom } = options;\n const isToken = checkToken(value);\n const tokenName = isToken ? value : undefined;\n const resolvedToken = useDesignToken(tokenName);\n const isFallbackToken = checkToken(fallback);\n const fallbackTokenName = isFallbackToken ? fallback : undefined;\n const resolvedFallback = useDesignToken(fallbackTokenName);\n\n if (isToken && !isEmptyValue(resolvedToken)) {\n return resolvedToken;\n }\n\n if (!isToken && !isEmptyValue(value)) {\n return normalizeCustom(value);\n }\n\n if (isFallbackToken && !isEmptyValue(resolvedFallback)) {\n return resolvedFallback;\n }\n\n return normalizeCustom(fallback as TCustom);\n};\n"],"names":["isEmptyValue","value","useDesignToken","tokenName","theme","mode","themeElement","useTheme","setValue","useState","undefined","useEffect","parseCSSVariableValue","options","fallback","isToken","checkToken","normalizeCustom","resolvedToken","isFallbackToken","resolvedFallback"],"mappings":"2GAMA,MAAMA,EAAgBC,GACF,MAATA,GAA2B,KAAVA,EAafC,EACTC,IAEA,MAAMC,MAAEA,EAAKC,KAAEA,EAAIC,aAAEA,GAAiBC,EAAAA,YAC/BN,EAAOO,GAAYC,EAAAA,cAA6BC,GAQvD,OANAC,EAAAA,WAAU,KACDL,GAELE,EAASI,EAAAA,sBAAsBT,EAAWG,GAAc,GACzD,CAACF,EAAOC,EAAMC,EAAcH,IAExBF,CAAK,yDA6BZY,IAEA,MAAMZ,MAAEA,EAAKa,SAAEA,EAAUC,QAASC,EAAUC,gBAAEA,GAAoBJ,EAC5DE,EAAUC,EAAWf,GAErBiB,EAAgBhB,EADJa,EAAUd,OAAQS,GAE9BS,EAAkBH,EAAWF,GAE7BM,EAAmBlB,EADCiB,EAAkBL,OAAWJ,GAGvD,OAAIK,IAAYf,EAAakB,GAClBA,EAGNH,GAAYf,EAAaC,GAI1BkB,IAAoBnB,EAAaoB,GAC1BA,EAGJH,EAAgBH,GAPZG,EAAgBhB,EAOgB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-media-query.js","sources":["../../../../src/theme/utils/use-media-query.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nimport { Breakpoint } from \"../tokens/breakpoint\";\nimport { isTokenFromSet } from \"./token-resolver\";\nimport { useResolvedTokenValue } from \"./use-design-token\";\n\n/** Named width breakpoint identifier used for responsive width comparisons. */\ntype BreakpointName = \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"xxl\";\ntype MaxWidthBreakpointName = Exclude<BreakpointName, \"xxl\">;\ntype MinWidthBreakpointTokenKey = `${BreakpointName}-min`;\ntype MaxWidthBreakpointTokenKey = `${MaxWidthBreakpointName}-max`;\ntype WidthBreakpointTokenKey =\n | MinWidthBreakpointTokenKey\n | MaxWidthBreakpointTokenKey;\ntype WidthBreakpointCSSVariableString =\n (typeof Breakpoint)[WidthBreakpointTokenKey];\n\ntype MediaQueryFeature =\n | \"aspect-ratio\"\n | \"color-index\"\n | \"color\"\n | \"device-aspect-ratio\"\n | \"device-height\"\n | \"device-width\"\n | \"grid\"\n | \"height\"\n | \"max-height\"\n | \"min-height\"\n | \"hover\"\n | \"monochrome\"\n | \"orientation\"\n | \"pointer\"\n | \"prefers-color-scheme\"\n | \"resolution\"\n | \"scan\"\n | \"width\";\n\ntype MediaQueryClauseValue = string | number | boolean;\n\n/** A single media-query feature condition. */\nexport interface MediaQueryClause {\n feature: MediaQueryFeature;\n /**\n * Value for the media-query feature.\n *\n * - A string or number emits `(feature: value)`.\n * - `true` emits a bare feature clause (e.g. `(hover)`).\n * - `false` or `undefined` omits the clause entirely.\n */\n value: MediaQueryClauseValue | undefined;\n}\n\n/** Options for `useMediaQuery`. */\nexport interface MediaQueryOptions {\n /** Lower-bound breakpoint token. Viewport must be >= this width. */\n minWidth?: WidthBreakpointCSSVariableString;\n /** Upper-bound breakpoint token. Viewport must be <= this width. */\n maxWidth?: WidthBreakpointCSSVariableString;\n /** Extra feature conditions (e.g. `hover`, `orientation`) combined with `and`. */\n clauses?: MediaQueryClause[];\n}\n\n/**\n * Default LifeSG breakpoint values for width-based tokens.\n * Extracted from src/theme/styles/default.css.\n */\nconst WIDTH_BREAKPOINT_DEFAULTS: Record<\n WidthBreakpointCSSVariableString,\n string\n> = {\n [Breakpoint[\"xxs-min\"]]: \"0\",\n [Breakpoint[\"xs-min\"]]: \"321px\",\n [Breakpoint[\"sm-min\"]]: \"376px\",\n [Breakpoint[\"md-min\"]]: \"481px\",\n [Breakpoint[\"lg-min\"]]: \"769px\",\n [Breakpoint[\"xl-min\"]]: \"1201px\",\n [Breakpoint[\"xxl-min\"]]: \"1441px\",\n [Breakpoint[\"xxs-max\"]]: \"320px\",\n [Breakpoint[\"xs-max\"]]: \"375px\",\n [Breakpoint[\"sm-max\"]]: \"480px\",\n [Breakpoint[\"md-max\"]]: \"768px\",\n [Breakpoint[\"lg-max\"]]: \"1200px\",\n [Breakpoint[\"xl-max\"]]: \"1440px\",\n};\n\nconst WIDTH_BREAKPOINT_TOKEN_SET = new Set<WidthBreakpointCSSVariableString>([\n Breakpoint[\"xxs-min\"],\n Breakpoint[\"xs-min\"],\n Breakpoint[\"sm-min\"],\n Breakpoint[\"md-min\"],\n Breakpoint[\"lg-min\"],\n Breakpoint[\"xl-min\"],\n Breakpoint[\"xxl-min\"],\n Breakpoint[\"xxs-max\"],\n Breakpoint[\"xs-max\"],\n Breakpoint[\"sm-max\"],\n Breakpoint[\"md-max\"],\n Breakpoint[\"lg-max\"],\n Breakpoint[\"xl-max\"],\n]);\n\nconst isBreakpointToken = (\n value: unknown\n): value is WidthBreakpointCSSVariableString => {\n return isTokenFromSet<WidthBreakpointCSSVariableString>(\n value,\n WIDTH_BREAKPOINT_TOKEN_SET\n );\n};\n\nconst getMinWidthBreakpointToken = (breakpoint: BreakpointName) => {\n return Breakpoint[`${breakpoint}-min`];\n};\n\nconst getMaxWidthBreakpointToken = (breakpoint: MaxWidthBreakpointName) => {\n return Breakpoint[`${breakpoint}-max`];\n};\n\n/**\n * Returns `true` when the viewport width is at or above the named breakpoint.\n *\n * @param breakpoint Named breakpoint to compare against.\n */\nexport const useMinWidthMediaQuery = (breakpoint: BreakpointName) =>\n useMediaQuery({\n minWidth: getMinWidthBreakpointToken(breakpoint),\n });\n\n/**\n * Returns `true` when the viewport width is at or below the named breakpoint.\n *\n * @param breakpoint Named breakpoint to compare against.\n */\nexport const useMaxWidthMediaQuery = (breakpoint: MaxWidthBreakpointName) =>\n useMediaQuery({\n maxWidth: getMaxWidthBreakpointToken(breakpoint),\n });\n\nconst getMediaQueryClause = (\n feature: \"min-width\" | \"max-width\",\n value: string | undefined\n) => {\n if (!value) {\n return undefined;\n }\n\n return `(${feature}: ${value})`;\n};\n\nconst getCustomMediaQueryClause = (\n clause: MediaQueryClause | null | undefined\n) => {\n if (clause?.value === undefined) {\n return undefined;\n }\n\n if (clause.value === true) {\n return `(${clause.feature})`;\n }\n\n if (clause.value === false) {\n return undefined;\n }\n\n const value = `${clause.value}`.trim();\n\n if (!value) {\n return undefined;\n }\n\n return `(${clause.feature}: ${value})`;\n};\n\nconst getDefaultMatch = (hasMinWidth: boolean, hasMaxWidth: boolean) => {\n if (hasMaxWidth) {\n return false;\n }\n\n if (hasMinWidth) {\n return true;\n }\n\n return false;\n};\n\nconst getCurrentMatch = (queryString: string, defaultMatch: boolean) => {\n if (!queryString) {\n return defaultMatch;\n }\n\n if (!globalThis.window?.matchMedia) {\n return defaultMatch;\n }\n\n return globalThis.window.matchMedia(queryString).matches;\n};\n\n/**\n * Resolves a width breakpoint CSS variable token to its computed pixel string.\n *\n * @returns The resolved pixel value, falling back to default LifeSG breakpoint\n * values when the theme element is not yet mounted, or `\"\"` for unrecognised\n * tokens.\n */\nexport const useResolvedBreakpointToken = (\n breakpointToken: WidthBreakpointCSSVariableString | undefined\n): string => {\n const effectiveFallback =\n isBreakpointToken(breakpointToken) &&\n WIDTH_BREAKPOINT_DEFAULTS[breakpointToken]\n ? WIDTH_BREAKPOINT_DEFAULTS[breakpointToken]\n : \"\";\n\n return useResolvedTokenValue<WidthBreakpointCSSVariableString, string>({\n value: breakpointToken,\n fallback: effectiveFallback,\n isToken: isBreakpointToken,\n normalizeCustom: (value) => value,\n });\n};\n\nconst useMatchMediaQuery = (\n queryString: string,\n defaultMatch: boolean\n): boolean => {\n const [matches, setMatches] = useState(() =>\n getCurrentMatch(queryString, defaultMatch)\n );\n\n useEffect(() => {\n if (!queryString || !globalThis.window?.matchMedia) {\n setMatches(defaultMatch);\n return;\n }\n\n const mediaQueryList = globalThis.window.matchMedia(queryString);\n const handleChange = (event: MediaQueryListEvent) => {\n setMatches(event.matches);\n };\n\n setMatches(mediaQueryList.matches);\n mediaQueryList.addEventListener(\"change\", handleChange);\n\n return () => {\n mediaQueryList.removeEventListener(\"change\", handleChange);\n };\n }, [defaultMatch, queryString]);\n\n return matches;\n};\n\n/**\n * Reactive boolean hook that evaluates a media query built from width\n * breakpoint tokens and optional custom feature clauses.\n *\n * @returns `true` when the query matches. When `window.matchMedia` is\n * unavailable (SSR), defaults to `true` for min-width-only queries and\n * `false` for max-width-only.\n */\nexport const useMediaQuery = (options: MediaQueryOptions): boolean => {\n const { minWidth, maxWidth, clauses = [] } = options;\n const normalizedMinWidth = useResolvedBreakpointToken(minWidth);\n const normalizedMaxWidth = useResolvedBreakpointToken(maxWidth);\n const widthClauses = [\n getMediaQueryClause(\"min-width\", normalizedMinWidth),\n getMediaQueryClause(\"max-width\", normalizedMaxWidth),\n ].filter((value): value is string => !!value);\n const customClauses = clauses\n .map(getCustomMediaQueryClause)\n .filter((value): value is string => !!value);\n const queryString = [...widthClauses, ...customClauses].join(\" and \");\n const hasMinWidth = !!normalizedMinWidth;\n const hasMaxWidth = !!normalizedMaxWidth;\n const defaultMatch = getDefaultMatch(hasMinWidth, hasMaxWidth);\n\n return useMatchMediaQuery(queryString, defaultMatch);\n};\n"],"names":["WIDTH_BREAKPOINT_DEFAULTS","Breakpoint","WIDTH_BREAKPOINT_TOKEN_SET","Set","isBreakpointToken","value","isTokenFromSet","getMinWidthBreakpointToken","breakpoint","getMaxWidthBreakpointToken","getMediaQueryClause","feature","getCustomMediaQueryClause","clause","undefined","trim","useResolvedBreakpointToken","breakpointToken","effectiveFallback","useResolvedTokenValue","fallback","isToken","normalizeCustom","useMatchMediaQuery","queryString","defaultMatch","matches","setMatches","useState","_a","globalThis","window","matchMedia","getCurrentMatch","useEffect","mediaQueryList","handleChange","event","addEventListener","removeEventListener","useMediaQuery","options","minWidth","maxWidth","clauses","normalizedMinWidth","normalizedMaxWidth","filter","map","join","hasMinWidth","hasMaxWidth","getDefaultMatch"],"mappings":"6IAkEA,MAAMA,EAGF,CACA,CAACC,EAAAA,WAAW,YAAa,IACzB,CAACA,EAAAA,WAAW,WAAY,QACxB,CAACA,EAAAA,WAAW,WAAY,QACxB,CAACA,EAAAA,WAAW,WAAY,QACxB,CAACA,EAAAA,WAAW,WAAY,QACxB,CAACA,EAAAA,WAAW,WAAY,SACxB,CAACA,EAAAA,WAAW,YAAa,SACzB,CAACA,EAAAA,WAAW,YAAa,QACzB,CAACA,EAAAA,WAAW,WAAY,QACxB,CAACA,EAAAA,WAAW,WAAY,QACxB,CAACA,EAAAA,WAAW,WAAY,QACxB,CAACA,EAAAA,WAAW,WAAY,SACxB,CAACA,EAAAA,WAAW,WAAY,UAGtBC,EAA6B,IAAIC,IAAsC,CACzEF,EAAAA,WAAW,WACXA,EAAAA,WAAW,UACXA,EAAAA,WAAW,UACXA,EAAAA,WAAW,UACXA,EAAAA,WAAW,UACXA,EAAAA,WAAW,UACXA,EAAAA,WAAW,WACXA,EAAAA,WAAW,WACXA,EAAAA,WAAW,UACXA,EAAAA,WAAW,UACXA,EAAAA,WAAW,UACXA,EAAAA,WAAW,UACXA,EAAAA,WAAW,YAGTG,EACFC,GAEOC,EAAAA,eACHD,EACAH,GAIFK,EAA8BC,GACzBP,aAAW,GAAGO,SAGnBC,EAA8BD,GACzBP,aAAW,GAAGO,SAuBnBE,EAAsB,CACxBC,EACAN,KAEA,GAAKA,EAIL,MAAO,IAAIM,MAAYN,IAAQ,EAG7BO,EACFC,IAEA,QAAsBC,KAAlBD,aAAM,EAANA,EAAQR,OACR,OAGJ,IAAqB,IAAjBQ,EAAOR,MACP,MAAO,IAAIQ,EAAOF,WAGtB,IAAqB,IAAjBE,EAAOR,MACP,OAGJ,MAAMA,EAAQ,GAAGQ,EAAOR,QAAQU,OAEhC,OAAKV,EAIE,IAAIQ,EAAOF,YAAYN,UAJ9B,CAIsC,EAkC7BW,EACTC,IAEA,MAAMC,EACFd,EAAkBa,IAClBjB,EAA0BiB,GACpBjB,EAA0BiB,GAC1B,GAEV,OAAOE,wBAAgE,CACnEd,MAAOY,EACPG,SAAUF,EACVG,QAASjB,EACTkB,gBAAkBjB,GAAUA,GAC9B,EAGAkB,EAAqB,CACvBC,EACAC,KAEA,MAAOC,EAASC,GAAcC,EAAAA,UAAS,IAxCnB,EAACJ,EAAqBC,WAC1C,OAAKD,IAIiB,QAAjBK,EAAAC,WAAWC,cAAM,IAAAF,OAAA,EAAAA,EAAEG,YAIjBF,WAAWC,OAAOC,WAAWR,GAAaE,QAPtCD,CAO6C,EAgCpDQ,CAAgBT,EAAaC,KAsBjC,OAnBAS,EAAAA,WAAU,WACN,IAAKV,KAAiC,QAAjBK,EAAAC,WAAWC,cAAM,IAAAF,OAAA,EAAAA,EAAEG,YAEpC,YADAL,EAAWF,GAIf,MAAMU,EAAiBL,WAAWC,OAAOC,WAAWR,GAC9CY,EAAgBC,IAClBV,EAAWU,EAAMX,QAAQ,EAM7B,OAHAC,EAAWQ,EAAeT,SAC1BS,EAAeG,iBAAiB,SAAUF,GAEnC,KACHD,EAAeI,oBAAoB,SAAUH,EAAa,CAC7D,GACF,CAACX,EAAcD,IAEXE,CAAO,EAWLc,EAAiBC,IAC1B,MAAMC,SAAEA,EAAQC,SAAEA,EAAQC,QAAEA,EAAU,IAAOH,EACvCI,EAAqB7B,EAA2B0B,GAChDI,EAAqB9B,EAA2B2B,GAQhDnB,EAAc,IAPC,CACjBd,EAAoB,YAAamC,GACjCnC,EAAoB,YAAaoC,IACnCC,QAAQ1C,KAA6BA,OACjBuC,EACjBI,IAAIpC,GACJmC,QAAQ1C,KAA6BA,KACc4C,KAAK,SAGvDxB,EApGc,EAACyB,EAAsBC,KACvCA,KAIAD,EA+FiBE,GAFCP,IACAC,GAGtB,OAAOvB,EAAmBC,EAAaC,EAAa,gCA9IlBjB,GAClCgC,EAAc,CACVG,SAAUlC,EAA2BD,2DAZPA,GAClCgC,EAAc,CACVE,SAAUnC,EAA2BC"}
|
|
1
|
+
{"version":3,"file":"use-media-query.js","sources":["../../../../src/theme/utils/use-media-query.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nimport { Breakpoint } from \"../tokens/breakpoint\";\nimport { isTokenFromSet } from \"./token-resolver\";\nimport { useResolvedTokenValue } from \"./use-design-token\";\n\n/** Named width breakpoint identifier used for responsive width comparisons. */\ntype BreakpointName = \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"xxl\";\ntype MaxWidthBreakpointName = Exclude<BreakpointName, \"xxl\">;\ntype MinWidthBreakpointTokenKey = `${BreakpointName}-min`;\ntype MaxWidthBreakpointTokenKey = `${MaxWidthBreakpointName}-max`;\ntype WidthBreakpointTokenKey =\n | MinWidthBreakpointTokenKey\n | MaxWidthBreakpointTokenKey;\ntype WidthBreakpointCSSVariableString =\n (typeof Breakpoint)[WidthBreakpointTokenKey];\n\ntype MediaQueryFeature =\n | \"aspect-ratio\"\n | \"color-index\"\n | \"color\"\n | \"device-aspect-ratio\"\n | \"device-height\"\n | \"device-width\"\n | \"grid\"\n | \"height\"\n | \"max-height\"\n | \"min-height\"\n | \"hover\"\n | \"monochrome\"\n | \"orientation\"\n | \"pointer\"\n | \"prefers-color-scheme\"\n | \"resolution\"\n | \"scan\"\n | \"width\";\n\ntype MediaQueryClauseValue = string | number | boolean;\n\n/** A single media-query feature condition. */\nexport interface MediaQueryClause {\n feature: MediaQueryFeature;\n /**\n * Value for the media-query feature.\n *\n * - A string or number emits `(feature: value)`.\n * - `true` emits a bare feature clause (e.g. `(hover)`).\n * - `false` or `undefined` omits the clause entirely.\n */\n value: MediaQueryClauseValue | undefined;\n}\n\n/** Options for `useMediaQuery`. */\nexport interface MediaQueryOptions {\n /** Lower-bound breakpoint token. Viewport must be >= this width. */\n minWidth?: WidthBreakpointCSSVariableString;\n /** Upper-bound breakpoint token. Viewport must be <= this width. */\n maxWidth?: WidthBreakpointCSSVariableString;\n /** Extra feature conditions (e.g. `hover`, `orientation`) combined with `and`. */\n clauses?: MediaQueryClause[];\n}\n\n/**\n * Default LifeSG breakpoint values for width-based tokens.\n * Extracted from src/theme/styles/default.css.\n */\nconst WIDTH_BREAKPOINT_DEFAULTS: Record<\n WidthBreakpointCSSVariableString,\n string\n> = {\n [Breakpoint[\"xxs-min\"]]: \"0\",\n [Breakpoint[\"xs-min\"]]: \"321px\",\n [Breakpoint[\"sm-min\"]]: \"376px\",\n [Breakpoint[\"md-min\"]]: \"481px\",\n [Breakpoint[\"lg-min\"]]: \"769px\",\n [Breakpoint[\"xl-min\"]]: \"1201px\",\n [Breakpoint[\"xxl-min\"]]: \"1441px\",\n [Breakpoint[\"xxs-max\"]]: \"320px\",\n [Breakpoint[\"xs-max\"]]: \"375px\",\n [Breakpoint[\"sm-max\"]]: \"480px\",\n [Breakpoint[\"md-max\"]]: \"768px\",\n [Breakpoint[\"lg-max\"]]: \"1200px\",\n [Breakpoint[\"xl-max\"]]: \"1440px\",\n};\n\nconst WIDTH_BREAKPOINT_TOKEN_SET = new Set<WidthBreakpointCSSVariableString>([\n Breakpoint[\"xxs-min\"],\n Breakpoint[\"xs-min\"],\n Breakpoint[\"sm-min\"],\n Breakpoint[\"md-min\"],\n Breakpoint[\"lg-min\"],\n Breakpoint[\"xl-min\"],\n Breakpoint[\"xxl-min\"],\n Breakpoint[\"xxs-max\"],\n Breakpoint[\"xs-max\"],\n Breakpoint[\"sm-max\"],\n Breakpoint[\"md-max\"],\n Breakpoint[\"lg-max\"],\n Breakpoint[\"xl-max\"],\n]);\n\nconst isBreakpointToken = (\n value: unknown\n): value is WidthBreakpointCSSVariableString => {\n return isTokenFromSet<WidthBreakpointCSSVariableString>(\n value,\n WIDTH_BREAKPOINT_TOKEN_SET\n );\n};\n\nconst getMinWidthBreakpointToken = (breakpoint: BreakpointName) => {\n return Breakpoint[`${breakpoint}-min`];\n};\n\nconst getMaxWidthBreakpointToken = (breakpoint: MaxWidthBreakpointName) => {\n return Breakpoint[`${breakpoint}-max`];\n};\n\n// @catalog\n/**\n * Returns `true` when the viewport width is at or above the named breakpoint.\n *\n * @param breakpoint Named breakpoint to compare against.\n */\nexport const useMinWidthMediaQuery = (breakpoint: BreakpointName) =>\n useMediaQuery({\n minWidth: getMinWidthBreakpointToken(breakpoint),\n });\n\n// @catalog\n/**\n * Returns `true` when the viewport width is at or below the named breakpoint.\n *\n * @param breakpoint Named breakpoint to compare against.\n */\nexport const useMaxWidthMediaQuery = (breakpoint: MaxWidthBreakpointName) =>\n useMediaQuery({\n maxWidth: getMaxWidthBreakpointToken(breakpoint),\n });\n\nconst getMediaQueryClause = (\n feature: \"min-width\" | \"max-width\",\n value: string | undefined\n) => {\n if (!value) {\n return undefined;\n }\n\n return `(${feature}: ${value})`;\n};\n\nconst getCustomMediaQueryClause = (\n clause: MediaQueryClause | null | undefined\n) => {\n if (clause?.value === undefined) {\n return undefined;\n }\n\n if (clause.value === true) {\n return `(${clause.feature})`;\n }\n\n if (clause.value === false) {\n return undefined;\n }\n\n const value = `${clause.value}`.trim();\n\n if (!value) {\n return undefined;\n }\n\n return `(${clause.feature}: ${value})`;\n};\n\nconst getDefaultMatch = (hasMinWidth: boolean, hasMaxWidth: boolean) => {\n if (hasMaxWidth) {\n return false;\n }\n\n if (hasMinWidth) {\n return true;\n }\n\n return false;\n};\n\nconst getCurrentMatch = (queryString: string, defaultMatch: boolean) => {\n if (!queryString) {\n return defaultMatch;\n }\n\n if (!globalThis.window?.matchMedia) {\n return defaultMatch;\n }\n\n return globalThis.window.matchMedia(queryString).matches;\n};\n\n// @catalog\n/**\n * Resolves a width breakpoint CSS variable token to its computed pixel string.\n *\n * @returns The resolved pixel value, falling back to default LifeSG breakpoint\n * values when the theme element is not yet mounted, or `\"\"` for unrecognised\n * tokens.\n */\nexport const useResolvedBreakpointToken = (\n breakpointToken: WidthBreakpointCSSVariableString | undefined\n): string => {\n const effectiveFallback =\n isBreakpointToken(breakpointToken) &&\n WIDTH_BREAKPOINT_DEFAULTS[breakpointToken]\n ? WIDTH_BREAKPOINT_DEFAULTS[breakpointToken]\n : \"\";\n\n return useResolvedTokenValue<WidthBreakpointCSSVariableString, string>({\n value: breakpointToken,\n fallback: effectiveFallback,\n isToken: isBreakpointToken,\n normalizeCustom: (value) => value,\n });\n};\n\nconst useMatchMediaQuery = (\n queryString: string,\n defaultMatch: boolean\n): boolean => {\n const [matches, setMatches] = useState(() =>\n getCurrentMatch(queryString, defaultMatch)\n );\n\n useEffect(() => {\n if (!queryString || !globalThis.window?.matchMedia) {\n setMatches(defaultMatch);\n return;\n }\n\n const mediaQueryList = globalThis.window.matchMedia(queryString);\n const handleChange = (event: MediaQueryListEvent) => {\n setMatches(event.matches);\n };\n\n setMatches(mediaQueryList.matches);\n mediaQueryList.addEventListener(\"change\", handleChange);\n\n return () => {\n mediaQueryList.removeEventListener(\"change\", handleChange);\n };\n }, [defaultMatch, queryString]);\n\n return matches;\n};\n\n// @catalog\n/**\n * Reactive boolean hook that evaluates a media query built from width\n * breakpoint tokens and optional custom feature clauses.\n *\n * @returns `true` when the query matches. When `window.matchMedia` is\n * unavailable (SSR), defaults to `true` for min-width-only queries and\n * `false` for max-width-only.\n */\nexport const useMediaQuery = (options: MediaQueryOptions): boolean => {\n const { minWidth, maxWidth, clauses = [] } = options;\n const normalizedMinWidth = useResolvedBreakpointToken(minWidth);\n const normalizedMaxWidth = useResolvedBreakpointToken(maxWidth);\n const widthClauses = [\n getMediaQueryClause(\"min-width\", normalizedMinWidth),\n getMediaQueryClause(\"max-width\", normalizedMaxWidth),\n ].filter((value): value is string => !!value);\n const customClauses = clauses\n .map(getCustomMediaQueryClause)\n .filter((value): value is string => !!value);\n const queryString = [...widthClauses, ...customClauses].join(\" and \");\n const hasMinWidth = !!normalizedMinWidth;\n const hasMaxWidth = !!normalizedMaxWidth;\n const defaultMatch = getDefaultMatch(hasMinWidth, hasMaxWidth);\n\n return useMatchMediaQuery(queryString, defaultMatch);\n};\n"],"names":["WIDTH_BREAKPOINT_DEFAULTS","Breakpoint","WIDTH_BREAKPOINT_TOKEN_SET","Set","isBreakpointToken","value","isTokenFromSet","getMinWidthBreakpointToken","breakpoint","getMaxWidthBreakpointToken","getMediaQueryClause","feature","getCustomMediaQueryClause","clause","undefined","trim","useResolvedBreakpointToken","breakpointToken","effectiveFallback","useResolvedTokenValue","fallback","isToken","normalizeCustom","useMatchMediaQuery","queryString","defaultMatch","matches","setMatches","useState","_a","globalThis","window","matchMedia","getCurrentMatch","useEffect","mediaQueryList","handleChange","event","addEventListener","removeEventListener","useMediaQuery","options","minWidth","maxWidth","clauses","normalizedMinWidth","normalizedMaxWidth","filter","map","join","hasMinWidth","hasMaxWidth","getDefaultMatch"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("../../_virtual/_tslib.js"),r=require("react/jsx-runtime"),t=require("clsx"),i=require("react"),a=require("../../form/form-label.js"),s=require("../../shared/accessibility/index.js");require("../../theme/theme-provider/index.js"),require("../../theme/theme-provider/context.js"),require("../../theme/tokens/border.js"),require("../../theme/tokens/colour.js"),require("../../theme/tokens/font.js"),require("../../theme/tokens/media-query.js"),require("../../util/calendar-helper.js"),require("../../external/dayjs/dayjs.min.js");var l=require("../../util/simple-id-generator.js");require("../../util/string-helper.js"),require("@react-aria/live-announcer"),require("../../theme/utils/use-media-query.js"),require("../../shared/dropdown-list/dropdown-label.styles_mloii0.css");var n=require("../../shared/dropdown-list/dropdown-list.js"),o=require("../../shared/dropdown-list/dropdown-list-state.js");require("../../shared/dropdown-list/expandable-element.js"),require("@lifesg/react-icons/caret-right"),require("@lifesg/react-icons/exclamation-circle-fill"),require("@lifesg/react-icons/minus-square-fill"),require("@lifesg/react-icons/square"),require("@lifesg/react-icons/square-tick-fill"),require("@lifesg/react-icons/tick"),require("react-virtuoso"),require("../../markup/markup.js"),require("../../shared/component-loading-spinner/component-loading-spinner.styles_15eq02i.css");var d=require("../../shared/dropdown-wrapper/element-with-dropdown.js"),u=require("../../shared/input-wrapper/input-wrapper.js");require("../../shared/dropdown-list/dropdown-list.styles_konwm.css"),require("../../shared/dropdown-list/dropdown-search.js"),require("../../shared/dropdown-list/nested-dropdown-list.styles_wdhxoe.css"),require("immer"),require("../../external/lodash/_getTag.js"),require("../../external/lodash/isArguments.js"),require("../../external/lodash/_baseGetTag.js"),require("../../external/lodash/isBuffer.js"),require("../../external/lodash/isTypedArray.js"),require("../../external/lodash/_Stack.js"),require("../../external/lodash/_SetCache.js"),require("../../external/lodash/_equalByTag.js"),require("../../shared/dropdown-list/virtuoso-components.js");var c=require("../../shared/input-wrapper/input-wrapper.styles.js"),m=require("../../shared/range-input-inner-container/range-input-inner-container.js"),p=require("../../util/time-helper.js"),h=require("../common.styles.js"),v=require("./combobox-picker.styles.js");function f(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var b=f(t);exports.ComboboxPicker=t=>{var{id:f,disabled:q=!1,error:g,value:j,format:x="12hr",readOnly:y,onChange:w,onFocus:I,onBlur:T,alignment:C="left",dropdownZIndex:_,startLimit:S,endLimit:k,initialScrollStartTime:H,initialScrollEndTime:E,interval:B=15,dropdownRootNode:A,"aria-labelledby":F,"aria-describedby":O,"aria-invalid":N}=t,D=e.__rest(t,["id","disabled","error","value","format","readOnly","onChange","onFocus","onBlur","alignment","dropdownZIndex","startLimit","endLimit","initialScrollStartTime","initialScrollEndTime","interval","dropdownRootNode","aria-labelledby","aria-describedby","aria-invalid"]);const L=l.useId(),[M,$]=i.useState(null),[P,R]=i.useState(!1),[G,W]=i.useState(""),[Z,K]=i.useState(""),[V,z]=i.useState(""),[J,Q]=i.useState(""),[U,X]=i.useState(""),Y=i.useRef(null),ee=i.useRef(null),re=i.useRef(null),te=`${L}-listbox`,ie=`${L}-start-label`,ae=`${L}-end-label`,se=`${L}-error-message`,le=i.useMemo((()=>p.TimeHelper.generateTimings(B,x,S,k)),[B,x,S,k]),ne=i.useMemo((()=>{if(""===J)return le;const e=p.TimeHelper.findClosestFlooredTime(J,le);return e?le.slice(le.indexOf(e)):[]}),[le,J]),oe=i.useCallback((e=>p.TimeHelper.parseInput(e,x)),[x]),de=i.useMemo((()=>{var e;return null!==(e=oe(H))&&void 0!==e?e:""}),[H,oe]),ue=i.useMemo((()=>{var e;return null!==(e=oe(E))&&void 0!==e?e:""}),[E,oe]);i.useEffect((()=>{var e,r;if(j){const t=null!==(e=oe(j.start))&&void 0!==e?e:"",i=null!==(r=oe(j.end))&&void 0!==r?r:"";K(t),z(i),Q(t),X(i)}}),[j,oe]),i.useEffect((()=>{if(g)return void R(!1);const e=oe(Z),r=oe(V);if(void 0===e)W("Invalid start time");else if(void 0===r)W("Invalid end time");else{if(!(""!==e&&""!==r&&p.TimeHelper.to24Hour(r)<p.TimeHelper.to24Hour(e)))return W(""),void(document.activeElement!==ee.current&&document.activeElement!==re.current||R(!0));W("End time must be after start time")}R(!1)}),[Z,V,oe,g]);const ce=()=>"start"===M?"Selecting for: Start time":"end"===M?"Selecting for: End time":void 0,me=e=>s.concatIds(F,"start"===e?ie:ae),pe=()=>s.concatIds(O,!g&&G?se:void 0),he=e=>{q||y||(M||P||null==I||I(),$(e),R(!0))},ve=e=>{var r;q||y||($(e),R(!0),null===(r=("start"===e?ee:re).current)||void 0===r||r.select())};function fe(e){var r;switch(e.code){case"Enter":"start"===M?be(Z):"end"===M&&(P&&qe(V),null===(r=re.current)||void 0===r||r.blur());break;case"Tab":ge(Z,V,{})}}const be=e=>{ge(e,V,{goToNextInput:!0})},qe=e=>{ge(Z,e,{triggerOnBlur:!0})},ge=(e,r,{goToNextInput:t,triggerOnBlur:i})=>{var a,s,l;const n=null!==(a=oe(e))&&void 0!==a?a:J,o=null!==(s=oe(r))&&void 0!==s?s:U;K(n),z(o);n===J&&o===U||null==w||w({start:n,end:o}),t&&void 0!==oe(e)&&($("end"),null===(l=re.current)||void 0===l||l.select()),i&&($(null),R(!1),null==T||T()),Q(n),X(o)},je=e=>{e.stopPropagation(),K(""),z(""),Q(""),X("");null==w||w({start:"",end:""}),$(null),R(!1)},xe=e=>{var r,t;const i=e.relatedTarget,a=(null===(r=null==i?void 0:i.matches)||void 0===r?void 0:r.call(i,"[data-floating-ui-focusable]"))||(null===(t=null==i?void 0:i.matches)||void 0===t?void 0:t.call(i,"[data-floating-ui-focus-guard]")),s=Y.current&&Y.current.contains(i);M&&!P&&!s&&!a&&ge(Z,V,{triggerOnBlur:!0})},ye=()=>{if(!y&&!q&&((null==Z?void 0:Z.length)>0||(null==V?void 0:V.length)>0))return r.jsx("div",{className:c.clearButtonContainer,children:r.jsx(u.ClearButton,{onClick:je,type:"button","aria-label":"Clear"})})};return r.jsxs("div",Object.assign({id:f},D,{className:b.default(h.wrapper,D.className),children:[r.jsx(o.DropdownListState,{children:r.jsx(d.ElementWithDropdown,{enabled:!y&&!q,isOpen:P,renderElement:()=>r.jsxs(u.InputWrapper,{ref:Y,disabled:q,error:g||!!G,readOnly:y,onBlur:xe,role:"group","data-testid":"timepicker-container",className:v.timeFieldContainer,children:[r.jsx(s.VisuallyHidden,{id:ie,children:"Start time"}),r.jsx(s.VisuallyHidden,{id:ae,children:"End time"}),r.jsxs(m.RangeInputInnerContainer,{error:g||!!G,currentActive:null===M?"none":M,children:[r.jsx(u.BasicInput,{ref:ee,onFocus:()=>he("start"),placeholder:"start"===M?"hh:mm":"From",onChange:e=>K(e.target.value),value:Z,readOnly:y||q,"data-testid":D["data-testid"]?`${D["data-testid"]}-timepicker-selector-start`:"timepicker-selector-start",onClick:()=>ve("start"),onKeyDown:fe,autoComplete:"off",type:"text",role:"combobox","aria-labelledby":me("start"),"aria-describedby":pe(),"aria-expanded":P&&"start"===M,"aria-controls":te,"aria-autocomplete":"list","aria-invalid":g||N||!!G,"aria-disabled":q,"aria-readonly":y,className:b.default(h.selectorInput,q&&h.selectorInputDisabled)}),r.jsx(u.BasicInput,{ref:re,onFocus:()=>he("end"),placeholder:"end"===M?"hh:mm":"To",onChange:e=>z(e.target.value),value:V,readOnly:y||q,"data-testid":D["data-testid"]?`${D["data-testid"]}-timepicker-selector-end`:"timepicker-selector-end",onClick:()=>ve("end"),onKeyDown:fe,autoComplete:"off",type:"text",role:"combobox","aria-labelledby":me("end"),"aria-describedby":pe(),"aria-expanded":P&&"end"===M,"aria-controls":te,"aria-autocomplete":"list","aria-invalid":g||N||!!G||void 0,"aria-disabled":q||void 0,"aria-readonly":y||void 0,className:b.default(h.selectorInput,q&&h.selectorInputDisabled)})]}),ye()]}),renderDropdown:()=>{if("start"===M){const e=oe(Z)||de;return r.jsx(n.DropdownList,{listItems:le,onSelectItem:be,selectedItems:[Z],topScrollItem:p.TimeHelper.findClosestFlooredTime(e,le),listboxId:te,ariaLabel:ce(),disableItemFocus:!0,matchElementWidth:!0})}{const e=oe(V)||ue;return r.jsx(n.DropdownList,{listItems:ne,onSelectItem:qe,selectedItems:[V],topScrollItem:p.TimeHelper.findClosestFlooredTime(e,ne),listboxId:te,ariaLabel:ce(),disableItemFocus:!0,matchElementWidth:!0})}},onClose:e=>{"outside-press"===e?($(null),R(!1),null==T||T()):ge(Z,V,{triggerOnBlur:!0})},onDismiss:()=>{var e;null===(e=("start"===M?ee:re).current)||void 0===e||e.focus(),R(!1)},offset:8,alignment:C,fitAvailableHeight:!0,customZIndex:_,rootNode:A})}),!g&&G&&r.jsx(a.FormErrorMessage,{id:se,tabIndex:0,"data-testid":f?`${f}-error-message`:"error-message",children:G})]}))};
|
|
1
|
+
"use strict";var e=require("../../_virtual/_tslib.js"),r=require("react/jsx-runtime"),t=require("clsx"),i=require("react"),a=require("../../form/form-label/form-label.js"),s=require("../../shared/accessibility/index.js");require("../../theme/theme-provider/index.js"),require("../../theme/theme-provider/context.js"),require("../../theme/tokens/border.js"),require("../../theme/tokens/colour.js"),require("../../theme/tokens/font.js"),require("../../theme/tokens/media-query.js"),require("../../util/calendar-helper.js"),require("../../external/dayjs/dayjs.min.js");var l=require("../../util/simple-id-generator.js");require("../../util/string-helper.js"),require("@react-aria/live-announcer"),require("../../theme/utils/use-media-query.js"),require("../../shared/dropdown-list/dropdown-label.styles_mloii0.css");var n=require("../../shared/dropdown-list/dropdown-list.js"),o=require("../../shared/dropdown-list/dropdown-list-state.js");require("../../shared/dropdown-list/expandable-element.js"),require("@lifesg/react-icons/caret-right"),require("@lifesg/react-icons/exclamation-circle-fill"),require("@lifesg/react-icons/minus-square-fill"),require("@lifesg/react-icons/square"),require("@lifesg/react-icons/square-tick-fill"),require("@lifesg/react-icons/tick"),require("react-virtuoso"),require("../../markup/markup.js"),require("../../shared/component-loading-spinner/component-loading-spinner.styles_15eq02i.css");var d=require("../../shared/dropdown-wrapper/element-with-dropdown.js"),u=require("../../shared/input-wrapper/input-wrapper.js");require("../../shared/dropdown-list/dropdown-list.styles_konwm.css"),require("../../shared/dropdown-list/dropdown-search.js"),require("../../shared/dropdown-list/nested-dropdown-list.styles_wdhxoe.css"),require("immer"),require("../../external/lodash/_getTag.js"),require("../../external/lodash/isArguments.js"),require("../../external/lodash/_baseGetTag.js"),require("../../external/lodash/isBuffer.js"),require("../../external/lodash/isTypedArray.js"),require("../../external/lodash/_Stack.js"),require("../../external/lodash/_SetCache.js"),require("../../external/lodash/_equalByTag.js"),require("../../shared/dropdown-list/virtuoso-components.js");var c=require("../../shared/input-wrapper/input-wrapper.styles.js"),m=require("../../shared/range-input-inner-container/range-input-inner-container.js"),p=require("../../util/time-helper.js"),h=require("../common.styles.js"),v=require("./combobox-picker.styles.js");function f(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var b=f(t);exports.ComboboxPicker=t=>{var{id:f,disabled:q=!1,error:g,value:j,format:x="12hr",readOnly:y,onChange:w,onFocus:I,onBlur:T,alignment:C="left",dropdownZIndex:_,startLimit:S,endLimit:k,initialScrollStartTime:H,initialScrollEndTime:E,interval:B=15,dropdownRootNode:A,"aria-labelledby":F,"aria-describedby":O,"aria-invalid":N}=t,D=e.__rest(t,["id","disabled","error","value","format","readOnly","onChange","onFocus","onBlur","alignment","dropdownZIndex","startLimit","endLimit","initialScrollStartTime","initialScrollEndTime","interval","dropdownRootNode","aria-labelledby","aria-describedby","aria-invalid"]);const L=l.useId(),[M,$]=i.useState(null),[P,R]=i.useState(!1),[G,W]=i.useState(""),[Z,K]=i.useState(""),[V,z]=i.useState(""),[J,Q]=i.useState(""),[U,X]=i.useState(""),Y=i.useRef(null),ee=i.useRef(null),re=i.useRef(null),te=`${L}-listbox`,ie=`${L}-start-label`,ae=`${L}-end-label`,se=`${L}-error-message`,le=i.useMemo((()=>p.TimeHelper.generateTimings(B,x,S,k)),[B,x,S,k]),ne=i.useMemo((()=>{if(""===J)return le;const e=p.TimeHelper.findClosestFlooredTime(J,le);return e?le.slice(le.indexOf(e)):[]}),[le,J]),oe=i.useCallback((e=>p.TimeHelper.parseInput(e,x)),[x]),de=i.useMemo((()=>{var e;return null!==(e=oe(H))&&void 0!==e?e:""}),[H,oe]),ue=i.useMemo((()=>{var e;return null!==(e=oe(E))&&void 0!==e?e:""}),[E,oe]);i.useEffect((()=>{var e,r;if(j){const t=null!==(e=oe(j.start))&&void 0!==e?e:"",i=null!==(r=oe(j.end))&&void 0!==r?r:"";K(t),z(i),Q(t),X(i)}}),[j,oe]),i.useEffect((()=>{if(g)return void R(!1);const e=oe(Z),r=oe(V);if(void 0===e)W("Invalid start time");else if(void 0===r)W("Invalid end time");else{if(!(""!==e&&""!==r&&p.TimeHelper.to24Hour(r)<p.TimeHelper.to24Hour(e)))return W(""),void(document.activeElement!==ee.current&&document.activeElement!==re.current||R(!0));W("End time must be after start time")}R(!1)}),[Z,V,oe,g]);const ce=()=>"start"===M?"Selecting for: Start time":"end"===M?"Selecting for: End time":void 0,me=e=>s.concatIds(F,"start"===e?ie:ae),pe=()=>s.concatIds(O,!g&&G?se:void 0),he=e=>{q||y||(M||P||null==I||I(),$(e),R(!0))},ve=e=>{var r;q||y||($(e),R(!0),null===(r=("start"===e?ee:re).current)||void 0===r||r.select())};function fe(e){var r;switch(e.code){case"Enter":"start"===M?be(Z):"end"===M&&(P&&qe(V),null===(r=re.current)||void 0===r||r.blur());break;case"Tab":ge(Z,V,{})}}const be=e=>{ge(e,V,{goToNextInput:!0})},qe=e=>{ge(Z,e,{triggerOnBlur:!0})},ge=(e,r,{goToNextInput:t,triggerOnBlur:i})=>{var a,s,l;const n=null!==(a=oe(e))&&void 0!==a?a:J,o=null!==(s=oe(r))&&void 0!==s?s:U;K(n),z(o);n===J&&o===U||null==w||w({start:n,end:o}),t&&void 0!==oe(e)&&($("end"),null===(l=re.current)||void 0===l||l.select()),i&&($(null),R(!1),null==T||T()),Q(n),X(o)},je=e=>{e.stopPropagation(),K(""),z(""),Q(""),X("");null==w||w({start:"",end:""}),$(null),R(!1)},xe=e=>{var r,t;const i=e.relatedTarget,a=(null===(r=null==i?void 0:i.matches)||void 0===r?void 0:r.call(i,"[data-floating-ui-focusable]"))||(null===(t=null==i?void 0:i.matches)||void 0===t?void 0:t.call(i,"[data-floating-ui-focus-guard]")),s=Y.current&&Y.current.contains(i);M&&!P&&!s&&!a&&ge(Z,V,{triggerOnBlur:!0})},ye=()=>{if(!y&&!q&&((null==Z?void 0:Z.length)>0||(null==V?void 0:V.length)>0))return r.jsx("div",{className:c.clearButtonContainer,children:r.jsx(u.ClearButton,{onClick:je,type:"button","aria-label":"Clear"})})};return r.jsxs("div",Object.assign({id:f},D,{className:b.default(h.wrapper,D.className),children:[r.jsx(o.DropdownListState,{children:r.jsx(d.ElementWithDropdown,{enabled:!y&&!q,isOpen:P,renderElement:()=>r.jsxs(u.InputWrapper,{ref:Y,disabled:q,error:g||!!G,readOnly:y,onBlur:xe,role:"group","data-testid":"timepicker-container",className:v.timeFieldContainer,children:[r.jsx(s.VisuallyHidden,{id:ie,children:"Start time"}),r.jsx(s.VisuallyHidden,{id:ae,children:"End time"}),r.jsxs(m.RangeInputInnerContainer,{error:g||!!G,currentActive:null===M?"none":M,children:[r.jsx(u.BasicInput,{ref:ee,onFocus:()=>he("start"),placeholder:"start"===M?"hh:mm":"From",onChange:e=>K(e.target.value),value:Z,readOnly:y||q,"data-testid":D["data-testid"]?`${D["data-testid"]}-timepicker-selector-start`:"timepicker-selector-start",onClick:()=>ve("start"),onKeyDown:fe,autoComplete:"off",type:"text",role:"combobox","aria-labelledby":me("start"),"aria-describedby":pe(),"aria-expanded":P&&"start"===M,"aria-controls":te,"aria-autocomplete":"list","aria-invalid":g||N||!!G,"aria-disabled":q,"aria-readonly":y,className:b.default(h.selectorInput,q&&h.selectorInputDisabled)}),r.jsx(u.BasicInput,{ref:re,onFocus:()=>he("end"),placeholder:"end"===M?"hh:mm":"To",onChange:e=>z(e.target.value),value:V,readOnly:y||q,"data-testid":D["data-testid"]?`${D["data-testid"]}-timepicker-selector-end`:"timepicker-selector-end",onClick:()=>ve("end"),onKeyDown:fe,autoComplete:"off",type:"text",role:"combobox","aria-labelledby":me("end"),"aria-describedby":pe(),"aria-expanded":P&&"end"===M,"aria-controls":te,"aria-autocomplete":"list","aria-invalid":g||N||!!G||void 0,"aria-disabled":q||void 0,"aria-readonly":y||void 0,className:b.default(h.selectorInput,q&&h.selectorInputDisabled)})]}),ye()]}),renderDropdown:()=>{if("start"===M){const e=oe(Z)||de;return r.jsx(n.DropdownList,{listItems:le,onSelectItem:be,selectedItems:[Z],topScrollItem:p.TimeHelper.findClosestFlooredTime(e,le),listboxId:te,ariaLabel:ce(),disableItemFocus:!0,matchElementWidth:!0})}{const e=oe(V)||ue;return r.jsx(n.DropdownList,{listItems:ne,onSelectItem:qe,selectedItems:[V],topScrollItem:p.TimeHelper.findClosestFlooredTime(e,ne),listboxId:te,ariaLabel:ce(),disableItemFocus:!0,matchElementWidth:!0})}},onClose:e=>{"outside-press"===e?($(null),R(!1),null==T||T()):ge(Z,V,{triggerOnBlur:!0})},onDismiss:()=>{var e;null===(e=("start"===M?ee:re).current)||void 0===e||e.focus(),R(!1)},offset:8,alignment:C,fitAvailableHeight:!0,customZIndex:_,rootNode:A})}),!g&&G&&r.jsx(a.FormErrorMessage,{id:se,tabIndex:0,"data-testid":f?`${f}-error-message`:"error-message",children:G})]}))};
|
|
2
2
|
//# sourceMappingURL=combobox-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox-picker.js","sources":["../../../../src/time-range-picker/combobox-picker/combobox-picker.tsx"],"sourcesContent":["import type { OpenChangeReason } from \"@floating-ui/react\";\nimport clsx from \"clsx\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { FormErrorMessage } from \"../../form/form-label\";\nimport { concatIds, VisuallyHidden } from \"../../shared/accessibility\";\nimport { DropdownListState } from \"../../shared/dropdown-list\";\nimport { DropdownList } from \"../../shared/dropdown-list/dropdown-list\";\nimport { ElementWithDropdown } from \"../../shared/dropdown-wrapper\";\nimport {\n BasicInput,\n ClearButton,\n InputWrapper,\n} from \"../../shared/input-wrapper\";\nimport * as inputWrapperStyles from \"../../shared/input-wrapper/input-wrapper.styles\";\nimport { RangeInputInnerContainer } from \"../../shared/range-input-inner-container\";\nimport { useId } from \"../../util\";\nimport { TimeHelper } from \"../../util/time-helper\";\nimport * as commonStyles from \"../common.styles\";\nimport type { TimeRangePickerProps, TimeRangePickerValue } from \"../types\";\nimport * as styles from \"./combobox-picker.styles\";\n\ntype TimeRangeInputType = \"start\" | \"end\";\ninterface TimeChangeOptions {\n goToNextInput?: boolean | undefined;\n triggerOnBlur?: boolean | undefined;\n}\n\nexport const ComboboxPicker = ({\n id,\n disabled = false,\n error,\n value,\n format = \"12hr\",\n readOnly,\n onChange,\n onFocus,\n onBlur,\n alignment = \"left\",\n dropdownZIndex,\n startLimit,\n endLimit,\n initialScrollStartTime,\n initialScrollEndTime,\n interval = 15,\n dropdownRootNode,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n ...otherProps\n}: TimeRangePickerProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const internalId = useId();\n const [activeTimeSelector, setActiveTimeSelector] =\n useState<TimeRangeInputType | null>(null);\n const [dropdownOpen, setDropdownOpen] = useState<boolean>(false);\n const [validationError, setValidationError] = useState<string>(\"\");\n\n const [startTimeVal, setStartTimeVal] = useState<string>(\"\");\n const [endTimeVal, setEndTimeVal] = useState<string>(\"\");\n const [initialStartTimeVal, setInitialStartTimeVal] = useState<string>(\"\");\n const [initialEndTimeVal, setInitialEndTimeVal] = useState<string>(\"\");\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const startInputRef = useRef<HTMLInputElement>(null);\n const endInputRef = useRef<HTMLInputElement>(null);\n\n const listboxId = `${internalId}-listbox`;\n const startLabelId = `${internalId}-start-label`;\n const endLabelId = `${internalId}-end-label`;\n const errorId = `${internalId}-error-message`;\n\n const startOptions = useMemo(\n () =>\n TimeHelper.generateTimings(interval, format, startLimit, endLimit),\n [interval, format, startLimit, endLimit]\n );\n const endOptions = useMemo(() => {\n if (initialStartTimeVal === \"\") return startOptions;\n\n const flooredStartVal = TimeHelper.findClosestFlooredTime(\n initialStartTimeVal,\n startOptions\n );\n return flooredStartVal\n ? startOptions.slice(startOptions.indexOf(flooredStartVal))\n : [];\n }, [startOptions, initialStartTimeVal]);\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n const parseInput = useCallback(\n (input: string | undefined): string | undefined => {\n return TimeHelper.parseInput(input, format);\n },\n [format]\n );\n\n const parsedInitialStartScrollTime = useMemo(\n () => parseInput(initialScrollStartTime) ?? \"\",\n [initialScrollStartTime, parseInput]\n );\n\n const parsedInitialEndScrollTime = useMemo(\n () => parseInput(initialScrollEndTime) ?? \"\",\n [initialScrollEndTime, parseInput]\n );\n\n useEffect(() => {\n if (value) {\n const start = parseInput(value.start) ?? \"\";\n const end = parseInput(value.end) ?? \"\";\n\n setStartTimeVal(start);\n setEndTimeVal(end);\n setInitialStartTimeVal(start);\n setInitialEndTimeVal(end);\n }\n }, [value, parseInput]);\n\n // Validation for keyboard input\n useEffect(() => {\n if (error) {\n setDropdownOpen(false);\n return;\n }\n\n const start = parseInput(startTimeVal);\n const end = parseInput(endTimeVal);\n\n if (start === undefined) {\n setValidationError(\"Invalid start time\");\n } else if (end === undefined) {\n setValidationError(\"Invalid end time\");\n } else if (\n start !== \"\" &&\n end !== \"\" &&\n TimeHelper.to24Hour(end) < TimeHelper.to24Hour(start)\n ) {\n setValidationError(\"End time must be after start time\");\n } else {\n setValidationError(\"\");\n // Re-open dropdown if error was corrected\n if (\n document.activeElement === startInputRef.current ||\n document.activeElement === endInputRef.current\n ) {\n setDropdownOpen(true);\n }\n return;\n }\n\n // Hide dropdown so error message is visible\n setDropdownOpen(false);\n }, [startTimeVal, endTimeVal, parseInput, error]);\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const getDropdownAriaLabel = () => {\n if (activeTimeSelector === \"start\") {\n return \"Selecting for: Start time\";\n }\n\n if (activeTimeSelector === \"end\") {\n return \"Selecting for: End time\";\n }\n\n return undefined;\n };\n\n const getInputLabelledBy = (type: TimeRangeInputType) => {\n return concatIds(\n ariaLabelledBy,\n type === \"start\" ? startLabelId : endLabelId\n );\n };\n\n const getInputDescribedBy = () => {\n return concatIds(\n ariaDescribedBy,\n !error && validationError ? errorId : undefined\n );\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleInputFocus = (selector: TimeRangeInputType) => {\n if (disabled || readOnly) return;\n\n // Only run onFocus if not already focused\n if (!activeTimeSelector && !dropdownOpen) onFocus?.();\n\n setActiveTimeSelector(selector);\n setDropdownOpen(true);\n };\n\n const handleInputClick = (selector: TimeRangeInputType) => {\n if (disabled || readOnly) return;\n\n setActiveTimeSelector(selector);\n setDropdownOpen(true);\n (selector === \"start\" ? startInputRef : endInputRef).current?.select();\n };\n\n function handleKeyDownEvent(event: React.KeyboardEvent<HTMLInputElement>) {\n switch (event.code) {\n case \"Enter\":\n if (activeTimeSelector === \"start\") {\n handleStartTime(startTimeVal);\n } else if (activeTimeSelector === \"end\") {\n // Let handleBlur call handleTimeChange instead\n if (dropdownOpen) handleEndTime(endTimeVal);\n endInputRef.current?.blur();\n }\n break;\n case \"Tab\":\n handleTimeChange(startTimeVal, endTimeVal, {});\n break;\n default:\n break;\n }\n }\n\n const handleStartTime = (input: string) => {\n handleTimeChange(input, endTimeVal, { goToNextInput: true });\n };\n\n const handleEndTime = (input: string) => {\n handleTimeChange(startTimeVal, input, { triggerOnBlur: true });\n };\n\n const handleTimeChange = (\n startInput: string,\n endInput: string,\n {\n goToNextInput, // Used by handleStart to move to end input automatically\n triggerOnBlur, // Used by handleEnd/handleClear to trigger onBlur\n }: TimeChangeOptions\n ) => {\n const start = parseInput(startInput) ?? initialStartTimeVal;\n const end = parseInput(endInput) ?? initialEndTimeVal;\n\n setStartTimeVal(start);\n setEndTimeVal(end);\n\n const timeValue: TimeRangePickerValue = { start, end };\n\n // Trigger onChange if values have changed\n if (start !== initialStartTimeVal || end !== initialEndTimeVal) {\n onChange?.(timeValue);\n }\n\n // Go to end input only if start is a valid time\n if (goToNextInput && parseInput(startInput) !== undefined) {\n setActiveTimeSelector(\"end\");\n endInputRef.current?.select();\n }\n\n if (triggerOnBlur) {\n setActiveTimeSelector(null);\n setDropdownOpen(false);\n onBlur?.();\n }\n\n setInitialStartTimeVal(start);\n setInitialEndTimeVal(end);\n };\n\n const handleClear = (event: React.MouseEvent) => {\n event.stopPropagation();\n setStartTimeVal(\"\");\n setEndTimeVal(\"\");\n setInitialStartTimeVal(\"\");\n setInitialEndTimeVal(\"\");\n\n const timeValue: TimeRangePickerValue = {\n start: \"\",\n end: \"\",\n };\n\n onChange?.(timeValue);\n setActiveTimeSelector(null);\n setDropdownOpen(false);\n };\n\n const handleDismiss = () => {\n (activeTimeSelector === \"start\"\n ? startInputRef\n : endInputRef\n ).current?.focus();\n setDropdownOpen(false);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLDivElement, Element>) => {\n const target = event.relatedTarget as HTMLElement;\n\n const isFloatingElement =\n target?.matches?.(\"[data-floating-ui-focusable]\") ||\n target?.matches?.(\"[data-floating-ui-focus-guard]\");\n const isInsideNode =\n nodeRef.current && nodeRef.current.contains(target);\n\n // Condition when the calendar is closed and focus moved outside the component\n const shouldBlurWhenClosed =\n activeTimeSelector &&\n !dropdownOpen &&\n !isInsideNode &&\n !isFloatingElement;\n\n if (shouldBlurWhenClosed) {\n handleTimeChange(startTimeVal, endTimeVal, { triggerOnBlur: true });\n }\n };\n\n // NOTE: Dropdown dismissal (esc) does not trigger onClose\n const handleClose = (reason: OpenChangeReason | undefined) => {\n if (reason === \"outside-press\") {\n // No handleTimeChange to avoid duplicate call from handleBlur\n setActiveTimeSelector(null);\n setDropdownOpen(false);\n onBlur?.();\n } else {\n // Dropdown closed via exiting component (eg. tab)\n handleTimeChange(startTimeVal, endTimeVal, { triggerOnBlur: true });\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderClearButton = () => {\n if (\n !readOnly &&\n !disabled &&\n (startTimeVal?.length > 0 || endTimeVal?.length > 0)\n ) {\n return (\n <div className={inputWrapperStyles.clearButtonContainer}>\n <ClearButton\n onClick={handleClear}\n type=\"button\"\n aria-label=\"Clear\"\n />\n </div>\n );\n }\n };\n\n const renderDropdown = () => {\n if (activeTimeSelector === \"start\") {\n // Prioritise start time value. If non existent, use initial scroll time\n // If both are non existent, DropdownList will default to first option\n const startScrollTime =\n parseInput(startTimeVal) || parsedInitialStartScrollTime;\n\n return (\n <DropdownList\n listItems={startOptions}\n onSelectItem={handleStartTime}\n selectedItems={[startTimeVal]}\n topScrollItem={TimeHelper.findClosestFlooredTime(\n startScrollTime,\n startOptions\n )}\n listboxId={listboxId}\n ariaLabel={getDropdownAriaLabel()}\n disableItemFocus\n matchElementWidth\n />\n );\n } else {\n const endScrollTime =\n parseInput(endTimeVal) || parsedInitialEndScrollTime;\n\n return (\n <DropdownList\n listItems={endOptions}\n onSelectItem={handleEndTime}\n selectedItems={[endTimeVal]}\n topScrollItem={TimeHelper.findClosestFlooredTime(\n endScrollTime,\n endOptions\n )}\n listboxId={listboxId}\n ariaLabel={getDropdownAriaLabel()}\n disableItemFocus\n matchElementWidth\n />\n );\n }\n };\n\n const renderElement = () => (\n <InputWrapper\n ref={nodeRef}\n disabled={disabled}\n error={error || !!validationError}\n readOnly={readOnly}\n onBlur={handleBlur}\n role=\"group\"\n data-testid=\"timepicker-container\"\n className={styles.timeFieldContainer}\n >\n <VisuallyHidden id={startLabelId}>Start time</VisuallyHidden>\n <VisuallyHidden id={endLabelId}>End time</VisuallyHidden>\n\n <RangeInputInnerContainer\n error={error || !!validationError}\n currentActive={\n activeTimeSelector === null ? \"none\" : activeTimeSelector\n }\n >\n {/* From */}\n <BasicInput\n ref={startInputRef}\n onFocus={() => handleInputFocus(\"start\")}\n placeholder={\n activeTimeSelector === \"start\" ? \"hh:mm\" : \"From\"\n }\n onChange={(e) => setStartTimeVal(e.target.value)}\n value={startTimeVal}\n readOnly={readOnly || disabled}\n data-testid={\n otherProps[\"data-testid\"]\n ? `${otherProps[\"data-testid\"]}-timepicker-selector-start`\n : \"timepicker-selector-start\"\n }\n onClick={() => handleInputClick(\"start\")}\n onKeyDown={handleKeyDownEvent}\n autoComplete=\"off\"\n type=\"text\"\n role=\"combobox\"\n aria-labelledby={getInputLabelledBy(\"start\")}\n aria-describedby={getInputDescribedBy()}\n aria-expanded={\n dropdownOpen && activeTimeSelector === \"start\"\n }\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-invalid={error || ariaInvalid || !!validationError}\n aria-disabled={disabled}\n aria-readonly={readOnly}\n className={clsx(\n commonStyles.selectorInput,\n disabled && commonStyles.selectorInputDisabled\n )}\n />\n {/* To */}\n <BasicInput\n ref={endInputRef}\n onFocus={() => handleInputFocus(\"end\")}\n placeholder={activeTimeSelector === \"end\" ? \"hh:mm\" : \"To\"}\n onChange={(e) => setEndTimeVal(e.target.value)}\n value={endTimeVal}\n readOnly={readOnly || disabled}\n data-testid={\n otherProps[\"data-testid\"]\n ? `${otherProps[\"data-testid\"]}-timepicker-selector-end`\n : \"timepicker-selector-end\"\n }\n onClick={() => handleInputClick(\"end\")}\n onKeyDown={handleKeyDownEvent}\n autoComplete=\"off\"\n type=\"text\"\n role=\"combobox\"\n aria-labelledby={getInputLabelledBy(\"end\")}\n aria-describedby={getInputDescribedBy()}\n aria-expanded={dropdownOpen && activeTimeSelector === \"end\"}\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-invalid={\n error || ariaInvalid || !!validationError || undefined\n }\n aria-disabled={disabled || undefined}\n aria-readonly={readOnly || undefined}\n className={clsx(\n commonStyles.selectorInput,\n disabled && commonStyles.selectorInputDisabled\n )}\n />\n </RangeInputInnerContainer>\n {renderClearButton()}\n </InputWrapper>\n );\n\n const renderError = () =>\n // Only display internal error message if user does not provide one\n !error &&\n validationError && (\n <FormErrorMessage\n id={errorId}\n tabIndex={0}\n data-testid={id ? `${id}-error-message` : \"error-message\"}\n >\n {validationError}\n </FormErrorMessage>\n );\n\n return (\n <div\n id={id}\n {...otherProps}\n className={clsx(commonStyles.wrapper, otherProps.className)}\n >\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={dropdownOpen}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onClose={handleClose}\n onDismiss={handleDismiss}\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n {renderError()}\n </div>\n );\n};\n"],"names":["_a","id","disabled","error","value","format","readOnly","onChange","onFocus","onBlur","alignment","dropdownZIndex","startLimit","endLimit","initialScrollStartTime","initialScrollEndTime","interval","dropdownRootNode","ariaLabelledBy","ariaDescribedBy","ariaInvalid","otherProps","__rest","internalId","useId","activeTimeSelector","setActiveTimeSelector","useState","dropdownOpen","setDropdownOpen","validationError","setValidationError","startTimeVal","setStartTimeVal","endTimeVal","setEndTimeVal","initialStartTimeVal","setInitialStartTimeVal","initialEndTimeVal","setInitialEndTimeVal","nodeRef","useRef","startInputRef","endInputRef","listboxId","startLabelId","endLabelId","errorId","startOptions","useMemo","TimeHelper","generateTimings","endOptions","flooredStartVal","findClosestFlooredTime","slice","indexOf","parseInput","useCallback","input","parsedInitialStartScrollTime","parsedInitialEndScrollTime","useEffect","start","end","_b","undefined","to24Hour","document","activeElement","current","getDropdownAriaLabel","getInputLabelledBy","type","concatIds","getInputDescribedBy","handleInputFocus","selector","handleInputClick","select","handleKeyDownEvent","event","code","handleStartTime","handleEndTime","blur","handleTimeChange","goToNextInput","triggerOnBlur","startInput","endInput","_c","handleClear","stopPropagation","handleBlur","target","relatedTarget","isFloatingElement","matches","call","isInsideNode","contains","renderClearButton","length","_jsx","className","inputWrapperStyles.clearButtonContainer","children","ClearButton","onClick","_jsxs","Object","assign","clsx","commonStyles.wrapper","DropdownListState","ElementWithDropdown","enabled","isOpen","renderElement","InputWrapper","ref","role","styles.timeFieldContainer","VisuallyHidden","RangeInputInnerContainer","currentActive","BasicInput","placeholder","e","onKeyDown","autoComplete","commonStyles.selectorInput","commonStyles.selectorInputDisabled","renderDropdown","startScrollTime","DropdownList","listItems","onSelectItem","selectedItems","topScrollItem","ariaLabel","disableItemFocus","matchElementWidth","endScrollTime","onClose","reason","onDismiss","focus","offset","fitAvailableHeight","customZIndex","rootNode","FormErrorMessage","tabIndex"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"combobox-picker.js","sources":["../../../../src/time-range-picker/combobox-picker/combobox-picker.tsx"],"sourcesContent":["import type { OpenChangeReason } from \"@floating-ui/react\";\nimport clsx from \"clsx\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { FormErrorMessage } from \"../../form/form-label\";\nimport { concatIds, VisuallyHidden } from \"../../shared/accessibility\";\nimport { DropdownListState } from \"../../shared/dropdown-list\";\nimport { DropdownList } from \"../../shared/dropdown-list/dropdown-list\";\nimport { ElementWithDropdown } from \"../../shared/dropdown-wrapper\";\nimport {\n BasicInput,\n ClearButton,\n InputWrapper,\n} from \"../../shared/input-wrapper\";\nimport * as inputWrapperStyles from \"../../shared/input-wrapper/input-wrapper.styles\";\nimport { RangeInputInnerContainer } from \"../../shared/range-input-inner-container\";\nimport { useId } from \"../../util\";\nimport { TimeHelper } from \"../../util/time-helper\";\nimport * as commonStyles from \"../common.styles\";\nimport type { TimeRangePickerProps, TimeRangePickerValue } from \"../types\";\nimport * as styles from \"./combobox-picker.styles\";\n\ntype TimeRangeInputType = \"start\" | \"end\";\ninterface TimeChangeOptions {\n goToNextInput?: boolean | undefined;\n triggerOnBlur?: boolean | undefined;\n}\n\nexport const ComboboxPicker = ({\n id,\n disabled = false,\n error,\n value,\n format = \"12hr\",\n readOnly,\n onChange,\n onFocus,\n onBlur,\n alignment = \"left\",\n dropdownZIndex,\n startLimit,\n endLimit,\n initialScrollStartTime,\n initialScrollEndTime,\n interval = 15,\n dropdownRootNode,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n ...otherProps\n}: TimeRangePickerProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const internalId = useId();\n const [activeTimeSelector, setActiveTimeSelector] =\n useState<TimeRangeInputType | null>(null);\n const [dropdownOpen, setDropdownOpen] = useState<boolean>(false);\n const [validationError, setValidationError] = useState<string>(\"\");\n\n const [startTimeVal, setStartTimeVal] = useState<string>(\"\");\n const [endTimeVal, setEndTimeVal] = useState<string>(\"\");\n const [initialStartTimeVal, setInitialStartTimeVal] = useState<string>(\"\");\n const [initialEndTimeVal, setInitialEndTimeVal] = useState<string>(\"\");\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const startInputRef = useRef<HTMLInputElement>(null);\n const endInputRef = useRef<HTMLInputElement>(null);\n\n const listboxId = `${internalId}-listbox`;\n const startLabelId = `${internalId}-start-label`;\n const endLabelId = `${internalId}-end-label`;\n const errorId = `${internalId}-error-message`;\n\n const startOptions = useMemo(\n () =>\n TimeHelper.generateTimings(interval, format, startLimit, endLimit),\n [interval, format, startLimit, endLimit]\n );\n const endOptions = useMemo(() => {\n if (initialStartTimeVal === \"\") return startOptions;\n\n const flooredStartVal = TimeHelper.findClosestFlooredTime(\n initialStartTimeVal,\n startOptions\n );\n return flooredStartVal\n ? startOptions.slice(startOptions.indexOf(flooredStartVal))\n : [];\n }, [startOptions, initialStartTimeVal]);\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n const parseInput = useCallback(\n (input: string | undefined): string | undefined => {\n return TimeHelper.parseInput(input, format);\n },\n [format]\n );\n\n const parsedInitialStartScrollTime = useMemo(\n () => parseInput(initialScrollStartTime) ?? \"\",\n [initialScrollStartTime, parseInput]\n );\n\n const parsedInitialEndScrollTime = useMemo(\n () => parseInput(initialScrollEndTime) ?? \"\",\n [initialScrollEndTime, parseInput]\n );\n\n useEffect(() => {\n if (value) {\n const start = parseInput(value.start) ?? \"\";\n const end = parseInput(value.end) ?? \"\";\n\n setStartTimeVal(start);\n setEndTimeVal(end);\n setInitialStartTimeVal(start);\n setInitialEndTimeVal(end);\n }\n }, [value, parseInput]);\n\n // Validation for keyboard input\n useEffect(() => {\n if (error) {\n setDropdownOpen(false);\n return;\n }\n\n const start = parseInput(startTimeVal);\n const end = parseInput(endTimeVal);\n\n if (start === undefined) {\n setValidationError(\"Invalid start time\");\n } else if (end === undefined) {\n setValidationError(\"Invalid end time\");\n } else if (\n start !== \"\" &&\n end !== \"\" &&\n TimeHelper.to24Hour(end) < TimeHelper.to24Hour(start)\n ) {\n setValidationError(\"End time must be after start time\");\n } else {\n setValidationError(\"\");\n // Re-open dropdown if error was corrected\n if (\n document.activeElement === startInputRef.current ||\n document.activeElement === endInputRef.current\n ) {\n setDropdownOpen(true);\n }\n return;\n }\n\n // Hide dropdown so error message is visible\n setDropdownOpen(false);\n }, [startTimeVal, endTimeVal, parseInput, error]);\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const getDropdownAriaLabel = () => {\n if (activeTimeSelector === \"start\") {\n return \"Selecting for: Start time\";\n }\n\n if (activeTimeSelector === \"end\") {\n return \"Selecting for: End time\";\n }\n\n return undefined;\n };\n\n const getInputLabelledBy = (type: TimeRangeInputType) => {\n return concatIds(\n ariaLabelledBy,\n type === \"start\" ? startLabelId : endLabelId\n );\n };\n\n const getInputDescribedBy = () => {\n return concatIds(\n ariaDescribedBy,\n !error && validationError ? errorId : undefined\n );\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleInputFocus = (selector: TimeRangeInputType) => {\n if (disabled || readOnly) return;\n\n // Only run onFocus if not already focused\n if (!activeTimeSelector && !dropdownOpen) onFocus?.();\n\n setActiveTimeSelector(selector);\n setDropdownOpen(true);\n };\n\n const handleInputClick = (selector: TimeRangeInputType) => {\n if (disabled || readOnly) return;\n\n setActiveTimeSelector(selector);\n setDropdownOpen(true);\n (selector === \"start\" ? startInputRef : endInputRef).current?.select();\n };\n\n function handleKeyDownEvent(event: React.KeyboardEvent<HTMLInputElement>) {\n switch (event.code) {\n case \"Enter\":\n if (activeTimeSelector === \"start\") {\n handleStartTime(startTimeVal);\n } else if (activeTimeSelector === \"end\") {\n // Let handleBlur call handleTimeChange instead\n if (dropdownOpen) handleEndTime(endTimeVal);\n endInputRef.current?.blur();\n }\n break;\n case \"Tab\":\n handleTimeChange(startTimeVal, endTimeVal, {});\n break;\n default:\n break;\n }\n }\n\n const handleStartTime = (input: string) => {\n handleTimeChange(input, endTimeVal, { goToNextInput: true });\n };\n\n const handleEndTime = (input: string) => {\n handleTimeChange(startTimeVal, input, { triggerOnBlur: true });\n };\n\n const handleTimeChange = (\n startInput: string,\n endInput: string,\n {\n goToNextInput, // Used by handleStart to move to end input automatically\n triggerOnBlur, // Used by handleEnd/handleClear to trigger onBlur\n }: TimeChangeOptions\n ) => {\n const start = parseInput(startInput) ?? initialStartTimeVal;\n const end = parseInput(endInput) ?? initialEndTimeVal;\n\n setStartTimeVal(start);\n setEndTimeVal(end);\n\n const timeValue: TimeRangePickerValue = { start, end };\n\n // Trigger onChange if values have changed\n if (start !== initialStartTimeVal || end !== initialEndTimeVal) {\n onChange?.(timeValue);\n }\n\n // Go to end input only if start is a valid time\n if (goToNextInput && parseInput(startInput) !== undefined) {\n setActiveTimeSelector(\"end\");\n endInputRef.current?.select();\n }\n\n if (triggerOnBlur) {\n setActiveTimeSelector(null);\n setDropdownOpen(false);\n onBlur?.();\n }\n\n setInitialStartTimeVal(start);\n setInitialEndTimeVal(end);\n };\n\n const handleClear = (event: React.MouseEvent) => {\n event.stopPropagation();\n setStartTimeVal(\"\");\n setEndTimeVal(\"\");\n setInitialStartTimeVal(\"\");\n setInitialEndTimeVal(\"\");\n\n const timeValue: TimeRangePickerValue = {\n start: \"\",\n end: \"\",\n };\n\n onChange?.(timeValue);\n setActiveTimeSelector(null);\n setDropdownOpen(false);\n };\n\n const handleDismiss = () => {\n (activeTimeSelector === \"start\"\n ? startInputRef\n : endInputRef\n ).current?.focus();\n setDropdownOpen(false);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLDivElement, Element>) => {\n const target = event.relatedTarget as HTMLElement;\n\n const isFloatingElement =\n target?.matches?.(\"[data-floating-ui-focusable]\") ||\n target?.matches?.(\"[data-floating-ui-focus-guard]\");\n const isInsideNode =\n nodeRef.current && nodeRef.current.contains(target);\n\n // Condition when the calendar is closed and focus moved outside the component\n const shouldBlurWhenClosed =\n activeTimeSelector &&\n !dropdownOpen &&\n !isInsideNode &&\n !isFloatingElement;\n\n if (shouldBlurWhenClosed) {\n handleTimeChange(startTimeVal, endTimeVal, { triggerOnBlur: true });\n }\n };\n\n // NOTE: Dropdown dismissal (esc) does not trigger onClose\n const handleClose = (reason: OpenChangeReason | undefined) => {\n if (reason === \"outside-press\") {\n // No handleTimeChange to avoid duplicate call from handleBlur\n setActiveTimeSelector(null);\n setDropdownOpen(false);\n onBlur?.();\n } else {\n // Dropdown closed via exiting component (eg. tab)\n handleTimeChange(startTimeVal, endTimeVal, { triggerOnBlur: true });\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderClearButton = () => {\n if (\n !readOnly &&\n !disabled &&\n (startTimeVal?.length > 0 || endTimeVal?.length > 0)\n ) {\n return (\n <div className={inputWrapperStyles.clearButtonContainer}>\n <ClearButton\n onClick={handleClear}\n type=\"button\"\n aria-label=\"Clear\"\n />\n </div>\n );\n }\n };\n\n const renderDropdown = () => {\n if (activeTimeSelector === \"start\") {\n // Prioritise start time value. If non existent, use initial scroll time\n // If both are non existent, DropdownList will default to first option\n const startScrollTime =\n parseInput(startTimeVal) || parsedInitialStartScrollTime;\n\n return (\n <DropdownList\n listItems={startOptions}\n onSelectItem={handleStartTime}\n selectedItems={[startTimeVal]}\n topScrollItem={TimeHelper.findClosestFlooredTime(\n startScrollTime,\n startOptions\n )}\n listboxId={listboxId}\n ariaLabel={getDropdownAriaLabel()}\n disableItemFocus\n matchElementWidth\n />\n );\n } else {\n const endScrollTime =\n parseInput(endTimeVal) || parsedInitialEndScrollTime;\n\n return (\n <DropdownList\n listItems={endOptions}\n onSelectItem={handleEndTime}\n selectedItems={[endTimeVal]}\n topScrollItem={TimeHelper.findClosestFlooredTime(\n endScrollTime,\n endOptions\n )}\n listboxId={listboxId}\n ariaLabel={getDropdownAriaLabel()}\n disableItemFocus\n matchElementWidth\n />\n );\n }\n };\n\n const renderElement = () => (\n <InputWrapper\n ref={nodeRef}\n disabled={disabled}\n error={error || !!validationError}\n readOnly={readOnly}\n onBlur={handleBlur}\n role=\"group\"\n data-testid=\"timepicker-container\"\n className={styles.timeFieldContainer}\n >\n <VisuallyHidden id={startLabelId}>Start time</VisuallyHidden>\n <VisuallyHidden id={endLabelId}>End time</VisuallyHidden>\n\n <RangeInputInnerContainer\n error={error || !!validationError}\n currentActive={\n activeTimeSelector === null ? \"none\" : activeTimeSelector\n }\n >\n {/* From */}\n <BasicInput\n ref={startInputRef}\n onFocus={() => handleInputFocus(\"start\")}\n placeholder={\n activeTimeSelector === \"start\" ? \"hh:mm\" : \"From\"\n }\n onChange={(e) => setStartTimeVal(e.target.value)}\n value={startTimeVal}\n readOnly={readOnly || disabled}\n data-testid={\n otherProps[\"data-testid\"]\n ? `${otherProps[\"data-testid\"]}-timepicker-selector-start`\n : \"timepicker-selector-start\"\n }\n onClick={() => handleInputClick(\"start\")}\n onKeyDown={handleKeyDownEvent}\n autoComplete=\"off\"\n type=\"text\"\n role=\"combobox\"\n aria-labelledby={getInputLabelledBy(\"start\")}\n aria-describedby={getInputDescribedBy()}\n aria-expanded={\n dropdownOpen && activeTimeSelector === \"start\"\n }\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-invalid={error || ariaInvalid || !!validationError}\n aria-disabled={disabled}\n aria-readonly={readOnly}\n className={clsx(\n commonStyles.selectorInput,\n disabled && commonStyles.selectorInputDisabled\n )}\n />\n {/* To */}\n <BasicInput\n ref={endInputRef}\n onFocus={() => handleInputFocus(\"end\")}\n placeholder={activeTimeSelector === \"end\" ? \"hh:mm\" : \"To\"}\n onChange={(e) => setEndTimeVal(e.target.value)}\n value={endTimeVal}\n readOnly={readOnly || disabled}\n data-testid={\n otherProps[\"data-testid\"]\n ? `${otherProps[\"data-testid\"]}-timepicker-selector-end`\n : \"timepicker-selector-end\"\n }\n onClick={() => handleInputClick(\"end\")}\n onKeyDown={handleKeyDownEvent}\n autoComplete=\"off\"\n type=\"text\"\n role=\"combobox\"\n aria-labelledby={getInputLabelledBy(\"end\")}\n aria-describedby={getInputDescribedBy()}\n aria-expanded={dropdownOpen && activeTimeSelector === \"end\"}\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-invalid={\n error || ariaInvalid || !!validationError || undefined\n }\n aria-disabled={disabled || undefined}\n aria-readonly={readOnly || undefined}\n className={clsx(\n commonStyles.selectorInput,\n disabled && commonStyles.selectorInputDisabled\n )}\n />\n </RangeInputInnerContainer>\n {renderClearButton()}\n </InputWrapper>\n );\n\n const renderError = () =>\n // Only display internal error message if user does not provide one\n !error &&\n validationError && (\n <FormErrorMessage\n id={errorId}\n tabIndex={0}\n data-testid={id ? `${id}-error-message` : \"error-message\"}\n >\n {validationError}\n </FormErrorMessage>\n );\n\n return (\n <div\n id={id}\n {...otherProps}\n className={clsx(commonStyles.wrapper, otherProps.className)}\n >\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={dropdownOpen}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onClose={handleClose}\n onDismiss={handleDismiss}\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n {renderError()}\n </div>\n );\n};\n"],"names":["_a","id","disabled","error","value","format","readOnly","onChange","onFocus","onBlur","alignment","dropdownZIndex","startLimit","endLimit","initialScrollStartTime","initialScrollEndTime","interval","dropdownRootNode","ariaLabelledBy","ariaDescribedBy","ariaInvalid","otherProps","__rest","internalId","useId","activeTimeSelector","setActiveTimeSelector","useState","dropdownOpen","setDropdownOpen","validationError","setValidationError","startTimeVal","setStartTimeVal","endTimeVal","setEndTimeVal","initialStartTimeVal","setInitialStartTimeVal","initialEndTimeVal","setInitialEndTimeVal","nodeRef","useRef","startInputRef","endInputRef","listboxId","startLabelId","endLabelId","errorId","startOptions","useMemo","TimeHelper","generateTimings","endOptions","flooredStartVal","findClosestFlooredTime","slice","indexOf","parseInput","useCallback","input","parsedInitialStartScrollTime","parsedInitialEndScrollTime","useEffect","start","end","_b","undefined","to24Hour","document","activeElement","current","getDropdownAriaLabel","getInputLabelledBy","type","concatIds","getInputDescribedBy","handleInputFocus","selector","handleInputClick","select","handleKeyDownEvent","event","code","handleStartTime","handleEndTime","blur","handleTimeChange","goToNextInput","triggerOnBlur","startInput","endInput","_c","handleClear","stopPropagation","handleBlur","target","relatedTarget","isFloatingElement","matches","call","isInsideNode","contains","renderClearButton","length","_jsx","className","inputWrapperStyles.clearButtonContainer","children","ClearButton","onClick","_jsxs","Object","assign","clsx","commonStyles.wrapper","DropdownListState","ElementWithDropdown","enabled","isOpen","renderElement","InputWrapper","ref","role","styles.timeFieldContainer","VisuallyHidden","RangeInputInnerContainer","currentActive","BasicInput","placeholder","e","onKeyDown","autoComplete","commonStyles.selectorInput","commonStyles.selectorInputDisabled","renderDropdown","startScrollTime","DropdownList","listItems","onSelectItem","selectedItems","topScrollItem","ariaLabel","disableItemFocus","matchElementWidth","endScrollTime","onClose","reason","onDismiss","focus","offset","fitAvailableHeight","customZIndex","rootNode","FormErrorMessage","tabIndex"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time-range-picker.js","sources":["../../../src/time-range-picker/time-range-picker.tsx"],"sourcesContent":["import { ComboboxPicker } from \"./combobox-picker/combobox-picker\";\nimport { DialPicker } from \"./dial-picker/dial-picker\";\nimport type { TimeRangePickerProps } from \"./types\";\n\n/**\n * A two-field time picker for selecting a start and end time.\n *\n * Use `TimeRangePicker` when users need to define a time range.\n */\nexport const TimeRangePicker = ({\n variant = \"dial\",\n ...otherProps\n}: TimeRangePickerProps) => {\n if (variant === \"combobox\") {\n return <ComboboxPicker {...otherProps} />;\n } else {\n return <DialPicker {...otherProps} />;\n }\n};\n"],"names":["_a","variant","otherProps","__rest","_jsx","ComboboxPicker","Object","assign","DialPicker"],"mappings":"
|
|
1
|
+
{"version":3,"file":"time-range-picker.js","sources":["../../../src/time-range-picker/time-range-picker.tsx"],"sourcesContent":["import { ComboboxPicker } from \"./combobox-picker/combobox-picker\";\nimport { DialPicker } from \"./dial-picker/dial-picker\";\nimport type { TimeRangePickerProps } from \"./types\";\n\n// @catalog\n/**\n * A two-field time picker for selecting a start and end time.\n *\n * Use `TimeRangePicker` when users need to define a time range.\n */\nexport const TimeRangePicker = ({\n variant = \"dial\",\n ...otherProps\n}: TimeRangePickerProps) => {\n if (variant === \"combobox\") {\n return <ComboboxPicker {...otherProps} />;\n } else {\n return <DialPicker {...otherProps} />;\n }\n};\n"],"names":["_a","variant","otherProps","__rest","_jsx","ComboboxPicker","Object","assign","DialPicker"],"mappings":"uMAUgCA,QAAAC,QAC5BA,EAAU,QAAMD,EACbE,EAAUC,SAAAH,EAFe,aAI5B,MAAgB,aAAZC,EACOG,EAAAA,IAACC,EAAAA,eAAcC,OAAAC,OAAA,CAAA,EAAKL,IAEpBE,EAAAA,IAACI,EAAAA,WAAUF,OAAAC,OAAA,CAAA,EAAKL,GAC3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time-slot-bar.js","sources":["../../../src/time-slot-bar/time-slot-bar.tsx"],"sourcesContent":["import { ChevronLeftIcon } from \"@lifesg/react-icons/chevron-left\";\nimport { ChevronRightIcon } from \"@lifesg/react-icons/chevron-right\";\nimport clsx from \"clsx\";\nimport dayjs, { type Dayjs } from \"dayjs\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { TimeSlot } from \"../shared/time-slot\";\nimport { Typography } from \"../typography\";\nimport { TimeHelper } from \"../util/time-helper\";\nimport { getCellWidth, TimeSlotBarHelper } from \"./helper\";\nimport type { Direction } from \"./internal-types\";\nimport * as styles from \"./time-slot-bar.styles\";\nimport TimeSlotDivider from \"./time-slot-divider\";\nimport TimeSlotItem from \"./time-slot-item\";\nimport type {\n TimeSlot as TTimeSlot,\n TimeSlotBarProps,\n TimeSlotBarRef,\n TimeSlotBarVariant,\n} from \"./types\";\n\nconst CELL_DURATION = 30; // In minutes\n\nconst Component = (props: TimeSlotBarProps, ref: React.Ref<TimeSlotBarRef>) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n \"data-testid\": testId,\n className,\n variant = \"default\",\n startTime,\n endTime,\n slots,\n onSlotClick,\n onClick,\n styleAttributes,\n initialScrollTime,\n roundInitialScrollTime = true,\n } = props;\n const barRef = useRef<HTMLDivElement>(null);\n const [scrollPosition, setScrollPosition] = useState<number>(0);\n const [clientWidth, setClientWidth] = useState<number>(0);\n const cellWidth = getCellWidth(variant);\n\n const adjustedStartTime = TimeSlotBarHelper.adjustTimeForMarker(\n startTime,\n \"start\"\n );\n const adjustedEndTime = TimeSlotBarHelper.adjustTimeForMarker(\n endTime,\n \"end\"\n );\n\n const SCROLL_INCREMENT = cellWidth * 2.5; // In px. Each scroll increment corresponds to 75mins\n\n // Expose imperative handle\n useImperativeHandle(ref, () => ({\n resetScroll,\n }));\n\n const { summary: slotsSummary, computedSlots: allSlots } = useMemo(() => {\n return TimeSlotBarHelper.processSlots(\n { start: adjustedStartTime, end: adjustedEndTime },\n slots,\n variant\n );\n }, [adjustedStartTime, adjustedEndTime, slots, variant]);\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n\n useEffect(() => {\n const container = barRef.current;\n if (container) {\n container.addEventListener(\"scroll\", handleScroll);\n // Initialize clientWidth on mount\n setClientWidth(container.clientWidth);\n }\n\n return () => {\n if (container) {\n container.removeEventListener(\"scroll\", handleScroll);\n }\n };\n }, []);\n\n // Initial scroll on mount and when dependencies change\n useEffect(() => {\n resetScroll();\n }, [initialScrollTime, cellWidth, startTime, endTime]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n\n const handleScroll = () => {\n if (barRef.current) {\n setScrollPosition(barRef.current.scrollLeft);\n }\n };\n\n const handleArrowButtonClick = (direction: Direction) => {\n if (barRef.current) {\n barRef.current.scrollBy({\n left:\n direction === \"left\" ? -SCROLL_INCREMENT : SCROLL_INCREMENT,\n behavior: \"smooth\",\n });\n }\n };\n\n const handleResize = () => {\n if (barRef.current) {\n setClientWidth(barRef.current.clientWidth);\n }\n };\n\n useResizeDetector({\n onResize: handleResize,\n targetRef: barRef,\n refreshMode: \"debounce\",\n refreshRate: 50,\n });\n\n // ===========================================================================\n // HELPER FUNCTIONS\n // ===========================================================================\n /**\n * NOTE: Special condition\n * Show ellipsis only if the slotWidth is smaller or equal to\n * 15min interval\n */\n const showFullEllipsis = (slotWidth: number) => {\n return slotWidth <= cellWidth / 2;\n };\n\n const getDataTestId = (subStr: string) => {\n if (!testId) return undefined;\n return `${testId}-${subStr}`;\n };\n\n /**\n * Function to determine if a long time marker should be displayed\n * For minified variant the long time marker is displayed every alternate hour\n */\n const shouldDisplayLongTimeMarker = (\n currentTime: Dayjs,\n isStartHourEven: boolean, // To determine if the first hour is even or odd for minified\n variant: TimeSlotBarVariant\n ) => {\n const isHour = currentTime.minute() === 0;\n\n if (variant === \"default\") {\n return isHour;\n }\n\n const isAlternateHour =\n isHour &&\n (isStartHourEven\n ? currentTime.hour() % 2 === 0\n : currentTime.hour() % 2 === 1);\n\n return isAlternateHour;\n };\n\n // Function to reset scroll to initialScrollTime\n const resetScroll = () => {\n if (initialScrollTime && barRef.current && cellWidth > 0) {\n const scrollPosition = TimeHelper.calculateScrollPosition({\n scrollTime: initialScrollTime,\n minTime: adjustedStartTime,\n maxTime: adjustedEndTime,\n interval: CELL_DURATION,\n intervalWidth: cellWidth,\n options: {\n roundToInterval: roundInitialScrollTime,\n },\n });\n\n if (scrollPosition !== null) {\n barRef.current.scrollLeft = scrollPosition;\n }\n }\n };\n\n const isVariant = (v: TimeSlotBarVariant) => {\n if (variant === v) return true;\n return false;\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n\n // Render time markers\n const renderTimeMarkers = () => {\n const timeMarkers = [];\n const startTimeFormatted = dayjs(adjustedStartTime, \"HH:mm\");\n const endTimeFormatted = dayjs(adjustedEndTime, \"HH:mm\");\n\n const isStartHourEven = startTimeFormatted.hour() % 2 === 0;\n\n for (\n let currentTime = startTimeFormatted;\n currentTime.isBefore(endTimeFormatted);\n currentTime = currentTime.add(CELL_DURATION, \"minute\")\n ) {\n const displayLongTimeMarker = shouldDisplayLongTimeMarker(\n currentTime,\n isStartHourEven,\n variant\n );\n\n timeMarkers.push(\n <div\n data-testid={`${currentTime.format(\"HH:mm\")}-marker`}\n key={currentTime.format(\"HH:mm\")}\n className={clsx(\n styles.timeMarker,\n variant === \"default\"\n ? styles.timeMarkerDefault\n : styles.timeMarkerMinified,\n displayLongTimeMarker && styles.timeMarkerLong\n )}\n >\n {displayLongTimeMarker && (\n <Typography.BodyXS\n className={styles.timeLabel}\n weight=\"semibold\"\n >\n {TimeSlotBarHelper.formatHourlyDisplay(\n currentTime.format(\"HH:mm\")\n )}\n </Typography.BodyXS>\n )}\n </div>\n );\n }\n return timeMarkers;\n };\n\n // Render default time slot (aka background)\n const renderDefaultTimeSlots = () => {\n if (!styleAttributes) return;\n\n const {\n backgroundColor,\n backgroundColor2,\n hoverBackgroundColor,\n hoverBackgroundColor2,\n styleType = \"default\",\n } = styleAttributes;\n\n const slotWidth = TimeSlotBarHelper.calculateWidth(\n adjustedStartTime,\n adjustedEndTime,\n cellWidth\n );\n\n const isClickable = !!onClick && isVariant(\"default\");\n\n return (\n <>\n <TimeSlotDivider variant={variant} />\n <TimeSlotItem\n key={\"default-timeslot\"}\n variant={variant}\n dataTestId={getDataTestId(\"default-timeslot\")}\n slotWidth={slotWidth}\n slotOffset={0}\n onClick={isClickable ? onClick : undefined}\n >\n <TimeSlot\n className={styles.timeSlotItemContent}\n styleType={styleType}\n bgColor={backgroundColor}\n bgColor2={backgroundColor2}\n hoverBgColor={hoverBackgroundColor}\n hoverBgColor2={hoverBackgroundColor2}\n clickable={isClickable}\n />\n </TimeSlotItem>\n </>\n );\n };\n\n // Render time slots\n const renderTimeSlots = () => {\n return allSlots.map((slot) => {\n const {\n id,\n startTime: slotStartTime,\n endTime: slotEndTime,\n label,\n clickable = true,\n styleAttributes,\n ariaLabel,\n } = slot;\n\n const {\n color,\n styleType = \"default\",\n backgroundColor,\n backgroundColor2,\n hoverBackgroundColor,\n hoverBackgroundColor2,\n } = styleAttributes;\n\n const slotWidth = TimeSlotBarHelper.calculateWidth(\n slotStartTime,\n slotEndTime,\n cellWidth\n );\n const slotOffset = TimeSlotBarHelper.calculateWidth(\n adjustedStartTime,\n slotStartTime,\n cellWidth\n );\n\n const isClickable = clickable && variant === \"default\";\n const showLabel = isVariant(\"default\") && label;\n\n const handleSlotClick =\n (clickedSlot: TTimeSlot & { ariaLabel?: string }) =>\n (evt: React.MouseEvent<HTMLElement>) => {\n evt.stopPropagation();\n\n const { ariaLabel: _, ...slot } = clickedSlot;\n if (isClickable) onSlotClick(slot);\n };\n\n return (\n <div key={id} role=\"gridcell\">\n <TimeSlotDivider\n variant={variant}\n left={slotOffset}\n dataTestId=\"start-border\"\n />\n <TimeSlotItem\n variant={variant}\n dataTestId={getDataTestId(`${id}-timeslot`)}\n slotWidth={slotWidth}\n slotOffset={slotOffset}\n color={color}\n onClick={handleSlotClick(slot)}\n >\n <TimeSlot\n className={styles.timeSlotItemContent}\n styleType={styleType}\n bgColor={backgroundColor}\n bgColor2={backgroundColor2}\n hoverBgColor={hoverBackgroundColor}\n hoverBgColor2={hoverBackgroundColor2}\n clickable={isClickable}\n >\n {!!ariaLabel && (\n <VisuallyHidden>\n <button\n type=\"button\" // overrides default type=\"submit\" when used with <form>\n aria-disabled={!isClickable}\n aria-label={ariaLabel}\n onClick={handleSlotClick(slot)} // use `button` element native keyboard activation handling\n />\n </VisuallyHidden>\n )}\n\n {showLabel && (\n <Typography.BodyXS\n className={styles.cellText}\n weight={\"semibold\"}\n aria-hidden={!ariaLabel}\n >\n {showFullEllipsis(slotWidth)\n ? \"...\"\n : label}\n </Typography.BodyXS>\n )}\n </TimeSlot>\n </TimeSlotItem>\n {endTime !== slotEndTime && (\n <TimeSlotDivider\n variant={variant}\n dataTestId=\"end-border\"\n left={slotOffset + slotWidth}\n />\n )}\n </div>\n );\n });\n };\n\n const renderArrowButton = (direction: Direction) => {\n const isLeft = direction === \"left\";\n const totalScrollableWidth = TimeSlotBarHelper.calculateWidth(\n adjustedStartTime,\n adjustedEndTime,\n cellWidth\n );\n const hasContentOnLeft = scrollPosition > 0;\n const hasContentOnRight =\n scrollPosition + clientWidth < totalScrollableWidth;\n const shouldShowArrow = isLeft ? hasContentOnLeft : hasContentOnRight;\n\n if (!shouldShowArrow) return null;\n\n const directionClass = isLeft\n ? styles.arrowButtonLeft\n : styles.arrowButtonRight;\n const variantClass =\n variant === \"default\"\n ? styles.arrowButtonDefault\n : styles.arrowButtonMinified;\n const arrowIcon = isLeft ? (\n <ChevronLeftIcon className={styles.arrowIcon} />\n ) : (\n <ChevronRightIcon className={styles.arrowIcon} />\n );\n\n return (\n <ClickableIcon\n data-testid={getDataTestId(`arrow-${direction}`)}\n aria-hidden\n tabIndex={-1}\n className={clsx(\n styles.arrowButton,\n directionClass,\n variantClass\n )}\n focusHighlight={false}\n focusOutline=\"none\"\n onClick={() => {\n handleArrowButtonClick(direction);\n }}\n >\n {arrowIcon}\n </ClickableIcon>\n );\n };\n\n return (\n <div className={clsx(styles.container, className)}>\n <div\n data-testid={testId}\n ref={barRef}\n className={clsx(\n styles.timeSlotBarContainer,\n variant === \"default\"\n ? styles.containerDefault\n : styles.containerMinified\n )}\n >\n <div\n className={styles.timeMarkerWrapper}\n data-testid={getDataTestId(\"time-marker-wrapper\")}\n data-id=\"marker-wrapper\"\n >\n {renderTimeMarkers()}\n </div>\n <div role=\"grid\" aria-label={slotsSummary} tabIndex={0}>\n <div\n className={styles.timeSlotWrapper}\n data-testid={getDataTestId(\"time-slot-wrapper\")}\n data-id=\"slot-wrapper\"\n role=\"row\"\n >\n {renderDefaultTimeSlots()}\n {renderTimeSlots()}\n </div>\n </div>\n </div>\n {renderArrowButton(\"left\")}\n {renderArrowButton(\"right\")}\n </div>\n );\n};\n\n/**\n * A horizontally scrollable timeline bar that visualises time slots across a\n * defined time range.\n *\n * Use `TimeSlotBar` to display availability, bookings, or schedule occupancy\n * as coloured cells on a shared time axis.\n */\nexport const TimeSlotBar = forwardRef<TimeSlotBarRef, TimeSlotBarProps>(\n Component\n);\n"],"names":["TimeSlotBar","forwardRef","props","ref","testId","className","variant","startTime","endTime","slots","onSlotClick","onClick","styleAttributes","initialScrollTime","roundInitialScrollTime","barRef","useRef","scrollPosition","setScrollPosition","useState","clientWidth","setClientWidth","cellWidth","getCellWidth","adjustedStartTime","TimeSlotBarHelper","adjustTimeForMarker","adjustedEndTime","SCROLL_INCREMENT","useImperativeHandle","resetScroll","summary","slotsSummary","computedSlots","allSlots","useMemo","processSlots","start","end","useEffect","container","current","addEventListener","handleScroll","removeEventListener","scrollLeft","useResizeDetector","onResize","targetRef","refreshMode","refreshRate","showFullEllipsis","slotWidth","getDataTestId","subStr","shouldDisplayLongTimeMarker","currentTime","isStartHourEven","isHour","minute","hour","TimeHelper","calculateScrollPosition","scrollTime","minTime","maxTime","interval","intervalWidth","options","roundToInterval","isVariant","v","renderArrowButton","direction","isLeft","totalScrollableWidth","calculateWidth","directionClass","styles.arrowButtonLeft","styles.arrowButtonRight","variantClass","styles.arrowButtonDefault","styles.arrowButtonMinified","arrowIcon","_jsx","ChevronLeftIcon","styles.arrowIcon","ChevronRightIcon","ClickableIcon","tabIndex","clsx","styles.arrowButton","focusHighlight","focusOutline","scrollBy","left","behavior","handleArrowButtonClick","children","_jsxs","styles.container","styles.timeSlotBarContainer","styles.containerDefault","styles.containerMinified","styles.timeMarkerWrapper","timeMarkers","startTimeFormatted","dayjs","endTimeFormatted","isBefore","add","displayLongTimeMarker","push","format","styles.timeMarker","styles.timeMarkerDefault","styles.timeMarkerMinified","styles.timeMarkerLong","Typography","BodyXS","styles.timeLabel","weight","formatHourlyDisplay","renderTimeMarkers","role","styles.timeSlotWrapper","backgroundColor","backgroundColor2","hoverBackgroundColor","hoverBackgroundColor2","styleType","isClickable","_Fragment","TimeSlotDivider","TimeSlotItem","dataTestId","slotOffset","undefined","TimeSlot","styles.timeSlotItemContent","bgColor","bgColor2","hoverBgColor","hoverBgColor2","clickable","renderDefaultTimeSlots","map","slot","id","slotStartTime","slotEndTime","label","ariaLabel","color","showLabel","handleSlotClick","clickedSlot","evt","stopPropagation","_","__rest","VisuallyHidden","type","styles.cellText"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"time-slot-bar.js","sources":["../../../src/time-slot-bar/time-slot-bar.tsx"],"sourcesContent":["import { ChevronLeftIcon } from \"@lifesg/react-icons/chevron-left\";\nimport { ChevronRightIcon } from \"@lifesg/react-icons/chevron-right\";\nimport clsx from \"clsx\";\nimport dayjs, { type Dayjs } from \"dayjs\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { TimeSlot } from \"../shared/time-slot\";\nimport { Typography } from \"../typography\";\nimport { TimeHelper } from \"../util/time-helper\";\nimport { getCellWidth, TimeSlotBarHelper } from \"./helper\";\nimport type { Direction } from \"./internal-types\";\nimport * as styles from \"./time-slot-bar.styles\";\nimport TimeSlotDivider from \"./time-slot-divider\";\nimport TimeSlotItem from \"./time-slot-item\";\nimport type {\n TimeSlot as TTimeSlot,\n TimeSlotBarProps,\n TimeSlotBarRef,\n TimeSlotBarVariant,\n} from \"./types\";\n\nconst CELL_DURATION = 30; // In minutes\n\nconst Component = (props: TimeSlotBarProps, ref: React.Ref<TimeSlotBarRef>) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n \"data-testid\": testId,\n className,\n variant = \"default\",\n startTime,\n endTime,\n slots,\n onSlotClick,\n onClick,\n styleAttributes,\n initialScrollTime,\n roundInitialScrollTime = true,\n } = props;\n const barRef = useRef<HTMLDivElement>(null);\n const [scrollPosition, setScrollPosition] = useState<number>(0);\n const [clientWidth, setClientWidth] = useState<number>(0);\n const cellWidth = getCellWidth(variant);\n\n const adjustedStartTime = TimeSlotBarHelper.adjustTimeForMarker(\n startTime,\n \"start\"\n );\n const adjustedEndTime = TimeSlotBarHelper.adjustTimeForMarker(\n endTime,\n \"end\"\n );\n\n const SCROLL_INCREMENT = cellWidth * 2.5; // In px. Each scroll increment corresponds to 75mins\n\n // Expose imperative handle\n useImperativeHandle(ref, () => ({\n resetScroll,\n }));\n\n const { summary: slotsSummary, computedSlots: allSlots } = useMemo(() => {\n return TimeSlotBarHelper.processSlots(\n { start: adjustedStartTime, end: adjustedEndTime },\n slots,\n variant\n );\n }, [adjustedStartTime, adjustedEndTime, slots, variant]);\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n\n useEffect(() => {\n const container = barRef.current;\n if (container) {\n container.addEventListener(\"scroll\", handleScroll);\n // Initialize clientWidth on mount\n setClientWidth(container.clientWidth);\n }\n\n return () => {\n if (container) {\n container.removeEventListener(\"scroll\", handleScroll);\n }\n };\n }, []);\n\n // Initial scroll on mount and when dependencies change\n useEffect(() => {\n resetScroll();\n }, [initialScrollTime, cellWidth, startTime, endTime]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n\n const handleScroll = () => {\n if (barRef.current) {\n setScrollPosition(barRef.current.scrollLeft);\n }\n };\n\n const handleArrowButtonClick = (direction: Direction) => {\n if (barRef.current) {\n barRef.current.scrollBy({\n left:\n direction === \"left\" ? -SCROLL_INCREMENT : SCROLL_INCREMENT,\n behavior: \"smooth\",\n });\n }\n };\n\n const handleResize = () => {\n if (barRef.current) {\n setClientWidth(barRef.current.clientWidth);\n }\n };\n\n useResizeDetector({\n onResize: handleResize,\n targetRef: barRef,\n refreshMode: \"debounce\",\n refreshRate: 50,\n });\n\n // ===========================================================================\n // HELPER FUNCTIONS\n // ===========================================================================\n /**\n * NOTE: Special condition\n * Show ellipsis only if the slotWidth is smaller or equal to\n * 15min interval\n */\n const showFullEllipsis = (slotWidth: number) => {\n return slotWidth <= cellWidth / 2;\n };\n\n const getDataTestId = (subStr: string) => {\n if (!testId) return undefined;\n return `${testId}-${subStr}`;\n };\n\n /**\n * Function to determine if a long time marker should be displayed\n * For minified variant the long time marker is displayed every alternate hour\n */\n const shouldDisplayLongTimeMarker = (\n currentTime: Dayjs,\n isStartHourEven: boolean, // To determine if the first hour is even or odd for minified\n variant: TimeSlotBarVariant\n ) => {\n const isHour = currentTime.minute() === 0;\n\n if (variant === \"default\") {\n return isHour;\n }\n\n const isAlternateHour =\n isHour &&\n (isStartHourEven\n ? currentTime.hour() % 2 === 0\n : currentTime.hour() % 2 === 1);\n\n return isAlternateHour;\n };\n\n // Function to reset scroll to initialScrollTime\n const resetScroll = () => {\n if (initialScrollTime && barRef.current && cellWidth > 0) {\n const scrollPosition = TimeHelper.calculateScrollPosition({\n scrollTime: initialScrollTime,\n minTime: adjustedStartTime,\n maxTime: adjustedEndTime,\n interval: CELL_DURATION,\n intervalWidth: cellWidth,\n options: {\n roundToInterval: roundInitialScrollTime,\n },\n });\n\n if (scrollPosition !== null) {\n barRef.current.scrollLeft = scrollPosition;\n }\n }\n };\n\n const isVariant = (v: TimeSlotBarVariant) => {\n if (variant === v) return true;\n return false;\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n\n // Render time markers\n const renderTimeMarkers = () => {\n const timeMarkers = [];\n const startTimeFormatted = dayjs(adjustedStartTime, \"HH:mm\");\n const endTimeFormatted = dayjs(adjustedEndTime, \"HH:mm\");\n\n const isStartHourEven = startTimeFormatted.hour() % 2 === 0;\n\n for (\n let currentTime = startTimeFormatted;\n currentTime.isBefore(endTimeFormatted);\n currentTime = currentTime.add(CELL_DURATION, \"minute\")\n ) {\n const displayLongTimeMarker = shouldDisplayLongTimeMarker(\n currentTime,\n isStartHourEven,\n variant\n );\n\n timeMarkers.push(\n <div\n data-testid={`${currentTime.format(\"HH:mm\")}-marker`}\n key={currentTime.format(\"HH:mm\")}\n className={clsx(\n styles.timeMarker,\n variant === \"default\"\n ? styles.timeMarkerDefault\n : styles.timeMarkerMinified,\n displayLongTimeMarker && styles.timeMarkerLong\n )}\n >\n {displayLongTimeMarker && (\n <Typography.BodyXS\n className={styles.timeLabel}\n weight=\"semibold\"\n >\n {TimeSlotBarHelper.formatHourlyDisplay(\n currentTime.format(\"HH:mm\")\n )}\n </Typography.BodyXS>\n )}\n </div>\n );\n }\n return timeMarkers;\n };\n\n // Render default time slot (aka background)\n const renderDefaultTimeSlots = () => {\n if (!styleAttributes) return;\n\n const {\n backgroundColor,\n backgroundColor2,\n hoverBackgroundColor,\n hoverBackgroundColor2,\n styleType = \"default\",\n } = styleAttributes;\n\n const slotWidth = TimeSlotBarHelper.calculateWidth(\n adjustedStartTime,\n adjustedEndTime,\n cellWidth\n );\n\n const isClickable = !!onClick && isVariant(\"default\");\n\n return (\n <>\n <TimeSlotDivider variant={variant} />\n <TimeSlotItem\n key={\"default-timeslot\"}\n variant={variant}\n dataTestId={getDataTestId(\"default-timeslot\")}\n slotWidth={slotWidth}\n slotOffset={0}\n onClick={isClickable ? onClick : undefined}\n >\n <TimeSlot\n className={styles.timeSlotItemContent}\n styleType={styleType}\n bgColor={backgroundColor}\n bgColor2={backgroundColor2}\n hoverBgColor={hoverBackgroundColor}\n hoverBgColor2={hoverBackgroundColor2}\n clickable={isClickable}\n />\n </TimeSlotItem>\n </>\n );\n };\n\n // Render time slots\n const renderTimeSlots = () => {\n return allSlots.map((slot) => {\n const {\n id,\n startTime: slotStartTime,\n endTime: slotEndTime,\n label,\n clickable = true,\n styleAttributes,\n ariaLabel,\n } = slot;\n\n const {\n color,\n styleType = \"default\",\n backgroundColor,\n backgroundColor2,\n hoverBackgroundColor,\n hoverBackgroundColor2,\n } = styleAttributes;\n\n const slotWidth = TimeSlotBarHelper.calculateWidth(\n slotStartTime,\n slotEndTime,\n cellWidth\n );\n const slotOffset = TimeSlotBarHelper.calculateWidth(\n adjustedStartTime,\n slotStartTime,\n cellWidth\n );\n\n const isClickable = clickable && variant === \"default\";\n const showLabel = isVariant(\"default\") && label;\n\n const handleSlotClick =\n (clickedSlot: TTimeSlot & { ariaLabel?: string }) =>\n (evt: React.MouseEvent<HTMLElement>) => {\n evt.stopPropagation();\n\n const { ariaLabel: _, ...slot } = clickedSlot;\n if (isClickable) onSlotClick(slot);\n };\n\n return (\n <div key={id} role=\"gridcell\">\n <TimeSlotDivider\n variant={variant}\n left={slotOffset}\n dataTestId=\"start-border\"\n />\n <TimeSlotItem\n variant={variant}\n dataTestId={getDataTestId(`${id}-timeslot`)}\n slotWidth={slotWidth}\n slotOffset={slotOffset}\n color={color}\n onClick={handleSlotClick(slot)}\n >\n <TimeSlot\n className={styles.timeSlotItemContent}\n styleType={styleType}\n bgColor={backgroundColor}\n bgColor2={backgroundColor2}\n hoverBgColor={hoverBackgroundColor}\n hoverBgColor2={hoverBackgroundColor2}\n clickable={isClickable}\n >\n {!!ariaLabel && (\n <VisuallyHidden>\n <button\n type=\"button\" // overrides default type=\"submit\" when used with <form>\n aria-disabled={!isClickable}\n aria-label={ariaLabel}\n onClick={handleSlotClick(slot)} // use `button` element native keyboard activation handling\n />\n </VisuallyHidden>\n )}\n\n {showLabel && (\n <Typography.BodyXS\n className={styles.cellText}\n weight={\"semibold\"}\n aria-hidden={!ariaLabel}\n >\n {showFullEllipsis(slotWidth)\n ? \"...\"\n : label}\n </Typography.BodyXS>\n )}\n </TimeSlot>\n </TimeSlotItem>\n {endTime !== slotEndTime && (\n <TimeSlotDivider\n variant={variant}\n dataTestId=\"end-border\"\n left={slotOffset + slotWidth}\n />\n )}\n </div>\n );\n });\n };\n\n const renderArrowButton = (direction: Direction) => {\n const isLeft = direction === \"left\";\n const totalScrollableWidth = TimeSlotBarHelper.calculateWidth(\n adjustedStartTime,\n adjustedEndTime,\n cellWidth\n );\n const hasContentOnLeft = scrollPosition > 0;\n const hasContentOnRight =\n scrollPosition + clientWidth < totalScrollableWidth;\n const shouldShowArrow = isLeft ? hasContentOnLeft : hasContentOnRight;\n\n if (!shouldShowArrow) return null;\n\n const directionClass = isLeft\n ? styles.arrowButtonLeft\n : styles.arrowButtonRight;\n const variantClass =\n variant === \"default\"\n ? styles.arrowButtonDefault\n : styles.arrowButtonMinified;\n const arrowIcon = isLeft ? (\n <ChevronLeftIcon className={styles.arrowIcon} />\n ) : (\n <ChevronRightIcon className={styles.arrowIcon} />\n );\n\n return (\n <ClickableIcon\n data-testid={getDataTestId(`arrow-${direction}`)}\n aria-hidden\n tabIndex={-1}\n className={clsx(\n styles.arrowButton,\n directionClass,\n variantClass\n )}\n focusHighlight={false}\n focusOutline=\"none\"\n onClick={() => {\n handleArrowButtonClick(direction);\n }}\n >\n {arrowIcon}\n </ClickableIcon>\n );\n };\n\n return (\n <div className={clsx(styles.container, className)}>\n <div\n data-testid={testId}\n ref={barRef}\n className={clsx(\n styles.timeSlotBarContainer,\n variant === \"default\"\n ? styles.containerDefault\n : styles.containerMinified\n )}\n >\n <div\n className={styles.timeMarkerWrapper}\n data-testid={getDataTestId(\"time-marker-wrapper\")}\n data-id=\"marker-wrapper\"\n >\n {renderTimeMarkers()}\n </div>\n <div role=\"grid\" aria-label={slotsSummary} tabIndex={0}>\n <div\n className={styles.timeSlotWrapper}\n data-testid={getDataTestId(\"time-slot-wrapper\")}\n data-id=\"slot-wrapper\"\n role=\"row\"\n >\n {renderDefaultTimeSlots()}\n {renderTimeSlots()}\n </div>\n </div>\n </div>\n {renderArrowButton(\"left\")}\n {renderArrowButton(\"right\")}\n </div>\n );\n};\n\n// @catalog\n/**\n * A horizontally scrollable timeline bar that visualises time slots across a\n * defined time range.\n *\n * Use `TimeSlotBar` to display availability, bookings, or schedule occupancy\n * as coloured cells on a shared time axis.\n */\nexport const TimeSlotBar = forwardRef<TimeSlotBarRef, TimeSlotBarProps>(\n Component\n);\n"],"names":["TimeSlotBar","forwardRef","props","ref","testId","className","variant","startTime","endTime","slots","onSlotClick","onClick","styleAttributes","initialScrollTime","roundInitialScrollTime","barRef","useRef","scrollPosition","setScrollPosition","useState","clientWidth","setClientWidth","cellWidth","getCellWidth","adjustedStartTime","TimeSlotBarHelper","adjustTimeForMarker","adjustedEndTime","SCROLL_INCREMENT","useImperativeHandle","resetScroll","summary","slotsSummary","computedSlots","allSlots","useMemo","processSlots","start","end","useEffect","container","current","addEventListener","handleScroll","removeEventListener","scrollLeft","useResizeDetector","onResize","targetRef","refreshMode","refreshRate","showFullEllipsis","slotWidth","getDataTestId","subStr","shouldDisplayLongTimeMarker","currentTime","isStartHourEven","isHour","minute","hour","TimeHelper","calculateScrollPosition","scrollTime","minTime","maxTime","interval","intervalWidth","options","roundToInterval","isVariant","v","renderArrowButton","direction","isLeft","totalScrollableWidth","calculateWidth","directionClass","styles.arrowButtonLeft","styles.arrowButtonRight","variantClass","styles.arrowButtonDefault","styles.arrowButtonMinified","arrowIcon","_jsx","ChevronLeftIcon","styles.arrowIcon","ChevronRightIcon","ClickableIcon","tabIndex","clsx","styles.arrowButton","focusHighlight","focusOutline","scrollBy","left","behavior","handleArrowButtonClick","children","_jsxs","styles.container","styles.timeSlotBarContainer","styles.containerDefault","styles.containerMinified","styles.timeMarkerWrapper","timeMarkers","startTimeFormatted","dayjs","endTimeFormatted","isBefore","add","displayLongTimeMarker","push","format","styles.timeMarker","styles.timeMarkerDefault","styles.timeMarkerMinified","styles.timeMarkerLong","Typography","BodyXS","styles.timeLabel","weight","formatHourlyDisplay","renderTimeMarkers","role","styles.timeSlotWrapper","backgroundColor","backgroundColor2","hoverBackgroundColor","hoverBackgroundColor2","styleType","isClickable","_Fragment","TimeSlotDivider","TimeSlotItem","dataTestId","slotOffset","undefined","TimeSlot","styles.timeSlotItemContent","bgColor","bgColor2","hoverBgColor","hoverBgColor2","clickable","renderDefaultTimeSlots","map","slot","id","slotStartTime","slotEndTime","label","ariaLabel","color","showLabel","handleSlotClick","clickedSlot","evt","stopPropagation","_","__rest","VisuallyHidden","type","styles.cellText"],"mappings":"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"}
|