@lifesg/react-design-system 4.0.0-alpha.12 → 4.0.0-alpha.14
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/breadcrumb/breadcrumb.js +1 -1
- package/breadcrumb/breadcrumb.js.map +1 -1
- package/breadcrumb/breadcrumb.styles.d.ts +0 -8
- package/breadcrumb/breadcrumb.styles.js +1 -1
- package/breadcrumb/breadcrumb.styles.js.map +1 -1
- package/breadcrumb/breadcrumb.styles_1blzn8n.css +7 -0
- package/breadcrumb/types.d.ts +2 -13
- package/cjs/breadcrumb/breadcrumb.js +1 -1
- package/cjs/breadcrumb/breadcrumb.js.map +1 -1
- package/cjs/breadcrumb/breadcrumb.styles.js +1 -1
- package/cjs/breadcrumb/breadcrumb.styles.js.map +1 -1
- package/cjs/breadcrumb/breadcrumb.styles_1blzn8n.css +7 -0
- package/cjs/drawer/drawer.js +1 -1
- package/cjs/drawer/drawer.js.map +1 -1
- package/cjs/drawer/drawer.styles.js +1 -1
- package/cjs/drawer/drawer.styles.js.map +1 -1
- package/{drawer/drawer.styles_94hx3y.css → cjs/drawer/drawer.styles_a4bwe0.css} +6 -3
- package/cjs/external/dompurify/dist/purify.es.js +4 -2
- package/cjs/external/dompurify/dist/purify.es.js.map +1 -1
- package/cjs/file-upload/file-list/file-list.js +1 -1
- package/cjs/file-upload/file-list/file-list.js.map +1 -1
- package/cjs/file-upload/file-list/file-list.styles.js +1 -1
- package/cjs/file-upload/file-list/file-list.styles.js.map +1 -1
- package/cjs/file-upload/file-list/file-list.styles_1xbypnh.css +2 -0
- package/cjs/file-upload/file-list-item/file-item-actions.js +2 -0
- package/cjs/file-upload/file-list-item/file-item-actions.js.map +1 -0
- package/cjs/file-upload/file-list-item/file-item-actions.styles.js +2 -0
- package/cjs/file-upload/file-list-item/file-item-actions.styles.js.map +1 -0
- package/cjs/file-upload/file-list-item/file-item-actions.styles_1quulgy.css +8 -0
- package/cjs/file-upload/file-list-item/file-item-details.js +2 -0
- package/cjs/file-upload/file-list-item/file-item-details.js.map +1 -0
- package/cjs/file-upload/file-list-item/file-item-details.styles.js +2 -0
- package/cjs/file-upload/file-list-item/file-item-details.styles.js.map +1 -0
- package/cjs/file-upload/file-list-item/file-item-details.styles_1ce9akx.css +7 -0
- package/cjs/file-upload/file-list-item/file-list-item.js +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_x3a500.css +10 -0
- package/cjs/file-upload/file-list-item/use-truncated-name.js +2 -0
- package/cjs/file-upload/file-list-item/use-truncated-name.js.map +1 -0
- package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.js +1 -1
- package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
- package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.styles.js +1 -1
- package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.styles.js.map +1 -1
- package/{local-nav/local-nav-dropdown/local-nav-dropdown.styles_uhd4xl.css → cjs/local-nav/local-nav-dropdown/local-nav-dropdown.styles_kpel1m.css} +9 -6
- package/cjs/local-nav/local-nav-menu/local-nav-menu.js +1 -1
- package/cjs/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
- package/cjs/local-nav/local-nav-menu/local-nav-menu.styles.js +1 -1
- package/cjs/local-nav/local-nav-menu/local-nav-menu.styles.js.map +1 -1
- package/cjs/local-nav/local-nav-menu/local-nav-menu.styles_67fcyc.css +8 -0
- package/cjs/menu/menu-content.js +1 -1
- package/cjs/menu/menu-content.js.map +1 -1
- package/cjs/menu/menu-content.styles.js +1 -1
- package/cjs/menu/menu-content.styles.js.map +1 -1
- package/cjs/menu/menu-content.styles_1r8oxtk.css +5 -0
- package/cjs/menu/menu-item.styles.js +1 -1
- package/cjs/menu/menu-item.styles.js.map +1 -1
- package/cjs/menu/{menu-item.styles_liyed8.css → menu-item.styles_eut2j9.css} +1 -1
- package/cjs/menu/menu-link.styles.js +1 -1
- package/cjs/menu/menu-link.styles.js.map +1 -1
- package/cjs/menu/menu-link.styles_rng7n7.css +2 -0
- package/cjs/menu/menu-section.js +1 -1
- package/cjs/menu/menu-section.js.map +1 -1
- package/cjs/menu/menu-section.styles.js +1 -1
- package/cjs/menu/menu-section.styles.js.map +1 -1
- package/cjs/menu/menu-section.styles_1n0ppxl.css +5 -0
- package/cjs/modal-v2/slots/slot-styles.js +1 -1
- package/cjs/modal-v2/slots/slot-styles.js.map +1 -1
- package/cjs/modal-v2/slots/{slot-styles_ayb9il.css → slot-styles_ygu6zc.css} +1 -1
- package/cjs/navbar/navbar-items.js +1 -1
- package/cjs/navbar/navbar-items.js.map +1 -1
- package/cjs/notification-banner/notification-banner-hoc.js +1 -1
- package/cjs/notification-banner/notification-banner-hoc.js.map +1 -1
- package/cjs/pagination/pagination.js +1 -1
- package/cjs/pagination/pagination.js.map +1 -1
- package/cjs/shared/dropdown-list/dropdown-label.js +1 -1
- package/cjs/shared/dropdown-list/dropdown-label.js.map +1 -1
- package/cjs/shared/fade-wrapper/fade-wrapper.js +1 -1
- package/cjs/shared/fade-wrapper/fade-wrapper.js.map +1 -1
- package/cjs/theme/tokens/colour.js +1 -1
- package/cjs/theme/tokens/colour.js.map +1 -1
- package/cjs/theme/tokens/radius.js +1 -1
- package/cjs/theme/tokens/radius.js.map +1 -1
- package/codemods/run-codemod.js +8 -2
- package/codemods/run-codemod.js.map +1 -1
- package/codemods/run-codemod.ts +13 -4
- package/drawer/drawer.d.ts +1 -1
- package/drawer/drawer.js +1 -1
- package/drawer/drawer.js.map +1 -1
- package/drawer/drawer.styles.d.ts +3 -0
- package/drawer/drawer.styles.js +1 -1
- package/drawer/drawer.styles.js.map +1 -1
- package/{cjs/drawer/drawer.styles_94hx3y.css → drawer/drawer.styles_a4bwe0.css} +6 -3
- package/drawer/types.d.ts +7 -0
- package/external/dompurify/dist/purify.es.js +4 -2
- package/external/dompurify/dist/purify.es.js.map +1 -1
- package/file-upload/file-list/file-list.js +1 -1
- package/file-upload/file-list/file-list.js.map +1 -1
- package/file-upload/file-list/file-list.styles.d.ts +0 -1
- package/file-upload/file-list/file-list.styles.js +1 -1
- package/file-upload/file-list/file-list.styles.js.map +1 -1
- package/file-upload/file-list/file-list.styles_1xbypnh.css +2 -0
- package/file-upload/file-list-item/file-item-actions.d.ts +30 -0
- package/file-upload/file-list-item/file-item-actions.js +2 -0
- package/file-upload/file-list-item/file-item-actions.js.map +1 -0
- package/file-upload/file-list-item/file-item-actions.styles.d.ts +6 -0
- package/file-upload/file-list-item/file-item-actions.styles.js +2 -0
- package/file-upload/file-list-item/file-item-actions.styles.js.map +1 -0
- package/file-upload/file-list-item/file-item-actions.styles_1quulgy.css +8 -0
- package/file-upload/file-list-item/file-item-details.d.ts +15 -0
- package/file-upload/file-list-item/file-item-details.js +2 -0
- package/file-upload/file-list-item/file-item-details.js.map +1 -0
- package/file-upload/file-list-item/file-item-details.styles.d.ts +7 -0
- package/file-upload/file-list-item/file-item-details.styles.js +2 -0
- package/file-upload/file-list-item/file-item-details.styles.js.map +1 -0
- package/file-upload/file-list-item/file-item-details.styles_1ce9akx.css +7 -0
- package/file-upload/file-list-item/file-list-item.d.ts +1 -7
- package/file-upload/file-list-item/file-list-item.js +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.d.ts +6 -13
- 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_x3a500.css +10 -0
- package/file-upload/file-list-item/types.d.ts +10 -3
- package/file-upload/file-list-item/use-truncated-name.d.ts +1 -0
- package/file-upload/file-list-item/use-truncated-name.js +2 -0
- package/file-upload/file-list-item/use-truncated-name.js.map +1 -0
- package/input-group/types.d.ts +4 -1
- package/input-select/types.d.ts +1 -0
- package/local-nav/local-nav-dropdown/local-nav-dropdown.js +1 -1
- package/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
- package/local-nav/local-nav-dropdown/local-nav-dropdown.styles.d.ts +3 -0
- package/local-nav/local-nav-dropdown/local-nav-dropdown.styles.js +1 -1
- package/local-nav/local-nav-dropdown/local-nav-dropdown.styles.js.map +1 -1
- package/{cjs/local-nav/local-nav-dropdown/local-nav-dropdown.styles_uhd4xl.css → local-nav/local-nav-dropdown/local-nav-dropdown.styles_kpel1m.css} +9 -6
- package/local-nav/local-nav-menu/local-nav-menu.js +1 -1
- package/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
- package/local-nav/local-nav-menu/local-nav-menu.styles.d.ts +3 -0
- package/local-nav/local-nav-menu/local-nav-menu.styles.js +1 -1
- package/local-nav/local-nav-menu/local-nav-menu.styles.js.map +1 -1
- package/local-nav/local-nav-menu/local-nav-menu.styles_67fcyc.css +8 -0
- package/local-nav/types.d.ts +17 -0
- package/masked-input/types.d.ts +1 -2
- package/menu/menu-content.js +1 -1
- package/menu/menu-content.js.map +1 -1
- package/menu/menu-content.styles.d.ts +1 -0
- package/menu/menu-content.styles.js +1 -1
- package/menu/menu-content.styles.js.map +1 -1
- package/menu/menu-content.styles_1r8oxtk.css +5 -0
- package/menu/menu-item.styles.js +1 -1
- package/menu/menu-item.styles.js.map +1 -1
- package/menu/{menu-item.styles_liyed8.css → menu-item.styles_eut2j9.css} +1 -1
- package/menu/menu-link.styles.js +1 -1
- package/menu/menu-link.styles.js.map +1 -1
- package/menu/menu-link.styles_rng7n7.css +2 -0
- package/menu/menu-section.d.ts +1 -1
- package/menu/menu-section.js +1 -1
- package/menu/menu-section.js.map +1 -1
- package/menu/menu-section.styles.d.ts +7 -0
- package/menu/menu-section.styles.js +1 -1
- package/menu/menu-section.styles.js.map +1 -1
- package/menu/menu-section.styles_1n0ppxl.css +5 -0
- package/menu/menu.d.ts +1 -1
- package/menu/types.d.ts +10 -2
- package/modal-v2/slots/slot-styles.js +1 -1
- package/modal-v2/slots/slot-styles.js.map +1 -1
- package/modal-v2/slots/{slot-styles_ayb9il.css → slot-styles_ygu6zc.css} +1 -1
- package/navbar/navbar-items.js +1 -1
- package/navbar/navbar-items.js.map +1 -1
- package/navbar/types.d.ts +9 -0
- package/notification-banner/notification-banner-hoc.js +1 -1
- package/notification-banner/notification-banner-hoc.js.map +1 -1
- package/package.json +3 -4
- package/pagination/pagination.js +1 -1
- package/pagination/pagination.js.map +1 -1
- package/pagination/types.d.ts +8 -1
- package/scripts/cli.js +18 -0
- package/select-histogram/types.d.ts +1 -0
- package/shared/dropdown-list/dropdown-label.d.ts +2 -2
- package/shared/dropdown-list/dropdown-label.js +1 -1
- package/shared/dropdown-list/dropdown-label.js.map +1 -1
- package/shared/dropdown-list/types.d.ts +6 -2
- package/shared/fade-wrapper/fade-wrapper.js +1 -1
- package/shared/fade-wrapper/fade-wrapper.js.map +1 -1
- package/shared/fade-wrapper/types.d.ts +1 -0
- package/shared/styles/index.d.ts +5 -0
- package/skills/fds-build/SKILL.md +167 -0
- package/skills/fds-build/catalogue.md +181 -0
- package/skills/fds-build/evals/evals.json +519 -0
- package/skills/fds-build/resources/components/accordion.md +128 -0
- package/skills/fds-build/resources/components/alert.md +54 -0
- package/skills/fds-build/resources/components/animation.md +18 -0
- package/skills/fds-build/resources/components/avatar.md +10 -0
- package/skills/fds-build/resources/components/badge.md +18 -0
- package/skills/fds-build/resources/components/box-container.md +61 -0
- package/skills/fds-build/resources/components/breadcrumb.md +60 -0
- package/skills/fds-build/resources/components/button.md +74 -0
- package/skills/fds-build/resources/components/calendar.md +113 -0
- package/skills/fds-build/resources/components/card.md +43 -0
- package/skills/fds-build/resources/components/checkbox.md +53 -0
- package/skills/fds-build/resources/components/countdown-timer.md +20 -0
- package/skills/fds-build/resources/components/data-table.md +142 -0
- package/skills/fds-build/resources/components/date-navigator.md +25 -0
- package/skills/fds-build/resources/components/divider.md +23 -0
- package/skills/fds-build/resources/components/drawer.md +78 -0
- package/skills/fds-build/resources/components/error-display.md +137 -0
- package/skills/fds-build/resources/components/feedback-rating.md +61 -0
- package/skills/fds-build/resources/components/file-download.md +54 -0
- package/skills/fds-build/resources/components/file-upload.md +105 -0
- package/skills/fds-build/resources/components/filter.md +228 -0
- package/skills/fds-build/resources/components/footer.md +94 -0
- package/skills/fds-build/resources/components/form-date-input.md +85 -0
- package/skills/fds-build/resources/components/form-date-range-input.md +146 -0
- package/skills/fds-build/resources/components/form-e-signature.md +55 -0
- package/skills/fds-build/resources/components/form-input.md +65 -0
- package/skills/fds-build/resources/components/form-masked-input.md +69 -0
- package/skills/fds-build/resources/components/form-multi-select.md +100 -0
- package/skills/fds-build/resources/components/form-nested-multi-select.md +159 -0
- package/skills/fds-build/resources/components/form-nested-select.md +151 -0
- package/skills/fds-build/resources/components/form-otp-verification.md +175 -0
- package/skills/fds-build/resources/components/form-phone-number-input.md +87 -0
- package/skills/fds-build/resources/components/form-predictive-text-input.md +108 -0
- package/skills/fds-build/resources/components/form-select.md +103 -0
- package/skills/fds-build/resources/components/form-slider.md +116 -0
- package/skills/fds-build/resources/components/form-textarea.md +116 -0
- package/skills/fds-build/resources/components/form-time-range-picker.md +98 -0
- package/skills/fds-build/resources/components/form-timepicker.md +77 -0
- package/skills/fds-build/resources/components/form-unit-number-input.md +138 -0
- package/skills/fds-build/resources/components/fullscreen-image-carousel.md +159 -0
- package/skills/fds-build/resources/components/histogram-slider.md +41 -0
- package/skills/fds-build/resources/components/icon.md +167 -0
- package/skills/fds-build/resources/components/image-button.md +12 -0
- package/skills/fds-build/resources/components/input.md +51 -0
- package/skills/fds-build/resources/components/language-switcher.md +15 -0
- package/skills/fds-build/resources/components/layout.md +156 -0
- package/skills/fds-build/resources/components/link-list.md +120 -0
- package/skills/fds-build/resources/components/local-nav.md +119 -0
- package/skills/fds-build/resources/components/masthead.md +14 -0
- package/skills/fds-build/resources/components/menu.md +109 -0
- package/skills/fds-build/resources/components/modal.md +150 -0
- package/skills/fds-build/resources/components/navbar.md +270 -0
- package/skills/fds-build/resources/components/notification-banner.md +106 -0
- package/skills/fds-build/resources/components/pagination.md +104 -0
- package/skills/fds-build/resources/components/pill.md +55 -0
- package/skills/fds-build/resources/components/popover.md +80 -0
- package/skills/fds-build/resources/components/progress-indicator.md +47 -0
- package/skills/fds-build/resources/components/radio-button.md +66 -0
- package/skills/fds-build/resources/components/schedule.md +78 -0
- package/skills/fds-build/resources/components/sidenav.md +183 -0
- package/skills/fds-build/resources/components/singpass-button.md +14 -0
- package/skills/fds-build/resources/components/smart-app-banner.md +28 -0
- package/skills/fds-build/resources/components/tab.md +107 -0
- package/skills/fds-build/resources/components/table.md +65 -0
- package/skills/fds-build/resources/components/tag.md +68 -0
- package/skills/fds-build/resources/components/text-list.md +44 -0
- package/skills/fds-build/resources/components/time-slot-bar-week.md +66 -0
- package/skills/fds-build/resources/components/time-slot-bar.md +57 -0
- package/skills/fds-build/resources/components/time-slot-week-view.md +70 -0
- package/skills/fds-build/resources/components/timeline.md +69 -0
- package/skills/fds-build/resources/components/timetable.md +123 -0
- package/skills/fds-build/resources/components/toast.md +72 -0
- package/skills/fds-build/resources/components/toggle.md +119 -0
- package/skills/fds-build/resources/components/typography.md +86 -0
- package/skills/fds-build/resources/components/uneditable-section.md +84 -0
- package/skills/fds-build/resources/foundations/layout-composition-patterns.md +53 -0
- package/skills/fds-build/resources/foundations/tokens.md +547 -0
- package/skills/fds-build/resources/patterns/states.md +300 -0
- package/skills/fds-build/resources/setup/setup.md +202 -0
- package/skills/fds-build/resources/templates/form.md +427 -0
- package/skills/fds-build/resources/templates/listing.md +435 -0
- package/theme/styles/a11y-playground.css +52 -40
- package/theme/styles/bookingsg.css +52 -40
- package/theme/styles/careercompass.css +52 -40
- package/theme/styles/ccube.css +52 -40
- package/theme/styles/imda.css +52 -40
- package/theme/styles/lifesg.css +52 -40
- package/theme/styles/mylegacy.css +52 -40
- package/theme/styles/oneservice.css +52 -40
- package/theme/styles/pa.css +28 -22
- package/theme/styles/rbs.css +52 -40
- package/theme/styles/sgw-digital-lobby.css +52 -40
- package/theme/styles/smgs.css +52 -40
- package/theme/styles/spf.css +28 -27
- package/theme/styles/sportsg-orange.css +52 -40
- package/theme/styles/supportgowhere.css +52 -40
- package/theme/styles/tote-board.css +52 -40
- package/theme/styles/vica.css +52 -40
- package/theme/styles/websg.css +52 -40
- package/theme/styles/wise.css +52 -40
- package/theme/styles/wogaa.css +52 -40
- package/theme/tokens/colour.d.ts +6 -0
- package/theme/tokens/colour.js +1 -1
- package/theme/tokens/colour.js.map +1 -1
- package/theme/tokens/radius.d.ts +3 -0
- package/theme/tokens/radius.js +1 -1
- package/theme/tokens/radius.js.map +1 -1
- package/breadcrumb/breadcrumb.styles_1nl4aua.css +0 -18
- package/cjs/breadcrumb/breadcrumb.styles_1nl4aua.css +0 -18
- package/cjs/file-upload/file-item-edit.js +0 -2
- package/cjs/file-upload/file-item-edit.js.map +0 -1
- package/cjs/file-upload/file-item-edit.styles.js +0 -2
- package/cjs/file-upload/file-item-edit.styles.js.map +0 -1
- package/cjs/file-upload/file-item-edit.styles_19bvztn.css +0 -11
- package/cjs/file-upload/file-list/file-list.styles_1w7so98.css +0 -3
- package/cjs/file-upload/file-list-item/file-list-item.styles_kgtfke.css +0 -17
- package/cjs/local-nav/local-nav-menu/local-nav-menu.styles_pq19dh.css +0 -5
- package/cjs/menu/menu-content.styles_p7ijll.css +0 -2
- package/cjs/menu/menu-link.styles_hfxoez.css +0 -2
- package/cjs/menu/menu-section.styles_g7my4d.css +0 -3
- package/file-upload/file-item-edit.d.ts +0 -14
- package/file-upload/file-item-edit.js +0 -2
- package/file-upload/file-item-edit.js.map +0 -1
- package/file-upload/file-item-edit.styles.d.ts +0 -9
- package/file-upload/file-item-edit.styles.js +0 -2
- package/file-upload/file-item-edit.styles.js.map +0 -1
- package/file-upload/file-item-edit.styles_19bvztn.css +0 -11
- package/file-upload/file-list/file-list.styles_1w7so98.css +0 -3
- package/file-upload/file-list-item/file-list-item.styles_kgtfke.css +0 -17
- package/local-nav/local-nav-menu/local-nav-menu.styles_pq19dh.css +0 -5
- package/menu/menu-content.styles_p7ijll.css +0 -2
- package/menu/menu-link.styles_hfxoez.css +0 -2
- package/menu/menu-section.styles_g7my4d.css +0 -3
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Alert
|
|
2
|
+
|
|
3
|
+
Import: `import { Alert } from "@lifesg/react-design-system/alert"`
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
Use to call out important information within page sections — warnings before a user starts a task, informational notes relevant to a specific section, or non-transient status messages. Not for form validation errors (use form error patterns instead).
|
|
8
|
+
|
|
9
|
+
## Variants
|
|
10
|
+
|
|
11
|
+
| `type` | When to use |
|
|
12
|
+
| --------------- | ------------------------------------------ |
|
|
13
|
+
| `"success"` | Action completed successfully |
|
|
14
|
+
| `"error"` | Action failed or system error |
|
|
15
|
+
| `"warning"` | User should proceed with caution |
|
|
16
|
+
| `"info"` | Neutral informational message |
|
|
17
|
+
| `"description"` | Descriptive content with no status meaning |
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { Alert } from "@lifesg/react-design-system/alert";
|
|
23
|
+
|
|
24
|
+
<Alert type="warning" showIcon role="alert">
|
|
25
|
+
Your session will expire in 5 minutes. Save your work to avoid losing
|
|
26
|
+
progress.
|
|
27
|
+
</Alert>;
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Props — `AlertProps`
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Default | Description |
|
|
33
|
+
| -------------------- | ----------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
34
|
+
| `type` \* | `AlertType` | — | Visual severity or purpose of the alert banner. |
|
|
35
|
+
| `actionLink` | `React.AnchorHTMLAttributes<HTMLAnchorElement>` | — | Anchor attributes for an optional call-to-action link rendered below the alert content. The link is styled with a trailing arrow icon by default; supply `actionLinkIcon` to replace that icon. |
|
|
36
|
+
| `showIcon` | `boolean` | false | Renders the type-specific icon to the left of the content. |
|
|
37
|
+
| `actionLinkIcon` | `JSX.Element` | <ArrowRightIcon /> | Replaces the default trailing arrow on the action link. Only visible when `actionLink` is also provided. |
|
|
38
|
+
| `sizeType` | `AlertSizeType` | — | Controls the overall size of the alert, affecting typography and icon dimensions. |
|
|
39
|
+
| `customIcon` | `JSX.Element` | — | Replaces the default type-specific icon. Only visible when `showIcon` is `true`. |
|
|
40
|
+
| `maxCollapsedHeight` | `number` | — | Maximum height in pixels before the content area is collapsed. When the rendered content exceeds this value a "Show more / Show less" toggle is displayed. The content container is marked as inert whenever the collapsed state is active. |
|
|
41
|
+
|
|
42
|
+
## Rules
|
|
43
|
+
|
|
44
|
+
- Always use `showIcon` — icons provide immediate visual recognition of alert severity.
|
|
45
|
+
- Use `actionLink` for recoverable errors (retry, undo, view details).
|
|
46
|
+
- Set `role` based on how the alert appears: `"alert"` for dynamic alerts triggered by user action, `"status"` for background status updates, omit for static content visible on page load.
|
|
47
|
+
- Use `maxCollapsedHeight` to avoid long content overwhelming the layout.
|
|
48
|
+
- `role` is not set automatically — set `role="alert"` for dynamic alerts, `role="status"` for background updates, and omit for static content.
|
|
49
|
+
|
|
50
|
+
## Anti-patterns
|
|
51
|
+
|
|
52
|
+
- Using Alert for form field validation errors — use inline form error patterns instead.
|
|
53
|
+
- Omitting `role` on dynamically injected alerts — screen readers will not announce them.
|
|
54
|
+
- Using `type="description"` with `showIcon` — description has no semantic status meaning.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Animation
|
|
2
|
+
|
|
3
|
+
Import: `import { Animation } from "@lifesg/react-design-system/animation"`
|
|
4
|
+
|
|
5
|
+
## Props — `AnimationProps`
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
| ----------- | -------- | ------- | ----------- |
|
|
9
|
+
| `id` | `string` | — | — |
|
|
10
|
+
| `className` | `string` | — | — |
|
|
11
|
+
|
|
12
|
+
## Props — `CustomisableAnimationProps`
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Default | Description |
|
|
15
|
+
| ----------- | ------------------------------------------------------------------------- | ------- | -------------------------------------------------------- |
|
|
16
|
+
| `id` | `string` | — | — |
|
|
17
|
+
| `className` | `string` | — | — |
|
|
18
|
+
| `color` | `\| string \| ColourCSSVariableString \| ComponentTokenCSSVariableString` | — | The color that is to be applied on the animated elements |
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Avatar
|
|
2
|
+
|
|
3
|
+
Import: `import { Avatar } from "@lifesg/react-design-system/avatar"`
|
|
4
|
+
|
|
5
|
+
## Props — `AvatarProps`
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
| ------------- | ----------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| `children` \* | `string \| JSX.Element` | — | A string or JSX element to display inside the avatar. When a string is provided, only the first Unicode code point is rendered as an uppercase initial. Pass a JSX element (e.g. an `<img>`) to render custom content. |
|
|
10
|
+
| `sizeType` | `AvatarSize` | — | Controls the visual size of the avatar. `"small"` renders a compact variant with reduced typography; `"default"` uses the standard size. |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Badge
|
|
2
|
+
|
|
3
|
+
Import: `import { Badge } from "@lifesg/react-design-system/badge"`
|
|
4
|
+
|
|
5
|
+
## Props — `BadgeProps`
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
| ------------- | ------------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| `badgeOffset` | `[string, string]` | — | Horizontal and vertical offset applied to the badge when it overlays a child element. Provided as a `[x, y]` tuple of CSS length values (e.g. `["-4px", "-4px"]`). Ignored when no child is rendered. |
|
|
10
|
+
| `children` | `JSX.Element` | — | Element that the badge overlays. When provided, the badge is positioned absolutely over the top-right corner of this child. Omit to render the badge as a standalone indicator. |
|
|
11
|
+
| `color` | `BadgeColor` | "default" | Color scheme applied to the badge. |
|
|
12
|
+
| `count` | `number` | — | Numeric value displayed inside `number`, `number-with-border`, and `square-number` variants. Values above 1000 are capped and shown as `"1K"` or `"1K+"`. Has no effect on dot variants. |
|
|
13
|
+
| `variant` | `BadgeVariant` | "number" | Visual style of the badge indicator. |
|
|
14
|
+
|
|
15
|
+
## Rules
|
|
16
|
+
|
|
17
|
+
- `count` only applies to `"number"`, `"number-with-border"`, and `"square-number"` variants.
|
|
18
|
+
- When `children` is provided, the badge overlays the top-right corner of the child element.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# BoxContainer
|
|
2
|
+
|
|
3
|
+
Import: `import { BoxContainer } from "@lifesg/react-design-system/box-container"`
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
Use for a single collapsible panel displaying form data or structured content — typically a named section within a form or detail view. Supports an optional header action and a status indicator to flag section-level errors or warnings.
|
|
8
|
+
|
|
9
|
+
## Sub-components
|
|
10
|
+
|
|
11
|
+
### BoxContainerSubComponentTestIds
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Description |
|
|
14
|
+
| ------------------ | -------- | -------------------------------------- |
|
|
15
|
+
| `title` | `string` | Test id for the header title |
|
|
16
|
+
| `displayStateIcon` | `string` | Test id for the display state icon |
|
|
17
|
+
| `handle` | `string` | Test id for the expand/collapse handle |
|
|
18
|
+
|
|
19
|
+
## Variants
|
|
20
|
+
|
|
21
|
+
| `displayState` | When to use |
|
|
22
|
+
| -------------- | ------------------------------------------ |
|
|
23
|
+
| `"default"` | Normal state — no icon |
|
|
24
|
+
| `"error"` | Section has validation errors |
|
|
25
|
+
| `"warning"` | Section has a warning that needs attention |
|
|
26
|
+
|
|
27
|
+
## Props — `BoxContainerSubComponentTestIds`
|
|
28
|
+
|
|
29
|
+
| Prop | Type | Default | Description |
|
|
30
|
+
| ------------------ | -------- | ------- | ----------- |
|
|
31
|
+
| `title` | `string` | — | — |
|
|
32
|
+
| `handle` | `string` | — | — |
|
|
33
|
+
| `displayStateIcon` | `string` | — | — |
|
|
34
|
+
|
|
35
|
+
## Props — `BoxContainerProps`
|
|
36
|
+
|
|
37
|
+
| Prop | Type | Default | Description |
|
|
38
|
+
| ----------------------- | --------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
|
+
| `children` \* | `JSX.Element \| JSX.Element[]` | — | — |
|
|
40
|
+
| `title` \* | `string \| JSX.Element` | — | — |
|
|
41
|
+
| `collapsible` | `boolean` | true | When `false`, the container is always expanded and the collapse handle is hidden. |
|
|
42
|
+
| `expanded` | `boolean` | false | Initial expanded state when `collapsible` is `true`. |
|
|
43
|
+
| `callToActionComponent` | `JSX.Element` | — | Optional element rendered in the header alongside the title, e.g. a link or button. |
|
|
44
|
+
| `displayState` | `BoxContainerDisplayState` | "default" | Renders an inline alert icon next to the title and announces the state to screen readers. Has no effect when set to `"default"`. |
|
|
45
|
+
| `className` | `string` | — | — |
|
|
46
|
+
| `subComponentTestIds` | `BoxContainerSubComponentTestIds` | — | — |
|
|
47
|
+
| `id` | `string` | — | — |
|
|
48
|
+
| `clickableHeader` | `boolean` | — | When `true` (and `collapsible` is also `true`), the entire header row becomes a click target for toggling expand/collapse, not just the chevron button. |
|
|
49
|
+
|
|
50
|
+
## Rules
|
|
51
|
+
|
|
52
|
+
- Use `displayState` to indicate section-level status — not as a substitute for inline field errors.
|
|
53
|
+
- Use `callToActionComponent` for section-level actions only — not for form submission buttons.
|
|
54
|
+
- Use `collapsible={false}` when the content must always be visible.
|
|
55
|
+
- Use `clickableHeader` to make the full header row the expand/collapse trigger — improves usability for dense layouts.
|
|
56
|
+
|
|
57
|
+
## Anti-patterns
|
|
58
|
+
|
|
59
|
+
- Using `displayState="error"` instead of inline form field errors — `displayState` signals section-level status only.
|
|
60
|
+
- Using `callToActionComponent` for form submission — use a dedicated submit button outside the container.
|
|
61
|
+
- Nesting BoxContainer inside another BoxContainer.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Breadcrumb
|
|
2
|
+
|
|
3
|
+
Import: `import { Breadcrumb } from "@lifesg/react-design-system/breadcrumb"`
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
Use on pages within a multi-level hierarchy to help users navigate to parent pages.
|
|
8
|
+
|
|
9
|
+
Do not use on:
|
|
10
|
+
|
|
11
|
+
- The home page
|
|
12
|
+
- Pages with no parent
|
|
13
|
+
- Focused flows such as forms or wizards
|
|
14
|
+
|
|
15
|
+
## Variants
|
|
16
|
+
|
|
17
|
+
| `separatorStyle` | When to use |
|
|
18
|
+
| --------------------- | ------------------------ |
|
|
19
|
+
| `"chevron"` (default) | Standard pages |
|
|
20
|
+
| `"slash"` | Alternative visual style |
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { Breadcrumb } from "@lifesg/react-design-system/breadcrumb";
|
|
26
|
+
|
|
27
|
+
<Breadcrumb
|
|
28
|
+
links={[
|
|
29
|
+
{ children: "Home", href: "/" },
|
|
30
|
+
{ children: "Services", href: "/services" },
|
|
31
|
+
{ children: "Apply" },
|
|
32
|
+
]}
|
|
33
|
+
/>;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Props
|
|
37
|
+
|
|
38
|
+
| Prop | Type | Default | Description |
|
|
39
|
+
| ---------------- | ------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
40
|
+
| `links` \* | `React.AnchorHTMLAttributes<HTMLAnchorElement>[]` | — | Navigation items rendered as the breadcrumb trail. The last item is treated as the current page (`aria-current="page"`) and is not clickable. Items without `href` render as non-clickable labels. Items without `children` are skipped. |
|
|
41
|
+
| `fadeColor` | `string[] \| FadeColorSet` | — | Gradient color stops for the fade overlays shown on horizontal scroll. Pass a `string[]` to apply the same gradient to both edges, or a `FadeColorSet` to configure each edge independently. |
|
|
42
|
+
| `fadePosition` | `FadePosition` | "both" | Which edges display fade overlays when content overflows. |
|
|
43
|
+
| `separatorStyle` | `SeparatorStyle` | "chevron" | Visual separator between breadcrumb items. |
|
|
44
|
+
| `className` | `string` | — | — |
|
|
45
|
+
| `id` | `string` | "breadcrumb" | HTML `id` for the wrapper element. |
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
|
|
49
|
+
- Always place the current page last in `links` — omit `href` on the last item.
|
|
50
|
+
- Keep breadcrumb trails to 4 items or fewer; 5 or more items automatically collapse the middle into an overflow menu.
|
|
51
|
+
- Set `fadeColor` to match the page background so the horizontal scroll fade blends correctly on mobile.
|
|
52
|
+
- The last item in `links` is rendered as the current page (non-clickable, `aria-current="page"`). Omit `href` on the last item.
|
|
53
|
+
- When 5 or more items are present, middle items automatically collapse into an overflow menu.
|
|
54
|
+
- On mobile, breadcrumbs scroll horizontally with a fade effect at the edges controlled by `fadeColor` and `fadePosition`.
|
|
55
|
+
|
|
56
|
+
## Anti-patterns
|
|
57
|
+
|
|
58
|
+
- Do not add `href` to the last breadcrumb item — it represents the current page and must not be clickable.
|
|
59
|
+
- Do not use breadcrumbs on single-level or flat navigation structures.
|
|
60
|
+
- Do not use breadcrumbs inside forms or wizard flows.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Button
|
|
2
|
+
|
|
3
|
+
Import: `import { Button } from "@lifesg/react-design-system/button"`
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
`Button` handles all button variants in v4 — there are no separate `IconButton` or `ButtonWithIcon` components:
|
|
8
|
+
|
|
9
|
+
| Need | Usage |
|
|
10
|
+
| ------------------- | ---------------------------------------------------------------- |
|
|
11
|
+
| Text only | `<Button>Label</Button>` |
|
|
12
|
+
| Text + icon | `<Button icon={<Icon />}>Label</Button>` — icon defaults to left |
|
|
13
|
+
| Icon only (no text) | `<Button icon={<Icon />} aria-label="..." />` — renders square |
|
|
14
|
+
|
|
15
|
+
## Size variants
|
|
16
|
+
|
|
17
|
+
| Usage | When to use |
|
|
18
|
+
| ------------------------------------------- | ------------------------------------------------------- |
|
|
19
|
+
| `<Button>` or `<Button sizeType="default">` | Standard size — use for all buttons including hero CTAs |
|
|
20
|
+
| `<Button sizeType="small">` | Dense layouts, toolbars |
|
|
21
|
+
| `<Button sizeType="large">` | Only when explicitly specified — do not use by default |
|
|
22
|
+
|
|
23
|
+
> **Deprecated:** `Button.Default`, `Button.Small`, `Button.Large` sub-components are deprecated in v4. Use `<Button sizeType="...">` instead.
|
|
24
|
+
|
|
25
|
+
## Variants
|
|
26
|
+
|
|
27
|
+
| `styleType` | When to use |
|
|
28
|
+
| ------------- | ------------------------------------- |
|
|
29
|
+
| `"default"` | Main action on the page |
|
|
30
|
+
| `"secondary"` | Cancel, go back, alternative option |
|
|
31
|
+
| `"light"` | On colored or dark backgrounds |
|
|
32
|
+
| `"link"` | Tertiary, de-emphasized inline action |
|
|
33
|
+
|
|
34
|
+
Add `danger` for destructive actions (delete, remove) — applies to any `styleType`.
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { Button } from "@lifesg/react-design-system/button";
|
|
40
|
+
|
|
41
|
+
<Button styleType="default" onClick={() => {}}>
|
|
42
|
+
Save changes
|
|
43
|
+
</Button>;
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Props
|
|
47
|
+
|
|
48
|
+
| Prop | Type | Default | Description |
|
|
49
|
+
| ----------------------- | -------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
50
|
+
| `styleType` | `ButtonStyleType` | "default" | Visual style variant of the button. |
|
|
51
|
+
| `sizeType` | `ButtonSizeType` | "default" | Controls the button's size. |
|
|
52
|
+
| `danger` | `boolean` | false | Applies a red color scheme for destructive actions. |
|
|
53
|
+
| `loading` | `boolean` | false | Displays a loading spinner and sets `aria-busy` on the button. The spinner replaces the icon (if present); children continue to render. |
|
|
54
|
+
| `focusableWhenDisabled` | `boolean` | false | Keeps the button keyboard-focusable when disabled. When true, the HTML `disabled` attribute is not set, but `aria-disabled` remains true and the click handler is suppressed. |
|
|
55
|
+
| `icon` | `JSX.Element` | — | Icon element rendered inside the button. The icon receives `aria-hidden` automatically. When provided without children, the button renders in icon-only mode (square layout) — provide `aria-label` on the button for accessibility in that case. |
|
|
56
|
+
| `iconPosition` | `ButtonIconPosition` | "left" | Position of the icon relative to the button label. |
|
|
57
|
+
|
|
58
|
+
## Rules
|
|
59
|
+
|
|
60
|
+
- `styleType` is mandatory.
|
|
61
|
+
- Use sentence case for all labels — "Save changes" not "Save Changes".
|
|
62
|
+
- Use concise verb + noun labels — avoid "OK", "Yes", "Click here".
|
|
63
|
+
- Do not use `sizeType="large"` unless explicitly required — default size is correct for hero CTAs.
|
|
64
|
+
- Combine `loading` and `disabled` during async operations to prevent double-submission.
|
|
65
|
+
- Never use raw `<button>` elements — always use design system button components.
|
|
66
|
+
- Do not nest buttons inside buttons or links.
|
|
67
|
+
- `danger` applies to any `styleType`.
|
|
68
|
+
|
|
69
|
+
## Anti-patterns
|
|
70
|
+
|
|
71
|
+
- Do not use `sizeType="large"` as a default choice — it is a special case only.
|
|
72
|
+
- Do not use `Button.Default`, `Button.Small`, or `Button.Large` — these sub-components are deprecated in v4.
|
|
73
|
+
- Do not use vague labels like "OK" or "Yes" — labels must describe the action.
|
|
74
|
+
- Do not use `loading` alone without also setting `disabled`.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Calendar
|
|
2
|
+
|
|
3
|
+
Import: `import { Calendar } from "@lifesg/react-design-system/calendar"`
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Displaying an inline date picker when a full-page or panel calendar is preferable over a dropdown.
|
|
8
|
+
- Use `variant="single"` for standard single-date selection.
|
|
9
|
+
- Use `variant="multi"` when the user must pick multiple non-contiguous dates (e.g. recurring appointments).
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### variant="single" — single date selection
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { useState } from "react";
|
|
17
|
+
import { Calendar } from "@lifesg/react-design-system/calendar";
|
|
18
|
+
|
|
19
|
+
const AppointmentCalendar = () => {
|
|
20
|
+
const [date, setDate] = useState("2024-06-15");
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Calendar
|
|
24
|
+
variant="single"
|
|
25
|
+
value={date}
|
|
26
|
+
minDate="2024-01-01"
|
|
27
|
+
maxDate="2024-12-31"
|
|
28
|
+
onChange={(selected) => setDate(selected)}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### variant="multi" — multiple date selection
|
|
35
|
+
|
|
36
|
+
Note `values` (plural) and `onChange` receives the full updated array.
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { useState } from "react";
|
|
40
|
+
import { Calendar } from "@lifesg/react-design-system/calendar";
|
|
41
|
+
|
|
42
|
+
const MultiDateCalendar = () => {
|
|
43
|
+
const [dates, setDates] = useState<string[]>([]);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Calendar
|
|
47
|
+
variant="multi"
|
|
48
|
+
values={dates}
|
|
49
|
+
minDate="2024-01-01"
|
|
50
|
+
maxDate="2024-12-31"
|
|
51
|
+
maxSelectable={5}
|
|
52
|
+
onChange={(selected) => setDates(selected)}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## YearMonthDisplay
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Description |
|
|
61
|
+
| ------- | -------- | ------------------------------------- |
|
|
62
|
+
| `year` | `number` | Current visible year in `YYYY` format |
|
|
63
|
+
| `month` | `number` | Current visible month, 1–12 |
|
|
64
|
+
|
|
65
|
+
## Props — `CalendarSingleProps`
|
|
66
|
+
|
|
67
|
+
| Prop | Type | Default | Description |
|
|
68
|
+
| ---------- | --------------------------- | -------- | -------------------------------------- |
|
|
69
|
+
| `variant` | `"single"` | "single" | — |
|
|
70
|
+
| `value` | `string` | — | Selected date in `YYYY-MM-DD` format |
|
|
71
|
+
| `onChange` | `((value: string) => void)` | — | Called when the selected date changes. |
|
|
72
|
+
| `onSelect` | `((value: string) => void)` | — | Called when a date is selected. |
|
|
73
|
+
|
|
74
|
+
## Props — `CalendarMultiProps`
|
|
75
|
+
|
|
76
|
+
| Prop | Type | Default | Description |
|
|
77
|
+
| --------------- | ------------------------------ | ------- | --------------------------------------------- |
|
|
78
|
+
| `variant` \* | `"multi"` | — | — |
|
|
79
|
+
| `values` | `string[]` | — | Selected dates in `YYYY-MM-DD` format |
|
|
80
|
+
| `minSelectable` | `number` | — | Minimum number of dates that must be selected |
|
|
81
|
+
| `maxSelectable` | `number` | — | Maximum number of dates that can be selected |
|
|
82
|
+
| `onChange` | `((values: string[]) => void)` | — | Called when the selection changes. |
|
|
83
|
+
|
|
84
|
+
## Props — `CalendarProps`
|
|
85
|
+
|
|
86
|
+
| Prop | Type | Default | Description |
|
|
87
|
+
| -------------------------- | ------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| `className` | `string` | — | — |
|
|
89
|
+
| `id` | `string` | — | — |
|
|
90
|
+
| `styleType` | `"no-border" \| "bordered"` | "bordered" | Border style of the calendar container. |
|
|
91
|
+
| `onHover` | `((value: string) => void)` | — | Called when a day cell is hovered. |
|
|
92
|
+
| `onYearMonthDisplayChange` | `((value: YearMonthDisplay) => void)` | — | Called when the visible month or year changes. |
|
|
93
|
+
| `minDate` | `string` | — | The minimum date that can be selected (inclusive) in 'YYYY-MM-DD' format. |
|
|
94
|
+
| `maxDate` | `string` | — | The maximum date that can be selected (inclusive) in 'YYYY-MM-DD' format. |
|
|
95
|
+
| `disabledDates` | `string[]` | — | Dates to disable in `YYYY-MM-DD` format. Example: `["2023-04-30"]` |
|
|
96
|
+
| `allowDisabledSelection` | `boolean` | — | Specifies if dates normally disabled by `minDate`, `maxDate` and `disabledDates` are still selectable |
|
|
97
|
+
| `showActiveMonthDaysOnly` | `boolean` | — | Specifies if the calendar should display only dates for the selected month |
|
|
98
|
+
| `variant` | `"single"` | "single" | — |
|
|
99
|
+
| `onChange` | `((value: string) => void)` | — | Called when the selected date changes. |
|
|
100
|
+
|
|
101
|
+
## Rules
|
|
102
|
+
|
|
103
|
+
- `variant="single"` uses `value: string` and `onChange: (date: string) => void`.
|
|
104
|
+
- `variant="multi"` uses `values: string[]` and `onChange: (dates: string[]) => void` — note the plural prop names.
|
|
105
|
+
- All dates must be in `YYYY-MM-DD` format.
|
|
106
|
+
- Use `minDate`/`maxDate` to constrain selectable range.
|
|
107
|
+
- Use `disabledDates` for specific non-selectable dates within the allowed range.
|
|
108
|
+
|
|
109
|
+
## Anti-patterns
|
|
110
|
+
|
|
111
|
+
- Do not pass `value` to `variant="multi"` — the prop is `values` (plural).
|
|
112
|
+
- Do not pass `values` to `variant="single"` — the prop is `value` (singular).
|
|
113
|
+
- Do not use Calendar inside a form for simple date entry — prefer `Form.DateInput` for that pattern.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Card
|
|
2
|
+
|
|
3
|
+
Import: `import { Card } from "@lifesg/react-design-system/card"`
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
Use to visually group related content — information panels, form sections, list items, or grid tiles.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import styles from "./Card.module.css";
|
|
13
|
+
import { Card } from "@lifesg/react-design-system/card";
|
|
14
|
+
import { Typography } from "@lifesg/react-design-system/typography";
|
|
15
|
+
|
|
16
|
+
<Card>
|
|
17
|
+
<div className={styles.cardBody}>
|
|
18
|
+
<Typography.HeadingSM>Card title</Typography.HeadingSM>
|
|
19
|
+
<Typography.BodyMD>Card content goes here.</Typography.BodyMD>
|
|
20
|
+
</div>
|
|
21
|
+
</Card>;
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```css
|
|
25
|
+
/* Card.module.css */
|
|
26
|
+
.cardBody {
|
|
27
|
+
padding: var(--fds-spacing-24);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Rules
|
|
32
|
+
|
|
33
|
+
- Card has no default padding — use `spacing-24` internal padding and `spacing-16` gap between content items as the standard.
|
|
34
|
+
- Shadow (`Shadow["md-subtle"]`) is applied automatically — do not add `box-shadow` manually.
|
|
35
|
+
- Do not nest cards inside cards.
|
|
36
|
+
- Use Typography components for all text inside Card — not raw HTML elements.
|
|
37
|
+
- Combine with `Layout.Container` and `Layout.ColDiv` for responsive card grids.
|
|
38
|
+
|
|
39
|
+
## Anti-patterns
|
|
40
|
+
|
|
41
|
+
- Adding `box-shadow` via CSS — the Card component already applies the correct elevation shadow.
|
|
42
|
+
- Using raw `<div>` with custom styling instead of Card when the DS Card fits the use case.
|
|
43
|
+
- Nesting `<Card>` inside another `<Card>`.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Checkbox
|
|
2
|
+
|
|
3
|
+
Import: `import { Checkbox } from "@lifesg/react-design-system/checkbox"`
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Simple boolean selections where a compact tick-box is sufficient.
|
|
8
|
+
- Table row selection (single or "select all").
|
|
9
|
+
- Filter lists with multiple independent options.
|
|
10
|
+
- "Select all" patterns using the `indeterminate` state.
|
|
11
|
+
|
|
12
|
+
Prefer `Toggle` over `Checkbox` when building form inputs that need a visible card-style label container.
|
|
13
|
+
|
|
14
|
+
## Variants
|
|
15
|
+
|
|
16
|
+
| `displaySize` | When to use |
|
|
17
|
+
| ------------- | ------------------------------ |
|
|
18
|
+
| `"default"` | Standard use |
|
|
19
|
+
| `"small"` | Dense layouts, inline controls |
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { Checkbox } from "@lifesg/react-design-system/checkbox";
|
|
25
|
+
|
|
26
|
+
<label>
|
|
27
|
+
<Checkbox checked={agreed} onChange={(e) => {}} />I agree to the terms and
|
|
28
|
+
conditions
|
|
29
|
+
</label>;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Props
|
|
33
|
+
|
|
34
|
+
| Prop | Type | Default | Description |
|
|
35
|
+
| ----------------------- | -------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
36
|
+
| `checked` | `boolean` | — | Controls the checked state of the checkbox. When omitted, the checkbox is uncontrolled. |
|
|
37
|
+
| `displaySize` | `CheckboxSize` | "default" | Controls the visual size of the checkbox. |
|
|
38
|
+
| `indeterminate` | `boolean` | — | Puts the checkbox into an indeterminate visual and accessibility state. |
|
|
39
|
+
| `focusableWhenDisabled` | `boolean` | — | Allows the checkbox to receive focus when `disabled` is true. When set alongside `disabled`, the native `disabled` attribute is omitted in favor of `aria-disabled="true"` and `tabIndex={0}`, keeping the element keyboard-reachable. `onChange` is still suppressed. |
|
|
40
|
+
|
|
41
|
+
## Rules
|
|
42
|
+
|
|
43
|
+
- Always pair with a visible label — wrap in `<label>` or use `aria-label`.
|
|
44
|
+
- Use `indeterminate` for "select all" controls when only some items in a list are selected — not as a permanent state.
|
|
45
|
+
- Use the same `name` attribute when grouping checkboxes in a form.
|
|
46
|
+
- No dedicated `disabled` prop — use the inherited `disabled` from `InputHTMLAttributes`, or `focusableWhenDisabled` to retain focus while blocking interaction.
|
|
47
|
+
- `indeterminate` is a visual state; manage controlled `checked` separately.
|
|
48
|
+
|
|
49
|
+
## Anti-patterns
|
|
50
|
+
|
|
51
|
+
- Do not use `indeterminate` as a permanent or final state — it is a transitional indicator only.
|
|
52
|
+
- Do not use `Checkbox` alone without a label — always provide accessible text.
|
|
53
|
+
- Do not use `Checkbox` when only one option from a set can be selected — use `RadioButton` instead.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# CountdownTimer
|
|
2
|
+
|
|
3
|
+
Import: `import { CountdownTimer } from "@lifesg/react-design-system/countdown-timer"`
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
| ------------------ | ----------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| `show` \* | `boolean` | — | Controls whether the timer is visible and actively counting down. |
|
|
10
|
+
| `fixed` | `boolean` | true | When `true`, the timer switches to a fixed viewport overlay once its inline position scrolls out of view, keeping the countdown visible at all times. |
|
|
11
|
+
| `notifyTimer` | `number` | — | Remaining-seconds threshold at which the warning state activates. Once the countdown reaches this value, `onNotify` fires once and `onTick` fires every second until the timer finishes. |
|
|
12
|
+
| `offset` | `Offset` | — | Fine-tunes the fixed overlay position on tablet and desktop viewports. |
|
|
13
|
+
| `mobileOffset` | `MobileOffset` | { top: 80 } | Fine-tunes the fixed overlay position on mobile viewports. |
|
|
14
|
+
| `align` | `AlignPosition` | "right" | Side of the inline wrapper the fixed overlay is pinned to when scrolled into sticky mode. |
|
|
15
|
+
| `onTick` | `((seconds: number) => void)` | — | Called every second with the remaining seconds once the countdown falls at or below `notifyTimer`. |
|
|
16
|
+
| `onNotify` | `(() => void)` | — | Called once when the remaining seconds first reach the `notifyTimer` threshold. |
|
|
17
|
+
| `onFinish` | `(() => void)` | — | Called when the countdown reaches zero. |
|
|
18
|
+
| `reminderInterval` | `number` | 120 | Interval in seconds between polite screen-reader announcement of the remaining time while the timer is above the `notifyTimer` threshold. |
|
|
19
|
+
| `timer` \* | `number` | — | Duration of the countdown in seconds. |
|
|
20
|
+
| `timestamp` | `number` | — | — |
|