@lifesg/react-design-system 4.0.0-alpha.6 → 4.0.0-alpha.7
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.map +1 -1
- 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.map +1 -1
- 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.map +1 -1
- 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.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/cjs/file-upload/file-list-item/{file-list-item.styles_o8000f.css → 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/filter-item.js +1 -1
- package/cjs/filter/filter-item.js.map +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/smart-app-banner/smart-app-banner.js.map +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/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.js.map +1 -1
- 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.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/file-upload/file-list-item/{file-list-item.styles_o8000f.css → 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/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.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/smart-app-banner/smart-app-banner.js.map +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/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/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 +43 -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 +102 -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/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,2 +1,2 @@
|
|
|
1
|
-
import"./file-list-item.
|
|
1
|
+
import"./file-list-item.styles_kgtfke.css";const i="i18pxk0j",e="dqb8x5u",l="bddx9rr",o="c1dhzflv",t="nk38w4a",f="elwke9e",d="f14h64yt",k="f1wv8fjl",s="divlkvo",v="i1jm950n",p="i1vgco4e",m="eap0p9n",r="d1gk2zsk",a="m1wh4bod",c="a3rvfgv",g="i5ozu70",n="ilou5qo";export{c as actionContainer,l as box,o as contentSection,s as descriptionFileSizeText,r as desktopErrorMessage,e as dragHandleIcon,m as errorIcon,f as extendedNameSection,d as fileSizeSection,k as fileSizeText,n as iconButton,g as inlineActionContainer,i as item,v as itemDescriptionLabel,p as itemDescriptionText,a as mobileErrorMessage,t as nameSection};
|
|
2
2
|
//# sourceMappingURL=file-list-item.styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-list-item.styles.js","sources":["../../../src/file-upload/file-list-item/file-list-item.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport {\n Border,\n Colour,\n Font,\n MediaQuery,\n Radius,\n Shadow,\n Spacing,\n} from \"../../theme\";\n\nexport type ItemFocusType = \"self\" | \"others\" | \"none\";\n\nexport const item = css`\n display: flex;\n align-items: center;\n width: 100%;\n border: none;\n\n &:not(:last-child) {\n margin-bottom: ${Spacing[\"spacing-16\"]};\n }\n &[data-item-state=\"disabled\"] {\n cursor: not-allowed;\n }\n\n &[data-item-state=\"sortable\"] {\n &:hover {\n cursor: grab;\n }\n\n // Following recommendation by the library for touch events\n // https://docs.dndkit.com/api-documentation/sensors/touch#recommendations\n touch-action: manipulation;\n }\n\n &[data-item-state=\"sortable-active\"] {\n cursor: grabbing;\n\n // Following recommendation by the library for touch events\n // https://docs.dndkit.com/api-documentation/sensors/touch#recommendations\n touch-action: manipulation;\n }\n`;\n\nexport const dragHandleIcon = css`\n margin-right: ${Spacing[\"spacing-16\"]};\n height: 1.5rem;\n width: 1.5rem;\n color: ${Colour[\"icon\"]};\n\n &[data-drag-handle-state=\"active\"] {\n color: ${Colour[\"icon-primary\"]};\n }\n\n &[data-drag-handle-state=\"disabled\"] {\n color: ${Colour[\"icon-disabled\"]};\n }\n`;\n\nexport const box = css`\n background: ${Colour[\"bg-primary-subtlest\"]};\n border: ${Border[\"width-010\"]} ${Border[\"solid\"]} ${Colour[\"border\"]};\n border-radius: ${Radius[\"sm\"]};\n padding: ${Spacing[\"spacing-16\"]} ${Spacing[\"spacing-32\"]};\n display: flex;\n align-items: center;\n width: 100%;\n\n ${MediaQuery.MaxWidth.md} {\n padding: ${Spacing[\"spacing-16\"]};\n }\n\n &[data-box-state=\"focused\"] {\n border-color: ${Colour[\"border-focus\"]};\n box-shadow: ${Shadow[\"xs-focus-strong\"]};\n }\n\n &[data-box-state=\"disabled\"] {\n border-color: ${Colour[\"border-disabled\"]};\n }\n\n &[data-box-state=\"error\"] {\n background: ${Colour[\"bg-error\"]};\n border-color: ${Colour[\"border-error\"]};\n }\n\n &[data-stack-mobile=\"true\"] {\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n align-items: flex-start;\n }\n }\n`;\n\nexport const contentSection = css`\n display: flex;\n flex: 1;\n align-items: center;\n\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n width: 100%;\n align-items: flex-start;\n }\n\n &[data-has-thumbnail=\"true\"] {\n ${MediaQuery.MaxWidth.md} {\n flex-direction: row;\n align-items: center;\n }\n }\n`;\n\nexport const nameSection = css`\n display: flex;\n flex: 1;\n flex-direction: column;\n width: 100%;\n`;\n\nexport const extendedNameSection = css`\n display: flex;\n flex: 1;\n flex-direction: column;\n align-items: flex-start;\n\n ${MediaQuery.MaxWidth.md} {\n width: 100%;\n }\n`;\n\nexport const fileSizeSection = css`\n display: flex;\n width: 5rem;\n margin-left: ${Spacing[\"spacing-8\"]};\n justify-content: flex-end;\n\n &[data-mobile-visibility=\"hidden\"] {\n ${MediaQuery.MaxWidth.md} {\n display: none;\n visibility: hidden;\n }\n }\n\n &[data-mobile-visibility=\"expand\"] {\n ${MediaQuery.MaxWidth.md} {\n width: 100%;\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-8\"]};\n justify-content: flex-start;\n }\n }\n`;\n\nexport const fileSizeText = css`\n color: ${Colour[\"text-subtler\"]};\n`;\n\nexport const descriptionFileSizeText = css`\n color: ${Colour[\"text-subtler\"]};\n margin-top: ${Spacing[\"spacing-16\"]};\n`;\n\nexport const itemDescriptionLabel = css`\n ${Font[\"form-label\"]}\n font-weight: ${Font.Spec[\"weight-semibold\"]};\n color: ${Colour[\"text-subtle\"]};\n margin-top: ${Spacing[\"spacing-16\"]};\n`;\n\nexport const itemDescriptionText = css`\n margin-top: ${Spacing[\"spacing-4\"]};\n`;\n\nexport const errorIcon = css`\n height: 1lh;\n width: 1em;\n flex-shrink: 0;\n color: ${Colour[\"icon-error-strong\"]};\n`;\n\nexport const desktopErrorMessage = css`\n color: ${Colour[\"text-error\"]};\n margin-top: ${Spacing[\"spacing-4\"]};\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n\n ${MediaQuery.MaxWidth.md} {\n display: none;\n visibility: hidden;\n }\n`;\n\nexport const mobileErrorMessage = css`\n color: ${Colour[\"text-error\"]};\n display: none;\n visibility: hidden;\n\n ${MediaQuery.MaxWidth.md} {\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n visibility: visible;\n margin-top: ${Spacing[\"spacing-8\"]};\n }\n`;\n\nexport const actionContainer = css`\n width: 6rem;\n margin-left: ${Spacing[\"spacing-32\"]};\n display: flex;\n justify-content: flex-end;\n align-items: center;\n\n ${MediaQuery.MaxWidth.md} {\n width: fit-content;\n }\n\n &[data-mobile-layout=\"loading\"] {\n ${MediaQuery.MaxWidth.md} {\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-16\"]};\n width: 100%;\n }\n }\n\n &[data-mobile-layout=\"editable\"] {\n ${MediaQuery.MaxWidth.md} {\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-16\"]};\n align-self: flex-end;\n }\n }\n`;\n\nexport const inlineActionContainer = css`\n width: 100%;\n margin-top: ${Spacing[\"spacing-16\"]};\n display: flex;\n justify-content: flex-end;\n align-items: center;\n`;\n\nexport const iconButton = css`\n min-width: unset;\n\n &:not(:last-child) {\n margin-right: ${Spacing[\"spacing-8\"]};\n }\n`;\n"],"names":["item","dragHandleIcon","box","contentSection","nameSection","extendedNameSection","fileSizeSection","fileSizeText","descriptionFileSizeText","itemDescriptionLabel","itemDescriptionText","errorIcon","desktopErrorMessage","mobileErrorMessage","actionContainer","inlineActionContainer","iconButton"],"mappings":"qFAcO,MAAMA,EAAI,WAgCJC,EAAc,UAedC,EAAG,UAmCHC,EAAc,WAmBdC,EAAW,UAOXC,EAAmB,UAWnBC,EAAe,WAuBfC,EAAY,WAIZC,EAAuB,UAKvBC,EAAoB,WAOpBC,EAAmB,
|
|
1
|
+
{"version":3,"file":"file-list-item.styles.js","sources":["../../../src/file-upload/file-list-item/file-list-item.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport {\n Border,\n Colour,\n Font,\n MediaQuery,\n Radius,\n Shadow,\n Spacing,\n} from \"../../theme\";\n\nexport type ItemFocusType = \"self\" | \"others\" | \"none\";\n\nexport const item = css`\n display: flex;\n align-items: center;\n width: 100%;\n border: none;\n\n &:not(:last-child) {\n margin-bottom: ${Spacing[\"spacing-16\"]};\n }\n &[data-item-state=\"disabled\"] {\n cursor: not-allowed;\n }\n\n &[data-item-state=\"sortable\"] {\n &:hover {\n cursor: grab;\n }\n\n // Following recommendation by the library for touch events\n // https://docs.dndkit.com/api-documentation/sensors/touch#recommendations\n touch-action: manipulation;\n }\n\n &[data-item-state=\"sortable-active\"] {\n cursor: grabbing;\n\n // Following recommendation by the library for touch events\n // https://docs.dndkit.com/api-documentation/sensors/touch#recommendations\n touch-action: manipulation;\n }\n`;\n\nexport const dragHandleIcon = css`\n margin-right: ${Spacing[\"spacing-16\"]};\n height: 1.5rem;\n width: 1.5rem;\n color: ${Colour[\"icon\"]};\n\n &[data-drag-handle-state=\"active\"] {\n color: ${Colour[\"icon-primary\"]};\n }\n\n &[data-drag-handle-state=\"disabled\"] {\n color: ${Colour[\"icon-disabled\"]};\n }\n`;\n\nexport const box = css`\n background: ${Colour[\"bg-primary-subtlest\"]};\n border: ${Border[\"width-010\"]} ${Border[\"solid\"]} ${Colour[\"border\"]};\n border-radius: ${Radius[\"sm\"]};\n padding: ${Spacing[\"spacing-16\"]} ${Spacing[\"spacing-32\"]};\n display: flex;\n align-items: center;\n width: 100%;\n\n ${MediaQuery.MaxWidth.md} {\n padding: ${Spacing[\"spacing-16\"]};\n }\n\n &[data-box-state=\"focused\"] {\n border-color: ${Colour[\"border-focus\"]};\n box-shadow: ${Shadow[\"xs-focus-strong\"]};\n }\n\n &[data-box-state=\"disabled\"] {\n border-color: ${Colour[\"border-disabled\"]};\n }\n\n &[data-box-state=\"error\"] {\n background: ${Colour[\"bg-error\"]};\n border-color: ${Colour[\"border-error\"]};\n }\n\n &[data-stack-mobile=\"true\"] {\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n align-items: flex-start;\n }\n }\n`;\n\nexport const contentSection = css`\n display: flex;\n flex: 1;\n align-items: center;\n\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n width: 100%;\n align-items: flex-start;\n }\n\n &[data-has-thumbnail=\"true\"] {\n ${MediaQuery.MaxWidth.md} {\n flex-direction: row;\n align-items: center;\n }\n }\n`;\n\nexport const nameSection = css`\n display: flex;\n flex: 1;\n flex-direction: column;\n width: 100%;\n`;\n\nexport const extendedNameSection = css`\n display: flex;\n flex: 1;\n flex-direction: column;\n align-items: flex-start;\n\n ${MediaQuery.MaxWidth.md} {\n width: 100%;\n }\n`;\n\nexport const fileSizeSection = css`\n display: flex;\n width: 5rem;\n margin-left: ${Spacing[\"spacing-8\"]};\n justify-content: flex-end;\n\n &[data-mobile-visibility=\"hidden\"] {\n ${MediaQuery.MaxWidth.md} {\n display: none;\n visibility: hidden;\n }\n }\n\n &[data-mobile-visibility=\"expand\"] {\n ${MediaQuery.MaxWidth.md} {\n width: 100%;\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-8\"]};\n justify-content: flex-start;\n }\n }\n`;\n\nexport const fileSizeText = css`\n color: ${Colour[\"text-subtler\"]};\n`;\n\nexport const descriptionFileSizeText = css`\n color: ${Colour[\"text-subtler\"]};\n margin-top: ${Spacing[\"spacing-16\"]};\n`;\n\nexport const itemDescriptionLabel = css`\n ${Font[\"form-label\"]}\n font-weight: ${Font.Spec[\"weight-semibold\"]};\n color: ${Colour[\"text-subtle\"]};\n margin-top: ${Spacing[\"spacing-16\"]};\n`;\n\nexport const itemDescriptionText = css`\n margin-top: ${Spacing[\"spacing-4\"]};\n overflow-wrap: anywhere;\n`;\n\nexport const errorIcon = css`\n height: 1lh;\n width: 1em;\n flex-shrink: 0;\n color: ${Colour[\"icon-error-strong\"]};\n`;\n\nexport const desktopErrorMessage = css`\n color: ${Colour[\"text-error\"]};\n margin-top: ${Spacing[\"spacing-4\"]};\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n\n ${MediaQuery.MaxWidth.md} {\n display: none;\n visibility: hidden;\n }\n`;\n\nexport const mobileErrorMessage = css`\n color: ${Colour[\"text-error\"]};\n display: none;\n visibility: hidden;\n\n ${MediaQuery.MaxWidth.md} {\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n visibility: visible;\n margin-top: ${Spacing[\"spacing-8\"]};\n }\n`;\n\nexport const actionContainer = css`\n width: 6rem;\n margin-left: ${Spacing[\"spacing-32\"]};\n display: flex;\n justify-content: flex-end;\n align-items: center;\n\n ${MediaQuery.MaxWidth.md} {\n width: fit-content;\n }\n\n &[data-mobile-layout=\"loading\"] {\n ${MediaQuery.MaxWidth.md} {\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-16\"]};\n width: 100%;\n }\n }\n\n &[data-mobile-layout=\"editable\"] {\n ${MediaQuery.MaxWidth.md} {\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-16\"]};\n align-self: flex-end;\n }\n }\n`;\n\nexport const inlineActionContainer = css`\n width: 100%;\n margin-top: ${Spacing[\"spacing-16\"]};\n display: flex;\n justify-content: flex-end;\n align-items: center;\n`;\n\nexport const iconButton = css`\n min-width: unset;\n\n &:not(:last-child) {\n margin-right: ${Spacing[\"spacing-8\"]};\n }\n`;\n"],"names":["item","dragHandleIcon","box","contentSection","nameSection","extendedNameSection","fileSizeSection","fileSizeText","descriptionFileSizeText","itemDescriptionLabel","itemDescriptionText","errorIcon","desktopErrorMessage","mobileErrorMessage","actionContainer","inlineActionContainer","iconButton"],"mappings":"qFAcO,MAAMA,EAAI,WAgCJC,EAAc,UAedC,EAAG,UAmCHC,EAAc,WAmBdC,EAAW,UAOXC,EAAmB,UAWnBC,EAAe,WAuBfC,EAAY,WAIZC,EAAuB,UAKvBC,EAAoB,WAOpBC,EAAmB,WAKnBC,EAAS,UAOTC,EAAmB,WAYnBC,EAAkB,WAalBC,EAAe,UA4BfC,EAAqB,UAQrBC,EAAU"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
.f1wv8fjl{color:var(--fds-colour-text-subtler);}
|
|
9
9
|
.divlkvo{color:var(--fds-colour-text-subtler);margin-top:var(--fds-spacing-16);}
|
|
10
10
|
.i1jm950n{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-form-label-size);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-form-label-lh);letter-spacing:var(--fds-font-form-label-ls);font-weight:var(--fds-font-weight-semibold);color:var(--fds-colour-text-subtle);margin-top:var(--fds-spacing-16);}
|
|
11
|
-
.i1vgco4e{margin-top:var(--fds-spacing-4);}
|
|
11
|
+
.i1vgco4e{margin-top:var(--fds-spacing-4);overflow-wrap:anywhere;}
|
|
12
12
|
.eap0p9n{height:1lh;width:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:var(--fds-colour-icon-error-strong);}
|
|
13
13
|
.d1gk2zsk{color:var(--fds-colour-text-error);margin-top:var(--fds-spacing-4);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:var(--fds-spacing-4);}:where(body.fds-breakpoint-md-max) .d1gk2zsk{display:none;visibility:hidden;}
|
|
14
14
|
.m1wh4bod{color:var(--fds-colour-text-error);display:none;visibility:hidden;}:where(body.fds-breakpoint-md-max) .m1wh4bod{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:var(--fds-spacing-4);visibility:visible;margin-top:var(--fds-spacing-8);}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-upload.js","sources":["../../src/file-upload/file-upload.tsx"],"sourcesContent":["import { useRef, useState } from \"react\";\n\nimport { Alert } from \"../alert\";\nimport { Button } from \"../button\";\nimport { Markup } from \"../markup\";\nimport { Typography } from \"../typography\";\nimport { FileUploadContext } from \"./context\";\nimport type { DropzoneElement } from \"./dropzone\";\nimport { FileUploadDropzone } from \"./dropzone\";\nimport type { FileListRef } from \"./file-list\";\nimport { FileList } from \"./file-list\";\nimport * as styles from \"./file-upload.styles\";\nimport type { FileItemProps, FileUploadProps } from \"./types\";\n\n/** Allows user to upload images via drag-and-drop or a native file dialog. */\nexport const FileUpload = ({\n styleType = \"bordered\",\n fileItems,\n title,\n description,\n maxFiles,\n warning,\n className,\n name,\n id,\n \"data-testid\": testId,\n accept,\n capture,\n multiple,\n disabled,\n sortable = false,\n fileDescriptionMaxLength,\n editableFileItems = false,\n descriptionRequired = true,\n descriptionLabel,\n errorMessage,\n readOnly,\n customLabels,\n onChange,\n onDelete,\n onEdit,\n onSort,\n}: FileUploadProps) => {\n const labels = {\n uploadButton: customLabels?.uploadButtonLabel || \"Upload files\",\n };\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const dropzoneRef = useRef<DropzoneElement>(null);\n const fileListRef = useRef<FileListRef>(null);\n const [activeId, setActiveId] = useState<string>();\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleChange = (files: File[]) => {\n const filesToProcess = limitIncomingFiles(files);\n\n if (!disabled && onChange && filesToProcess.length > 0) {\n onChange(filesToProcess);\n fileListRef.current?.focus();\n }\n };\n\n const handleItemDelete = (item: FileItemProps) => {\n if (onDelete) {\n onDelete(item);\n fileListRef.current?.focus();\n }\n };\n\n const handleUploadButtonClick = (\n event: React.MouseEvent<HTMLButtonElement>\n ) => {\n if (!disabled) {\n event.preventDefault();\n if (dropzoneRef.current) {\n dropzoneRef.current.openFileDialog();\n }\n }\n };\n\n const handleItemUpdate = (updatedItem: FileItemProps) => {\n if (onEdit) {\n onEdit(updatedItem);\n }\n };\n\n const handleSort = (updatedItems: FileItemProps[]) => {\n if (onSort) {\n onSort(updatedItems);\n }\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const limitIncomingFiles = (files: File[]) => {\n if (maxFiles === undefined) {\n return files;\n }\n\n const existingItemsCount = fileItems?.length ?? 0;\n const remainingSlots = Math.max(maxFiles - existingItemsCount, 0);\n\n return files.slice(0, remainingSlots);\n };\n\n const reachedMaxFiles = () => {\n return maxFiles && fileItems ? fileItems.length >= maxFiles : false;\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderTitle = () => {\n if (!title) {\n return null;\n }\n\n if (typeof title === \"string\") {\n return <Typography.BodyBL>{title}</Typography.BodyBL>;\n }\n\n return (\n <Markup\n className={styles.markupContainer}\n baseTextSize=\"body-baseline\"\n >\n {title}\n </Markup>\n );\n };\n\n const renderDescription = () => {\n if (!description) {\n return null;\n }\n\n if (typeof description === \"string\") {\n return (\n <Typography.BodyMD className={styles.description}>\n {description}\n </Typography.BodyMD>\n );\n }\n\n return (\n <Markup className={styles.markupContainer} baseTextSize=\"body-md\">\n {description}\n </Markup>\n );\n };\n\n return (\n <FileUploadContext.Provider value={{ activeId, setActiveId }}>\n <FileUploadDropzone\n ref={dropzoneRef}\n onChange={handleChange}\n id={id ? `${id}-dropzone` : \"dropzone\"}\n accept={accept}\n capture={capture}\n border={styleType === \"bordered\"}\n className={className}\n data-testid={testId}\n name={name}\n multiple={multiple}\n disabled={disabled || reachedMaxFiles() || readOnly}\n >\n {!!(title || description) && (\n <div className={styles.textContainer}>\n {renderTitle()}\n {renderDescription()}\n </div>\n )}\n {!!warning && (\n <Alert className={styles.warningAlert} type=\"warning\">\n {warning}\n </Alert>\n )}\n <FileList\n ref={fileListRef}\n fileItems={fileItems}\n editableFileItems={editableFileItems}\n descriptionRequired={descriptionRequired}\n descriptionLabel={descriptionLabel}\n fileDescriptionMaxLength={fileDescriptionMaxLength}\n sortable={sortable}\n disabled={disabled}\n readOnly={readOnly}\n onItemDelete={handleItemDelete}\n onItemUpdate={handleItemUpdate}\n onSort={handleSort}\n />\n {errorMessage && (\n <Alert className={styles.errorAlert} type=\"error\">\n {errorMessage}\n </Alert>\n )}\n {!readOnly && (\n <div className={styles.uploadButtonContainer}>\n <Button\n type=\"button\"\n sizeType=\"small\"\n styleType=\"secondary\"\n disabled={\n !!activeId || disabled || reachedMaxFiles()\n }\n onClick={handleUploadButtonClick}\n className={styles.uploadButton}\n >\n {labels.uploadButton}\n </Button>\n <Typography.BodyMD\n className={styles.uploadButtonText}\n weight=\"semibold\"\n >\n or drop them here\n </Typography.BodyMD>\n </div>\n )}\n </FileUploadDropzone>\n </FileUploadContext.Provider>\n );\n};\n"],"names":["FileUpload","styleType","fileItems","title","description","maxFiles","warning","className","name","id","testId","accept","capture","multiple","disabled","sortable","fileDescriptionMaxLength","editableFileItems","descriptionRequired","descriptionLabel","errorMessage","readOnly","customLabels","onChange","onDelete","onEdit","onSort","labels","uploadButton","uploadButtonLabel","dropzoneRef","useRef","fileListRef","activeId","setActiveId","useState","limitIncomingFiles","files","undefined","existingItemsCount","_a","length","remainingSlots","Math","max","slice","reachedMaxFiles","_jsx","FileUploadContext","Provider","value","children","_jsxs","FileUploadDropzone","ref","filesToProcess","current","focus","border","styles.textContainer","Typography","BodyBL","Markup","styles.markupContainer","baseTextSize","BodyMD","styles.description","Alert","styles.warningAlert","type","FileList","onItemDelete","item","onItemUpdate","updatedItem","updatedItems","styles.errorAlert","styles.uploadButtonContainer","Button","sizeType","onClick","event","preventDefault","openFileDialog","styles.uploadButton","styles.uploadButtonText","weight"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"file-upload.js","sources":["../../src/file-upload/file-upload.tsx"],"sourcesContent":["import { useRef, useState } from \"react\";\n\nimport { Alert } from \"../alert\";\nimport { Button } from \"../button\";\nimport { Markup } from \"../markup\";\nimport { Typography } from \"../typography\";\nimport { FileUploadContext } from \"./context\";\nimport type { DropzoneElement } from \"./dropzone\";\nimport { FileUploadDropzone } from \"./dropzone\";\nimport type { FileListRef } from \"./file-list\";\nimport { FileList } from \"./file-list\";\nimport * as styles from \"./file-upload.styles\";\nimport type { FileItemProps, FileUploadProps } from \"./types\";\n\n// @catalog\n/** Allows user to upload images via drag-and-drop or a native file dialog. */\nexport const FileUpload = ({\n styleType = \"bordered\",\n fileItems,\n title,\n description,\n maxFiles,\n warning,\n className,\n name,\n id,\n \"data-testid\": testId,\n accept,\n capture,\n multiple,\n disabled,\n sortable = false,\n fileDescriptionMaxLength,\n editableFileItems = false,\n descriptionRequired = true,\n descriptionLabel,\n errorMessage,\n readOnly,\n customLabels,\n onChange,\n onDelete,\n onEdit,\n onSort,\n}: FileUploadProps) => {\n const labels = {\n uploadButton: customLabels?.uploadButtonLabel || \"Upload files\",\n };\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const dropzoneRef = useRef<DropzoneElement>(null);\n const fileListRef = useRef<FileListRef>(null);\n const [activeId, setActiveId] = useState<string>();\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleChange = (files: File[]) => {\n const filesToProcess = limitIncomingFiles(files);\n\n if (!disabled && onChange && filesToProcess.length > 0) {\n onChange(filesToProcess);\n fileListRef.current?.focus();\n }\n };\n\n const handleItemDelete = (item: FileItemProps) => {\n if (onDelete) {\n onDelete(item);\n fileListRef.current?.focus();\n }\n };\n\n const handleUploadButtonClick = (\n event: React.MouseEvent<HTMLButtonElement>\n ) => {\n if (!disabled) {\n event.preventDefault();\n if (dropzoneRef.current) {\n dropzoneRef.current.openFileDialog();\n }\n }\n };\n\n const handleItemUpdate = (updatedItem: FileItemProps) => {\n if (onEdit) {\n onEdit(updatedItem);\n }\n };\n\n const handleSort = (updatedItems: FileItemProps[]) => {\n if (onSort) {\n onSort(updatedItems);\n }\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const limitIncomingFiles = (files: File[]) => {\n if (maxFiles === undefined) {\n return files;\n }\n\n const existingItemsCount = fileItems?.length ?? 0;\n const remainingSlots = Math.max(maxFiles - existingItemsCount, 0);\n\n return files.slice(0, remainingSlots);\n };\n\n const reachedMaxFiles = () => {\n return maxFiles && fileItems ? fileItems.length >= maxFiles : false;\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderTitle = () => {\n if (!title) {\n return null;\n }\n\n if (typeof title === \"string\") {\n return <Typography.BodyBL>{title}</Typography.BodyBL>;\n }\n\n return (\n <Markup\n className={styles.markupContainer}\n baseTextSize=\"body-baseline\"\n >\n {title}\n </Markup>\n );\n };\n\n const renderDescription = () => {\n if (!description) {\n return null;\n }\n\n if (typeof description === \"string\") {\n return (\n <Typography.BodyMD className={styles.description}>\n {description}\n </Typography.BodyMD>\n );\n }\n\n return (\n <Markup className={styles.markupContainer} baseTextSize=\"body-md\">\n {description}\n </Markup>\n );\n };\n\n return (\n <FileUploadContext.Provider value={{ activeId, setActiveId }}>\n <FileUploadDropzone\n ref={dropzoneRef}\n onChange={handleChange}\n id={id ? `${id}-dropzone` : \"dropzone\"}\n accept={accept}\n capture={capture}\n border={styleType === \"bordered\"}\n className={className}\n data-testid={testId}\n name={name}\n multiple={multiple}\n disabled={disabled || reachedMaxFiles() || readOnly}\n >\n {!!(title || description) && (\n <div className={styles.textContainer}>\n {renderTitle()}\n {renderDescription()}\n </div>\n )}\n {!!warning && (\n <Alert className={styles.warningAlert} type=\"warning\">\n {warning}\n </Alert>\n )}\n <FileList\n ref={fileListRef}\n fileItems={fileItems}\n editableFileItems={editableFileItems}\n descriptionRequired={descriptionRequired}\n descriptionLabel={descriptionLabel}\n fileDescriptionMaxLength={fileDescriptionMaxLength}\n sortable={sortable}\n disabled={disabled}\n readOnly={readOnly}\n onItemDelete={handleItemDelete}\n onItemUpdate={handleItemUpdate}\n onSort={handleSort}\n />\n {errorMessage && (\n <Alert className={styles.errorAlert} type=\"error\">\n {errorMessage}\n </Alert>\n )}\n {!readOnly && (\n <div className={styles.uploadButtonContainer}>\n <Button\n type=\"button\"\n sizeType=\"small\"\n styleType=\"secondary\"\n disabled={\n !!activeId || disabled || reachedMaxFiles()\n }\n onClick={handleUploadButtonClick}\n className={styles.uploadButton}\n >\n {labels.uploadButton}\n </Button>\n <Typography.BodyMD\n className={styles.uploadButtonText}\n weight=\"semibold\"\n >\n or drop them here\n </Typography.BodyMD>\n </div>\n )}\n </FileUploadDropzone>\n </FileUploadContext.Provider>\n );\n};\n"],"names":["FileUpload","styleType","fileItems","title","description","maxFiles","warning","className","name","id","testId","accept","capture","multiple","disabled","sortable","fileDescriptionMaxLength","editableFileItems","descriptionRequired","descriptionLabel","errorMessage","readOnly","customLabels","onChange","onDelete","onEdit","onSort","labels","uploadButton","uploadButtonLabel","dropzoneRef","useRef","fileListRef","activeId","setActiveId","useState","limitIncomingFiles","files","undefined","existingItemsCount","_a","length","remainingSlots","Math","max","slice","reachedMaxFiles","_jsx","FileUploadContext","Provider","value","children","_jsxs","FileUploadDropzone","ref","filesToProcess","current","focus","border","styles.textContainer","Typography","BodyBL","Markup","styles.markupContainer","baseTextSize","BodyMD","styles.description","Alert","styles.warningAlert","type","FileList","onItemDelete","item","onItemUpdate","updatedItem","updatedItems","styles.errorAlert","styles.uploadButtonContainer","Button","sizeType","onClick","event","preventDefault","openFileDialog","styles.uploadButton","styles.uploadButtonText","weight"],"mappings":"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"}
|
package/file-upload/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FormLabelProps } from "../form/types";
|
|
1
|
+
import type { FormLabelProps } from "../form/form-label/types";
|
|
2
2
|
/**
|
|
3
3
|
* Represents a single file entry managed by `FileUpload`.
|
|
4
4
|
*/
|
|
@@ -29,7 +29,11 @@ export interface FileItemProps {
|
|
|
29
29
|
* other file types show no default icon.
|
|
30
30
|
*/
|
|
31
31
|
thumbnailImageDataUrl?: string | undefined;
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Truncates long file names with an ellipsis when `true`.
|
|
34
|
+
*
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
33
37
|
truncateText?: boolean | undefined;
|
|
34
38
|
}
|
|
35
39
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { FlattenedFilterOption } from "./internal-types";
|
|
2
|
+
import type { FilterItemCheckboxOptionProps } from "./types";
|
|
3
3
|
/**
|
|
4
4
|
* Builds a key path string from an array of keys
|
|
5
5
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-item-checkbox-helpers.js","sources":["../../../src/filter/addons/filter-item-checkbox-helpers.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"filter-item-checkbox-helpers.js","sources":["../../../src/filter/addons/filter-item-checkbox-helpers.ts"],"sourcesContent":["import type { FlattenedFilterOption } from \"./internal-types\";\nimport type { FilterItemCheckboxOptionProps } from \"./types\";\n\n// =============================================================================\n// HELPER FUNCTIONS FOR NESTED OPTIONS\n// =============================================================================\n\n/**\n * Builds a key path string from an array of keys\n */\nexport const buildKeyPath = (keyPath: string[]): string => {\n return keyPath.join(\".\");\n};\n\n/**\n * Flattens nested options into a flat array for rendering\n */\nexport const flattenNestedOptions = <T = FilterItemCheckboxOptionProps>(\n nestedOptions: T[],\n parentKeyPath: string[] = [],\n valueExtractor?: (item: T) => string,\n labelExtractor?: (item: T) => string\n): FlattenedFilterOption<T>[] => {\n const flattened: FlattenedFilterOption<T>[] = [];\n\n nestedOptions.forEach((option, index) => {\n const value: string = valueExtractor\n ? valueExtractor(option)\n : (option as any).value;\n const label: string = labelExtractor\n ? labelExtractor(option)\n : (option as any).label;\n const options: any[] = (option as any).options;\n const keyPath = [...parentKeyPath, value];\n const hasChildren = !!(options && options.length > 0);\n\n flattened.push({\n originalItem: option,\n value,\n label,\n keyPath,\n level: parentKeyPath.length,\n hasChildren,\n parentKeyPath: parentKeyPath.length > 0 ? parentKeyPath : undefined,\n indexInParent: index,\n parentSetSize: nestedOptions.length,\n });\n\n // Recursively flatten children\n if (hasChildren) {\n flattened.push(\n ...flattenNestedOptions(\n options,\n keyPath,\n valueExtractor,\n labelExtractor\n )\n );\n }\n });\n\n return flattened;\n};\n\n/**\n * Checks if a child key path is a descendant of a parent key path\n */\nconst isChild = (parentKeyPath: string[], childKeyPath: string[]): boolean => {\n if (childKeyPath.length <= parentKeyPath.length) return false;\n\n const parentKeyPathString = buildKeyPath(parentKeyPath);\n const childKeyPathString = buildKeyPath(childKeyPath);\n\n return childKeyPathString.startsWith(parentKeyPathString + \".\");\n};\n\n/**\n * Gets all descendant key paths (children, grandchildren, etc.) for a given parent\n */\nexport const getAllDescendantKeyPaths = <T = FilterItemCheckboxOptionProps>(\n flattenedOptions: FlattenedFilterOption<T>[],\n parentKeyPath: string[]\n): string[][] => {\n return flattenedOptions\n .filter((option) => isChild(parentKeyPath, option.keyPath))\n .map((option) => option.keyPath);\n};\n\n/**\n * Gets all descendant leaf children (non-parent items)\n */\nexport const getAllDescendantChildren = <T = FilterItemCheckboxOptionProps>(\n flattenedOptions: FlattenedFilterOption<T>[],\n parentKeyPath: string[]\n): T[] => {\n const parentKeyPathString = buildKeyPath(parentKeyPath);\n const children: T[] = [];\n\n const parentIndex = flattenedOptions.findIndex(\n (option) => buildKeyPath(option.keyPath) === parentKeyPathString\n );\n\n if (parentIndex === -1) return children;\n\n // Single pass: iterate from parent+1 until we find an item that's not a descendant\n for (let i = parentIndex + 1; i < flattenedOptions.length; i++) {\n const option = flattenedOptions[i];\n\n // Check if this item is a descendant\n if (isChild(parentKeyPath, option.keyPath)) {\n // Only include leaf nodes (non-parent items)\n if (!option.hasChildren) {\n children.push(option.originalItem as T);\n }\n } else {\n // No more descendants - we can break early\n break;\n }\n }\n\n return children;\n};\n\n/**\n * Checks if an option has nested options\n */\nexport const hasNestedOptions = <T = FilterItemCheckboxOptionProps>(\n options: T[],\n optionsExtractor?: (item: T) => T[]\n): boolean => {\n return options.some((option: T) => {\n const nestedOptions: any[] = optionsExtractor\n ? optionsExtractor(option)\n : (option as any).options;\n return nestedOptions && nestedOptions.length > 0;\n });\n};\n"],"names":["buildKeyPath","keyPath","join","flattenNestedOptions","nestedOptions","parentKeyPath","valueExtractor","labelExtractor","flattened","forEach","option","index","value","label","options","hasChildren","length","push","originalItem","level","undefined","indexInParent","parentSetSize","isChild","childKeyPath","parentKeyPathString","startsWith","getAllDescendantKeyPaths","flattenedOptions","filter","map","getAllDescendantChildren","children","parentIndex","findIndex","i","hasNestedOptions","optionsExtractor","some"],"mappings":"AAUO,MAAMA,EAAgBC,GAClBA,EAAQC,KAAK,KAMXC,EAAuB,CAChCC,EACAC,EAA0B,GAC1BC,EACAC,KAEA,MAAMC,EAAwC,GAsC9C,OApCAJ,EAAcK,SAAQ,CAACC,EAAQC,KAC3B,MAAMC,EAAgBN,EAChBA,EAAeI,GACdA,EAAeE,MAChBC,EAAgBN,EAChBA,EAAeG,GACdA,EAAeG,MAChBC,EAAkBJ,EAAeI,QACjCb,EAAU,IAAII,EAAeO,GAC7BG,KAAiBD,GAAWA,EAAQE,OAAS,GAEnDR,EAAUS,KAAK,CACXC,aAAcR,EACdE,QACAC,QACAZ,UACAkB,MAAOd,EAAcW,OACrBD,cACAV,cAAeA,EAAcW,OAAS,EAAIX,OAAgBe,EAC1DC,cAAeV,EACfW,cAAelB,EAAcY,SAI7BD,GACAP,EAAUS,QACHd,EACCW,EACAb,EACAK,EACAC,GAGZ,IAGGC,CAAS,EAMde,EAAU,CAAClB,EAAyBmB,KACtC,GAAIA,EAAaR,QAAUX,EAAcW,OAAQ,OAAO,EAExD,MAAMS,EAAsBzB,EAAaK,GAGzC,OAF2BL,EAAawB,GAEdE,WAAWD,EAAsB,IAAI,EAMtDE,EAA2B,CACpCC,EACAvB,IAEOuB,EACFC,QAAQnB,GAAWa,EAAQlB,EAAeK,EAAOT,WACjD6B,KAAKpB,GAAWA,EAAOT,UAMnB8B,EAA2B,CACpCH,EACAvB,KAEA,MAAMoB,EAAsBzB,EAAaK,GACnC2B,EAAgB,GAEhBC,EAAcL,EAAiBM,WAChCxB,GAAWV,EAAaU,EAAOT,WAAawB,IAGjD,IAAoB,IAAhBQ,EAAoB,OAAOD,EAG/B,IAAK,IAAIG,EAAIF,EAAc,EAAGE,EAAIP,EAAiBZ,OAAQmB,IAAK,CAC5D,MAAMzB,EAASkB,EAAiBO,GAGhC,IAAIZ,EAAQlB,EAAeK,EAAOT,SAO9B,MALKS,EAAOK,aACRiB,EAASf,KAAKP,EAAOQ,aAMjC,CAEA,OAAOc,CAAQ,EAMNI,EAAmB,CAC5BtB,EACAuB,IAEOvB,EAAQwB,MAAM5B,IACjB,MAAMN,EAAuBiC,EACvBA,EAAiB3B,GAChBA,EAAeI,QACtB,OAAOV,GAAiBA,EAAcY,OAAS,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FilterItemCheckboxOptionProps, FilterItemCheckboxProps } from "
|
|
1
|
+
import type { FilterItemCheckboxOptionProps, FilterItemCheckboxProps } from "./types";
|
|
2
2
|
export declare const FilterItemCheckbox: {
|
|
3
3
|
<T = FilterItemCheckboxOptionProps>({ selectedOptions, options, showAsCheckboxInMobile, minimisableOptions, onSelect, labelExtractor, valueExtractor, useToggleContentWidth, ...filterItemProps }: FilterItemCheckboxProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
displayName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-item-checkbox.js","sources":["../../../src/filter/addons/filter-item-checkbox.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type { AriaAttributes } from \"react\";\nimport {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { Button } from \"../../button\";\nimport { Checkbox } from \"../../checkbox\";\nimport { Toggle } from \"../../toggle\";\nimport { FilterContext } from \"../filter-context\";\nimport { FilterItem } from \"../filter-item\";\nimport type {\n FilterItemCheckboxOptionProps,\n FilterItemCheckboxProps,\n} from \"../types\";\nimport * as styles from \"./filter-item-checkbox.styles\";\nimport {\n buildKeyPath,\n flattenNestedOptions,\n getAllDescendantChildren,\n getAllDescendantKeyPaths,\n hasNestedOptions,\n} from \"./filter-item-checkbox-helpers\";\nimport type { FlattenedFilterOption } from \"./types\";\n\nexport const FilterItemCheckbox = <T = FilterItemCheckboxOptionProps,>({\n selectedOptions,\n options,\n showAsCheckboxInMobile = false,\n minimisableOptions = true,\n onSelect,\n labelExtractor,\n valueExtractor,\n useToggleContentWidth,\n ...filterItemProps\n}: FilterItemCheckboxProps<T>) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const { mode } = useContext(FilterContext);\n const [selected, setSelected] = useState<T[]>(selectedOptions || []);\n const [minimisedHeight, setMinimisedHeight] = useState<number>();\n const [lastVisibleElementIndex, setLastVisibleElementIndex] =\n useState<number>(options.length);\n const parentRef = useRef<HTMLDivElement>(null);\n const lastVisibleElement = useRef<HTMLElement | null>(null);\n\n // Check if options have nested structure\n const isNested = useMemo(\n () => hasNestedOptions(options, (item) => (item as any).options),\n [options]\n );\n\n const isMobileToggleMode =\n mode === \"mobile\" && !showAsCheckboxInMobile && !isNested;\n\n // Flatten nested options\n const flattenedOptions = useMemo(\n () =>\n flattenNestedOptions(\n options,\n [],\n valueExtractor || ((item) => (item as any).value),\n labelExtractor || ((item) => (item as any).label)\n ),\n [options, valueExtractor, labelExtractor]\n );\n\n const optionCount = flattenedOptions.length;\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleItemClick = (item: T) => () => {\n // Find the flattened option\n const flatOption = flattenedOptions.find(\n (opt) => opt.originalItem === item\n );\n if (!flatOption) return;\n\n if (flatOption.hasChildren) {\n // Handle parent click - select/deselect all children\n const allChildren = getAllDescendantChildren<T>(\n flattenedOptions,\n flatOption.keyPath\n );\n\n const currentlySelectedChildren = allChildren.filter((child) =>\n selected.some((s) => getValue(s) === getValue(child))\n );\n\n let newSelection = [...selected];\n\n if (currentlySelectedChildren.length === allChildren.length) {\n // All children selected, deselect all\n newSelection = newSelection.filter(\n (s) =>\n !allChildren.some(\n (child) => getValue(child) === getValue(s)\n )\n );\n } else {\n // Some or no children selected, select all\n allChildren.forEach((child) => {\n if (\n !newSelection.some(\n (s) => getValue(s) === getValue(child)\n )\n ) {\n newSelection.push(child);\n }\n });\n }\n\n setSelected(newSelection);\n onSelect?.(newSelection);\n } else {\n // Handle leaf item click - toggle selection\n const newSelection = [...selected];\n const selectedIndex = selected.findIndex(\n (s) => getValue(s) === getValue(item)\n );\n\n if (selectedIndex >= 0) {\n newSelection.splice(selectedIndex, 1);\n } else {\n newSelection.push(item);\n }\n setSelected(newSelection);\n onSelect?.(newSelection);\n }\n };\n\n const handleSelectClearAll = () => {\n if (isNested) {\n if (selected.length > 0) {\n // Clear all\n setSelected([]);\n onSelect?.([]);\n } else {\n // Select all leaf nodes\n const leafOptions = flattenedOptions.filter(\n (option) => !option.hasChildren\n );\n const allValues = leafOptions.map(\n (option) => option.originalItem\n ) as T[];\n setSelected(allValues);\n onSelect?.(allValues);\n }\n } else {\n const newSelection = selected.length ? [] : options;\n setSelected(newSelection);\n onSelect?.(newSelection);\n }\n };\n\n const handleListItemKeyDown =\n (originalItem: T) => (event: React.KeyboardEvent) => {\n if (isNested && (event.key === \" \" || event.key === \"Enter\")) {\n event.preventDefault();\n handleItemClick(originalItem)();\n }\n };\n\n const handleCheckboxChange = (originalItem: T) => () => {\n if (!isNested) {\n handleItemClick(originalItem)();\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const getCheckboxState = (flatOption: (typeof flattenedOptions)[0]) => {\n if (!flatOption.hasChildren) {\n // Leaf item - simple check\n return {\n checked: selected.some(\n (s) =>\n getValue(s) === getValue(flatOption.originalItem as T)\n ),\n indeterminate: false,\n };\n }\n\n // Parent item - check children states (following IndeterminateState pattern)\n const allChildren = getAllDescendantKeyPaths(\n flattenedOptions,\n flatOption.keyPath\n )\n .map((keyPath: string[]) =>\n flattenedOptions.find(\n (opt) => buildKeyPath(opt.keyPath) === buildKeyPath(keyPath)\n )\n )\n .filter((opt) => opt && !opt.hasChildren)\n .map((opt) => opt!.originalItem as T);\n\n const selectedChildren = allChildren.filter((child) =>\n selected.some((s) => getValue(s) === getValue(child))\n );\n\n return {\n checked:\n selectedChildren.length === allChildren.length &&\n allChildren.length > 0,\n indeterminate:\n selectedChildren.length > 0 &&\n selectedChildren.length < allChildren.length,\n };\n };\n\n const getLabel = (item: T): React.ReactNode => {\n return labelExtractor\n ? labelExtractor(item)\n : (item as any).label ?? item?.toString();\n };\n\n const getValue = (item: T): string => {\n return valueExtractor\n ? valueExtractor(item)\n : (item as any).value ?? item?.toString();\n };\n\n const setVisibleItemsWhenMinimised = () => {\n const elementBottom = lastVisibleElement.current\n ? lastVisibleElement.current.offsetTop +\n lastVisibleElement.current.clientHeight\n : undefined;\n setMinimisedHeight(elementBottom);\n };\n\n const setVisibleMobileItemsWhenMinimised = useCallback(() => {\n if (!parentRef.current) {\n setMinimisedHeight(undefined);\n return;\n }\n\n const children = Array.from(parentRef.current.children);\n\n let lastElementInRow = 0;\n let rowCount = 0;\n let rowTop = -1;\n\n for (let i = 0; i < children.length; i++) {\n const childTop = (children[i] as HTMLDivElement).offsetTop;\n if (childTop > rowTop) {\n rowCount++;\n rowTop = childTop;\n // show only the first 2 rows\n if (rowCount > 2) {\n break;\n }\n }\n lastElementInRow = i;\n }\n\n setLastVisibleElementIndex(lastElementInRow);\n\n if (rowCount > 2) {\n setMinimisedHeight(rowTop - 8); // gap from next row\n } else {\n setMinimisedHeight(undefined);\n }\n }, []);\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n if (selectedOptions !== selected) {\n setSelected(selectedOptions || []);\n }\n }, [selectedOptions]);\n\n useEffect(() => {\n if (isMobileToggleMode) {\n setVisibleMobileItemsWhenMinimised();\n } else {\n setVisibleItemsWhenMinimised();\n }\n }, [options]);\n\n useResizeDetector({\n handleWidth: true,\n handleHeight: false,\n skipOnMount: true,\n refreshMode: \"throttle\",\n targetRef: parentRef,\n onResize: isMobileToggleMode\n ? setVisibleMobileItemsWhenMinimised\n : setVisibleItemsWhenMinimised,\n });\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderCheckboxIcon = (\n originalItem: T,\n flatOption: FlattenedFilterOption<T>\n ) => {\n const { checked, indeterminate } = getCheckboxState(flatOption);\n\n return (\n <Checkbox\n className={styles.checkbox}\n displaySize=\"small\"\n checked={checked}\n indeterminate={indeterminate}\n onChange={handleCheckboxChange(originalItem)}\n tabIndex={isNested ? -1 : undefined}\n aria-hidden={isNested ? \"true\" : undefined}\n />\n );\n };\n\n const renderCheckbox = (\n option: FlattenedFilterOption<T>,\n index: number,\n minimised: boolean\n ) => {\n const originalItem = option.originalItem;\n const optionLabel = getLabel(originalItem);\n const { checked, indeterminate } = getCheckboxState(option);\n const isSelected = checked || indeterminate;\n const isVisible = !minimised || index < 5;\n\n // ARIA attributes for tree items\n const treeItemAriaAttributes: AriaAttributes = isNested\n ? {\n \"aria-checked\": indeterminate ? \"mixed\" : checked,\n \"aria-selected\": !!checked,\n \"aria-level\": option.level + 1,\n \"aria-posinset\": option.indexInParent + 1,\n \"aria-setsize\": option.parentSetSize,\n }\n : {};\n\n const itemRef = (el: HTMLElement | null) => {\n if (el && option.level) {\n el.style.setProperty(\n styles.tokens.item.level,\n String(option.level)\n );\n }\n if (index === 4) {\n lastVisibleElement.current = el;\n }\n };\n\n const itemClassName = clsx(\n styles.item,\n !isVisible && styles.itemHidden,\n isSelected && styles.itemSelected\n );\n\n const itemContent = (\n <>\n {renderCheckboxIcon(originalItem, option)}\n {optionLabel}\n </>\n );\n\n if (isNested) {\n return (\n <div\n key={buildKeyPath(option.keyPath)}\n role=\"treeitem\"\n {...treeItemAriaAttributes}\n onClick={handleItemClick(originalItem)}\n onKeyDown={handleListItemKeyDown(originalItem)}\n tabIndex={0}\n className={itemClassName}\n ref={itemRef}\n >\n {itemContent}\n </div>\n );\n }\n\n return (\n <label\n key={buildKeyPath(option.keyPath)}\n onKeyDown={handleListItemKeyDown(originalItem)}\n className={itemClassName}\n ref={itemRef}\n >\n {itemContent}\n </label>\n );\n };\n\n const renderToggle = (\n option: FlattenedFilterOption<T>,\n index: number,\n minimised: boolean\n ) => {\n const originalItem = option.originalItem;\n const optionLabel = getLabel(originalItem);\n const optionValue = getValue(originalItem);\n const checked = !!selected.find((s) => getValue(s) === optionValue);\n const isToggleVisible =\n !minimised ||\n (!!minimisedHeight && index <= lastVisibleElementIndex);\n return (\n <Toggle\n key={optionValue}\n type=\"checkbox\"\n checked={checked}\n className={clsx(\n !useToggleContentWidth && styles.toggle,\n !isToggleVisible && styles.toggleHidden\n )}\n onChange={handleItemClick(originalItem)}\n useContentWidth={useToggleContentWidth}\n >\n {optionLabel}\n </Toggle>\n );\n };\n\n const renderSelectClearAllButton = () => {\n if (optionCount < 3) {\n return null;\n }\n return (\n <Button\n className={styles.selectAllButton}\n styleType=\"link\"\n type=\"button\"\n sizeType=\"small\"\n onClick={handleSelectClearAll}\n aria-label={\n selected.length\n ? \"Clear all selections\"\n : `Select all in ${\n parentRef.current?.ariaLabel || \"this group\"\n }`\n }\n >\n {selected.length ? \"Clear all\" : \"Select all\"}\n </Button>\n );\n };\n\n return (\n <FilterItem\n minimisable={\n minimisableOptions\n ? isMobileToggleMode // set minimisable base on mobile toggle mode\n ? !!minimisedHeight\n : optionCount > 5\n : false // if minimisableOptions is false, never allow minimising\n }\n minimisedHeight={minimisedHeight}\n {...filterItemProps}\n className={clsx(styles.filterItem, filterItemProps.className)}\n >\n {(_, { minimised }) => (\n <>\n {renderSelectClearAllButton()}\n <div\n role={isNested ? \"tree\" : \"group\"}\n aria-label={filterItemProps.title}\n aria-multiselectable={true}\n ref={parentRef}\n className={clsx(\n styles.group,\n isMobileToggleMode && styles.groupMobileToggleMode\n )}\n >\n {flattenedOptions.map((option, i) =>\n isMobileToggleMode\n ? renderToggle(option, i, minimised)\n : renderCheckbox(option, i, minimised)\n )}\n </div>\n </>\n )}\n </FilterItem>\n );\n};\n\nFilterItemCheckbox.displayName = \"Filter.Checkbox\";\n"],"names":["FilterItemCheckbox","_a","selectedOptions","options","showAsCheckboxInMobile","minimisableOptions","onSelect","labelExtractor","valueExtractor","useToggleContentWidth","filterItemProps","__rest","mode","useContext","FilterContext","selected","setSelected","useState","minimisedHeight","setMinimisedHeight","lastVisibleElementIndex","setLastVisibleElementIndex","length","parentRef","useRef","lastVisibleElement","isNested","useMemo","hasNestedOptions","item","isMobileToggleMode","flattenedOptions","flattenNestedOptions","value","label","optionCount","handleItemClick","flatOption","find","opt","originalItem","hasChildren","allChildren","getAllDescendantChildren","keyPath","currentlySelectedChildren","filter","child","some","s","getValue","newSelection","forEach","push","selectedIndex","findIndex","splice","handleSelectClearAll","allValues","option","map","handleListItemKeyDown","event","key","preventDefault","handleCheckboxChange","getCheckboxState","checked","indeterminate","getAllDescendantKeyPaths","buildKeyPath","selectedChildren","getLabel","toString","setVisibleItemsWhenMinimised","elementBottom","current","offsetTop","clientHeight","undefined","setVisibleMobileItemsWhenMinimised","useCallback","children","Array","from","lastElementInRow","rowCount","rowTop","i","childTop","useEffect","useResizeDetector","handleWidth","handleHeight","skipOnMount","refreshMode","targetRef","onResize","renderCheckboxIcon","_jsx","Checkbox","className","styles.checkbox","displaySize","onChange","tabIndex","renderSelectClearAllButton","Button","styles.selectAllButton","styleType","type","sizeType","onClick","ariaLabel","FilterItem","Object","assign","minimisable","clsx","styles.filterItem","_","minimised","_jsxs","_Fragment","role","title","ref","styles.group","styles.groupMobileToggleMode","index","optionLabel","optionValue","Toggle","styles.toggle","styles.toggleHidden","useContentWidth","renderToggle","isSelected","isVisible","treeItemAriaAttributes","level","indexInParent","parentSetSize","itemRef","el","style","setProperty","styles.tokens","String","itemClassName","styles.item","styles.itemHidden","styles.itemSelected","itemContent","onKeyDown","renderCheckbox","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filter-item-checkbox.js","sources":["../../../src/filter/addons/filter-item-checkbox.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type { AriaAttributes } from \"react\";\nimport {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { Button } from \"../../button\";\nimport { Checkbox } from \"../../checkbox\";\nimport { Toggle } from \"../../toggle\";\nimport { FilterContext } from \"../filter-context\";\nimport { FilterItem } from \"../filter-item\";\nimport * as styles from \"./filter-item-checkbox.styles\";\nimport {\n buildKeyPath,\n flattenNestedOptions,\n getAllDescendantChildren,\n getAllDescendantKeyPaths,\n hasNestedOptions,\n} from \"./filter-item-checkbox-helpers\";\nimport type { FlattenedFilterOption } from \"./internal-types\";\nimport type {\n FilterItemCheckboxOptionProps,\n FilterItemCheckboxProps,\n} from \"./types\";\n\nexport const FilterItemCheckbox = <T = FilterItemCheckboxOptionProps,>({\n selectedOptions,\n options,\n showAsCheckboxInMobile = false,\n minimisableOptions = true,\n onSelect,\n labelExtractor,\n valueExtractor,\n useToggleContentWidth,\n ...filterItemProps\n}: FilterItemCheckboxProps<T>) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const { mode } = useContext(FilterContext);\n const [selected, setSelected] = useState<T[]>(selectedOptions || []);\n const [minimisedHeight, setMinimisedHeight] = useState<number>();\n const [lastVisibleElementIndex, setLastVisibleElementIndex] =\n useState<number>(options.length);\n const parentRef = useRef<HTMLDivElement>(null);\n const lastVisibleElement = useRef<HTMLElement | null>(null);\n\n // Check if options have nested structure\n const isNested = useMemo(\n () => hasNestedOptions(options, (item) => (item as any).options),\n [options]\n );\n\n const isMobileToggleMode =\n mode === \"mobile\" && !showAsCheckboxInMobile && !isNested;\n\n // Flatten nested options\n const flattenedOptions = useMemo(\n () =>\n flattenNestedOptions(\n options,\n [],\n valueExtractor || ((item) => (item as any).value),\n labelExtractor || ((item) => (item as any).label)\n ),\n [options, valueExtractor, labelExtractor]\n );\n\n const optionCount = flattenedOptions.length;\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleItemClick = (item: T) => () => {\n // Find the flattened option\n const flatOption = flattenedOptions.find(\n (opt) => opt.originalItem === item\n );\n if (!flatOption) return;\n\n if (flatOption.hasChildren) {\n // Handle parent click - select/deselect all children\n const allChildren = getAllDescendantChildren<T>(\n flattenedOptions,\n flatOption.keyPath\n );\n\n const currentlySelectedChildren = allChildren.filter((child) =>\n selected.some((s) => getValue(s) === getValue(child))\n );\n\n let newSelection = [...selected];\n\n if (currentlySelectedChildren.length === allChildren.length) {\n // All children selected, deselect all\n newSelection = newSelection.filter(\n (s) =>\n !allChildren.some(\n (child) => getValue(child) === getValue(s)\n )\n );\n } else {\n // Some or no children selected, select all\n allChildren.forEach((child) => {\n if (\n !newSelection.some(\n (s) => getValue(s) === getValue(child)\n )\n ) {\n newSelection.push(child);\n }\n });\n }\n\n setSelected(newSelection);\n onSelect?.(newSelection);\n } else {\n // Handle leaf item click - toggle selection\n const newSelection = [...selected];\n const selectedIndex = selected.findIndex(\n (s) => getValue(s) === getValue(item)\n );\n\n if (selectedIndex >= 0) {\n newSelection.splice(selectedIndex, 1);\n } else {\n newSelection.push(item);\n }\n setSelected(newSelection);\n onSelect?.(newSelection);\n }\n };\n\n const handleSelectClearAll = () => {\n if (isNested) {\n if (selected.length > 0) {\n // Clear all\n setSelected([]);\n onSelect?.([]);\n } else {\n // Select all leaf nodes\n const leafOptions = flattenedOptions.filter(\n (option) => !option.hasChildren\n );\n const allValues = leafOptions.map(\n (option) => option.originalItem\n ) as T[];\n setSelected(allValues);\n onSelect?.(allValues);\n }\n } else {\n const newSelection = selected.length ? [] : options;\n setSelected(newSelection);\n onSelect?.(newSelection);\n }\n };\n\n const handleListItemKeyDown =\n (originalItem: T) => (event: React.KeyboardEvent) => {\n if (isNested && (event.key === \" \" || event.key === \"Enter\")) {\n event.preventDefault();\n handleItemClick(originalItem)();\n }\n };\n\n const handleCheckboxChange = (originalItem: T) => () => {\n if (!isNested) {\n handleItemClick(originalItem)();\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const getCheckboxState = (flatOption: (typeof flattenedOptions)[0]) => {\n if (!flatOption.hasChildren) {\n // Leaf item - simple check\n return {\n checked: selected.some(\n (s) =>\n getValue(s) === getValue(flatOption.originalItem as T)\n ),\n indeterminate: false,\n };\n }\n\n // Parent item - check children states (following IndeterminateState pattern)\n const allChildren = getAllDescendantKeyPaths(\n flattenedOptions,\n flatOption.keyPath\n )\n .map((keyPath: string[]) =>\n flattenedOptions.find(\n (opt) => buildKeyPath(opt.keyPath) === buildKeyPath(keyPath)\n )\n )\n .filter((opt) => opt && !opt.hasChildren)\n .map((opt) => opt!.originalItem as T);\n\n const selectedChildren = allChildren.filter((child) =>\n selected.some((s) => getValue(s) === getValue(child))\n );\n\n return {\n checked:\n selectedChildren.length === allChildren.length &&\n allChildren.length > 0,\n indeterminate:\n selectedChildren.length > 0 &&\n selectedChildren.length < allChildren.length,\n };\n };\n\n const getLabel = (item: T): React.ReactNode => {\n return labelExtractor\n ? labelExtractor(item)\n : (item as any).label ?? item?.toString();\n };\n\n const getValue = (item: T): string => {\n return valueExtractor\n ? valueExtractor(item)\n : (item as any).value ?? item?.toString();\n };\n\n const setVisibleItemsWhenMinimised = () => {\n const elementBottom = lastVisibleElement.current\n ? lastVisibleElement.current.offsetTop +\n lastVisibleElement.current.clientHeight\n : undefined;\n setMinimisedHeight(elementBottom);\n };\n\n const setVisibleMobileItemsWhenMinimised = useCallback(() => {\n if (!parentRef.current) {\n setMinimisedHeight(undefined);\n return;\n }\n\n const children = Array.from(parentRef.current.children);\n\n let lastElementInRow = 0;\n let rowCount = 0;\n let rowTop = -1;\n\n for (let i = 0; i < children.length; i++) {\n const childTop = (children[i] as HTMLDivElement).offsetTop;\n if (childTop > rowTop) {\n rowCount++;\n rowTop = childTop;\n // show only the first 2 rows\n if (rowCount > 2) {\n break;\n }\n }\n lastElementInRow = i;\n }\n\n setLastVisibleElementIndex(lastElementInRow);\n\n if (rowCount > 2) {\n setMinimisedHeight(rowTop - 8); // gap from next row\n } else {\n setMinimisedHeight(undefined);\n }\n }, []);\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n if (selectedOptions !== selected) {\n setSelected(selectedOptions || []);\n }\n }, [selectedOptions]);\n\n useEffect(() => {\n if (isMobileToggleMode) {\n setVisibleMobileItemsWhenMinimised();\n } else {\n setVisibleItemsWhenMinimised();\n }\n }, [options]);\n\n useResizeDetector({\n handleWidth: true,\n handleHeight: false,\n skipOnMount: true,\n refreshMode: \"throttle\",\n targetRef: parentRef,\n onResize: isMobileToggleMode\n ? setVisibleMobileItemsWhenMinimised\n : setVisibleItemsWhenMinimised,\n });\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderCheckboxIcon = (\n originalItem: T,\n flatOption: FlattenedFilterOption<T>\n ) => {\n const { checked, indeterminate } = getCheckboxState(flatOption);\n\n return (\n <Checkbox\n className={styles.checkbox}\n displaySize=\"small\"\n checked={checked}\n indeterminate={indeterminate}\n onChange={handleCheckboxChange(originalItem)}\n tabIndex={isNested ? -1 : undefined}\n aria-hidden={isNested ? \"true\" : undefined}\n />\n );\n };\n\n const renderCheckbox = (\n option: FlattenedFilterOption<T>,\n index: number,\n minimised: boolean\n ) => {\n const originalItem = option.originalItem;\n const optionLabel = getLabel(originalItem);\n const { checked, indeterminate } = getCheckboxState(option);\n const isSelected = checked || indeterminate;\n const isVisible = !minimised || index < 5;\n\n // ARIA attributes for tree items\n const treeItemAriaAttributes: AriaAttributes = isNested\n ? {\n \"aria-checked\": indeterminate ? \"mixed\" : checked,\n \"aria-selected\": !!checked,\n \"aria-level\": option.level + 1,\n \"aria-posinset\": option.indexInParent + 1,\n \"aria-setsize\": option.parentSetSize,\n }\n : {};\n\n const itemRef = (el: HTMLElement | null) => {\n if (el && option.level) {\n el.style.setProperty(\n styles.tokens.item.level,\n String(option.level)\n );\n }\n if (index === 4) {\n lastVisibleElement.current = el;\n }\n };\n\n const itemClassName = clsx(\n styles.item,\n !isVisible && styles.itemHidden,\n isSelected && styles.itemSelected\n );\n\n const itemContent = (\n <>\n {renderCheckboxIcon(originalItem, option)}\n {optionLabel}\n </>\n );\n\n if (isNested) {\n return (\n <div\n key={buildKeyPath(option.keyPath)}\n role=\"treeitem\"\n {...treeItemAriaAttributes}\n onClick={handleItemClick(originalItem)}\n onKeyDown={handleListItemKeyDown(originalItem)}\n tabIndex={0}\n className={itemClassName}\n ref={itemRef}\n >\n {itemContent}\n </div>\n );\n }\n\n return (\n <label\n key={buildKeyPath(option.keyPath)}\n onKeyDown={handleListItemKeyDown(originalItem)}\n className={itemClassName}\n ref={itemRef}\n >\n {itemContent}\n </label>\n );\n };\n\n const renderToggle = (\n option: FlattenedFilterOption<T>,\n index: number,\n minimised: boolean\n ) => {\n const originalItem = option.originalItem;\n const optionLabel = getLabel(originalItem);\n const optionValue = getValue(originalItem);\n const checked = !!selected.find((s) => getValue(s) === optionValue);\n const isToggleVisible =\n !minimised ||\n (!!minimisedHeight && index <= lastVisibleElementIndex);\n return (\n <Toggle\n key={optionValue}\n type=\"checkbox\"\n checked={checked}\n className={clsx(\n !useToggleContentWidth && styles.toggle,\n !isToggleVisible && styles.toggleHidden\n )}\n onChange={handleItemClick(originalItem)}\n useContentWidth={useToggleContentWidth}\n >\n {optionLabel}\n </Toggle>\n );\n };\n\n const renderSelectClearAllButton = () => {\n if (optionCount < 3) {\n return null;\n }\n return (\n <Button\n className={styles.selectAllButton}\n styleType=\"link\"\n type=\"button\"\n sizeType=\"small\"\n onClick={handleSelectClearAll}\n aria-label={\n selected.length\n ? \"Clear all selections\"\n : `Select all in ${\n parentRef.current?.ariaLabel || \"this group\"\n }`\n }\n >\n {selected.length ? \"Clear all\" : \"Select all\"}\n </Button>\n );\n };\n\n return (\n <FilterItem\n minimisable={\n minimisableOptions\n ? isMobileToggleMode // set minimisable base on mobile toggle mode\n ? !!minimisedHeight\n : optionCount > 5\n : false // if minimisableOptions is false, never allow minimising\n }\n minimisedHeight={minimisedHeight}\n {...filterItemProps}\n className={clsx(styles.filterItem, filterItemProps.className)}\n >\n {(_, { minimised }) => (\n <>\n {renderSelectClearAllButton()}\n <div\n role={isNested ? \"tree\" : \"group\"}\n aria-label={filterItemProps.title}\n aria-multiselectable={true}\n ref={parentRef}\n className={clsx(\n styles.group,\n isMobileToggleMode && styles.groupMobileToggleMode\n )}\n >\n {flattenedOptions.map((option, i) =>\n isMobileToggleMode\n ? renderToggle(option, i, minimised)\n : renderCheckbox(option, i, minimised)\n )}\n </div>\n </>\n )}\n </FilterItem>\n );\n};\n\nFilterItemCheckbox.displayName = \"Filter.Checkbox\";\n"],"names":["FilterItemCheckbox","_a","selectedOptions","options","showAsCheckboxInMobile","minimisableOptions","onSelect","labelExtractor","valueExtractor","useToggleContentWidth","filterItemProps","__rest","mode","useContext","FilterContext","selected","setSelected","useState","minimisedHeight","setMinimisedHeight","lastVisibleElementIndex","setLastVisibleElementIndex","length","parentRef","useRef","lastVisibleElement","isNested","useMemo","hasNestedOptions","item","isMobileToggleMode","flattenedOptions","flattenNestedOptions","value","label","optionCount","handleItemClick","flatOption","find","opt","originalItem","hasChildren","allChildren","getAllDescendantChildren","keyPath","currentlySelectedChildren","filter","child","some","s","getValue","newSelection","forEach","push","selectedIndex","findIndex","splice","handleSelectClearAll","allValues","option","map","handleListItemKeyDown","event","key","preventDefault","handleCheckboxChange","getCheckboxState","checked","indeterminate","getAllDescendantKeyPaths","buildKeyPath","selectedChildren","getLabel","toString","setVisibleItemsWhenMinimised","elementBottom","current","offsetTop","clientHeight","undefined","setVisibleMobileItemsWhenMinimised","useCallback","children","Array","from","lastElementInRow","rowCount","rowTop","i","childTop","useEffect","useResizeDetector","handleWidth","handleHeight","skipOnMount","refreshMode","targetRef","onResize","renderCheckboxIcon","_jsx","Checkbox","className","styles.checkbox","displaySize","onChange","tabIndex","renderSelectClearAllButton","Button","styles.selectAllButton","styleType","type","sizeType","onClick","ariaLabel","FilterItem","Object","assign","minimisable","clsx","styles.filterItem","_","minimised","_jsxs","_Fragment","role","title","ref","styles.group","styles.groupMobileToggleMode","index","optionLabel","optionValue","Toggle","styles.toggle","styles.toggleHidden","useContentWidth","renderToggle","isSelected","isVisible","treeItemAriaAttributes","level","indexInParent","parentSetSize","itemRef","el","style","setProperty","styles.tokens","String","itemClassName","styles.item","styles.itemHidden","styles.itemSelected","itemContent","onKeyDown","renderCheckbox","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FilterItemCheckboxOptionProps } from "./types";
|
|
2
|
+
export interface FlattenedFilterOption<T = FilterItemCheckboxOptionProps> {
|
|
3
|
+
originalItem: T;
|
|
4
|
+
value: any;
|
|
5
|
+
label: string;
|
|
6
|
+
keyPath: string[];
|
|
7
|
+
level: number;
|
|
8
|
+
hasChildren: boolean;
|
|
9
|
+
parentKeyPath?: string[] | undefined;
|
|
10
|
+
indexInParent: number;
|
|
11
|
+
parentSetSize: number;
|
|
12
|
+
}
|
package/filter/addons/types.d.ts
CHANGED
|
@@ -1,12 +1,63 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { FilterItemProps } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Default shape for a checkbox option in `Filter.Checkbox`.
|
|
4
|
+
*
|
|
5
|
+
* Nest `options` to create hierarchical groups with parent-level
|
|
6
|
+
* select/deselect all behavior.
|
|
7
|
+
*/
|
|
8
|
+
export interface FilterItemCheckboxOptionProps {
|
|
4
9
|
value: any;
|
|
5
10
|
label: string;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
/** Nested child options. Providing children makes this item a parent node. */
|
|
12
|
+
options?: FilterItemCheckboxOptionProps[] | undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Props for the `Filter.Checkbox` sub-component.
|
|
16
|
+
*
|
|
17
|
+
* Supply a generic type `T` to use a custom option shape together with
|
|
18
|
+
* `labelExtractor` and `valueExtractor`.
|
|
19
|
+
*/
|
|
20
|
+
export interface FilterItemCheckboxProps<T = FilterItemCheckboxOptionProps> extends Omit<FilterItemProps, "children"> {
|
|
21
|
+
/** The full list of selectable options. */
|
|
22
|
+
options: T[];
|
|
23
|
+
/**
|
|
24
|
+
* The currently selected options. When provided, the component syncs its
|
|
25
|
+
* internal selection state to this value.
|
|
26
|
+
*/
|
|
27
|
+
selectedOptions?: T[] | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Called when the selection changes.
|
|
30
|
+
*
|
|
31
|
+
* @param options The updated array of selected options.
|
|
32
|
+
*/
|
|
33
|
+
onSelect?: ((options: T[]) => void) | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Derives the display label from an option item.
|
|
36
|
+
* Falls back to `item.label` when not provided.
|
|
37
|
+
*/
|
|
38
|
+
labelExtractor?: ((item: T) => React.ReactNode) | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Derives the unique value key from an option item.
|
|
41
|
+
* Falls back to `item.value` when not provided.
|
|
42
|
+
*/
|
|
43
|
+
valueExtractor?: ((item: T) => string) | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* When `true`, toggle chips in mobile mode grow to fit their content width
|
|
46
|
+
* instead of stretching to a fixed minimum width.
|
|
47
|
+
*/
|
|
48
|
+
useToggleContentWidth?: boolean | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* When `true`, renders checkboxes instead of toggle chips in mobile mode.
|
|
51
|
+
* Has no effect for nested option trees, which always use checkboxes.
|
|
52
|
+
*
|
|
53
|
+
* @default false
|
|
54
|
+
*/
|
|
55
|
+
showAsCheckboxInMobile?: boolean | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* When `true`, shows a "View more / View less" button when there are more
|
|
58
|
+
* options than the minimised threshold.
|
|
59
|
+
*
|
|
60
|
+
* @default true
|
|
61
|
+
*/
|
|
62
|
+
minimisableOptions?: boolean | undefined;
|
|
12
63
|
}
|
package/filter/filter-item.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__rest as e}from"../_virtual/_tslib.js";import{jsxs as i,jsx as t}from"react/jsx-runtime";import{ChevronDownIcon as r}from"@lifesg/react-icons/chevron-down";import{useSpring as o,animated as a}from"@react-spring/web";import
|
|
1
|
+
import{__rest as e}from"../_virtual/_tslib.js";import{jsxs as i,jsx as t}from"react/jsx-runtime";import{ChevronDownIcon as r}from"@lifesg/react-icons/chevron-down";import{useSpring as o,animated as a}from"@react-spring/web";import l from"clsx";import n from"../external/lodash/isNil.js";import{useContext as s,useState as d,useRef as m,useEffect as c}from"react";import{useResizeDetector as p}from"../external/react-resize-detector/build/index.esm.js";import{Button as h}from"../button/button.js";import{PopoverAddon as f}from"../form/form-label/form-label-addon.js";import{VisuallyHidden as u,inertValue as b}from"../shared/accessibility/index.js";import{ClickableIcon as j}from"../shared/clickable-icon/clickable-icon.js";import"../theme/theme-provider/index.js";import"../theme/theme-provider/context.js";import"../theme/tokens/border.js";import"../theme/tokens/colour.js";import"../theme/tokens/font.js";import"../theme/tokens/media-query.js";import{useApplyStyle as v}from"../theme/utils/use-apply-styles.js";import"../theme/utils/use-media-query.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as x}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{FilterContext as y}from"./filter-context.js";import{tokens as g,divider as N,dividerVisible as k,dividerMobile as w,filterItemTitle as C,filterItemTitleMobile as $,filterItemExpandButton as D,chevronIcon as E,chevronIconExpanded as H,filterItemHeader as M,filterItemHeaderMobile as q,expandableItem as z,filterItemBody as O,minimisableContent as T,minimisableContentMinimisable as _,filterItemMinimiseButton as F,filterItemWrapper as I,filterItemWrapperDarker as V}from"./filter-item.styles.js";const A=A=>{var B,{collapsible:G=!0,initialExpanded:J=!1,expanded:K,onExpandChange:L,minimisable:P=!1,minimisedHeight:Q,showDivider:R=!0,showMobileDivider:S=!0,title:U,addon:W,children:X,className:Y}=A,Z=e(A,["collapsible","initialExpanded","expanded","onExpandChange","minimisable","minimisedHeight","showDivider","showMobileDivider","title","addon","children","className"]);const{mode:ee,rootNode:ie}=s(y),te="mobile"===ee,[re,oe]=d(be()),[ae,le]=d(P),ne=!te&&G,se=p(),de=p(),me=o({height:re?se.height:0}),ce=ae?null!=Q?Q:Math.min(.5*(null!==(B=de.height)&&void 0!==B?B:0),216):de.height,pe=x(),he=`${pe}-content`,fe=`${pe}-title`,ue=m(null);v(ue,{[g.minimisableContent.height]:ce?`${ce}px`:null}),c((()=>{oe(be())}),[G,K]),c((()=>{le(P)}),[P]);function be(){return!!te||(n(K)?!G||J:K)}return i("div",{"aria-labelledby":fe,className:l(I,(ne||te)&&V),children:[t("div",{className:l(N,(te?S:R)&&k,te&&w)}),(U||ne)&&i("div",{className:l(M,te&&q),children:[U&&i("h3",{id:fe,"data-testid":"filter-item-title",className:l(C,te&&$),children:[U," ",W&&("popover"===(null==W?void 0:W.type)?t(f,{addon:W,rootNode:te?ie:void 0}):null)]}),ne&&i(j,{className:D,"data-testid":"expand-collapse-button",focusHighlight:!1,focusOutline:"browser",onClick:()=>{const e=!re;n(K)&&oe(e),L&&L(e)},"aria-expanded":re,"aria-disabled":!ne,"aria-controls":he,children:[U&&t(u,{children:U}),t(r,{"aria-hidden":!0,className:l(E,re&&H)})]})]}),t(a.div,{className:z,id:he,"data-testid":"expandable-container","data-expanded":re,style:me,inert:b(!re),children:t("div",{ref:se.ref,children:i("div",Object.assign({className:l(O,Y)},Z,{children:[t("div",{ref:ue,"data-testid":"minimisable-container",className:l(T,P&&_),children:t("div",{ref:de.ref,children:t("div",{"data-id":"content-container",children:"function"==typeof X?X(ee,{minimised:ae}):X})})}),P&&i(h,{className:F,"data-id":"minimise-button",sizeType:"small",styleType:"link",type:"button",onClick:()=>{le(!ae)},children:[t(u,{children:`view ${ae?"more":"less"} in ${U}`}),i("span",{"aria-hidden":!0,children:["View ",ae?"more":"less"]})]})]}))})})]})};A.displayName="Filter.Item";export{A as FilterItem};
|
|
2
2
|
//# sourceMappingURL=filter-item.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-item.js","sources":["../../src/filter/filter-item.tsx"],"sourcesContent":["import { ChevronDownIcon } from \"@lifesg/react-icons/chevron-down\";\nimport { animated, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport isNil from \"lodash/isNil\";\nimport { useContext, useEffect, useRef, useState } from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { Button } from \"../button\";\nimport { PopoverAddon } from \"../form/form-label-addon\";\nimport { inertValue, VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { useApplyStyle } from \"../theme\";\nimport { useId } from \"../util\";\nimport { FilterContext } from \"./filter-context\";\nimport * as styles from \"./filter-item.styles\";\nimport type { FilterItemProps } from \"./types\";\n\nconst DEFAULT_MINIMISED_HEIGHT_CAP = 216;\n\nexport const FilterItem = ({\n collapsible: desktopCollapsible = true,\n initialExpanded = false,\n expanded: controlledExpanded,\n onExpandChange,\n minimisable = false,\n minimisedHeight,\n showDivider = true,\n showMobileDivider = true,\n title,\n addon,\n children,\n className,\n ...otherProps\n}: FilterItemProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const { mode, rootNode } = useContext(FilterContext);\n const isMobile = mode === \"mobile\";\n const [expanded, setExpanded] = useState(getInitialExpandState());\n const [contentMinimised, setContentMinimised] = useState(minimisable);\n const collapsible = !isMobile && desktopCollapsible;\n\n const itemResizeDetector = useResizeDetector();\n const contentResizeDetector = useResizeDetector();\n const itemAnimationStyles = useSpring({\n height: expanded ? itemResizeDetector.height : 0,\n });\n const contentHeight = contentMinimised\n ? minimisedHeight ??\n Math.min(\n (contentResizeDetector.height ?? 0) * 0.5,\n DEFAULT_MINIMISED_HEIGHT_CAP\n )\n : contentResizeDetector.height;\n const internalId = useId();\n const contentId = `${internalId}-content`;\n const titleId = `${internalId}-title`;\n const minimisableContentRef = useRef<HTMLDivElement | null>(null);\n\n useApplyStyle(minimisableContentRef, {\n [styles.tokens.minimisableContent.height]: contentHeight\n ? `${contentHeight}px`\n : null,\n });\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setExpanded(getInitialExpandState());\n }, [desktopCollapsible, controlledExpanded]);\n\n useEffect(() => {\n setContentMinimised(minimisable);\n }, [minimisable]);\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleExpandCollapse = () => {\n const nextState = !expanded;\n\n if (isNil(controlledExpanded)) {\n setExpanded(nextState);\n }\n\n if (onExpandChange) {\n onExpandChange(nextState);\n }\n };\n\n const handleMinimise = () => {\n setContentMinimised(!contentMinimised);\n };\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n function getInitialExpandState() {\n if (isMobile) {\n return true;\n }\n if (isNil(controlledExpanded)) {\n return !desktopCollapsible || initialExpanded;\n }\n return controlledExpanded;\n }\n\n // =============================================================================\n // RENDER\n // =============================================================================\n\n const renderAddon = () => {\n switch (addon?.type) {\n case \"popover\":\n return (\n <PopoverAddon\n addon={addon}\n rootNode={isMobile ? rootNode : undefined}\n />\n );\n default:\n return null;\n }\n };\n\n return (\n <div\n aria-labelledby={titleId}\n className={clsx(\n styles.filterItemWrapper,\n (collapsible || isMobile) && styles.filterItemWrapperDarker\n )}\n >\n <div\n className={clsx(\n styles.divider,\n (isMobile ? showMobileDivider : showDivider) &&\n styles.dividerVisible,\n isMobile && styles.dividerMobile\n )}\n />\n {(title || collapsible) && (\n <div\n className={clsx(\n styles.filterItemHeader,\n isMobile && styles.filterItemHeaderMobile\n )}\n >\n {title && (\n <h3\n id={titleId}\n data-testid=\"filter-item-title\"\n className={clsx(\n styles.filterItemTitle,\n isMobile && styles.filterItemTitleMobile\n )}\n >\n {title} {addon && renderAddon()}\n </h3>\n )}\n {collapsible && (\n <ClickableIcon\n className={styles.filterItemExpandButton}\n data-testid={\"expand-collapse-button\"}\n focusHighlight={false}\n focusOutline=\"browser\"\n onClick={handleExpandCollapse}\n aria-expanded={expanded}\n aria-disabled={!collapsible}\n aria-controls={contentId}\n >\n {title && <VisuallyHidden>{title}</VisuallyHidden>}\n <ChevronDownIcon\n aria-hidden\n className={clsx(\n styles.chevronIcon,\n expanded && styles.chevronIconExpanded\n )}\n />\n </ClickableIcon>\n )}\n </div>\n )}\n <animated.div\n className={styles.expandableItem}\n id={contentId}\n data-testid={\"expandable-container\"}\n data-expanded={expanded}\n style={itemAnimationStyles}\n inert={inertValue(!expanded)}\n >\n <div ref={itemResizeDetector.ref}>\n <div\n className={clsx(styles.filterItemBody, className)}\n {...otherProps}\n >\n <div\n ref={minimisableContentRef}\n data-testid=\"minimisable-container\"\n className={clsx(\n styles.minimisableContent,\n minimisable &&\n styles.minimisableContentMinimisable\n )}\n >\n <div ref={contentResizeDetector.ref}>\n <div data-id=\"content-container\">\n {typeof children === \"function\"\n ? children(mode, {\n minimised: contentMinimised,\n })\n : children}\n </div>\n </div>\n </div>\n {minimisable && (\n <Button\n className={styles.filterItemMinimiseButton}\n data-id=\"minimise-button\"\n sizeType=\"small\"\n styleType=\"link\"\n type=\"button\"\n onClick={handleMinimise}\n >\n <VisuallyHidden>{`view ${\n contentMinimised ? \"more\" : \"less\"\n } in ${title}`}</VisuallyHidden>\n <span aria-hidden>\n View {contentMinimised ? \"more\" : \"less\"}\n </span>\n </Button>\n )}\n </div>\n </div>\n </animated.div>\n </div>\n );\n};\n\nFilterItem.displayName = \"Filter.Item\";\n"],"names":["FilterItem","_a","collapsible","desktopCollapsible","initialExpanded","expanded","controlledExpanded","onExpandChange","minimisable","minimisedHeight","showDivider","showMobileDivider","title","addon","children","className","otherProps","__rest","mode","rootNode","useContext","FilterContext","isMobile","setExpanded","useState","getInitialExpandState","contentMinimised","setContentMinimised","itemResizeDetector","useResizeDetector","contentResizeDetector","itemAnimationStyles","useSpring","height","contentHeight","Math","min","_b","internalId","useId","contentId","titleId","minimisableContentRef","useRef","useApplyStyle","styles.tokens","minimisableContent","useEffect","isNil","_jsxs","clsx","styles.filterItemWrapper","styles.filterItemWrapperDarker","_jsx","styles.divider","styles.dividerVisible","styles.dividerMobile","styles.filterItemHeader","styles.filterItemHeaderMobile","id","styles.filterItemTitle","styles.filterItemTitleMobile","type","PopoverAddon","undefined","ClickableIcon","styles.filterItemExpandButton","focusHighlight","focusOutline","onClick","nextState","VisuallyHidden","ChevronDownIcon","styles.chevronIcon","styles.chevronIconExpanded","animated","div","styles.expandableItem","style","inert","inertValue","ref","Object","assign","styles.filterItemBody","styles.minimisableContent","styles.minimisableContentMinimisable","minimised","Button","styles.filterItemMinimiseButton","sizeType","styleType","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filter-item.js","sources":["../../src/filter/filter-item.tsx"],"sourcesContent":["import { ChevronDownIcon } from \"@lifesg/react-icons/chevron-down\";\nimport { animated, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport isNil from \"lodash/isNil\";\nimport { useContext, useEffect, useRef, useState } from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { Button } from \"../button\";\nimport { PopoverAddon } from \"../form/form-label/form-label-addon\";\nimport { inertValue, VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { useApplyStyle } from \"../theme\";\nimport { useId } from \"../util\";\nimport { FilterContext } from \"./filter-context\";\nimport * as styles from \"./filter-item.styles\";\nimport type { FilterItemProps } from \"./types\";\n\nconst DEFAULT_MINIMISED_HEIGHT_CAP = 216;\n\nexport const FilterItem = ({\n collapsible: desktopCollapsible = true,\n initialExpanded = false,\n expanded: controlledExpanded,\n onExpandChange,\n minimisable = false,\n minimisedHeight,\n showDivider = true,\n showMobileDivider = true,\n title,\n addon,\n children,\n className,\n ...otherProps\n}: FilterItemProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const { mode, rootNode } = useContext(FilterContext);\n const isMobile = mode === \"mobile\";\n const [expanded, setExpanded] = useState(getInitialExpandState());\n const [contentMinimised, setContentMinimised] = useState(minimisable);\n const collapsible = !isMobile && desktopCollapsible;\n\n const itemResizeDetector = useResizeDetector();\n const contentResizeDetector = useResizeDetector();\n const itemAnimationStyles = useSpring({\n height: expanded ? itemResizeDetector.height : 0,\n });\n const contentHeight = contentMinimised\n ? minimisedHeight ??\n Math.min(\n (contentResizeDetector.height ?? 0) * 0.5,\n DEFAULT_MINIMISED_HEIGHT_CAP\n )\n : contentResizeDetector.height;\n const internalId = useId();\n const contentId = `${internalId}-content`;\n const titleId = `${internalId}-title`;\n const minimisableContentRef = useRef<HTMLDivElement | null>(null);\n\n useApplyStyle(minimisableContentRef, {\n [styles.tokens.minimisableContent.height]: contentHeight\n ? `${contentHeight}px`\n : null,\n });\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setExpanded(getInitialExpandState());\n }, [desktopCollapsible, controlledExpanded]);\n\n useEffect(() => {\n setContentMinimised(minimisable);\n }, [minimisable]);\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleExpandCollapse = () => {\n const nextState = !expanded;\n\n if (isNil(controlledExpanded)) {\n setExpanded(nextState);\n }\n\n if (onExpandChange) {\n onExpandChange(nextState);\n }\n };\n\n const handleMinimise = () => {\n setContentMinimised(!contentMinimised);\n };\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n function getInitialExpandState() {\n if (isMobile) {\n return true;\n }\n if (isNil(controlledExpanded)) {\n return !desktopCollapsible || initialExpanded;\n }\n return controlledExpanded;\n }\n\n // =============================================================================\n // RENDER\n // =============================================================================\n\n const renderAddon = () => {\n switch (addon?.type) {\n case \"popover\":\n return (\n <PopoverAddon\n addon={addon}\n rootNode={isMobile ? rootNode : undefined}\n />\n );\n default:\n return null;\n }\n };\n\n return (\n <div\n aria-labelledby={titleId}\n className={clsx(\n styles.filterItemWrapper,\n (collapsible || isMobile) && styles.filterItemWrapperDarker\n )}\n >\n <div\n className={clsx(\n styles.divider,\n (isMobile ? showMobileDivider : showDivider) &&\n styles.dividerVisible,\n isMobile && styles.dividerMobile\n )}\n />\n {(title || collapsible) && (\n <div\n className={clsx(\n styles.filterItemHeader,\n isMobile && styles.filterItemHeaderMobile\n )}\n >\n {title && (\n <h3\n id={titleId}\n data-testid=\"filter-item-title\"\n className={clsx(\n styles.filterItemTitle,\n isMobile && styles.filterItemTitleMobile\n )}\n >\n {title} {addon && renderAddon()}\n </h3>\n )}\n {collapsible && (\n <ClickableIcon\n className={styles.filterItemExpandButton}\n data-testid={\"expand-collapse-button\"}\n focusHighlight={false}\n focusOutline=\"browser\"\n onClick={handleExpandCollapse}\n aria-expanded={expanded}\n aria-disabled={!collapsible}\n aria-controls={contentId}\n >\n {title && <VisuallyHidden>{title}</VisuallyHidden>}\n <ChevronDownIcon\n aria-hidden\n className={clsx(\n styles.chevronIcon,\n expanded && styles.chevronIconExpanded\n )}\n />\n </ClickableIcon>\n )}\n </div>\n )}\n <animated.div\n className={styles.expandableItem}\n id={contentId}\n data-testid={\"expandable-container\"}\n data-expanded={expanded}\n style={itemAnimationStyles}\n inert={inertValue(!expanded)}\n >\n <div ref={itemResizeDetector.ref}>\n <div\n className={clsx(styles.filterItemBody, className)}\n {...otherProps}\n >\n <div\n ref={minimisableContentRef}\n data-testid=\"minimisable-container\"\n className={clsx(\n styles.minimisableContent,\n minimisable &&\n styles.minimisableContentMinimisable\n )}\n >\n <div ref={contentResizeDetector.ref}>\n <div data-id=\"content-container\">\n {typeof children === \"function\"\n ? children(mode, {\n minimised: contentMinimised,\n })\n : children}\n </div>\n </div>\n </div>\n {minimisable && (\n <Button\n className={styles.filterItemMinimiseButton}\n data-id=\"minimise-button\"\n sizeType=\"small\"\n styleType=\"link\"\n type=\"button\"\n onClick={handleMinimise}\n >\n <VisuallyHidden>{`view ${\n contentMinimised ? \"more\" : \"less\"\n } in ${title}`}</VisuallyHidden>\n <span aria-hidden>\n View {contentMinimised ? \"more\" : \"less\"}\n </span>\n </Button>\n )}\n </div>\n </div>\n </animated.div>\n </div>\n );\n};\n\nFilterItem.displayName = \"Filter.Item\";\n"],"names":["FilterItem","_a","collapsible","desktopCollapsible","initialExpanded","expanded","controlledExpanded","onExpandChange","minimisable","minimisedHeight","showDivider","showMobileDivider","title","addon","children","className","otherProps","__rest","mode","rootNode","useContext","FilterContext","isMobile","setExpanded","useState","getInitialExpandState","contentMinimised","setContentMinimised","itemResizeDetector","useResizeDetector","contentResizeDetector","itemAnimationStyles","useSpring","height","contentHeight","Math","min","_b","internalId","useId","contentId","titleId","minimisableContentRef","useRef","useApplyStyle","styles.tokens","minimisableContent","useEffect","isNil","_jsxs","clsx","styles.filterItemWrapper","styles.filterItemWrapperDarker","_jsx","styles.divider","styles.dividerVisible","styles.dividerMobile","styles.filterItemHeader","styles.filterItemHeaderMobile","id","styles.filterItemTitle","styles.filterItemTitleMobile","type","PopoverAddon","undefined","ClickableIcon","styles.filterItemExpandButton","focusHighlight","focusOutline","onClick","nextState","VisuallyHidden","ChevronDownIcon","styles.chevronIcon","styles.chevronIconExpanded","animated","div","styles.expandableItem","style","inert","inertValue","ref","Object","assign","styles.filterItemBody","styles.minimisableContent","styles.minimisableContentMinimisable","minimised","Button","styles.filterItemMinimiseButton","sizeType","styleType","displayName"],"mappings":"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"}
|
package/filter/filter.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export declare const Filter: {
|
|
|
39
39
|
};
|
|
40
40
|
/** A filter item that renders selectable checkboxes (desktop) or toggle chips (mobile). */
|
|
41
41
|
Checkbox: {
|
|
42
|
-
<T = import("
|
|
42
|
+
<T = import(".").FilterItemCheckboxOptionProps>({ selectedOptions, options, showAsCheckboxInMobile, minimisableOptions, onSelect, labelExtractor, valueExtractor, useToggleContentWidth, ...filterItemProps }: import(".").FilterItemCheckboxProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
43
43
|
displayName: string;
|
|
44
44
|
};
|
|
45
45
|
};
|
package/filter/filter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sources":["../../src/filter/filter.tsx"],"sourcesContent":["import { useEffect } from \"react\";\n\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport { FilterItemCheckbox } from \"./addons/filter-item-checkbox\";\nimport { FilterItem } from \"./filter-item\";\nimport { FilterItemPage } from \"./filter-item-page\";\nimport { FilterModal } from \"./filter-modal\";\nimport { FilterSidebar } from \"./filter-sidebar\";\nimport type { FilterProps } from \"./types\";\n\n/**\n * A responsive filter panel that switches between a persistent sidebar on\n * desktop and a modal overlay on mobile.\n *\n * Use `Filter` to let users narrow a result set by one or more criteria.\n * On mobile (below lg breakpoint) the panel is hidden behind a toggle button and\n * rendered in a full-screen modal; otherwise it is displayed as a\n * fixed sidebar.\n *\n * Sub-components:\n * - `Filter.Sidebar` — standalone desktop sidebar, used by `Filter` internally.\n * - `Filter.Modal` — standalone mobile modal, used by `Filter` internally.\n * - `Filter.Item` — a collapsible section within the panel.\n * - `Filter.Page` — a drill-down sub-page inside the mobile modal.\n * - `Filter.Checkbox` — a filter item with selectable checkbox or toggle options.\n */\nexport const Filter = ({\n children,\n className,\n style,\n onDismiss,\n onDone,\n onModalOpen,\n toggleFilterButtonStyle,\n insets,\n id,\n \"data-testid\": testId,\n ...props\n}: FilterProps) => {\n const isMobile = useMaxWidthMediaQuery(\"lg\");\n\n useEffect(() => {\n if (!isMobile) {\n onDismiss?.();\n }\n }, [isMobile]);\n\n return (\n <div className={className} style={style} id={id} data-testid={testId}>\n {isMobile ? (\n <FilterModal\n onDismiss={onDismiss}\n onDone={onDone}\n onModalOpen={onModalOpen}\n toggleFilterButtonStyle={toggleFilterButtonStyle}\n insets={insets}\n {...props}\n >\n {typeof children === \"function\"\n ? children(\"mobile\")\n : children}\n </FilterModal>\n ) : (\n <FilterSidebar {...props}>\n {typeof children === \"function\"\n ? children(\"default\")\n : children}\n </FilterSidebar>\n )}\n </div>\n );\n};\n\n/** Standalone desktop sidebar variant of the filter panel. */\nFilter.Sidebar = FilterSidebar;\n/** Standalone mobile modal variant of the filter panel. */\nFilter.Modal = FilterModal;\n/** A collapsible section within a filter panel. */\nFilter.Item = FilterItem;\n/** A full-screen sub-page overlay for drill-down selection in the mobile modal. */\nFilter.Page = FilterItemPage;\n/** A filter item that renders selectable checkboxes (desktop) or toggle chips (mobile). */\nFilter.Checkbox = FilterItemCheckbox;\n"],"names":["Filter","_a","children","className","style","onDismiss","onDone","onModalOpen","toggleFilterButtonStyle","insets","id","testId","props","__rest","isMobile","useMaxWidthMediaQuery","useEffect","_jsx","FilterModal","Object","assign","FilterSidebar","Sidebar","Modal","Item","FilterItem","Page","FilterItemPage","Checkbox","FilterItemCheckbox"],"mappings":"
|
|
1
|
+
{"version":3,"file":"filter.js","sources":["../../src/filter/filter.tsx"],"sourcesContent":["import { useEffect } from \"react\";\n\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport { FilterItemCheckbox } from \"./addons/filter-item-checkbox\";\nimport { FilterItem } from \"./filter-item\";\nimport { FilterItemPage } from \"./filter-item-page\";\nimport { FilterModal } from \"./filter-modal\";\nimport { FilterSidebar } from \"./filter-sidebar\";\nimport type { FilterProps } from \"./types\";\n\n// @catalog\n/**\n * A responsive filter panel that switches between a persistent sidebar on\n * desktop and a modal overlay on mobile.\n *\n * Use `Filter` to let users narrow a result set by one or more criteria.\n * On mobile (below lg breakpoint) the panel is hidden behind a toggle button and\n * rendered in a full-screen modal; otherwise it is displayed as a\n * fixed sidebar.\n *\n * Sub-components:\n * - `Filter.Sidebar` — standalone desktop sidebar, used by `Filter` internally.\n * - `Filter.Modal` — standalone mobile modal, used by `Filter` internally.\n * - `Filter.Item` — a collapsible section within the panel.\n * - `Filter.Page` — a drill-down sub-page inside the mobile modal.\n * - `Filter.Checkbox` — a filter item with selectable checkbox or toggle options.\n */\nexport const Filter = ({\n children,\n className,\n style,\n onDismiss,\n onDone,\n onModalOpen,\n toggleFilterButtonStyle,\n insets,\n id,\n \"data-testid\": testId,\n ...props\n}: FilterProps) => {\n const isMobile = useMaxWidthMediaQuery(\"lg\");\n\n useEffect(() => {\n if (!isMobile) {\n onDismiss?.();\n }\n }, [isMobile]);\n\n return (\n <div className={className} style={style} id={id} data-testid={testId}>\n {isMobile ? (\n <FilterModal\n onDismiss={onDismiss}\n onDone={onDone}\n onModalOpen={onModalOpen}\n toggleFilterButtonStyle={toggleFilterButtonStyle}\n insets={insets}\n {...props}\n >\n {typeof children === \"function\"\n ? children(\"mobile\")\n : children}\n </FilterModal>\n ) : (\n <FilterSidebar {...props}>\n {typeof children === \"function\"\n ? children(\"default\")\n : children}\n </FilterSidebar>\n )}\n </div>\n );\n};\n\n/** Standalone desktop sidebar variant of the filter panel. */\nFilter.Sidebar = FilterSidebar;\n/** Standalone mobile modal variant of the filter panel. */\nFilter.Modal = FilterModal;\n/** A collapsible section within a filter panel. */\nFilter.Item = FilterItem;\n/** A full-screen sub-page overlay for drill-down selection in the mobile modal. */\nFilter.Page = FilterItemPage;\n/** A filter item that renders selectable checkboxes (desktop) or toggle chips (mobile). */\nFilter.Checkbox = FilterItemCheckbox;\n"],"names":["Filter","_a","children","className","style","onDismiss","onDone","onModalOpen","toggleFilterButtonStyle","insets","id","testId","props","__rest","isMobile","useMaxWidthMediaQuery","useEffect","_jsx","FilterModal","Object","assign","FilterSidebar","Sidebar","Modal","Item","FilterItem","Page","FilterItemPage","Checkbox","FilterItemCheckbox"],"mappings":"s2BA2BO,MAAMA,EAAUC,QAAAC,SACnBA,EAAQC,UACRA,EAASC,MACTA,EAAKC,UACLA,EAASC,OACTA,EAAMC,YACNA,EAAWC,wBACXA,EAAuBC,OACvBA,EAAMC,GACNA,EACA,cAAeC,GAAMV,EAClBW,EAAKC,EAAAZ,EAXW,CAAA,WAAA,YAAA,QAAA,YAAA,SAAA,cAAA,0BAAA,SAAA,KAAA,gBAanB,MAAMa,EAAWC,EAAsB,MAQvC,OANAC,GAAU,KACDF,GACDT,SAAAA,GACJ,GACD,CAACS,IAGAG,SAAKd,UAAWA,EAAWC,MAAOA,EAAOM,GAAIA,EAAE,cAAeC,EAAMT,SAC/DY,EACGG,EAACC,EAAWC,OAAAC,OAAA,CACRf,UAAWA,EACXC,OAAQA,EACRC,YAAaA,EACbC,wBAAyBA,EACzBC,OAAQA,GACJG,EAAK,CAAAV,SAEY,mBAAbA,EACFA,EAAS,UACTA,KAGVe,EAACI,mBAAkBT,EAAK,CAAAV,SACC,mBAAbA,EACFA,EAAS,WACTA,MAGZ,EAKdF,EAAOsB,QAAUD,EAEjBrB,EAAOuB,MAAQL,EAEflB,EAAOwB,KAAOC,EAEdzB,EAAO0B,KAAOC,EAEd3B,EAAO4B,SAAWC"}
|
package/filter/index.d.ts
CHANGED