@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":"predictive-text-input.js","sources":["../../../src/predictive-text-input/predictive-text-input.tsx"],"sourcesContent":["import debounce from \"lodash/debounce\";\nimport type React from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { Input } from \"../input\";\nimport { concatIds, VisuallyHidden } from \"../shared/accessibility\";\nimport { DropdownList, DropdownListState } from \"../shared/dropdown-list\";\nimport type { ItemsLoadStateType } from \"../shared/dropdown-list/types\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport { InputWrapper } from \"../shared/input-wrapper\";\nimport { useId } from \"../util\";\nimport type { PredictiveTextInputProps } from \"./types\";\n\n/**\n * A text input that fetches and displays matching suggestions as the user types.\n *\n * Use `PredictiveTextInput` for search-as-you-type or autocomplete scenarios\n * where options are loaded asynchronously based on the current input.\n */\nexport const PredictiveTextInput = <T, V>({\n className,\n \"data-testid\": testId,\n selectedOption,\n minimumCharacters = 3,\n fetchOptions,\n placeholder = \"Enter here...\",\n readOnly = false,\n disabled = false,\n error,\n valueExtractor,\n listExtractor,\n displayValueExtractor,\n onSelectOption,\n alignment,\n dropdownZIndex,\n dropdownRootNode,\n dropdownWidth,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: PredictiveTextInputProps<T, V>): JSX.Element => {\n const getDisplayValue = (item: T | undefined): string => {\n if (!item) return \"\";\n return displayValueExtractor\n ? displayValueExtractor(item)\n : item.toString();\n };\n\n // =============================================================================\n // CONST, STATE\n // =============================================================================\n const [input, setInput] = useState<string>(() =>\n selectedOption ? getDisplayValue(selectedOption) : \"\"\n );\n const [searchedInput, setSearchedInput] = useState<string>(() =>\n selectedOption ? getDisplayValue(selectedOption) : \"\"\n );\n const [options, setOptions] = useState<T[]>([]);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [isError, setIsError] = useState<boolean>(false);\n const [isOptionSelected, setIsOptionSelected] = useState<boolean>(\n !!selectedOption\n );\n const [prevOptionSelected, setPrevOptionSelected] = useState<T | undefined>(\n selectedOption\n );\n const [isOpen, setIsOpen] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n const internalId = useId();\n const [resultAnnouncement, setResultAnnouncement] = useState<string | null>(\n null\n );\n const instructionId = `${internalId}-instruction`;\n\n const nodeRef = useRef<HTMLDivElement | null>(null);\n const selectorRef = useRef<HTMLInputElement | null>(null);\n\n const fetchOptionsRef = useRef(fetchOptions);\n\n // =============================================================================\n // DEBOUNCE FUNCTIONS\n // =============================================================================\n const handleFetchOptions = useCallback(async (input: string) => {\n if (!fetchOptionsRef.current) return;\n setIsError(false);\n setIsLoading(true);\n try {\n const fetchedOptions = await fetchOptionsRef.current(input);\n setSearchedInput(input);\n setOptions(fetchedOptions ?? []);\n setIsLoading(false);\n } catch {\n setIsError(true);\n setIsLoading(false);\n }\n }, []);\n\n const fetchOptionsDebounced = useCallback(\n debounce((input: string) => {\n handleFetchOptions(input);\n }, 500),\n [handleFetchOptions]\n );\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n\n useEffect(() => {\n fetchOptionsRef.current = fetchOptions;\n }, [fetchOptions]);\n\n useEffect(() => {\n /***\n * Should not fetch options for the following the scenario :\n * 1. When input < minimumCharacters\n * 2. When user selected option from dropdown becomes input\n * 3. Initial selectedOption passed in as input\n */\n if (input && input.length >= minimumCharacters) {\n if (!isOptionSelected) {\n setIsOpen(true);\n fetchOptionsDebounced(input);\n } else if (input !== searchedInput) {\n fetchOptionsDebounced(input);\n }\n } else {\n fetchOptionsDebounced.cancel();\n }\n\n if (input === \"\" && prevOptionSelected) {\n onSelectOption?.(undefined, undefined);\n handleDropdownDismiss();\n setPrevOptionSelected(undefined);\n }\n\n if (selectedOption && input !== getDisplayValue(selectedOption)) {\n setIsOptionSelected(false);\n }\n }, [input, selectedOption]);\n\n useEffect(() => {\n setInput(selectedOption ? getDisplayValue(selectedOption) : \"\");\n setSearchedInput(selectedOption ? getDisplayValue(selectedOption) : \"\");\n setPrevOptionSelected(selectedOption);\n setOptions([]);\n setIsOptionSelected(!!selectedOption);\n }, [selectedOption]);\n\n useEffect(() => {\n const state = getItemsLoadState();\n const count = options?.length ?? 0;\n\n if (state === \"loading\" && input.length >= minimumCharacters) {\n setResultAnnouncement(\"Loading suggested results\");\n return;\n }\n\n if (state === \"fail\") {\n setResultAnnouncement(\"Suggestions failed to load. Try again.\");\n return;\n }\n\n if (isOpen && !isLoading && !isError) {\n if (count === 0) {\n setResultAnnouncement(input ? \"No results found.\" : null);\n } else {\n setResultAnnouncement(\n `${count} result${\n count > 1 ? \"s\" : \"\"\n } found. Press down arrow to scroll through the list.`\n );\n }\n }\n }, [options, input, isError, isLoading]);\n\n // =============================================================================\n // Cleanup: cancel debounce on unmount\n // =============================================================================\n useEffect(() => {\n return () => {\n fetchOptionsDebounced.cancel();\n };\n }, [fetchOptionsDebounced]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleListItemClick = (item: T, extractedValue: V) => {\n selectorRef.current?.focus();\n setInput(getDisplayValue(item));\n setSearchedInput(item ? getDisplayValue(item) : \"\");\n setIsOptionSelected(true);\n setPrevOptionSelected(item);\n setIsOpen(false);\n onSelectOption?.(item, extractedValue);\n };\n\n const handleOpen = () => {\n if (!isOptionSelected && input.length >= minimumCharacters) {\n setIsFocused(true);\n }\n };\n\n const handleClose = () => {\n setIsOpen(false);\n setIsFocused(false);\n handleOnBlur();\n };\n\n const handleNodeFocus = () => {\n setIsFocused(true);\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n !isOpen &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setIsFocused(false);\n handleOnBlur();\n }\n };\n\n const handleListDismiss = () => {\n setIsOpen(false);\n setIsFocused(false);\n };\n\n const handleDismiss = () => {\n setIsOpen(false);\n setIsFocused(false);\n handleOnBlur();\n selectorRef.current?.focus();\n };\n\n const handleOnClear = () => {\n setInput(\"\");\n setOptions([]);\n setIsOptionSelected(false);\n setIsOpen(false);\n onSelectOption?.(undefined, undefined);\n };\n\n const handleOnBlur = () => {\n if (!isOptionSelected) {\n if (prevOptionSelected) {\n const prevValue = getDisplayValue(prevOptionSelected);\n setInput(prevValue);\n setIsOpen(false);\n } else {\n handleOnClear();\n }\n }\n };\n\n const handleTyping = (e: React.ChangeEvent<HTMLInputElement>) => {\n setInput(e.target.value);\n setIsOptionSelected(false);\n };\n\n const handleDropdownDismiss = (item?: T) => {\n setSearchedInput(item ? getDisplayValue(item) : \"\");\n setIsOptionSelected(!!item);\n setOptions([]);\n setIsLoading(true);\n };\n\n // =============================================================================\n // HELPER FUNCTION\n // =============================================================================\n const getItemsLoadState = (): ItemsLoadStateType => {\n if (isError) return \"fail\";\n return isLoading ? \"loading\" : \"success\";\n };\n\n // =============================================================================\n // RENDER FUNCTION\n // =============================================================================\n const renderInputElement = () => {\n return (\n <InputWrapper\n className={className}\n data-testid={testId}\n ref={nodeRef}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n focused={isFocused}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n >\n <VisuallyHidden id={instructionId} aria-hidden>\n Type in {minimumCharacters} or more characters for suggested\n results.\n </VisuallyHidden>\n {resultAnnouncement && (\n <VisuallyHidden aria-live=\"polite\">\n {resultAnnouncement}\n </VisuallyHidden>\n )}\n <Input\n role=\"combobox\"\n ref={selectorRef}\n id={internalId}\n type=\"text\"\n value={input}\n onChange={handleTyping}\n placeholder={placeholder}\n readOnly={readOnly}\n disabled={disabled}\n allowClear\n onClear={handleOnClear}\n aria-expanded={isOpen}\n aria-controls={internalId}\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n onBlur={\n input.length < minimumCharacters\n ? handleOnBlur\n : undefined\n }\n styleType=\"no-border\"\n aria-describedby={concatIds(ariaDescribedBy, instructionId)}\n {...otherProps}\n />\n </InputWrapper>\n );\n };\n\n const renderDropdown = () => {\n return (\n <>\n <DropdownList\n listboxId={internalId}\n listItems={options}\n onSelectItem={handleListItemClick}\n onDismiss={handleListDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n itemsLoadState={getItemsLoadState()}\n itemTruncationType={\"end\"}\n itemMaxLines={1}\n labelDisplayType={\"next-line\"}\n disableItemFocus\n onRetry={() => handleFetchOptions(input)}\n width={dropdownWidth}\n matchElementWidth\n />\n </>\n );\n };\n\n return (\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={isOpen}\n renderElement={renderInputElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle={false}\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n );\n};\n"],"names":["_a","className","testId","selectedOption","minimumCharacters","fetchOptions","placeholder","readOnly","disabled","error","valueExtractor","listExtractor","displayValueExtractor","onSelectOption","alignment","dropdownZIndex","dropdownRootNode","dropdownWidth","ariaDescribedBy","otherProps","__rest","getDisplayValue","item","toString","input","setInput","useState","searchedInput","setSearchedInput","options","setOptions","isLoading","setIsLoading","isError","setIsError","isOptionSelected","setIsOptionSelected","prevOptionSelected","setPrevOptionSelected","isOpen","setIsOpen","isFocused","setIsFocused","internalId","useId","resultAnnouncement","setResultAnnouncement","instructionId","nodeRef","useRef","selectorRef","fetchOptionsRef","handleFetchOptions","useCallback","__awaiter","current","fetchedOptions","fetchOptionsDebounced","debounce","useEffect","length","cancel","undefined","handleDropdownDismiss","state","getItemsLoadState","count","handleListItemClick","extractedValue","focus","handleNodeFocus","handleNodeBlur","e","contains","relatedTarget","handleOnBlur","handleListDismiss","handleOnClear","prevValue","handleTyping","target","value","_jsx","DropdownListState","children","ElementWithDropdown","enabled","renderElement","_jsxs","InputWrapper","ref","tabIndex","onFocus","onBlur","focused","VisuallyHidden","id","Input","Object","assign","role","type","onChange","allowClear","onClear","styleType","concatIds","renderDropdown","_Fragment","DropdownList","listboxId","listItems","onSelectItem","onDismiss","itemsLoadState","itemTruncationType","itemMaxLines","labelDisplayType","disableItemFocus","onRetry","width","matchElementWidth","onOpen","onClose","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"predictive-text-input.js","sources":["../../../src/predictive-text-input/predictive-text-input.tsx"],"sourcesContent":["import debounce from \"lodash/debounce\";\nimport type React from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { Input } from \"../input\";\nimport { concatIds, VisuallyHidden } from \"../shared/accessibility\";\nimport { DropdownList, DropdownListState } from \"../shared/dropdown-list\";\nimport type { ItemsLoadStateType } from \"../shared/dropdown-list/types\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport { InputWrapper } from \"../shared/input-wrapper\";\nimport { useId } from \"../util\";\nimport type { PredictiveTextInputProps } from \"./types\";\n\n// @catalog\n/**\n * A text input that fetches and displays matching suggestions as the user types.\n *\n * Use `PredictiveTextInput` for search-as-you-type or autocomplete scenarios\n * where options are loaded asynchronously based on the current input.\n */\nexport const PredictiveTextInput = <T, V>({\n className,\n \"data-testid\": testId,\n selectedOption,\n minimumCharacters = 3,\n fetchOptions,\n placeholder = \"Enter here...\",\n readOnly = false,\n disabled = false,\n error,\n valueExtractor,\n listExtractor,\n displayValueExtractor,\n onSelectOption,\n alignment,\n dropdownZIndex,\n dropdownRootNode,\n dropdownWidth,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: PredictiveTextInputProps<T, V>): JSX.Element => {\n const getDisplayValue = (item: T | undefined): string => {\n if (!item) return \"\";\n return displayValueExtractor\n ? displayValueExtractor(item)\n : item.toString();\n };\n\n // =============================================================================\n // CONST, STATE\n // =============================================================================\n const [input, setInput] = useState<string>(() =>\n selectedOption ? getDisplayValue(selectedOption) : \"\"\n );\n const [searchedInput, setSearchedInput] = useState<string>(() =>\n selectedOption ? getDisplayValue(selectedOption) : \"\"\n );\n const [options, setOptions] = useState<T[]>([]);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [isError, setIsError] = useState<boolean>(false);\n const [isOptionSelected, setIsOptionSelected] = useState<boolean>(\n !!selectedOption\n );\n const [prevOptionSelected, setPrevOptionSelected] = useState<T | undefined>(\n selectedOption\n );\n const [isOpen, setIsOpen] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n const internalId = useId();\n const [resultAnnouncement, setResultAnnouncement] = useState<string | null>(\n null\n );\n const instructionId = `${internalId}-instruction`;\n\n const nodeRef = useRef<HTMLDivElement | null>(null);\n const selectorRef = useRef<HTMLInputElement | null>(null);\n\n const fetchOptionsRef = useRef(fetchOptions);\n\n // =============================================================================\n // DEBOUNCE FUNCTIONS\n // =============================================================================\n const handleFetchOptions = useCallback(async (input: string) => {\n if (!fetchOptionsRef.current) return;\n setIsError(false);\n setIsLoading(true);\n try {\n const fetchedOptions = await fetchOptionsRef.current(input);\n setSearchedInput(input);\n setOptions(fetchedOptions ?? []);\n setIsLoading(false);\n } catch {\n setIsError(true);\n setIsLoading(false);\n }\n }, []);\n\n const fetchOptionsDebounced = useCallback(\n debounce((input: string) => {\n handleFetchOptions(input);\n }, 500),\n [handleFetchOptions]\n );\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n\n useEffect(() => {\n fetchOptionsRef.current = fetchOptions;\n }, [fetchOptions]);\n\n useEffect(() => {\n /***\n * Should not fetch options for the following the scenario :\n * 1. When input < minimumCharacters\n * 2. When user selected option from dropdown becomes input\n * 3. Initial selectedOption passed in as input\n */\n if (input && input.length >= minimumCharacters) {\n if (!isOptionSelected) {\n setIsOpen(true);\n fetchOptionsDebounced(input);\n } else if (input !== searchedInput) {\n fetchOptionsDebounced(input);\n }\n } else {\n fetchOptionsDebounced.cancel();\n }\n\n if (input === \"\" && prevOptionSelected) {\n onSelectOption?.(undefined, undefined);\n handleDropdownDismiss();\n setPrevOptionSelected(undefined);\n }\n\n if (selectedOption && input !== getDisplayValue(selectedOption)) {\n setIsOptionSelected(false);\n }\n }, [input, selectedOption]);\n\n useEffect(() => {\n setInput(selectedOption ? getDisplayValue(selectedOption) : \"\");\n setSearchedInput(selectedOption ? getDisplayValue(selectedOption) : \"\");\n setPrevOptionSelected(selectedOption);\n setIsOptionSelected(!!selectedOption);\n }, [selectedOption]);\n\n useEffect(() => {\n const state = getItemsLoadState();\n const count = options?.length ?? 0;\n\n if (state === \"loading\" && input.length >= minimumCharacters) {\n setResultAnnouncement(\"Loading suggested results\");\n return;\n }\n\n if (state === \"fail\") {\n setResultAnnouncement(\"Suggestions failed to load. Try again.\");\n return;\n }\n\n if (isOpen && !isLoading && !isError) {\n if (count === 0) {\n setResultAnnouncement(input ? \"No results found.\" : null);\n } else {\n setResultAnnouncement(\n `${count} result${\n count > 1 ? \"s\" : \"\"\n } found. Press down arrow to scroll through the list.`\n );\n }\n }\n }, [options, input, isError, isLoading]);\n\n // =============================================================================\n // Cleanup: cancel debounce on unmount\n // =============================================================================\n useEffect(() => {\n return () => {\n fetchOptionsDebounced.cancel();\n };\n }, [fetchOptionsDebounced]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleListItemClick = (item: T, extractedValue: V) => {\n selectorRef.current?.focus();\n setInput(getDisplayValue(item));\n setSearchedInput(item ? getDisplayValue(item) : \"\");\n setIsOptionSelected(true);\n setPrevOptionSelected(item);\n setIsOpen(false);\n onSelectOption?.(item, extractedValue);\n };\n\n const handleOpen = () => {\n if (!isOptionSelected && input.length >= minimumCharacters) {\n setIsFocused(true);\n }\n };\n\n const handleClose = () => {\n setIsOpen(false);\n setIsFocused(false);\n handleOnBlur();\n };\n\n const handleNodeFocus = () => {\n setIsFocused(true);\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n !isOpen &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setIsFocused(false);\n handleOnBlur();\n }\n };\n\n const handleListDismiss = () => {\n setIsOpen(false);\n setIsFocused(false);\n };\n\n const handleDismiss = () => {\n setIsOpen(false);\n setIsFocused(false);\n handleOnBlur();\n selectorRef.current?.focus();\n };\n\n const handleHide = () => {\n // reset dropdown state once it fully closes\n setOptions([]);\n setIsLoading(true);\n setIsError(false);\n };\n\n const handleOnClear = () => {\n setInput(\"\");\n setIsOptionSelected(false);\n setIsOpen(false);\n onSelectOption?.(undefined, undefined);\n };\n\n const handleOnBlur = () => {\n if (!isOptionSelected) {\n if (prevOptionSelected) {\n const prevValue = getDisplayValue(prevOptionSelected);\n setInput(prevValue);\n setIsOpen(false);\n } else {\n handleOnClear();\n }\n }\n };\n\n const handleTyping = (e: React.ChangeEvent<HTMLInputElement>) => {\n setInput(e.target.value);\n setIsOptionSelected(false);\n };\n\n const handleDropdownDismiss = (item?: T) => {\n setSearchedInput(item ? getDisplayValue(item) : \"\");\n setIsOptionSelected(!!item);\n setIsLoading(true);\n };\n\n // =============================================================================\n // HELPER FUNCTION\n // =============================================================================\n const getItemsLoadState = (): ItemsLoadStateType => {\n if (isError) return \"fail\";\n return isLoading ? \"loading\" : \"success\";\n };\n\n // =============================================================================\n // RENDER FUNCTION\n // =============================================================================\n const renderInputElement = () => {\n return (\n <InputWrapper\n className={className}\n data-testid={testId}\n ref={nodeRef}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n focused={isFocused}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n >\n <VisuallyHidden id={instructionId} aria-hidden>\n Type in {minimumCharacters} or more characters for suggested\n results.\n </VisuallyHidden>\n {resultAnnouncement && (\n <VisuallyHidden aria-live=\"polite\">\n {resultAnnouncement}\n </VisuallyHidden>\n )}\n <Input\n role=\"combobox\"\n ref={selectorRef}\n id={internalId}\n type=\"text\"\n value={input}\n onChange={handleTyping}\n placeholder={placeholder}\n readOnly={readOnly}\n disabled={disabled}\n allowClear\n onClear={handleOnClear}\n aria-expanded={isOpen}\n aria-controls={internalId}\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n onBlur={\n input.length < minimumCharacters\n ? handleOnBlur\n : undefined\n }\n styleType=\"no-border\"\n aria-describedby={concatIds(ariaDescribedBy, instructionId)}\n {...otherProps}\n />\n </InputWrapper>\n );\n };\n\n const renderDropdown = () => {\n return (\n <DropdownList\n listboxId={internalId}\n listItems={options}\n onSelectItem={handleListItemClick}\n onDismiss={handleListDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n itemsLoadState={getItemsLoadState()}\n itemTruncationType={\"end\"}\n itemMaxLines={1}\n labelDisplayType={\"next-line\"}\n disableItemFocus\n onRetry={() => handleFetchOptions(input)}\n width={dropdownWidth}\n matchElementWidth\n />\n );\n };\n\n return (\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={isOpen}\n renderElement={renderInputElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n onHide={handleHide}\n clickToToggle={false}\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n );\n};\n"],"names":["_a","className","testId","selectedOption","minimumCharacters","fetchOptions","placeholder","readOnly","disabled","error","valueExtractor","listExtractor","displayValueExtractor","onSelectOption","alignment","dropdownZIndex","dropdownRootNode","dropdownWidth","ariaDescribedBy","otherProps","__rest","getDisplayValue","item","toString","input","setInput","useState","searchedInput","setSearchedInput","options","setOptions","isLoading","setIsLoading","isError","setIsError","isOptionSelected","setIsOptionSelected","prevOptionSelected","setPrevOptionSelected","isOpen","setIsOpen","isFocused","setIsFocused","internalId","useId","resultAnnouncement","setResultAnnouncement","instructionId","nodeRef","useRef","selectorRef","fetchOptionsRef","handleFetchOptions","useCallback","__awaiter","current","fetchedOptions","fetchOptionsDebounced","debounce","useEffect","length","cancel","undefined","handleDropdownDismiss","state","getItemsLoadState","count","handleListItemClick","extractedValue","focus","handleNodeFocus","handleNodeBlur","e","contains","relatedTarget","handleOnBlur","handleListDismiss","handleOnClear","prevValue","handleTyping","target","value","_jsx","DropdownListState","children","ElementWithDropdown","enabled","renderElement","_jsxs","InputWrapper","ref","tabIndex","onFocus","onBlur","focused","VisuallyHidden","id","Input","Object","assign","role","type","onChange","allowClear","onClear","styleType","concatIds","renderDropdown","DropdownList","listboxId","listItems","onSelectItem","onDismiss","itemsLoadState","itemTruncationType","itemMaxLines","labelDisplayType","disableItemFocus","onRetry","width","matchElementWidth","onOpen","onClose","onHide","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"mqEAoB0CA,QAAAC,UACtCA,EACA,cAAeC,EAAMC,eACrBA,EAAcC,kBACdA,EAAoB,EAACC,aACrBA,EAAYC,YACZA,EAAc,gBAAeC,SAC7BA,GAAW,EAAKC,SAChBA,GAAW,EAAKC,MAChBA,EAAKC,eACLA,EAAcC,cACdA,EAAaC,sBACbA,EAAqBC,eACrBA,EAAcC,UACdA,EAASC,eACTA,EAAcC,iBACdA,EAAgBC,cAChBA,EACA,mBAAoBC,KACjBC,EAAUC,EAAAA,OAAApB,EAnByB,CAAA,YAAA,cAAA,iBAAA,oBAAA,eAAA,cAAA,WAAA,WAAA,QAAA,iBAAA,gBAAA,wBAAA,iBAAA,YAAA,iBAAA,mBAAA,gBAAA,qBAqBtC,MAAMqB,EAAmBC,GAChBA,EACEV,EACDA,EAAsBU,GACtBA,EAAKC,WAHO,IASfC,EAAOC,GAAYC,EAAAA,UAAiB,IACvCvB,EAAiBkB,EAAgBlB,GAAkB,MAEhDwB,EAAeC,GAAoBF,EAAAA,UAAiB,IACvDvB,EAAiBkB,EAAgBlB,GAAkB,MAEhD0B,EAASC,GAAcJ,EAAAA,SAAc,KACrCK,EAAWC,GAAgBN,EAAAA,UAAkB,IAC7CO,EAASC,GAAcR,EAAAA,UAAkB,IACzCS,EAAkBC,GAAuBV,EAAAA,WAC1CvB,IAECkC,EAAoBC,GAAyBZ,EAAAA,SAChDvB,IAEGoC,EAAQC,GAAad,EAAAA,UAAS,IAC9Be,EAAWC,GAAgBhB,EAAAA,UAAS,GAErCiB,EAAaC,EAAAA,SACZC,EAAoBC,GAAyBpB,EAAAA,SAChD,MAEEqB,EAAgB,GAAGJ,gBAEnBK,GAAUC,EAAAA,OAA8B,MACxCC,GAAcD,EAAAA,OAAgC,MAE9CE,GAAkBF,EAAAA,OAAO5C,GAKzB+C,GAAqBC,EAAAA,aAAmB7B,GAAiB8B,EAAAA,eAAA,OAAA,OAAA,GAAA,YAC3D,GAAKH,GAAgBI,QAArB,CACArB,GAAW,GACXF,GAAa,GACb,IACI,MAAMwB,QAAuBL,GAAgBI,QAAQ/B,GACrDI,EAAiBJ,GACjBM,EAAW0B,QAAAA,EAAkB,IAC7BxB,GAAa,EACjB,CAAE,MAAAhC,GACEkC,GAAW,GACXF,GAAa,EACjB,CAX8B,CAYlC,KAAG,IAEGyB,GAAwBJ,EAAAA,YAC1BK,EAAAA,SAAUlC,IACN4B,GAAmB5B,EAAM,GAC1B,KACH,CAAC4B,KAOLO,EAAAA,WAAU,KACNR,GAAgBI,QAAUlD,CAAY,GACvC,CAACA,IAEJsD,EAAAA,WAAU,KAOFnC,GAASA,EAAMoC,QAAUxD,EACpB+B,EAGMX,IAAUG,GACjB8B,GAAsBjC,IAHtBgB,GAAU,GACViB,GAAsBjC,IAK1BiC,GAAsBI,SAGZ,KAAVrC,GAAgBa,IAChBxB,SAAAA,OAAiBiD,OAAWA,GAC5BC,KACAzB,OAAsBwB,IAGtB3D,GAAkBqB,IAAUH,EAAgBlB,IAC5CiC,GAAoB,EACxB,GACD,CAACZ,EAAOrB,IAEXwD,EAAAA,WAAU,KACNlC,EAAStB,EAAiBkB,EAAgBlB,GAAkB,IAC5DyB,EAAiBzB,EAAiBkB,EAAgBlB,GAAkB,IACpEmC,EAAsBnC,GACtBiC,IAAsBjC,EAAe,GACtC,CAACA,IAEJwD,EAAAA,WAAU,WACN,MAAMK,EAAQC,KACRC,EAAuB,QAAflE,EAAA6B,aAAO,EAAPA,EAAS+B,cAAM,IAAA5D,EAAAA,EAAI,EAEnB,YAAVgE,GAAuBxC,EAAMoC,QAAUxD,EACvC0C,EAAsB,6BAIZ,SAAVkB,GAKAzB,GAAWR,GAAcE,GAErBa,EADU,IAAVoB,EACsB1C,EAAQ,oBAAsB,KAGhD,GAAG0C,WACCA,EAAQ,EAAI,IAAM,0DAV9BpB,EAAsB,yCAc1B,GACD,CAACjB,EAASL,EAAOS,EAASF,IAK7B4B,EAAAA,WAAU,IACC,KACHF,GAAsBI,QAAQ,GAEnC,CAACJ,KAKJ,MAAMU,GAAsB,CAAC7C,EAAS8C,WACf,QAAnBpE,EAAAkD,GAAYK,eAAO,IAAAvD,GAAAA,EAAEqE,QACrB5C,EAASJ,EAAgBC,IACzBM,EAAiBN,EAAOD,EAAgBC,GAAQ,IAChDc,GAAoB,GACpBE,EAAsBhB,GACtBkB,GAAU,GACV3B,SAAAA,EAAiBS,EAAM8C,EAAe,EAepCE,GAAkB,KACpB5B,GAAa,EAAK,EAGhB6B,GAAkBC,IAEfjC,IACDS,GAAQO,SACPP,GAAQO,QAAQkB,SAASD,EAAEE,iBAE5BhC,GAAa,GACbiC,KACJ,EAGEC,GAAoB,KACtBpC,GAAU,GACVE,GAAa,EAAM,EAiBjBmC,GAAgB,KAClBpD,EAAS,IACTW,GAAoB,GACpBI,GAAU,GACV3B,SAAAA,OAAiBiD,OAAWA,EAAU,EAGpCa,GAAe,KACjB,IAAKxC,EACD,GAAIE,EAAoB,CACpB,MAAMyC,EAAYzD,EAAgBgB,GAClCZ,EAASqD,GACTtC,GAAU,EACd,MACIqC,IAER,EAGEE,GAAgBP,IAClB/C,EAAS+C,EAAEQ,OAAOC,OAClB7C,GAAoB,EAAM,EAGxB2B,GAAyBzC,IAC3BM,EAAgD,IAChDQ,GAAoB,GACpBJ,GAAa,EAAK,EAMhBiC,GAAoB,IAClBhC,EAAgB,OACbF,EAAY,UAAY,UA+EnC,OACImD,EAAAA,IAACC,EAAAA,kBAAiB,CAAAC,SACdF,EAAAA,IAACG,EAAAA,oBAAmB,CAChBC,SAAU/E,IAAaC,EACvB+B,OAAQA,EACRgD,cA9Ee,IAEnBC,EAAAA,KAACC,EAAAA,aAAY,CACTxF,UAAWA,EAAS,cACPC,EACbwF,IAAK1C,GACL2C,UAAU,EACVC,QAAStB,GACTuB,OAAQtB,GACRuB,QAASrD,EACTjC,SAAUA,EACVD,SAAUA,EACVE,MAAOA,EAAK2E,SAAA,CAEZI,EAAAA,KAACO,EAAAA,eAAc,CAACC,GAAIjD,EAAa,eAAA,EAAAqC,SAAA,CAAA,WACpBhF,EAAiB,gDAG7ByC,GACGqC,EAAAA,IAACa,EAAAA,eAAc,CAAA,YAAW,SAAQX,SAC7BvC,IAGTqC,EAAAA,IAACe,EAAAA,MAAKC,OAAAC,OAAA,CACFC,KAAK,WACLV,IAAKxC,GACL8C,GAAIrD,EACJ0D,KAAK,OACLpB,MAAOzD,EACP8E,SAAUvB,GACVzE,YAAaA,EACbC,SAAUA,EACVC,SAAUA,EACV+F,YAAU,EACVC,QAAS3B,GAAa,gBACPtC,EAAM,gBACNI,EAAU,oBACP,OAAM,gBACV,UACdkD,OACIrE,EAAMoC,OAASxD,EACTuE,QACAb,EAEV2C,UAAU,+BACQC,EAAAA,UAAUxF,EAAiB6B,IACzC5B,OAiCRwF,eA3BW,IAEfzB,EAAAA,IAAC0B,EAAAA,aAAY,CACTC,UAAWlE,EACXmE,UAAWjF,EACXkF,aAAc5C,GACd6C,UAAWpC,GACXlE,eAAgBA,EAChBC,cAAeA,EACfsG,eAAgBhD,KAChBiD,mBAAoB,MACpBC,aAAc,EACdC,iBAAkB,YAClBC,oBACAC,QAAS,IAAMlE,GAAmB5B,GAClC+F,MAAOtG,EACPuG,mBAAiB,IAYjBC,OAvKO,MACVtF,GAAoBX,EAAMoC,QAAUxD,GACrCsC,GAAa,EACjB,EAqKQgF,QAlKQ,KAChBlF,GAAU,GACVE,GAAa,GACbiC,IAAc,EAgKNqC,UAzIU,WAClBxE,GAAU,GACVE,GAAa,GACbiC,KACmB,QAAnB3E,EAAAkD,GAAYK,eAAO,IAAAvD,GAAAA,EAAEqE,OAAO,EAsIpBsD,OAnIO,KAEf7F,EAAW,IACXE,GAAa,GACbE,GAAW,EAAM,EAgIT0F,eAAe,EACfC,OAAQ,EACR/G,UAAWA,EACXgH,oBAAkB,EAClBC,aAAchH,EACdiH,SAAUhH,KAEE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress-indicator.js","sources":["../../../src/progress-indicator/progress-indicator.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport kebabCase from \"lodash/kebabCase\";\n\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport * as styles from \"./progress-indicator.styles\";\nimport type { ProgressIndicatorProps } from \"./types\";\n\n/**\n * A horizontal step-progress bar that tracks a user's position through a\n * multi-step flow.\n *\n * Use `ProgressIndicator` when you need to communicate progress through an\n * ordered sequence of steps.\n */\nexport const ProgressIndicator = <T,>({\n steps,\n currentIndex,\n displayExtractor,\n className,\n ...otherProps\n}: ProgressIndicatorProps<T>) => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const isTablet = useMaxWidthMediaQuery(\"lg\");\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const getDisplayValue = (item: T): string => {\n if (displayExtractor) {\n return displayExtractor(item);\n }\n return item?.toString() ?? \"\";\n };\n\n const getStepAriaLabel = (stepIndex: number, currentIndex: number) => {\n if (stepIndex < currentIndex) {\n return \"Completed step\";\n } else if (stepIndex === currentIndex) {\n return \"Current step\";\n } else {\n return \"Upcoming step\";\n }\n };\n\n const getId = (stepIndex: number, currentIndex: number) => {\n return kebabCase(\n `${getStepAriaLabel(stepIndex, currentIndex)} ${stepIndex}`\n );\n };\n\n // =============================================================================\n // RENDER\n // =============================================================================\n if (!steps.length) return null;\n\n const renderBars = () => {\n return steps.map((step: T, stepIndex: number) => {\n // previous and current index elements are highlighted\n const highlighted = stepIndex <= currentIndex;\n\n return (\n <div\n key={stepIndex}\n id={getId(stepIndex, currentIndex)}\n className={styles.indicator}\n >\n <div\n className={clsx(\n styles.indicatorBar,\n highlighted && styles.indicatorBarHighlighted\n )}\n />\n </div>\n );\n });\n };\n\n const renderStepTitleDesktop = () => {\n return steps.map((step: T, stepIndex: number) => {\n const highlighted = stepIndex <= currentIndex;\n const current = stepIndex === currentIndex;\n const fontWeight = current ? \"bold\" : \"regular\";\n\n return (\n <div\n key={stepIndex}\n id={`${getId(stepIndex, currentIndex)}-title`}\n className={styles.indicator}\n >\n <Typography.BodyMD\n className={clsx(\n styles.indicatorTitleDesktop,\n highlighted &&\n styles.indicatorTitleDesktopHighlighted\n )}\n weight={fontWeight}\n aria-current={current}\n >\n {getDisplayValue(step)}\n <VisuallyHidden>\n {getStepAriaLabel(stepIndex, currentIndex)}\n </VisuallyHidden>\n </Typography.BodyMD>\n </div>\n );\n });\n };\n\n const renderStepTitleTablet = () => {\n return (\n <div\n key={currentIndex}\n id={getId(currentIndex, currentIndex)}\n className={styles.indicator}\n >\n <Typography.BodyMD\n className={styles.indicatorTitleTablet}\n weight={\"semibold\"}\n id={`${getId(currentIndex, currentIndex)}-counter`}\n >\n Step {currentIndex + 1} of {steps.length}\n </Typography.BodyMD>\n <Typography.BodyMD\n className={styles.indicatorTitleTablet}\n weight={\"regular\"}\n id={`${getId(currentIndex, currentIndex)}-title`}\n >\n {getDisplayValue(steps[currentIndex])}\n </Typography.BodyMD>\n </div>\n );\n };\n\n return (\n <div className={clsx(styles.wrapper, className)} {...otherProps}>\n <div className={styles.content}>{renderBars()}</div>\n <div className={styles.content}>\n {isTablet ? renderStepTitleTablet() : renderStepTitleDesktop()}\n </div>\n </div>\n );\n};\n"],"names":["_a","steps","currentIndex","displayExtractor","className","otherProps","__rest","isTablet","useMaxWidthMediaQuery","getDisplayValue","item","toString","getStepAriaLabel","stepIndex","getId","kebabCase","length","_jsxs","clsx","styles.wrapper","children","_jsx","styles.content","map","step","highlighted","id","styles.indicator","styles.indicatorBar","styles.indicatorBarHighlighted","Typography","BodyMD","styles.indicatorTitleTablet","weight","current","fontWeight","styles.indicatorTitleDesktop","styles.indicatorTitleDesktopHighlighted","VisuallyHidden"],"mappings":"
|
|
1
|
+
{"version":3,"file":"progress-indicator.js","sources":["../../../src/progress-indicator/progress-indicator.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport kebabCase from \"lodash/kebabCase\";\n\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport * as styles from \"./progress-indicator.styles\";\nimport type { ProgressIndicatorProps } from \"./types\";\n\n// @catalog\n/**\n * A horizontal step-progress bar that tracks a user's position through a\n * multi-step flow.\n *\n * Use `ProgressIndicator` when you need to communicate progress through an\n * ordered sequence of steps.\n */\nexport const ProgressIndicator = <T,>({\n steps,\n currentIndex,\n displayExtractor,\n className,\n ...otherProps\n}: ProgressIndicatorProps<T>) => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const isTablet = useMaxWidthMediaQuery(\"lg\");\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const getDisplayValue = (item: T): string => {\n if (displayExtractor) {\n return displayExtractor(item);\n }\n return item?.toString() ?? \"\";\n };\n\n const getStepAriaLabel = (stepIndex: number, currentIndex: number) => {\n if (stepIndex < currentIndex) {\n return \"Completed step\";\n } else if (stepIndex === currentIndex) {\n return \"Current step\";\n } else {\n return \"Upcoming step\";\n }\n };\n\n const getId = (stepIndex: number, currentIndex: number) => {\n return kebabCase(\n `${getStepAriaLabel(stepIndex, currentIndex)} ${stepIndex}`\n );\n };\n\n // =============================================================================\n // RENDER\n // =============================================================================\n if (!steps.length) return null;\n\n const renderBars = () => {\n return steps.map((step: T, stepIndex: number) => {\n // previous and current index elements are highlighted\n const highlighted = stepIndex <= currentIndex;\n\n return (\n <div\n key={stepIndex}\n id={getId(stepIndex, currentIndex)}\n className={styles.indicator}\n >\n <div\n className={clsx(\n styles.indicatorBar,\n highlighted && styles.indicatorBarHighlighted\n )}\n />\n </div>\n );\n });\n };\n\n const renderStepTitleDesktop = () => {\n return steps.map((step: T, stepIndex: number) => {\n const highlighted = stepIndex <= currentIndex;\n const current = stepIndex === currentIndex;\n const fontWeight = current ? \"bold\" : \"regular\";\n\n return (\n <div\n key={stepIndex}\n id={`${getId(stepIndex, currentIndex)}-title`}\n className={styles.indicator}\n >\n <Typography.BodyMD\n className={clsx(\n styles.indicatorTitleDesktop,\n highlighted &&\n styles.indicatorTitleDesktopHighlighted\n )}\n weight={fontWeight}\n aria-current={current}\n >\n {getDisplayValue(step)}\n <VisuallyHidden>\n {getStepAriaLabel(stepIndex, currentIndex)}\n </VisuallyHidden>\n </Typography.BodyMD>\n </div>\n );\n });\n };\n\n const renderStepTitleTablet = () => {\n return (\n <div\n key={currentIndex}\n id={getId(currentIndex, currentIndex)}\n className={styles.indicator}\n >\n <Typography.BodyMD\n className={styles.indicatorTitleTablet}\n weight={\"semibold\"}\n id={`${getId(currentIndex, currentIndex)}-counter`}\n >\n Step {currentIndex + 1} of {steps.length}\n </Typography.BodyMD>\n <Typography.BodyMD\n className={styles.indicatorTitleTablet}\n weight={\"regular\"}\n id={`${getId(currentIndex, currentIndex)}-title`}\n >\n {getDisplayValue(steps[currentIndex])}\n </Typography.BodyMD>\n </div>\n );\n };\n\n return (\n <div className={clsx(styles.wrapper, className)} {...otherProps}>\n <div className={styles.content}>{renderBars()}</div>\n <div className={styles.content}>\n {isTablet ? renderStepTitleTablet() : renderStepTitleDesktop()}\n </div>\n </div>\n );\n};\n"],"names":["_a","steps","currentIndex","displayExtractor","className","otherProps","__rest","isTablet","useMaxWidthMediaQuery","getDisplayValue","item","toString","getStepAriaLabel","stepIndex","getId","kebabCase","length","_jsxs","clsx","styles.wrapper","children","_jsx","styles.content","map","step","highlighted","id","styles.indicator","styles.indicatorBar","styles.indicatorBarHighlighted","Typography","BodyMD","styles.indicatorTitleTablet","weight","current","fontWeight","styles.indicatorTitleDesktop","styles.indicatorTitleDesktopHighlighted","VisuallyHidden"],"mappings":"s3BAiBsCA,IAAA,IAAAC,MAClCA,EAAKC,aACLA,EAAYC,iBACZA,EAAgBC,UAChBA,GAASJ,EACNK,EAAUC,EAAAA,OAAAN,EALqB,CAAA,QAAA,eAAA,mBAAA,cAUlC,MAAMO,EAAWC,EAAAA,sBAAsB,MAajCC,EAAmBC,UACrB,OAAIP,EACOA,EAAiBO,GAEL,QAAhBV,EAAAU,aAAI,EAAJA,EAAMC,kBAAU,IAAAX,EAAAA,EAAI,EAAE,EAG3BY,EAAmB,CAACC,EAAmBX,IACrCW,EAAYX,EACL,iBACAW,IAAcX,EACd,eAEA,gBAITY,EAAQ,CAACD,EAAmBX,IACvBa,EAAAA,QACH,GAAGH,EAAiBC,EAAWX,MAAiBW,KAOxD,IAAKZ,EAAMe,OAAQ,OAAO,KAgF1B,OACIC,EAAAA,0BAAKb,UAAWc,UAAKC,EAAAA,QAAgBf,IAAgBC,EAAU,CAAAe,SAAA,CAC3DC,EAAAA,IAAA,MAAA,CAAKjB,UAAWkB,EAAAA,QAAcF,SA/E3BnB,EAAMsB,KAAI,CAACC,EAASX,KAEvB,MAAMY,EAAcZ,GAAaX,EAEjC,OACImB,EAAAA,IAAA,MAAA,CAEIK,GAAIZ,EAAMD,EAAWX,GACrBE,UAAWuB,YAAgBP,SAE3BC,EAAAA,IAAA,MAAA,CACIjB,UAAWc,UACPU,EAAAA,aACAH,GAAeI,8BAPlBhB,EAUH,MAgEVQ,EAAAA,WAAKjB,UAAWkB,EAAAA,QAAcF,SACzBb,EA3BLU,EAAAA,KAAA,MAAA,CAEIS,GAAIZ,EAAMZ,EAAcA,GACxBE,UAAWuB,EAAAA,UAAgBP,SAAA,CAE3BH,EAAAA,KAACa,EAAAA,WAAWC,QACR3B,UAAW4B,EAAAA,qBACXC,OAAQ,WACRP,GAAI,GAAGZ,EAAMZ,EAAcA,+BAErBA,EAAe,EAAC,OAAMD,EAAMe,UAEtCK,EAAAA,IAACS,EAAAA,WAAWC,QACR3B,UAAW4B,EAAAA,qBACXC,OAAQ,UACRP,GAAI,GAAGZ,EAAMZ,EAAcA,oBAE1BO,EAAgBR,EAAMC,QAhBtBA,GAjCND,EAAMsB,KAAI,CAACC,EAASX,KACvB,MAAMY,EAAcZ,GAAaX,EAC3BgC,EAAUrB,IAAcX,EACxBiC,EAAaD,EAAU,OAAS,UAEtC,OACIb,EAAAA,IAAA,MAAA,CAEIK,GAAI,GAAGZ,EAAMD,EAAWX,WACxBE,UAAWuB,EAAAA,UAAgBP,SAE3BH,EAAAA,KAACa,EAAAA,WAAWC,OAAM,CACd3B,UAAWc,UACPkB,EAAAA,sBACAX,GACIY,oCAERJ,OAAQE,EAAU,eACJD,EAAOd,SAAA,CAEpBX,EAAgBe,GACjBH,EAAAA,IAACiB,EAAAA,eAAc,CAAAlB,SACVR,EAAiBC,EAAWX,SAfhCW,EAkBH,SAoCR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio-button.js","sources":["../../../src/radio-button/radio-button.tsx"],"sourcesContent":["import { CircleDotIcon, CircleIcon } from \"@lifesg/react-icons\";\nimport clsx from \"clsx\";\nimport type { ChangeEvent } from \"react\";\n\nimport * as styles from \"./radio-button.styles\";\nimport type { RadioButtonProps } from \"./types\";\n\n/**\n * A single radio button input.\n *\n * Use `RadioButton` as an input within a radio group.\n */\nexport const RadioButton = ({\n className,\n checked,\n disabled,\n displaySize = \"default\",\n focusableWhenDisabled,\n onChange,\n tabIndex,\n ...otherProps\n}: RadioButtonProps) => {\n // =============================================================================\n // CONST\n // =============================================================================\n const isFocusableWhenDisabled = !!disabled && !!focusableWhenDisabled;\n const isNativeDisabled = !!disabled && !focusableWhenDisabled;\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOnChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n\n onChange?.(event);\n };\n\n // =============================================================================\n // RENDER FUNCTION\n // =============================================================================\n const renderIcon = () => {\n return checked ? (\n <CircleDotIcon\n data-testid=\"radio-checked\"\n className={clsx(\n styles.icon,\n disabled ? styles.checkedIconDisabled : styles.checkedIcon\n )}\n aria-hidden\n />\n ) : (\n <CircleIcon\n data-testid=\"radio-unchecked\"\n className={clsx(\n styles.icon,\n disabled\n ? styles.uncheckedIconDisabled\n : styles.uncheckedIcon\n )}\n aria-hidden\n />\n );\n };\n\n return (\n <div\n className={clsx(styles.container, className)}\n data-display-size={displaySize}\n data-testid=\"radio-button\"\n >\n <input\n type=\"radio\"\n data-testid=\"radio-input\"\n onChange={handleOnChange}\n checked={checked}\n disabled={isNativeDisabled}\n aria-disabled={isFocusableWhenDisabled}\n tabIndex={isFocusableWhenDisabled ? 0 : tabIndex}\n className={clsx(styles.input, !disabled && styles.inputActive)}\n {...otherProps}\n />\n {renderIcon()}\n </div>\n );\n};\n"],"names":["_a","className","checked","disabled","displaySize","focusableWhenDisabled","onChange","tabIndex","otherProps","__rest","isFocusableWhenDisabled","isNativeDisabled","_jsxs","clsx","styles.container","children","_jsx","Object","assign","type","event","preventDefault","styles.input","styles.inputActive","CircleDotIcon","styles.icon","styles.checkedIconDisabled","styles.checkedIcon","CircleIcon","styles.uncheckedIconDisabled","styles.uncheckedIcon"],"mappings":"
|
|
1
|
+
{"version":3,"file":"radio-button.js","sources":["../../../src/radio-button/radio-button.tsx"],"sourcesContent":["import { CircleDotIcon, CircleIcon } from \"@lifesg/react-icons\";\nimport clsx from \"clsx\";\nimport type { ChangeEvent } from \"react\";\n\nimport * as styles from \"./radio-button.styles\";\nimport type { RadioButtonProps } from \"./types\";\n\n// @catalog\n/**\n * A single radio button input.\n *\n * Use `RadioButton` as an input within a radio group.\n */\nexport const RadioButton = ({\n className,\n checked,\n disabled,\n displaySize = \"default\",\n focusableWhenDisabled,\n onChange,\n tabIndex,\n ...otherProps\n}: RadioButtonProps) => {\n // =============================================================================\n // CONST\n // =============================================================================\n const isFocusableWhenDisabled = !!disabled && !!focusableWhenDisabled;\n const isNativeDisabled = !!disabled && !focusableWhenDisabled;\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOnChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n\n onChange?.(event);\n };\n\n // =============================================================================\n // RENDER FUNCTION\n // =============================================================================\n const renderIcon = () => {\n return checked ? (\n <CircleDotIcon\n data-testid=\"radio-checked\"\n className={clsx(\n styles.icon,\n disabled ? styles.checkedIconDisabled : styles.checkedIcon\n )}\n aria-hidden\n />\n ) : (\n <CircleIcon\n data-testid=\"radio-unchecked\"\n className={clsx(\n styles.icon,\n disabled\n ? styles.uncheckedIconDisabled\n : styles.uncheckedIcon\n )}\n aria-hidden\n />\n );\n };\n\n return (\n <div\n className={clsx(styles.container, className)}\n data-display-size={displaySize}\n data-testid=\"radio-button\"\n >\n <input\n type=\"radio\"\n data-testid=\"radio-input\"\n onChange={handleOnChange}\n checked={checked}\n disabled={isNativeDisabled}\n aria-disabled={isFocusableWhenDisabled}\n tabIndex={isFocusableWhenDisabled ? 0 : tabIndex}\n className={clsx(styles.input, !disabled && styles.inputActive)}\n {...otherProps}\n />\n {renderIcon()}\n </div>\n );\n};\n"],"names":["_a","className","checked","disabled","displaySize","focusableWhenDisabled","onChange","tabIndex","otherProps","__rest","isFocusableWhenDisabled","isNativeDisabled","_jsxs","clsx","styles.container","children","_jsx","Object","assign","type","event","preventDefault","styles.input","styles.inputActive","CircleDotIcon","styles.icon","styles.checkedIconDisabled","styles.checkedIcon","CircleIcon","styles.uncheckedIconDisabled","styles.uncheckedIcon"],"mappings":"mRAa4BA,QAAAC,UACxBA,EAASC,QACTA,EAAOC,SACPA,EAAQC,YACRA,EAAc,UAASC,sBACvBA,EAAqBC,SACrBA,EAAQC,SACRA,GAAQP,EACLQ,EAAUC,SAAAT,EARW,gGAaxB,MAAMU,IAA4BP,KAAcE,EAC1CM,IAAqBR,IAAaE,EAyCxC,OACIO,EAAAA,KAAA,MAAA,CACIX,UAAWY,EAAAA,QAAKC,EAAAA,UAAkBb,GAAU,oBACzBG,gBACP,eAAcW,SAAA,CAE1BC,MAAA,QAAAC,OAAAC,OAAA,CACIC,KAAK,QAAO,cACA,cACZb,SA7CYc,IAChBjB,EACAiB,EAAMC,iBAIVf,SAAAA,EAAWc,EAAM,EAwCTlB,QAASA,EACTC,SAAUQ,EAAgB,gBACXD,EACfH,SAAUG,EAA0B,EAAIH,EACxCN,UAAWY,UAAKS,EAAAA,OAAenB,GAAYoB,EAAAA,cACvCf,IAtCLN,EACHc,EAAAA,IAACQ,EAAAA,cAAa,CAAA,cACE,gBACZvB,UAAWY,EAAAA,QACPY,OACAtB,EAAWuB,EAAAA,oBAA6BC,kCAKhDX,MAACY,EAAAA,WAAU,CAAA,cACK,kBACZ3B,UAAWY,EAAAA,QACPY,EAAAA,KACAtB,EACM0B,EAAAA,sBACAC,EAAAA,eACT,eAAA,MAwBH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.js","sources":["../../../src/schedule/schedule.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { isEmpty } from \"lodash\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { ErrorDisplay } from \"../error-display\";\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport type { CommonScheduleViewProps } from \"./internal-types\";\nimport * as styles from \"./schedule.styles\";\nimport { ScheduleDayView } from \"./schedule-day-view/schedule-day-view\";\nimport { ScheduleHeader } from \"./schedule-header/schedule-header\";\nimport { ScheduleWeekView } from \"./schedule-week-view/schedule-week-view\";\nimport type { ScheduleProps } from \"./types\";\n\n/**\n * A grid visualisation of slot-based time availability for services across day and week views.\n */\nexport const Schedule = ({\n id,\n className,\n view = \"day\",\n date,\n serviceData,\n loading = false,\n minTime = \"00:00\",\n maxTime = \"23:59\",\n initialScrollTime = minTime,\n minDate,\n maxDate,\n emptyContentMessage,\n emptySlotPopover,\n onPreviousDayClick,\n onNextDayClick,\n onCalendarDateSelect,\n onTodayClick,\n onEmptySlotClick,\n blockedMessage,\n onClickHiddenSlots,\n \"data-testid\": testId = \"schedule\",\n ...otherProps\n}: ScheduleProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [currentView, setCurrentView] = useState<\"day\" | \"week\">(view);\n const isSmallScreen = useMaxWidthMediaQuery(\"lg\");\n const effectiveView = isSmallScreen ? \"day\" : currentView;\n const contentContainerRef = useRef<HTMLDivElement>(null);\n const [visibleServiceIdx, setVisibleServiceIdx] = useState(0);\n const isEmptyContent = serviceData.length === 0 || isEmpty(serviceData);\n const filteredServiceData = useMemo(\n () =>\n serviceData.map((service) => ({\n ...service,\n slots: service.slots.filter((slot) => slot.date === date),\n })),\n [serviceData, date]\n );\n let visibleServiceData = filteredServiceData;\n if (isSmallScreen) {\n visibleServiceData =\n filteredServiceData.length > 0\n ? [filteredServiceData[visibleServiceIdx]]\n : [];\n }\n const showPrevArrow = isSmallScreen && visibleServiceIdx > 0;\n const showNextArrow =\n isSmallScreen && visibleServiceIdx < filteredServiceData.length - 1;\n\n useEffect(() => {\n setVisibleServiceIdx(0);\n }, [filteredServiceData]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleViewChange = (newView: \"day\" | \"week\") => {\n setCurrentView(newView);\n };\n\n const handleTodayClick = useCallback(() => {\n onTodayClick?.();\n }, [onTodayClick]);\n\n const handleNextService = useCallback(() => {\n if (!filteredServiceData) return;\n setVisibleServiceIdx((idx) =>\n idx < filteredServiceData.length - 1 ? idx + 1 : idx\n );\n }, [filteredServiceData]);\n\n const handlePrevService = useCallback(() => {\n setVisibleServiceIdx((idx) => (idx > 0 ? idx - 1 : idx));\n }, []);\n\n // =============================================================================\n // RENDER FUNCTION\n // =============================================================================\n\n const renderEmptyContent = () => (\n <div className={clsx(styles.emptyTableContainer, \"empty-container\")}>\n <ErrorDisplay\n className={styles.noResultsFound}\n type=\"no-item-found\"\n description={emptyContentMessage}\n />\n </div>\n );\n\n const commonScheduleViewProps: CommonScheduleViewProps = {\n date,\n loading,\n minTime,\n maxTime,\n initialScrollTime,\n containerRef: contentContainerRef,\n blockedMessage,\n };\n\n const renderScheduleView = () => (\n <div\n className={styles.scheduleBodyContainer}\n ref={contentContainerRef}\n data-id=\"schedule-container\"\n >\n {effectiveView === \"day\" ? (\n <ScheduleDayView\n {...commonScheduleViewProps}\n serviceData={visibleServiceData}\n emptySlotPopover={emptySlotPopover}\n isMobile={isSmallScreen}\n onNextService={handleNextService}\n onPrevService={handlePrevService}\n showPrevArrow={showPrevArrow}\n showNextArrow={showNextArrow}\n onEmptySlotClick={onEmptySlotClick}\n />\n ) : (\n <ScheduleWeekView\n {...commonScheduleViewProps}\n serviceData={serviceData}\n onClickHiddenSlots={onClickHiddenSlots}\n />\n )}\n </div>\n );\n\n return (\n <div\n id={id}\n className={clsx(\n styles.container,\n loading && styles.containerLoading,\n className\n )}\n data-testid={testId}\n {...otherProps}\n >\n <ScheduleHeader\n data-id=\"schedule-header\"\n date={date}\n view={effectiveView}\n minDate={minDate}\n maxDate={maxDate}\n onPreviousDayClick={onPreviousDayClick}\n onNextDayClick={onNextDayClick}\n onCalendarDateSelect={onCalendarDateSelect}\n onViewChange={handleViewChange}\n onTodayClick={handleTodayClick}\n />\n\n {isEmptyContent ? renderEmptyContent() : renderScheduleView()}\n </div>\n );\n};\n"],"names":["_a","id","className","view","date","serviceData","loading","minTime","maxTime","initialScrollTime","minDate","maxDate","emptyContentMessage","emptySlotPopover","onPreviousDayClick","onNextDayClick","onCalendarDateSelect","onTodayClick","onEmptySlotClick","blockedMessage","onClickHiddenSlots","testId","otherProps","__rest","currentView","setCurrentView","useState","isSmallScreen","useMaxWidthMediaQuery","effectiveView","contentContainerRef","useRef","visibleServiceIdx","setVisibleServiceIdx","isEmptyContent","length","isEmpty","filteredServiceData","useMemo","map","service","slots","filter","slot","visibleServiceData","showPrevArrow","showNextArrow","useEffect","handleTodayClick","useCallback","handleNextService","idx","handlePrevService","commonScheduleViewProps","containerRef","_jsxs","Object","assign","clsx","styles.container","styles.containerLoading","children","_jsx","ScheduleHeader","onViewChange","newView","styles.emptyTableContainer","ErrorDisplay","styles.noResultsFound","type","description","styles.scheduleBodyContainer","ref","ScheduleDayView","isMobile","onNextService","onPrevService","ScheduleWeekView"],"mappings":"+
|
|
1
|
+
{"version":3,"file":"schedule.js","sources":["../../../src/schedule/schedule.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { isEmpty } from \"lodash\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { ErrorDisplay } from \"../error-display\";\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport type { CommonScheduleViewProps } from \"./internal-types\";\nimport * as styles from \"./schedule.styles\";\nimport { ScheduleDayView } from \"./schedule-day-view/schedule-day-view\";\nimport { ScheduleHeader } from \"./schedule-header/schedule-header\";\nimport { ScheduleWeekView } from \"./schedule-week-view/schedule-week-view\";\nimport type { ScheduleProps } from \"./types\";\n\n// @catalog\n/**\n * A grid visualisation of slot-based time availability for services across day and week views.\n */\nexport const Schedule = ({\n id,\n className,\n view = \"day\",\n date,\n serviceData,\n loading = false,\n minTime = \"00:00\",\n maxTime = \"23:59\",\n initialScrollTime = minTime,\n minDate,\n maxDate,\n emptyContentMessage,\n emptySlotPopover,\n onPreviousDayClick,\n onNextDayClick,\n onCalendarDateSelect,\n onTodayClick,\n onEmptySlotClick,\n blockedMessage,\n onClickHiddenSlots,\n \"data-testid\": testId = \"schedule\",\n ...otherProps\n}: ScheduleProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [currentView, setCurrentView] = useState<\"day\" | \"week\">(view);\n const isSmallScreen = useMaxWidthMediaQuery(\"lg\");\n const effectiveView = isSmallScreen ? \"day\" : currentView;\n const contentContainerRef = useRef<HTMLDivElement>(null);\n const [visibleServiceIdx, setVisibleServiceIdx] = useState(0);\n const isEmptyContent = serviceData.length === 0 || isEmpty(serviceData);\n const filteredServiceData = useMemo(\n () =>\n serviceData.map((service) => ({\n ...service,\n slots: service.slots.filter((slot) => slot.date === date),\n })),\n [serviceData, date]\n );\n let visibleServiceData = filteredServiceData;\n if (isSmallScreen) {\n visibleServiceData =\n filteredServiceData.length > 0\n ? [filteredServiceData[visibleServiceIdx]]\n : [];\n }\n const showPrevArrow = isSmallScreen && visibleServiceIdx > 0;\n const showNextArrow =\n isSmallScreen && visibleServiceIdx < filteredServiceData.length - 1;\n\n useEffect(() => {\n setVisibleServiceIdx(0);\n }, [filteredServiceData]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleViewChange = (newView: \"day\" | \"week\") => {\n setCurrentView(newView);\n };\n\n const handleTodayClick = useCallback(() => {\n onTodayClick?.();\n }, [onTodayClick]);\n\n const handleNextService = useCallback(() => {\n if (!filteredServiceData) return;\n setVisibleServiceIdx((idx) =>\n idx < filteredServiceData.length - 1 ? idx + 1 : idx\n );\n }, [filteredServiceData]);\n\n const handlePrevService = useCallback(() => {\n setVisibleServiceIdx((idx) => (idx > 0 ? idx - 1 : idx));\n }, []);\n\n // =============================================================================\n // RENDER FUNCTION\n // =============================================================================\n\n const renderEmptyContent = () => (\n <div className={clsx(styles.emptyTableContainer, \"empty-container\")}>\n <ErrorDisplay\n className={styles.noResultsFound}\n type=\"no-item-found\"\n description={emptyContentMessage}\n />\n </div>\n );\n\n const commonScheduleViewProps: CommonScheduleViewProps = {\n date,\n loading,\n minTime,\n maxTime,\n initialScrollTime,\n containerRef: contentContainerRef,\n blockedMessage,\n };\n\n const renderScheduleView = () => (\n <div\n className={styles.scheduleBodyContainer}\n ref={contentContainerRef}\n data-id=\"schedule-container\"\n >\n {effectiveView === \"day\" ? (\n <ScheduleDayView\n {...commonScheduleViewProps}\n serviceData={visibleServiceData}\n emptySlotPopover={emptySlotPopover}\n isMobile={isSmallScreen}\n onNextService={handleNextService}\n onPrevService={handlePrevService}\n showPrevArrow={showPrevArrow}\n showNextArrow={showNextArrow}\n onEmptySlotClick={onEmptySlotClick}\n />\n ) : (\n <ScheduleWeekView\n {...commonScheduleViewProps}\n serviceData={serviceData}\n onClickHiddenSlots={onClickHiddenSlots}\n />\n )}\n </div>\n );\n\n return (\n <div\n id={id}\n className={clsx(\n styles.container,\n loading && styles.containerLoading,\n className\n )}\n data-testid={testId}\n {...otherProps}\n >\n <ScheduleHeader\n data-id=\"schedule-header\"\n date={date}\n view={effectiveView}\n minDate={minDate}\n maxDate={maxDate}\n onPreviousDayClick={onPreviousDayClick}\n onNextDayClick={onNextDayClick}\n onCalendarDateSelect={onCalendarDateSelect}\n onViewChange={handleViewChange}\n onTodayClick={handleTodayClick}\n />\n\n {isEmptyContent ? renderEmptyContent() : renderScheduleView()}\n </div>\n );\n};\n"],"names":["_a","id","className","view","date","serviceData","loading","minTime","maxTime","initialScrollTime","minDate","maxDate","emptyContentMessage","emptySlotPopover","onPreviousDayClick","onNextDayClick","onCalendarDateSelect","onTodayClick","onEmptySlotClick","blockedMessage","onClickHiddenSlots","testId","otherProps","__rest","currentView","setCurrentView","useState","isSmallScreen","useMaxWidthMediaQuery","effectiveView","contentContainerRef","useRef","visibleServiceIdx","setVisibleServiceIdx","isEmptyContent","length","isEmpty","filteredServiceData","useMemo","map","service","slots","filter","slot","visibleServiceData","showPrevArrow","showNextArrow","useEffect","handleTodayClick","useCallback","handleNextService","idx","handlePrevService","commonScheduleViewProps","containerRef","_jsxs","Object","assign","clsx","styles.container","styles.containerLoading","children","_jsx","ScheduleHeader","onViewChange","newView","styles.emptyTableContainer","ErrorDisplay","styles.noResultsFound","type","description","styles.scheduleBodyContainer","ref","ScheduleDayView","isMobile","onNextService","onPrevService","ScheduleWeekView"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select-histogram.js","sources":["../../../src/select-histogram/select-histogram.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { HistogramSlider } from \"../histogram-slider\";\nimport { DropdownListState, ExpandableElement } from \"../shared/dropdown-list\";\nimport type { DropdownRenderProps } from \"../shared/dropdown-wrapper\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport * as dropdownWrapperStyles from \"../shared/dropdown-wrapper/dropdown-wrapper.styles\";\nimport { InputBox } from \"../shared/input-wrapper\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport * as styles from \"./select-histogram.styles\";\nimport type { SelectHistogramProps } from \"./types\";\n\n/**\n * A form input that displays the selected range and reveals a histogram slider in a dropdown.\n *\n * Use `SelectHistogram` when users need to select a numeric range against a data distribution.\n */\nexport const SelectHistogram = ({\n alignment = \"left\",\n className,\n disabled,\n dropdownZIndex,\n error,\n histogramSlider,\n id,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n onBlur,\n onChange,\n onChangeEnd,\n optionTruncationType = \"end\",\n placeholder = \"Select\",\n rangeLabelPrefix,\n rangeLabelSuffix,\n readOnly,\n renderRangeLabel,\n value,\n dropdownRootNode,\n ...otherProps\n}: SelectHistogramProps): JSX.Element => {\n const {\n interval,\n bins = [],\n renderEmptyView,\n ariaLabels,\n } = histogramSlider;\n // =============================================================================\n // CONST, STATE\n // =============================================================================\n const values = bins.map((item) => item.minValue);\n const minValue = Math.min(...values);\n const [selection, setSelection] = useState<[number, number]>(\n initSelection()\n );\n const [showOptions, setShowOptions] = useState<boolean>(false);\n const [focused, setFocused] = useState<boolean>(false);\n const internalId = useId();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const selectorRef = useRef<HTMLButtonElement>(null);\n const labelContainerRef = useRef<HTMLDivElement>(null);\n\n const testId = otherProps[\"data-testid\"] || \"select-histogram\";\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n if (value !== selection) {\n setSelection(initSelection());\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOpen = () => {\n setShowOptions(true);\n };\n\n const handleClose = () => {\n setShowOptions(false);\n };\n\n const handleDismiss = () => {\n selectorRef.current?.focus();\n setShowOptions(false);\n };\n\n const onSliderChange = (values: [number, number]) => {\n setSelection(values);\n onChange?.(values);\n };\n\n const onSliderChangeEnd = (values: [number, number]) => {\n setSelection(values);\n onChangeEnd?.(values);\n };\n\n const handleNodeFocus = () => {\n if (!focused && !showOptions) {\n setFocused(true);\n }\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n focused &&\n !showOptions &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setFocused(false);\n onBlur?.();\n }\n };\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n function initSelection(): [number, number] {\n return value ?? [minValue, minValue + interval];\n }\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderSelector = (value: number) => {\n if (renderRangeLabel) {\n return renderRangeLabel(value);\n }\n\n return (\n <Typography.BodyBL>\n {rangeLabelPrefix}\n {value}\n {rangeLabelSuffix}\n </Typography.BodyBL>\n );\n };\n\n const getDisplayValue = () => {\n return !values || values.length === 0 ? (\n <div\n className={clsx(\n styles.placeholderLabel,\n optionTruncationType !== \"middle\" &&\n styles.placeholderLabelTruncateEnd\n )}\n >\n {placeholder}\n </div>\n ) : (\n <div className={styles.label}>\n {renderSelector(selection[0])}\n <div className={styles.separator}>-</div>\n {renderSelector(selection[1])}\n </div>\n );\n };\n\n const renderSelectorContent = () => (\n <div\n className={dropdownWrapperStyles.labelContainer}\n ref={labelContainerRef}\n data-disabled={disabled || undefined}\n >\n {getDisplayValue()}\n </div>\n );\n\n const renderElement = () => {\n return (\n <InputBox\n className={className}\n data-testid={testId}\n id={id}\n ref={nodeRef}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n focused={focused}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n >\n <ExpandableElement\n ref={selectorRef}\n disabled={disabled}\n expanded={showOptions}\n listboxId={internalId}\n popupRole=\"dialog\"\n readOnly={readOnly}\n variant=\"default\"\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n >\n {renderSelectorContent()}\n </ExpandableElement>\n </InputBox>\n );\n };\n\n const renderDropdown = ({\n elementWidth,\n styles: floatingStyles,\n setFloatingRef,\n getFloatingProps,\n }: DropdownRenderProps) => (\n <div\n className={styles.histogramSliderDropdownContainer}\n style={{ ...floatingStyles, width: elementWidth }}\n ref={setFloatingRef}\n data-testid={`${testId}-dropdown`}\n {...getFloatingProps()}\n >\n <HistogramSlider\n interval={interval}\n value={selection}\n bins={bins}\n onChange={onSliderChange}\n onChangeEnd={onSliderChangeEnd}\n showRangeLabels={false}\n renderEmptyView={renderEmptyView}\n ariaLabels={ariaLabels}\n />\n </div>\n );\n\n return (\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={showOptions}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n );\n};\n"],"names":["_a","alignment","className","disabled","dropdownZIndex","error","histogramSlider","id","ariaLabelledBy","ariaDescribedBy","ariaInvalid","onBlur","onChange","onChangeEnd","optionTruncationType","placeholder","rangeLabelPrefix","rangeLabelSuffix","readOnly","renderRangeLabel","value","dropdownRootNode","otherProps","__rest","interval","bins","renderEmptyView","ariaLabels","values","map","item","minValue","Math","min","selection","setSelection","useState","initSelection","showOptions","setShowOptions","focused","setFocused","internalId","useId","nodeRef","useRef","selectorRef","labelContainerRef","testId","useEffect","onSliderChange","onSliderChangeEnd","handleNodeFocus","handleNodeBlur","e","current","contains","relatedTarget","renderSelector","_jsxs","Typography","BodyBL","children","_jsx","DropdownListState","ElementWithDropdown","enabled","isOpen","renderElement","InputBox","ref","tabIndex","onFocus","ExpandableElement","expanded","listboxId","popupRole","variant","dropdownWrapperStyles.labelContainer","undefined","length","styles.label","styles.separator","clsx","styles.placeholderLabel","styles.placeholderLabelTruncateEnd","renderDropdown","elementWidth","styles","floatingStyles","setFloatingRef","getFloatingProps","Object","assign","styles.histogramSliderDropdownContainer","style","width","HistogramSlider","showRangeLabels","onOpen","onClose","onDismiss","focus","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"select-histogram.js","sources":["../../../src/select-histogram/select-histogram.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { HistogramSlider } from \"../histogram-slider\";\nimport { DropdownListState, ExpandableElement } from \"../shared/dropdown-list\";\nimport type { DropdownRenderProps } from \"../shared/dropdown-wrapper\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport * as dropdownWrapperStyles from \"../shared/dropdown-wrapper/dropdown-wrapper.styles\";\nimport { InputBox } from \"../shared/input-wrapper\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport * as styles from \"./select-histogram.styles\";\nimport type { SelectHistogramProps } from \"./types\";\n\n// @catalog\n/**\n * A form input that displays the selected range and reveals a histogram slider in a dropdown.\n *\n * Use `SelectHistogram` when users need to select a numeric range against a data distribution.\n */\nexport const SelectHistogram = ({\n alignment = \"left\",\n className,\n disabled,\n dropdownZIndex,\n error,\n histogramSlider,\n id,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n onBlur,\n onChange,\n onChangeEnd,\n optionTruncationType = \"end\",\n placeholder = \"Select\",\n rangeLabelPrefix,\n rangeLabelSuffix,\n readOnly,\n renderRangeLabel,\n value,\n dropdownRootNode,\n ...otherProps\n}: SelectHistogramProps): JSX.Element => {\n const {\n interval,\n bins = [],\n renderEmptyView,\n ariaLabels,\n } = histogramSlider;\n // =============================================================================\n // CONST, STATE\n // =============================================================================\n const values = bins.map((item) => item.minValue);\n const minValue = Math.min(...values);\n const [selection, setSelection] = useState<[number, number]>(\n initSelection()\n );\n const [showOptions, setShowOptions] = useState<boolean>(false);\n const [focused, setFocused] = useState<boolean>(false);\n const internalId = useId();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const selectorRef = useRef<HTMLButtonElement>(null);\n const labelContainerRef = useRef<HTMLDivElement>(null);\n\n const testId = otherProps[\"data-testid\"] || \"select-histogram\";\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n if (value !== selection) {\n setSelection(initSelection());\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOpen = () => {\n setShowOptions(true);\n };\n\n const handleClose = () => {\n setShowOptions(false);\n };\n\n const handleDismiss = () => {\n selectorRef.current?.focus();\n setShowOptions(false);\n };\n\n const onSliderChange = (values: [number, number]) => {\n setSelection(values);\n onChange?.(values);\n };\n\n const onSliderChangeEnd = (values: [number, number]) => {\n setSelection(values);\n onChangeEnd?.(values);\n };\n\n const handleNodeFocus = () => {\n if (!focused && !showOptions) {\n setFocused(true);\n }\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n focused &&\n !showOptions &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setFocused(false);\n onBlur?.();\n }\n };\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n function initSelection(): [number, number] {\n return value ?? [minValue, minValue + interval];\n }\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderSelector = (value: number) => {\n if (renderRangeLabel) {\n return renderRangeLabel(value);\n }\n\n return (\n <Typography.BodyBL>\n {rangeLabelPrefix}\n {value}\n {rangeLabelSuffix}\n </Typography.BodyBL>\n );\n };\n\n const getDisplayValue = () => {\n return !values || values.length === 0 ? (\n <div\n className={clsx(\n styles.placeholderLabel,\n optionTruncationType !== \"middle\" &&\n styles.placeholderLabelTruncateEnd\n )}\n >\n {placeholder}\n </div>\n ) : (\n <div className={styles.label}>\n {renderSelector(selection[0])}\n <div className={styles.separator}>-</div>\n {renderSelector(selection[1])}\n </div>\n );\n };\n\n const renderSelectorContent = () => (\n <div\n className={dropdownWrapperStyles.labelContainer}\n ref={labelContainerRef}\n data-disabled={disabled || undefined}\n >\n {getDisplayValue()}\n </div>\n );\n\n const renderElement = () => {\n return (\n <InputBox\n className={className}\n data-testid={testId}\n id={id}\n ref={nodeRef}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n focused={focused}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n >\n <ExpandableElement\n ref={selectorRef}\n disabled={disabled}\n expanded={showOptions}\n listboxId={internalId}\n popupRole=\"dialog\"\n readOnly={readOnly}\n variant=\"default\"\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n >\n {renderSelectorContent()}\n </ExpandableElement>\n </InputBox>\n );\n };\n\n const renderDropdown = ({\n elementWidth,\n styles: floatingStyles,\n setFloatingRef,\n getFloatingProps,\n }: DropdownRenderProps) => (\n <div\n className={styles.histogramSliderDropdownContainer}\n style={{ ...floatingStyles, width: elementWidth }}\n ref={setFloatingRef}\n data-testid={`${testId}-dropdown`}\n {...getFloatingProps()}\n >\n <HistogramSlider\n interval={interval}\n value={selection}\n bins={bins}\n onChange={onSliderChange}\n onChangeEnd={onSliderChangeEnd}\n showRangeLabels={false}\n renderEmptyView={renderEmptyView}\n ariaLabels={ariaLabels}\n />\n </div>\n );\n\n return (\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={showOptions}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n );\n};\n"],"names":["_a","alignment","className","disabled","dropdownZIndex","error","histogramSlider","id","ariaLabelledBy","ariaDescribedBy","ariaInvalid","onBlur","onChange","onChangeEnd","optionTruncationType","placeholder","rangeLabelPrefix","rangeLabelSuffix","readOnly","renderRangeLabel","value","dropdownRootNode","otherProps","__rest","interval","bins","renderEmptyView","ariaLabels","values","map","item","minValue","Math","min","selection","setSelection","useState","initSelection","showOptions","setShowOptions","focused","setFocused","internalId","useId","nodeRef","useRef","selectorRef","labelContainerRef","testId","useEffect","onSliderChange","onSliderChangeEnd","handleNodeFocus","handleNodeBlur","e","current","contains","relatedTarget","renderSelector","_jsxs","Typography","BodyBL","children","_jsx","DropdownListState","ElementWithDropdown","enabled","isOpen","renderElement","InputBox","ref","tabIndex","onFocus","ExpandableElement","expanded","listboxId","popupRole","variant","dropdownWrapperStyles.labelContainer","undefined","length","styles.label","styles.separator","clsx","styles.placeholderLabel","styles.placeholderLabelTruncateEnd","renderDropdown","elementWidth","styles","floatingStyles","setFloatingRef","getFloatingProps","Object","assign","styles.histogramSliderDropdownContainer","style","width","HistogramSlider","showRangeLabels","onOpen","onClose","onDismiss","focus","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"q0EAoBgCA,QAAAC,UAC5BA,EAAY,OAAMC,UAClBA,EAASC,SACTA,EAAQC,eACRA,EAAcC,MACdA,EAAKC,gBACLA,EAAeC,GACfA,EACA,kBAAmBC,EACnB,mBAAoBC,EACpB,eAAgBC,EAAWC,OAC3BA,EAAMC,SACNA,EAAQC,YACRA,EAAWC,qBACXA,EAAuB,MAAKC,YAC5BA,EAAc,SAAQC,iBACtBA,EAAgBC,iBAChBA,EAAgBC,SAChBA,EAAQC,iBACRA,EAAgBC,MAChBA,EAAKC,iBACLA,GAAgBrB,EACbsB,EAAUC,SAAAvB,EAtBe,CAAA,YAAA,YAAA,WAAA,iBAAA,QAAA,kBAAA,KAAA,kBAAA,mBAAA,eAAA,SAAA,WAAA,cAAA,uBAAA,cAAA,mBAAA,mBAAA,WAAA,mBAAA,QAAA,qBAwB5B,MAAMwB,SACFA,EAAQC,KACRA,EAAO,GAAEC,gBACTA,EAAeC,WACfA,GACArB,EAIEsB,EAASH,EAAKI,KAAKC,GAASA,EAAKC,WACjCA,EAAWC,KAAKC,OAAOL,IACtBM,EAAWC,GAAgBC,EAAAA,SAC9BC,OAEGC,EAAaC,GAAkBH,EAAAA,UAAkB,IACjDI,EAASC,GAAcL,EAAAA,UAAkB,GAC1CM,EAAaC,EAAAA,QAEbC,EAAUC,EAAAA,OAAuB,MACjCC,EAAcD,EAAAA,OAA0B,MACxCE,EAAoBF,EAAAA,OAAuB,MAE3CG,EAAS1B,EAAW,gBAAkB,mBAI5C2B,EAAAA,WAAU,KACF7B,IAAUc,GACVC,EAAaE,KACjB,GAED,CAACjB,IAKJ,MAaM8B,EAAkBtB,IACpBO,EAAaP,GACbhB,SAAAA,EAAWgB,EAAO,EAGhBuB,GAAqBvB,IACvBO,EAAaP,GACbf,SAAAA,EAAce,EAAO,EAGnBwB,GAAkB,KACfZ,GAAYF,GACbG,GAAW,EACf,EAGEY,GAAkBC,IAEhBd,IACCF,GACDM,EAAQW,UACPX,EAAQW,QAAQC,SAASF,EAAEG,iBAE5BhB,GAAW,GACX9B,SAAAA,IACJ,EAKJ,SAAS0B,KACL,OAAOjB,QAAAA,EAAS,CAACW,EAAUA,EAAWP,EAC1C,CAKA,MAAMkC,GAAkBtC,GAChBD,EACOA,EAAiBC,GAIxBuC,EAAAA,KAACC,aAAWC,OAAM,CAAAC,SAAA,CACb9C,EACAI,EACAH,KA8Fb,OACI8C,EAAAA,IAACC,EAAAA,kBAAiB,CAAAF,SACdC,EAAAA,IAACE,EAAAA,oBAAmB,CAChBC,SAAUhD,IAAaf,EACvBgE,OAAQ7B,EACR8B,cAhEU,IAEdL,MAACM,EAAAA,UACGnE,UAAWA,EAAS,cACP8C,EACbzC,GAAIA,EACJ+D,IAAK1B,EACL2B,UAAU,EACVC,QAASpB,GACTzC,OAAQ0C,GACRb,QAASA,EACTrC,SAAUA,EACVe,SAAUA,EACVb,MAAOA,WAEP0D,MAACU,EAAAA,mBACGH,IAAKxB,EACL3C,SAAUA,EACVuE,SAAUpC,EACVqC,UAAWjC,EACXkC,UAAU,SACV1D,SAAUA,EACV2D,QAAQ,UAAS,kBACArE,qBACCC,EAAe,eACnBC,EAAWoD,SAlCrCC,EAAAA,IAAA,MAAA,CACI7D,UAAW4E,EAAAA,eACXR,IAAKvB,EAAiB,gBACP5C,QAAY4E,EAASjB,SAvBhClC,GAA4B,IAAlBA,EAAOoD,OAWrBrB,EAAAA,KAAA,MAAA,CAAKzD,UAAW+E,EAAAA,MAAYnB,SAAA,CACvBJ,GAAexB,EAAU,IAC1B6B,EAAAA,IAAA,MAAA,CAAK7D,UAAWgF,EAAAA,UAAgBpB,SAAA,MAC/BJ,GAAexB,EAAU,OAb9B6B,EAAAA,IAAA,MAAA,CACI7D,UAAWiF,EAAAA,QACPC,EAAAA,iBACyB,WAAzBtE,GACIuE,EAAAA,sCAGPtE,UAsFDuE,eAhCW,EACnBC,eACAC,OAAQC,EACRC,iBACAC,sBAEA5B,EAAAA,IAAA,MAAA6B,OAAAC,OAAA,CACI3F,UAAW4F,mCACXC,qCAAYN,GAAc,CAAEO,MAAOT,IACnCjB,IAAKoB,EAAc,cACN,GAAG1C,cACZ2C,IAAkB,CAAA7B,SAEtBC,EAAAA,IAACkC,EAAAA,gBAAe,CACZzE,SAAUA,EACVJ,MAAOc,EACPT,KAAMA,EACNb,SAAUsC,EACVrC,YAAasC,GACb+C,iBAAiB,EACjBxE,gBAAiBA,EACjBC,WAAYA,OAYZwE,OAhKO,KACf5D,GAAe,EAAK,EAgKZ6D,QA7JQ,KAChB7D,GAAe,EAAM,EA6Jb8D,UA1JU,WACC,QAAnBrG,EAAA8C,EAAYS,eAAO,IAAAvD,GAAAA,EAAEsG,QACrB/D,GAAe,EAAM,EAyJbgE,eAAa,EACbC,OAAQ,EACRvG,UAAWA,EACXwG,oBAAkB,EAClBC,aAActG,EACduG,SAAUtF,KAEE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("react/jsx-runtime"),t=require("@lifesg/react-icons/exclamation-circle-fill"),r=require("@lifesg/react-icons/square"),s=require("@lifesg/react-icons/square-fill"),
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("@lifesg/react-icons/exclamation-circle-fill"),r=require("@lifesg/react-icons/square"),s=require("@lifesg/react-icons/square-fill"),n=require("@lifesg/react-icons/square-tick-fill"),l=require("@lifesg/react-icons/tick"),i=require("clsx"),a=require("../../external/lodash/find.js"),o=require("../../external/lodash/isEqual.js"),u=require("react"),c=require("react-virtuoso"),d=require("../../markup/markup.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");var m=require("../../theme/utils/use-apply-styles.js");require("../../theme/utils/use-media-query.js"),require("../../util/calendar-helper.js"),require("../../external/dayjs/dayjs.min.js");var v=require("../../util/merge-refs.js");require("../../util/simple-id-generator.js"),require("../../util/string-helper.js"),require("@react-aria/live-announcer");var f=require("../../util/use-event.js"),p=require("../../util/use-event-listener.js"),h=require("../../util/use-mount.js"),x=require("../../util/use-previous.js"),j=require("../accessibility/index.js"),b=require("../component-loading-spinner/component-loading-spinner.js"),q=require("../dropdown-wrapper/element-with-dropdown.js"),I=require("../input-wrapper/input-wrapper.js"),g=require("./dropdown-label.js"),y=require("./dropdown-list.styles.js"),S=require("./dropdown-list-state.js"),C=require("./dropdown-search.js"),w=require("./virtuoso-components.js");function k(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var T=k(i);const L=u.forwardRef((({listItems:i,multiSelect:k,maxSelectable:L,selectedItems:N,disableItemFocus:E,itemsLoadState:D="success",itemTruncationType:R="end",itemMaxLines:A=2,labelDisplayType:F="inline",variant:B="default",listboxId:M,ariaLabel:P,matchElementWidth:V=!1,width:O,topScrollItem:_,onSelectItem:W,onSelectAll:$,onDismiss:H,onRetry:U,valueExtractor:z,listExtractor:G,renderListItem:J,renderCustomCallToAction:K,enableSearch:Q,hideNoResultsDisplay:X,noResultsDescription:Y,customLabels:Z,searchPlaceholder:ee,searchFunction:te,onSearch:re},se)=>{const{noResultsLabel:ne="No results found.",selectAllButtonLabel:le="Select all",clearAllButtonLabel:ie="Clear all"}=Z||{},ae=(null==Z?void 0:Z.searchPlaceholder)||ee||"Search",oe=(null==Z?void 0:Z.noResultsDescription)||Y,{focusedIndex:ue,setFocusedIndex:ce}=u.useContext(S.DropdownListStateContext),{elementWidth:de,setFloatingRef:me,getFloatingProps:ve,styles:fe}=q.useDropdownRender(),[pe,he]=u.useState(""),[xe,je]=u.useState(null!=i?i:[]),be=x.useCompare(D),qe=h.useIsMounted(),Ie=u.useRef(null),ge=u.useRef([]),ye=u.useRef(null),Se=u.useRef(null),Ce=!!L&&!!N&&(null==N?void 0:N.length)===L;let we,ke="default";O?(we=O,ke="custom"):V&&de&&(we=`${de}px`,ke="match"),m.useApplyStyle(Ie,{[y.tokens.containerWidth]:we});const Te=e=>{const t=G?G(e):null==e?void 0:e.toString();return"object"==typeof t?{title:t.title,secondaryLabel:t.secondaryLabel}:{title:null!=t?t:""}},Le=u.useCallback((e=>!!a.default(N,(t=>o.default(t,e)))),[N]),Ne=f.useEvent((()=>null==te?void 0:te(pe))),Ee=f.useEvent((()=>null==i?void 0:i.filter((e=>{const{title:t,secondaryLabel:r}=Te(e),s=pe.trim().toLowerCase();return t.toLowerCase().includes(s)||r&&r.toLowerCase().includes(s)})))),De=u.useCallback((e=>{var t,r;if(E)return;if(ye.current)return ce(-1),void setTimeout((()=>{var e;return null===(e=ye.current)||void 0===e?void 0:e.focus()}),0);const s=null!=xe?xe:[];if(0===s.length)return;if(void 0!==(null==e?void 0:e.index)){const r=Math.max(0,Math.min(e.index,s.length-1));return null===(t=Se.current)||void 0===t||t.scrollToIndex({index:r,align:"center"}),ce(r),void setTimeout((()=>{var e;return null===(e=ge.current[r])||void 0===e?void 0:e.focus()}),0)}const n=(null==e?void 0:e.preferSelected)?s.findIndex((e=>Le(e))):-1,l=-1!==n?n:ue>=0&&ue<s.length?ue:0;null===(r=Se.current)||void 0===r||r.scrollToIndex({index:l,align:"center"}),ce(l),setTimeout((()=>{var e;return null===(e=ge.current[l])||void 0===e?void 0:e.focus()}),0)}),[Le,E,xe,ue,ce]),Re=(e,t)=>{Ce&&!Le(e)||(ce(t),null==W||W(e,(e=>z?z(e):e)(e)))},Ae=e=>{const t=e.target.value;he(t),null==re||re()},Fe=()=>{var e;he(""),null===(e=ye.current)||void 0===e||e.focus(),null==re||re()},Be=()=>null==U?void 0:U();p.useEventListener("keydown",(e=>{var t,r;switch(e.code){case"ArrowDown":if(e.preventDefault(),ue<xe.length-1){const e=ue+1;null===(t=ge.current[e])||void 0===t||t.focus(),ce(e)}break;case"ArrowUp":if(e.preventDefault(),ue>0){const e=ue-1;null===(r=ge.current[e])||void 0===r||r.focus(),ce(e)}else 0===ue&&ye.current&&(ye.current.focus(),ce(-1));break;case"Space":case"Enter":ue>=0&&(document.activeElement===ge.current[ue]||document.activeElement===ye.current)&&(e.preventDefault(),xe[ue]&&Re(xe[ue],ue))}})),u.useImperativeHandle(se,(()=>({refocus:De})),[De]),u.useEffect((()=>{var e;if(!_)return void(null===(e=Se.current)||void 0===e||e.scrollTo({top:0}));const t=setTimeout((()=>{if(!i)return;const e=i.indexOf(_);Se.current&&-1!==e&&(Se.current.scrollToIndex({index:e}),ce(e))}),0);return()=>clearTimeout(t)}),[ge,i,ce,_]),u.useEffect((()=>{E||qe&&be&&"success"===D&&ye.current&&(ce(-1),ye.current.focus())}),[qe,be,D,ce,E]),u.useEffect((()=>{var e;je(null!==(e=""===pe?i:te?Ne():Ee())&&void 0!==e?e:[])}),[Ne,Ee,i,te,pe]),u.useEffect((()=>{var e,t,r;if(qe)return;if(E||!i)return;const s=i.findIndex((e=>Le(e)));ye.current?(ce(-1),setTimeout((()=>{var e;return null===(e=ye.current)||void 0===e?void 0:e.focus()}),200)):ue>0?(null===(e=Se.current)||void 0===e||e.scrollToIndex({index:ue,align:"center"}),setTimeout((()=>{var e;return null===(e=ge.current[ue])||void 0===e?void 0:e.focus()}),200)):-1!==s?(null===(t=Se.current)||void 0===t||t.scrollToIndex({index:s,align:"center"}),ce(s),setTimeout((()=>{var e;return null===(e=ge.current[s])||void 0===e?void 0:e.focus()}),200)):(null===(r=Se.current)||void 0===r||r.scrollToIndex({index:0}),ce(0),setTimeout((()=>{var e;return null===(e=ge.current[0])||void 0===e?void 0:e.focus()}),200))}),[Le,E,ue,i,qe,ce]);const Me=t=>k?Ce&&!t?e.jsx(s.SquareFillIcon,{"aria-hidden":!0,className:T.default(y.baseCheckboxIndicatorStyle,y.checkboxDisabledIndicator)}):t?e.jsx(n.SquareTickFillIcon,{"aria-hidden":!0,className:T.default(y.baseCheckboxIndicatorStyle,y.checkboxSelectedIndicator)}):e.jsx(r.SquareIcon,{"aria-hidden":!0,className:T.default(y.baseCheckboxIndicatorStyle,y.checkboxUnselectedIndicator)}):t?e.jsx(l.TickIcon,{"aria-hidden":!0,className:T.default(y.baseIndicatorStyle,y.selectedIndicator)}):e.jsx("div",{className:y.baseIndicatorStyle}),Pe=(t,r)=>{const{title:s,secondaryLabel:n}=Te(t);return e.jsx(g.DropdownLabel,{displayType:F,label:s,maxLines:A,selected:r,disabled:!r&&Ce,sublabel:n,truncationType:R,variant:B})},Ve=(t,r)=>{if(!U||"success"===D){const s=Le(t),n=r===ue,l=!s&&Ce;return e.jsx("li",{"aria-selected":s,"aria-multiselectable":k,"aria-disabled":l,"aria-posinset":r+1,"aria-setsize":null==xe?void 0:xe.length,"data-testid":"list-item",onClick:()=>Re(t,r),onMouseEnter:()=>(e=>ce(e))(r),ref:e=>{ge.current[r]=e},role:"option",tabIndex:n?0:-1,className:T.default(y.listItem,l&&y.listItemDisabled||n&&s&&y.listItemActiveSelected||n&&y.listItemActive),children:J?J(t,{selected:s}):e.jsxs(e.Fragment,{children:[Me(s),Pe(t,s)]})},((e,t)=>`item_${t}__${z?z(e):e}`)(t,r))}},Oe=()=>{if((Q||te)&&"success"===D)return e.jsx(C.DropdownSearch,{ref:ye,onChange:Ae,value:pe,placeholder:ae,"data-testid":"search-input","aria-label":"Enter text to search",onClear:Fe,variant:B})},_e=()=>{if(N&&k&&xe.length>0&&!pe&&"success"===D)return e.jsx("div",{className:y.selectAllContainer,children:e.jsx(I.BasicButton,{onClick:$,type:"button",className:T.default(y.baseButton,y.selectAllButton),children:L||0!==N.length?ie:le})})},We=()=>{if(!X&&(pe||!Q)&&0===xe.length&&"success"===D)return e.jsxs(e.Fragment,{children:[e.jsxs("div",{"data-testid":"list-no-results",className:y.resultStateContainer,children:[e.jsx(t.ExclamationCircleFillIcon,{"data-testid":"no-result-icon",className:y.labelIcon}),ne]}),oe&&e.jsx(d.Markup,{"data-testid":"no-result-desc",className:y.noResultDescContainer,children:oe})]})},$e=()=>{if(U&&"loading"===D)return e.jsxs("div",{"data-testid":"list-loading",className:y.resultStateContainer,children:[e.jsx(b.ComponentLoadingSpinner,{className:y.spinner}),"Loading..."]})},He=()=>{if(U&&"fail"===D)return e.jsxs("div",{"data-testid":"list-fail",className:y.resultStateContainer,children:[e.jsx(t.ExclamationCircleFillIcon,{"data-testid":"load-error-icon",className:y.labelIcon}),"Failed to load. ",e.jsx(I.BasicButton,{onClick:Be,type:"button",className:T.default(y.baseButton,y.tryAgainButton),children:"Try again."})]})},Ue=()=>{var t;const r="test"===process.env.NODE_ENV;return e.jsx(c.Virtuoso,Object.assign({ref:Se,style:{height:"100%"},data:xe,customScrollParent:null!==(t=Ie.current)&&void 0!==t?t:void 0,itemContent:(e,t)=>Ve(t,e),components:{List:w.VirtuosoList,Item:w.VirtuosoItem},context:{listProps:{id:M,role:"listbox","aria-multiselectable":k},listItemProps:{role:"none"}}},r?{initialItemCount:xe.length}:{}),r?xe.length:void 0)};return e.jsxs("div",Object.assign({"data-testid":"dropdown-container",ref:v.mergeRefs(Ie,me)},ve(),{"data-width-type":ke,className:T.default(y.container,"small"===B&&y.containerVariantSmall),style:fe,children:[e.jsx(j.VisuallyHidden,{role:"status",children:P}),e.jsxs("div",{"data-testid":"dropdown-list",role:"group","aria-label":P,className:y.list,children:[Oe(),_e(),We(),$e(),He(),Ue()]}),(()=>{if(K)return e.jsx("div",{"data-testid":"custom-cta",children:K(H,xe)})})()]}))}));exports.DropdownList=L;
|
|
2
2
|
//# sourceMappingURL=dropdown-list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown-list.js","sources":["../../../../src/shared/dropdown-list/dropdown-list.tsx"],"sourcesContent":["import { ExclamationCircleFillIcon } from \"@lifesg/react-icons/exclamation-circle-fill\";\nimport { SquareIcon } from \"@lifesg/react-icons/square\";\nimport { SquareFillIcon } from \"@lifesg/react-icons/square-fill\";\nimport { SquareTickFillIcon } from \"@lifesg/react-icons/square-tick-fill\";\nimport { TickIcon } from \"@lifesg/react-icons/tick\";\nimport clsx from \"clsx\";\nimport find from \"lodash/find\";\nimport isEqual from \"lodash/isEqual\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport type { VirtuosoHandle } from \"react-virtuoso\";\nimport { Virtuoso } from \"react-virtuoso\";\n\nimport { Markup } from \"../../markup\";\nimport { useApplyStyle } from \"../../theme\";\nimport {\n mergeRefs,\n useCompare,\n useEvent,\n useEventListener,\n useIsMounted,\n} from \"../../util\";\nimport { VisuallyHidden } from \"../accessibility\";\nimport { ComponentLoadingSpinner } from \"../component-loading-spinner\";\nimport { useDropdownRender } from \"../dropdown-wrapper\";\nimport { BasicButton } from \"../input-wrapper\";\nimport { DropdownLabel } from \"./dropdown-label\";\nimport type { ContainerWidthType } from \"./dropdown-list.styles\";\nimport * as styles from \"./dropdown-list.styles\";\nimport { DropdownListStateContext } from \"./dropdown-list-state\";\nimport { DropdownSearch } from \"./dropdown-search\";\nimport type {\n DropdownListApi,\n DropdownListProps,\n ListItemDisplayProps,\n} from \"./types\";\nimport { VirtuosoItem, VirtuosoList } from \"./virtuoso-components\";\n\n/**\n * NOTE: This component is not directly exportable but forms part of a component\n */\nconst DropdownListInner = <T, V>(\n {\n listItems,\n multiSelect,\n maxSelectable,\n selectedItems,\n disableItemFocus,\n itemsLoadState = \"success\",\n itemTruncationType = \"end\",\n itemMaxLines = 2,\n labelDisplayType = \"inline\",\n variant = \"default\",\n listboxId,\n ariaLabel,\n matchElementWidth = false,\n width,\n topScrollItem,\n onSelectItem,\n onSelectAll,\n onDismiss,\n onRetry,\n /* DropdownDisplayProps */\n valueExtractor,\n listExtractor,\n renderListItem,\n renderCustomCallToAction,\n /* DropdownSearchProps */\n enableSearch,\n hideNoResultsDisplay,\n noResultsDescription: _noResultsDescription,\n customLabels,\n searchPlaceholder: _searchPlaceholder,\n searchFunction,\n onSearch,\n }: DropdownListProps<T, V>,\n ref: React.ForwardedRef<DropdownListApi>\n): JSX.Element => {\n // =========================================================================\n // CONST, REF, STATE\n // =========================================================================\n const {\n noResultsLabel = \"No results found.\",\n selectAllButtonLabel = \"Select all\",\n clearAllButtonLabel = \"Clear all\",\n } = customLabels || {};\n const searchPlaceholder =\n customLabels?.searchPlaceholder || _searchPlaceholder || \"Search\";\n const noResultsDescription =\n customLabels?.noResultsDescription || _noResultsDescription;\n const { focusedIndex, setFocusedIndex } = useContext(\n DropdownListStateContext\n );\n const {\n elementWidth,\n setFloatingRef,\n getFloatingProps,\n styles: floatingStyles,\n } = useDropdownRender();\n const [searchValue, setSearchValue] = useState<string>(\"\");\n const [displayListItems, setDisplayListItems] = useState(listItems ?? []);\n const itemsLoadStateChanged = useCompare(itemsLoadState);\n const mounted = useIsMounted();\n\n const nodeRef = useRef<HTMLDivElement | null>(null);\n const listItemRefs = useRef<(HTMLElement | null)[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n\n const hasSelectedMax =\n !!maxSelectable &&\n !!selectedItems &&\n selectedItems?.length === maxSelectable;\n\n // =========================================================================\n // APPLY STYLES\n // =========================================================================\n let containerWidthType: ContainerWidthType = \"default\";\n let containerWidth: string | undefined = undefined;\n if (width) {\n containerWidth = width;\n containerWidthType = \"custom\";\n } else if (matchElementWidth && elementWidth) {\n containerWidth = `${elementWidth}px`;\n containerWidthType = \"match\";\n }\n\n useApplyStyle(nodeRef, {\n [styles.tokens.containerWidth]: containerWidth,\n });\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const getValue = (item: T): V => {\n return valueExtractor ? valueExtractor(item) : (item as unknown as V);\n };\n\n const getItemKey = (item: T, index: number) => {\n const formattedValue = valueExtractor ? valueExtractor(item) : item;\n return `item_${index}__${formattedValue}`;\n };\n\n const getOptionLabel = (item: T): ListItemDisplayProps => {\n const value = listExtractor ? listExtractor(item) : item?.toString();\n\n if (typeof value === \"object\") {\n return { title: value.title, secondaryLabel: value.secondaryLabel };\n }\n\n return { title: value ?? \"\" };\n };\n\n const checkListItemSelected = useCallback(\n (item: T): boolean => {\n return !!find(selectedItems, (arrItem) => {\n return isEqual(arrItem, item);\n });\n },\n [selectedItems]\n );\n\n const filterItemsByCustomSearch = useEvent(() => {\n return searchFunction?.(searchValue);\n });\n\n const filterItemsByLabel = useEvent(() => {\n return listItems?.filter((item) => {\n const { title, secondaryLabel } = getOptionLabel(item);\n const updatedSearchValue = searchValue.trim().toLowerCase();\n return (\n title.toLowerCase().includes(updatedSearchValue) ||\n (secondaryLabel &&\n secondaryLabel.toLowerCase().includes(updatedSearchValue))\n );\n });\n });\n\n const refocus = useCallback(\n (opts?: { index?: number; preferSelected?: boolean }) => {\n if (disableItemFocus) return;\n\n if (searchInputRef.current) {\n setFocusedIndex(-1);\n setTimeout(() => searchInputRef.current?.focus(), 0);\n return;\n }\n\n const items = displayListItems ?? [];\n if (items.length === 0) return;\n\n if (opts?.index !== undefined) {\n const forced = Math.max(\n 0,\n Math.min(opts.index, items.length - 1)\n );\n virtuosoRef.current?.scrollToIndex({\n index: forced,\n align: \"center\",\n });\n setFocusedIndex(forced);\n setTimeout(() => listItemRefs.current[forced]?.focus(), 0);\n\n return;\n }\n\n const selectedIndex = opts?.preferSelected\n ? items.findIndex((item) => checkListItemSelected(item))\n : -1;\n\n const nextIndex =\n selectedIndex !== -1\n ? selectedIndex\n : focusedIndex >= 0 && focusedIndex < items.length\n ? focusedIndex\n : 0;\n\n virtuosoRef.current?.scrollToIndex({\n index: nextIndex,\n align: \"center\",\n });\n setFocusedIndex(nextIndex);\n setTimeout(() => listItemRefs.current[nextIndex]?.focus(), 0);\n },\n [\n checkListItemSelected,\n disableItemFocus,\n displayListItems,\n focusedIndex,\n setFocusedIndex,\n ]\n );\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleKeyboardPress = (event: KeyboardEvent) => {\n switch (event.code) {\n case \"ArrowDown\":\n event.preventDefault();\n if (focusedIndex < displayListItems.length - 1) {\n const upcomingIndex = focusedIndex + 1;\n listItemRefs.current[upcomingIndex]?.focus();\n setFocusedIndex(upcomingIndex);\n }\n break;\n case \"ArrowUp\":\n event.preventDefault();\n if (focusedIndex > 0) {\n const upcomingIndex = focusedIndex - 1;\n listItemRefs.current[upcomingIndex]?.focus();\n setFocusedIndex(upcomingIndex);\n } else if (focusedIndex === 0 && searchInputRef.current) {\n searchInputRef.current.focus();\n setFocusedIndex(-1);\n }\n break;\n case \"Space\":\n case \"Enter\":\n if (\n document.activeElement ===\n listItemRefs.current[focusedIndex]\n ) {\n event.preventDefault();\n if (displayListItems[focusedIndex]) {\n handleListItemClick(\n displayListItems[focusedIndex],\n focusedIndex\n );\n }\n }\n break;\n default:\n break;\n }\n };\n\n const handleListItemClick = (item: T, upcomingIndex: number) => {\n if (hasSelectedMax && !checkListItemSelected(item)) return;\n setFocusedIndex(upcomingIndex);\n onSelectItem?.(item, getValue(item));\n };\n\n const handleListItemHover = (index: number) => setFocusedIndex(index);\n\n const handleSearchInputChange = (\n event: React.ChangeEvent<HTMLInputElement>\n ) => {\n const value = event.target.value;\n setSearchValue(value);\n onSearch?.();\n };\n\n const handleOnClear = () => {\n setSearchValue(\"\");\n searchInputRef.current?.focus();\n onSearch?.();\n };\n\n const handleTryAgain = () => onRetry?.();\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEventListener(\"keydown\", handleKeyboardPress);\n useImperativeHandle(ref, () => ({ refocus }), [refocus]);\n\n useEffect(() => {\n if (!topScrollItem) {\n virtuosoRef.current?.scrollTo({ top: 0 });\n return;\n }\n const timer = setTimeout(() => {\n if (!listItems) return;\n\n const index = listItems.indexOf(topScrollItem);\n if (virtuosoRef.current && index !== -1) {\n virtuosoRef.current.scrollToIndex({ index });\n setFocusedIndex(index);\n }\n }, 0);\n\n return () => clearTimeout(timer);\n }, [listItemRefs, listItems, setFocusedIndex, topScrollItem]);\n\n useEffect(() => {\n if (disableItemFocus) return;\n if (!mounted || !itemsLoadStateChanged) return;\n\n if (itemsLoadState === \"success\") {\n if (searchInputRef.current) {\n setFocusedIndex(-1);\n searchInputRef.current.focus();\n }\n }\n }, [\n mounted,\n itemsLoadStateChanged,\n itemsLoadState,\n setFocusedIndex,\n disableItemFocus,\n ]);\n\n useEffect(() => {\n const filterItems = () => {\n if (searchValue === \"\") {\n return listItems;\n } else if (searchFunction) {\n return filterItemsByCustomSearch();\n } else {\n return filterItemsByLabel();\n }\n };\n\n setDisplayListItems(filterItems() ?? []);\n }, [\n filterItemsByCustomSearch,\n filterItemsByLabel,\n listItems,\n searchFunction,\n searchValue,\n ]);\n\n useEffect(() => {\n if (mounted) {\n return;\n }\n\n if (disableItemFocus || !listItems) return;\n\n const index = listItems.findIndex((item) =>\n checkListItemSelected(item)\n );\n\n if (searchInputRef.current) {\n setFocusedIndex(-1);\n setTimeout(() => searchInputRef.current?.focus(), 200);\n } else if (focusedIndex > 0) {\n virtuosoRef.current?.scrollToIndex({\n index: focusedIndex,\n align: \"center\",\n });\n setTimeout(() => listItemRefs.current[focusedIndex]?.focus(), 200);\n } else if (index !== -1) {\n virtuosoRef.current?.scrollToIndex({ index, align: \"center\" });\n setFocusedIndex(index);\n setTimeout(() => listItemRefs.current[index]?.focus(), 200);\n } else {\n virtuosoRef.current?.scrollToIndex({ index: 0 });\n setFocusedIndex(0);\n setTimeout(() => listItemRefs.current[0]?.focus(), 200);\n }\n }, [\n checkListItemSelected,\n disableItemFocus,\n focusedIndex,\n listItems,\n mounted,\n setFocusedIndex,\n ]);\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderListItemIcon = (selected: boolean) => {\n if (multiSelect) {\n if (hasSelectedMax && !selected) {\n return (\n <SquareFillIcon\n aria-hidden\n className={clsx(\n styles.baseCheckboxIndicatorStyle,\n styles.checkboxDisabledIndicator\n )}\n />\n );\n }\n\n return selected ? (\n <SquareTickFillIcon\n aria-hidden\n className={clsx(\n styles.baseCheckboxIndicatorStyle,\n styles.checkboxSelectedIndicator\n )}\n />\n ) : (\n <SquareIcon\n aria-hidden\n className={clsx(\n styles.baseCheckboxIndicatorStyle,\n styles.checkboxUnselectedIndicator\n )}\n />\n );\n }\n\n return selected ? (\n <TickIcon\n aria-hidden\n className={clsx(\n styles.baseIndicatorStyle,\n styles.selectedIndicator\n )}\n />\n ) : (\n <div className={styles.baseIndicatorStyle} />\n );\n };\n\n const renderDropdownLabel = (item: T, selected: boolean) => {\n const { title, secondaryLabel } = getOptionLabel(item);\n\n return (\n <DropdownLabel\n displayType={labelDisplayType}\n label={title}\n maxLines={itemMaxLines}\n selected={selected}\n disabled={!selected && hasSelectedMax}\n sublabel={secondaryLabel}\n truncationType={itemTruncationType}\n variant={variant}\n />\n );\n };\n\n const renderItem = (item: T, index: number) => {\n if (!onRetry || itemsLoadState === \"success\") {\n const selected = checkListItemSelected(item);\n const active = index === focusedIndex;\n const disabled = !selected && hasSelectedMax;\n return (\n <li\n aria-selected={selected}\n aria-multiselectable={multiSelect}\n aria-disabled={disabled}\n aria-posinset={index + 1}\n aria-setsize={displayListItems?.length}\n data-testid=\"list-item\"\n key={getItemKey(item, index)}\n onClick={() => handleListItemClick(item, index)}\n onMouseEnter={() => handleListItemHover(index)}\n ref={(element) => {\n listItemRefs.current[index] = element;\n }}\n role=\"option\"\n tabIndex={active ? 0 : -1}\n className={clsx(\n styles.listItem,\n (disabled && styles.listItemDisabled) ||\n (active &&\n selected &&\n styles.listItemActiveSelected) ||\n (active && styles.listItemActive)\n )}\n >\n {renderListItem ? (\n renderListItem(item, { selected })\n ) : (\n <>\n {renderListItemIcon(selected)}\n {renderDropdownLabel(item, selected)}\n </>\n )}\n </li>\n );\n }\n };\n\n const renderSearchInput = () => {\n if ((enableSearch || searchFunction) && itemsLoadState === \"success\") {\n return (\n <DropdownSearch\n ref={searchInputRef}\n onChange={handleSearchInputChange}\n value={searchValue}\n placeholder={searchPlaceholder}\n data-testid=\"search-input\"\n aria-label=\"Enter text to search\"\n onClear={handleOnClear}\n variant={variant}\n />\n );\n }\n };\n\n const renderSelectAll = () => {\n if (\n selectedItems &&\n multiSelect &&\n displayListItems.length > 0 &&\n !searchValue &&\n itemsLoadState === \"success\"\n ) {\n return (\n <div className={styles.selectAllContainer}>\n <BasicButton\n onClick={onSelectAll}\n type=\"button\"\n className={clsx(\n styles.baseButton,\n styles.selectAllButton\n )}\n >\n {maxSelectable || selectedItems.length !== 0\n ? clearAllButtonLabel\n : selectAllButtonLabel}\n </BasicButton>\n </div>\n );\n }\n };\n\n const renderNoResults = () => {\n if (\n !hideNoResultsDisplay &&\n (searchValue || !enableSearch) &&\n displayListItems.length === 0 &&\n itemsLoadState === \"success\"\n ) {\n return (\n <>\n <div\n data-testid=\"list-no-results\"\n className={styles.resultStateContainer}\n >\n <ExclamationCircleFillIcon\n data-testid=\"no-result-icon\"\n className={styles.labelIcon}\n />\n {noResultsLabel}\n </div>\n {noResultsDescription && (\n <Markup\n data-testid=\"no-result-desc\"\n className={styles.noResultDescContainer}\n >\n {noResultsDescription}\n </Markup>\n )}\n </>\n );\n }\n };\n\n const renderLoading = () => {\n if (onRetry && itemsLoadState === \"loading\") {\n return (\n <div\n data-testid=\"list-loading\"\n className={styles.resultStateContainer}\n >\n <ComponentLoadingSpinner className={styles.spinner} />\n Loading...\n </div>\n );\n }\n };\n\n const renderTryAgain = () => {\n if (onRetry && itemsLoadState === \"fail\") {\n return (\n <div\n data-testid=\"list-fail\"\n className={styles.resultStateContainer}\n >\n <ExclamationCircleFillIcon\n data-testid=\"load-error-icon\"\n className={styles.labelIcon}\n />\n Failed to load. \n <BasicButton\n onClick={handleTryAgain}\n type=\"button\"\n className={clsx(\n styles.baseButton,\n styles.tryAgainButton\n )}\n >\n Try again.\n </BasicButton>\n </div>\n );\n }\n };\n\n const renderVirtualisedList = () => {\n const isTestEnv = process.env.NODE_ENV === \"test\";\n\n return (\n <Virtuoso\n ref={virtuosoRef}\n style={{ height: \"100%\" }}\n data={displayListItems}\n customScrollParent={nodeRef.current ?? undefined}\n itemContent={(index, item) => renderItem(item, index)}\n components={{\n List: VirtuosoList,\n Item: VirtuosoItem,\n }}\n context={{\n listProps: {\n id: listboxId,\n role: \"listbox\",\n \"aria-multiselectable\": multiSelect,\n },\n listItemProps: {\n role: \"none\",\n },\n }}\n // disable virtualisation in tests\n // https://github.com/petyosi/react-virtuoso/issues/26#issuecomment-1040316576\n // explicitly set the `key` prop to avoid React warning\n key={isTestEnv ? displayListItems.length : undefined}\n // omit the `initialItemCount` prop to resolve NaN error\n {...(isTestEnv\n ? {\n initialItemCount: displayListItems.length,\n }\n : {})}\n />\n );\n };\n\n const renderList = () => {\n return (\n <div\n data-testid=\"dropdown-list\"\n role=\"group\"\n aria-label={ariaLabel}\n className={styles.list}\n >\n {renderSearchInput()}\n {renderSelectAll()}\n {renderNoResults()}\n {renderLoading()}\n {renderTryAgain()}\n {renderVirtualisedList()}\n </div>\n );\n };\n\n const renderBottomCta = () => {\n if (!renderCustomCallToAction) {\n return;\n }\n\n return (\n <div data-testid=\"custom-cta\">\n {renderCustomCallToAction(onDismiss as any, displayListItems)}\n </div>\n );\n };\n\n return (\n <div\n data-testid=\"dropdown-container\"\n ref={mergeRefs(nodeRef, setFloatingRef)}\n {...getFloatingProps()}\n data-width-type={containerWidthType}\n className={clsx(\n styles.container,\n variant === \"small\" && styles.containerVariantSmall\n )}\n style={floatingStyles}\n >\n <VisuallyHidden role=\"status\">{ariaLabel}</VisuallyHidden>\n {renderList()}\n {renderBottomCta()}\n </div>\n );\n};\n\nexport const DropdownList = forwardRef(DropdownListInner);\n"],"names":["DropdownList","forwardRef","listItems","multiSelect","maxSelectable","selectedItems","disableItemFocus","itemsLoadState","itemTruncationType","itemMaxLines","labelDisplayType","variant","listboxId","ariaLabel","matchElementWidth","width","topScrollItem","onSelectItem","onSelectAll","onDismiss","onRetry","valueExtractor","listExtractor","renderListItem","renderCustomCallToAction","enableSearch","hideNoResultsDisplay","noResultsDescription","_noResultsDescription","customLabels","searchPlaceholder","_searchPlaceholder","searchFunction","onSearch","ref","noResultsLabel","selectAllButtonLabel","clearAllButtonLabel","focusedIndex","setFocusedIndex","useContext","DropdownListStateContext","elementWidth","setFloatingRef","getFloatingProps","styles","floatingStyles","useDropdownRender","searchValue","setSearchValue","useState","displayListItems","setDisplayListItems","itemsLoadStateChanged","useCompare","mounted","useIsMounted","nodeRef","useRef","listItemRefs","searchInputRef","virtuosoRef","hasSelectedMax","length","containerWidth","containerWidthType","useApplyStyle","styles.tokens","getOptionLabel","item","value","toString","title","secondaryLabel","checkListItemSelected","useCallback","find","arrItem","isEqual","filterItemsByCustomSearch","useEvent","filterItemsByLabel","filter","updatedSearchValue","trim","toLowerCase","includes","refocus","opts","current","setTimeout","_a","focus","items","undefined","index","forced","Math","max","min","scrollToIndex","align","selectedIndex","preferSelected","findIndex","nextIndex","_b","handleListItemClick","upcomingIndex","getValue","handleSearchInputChange","event","target","handleOnClear","handleTryAgain","useEventListener","code","preventDefault","document","activeElement","useImperativeHandle","useEffect","scrollTo","top","timer","indexOf","clearTimeout","_c","renderListItemIcon","selected","_jsx","SquareFillIcon","className","clsx","styles.baseCheckboxIndicatorStyle","styles.checkboxDisabledIndicator","SquareTickFillIcon","styles.checkboxSelectedIndicator","SquareIcon","styles.checkboxUnselectedIndicator","TickIcon","styles.baseIndicatorStyle","styles.selectedIndicator","renderDropdownLabel","DropdownLabel","displayType","label","maxLines","disabled","sublabel","truncationType","renderItem","active","onClick","onMouseEnter","handleListItemHover","element","role","tabIndex","styles.listItem","styles.listItemDisabled","styles.listItemActiveSelected","styles.listItemActive","children","_jsxs","_Fragment","getItemKey","renderSearchInput","DropdownSearch","onChange","placeholder","onClear","renderSelectAll","styles.selectAllContainer","BasicButton","type","styles.baseButton","styles.selectAllButton","renderNoResults","styles.resultStateContainer","ExclamationCircleFillIcon","styles.labelIcon","Markup","styles.noResultDescContainer","renderLoading","ComponentLoadingSpinner","styles.spinner","renderTryAgain","styles.tryAgainButton","renderVirtualisedList","isTestEnv","process","env","NODE_ENV","Virtuoso","Object","assign","style","height","data","customScrollParent","itemContent","components","List","VirtuosoList","Item","VirtuosoItem","context","listProps","id","listItemProps","initialItemCount","mergeRefs","styles.container","styles.containerVariantSmall","VisuallyHidden","styles.list","renderBottomCta"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dropdown-list.js","sources":["../../../../src/shared/dropdown-list/dropdown-list.tsx"],"sourcesContent":["import { ExclamationCircleFillIcon } from \"@lifesg/react-icons/exclamation-circle-fill\";\nimport { SquareIcon } from \"@lifesg/react-icons/square\";\nimport { SquareFillIcon } from \"@lifesg/react-icons/square-fill\";\nimport { SquareTickFillIcon } from \"@lifesg/react-icons/square-tick-fill\";\nimport { TickIcon } from \"@lifesg/react-icons/tick\";\nimport clsx from \"clsx\";\nimport find from \"lodash/find\";\nimport isEqual from \"lodash/isEqual\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport type { VirtuosoHandle } from \"react-virtuoso\";\nimport { Virtuoso } from \"react-virtuoso\";\n\nimport { Markup } from \"../../markup\";\nimport { useApplyStyle } from \"../../theme\";\nimport {\n mergeRefs,\n useCompare,\n useEvent,\n useEventListener,\n useIsMounted,\n} from \"../../util\";\nimport { VisuallyHidden } from \"../accessibility\";\nimport { ComponentLoadingSpinner } from \"../component-loading-spinner\";\nimport { useDropdownRender } from \"../dropdown-wrapper\";\nimport { BasicButton } from \"../input-wrapper\";\nimport { DropdownLabel } from \"./dropdown-label\";\nimport type { ContainerWidthType } from \"./dropdown-list.styles\";\nimport * as styles from \"./dropdown-list.styles\";\nimport { DropdownListStateContext } from \"./dropdown-list-state\";\nimport { DropdownSearch } from \"./dropdown-search\";\nimport type {\n DropdownListApi,\n DropdownListProps,\n ListItemDisplayProps,\n} from \"./types\";\nimport { VirtuosoItem, VirtuosoList } from \"./virtuoso-components\";\n\n/**\n * NOTE: This component is not directly exportable but forms part of a component\n */\nconst DropdownListInner = <T, V>(\n {\n listItems,\n multiSelect,\n maxSelectable,\n selectedItems,\n disableItemFocus,\n itemsLoadState = \"success\",\n itemTruncationType = \"end\",\n itemMaxLines = 2,\n labelDisplayType = \"inline\",\n variant = \"default\",\n listboxId,\n ariaLabel,\n matchElementWidth = false,\n width,\n topScrollItem,\n onSelectItem,\n onSelectAll,\n onDismiss,\n onRetry,\n /* DropdownDisplayProps */\n valueExtractor,\n listExtractor,\n renderListItem,\n renderCustomCallToAction,\n /* DropdownSearchProps */\n enableSearch,\n hideNoResultsDisplay,\n noResultsDescription: _noResultsDescription,\n customLabels,\n searchPlaceholder: _searchPlaceholder,\n searchFunction,\n onSearch,\n }: DropdownListProps<T, V>,\n ref: React.ForwardedRef<DropdownListApi>\n): JSX.Element => {\n // =========================================================================\n // CONST, REF, STATE\n // =========================================================================\n const {\n noResultsLabel = \"No results found.\",\n selectAllButtonLabel = \"Select all\",\n clearAllButtonLabel = \"Clear all\",\n } = customLabels || {};\n const searchPlaceholder =\n customLabels?.searchPlaceholder || _searchPlaceholder || \"Search\";\n const noResultsDescription =\n customLabels?.noResultsDescription || _noResultsDescription;\n const { focusedIndex, setFocusedIndex } = useContext(\n DropdownListStateContext\n );\n const {\n elementWidth,\n setFloatingRef,\n getFloatingProps,\n styles: floatingStyles,\n } = useDropdownRender();\n const [searchValue, setSearchValue] = useState<string>(\"\");\n const [displayListItems, setDisplayListItems] = useState(listItems ?? []);\n const itemsLoadStateChanged = useCompare(itemsLoadState);\n const mounted = useIsMounted();\n\n const nodeRef = useRef<HTMLDivElement | null>(null);\n const listItemRefs = useRef<(HTMLElement | null)[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n\n const hasSelectedMax =\n !!maxSelectable &&\n !!selectedItems &&\n selectedItems?.length === maxSelectable;\n\n // =========================================================================\n // APPLY STYLES\n // =========================================================================\n let containerWidthType: ContainerWidthType = \"default\";\n let containerWidth: string | undefined = undefined;\n if (width) {\n containerWidth = width;\n containerWidthType = \"custom\";\n } else if (matchElementWidth && elementWidth) {\n containerWidth = `${elementWidth}px`;\n containerWidthType = \"match\";\n }\n\n useApplyStyle(nodeRef, {\n [styles.tokens.containerWidth]: containerWidth,\n });\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const getValue = (item: T): V => {\n return valueExtractor ? valueExtractor(item) : (item as unknown as V);\n };\n\n const getItemKey = (item: T, index: number) => {\n const formattedValue = valueExtractor ? valueExtractor(item) : item;\n return `item_${index}__${formattedValue}`;\n };\n\n const getOptionLabel = (item: T): ListItemDisplayProps => {\n const value = listExtractor ? listExtractor(item) : item?.toString();\n\n if (typeof value === \"object\") {\n return { title: value.title, secondaryLabel: value.secondaryLabel };\n }\n\n return { title: value ?? \"\" };\n };\n\n const checkListItemSelected = useCallback(\n (item: T): boolean => {\n return !!find(selectedItems, (arrItem) => {\n return isEqual(arrItem, item);\n });\n },\n [selectedItems]\n );\n\n const filterItemsByCustomSearch = useEvent(() => {\n return searchFunction?.(searchValue);\n });\n\n const filterItemsByLabel = useEvent(() => {\n return listItems?.filter((item) => {\n const { title, secondaryLabel } = getOptionLabel(item);\n const updatedSearchValue = searchValue.trim().toLowerCase();\n return (\n title.toLowerCase().includes(updatedSearchValue) ||\n (secondaryLabel &&\n secondaryLabel.toLowerCase().includes(updatedSearchValue))\n );\n });\n });\n\n const refocus = useCallback(\n (opts?: { index?: number; preferSelected?: boolean }) => {\n if (disableItemFocus) return;\n\n if (searchInputRef.current) {\n setFocusedIndex(-1);\n setTimeout(() => searchInputRef.current?.focus(), 0);\n return;\n }\n\n const items = displayListItems ?? [];\n if (items.length === 0) return;\n\n if (opts?.index !== undefined) {\n const forced = Math.max(\n 0,\n Math.min(opts.index, items.length - 1)\n );\n virtuosoRef.current?.scrollToIndex({\n index: forced,\n align: \"center\",\n });\n setFocusedIndex(forced);\n setTimeout(() => listItemRefs.current[forced]?.focus(), 0);\n\n return;\n }\n\n const selectedIndex = opts?.preferSelected\n ? items.findIndex((item) => checkListItemSelected(item))\n : -1;\n\n const nextIndex =\n selectedIndex !== -1\n ? selectedIndex\n : focusedIndex >= 0 && focusedIndex < items.length\n ? focusedIndex\n : 0;\n\n virtuosoRef.current?.scrollToIndex({\n index: nextIndex,\n align: \"center\",\n });\n setFocusedIndex(nextIndex);\n setTimeout(() => listItemRefs.current[nextIndex]?.focus(), 0);\n },\n [\n checkListItemSelected,\n disableItemFocus,\n displayListItems,\n focusedIndex,\n setFocusedIndex,\n ]\n );\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleKeyboardPress = (event: KeyboardEvent) => {\n switch (event.code) {\n case \"ArrowDown\":\n event.preventDefault();\n if (focusedIndex < displayListItems.length - 1) {\n const upcomingIndex = focusedIndex + 1;\n listItemRefs.current[upcomingIndex]?.focus();\n setFocusedIndex(upcomingIndex);\n }\n break;\n case \"ArrowUp\":\n event.preventDefault();\n if (focusedIndex > 0) {\n const upcomingIndex = focusedIndex - 1;\n listItemRefs.current[upcomingIndex]?.focus();\n setFocusedIndex(upcomingIndex);\n } else if (focusedIndex === 0 && searchInputRef.current) {\n searchInputRef.current.focus();\n setFocusedIndex(-1);\n }\n break;\n case \"Space\":\n case \"Enter\":\n if (\n focusedIndex >= 0 &&\n (document.activeElement ===\n listItemRefs.current[focusedIndex] ||\n document.activeElement === searchInputRef.current)\n ) {\n event.preventDefault();\n if (displayListItems[focusedIndex]) {\n handleListItemClick(\n displayListItems[focusedIndex],\n focusedIndex\n );\n }\n }\n break;\n default:\n break;\n }\n };\n\n const handleListItemClick = (item: T, upcomingIndex: number) => {\n if (hasSelectedMax && !checkListItemSelected(item)) return;\n setFocusedIndex(upcomingIndex);\n onSelectItem?.(item, getValue(item));\n };\n\n const handleListItemHover = (index: number) => setFocusedIndex(index);\n\n const handleSearchInputChange = (\n event: React.ChangeEvent<HTMLInputElement>\n ) => {\n const value = event.target.value;\n setSearchValue(value);\n onSearch?.();\n };\n\n const handleOnClear = () => {\n setSearchValue(\"\");\n searchInputRef.current?.focus();\n onSearch?.();\n };\n\n const handleTryAgain = () => onRetry?.();\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEventListener(\"keydown\", handleKeyboardPress);\n useImperativeHandle(ref, () => ({ refocus }), [refocus]);\n\n useEffect(() => {\n if (!topScrollItem) {\n virtuosoRef.current?.scrollTo({ top: 0 });\n return;\n }\n const timer = setTimeout(() => {\n if (!listItems) return;\n\n const index = listItems.indexOf(topScrollItem);\n if (virtuosoRef.current && index !== -1) {\n virtuosoRef.current.scrollToIndex({ index });\n setFocusedIndex(index);\n }\n }, 0);\n\n return () => clearTimeout(timer);\n }, [listItemRefs, listItems, setFocusedIndex, topScrollItem]);\n\n useEffect(() => {\n if (disableItemFocus) return;\n if (!mounted || !itemsLoadStateChanged) return;\n\n if (itemsLoadState === \"success\") {\n if (searchInputRef.current) {\n setFocusedIndex(-1);\n searchInputRef.current.focus();\n }\n }\n }, [\n mounted,\n itemsLoadStateChanged,\n itemsLoadState,\n setFocusedIndex,\n disableItemFocus,\n ]);\n\n useEffect(() => {\n const filterItems = () => {\n if (searchValue === \"\") {\n return listItems;\n } else if (searchFunction) {\n return filterItemsByCustomSearch();\n } else {\n return filterItemsByLabel();\n }\n };\n\n setDisplayListItems(filterItems() ?? []);\n }, [\n filterItemsByCustomSearch,\n filterItemsByLabel,\n listItems,\n searchFunction,\n searchValue,\n ]);\n\n useEffect(() => {\n if (mounted) {\n return;\n }\n\n if (disableItemFocus || !listItems) return;\n\n const index = listItems.findIndex((item) =>\n checkListItemSelected(item)\n );\n\n if (searchInputRef.current) {\n setFocusedIndex(-1);\n setTimeout(() => searchInputRef.current?.focus(), 200);\n } else if (focusedIndex > 0) {\n virtuosoRef.current?.scrollToIndex({\n index: focusedIndex,\n align: \"center\",\n });\n setTimeout(() => listItemRefs.current[focusedIndex]?.focus(), 200);\n } else if (index !== -1) {\n virtuosoRef.current?.scrollToIndex({ index, align: \"center\" });\n setFocusedIndex(index);\n setTimeout(() => listItemRefs.current[index]?.focus(), 200);\n } else {\n virtuosoRef.current?.scrollToIndex({ index: 0 });\n setFocusedIndex(0);\n setTimeout(() => listItemRefs.current[0]?.focus(), 200);\n }\n }, [\n checkListItemSelected,\n disableItemFocus,\n focusedIndex,\n listItems,\n mounted,\n setFocusedIndex,\n ]);\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderListItemIcon = (selected: boolean) => {\n if (multiSelect) {\n if (hasSelectedMax && !selected) {\n return (\n <SquareFillIcon\n aria-hidden\n className={clsx(\n styles.baseCheckboxIndicatorStyle,\n styles.checkboxDisabledIndicator\n )}\n />\n );\n }\n\n return selected ? (\n <SquareTickFillIcon\n aria-hidden\n className={clsx(\n styles.baseCheckboxIndicatorStyle,\n styles.checkboxSelectedIndicator\n )}\n />\n ) : (\n <SquareIcon\n aria-hidden\n className={clsx(\n styles.baseCheckboxIndicatorStyle,\n styles.checkboxUnselectedIndicator\n )}\n />\n );\n }\n\n return selected ? (\n <TickIcon\n aria-hidden\n className={clsx(\n styles.baseIndicatorStyle,\n styles.selectedIndicator\n )}\n />\n ) : (\n <div className={styles.baseIndicatorStyle} />\n );\n };\n\n const renderDropdownLabel = (item: T, selected: boolean) => {\n const { title, secondaryLabel } = getOptionLabel(item);\n\n return (\n <DropdownLabel\n displayType={labelDisplayType}\n label={title}\n maxLines={itemMaxLines}\n selected={selected}\n disabled={!selected && hasSelectedMax}\n sublabel={secondaryLabel}\n truncationType={itemTruncationType}\n variant={variant}\n />\n );\n };\n\n const renderItem = (item: T, index: number) => {\n if (!onRetry || itemsLoadState === \"success\") {\n const selected = checkListItemSelected(item);\n const active = index === focusedIndex;\n const disabled = !selected && hasSelectedMax;\n return (\n <li\n aria-selected={selected}\n aria-multiselectable={multiSelect}\n aria-disabled={disabled}\n aria-posinset={index + 1}\n aria-setsize={displayListItems?.length}\n data-testid=\"list-item\"\n key={getItemKey(item, index)}\n onClick={() => handleListItemClick(item, index)}\n onMouseEnter={() => handleListItemHover(index)}\n ref={(element) => {\n listItemRefs.current[index] = element;\n }}\n role=\"option\"\n tabIndex={active ? 0 : -1}\n className={clsx(\n styles.listItem,\n (disabled && styles.listItemDisabled) ||\n (active &&\n selected &&\n styles.listItemActiveSelected) ||\n (active && styles.listItemActive)\n )}\n >\n {renderListItem ? (\n renderListItem(item, { selected })\n ) : (\n <>\n {renderListItemIcon(selected)}\n {renderDropdownLabel(item, selected)}\n </>\n )}\n </li>\n );\n }\n };\n\n const renderSearchInput = () => {\n if ((enableSearch || searchFunction) && itemsLoadState === \"success\") {\n return (\n <DropdownSearch\n ref={searchInputRef}\n onChange={handleSearchInputChange}\n value={searchValue}\n placeholder={searchPlaceholder}\n data-testid=\"search-input\"\n aria-label=\"Enter text to search\"\n onClear={handleOnClear}\n variant={variant}\n />\n );\n }\n };\n\n const renderSelectAll = () => {\n if (\n selectedItems &&\n multiSelect &&\n displayListItems.length > 0 &&\n !searchValue &&\n itemsLoadState === \"success\"\n ) {\n return (\n <div className={styles.selectAllContainer}>\n <BasicButton\n onClick={onSelectAll}\n type=\"button\"\n className={clsx(\n styles.baseButton,\n styles.selectAllButton\n )}\n >\n {maxSelectable || selectedItems.length !== 0\n ? clearAllButtonLabel\n : selectAllButtonLabel}\n </BasicButton>\n </div>\n );\n }\n };\n\n const renderNoResults = () => {\n if (\n !hideNoResultsDisplay &&\n (searchValue || !enableSearch) &&\n displayListItems.length === 0 &&\n itemsLoadState === \"success\"\n ) {\n return (\n <>\n <div\n data-testid=\"list-no-results\"\n className={styles.resultStateContainer}\n >\n <ExclamationCircleFillIcon\n data-testid=\"no-result-icon\"\n className={styles.labelIcon}\n />\n {noResultsLabel}\n </div>\n {noResultsDescription && (\n <Markup\n data-testid=\"no-result-desc\"\n className={styles.noResultDescContainer}\n >\n {noResultsDescription}\n </Markup>\n )}\n </>\n );\n }\n };\n\n const renderLoading = () => {\n if (onRetry && itemsLoadState === \"loading\") {\n return (\n <div\n data-testid=\"list-loading\"\n className={styles.resultStateContainer}\n >\n <ComponentLoadingSpinner className={styles.spinner} />\n Loading...\n </div>\n );\n }\n };\n\n const renderTryAgain = () => {\n if (onRetry && itemsLoadState === \"fail\") {\n return (\n <div\n data-testid=\"list-fail\"\n className={styles.resultStateContainer}\n >\n <ExclamationCircleFillIcon\n data-testid=\"load-error-icon\"\n className={styles.labelIcon}\n />\n Failed to load. \n <BasicButton\n onClick={handleTryAgain}\n type=\"button\"\n className={clsx(\n styles.baseButton,\n styles.tryAgainButton\n )}\n >\n Try again.\n </BasicButton>\n </div>\n );\n }\n };\n\n const renderVirtualisedList = () => {\n const isTestEnv = process.env.NODE_ENV === \"test\";\n\n return (\n <Virtuoso\n ref={virtuosoRef}\n style={{ height: \"100%\" }}\n data={displayListItems}\n customScrollParent={nodeRef.current ?? undefined}\n itemContent={(index, item) => renderItem(item, index)}\n components={{\n List: VirtuosoList,\n Item: VirtuosoItem,\n }}\n context={{\n listProps: {\n id: listboxId,\n role: \"listbox\",\n \"aria-multiselectable\": multiSelect,\n },\n listItemProps: {\n role: \"none\",\n },\n }}\n // disable virtualisation in tests\n // https://github.com/petyosi/react-virtuoso/issues/26#issuecomment-1040316576\n // explicitly set the `key` prop to avoid React warning\n key={isTestEnv ? displayListItems.length : undefined}\n // omit the `initialItemCount` prop to resolve NaN error\n {...(isTestEnv\n ? {\n initialItemCount: displayListItems.length,\n }\n : {})}\n />\n );\n };\n\n const renderList = () => {\n return (\n <div\n data-testid=\"dropdown-list\"\n role=\"group\"\n aria-label={ariaLabel}\n className={styles.list}\n >\n {renderSearchInput()}\n {renderSelectAll()}\n {renderNoResults()}\n {renderLoading()}\n {renderTryAgain()}\n {renderVirtualisedList()}\n </div>\n );\n };\n\n const renderBottomCta = () => {\n if (!renderCustomCallToAction) {\n return;\n }\n\n return (\n <div data-testid=\"custom-cta\">\n {renderCustomCallToAction(onDismiss as any, displayListItems)}\n </div>\n );\n };\n\n return (\n <div\n data-testid=\"dropdown-container\"\n ref={mergeRefs(nodeRef, setFloatingRef)}\n {...getFloatingProps()}\n data-width-type={containerWidthType}\n className={clsx(\n styles.container,\n variant === \"small\" && styles.containerVariantSmall\n )}\n style={floatingStyles}\n >\n <VisuallyHidden role=\"status\">{ariaLabel}</VisuallyHidden>\n {renderList()}\n {renderBottomCta()}\n </div>\n );\n};\n\nexport const DropdownList = forwardRef(DropdownListInner);\n"],"names":["DropdownList","forwardRef","listItems","multiSelect","maxSelectable","selectedItems","disableItemFocus","itemsLoadState","itemTruncationType","itemMaxLines","labelDisplayType","variant","listboxId","ariaLabel","matchElementWidth","width","topScrollItem","onSelectItem","onSelectAll","onDismiss","onRetry","valueExtractor","listExtractor","renderListItem","renderCustomCallToAction","enableSearch","hideNoResultsDisplay","noResultsDescription","_noResultsDescription","customLabels","searchPlaceholder","_searchPlaceholder","searchFunction","onSearch","ref","noResultsLabel","selectAllButtonLabel","clearAllButtonLabel","focusedIndex","setFocusedIndex","useContext","DropdownListStateContext","elementWidth","setFloatingRef","getFloatingProps","styles","floatingStyles","useDropdownRender","searchValue","setSearchValue","useState","displayListItems","setDisplayListItems","itemsLoadStateChanged","useCompare","mounted","useIsMounted","nodeRef","useRef","listItemRefs","searchInputRef","virtuosoRef","hasSelectedMax","length","containerWidth","containerWidthType","useApplyStyle","styles.tokens","getOptionLabel","item","value","toString","title","secondaryLabel","checkListItemSelected","useCallback","find","arrItem","isEqual","filterItemsByCustomSearch","useEvent","filterItemsByLabel","filter","updatedSearchValue","trim","toLowerCase","includes","refocus","opts","current","setTimeout","_a","focus","items","undefined","index","forced","Math","max","min","scrollToIndex","align","selectedIndex","preferSelected","findIndex","nextIndex","_b","handleListItemClick","upcomingIndex","getValue","handleSearchInputChange","event","target","handleOnClear","handleTryAgain","useEventListener","code","preventDefault","document","activeElement","useImperativeHandle","useEffect","scrollTo","top","timer","indexOf","clearTimeout","_c","renderListItemIcon","selected","_jsx","SquareFillIcon","className","clsx","styles.baseCheckboxIndicatorStyle","styles.checkboxDisabledIndicator","SquareTickFillIcon","styles.checkboxSelectedIndicator","SquareIcon","styles.checkboxUnselectedIndicator","TickIcon","styles.baseIndicatorStyle","styles.selectedIndicator","renderDropdownLabel","DropdownLabel","displayType","label","maxLines","disabled","sublabel","truncationType","renderItem","active","onClick","onMouseEnter","handleListItemHover","element","role","tabIndex","styles.listItem","styles.listItemDisabled","styles.listItemActiveSelected","styles.listItemActive","children","_jsxs","_Fragment","getItemKey","renderSearchInput","DropdownSearch","onChange","placeholder","onClear","renderSelectAll","styles.selectAllContainer","BasicButton","type","styles.baseButton","styles.selectAllButton","renderNoResults","styles.resultStateContainer","ExclamationCircleFillIcon","styles.labelIcon","Markup","styles.noResultDescContainer","renderLoading","ComponentLoadingSpinner","styles.spinner","renderTryAgain","styles.tryAgainButton","renderVirtualisedList","isTestEnv","process","env","NODE_ENV","Virtuoso","Object","assign","style","height","data","customScrollParent","itemContent","components","List","VirtuosoList","Item","VirtuosoItem","context","listProps","id","listItemProps","initialItemCount","mergeRefs","styles.container","styles.containerVariantSmall","VisuallyHidden","styles.list","renderBottomCta"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("react/jsx-runtime"),t=require("@floating-ui/react"),i=require("react"),r=require("../../external/react-resize-detector/build/index.esm.js"),n=require("../../overlay/use-floating-context.js");require("../../theme/theme-provider/index.js");var s=require("../../theme/theme-provider/hooks.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"),require("../../util/simple-id-generator.js"),require("../../util/string-helper.js"),require("@react-aria/live-announcer");var o=require("../../theme/utils/use-media-query.js"),
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("@floating-ui/react"),i=require("react"),r=require("../../external/react-resize-detector/build/index.esm.js"),n=require("../../overlay/use-floating-context.js");require("../../theme/theme-provider/index.js");var s=require("../../theme/theme-provider/hooks.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"),require("../../util/simple-id-generator.js"),require("../../util/string-helper.js"),require("@react-aria/live-announcer");var o=require("../../util/use-event.js"),l=require("../../util/use-previous.js"),a=require("../../theme/utils/use-media-query.js"),u=require("./element-with-dropdown.styles.js");const d=e=>"right"===e?"bottom-end":"bottom-start",c=i.createContext({elementWidth:0,styles:{},setFloatingRef:()=>{},getFloatingProps:()=>({})});exports.DropdownRenderContext=c,exports.ElementWithDropdown=({enabled:h,isOpen:g,onOpen:m,onClose:p,onDismiss:f,onHide:j,renderElement:x,renderDropdown:y,customZIndex:q,clickToToggle:v=!1,offset:b=0,alignment:w="left",fitAvailableHeight:F,rootNode:k,positionRef:P})=>{var R;const H=a.useMaxWidthMediaQuery("sm"),O=i.useRef(null),{width:C=0}=r.useResizeDetector({targetRef:null!=P?P:O,handleHeight:!1}),D={name:"center",fn:({x:e,rects:t})=>({x:(0===e||e+t.floating.width===window.innerWidth)&&H?(window.innerWidth-t.floating.width)/2:e})},{refs:M,floatingStyles:W,context:E}=t.useFloating({open:g,onOpenChange:(e,t,i)=>{"escape-key"===i?null==f||f():e&&!g?null==m||m():!e&&g&&(null==p||p(i))},whileElementsMounted:t.autoUpdate,placement:d(w),middleware:[t.offset(b),t.flip(),t.shift({limiter:t.limitShift()}),t.size({apply({availableHeight:e,elements:t}){!F||e>=t.floating.scrollHeight?t.floating.style.setProperty(u.tokens.availableHeight,""):t.floating.style.setProperty(u.tokens.availableHeight,`${Math.max(0,e)}px`)}}),D]}),S=n.useFloatingChild(),{isMounted:z,styles:I}=t.useTransitionStyles(E,{initial:{opacity:0},open:{opacity:1},duration:300}),{themeProps:T,themeStyle:A}=s.useInheritedThemeScope(z),N=t.useClick(E,{enabled:h,toggle:v,keyboardHandlers:v}),Q=t.useDismiss(E,{enabled:h}),{getReferenceProps:U,getFloatingProps:Z}=t.useInteractions([N,Q]),$=l.usePrevious(z),B=o.useEvent((()=>null==j?void 0:j()));i.useEffect((()=>{$&&!z&&B()}),[$,z,B]);const G={elementWidth:C,styles:Object.assign(Object.assign(Object.assign({},I),W),{zIndex:null!==(R=null!=q?q:S)&&void 0!==R?R:50}),setFloatingRef:M.setFloating,getFloatingProps:Z};return e.jsxs(e.Fragment,{children:[e.jsx("div",Object.assign({ref:e=>{O.current=e,M.setReference(e)}},U(),{children:x()})),z&&e.jsx(t.FloatingPortal,{root:k,children:e.jsx(t.FloatingFocusManager,{context:E,modal:!1,initialFocus:-1,returnFocus:!1,children:e.jsx(c.Provider,{value:G,children:e.jsx("div",Object.assign({},T,{style:A,children:y(G)}))})})})]})},exports.useDropdownRender=()=>i.useContext(c);
|
|
2
2
|
//# sourceMappingURL=element-with-dropdown.js.map
|