@lifesg/react-design-system 4.0.0-alpha.11 → 4.0.0-alpha.13
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/file-download/file-download.js +1 -1
- package/cjs/file-download/file-download.js.map +1 -1
- package/cjs/file-download/file-list-card/file-list-card.js +1 -1
- package/cjs/file-download/file-list-card/file-list-card.js.map +1 -1
- package/cjs/file-download/file-list-card/file-list-card.styles.js +1 -1
- package/cjs/file-download/file-list-card/file-list-card.styles.js.map +1 -1
- package/cjs/file-download/file-list-card/file-list-card.styles_lzbqkk.css +18 -0
- 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/file-upload/helper.js +1 -1
- package/cjs/file-upload/helper.js.map +1 -1
- package/cjs/footer/footer-disclaimer-links-data.js +1 -1
- package/cjs/footer/footer-disclaimer-links-data.js.map +1 -1
- package/cjs/footer/footer.styles.js +1 -1
- package/cjs/footer/footer.styles.js.map +1 -1
- package/{footer/footer.styles_1msorhc.css → cjs/footer/footer.styles_14hnlcq.css} +4 -4
- package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.js +1 -1
- package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
- package/cjs/index.js +1 -1
- 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/cjs/local-nav/local-nav-dropdown/{local-nav-dropdown.styles_uhd4xl.css → 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/masthead/sgds-day.css +0 -1
- package/cjs/masthead/sgds-night.css +0 -1
- 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/navbar/navbar-items.js +1 -1
- package/cjs/navbar/navbar-items.js.map +1 -1
- package/cjs/navbar/navbar-logo-data.js +1 -1
- package/cjs/navbar/navbar-logo-data.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/index.js +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/cjs/theme/types.js +1 -1
- package/cjs/theme/types.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/file-download/file-download.d.ts +1 -1
- package/file-download/file-download.js +1 -1
- package/file-download/file-download.js.map +1 -1
- package/file-download/file-list-card/file-list-card.d.ts +1 -1
- package/file-download/file-list-card/file-list-card.js +1 -1
- package/file-download/file-list-card/file-list-card.js.map +1 -1
- package/file-download/file-list-card/file-list-card.styles.d.ts +2 -0
- package/file-download/file-list-card/file-list-card.styles.js +1 -1
- package/file-download/file-list-card/file-list-card.styles.js.map +1 -1
- package/file-download/file-list-card/file-list-card.styles_lzbqkk.css +18 -0
- package/file-download/file-list-card/types.d.ts +1 -0
- package/file-download/types.d.ts +13 -0
- 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/file-upload/helper.d.ts +30 -0
- package/file-upload/helper.js +1 -1
- package/file-upload/helper.js.map +1 -1
- package/footer/footer-disclaimer-links-data.js +1 -1
- package/footer/footer-disclaimer-links-data.js.map +1 -1
- package/footer/footer.styles.js +1 -1
- package/footer/footer.styles.js.map +1 -1
- package/{cjs/footer/footer.styles_1msorhc.css → footer/footer.styles_14hnlcq.css} +4 -4
- package/fullscreen-image-carousel/fullscreen-image-carousel.d.ts +1 -1
- package/fullscreen-image-carousel/fullscreen-image-carousel.js +1 -1
- package/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
- package/fullscreen-image-carousel/types.d.ts +37 -0
- package/index.js +1 -1
- 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/local-nav/local-nav-dropdown/{local-nav-dropdown.styles_uhd4xl.css → 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/masthead/sgds-day.css +0 -1
- package/masthead/sgds-night.css +0 -1
- 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/navbar/navbar-items.js +1 -1
- package/navbar/navbar-items.js.map +1 -1
- package/navbar/navbar-logo-data.js +1 -1
- package/navbar/navbar-logo-data.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 +2 -3
- package/pagination/pagination.js +1 -1
- package/pagination/pagination.js.map +1 -1
- package/pagination/types.d.ts +8 -1
- 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/theme/index.js +1 -1
- 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 +791 -0
- 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/theme-provider/preset.d.ts +2 -0
- 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/theme/types.d.ts +9 -3
- package/theme/types.js +1 -1
- package/theme/types.js.map +1 -1
- package/breadcrumb/breadcrumb.styles_1nl4aua.css +0 -18
- package/cjs/breadcrumb/breadcrumb.styles_1nl4aua.css +0 -18
- package/cjs/file-download/file-list-card/file-list-card.styles_18j2gut.css +0 -16
- 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-download/file-list-card/file-list-card.styles_18j2gut.css +0 -16
- 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
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export declare const gridTokens: {
|
|
2
|
+
readonly rows: "--fds-menu-section-grid-rows";
|
|
3
|
+
};
|
|
4
|
+
export declare const GRID_COLUMN_WIDTH_PX = 383;
|
|
5
|
+
export declare const GRID_COLUMN_GAP_PX = 8;
|
|
1
6
|
export declare const section: import("@linaria/core").LinariaClassName;
|
|
2
7
|
export declare const sectionWithDivider: import("@linaria/core").LinariaClassName;
|
|
3
8
|
export declare const label: import("@linaria/core").LinariaClassName;
|
|
9
|
+
export declare const list: import("@linaria/core").LinariaClassName;
|
|
10
|
+
export declare const listColumns: import("@linaria/core").LinariaClassName;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"./menu-section.
|
|
1
|
+
import"./menu-section.styles_1n0ppxl.css";const s={rows:"--fds-menu-section-grid-rows"},o=383,e=8,l="s1fmxqsy",n="s1o971t2",t="llhca5j",c="l7qikvl",i="l6d0215";export{e as GRID_COLUMN_GAP_PX,o as GRID_COLUMN_WIDTH_PX,s as gridTokens,t as label,c as list,i as listColumns,l as section,n as sectionWithDivider};
|
|
2
2
|
//# sourceMappingURL=menu-section.styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-section.styles.js","sources":["../../src/menu/menu-section.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Border, Colour, Spacing } from \"../theme/tokens\";\n\nexport const section = css`\n padding: ${Spacing[\"spacing-8\"]} 0;\n margin: 0;\n
|
|
1
|
+
{"version":3,"file":"menu-section.styles.js","sources":["../../src/menu/menu-section.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Border, Colour, MediaQuery, Spacing } from \"../theme/tokens\";\n\nexport const gridTokens = {\n rows: \"--fds-menu-section-grid-rows\",\n} as const;\n\n// 367px max content width (Figma) + 8px padding per side; used to cap the panel maxWidth in MenuContent\nexport const GRID_COLUMN_WIDTH_PX = 383;\n// matches Spacing[\"spacing-8\"]\nexport const GRID_COLUMN_GAP_PX = 8;\n\nexport const section = css`\n padding: ${Spacing[\"spacing-8\"]} 0;\n margin: 0;\n`;\n\nexport const sectionWithDivider = css`\n border-top: ${Border[\"width-010\"]} ${Border[\"solid\"]} ${Colour[\"border\"]};\n`;\n\nexport const label = css`\n margin: 0 ${Spacing[\"spacing-16\"]} ${Spacing[\"spacing-8\"]};\n color: ${Colour[\"text-subtler\"]};\n`;\n\nexport const list = css`\n list-style: none;\n`;\n\nexport const listColumns = css`\n ${gridTokens.rows}: initial;\n\n display: grid;\n grid-template-rows: repeat(var(${gridTokens.rows}), auto);\n grid-auto-flow: column;\n grid-auto-columns: minmax(0, 1fr);\n column-gap: ${Spacing[\"spacing-8\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n grid-template-rows: none;\n grid-auto-flow: row;\n }\n`;\n"],"names":["gridTokens","rows","GRID_COLUMN_WIDTH_PX","GRID_COLUMN_GAP_PX","section","sectionWithDivider","label","list","listColumns"],"mappings":"8DAIO,MAAMA,EAAa,CACtBC,KAAM,gCAIGC,EAAuB,IAEvBC,EAAqB,EAErBC,EAAO,WAKPC,EAAkB,WAIlBC,EAAK,UAKLC,EAAI,UAIJC,EAAW"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
@layer fds{.s1fmxqsy{padding:var(--fds-spacing-8) 0;margin:0;}
|
|
2
|
+
.s1o971t2{border-top:var(--fds-border-width-010) var(--fds-border-style-solid) var(--fds-colour-border);}
|
|
3
|
+
.llhca5j{margin:0 var(--fds-spacing-16) var(--fds-spacing-8);color:var(--fds-colour-text-subtler);}
|
|
4
|
+
.l7qikvl{list-style:none;}
|
|
5
|
+
.l6d0215{--fds-menu-section-grid-rows:initial;display:-ms-grid;display:grid;-ms-grid-rows:repeat(var(--fds-menu-section-grid-rows), auto);grid-template-rows:repeat(var(--fds-menu-section-grid-rows), auto);-ms-grid-auto-flow:column;grid-auto-flow:column;-ms-grid-auto-columns:minmax(0, 1fr);grid-auto-columns:minmax(0, 1fr);-webkit-column-gap:var(--fds-spacing-8);column-gap:var(--fds-spacing-8);}:where(body.fds-breakpoint-lg-max) .l6d0215{-ms-grid-rows:none;grid-template-rows:none;-ms-grid-auto-flow:row;grid-auto-flow:row;}}
|
package/menu/menu.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export declare const Menu: (({ children, position, menuContent, "data-testid": t
|
|
|
38
38
|
};
|
|
39
39
|
/** Groups related menu entries. */
|
|
40
40
|
Section: {
|
|
41
|
-
({ children, label, showDivider, className, "data-testid": testId, ...otherProps }: import("./types").MenuSectionProps): JSX.Element;
|
|
41
|
+
({ children, label, showDivider, className, columns, "data-testid": testId, ...otherProps }: import("./types").MenuSectionProps): JSX.Element;
|
|
42
42
|
displayName: string;
|
|
43
43
|
};
|
|
44
44
|
};
|
package/menu/types.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { AnchorHTMLAttributes, FunctionComponentElement, HTMLAttributes, Re
|
|
|
2
2
|
import type { PopoverPosition, PopoverRenderProps, PopoverTriggerProps } from "../popover";
|
|
3
3
|
import type { MenuItem } from "./menu-item";
|
|
4
4
|
import type { MenuLink } from "./menu-link";
|
|
5
|
-
import type { MenuSection } from "./menu-section";
|
|
6
5
|
/**
|
|
7
6
|
* Props for the `Menu` component.
|
|
8
7
|
*
|
|
@@ -24,7 +23,7 @@ export interface MenuProps extends Omit<PopoverTriggerProps, "popoverContent"> {
|
|
|
24
23
|
*/
|
|
25
24
|
export interface MenuContentProps extends HTMLAttributes<HTMLDivElement>, PopoverRenderProps {
|
|
26
25
|
/** One or more `Menu.Section` elements that make up the panel body. */
|
|
27
|
-
children: ReactElement<
|
|
26
|
+
children: ReactElement<MenuSectionProps> | ReactElement<MenuSectionProps>[];
|
|
28
27
|
"data-testid"?: string | undefined;
|
|
29
28
|
}
|
|
30
29
|
type MenuSectionItem = ReactElement<typeof MenuItem> | ReactElement<typeof MenuLink>;
|
|
@@ -40,6 +39,15 @@ export interface MenuSectionProps extends HTMLAttributes<HTMLUListElement> {
|
|
|
40
39
|
* @default true
|
|
41
40
|
*/
|
|
42
41
|
showDivider?: boolean | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Renders section children in a grid with the given number of columns
|
|
44
|
+
* on desktop. Items flow vertically (top-to-bottom) within each column
|
|
45
|
+
* before wrapping to the next. Has no effect on mobile viewports, which
|
|
46
|
+
* always render as a single column.
|
|
47
|
+
*
|
|
48
|
+
* @minimum 1
|
|
49
|
+
*/
|
|
50
|
+
columns?: number | undefined;
|
|
43
51
|
/**
|
|
44
52
|
* Accessible group label rendered above the section items.
|
|
45
53
|
*/
|
package/navbar/navbar-items.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as n,Fragment as i,jsxs as r}from"react/jsx-runtime";import{ChevronUpIcon as t}from"@lifesg/react-icons/chevron-up";import l from"clsx";import{useState as a,useRef as s,useEffect as o}from"react";import{Menu as c}from"../menu/menu.js";import{ClickableIcon as d}from"../shared/clickable-icon/clickable-icon.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as
|
|
1
|
+
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as n,Fragment as i,jsxs as r}from"react/jsx-runtime";import{ChevronUpIcon as t}from"@lifesg/react-icons/chevron-up";import l from"clsx";import{useState as a,useRef as s,useEffect as o}from"react";import{Menu as c}from"../menu/menu.js";import{ClickableIcon as d}from"../shared/clickable-icon/clickable-icon.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as u}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{Menu as m}from"./menu.js";import{mobileWrapper as p,wrapper as h,wrapperAlignLeft as b,link as v,linkSelected as f,linkItem as g,linkItemHiddenBranding as j,linkWeightRegular as N,linkWeightSemibold as k,linkWeightBold as x,linkLabel as C,linkButton as I,chevronIcon as M,chevronIconDesktop as $,chevronIconSelected as y,subMenuExpanded as O,linkIndicator as _,linkIndicatorSelected as L,linkIconContainer as P,expandCollapseButton as w}from"./navbar-items.styles.js";const E=({items:E,selectedId:D,mobile:T=!1,hideNavBranding:z,hideLinkIndicator:A=!1,onItemClick:B})=>{const[F,H]=a(null),R=s(null),S=u(),q=e=>{var n;return!!(null===(n=e.subMenu)||void 0===n?void 0:n.some((e=>e.id===D)))},G=T?E.findIndex((e=>"component"!==e.itemType&&q(e))):-1,J=G<0?null:G;o((()=>{T&&H(J)}),[T,J]),o((()=>{if(T)return;const e=e=>{R.current&&!R.current.contains(e.target)&&H(null)};return document.addEventListener("click",e,!0),()=>{document.removeEventListener("click",e,!0)}}),[T]);const K=(e,n)=>i=>{i.stopPropagation(),T&&H((i=>{var r;return(null===(r=e.subMenu)||void 0===r?void 0:r.length)&&i!==n?n:null})),B(i,e)},Q=(e,n)=>{e.stopPropagation(),B(e,n)},U=(e,i,r)=>n(c.Content,{id:i,children:n(c.Section,{showDivider:!1,columns:r,children:e.map(((e,i)=>n(c.Link,{href:e.href,children:e.children},`${e.id}-${i}`)))})}),V=e=>n(m,{items:e,selectedId:D,onItemClick:Q}),W=(a,s)=>{const{children:o,options:u,subMenu:m,subMenuColumns:p}=a,h=e(a,["children","options","subMenu","subMenuColumns"]),b=!!(null==m?void 0:m.length),B=(e=>e.id===D||q(e))(a),R=!T&&b&&F===s,G=T&&b&&F===s,J=R||G,Q=T||null===F?B:F===s,W=!A&&Q,X=T?`link__mobile-${s+1}`:`link__${s+1}`,Y=()=>W?n("div",{"data-testid":`${X}-indicator`,className:l(_,Q&&L)}):null,Z=l(v,(e=>{switch(e){case"bold":return x;case"semibold":return k;default:return N}})(Q?T?"bold":"semibold":"regular"),Q&&f);return n("li",{className:l(g,z&&j),children:b?(e=>{const v=`navbar-submenu-${S}-${a.id}`;return T?r(i,{children:[r("a",Object.assign({"data-testid":X,className:Z},h,{"aria-current":B?"page":void 0,"aria-haspopup":"menu","aria-expanded":J,onClick:K(a,s)},u,{children:[n("div",{className:C,children:o}),Y(),T&&b?n("div",{className:P,children:n(d,{"data-testid":`${X}-expand-collapse-button`,className:l(w,G&&O),focusHighlight:!1,focusOutline:"browser","aria-label":G?"Collapse":"Expand",children:n(t,{className:l(M,Q&&y)})})}):null]})),G&&V(m)]}):n(c,{position:e?"bottom-end":"bottom",customOffset:0,menuContent:U(m,v,p),enableResize:!0,triggerOnFocus:!0,isModal:!1,onPopoverAppear:()=>{H(s)},onPopoverDismiss:()=>{H((e=>e===s?null:e))},children:r("button",Object.assign({type:"button",tabIndex:0,"data-testid":X,className:l(Z,I),"aria-haspopup":"menu","aria-expanded":J},u,{children:[n("div",{className:C,children:o}),Y(),n(t,{className:l(M,$,Q&&y,R&&O)})]}))})})(s===E.length-1):r("a",Object.assign({tabIndex:0,"data-testid":X,className:Z},h,{"aria-current":B?"page":void 0,onClick:K(a,s)},u,{children:[n("div",{className:C,children:o}),Y()]}))},s)},X=()=>E.map(((e,i)=>{var r;return"component"===e.itemType?n("li",{children:null!==(r=e.children)&&void 0!==r?r:null},i):W(e,i)}));return E&&E.length>0?n("ul",T?{ref:R,className:p,children:X()}:{ref:R,className:l(h,z&&b),children:X()}):n(i,{})};export{E as NavbarItems};
|
|
2
2
|
//# sourceMappingURL=navbar-items.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navbar-items.js","sources":["../../src/navbar/navbar-items.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { Menu as DesktopMenu } from \"../menu\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport type { TypographyWeight } from \"../typography\";\nimport { useId } from \"../util\";\nimport { Menu as MobileMenu } from \"./menu\";\nimport * as styles from \"./navbar-items.styles\";\nimport type {\n NavItemCommonProps,\n NavItemLinkProps,\n NavItemProps,\n} from \"./types\";\n\nconst getLinkWeightClass = (weight: TypographyWeight) => {\n switch (weight) {\n case \"bold\":\n return styles.linkWeightBold;\n case \"semibold\":\n return styles.linkWeightSemibold;\n case \"regular\":\n default:\n return styles.linkWeightRegular;\n }\n};\n\ninterface Props<T> {\n items: NavItemProps<T>[];\n selectedId?: string | undefined;\n /** toggle for mobile or desktop view */\n mobile?: boolean | undefined;\n hideNavBranding?: boolean | undefined;\n /** hide the selected LinkIndicator */\n hideLinkIndicator?: boolean | undefined;\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemProps<T> | NavItemCommonProps<T>\n ) => void;\n}\n\nexport const NavbarItems = <T,>({\n items,\n selectedId,\n mobile = false,\n hideNavBranding,\n hideLinkIndicator = false,\n onItemClick,\n}: Props<T>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const [selectedIndex, setSelectedIndex] = useState<number | null>(null);\n const listRef = useRef<HTMLUListElement>(null);\n const instanceId = useId();\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const hasSelectedSubMenuItem = (item: NavItemLinkProps<T>): boolean =>\n !!item.subMenu?.some((subItem) => subItem.id === selectedId);\n\n const checkSelected = (item: NavItemLinkProps<T>): boolean =>\n item.id === selectedId || hasSelectedSubMenuItem(item);\n\n const itemIndexWithSelectedSubItem = mobile\n ? items.findIndex(\n (item) =>\n item.itemType !== \"component\" &&\n hasSelectedSubMenuItem(item as NavItemLinkProps<T>)\n )\n : -1;\n const initialExpandedItemIndex =\n itemIndexWithSelectedSubItem < 0 ? null : itemIndexWithSelectedSubItem;\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n\n useEffect(() => {\n if (!mobile) return;\n\n setSelectedIndex(initialExpandedItemIndex);\n }, [mobile, initialExpandedItemIndex]);\n\n useEffect(() => {\n if (mobile) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (\n listRef.current &&\n !listRef.current.contains(event.target as Node)\n ) {\n setSelectedIndex(null);\n }\n };\n document.addEventListener(\"click\", handleClickOutside, true);\n return () => {\n document.removeEventListener(\"click\", handleClickOutside, true);\n };\n }, [mobile]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleLinkClick = (item: NavItemLinkProps<T>, index: number) => {\n return (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation();\n\n // mobile expands inline when link has submenu\n if (mobile) {\n setSelectedIndex((prev) =>\n item.subMenu?.length && prev !== index ? index : null\n );\n }\n\n onItemClick(event, item);\n };\n };\n\n const handleMobileSubLinkClick = (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => {\n event.stopPropagation();\n onItemClick(event, item);\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderDesktopSubMenu = (\n subMenu: NavItemCommonProps<T>[],\n subMenuId: string\n ) => (\n <DesktopMenu.Content id={subMenuId}>\n <DesktopMenu.Section showDivider={false}>\n {subMenu.map((item, subIndex) => (\n <DesktopMenu.Link\n key={`${item.id}-${subIndex}`}\n href={item.href}\n >\n {item.children}\n </DesktopMenu.Link>\n ))}\n </DesktopMenu.Section>\n </DesktopMenu.Content>\n );\n\n const renderMobileSubMenu = (subMenu: NavItemCommonProps<T>[]) => (\n <MobileMenu\n items={subMenu}\n selectedId={selectedId}\n onItemClick={handleMobileSubLinkClick}\n />\n );\n\n const renderLinkItem = (item: NavItemLinkProps<T>, index: number) => {\n const { children, options, subMenu, ...otherItemAttrs } = item;\n\n const hasSubMenu = !!subMenu?.length;\n\n const isRouteSelected = checkSelected(item);\n\n // desktop popover open state\n const isDesktopExpanded =\n !mobile && hasSubMenu && selectedIndex === index;\n\n // mobile inline expanded state\n const isMobileExpanded =\n mobile && hasSubMenu && selectedIndex === index;\n\n const isExpanded = isDesktopExpanded || isMobileExpanded;\n\n const selected =\n !mobile && selectedIndex !== null\n ? selectedIndex === index\n : isRouteSelected;\n\n const showIndicator = !hideLinkIndicator && selected;\n\n const textWeight: TypographyWeight = selected\n ? mobile\n ? \"bold\"\n : \"semibold\"\n : \"regular\";\n\n const testId = mobile\n ? `link__mobile-${index + 1}`\n : `link__${index + 1}`;\n\n const renderIndicator = () =>\n showIndicator ? (\n <div\n data-testid={`${testId}-indicator`}\n className={clsx(\n styles.linkIndicator,\n selected && styles.linkIndicatorSelected\n )}\n />\n ) : null;\n\n const renderMobileChevron = () =>\n mobile && hasSubMenu ? (\n <div className={styles.linkIconContainer}>\n <ClickableIcon\n data-testid={`${testId}-expand-collapse-button`}\n className={clsx(\n styles.expandCollapseButton,\n isMobileExpanded && styles.subMenuExpanded\n )}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={isMobileExpanded ? \"Collapse\" : \"Expand\"}\n >\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n selected && styles.chevronIconSelected\n )}\n />\n </ClickableIcon>\n </div>\n ) : null;\n\n const linkClassName = clsx(\n styles.link,\n getLinkWeightClass(textWeight),\n selected && styles.linkSelected\n );\n\n const renderLink = () => (\n <a\n tabIndex={0}\n data-testid={testId}\n className={linkClassName}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n </a>\n );\n\n const renderLinkWithSubmenu = (isLastItem: boolean) => {\n const subMenuId = `navbar-submenu-${instanceId}-${item.id}`;\n\n if (mobile) {\n return (\n <>\n <a\n data-testid={testId}\n className={linkClassName}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n {renderMobileChevron()}\n </a>\n\n {isMobileExpanded && renderMobileSubMenu(subMenu!)}\n </>\n );\n }\n\n return (\n <DesktopMenu\n position={isLastItem ? \"bottom-end\" : \"bottom\"}\n customOffset={0}\n menuContent={renderDesktopSubMenu(subMenu!, subMenuId)}\n triggerOnFocus\n isModal={false}\n onPopoverAppear={() => {\n setSelectedIndex(index);\n }}\n onPopoverDismiss={() => {\n setSelectedIndex((prev) =>\n prev === index ? null : prev\n );\n }}\n >\n <button\n type=\"button\"\n tabIndex={0}\n data-testid={testId}\n className={clsx(linkClassName, styles.linkButton)}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n styles.chevronIconDesktop,\n selected && styles.chevronIconSelected,\n isDesktopExpanded && styles.subMenuExpanded\n )}\n />\n </button>\n </DesktopMenu>\n );\n };\n\n return (\n <li\n key={index}\n className={clsx(\n styles.linkItem,\n hideNavBranding && styles.linkItemHiddenBranding\n )}\n >\n {hasSubMenu\n ? renderLinkWithSubmenu(index === items.length - 1)\n : renderLink()}\n </li>\n );\n };\n\n const renderItems = () =>\n items.map((item, index) => {\n switch (item.itemType) {\n case \"component\": {\n return <li key={index}>{item.children ?? null}</li>;\n }\n case \"link\":\n default: {\n return renderLinkItem(item as NavItemLinkProps<T>, index);\n }\n }\n });\n\n if (items && items.length > 0) {\n return mobile ? (\n <ul ref={listRef} className={styles.mobileWrapper}>\n {renderItems()}\n </ul>\n ) : (\n <ul\n ref={listRef}\n className={clsx(\n styles.wrapper,\n hideNavBranding && styles.wrapperAlignLeft\n )}\n >\n {renderItems()}\n </ul>\n );\n }\n\n return <></>;\n};\n"],"names":["NavbarItems","items","selectedId","mobile","hideNavBranding","hideLinkIndicator","onItemClick","selectedIndex","setSelectedIndex","useState","listRef","useRef","instanceId","useId","hasSelectedSubMenuItem","item","_a","subMenu","some","subItem","id","itemIndexWithSelectedSubItem","findIndex","itemType","initialExpandedItemIndex","useEffect","handleClickOutside","event","current","contains","target","document","addEventListener","removeEventListener","handleLinkClick","index","stopPropagation","prev","length","handleMobileSubLinkClick","renderDesktopSubMenu","subMenuId","_jsx","DesktopMenu","Content","children","Section","showDivider","map","subIndex","Link","href","renderMobileSubMenu","MobileMenu","renderLinkItem","options","otherItemAttrs","__rest","hasSubMenu","isRouteSelected","checkSelected","isDesktopExpanded","isMobileExpanded","isExpanded","selected","showIndicator","testId","renderIndicator","className","clsx","styles.linkIndicator","styles.linkIndicatorSelected","linkClassName","styles.link","weight","styles.linkWeightBold","styles.linkWeightSemibold","styles.linkWeightRegular","getLinkWeightClass","styles.linkSelected","styles.linkItem","styles.linkItemHiddenBranding","isLastItem","_jsxs","_Fragment","Object","assign","undefined","onClick","styles.linkLabel","styles.linkIconContainer","ClickableIcon","styles.expandCollapseButton","styles.subMenuExpanded","focusHighlight","focusOutline","ChevronUpIcon","styles.chevronIcon","styles.chevronIconSelected","position","customOffset","menuContent","triggerOnFocus","isModal","onPopoverAppear","onPopoverDismiss","type","tabIndex","styles.linkButton","styles.chevronIconDesktop","renderLinkWithSubmenu","renderItems","ref","styles.mobileWrapper","styles.wrapper","styles.wrapperAlignLeft"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"navbar-items.js","sources":["../../src/navbar/navbar-items.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { Menu as DesktopMenu } from \"../menu\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport type { TypographyWeight } from \"../typography\";\nimport { useId } from \"../util\";\nimport { Menu as MobileMenu } from \"./menu\";\nimport * as styles from \"./navbar-items.styles\";\nimport type {\n NavItemCommonProps,\n NavItemLinkProps,\n NavItemProps,\n} from \"./types\";\n\nconst getLinkWeightClass = (weight: TypographyWeight) => {\n switch (weight) {\n case \"bold\":\n return styles.linkWeightBold;\n case \"semibold\":\n return styles.linkWeightSemibold;\n case \"regular\":\n default:\n return styles.linkWeightRegular;\n }\n};\n\ninterface Props<T> {\n items: NavItemProps<T>[];\n selectedId?: string | undefined;\n /** toggle for mobile or desktop view */\n mobile?: boolean | undefined;\n hideNavBranding?: boolean | undefined;\n /** hide the selected LinkIndicator */\n hideLinkIndicator?: boolean | undefined;\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemProps<T> | NavItemCommonProps<T>\n ) => void;\n}\n\nexport const NavbarItems = <T,>({\n items,\n selectedId,\n mobile = false,\n hideNavBranding,\n hideLinkIndicator = false,\n onItemClick,\n}: Props<T>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const [selectedIndex, setSelectedIndex] = useState<number | null>(null);\n const listRef = useRef<HTMLUListElement>(null);\n const instanceId = useId();\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const hasSelectedSubMenuItem = (item: NavItemLinkProps<T>): boolean =>\n !!item.subMenu?.some((subItem) => subItem.id === selectedId);\n\n const checkSelected = (item: NavItemLinkProps<T>): boolean =>\n item.id === selectedId || hasSelectedSubMenuItem(item);\n\n const itemIndexWithSelectedSubItem = mobile\n ? items.findIndex(\n (item) =>\n item.itemType !== \"component\" &&\n hasSelectedSubMenuItem(item as NavItemLinkProps<T>)\n )\n : -1;\n const initialExpandedItemIndex =\n itemIndexWithSelectedSubItem < 0 ? null : itemIndexWithSelectedSubItem;\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n\n useEffect(() => {\n if (!mobile) return;\n\n setSelectedIndex(initialExpandedItemIndex);\n }, [mobile, initialExpandedItemIndex]);\n\n useEffect(() => {\n if (mobile) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (\n listRef.current &&\n !listRef.current.contains(event.target as Node)\n ) {\n setSelectedIndex(null);\n }\n };\n document.addEventListener(\"click\", handleClickOutside, true);\n return () => {\n document.removeEventListener(\"click\", handleClickOutside, true);\n };\n }, [mobile]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleLinkClick = (item: NavItemLinkProps<T>, index: number) => {\n return (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation();\n\n // mobile expands inline when link has submenu\n if (mobile) {\n setSelectedIndex((prev) =>\n item.subMenu?.length && prev !== index ? index : null\n );\n }\n\n onItemClick(event, item);\n };\n };\n\n const handleMobileSubLinkClick = (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => {\n event.stopPropagation();\n onItemClick(event, item);\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderDesktopSubMenu = (\n subMenu: NavItemCommonProps<T>[],\n subMenuId: string,\n columns?: number\n ) => (\n <DesktopMenu.Content id={subMenuId}>\n <DesktopMenu.Section showDivider={false} columns={columns}>\n {subMenu.map((item, subIndex) => (\n <DesktopMenu.Link\n key={`${item.id}-${subIndex}`}\n href={item.href}\n >\n {item.children}\n </DesktopMenu.Link>\n ))}\n </DesktopMenu.Section>\n </DesktopMenu.Content>\n );\n\n const renderMobileSubMenu = (subMenu: NavItemCommonProps<T>[]) => (\n <MobileMenu\n items={subMenu}\n selectedId={selectedId}\n onItemClick={handleMobileSubLinkClick}\n />\n );\n\n const renderLinkItem = (item: NavItemLinkProps<T>, index: number) => {\n const {\n children,\n options,\n subMenu,\n subMenuColumns,\n ...otherItemAttrs\n } = item;\n\n const hasSubMenu = !!subMenu?.length;\n\n const isRouteSelected = checkSelected(item);\n\n // desktop popover open state\n const isDesktopExpanded =\n !mobile && hasSubMenu && selectedIndex === index;\n\n // mobile inline expanded state\n const isMobileExpanded =\n mobile && hasSubMenu && selectedIndex === index;\n\n const isExpanded = isDesktopExpanded || isMobileExpanded;\n\n const selected =\n !mobile && selectedIndex !== null\n ? selectedIndex === index\n : isRouteSelected;\n\n const showIndicator = !hideLinkIndicator && selected;\n\n const textWeight: TypographyWeight = selected\n ? mobile\n ? \"bold\"\n : \"semibold\"\n : \"regular\";\n\n const testId = mobile\n ? `link__mobile-${index + 1}`\n : `link__${index + 1}`;\n\n const renderIndicator = () =>\n showIndicator ? (\n <div\n data-testid={`${testId}-indicator`}\n className={clsx(\n styles.linkIndicator,\n selected && styles.linkIndicatorSelected\n )}\n />\n ) : null;\n\n const renderMobileChevron = () =>\n mobile && hasSubMenu ? (\n <div className={styles.linkIconContainer}>\n <ClickableIcon\n data-testid={`${testId}-expand-collapse-button`}\n className={clsx(\n styles.expandCollapseButton,\n isMobileExpanded && styles.subMenuExpanded\n )}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={isMobileExpanded ? \"Collapse\" : \"Expand\"}\n >\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n selected && styles.chevronIconSelected\n )}\n />\n </ClickableIcon>\n </div>\n ) : null;\n\n const linkClassName = clsx(\n styles.link,\n getLinkWeightClass(textWeight),\n selected && styles.linkSelected\n );\n\n const renderLink = () => (\n <a\n tabIndex={0}\n data-testid={testId}\n className={linkClassName}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n </a>\n );\n\n const renderLinkWithSubmenu = (isLastItem: boolean) => {\n const subMenuId = `navbar-submenu-${instanceId}-${item.id}`;\n\n if (mobile) {\n return (\n <>\n <a\n data-testid={testId}\n className={linkClassName}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n {renderMobileChevron()}\n </a>\n\n {isMobileExpanded && renderMobileSubMenu(subMenu!)}\n </>\n );\n }\n\n return (\n <DesktopMenu\n position={isLastItem ? \"bottom-end\" : \"bottom\"}\n customOffset={0}\n menuContent={renderDesktopSubMenu(\n subMenu!,\n subMenuId,\n subMenuColumns\n )}\n enableResize\n triggerOnFocus\n isModal={false}\n onPopoverAppear={() => {\n setSelectedIndex(index);\n }}\n onPopoverDismiss={() => {\n setSelectedIndex((prev) =>\n prev === index ? null : prev\n );\n }}\n >\n <button\n type=\"button\"\n tabIndex={0}\n data-testid={testId}\n className={clsx(linkClassName, styles.linkButton)}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n styles.chevronIconDesktop,\n selected && styles.chevronIconSelected,\n isDesktopExpanded && styles.subMenuExpanded\n )}\n />\n </button>\n </DesktopMenu>\n );\n };\n\n return (\n <li\n key={index}\n className={clsx(\n styles.linkItem,\n hideNavBranding && styles.linkItemHiddenBranding\n )}\n >\n {hasSubMenu\n ? renderLinkWithSubmenu(index === items.length - 1)\n : renderLink()}\n </li>\n );\n };\n\n const renderItems = () =>\n items.map((item, index) => {\n switch (item.itemType) {\n case \"component\": {\n return <li key={index}>{item.children ?? null}</li>;\n }\n case \"link\":\n default: {\n return renderLinkItem(item as NavItemLinkProps<T>, index);\n }\n }\n });\n\n if (items && items.length > 0) {\n return mobile ? (\n <ul ref={listRef} className={styles.mobileWrapper}>\n {renderItems()}\n </ul>\n ) : (\n <ul\n ref={listRef}\n className={clsx(\n styles.wrapper,\n hideNavBranding && styles.wrapperAlignLeft\n )}\n >\n {renderItems()}\n </ul>\n );\n }\n\n return <></>;\n};\n"],"names":["NavbarItems","items","selectedId","mobile","hideNavBranding","hideLinkIndicator","onItemClick","selectedIndex","setSelectedIndex","useState","listRef","useRef","instanceId","useId","hasSelectedSubMenuItem","item","_a","subMenu","some","subItem","id","itemIndexWithSelectedSubItem","findIndex","itemType","initialExpandedItemIndex","useEffect","handleClickOutside","event","current","contains","target","document","addEventListener","removeEventListener","handleLinkClick","index","stopPropagation","prev","length","handleMobileSubLinkClick","renderDesktopSubMenu","subMenuId","columns","_jsx","DesktopMenu","Content","children","Section","showDivider","map","subIndex","Link","href","renderMobileSubMenu","MobileMenu","renderLinkItem","options","subMenuColumns","otherItemAttrs","__rest","hasSubMenu","isRouteSelected","checkSelected","isDesktopExpanded","isMobileExpanded","isExpanded","selected","showIndicator","testId","renderIndicator","className","clsx","styles.linkIndicator","styles.linkIndicatorSelected","linkClassName","styles.link","weight","styles.linkWeightBold","styles.linkWeightSemibold","styles.linkWeightRegular","getLinkWeightClass","styles.linkSelected","styles.linkItem","styles.linkItemHiddenBranding","isLastItem","_jsxs","_Fragment","Object","assign","undefined","onClick","styles.linkLabel","styles.linkIconContainer","ClickableIcon","styles.expandCollapseButton","styles.subMenuExpanded","focusHighlight","focusOutline","ChevronUpIcon","styles.chevronIcon","styles.chevronIconSelected","position","customOffset","menuContent","enableResize","triggerOnFocus","isModal","onPopoverAppear","onPopoverDismiss","type","tabIndex","styles.linkButton","styles.chevronIconDesktop","renderLinkWithSubmenu","renderItems","ref","styles.mobileWrapper","styles.wrapper","styles.wrapperAlignLeft"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const s={primary:{brandName:"LifeSG",logoSrc:"https://assets.life.gov.sg/lifesg/logo-lifesg.svg"}},e={primary:{brandName:"BookingSG",logoSrc:"https://www.booking.gov.sg/logo.svg"}},o={primary:{brandName:"CCube",logoSrc:"https://assets.life.gov.sg/ccube/logo-ccube.svg"}},g={primary:{brandName:"IMDA",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/imda-logo.svg"}},r={primary:{brandName:"MyLegacy",logoSrc:"https://mylegacy.life.gov.sg/images/site-logo.png"}},a={primary:{brandName:"SPF",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/spf-logo.png"}},t={primary:{brandName:"SupportGoWhere",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/sgw-logo.png"}},
|
|
1
|
+
const s={primary:{brandName:"LifeSG",logoSrc:"https://assets.life.gov.sg/lifesg/logo-lifesg.svg"}},e={primary:{brandName:"BookingSG",logoSrc:"https://www.booking.gov.sg/logo.svg"}},o={primary:{brandName:"CCube",logoSrc:"https://assets.life.gov.sg/ccube/logo-ccube.svg"}},g={primary:{brandName:"IMDA",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/imda-logo.svg"}},r={primary:{brandName:"MyLegacy",logoSrc:"https://mylegacy.life.gov.sg/images/site-logo.png"}},a={primary:{brandName:"SPF",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/spf-logo.png"}},t={primary:{brandName:"SportSG",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/sportsg-logo.svg"}},i={primary:{brandName:"SupportGoWhere",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/sgw-logo.png"}},l={primary:{brandName:"Tote Board",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/tote-board-logo.svg"}},c=c=>{switch(c){case"bookingsg":return e;case"mylegacy":return r;case"ccube":return o;case"spf":return a;case"supportgowhere":case"sgw-digital-lobby":return i;case"imda":return g;case"tote-board":return l;case"sportsg-orange":return t;default:return s}};export{c as getDefaultResourceLogo};
|
|
2
2
|
//# sourceMappingURL=navbar-logo-data.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navbar-logo-data.js","sources":["../../src/navbar/navbar-logo-data.ts"],"sourcesContent":["import type { ThemeType } from \"../theme/types\";\nimport type { NavbarResourcesProps } from \"./types\";\n\nconst DEFAULT_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"LifeSG\",\n logoSrc: \"https://assets.life.gov.sg/lifesg/logo-lifesg.svg\",\n },\n};\n\nconst BOOKINGSG_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"BookingSG\",\n logoSrc: \"https://www.booking.gov.sg/logo.svg\",\n },\n};\n\nconst CCUBE_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"CCube\",\n logoSrc: \"https://assets.life.gov.sg/ccube/logo-ccube.svg\",\n },\n};\n\nconst IMDA_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"IMDA\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/imda-logo.svg\",\n },\n};\n\nconst MYLEGACY_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"MyLegacy\",\n logoSrc: \"https://mylegacy.life.gov.sg/images/site-logo.png\",\n },\n};\n\nconst SPF_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SPF\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/spf-logo.png\",\n },\n};\n\nconst SUPPORTGOWHERE_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SupportGoWhere\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/sgw-logo.png\",\n },\n};\n\nconst TOTEBOARD_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"Tote Board\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/tote-board-logo.svg\",\n },\n};\n\nexport const getDefaultResourceLogo = (resourceScheme?: ThemeType) => {\n switch (resourceScheme) {\n case \"bookingsg\":\n return BOOKINGSG_RESOURCES_LOGO;\n case \"mylegacy\":\n return MYLEGACY_RESOURCES_LOGO;\n case \"ccube\":\n return CCUBE_RESOURCES_LOGO;\n case \"spf\":\n return SPF_RESOURCE_LOGO;\n case \"supportgowhere\":\n case \"sgw-digital-lobby\":\n return SUPPORTGOWHERE_RESOURCE_LOGO;\n case \"imda\":\n return IMDA_RESOURCE_LOGO;\n case \"tote-board\":\n return TOTEBOARD_RESOURCES_LOGO;\n default:\n return DEFAULT_RESOURCES_LOGO;\n }\n};\n"],"names":["DEFAULT_RESOURCES_LOGO","primary","brandName","logoSrc","BOOKINGSG_RESOURCES_LOGO","CCUBE_RESOURCES_LOGO","IMDA_RESOURCE_LOGO","MYLEGACY_RESOURCES_LOGO","SPF_RESOURCE_LOGO","SUPPORTGOWHERE_RESOURCE_LOGO","TOTEBOARD_RESOURCES_LOGO","getDefaultResourceLogo","resourceScheme"],"mappings":"AAGA,MAAMA,EAA+C,CACjDC,QAAS,CACLC,UAAW,SACXC,QAAS,sDAIXC,EAAiD,CACnDH,QAAS,CACLC,UAAW,YACXC,QAAS,wCAIXE,EAA6C,CAC/CJ,QAAS,CACLC,UAAW,QACXC,QAAS,oDAIXG,EAA2C,CAC7CL,QAAS,CACLC,UAAW,OACXC,QACI,0EAINI,EAAgD,CAClDN,QAAS,CACLC,UAAW,WACXC,QAAS,sDAIXK,EAA0C,CAC5CP,QAAS,CACLC,UAAW,MACXC,QACI,yEAINM,EAAqD,
|
|
1
|
+
{"version":3,"file":"navbar-logo-data.js","sources":["../../src/navbar/navbar-logo-data.ts"],"sourcesContent":["import type { ThemeType } from \"../theme/types\";\nimport type { NavbarResourcesProps } from \"./types\";\n\nconst DEFAULT_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"LifeSG\",\n logoSrc: \"https://assets.life.gov.sg/lifesg/logo-lifesg.svg\",\n },\n};\n\nconst BOOKINGSG_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"BookingSG\",\n logoSrc: \"https://www.booking.gov.sg/logo.svg\",\n },\n};\n\nconst CCUBE_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"CCube\",\n logoSrc: \"https://assets.life.gov.sg/ccube/logo-ccube.svg\",\n },\n};\n\nconst IMDA_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"IMDA\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/imda-logo.svg\",\n },\n};\n\nconst MYLEGACY_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"MyLegacy\",\n logoSrc: \"https://mylegacy.life.gov.sg/images/site-logo.png\",\n },\n};\n\nconst SPF_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SPF\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/spf-logo.png\",\n },\n};\n\nconst SPORTSG_ORANGE_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SportSG\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/sportsg-logo.svg\",\n },\n};\n\nconst SUPPORTGOWHERE_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SupportGoWhere\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/sgw-logo.png\",\n },\n};\n\nconst TOTEBOARD_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"Tote Board\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/tote-board-logo.svg\",\n },\n};\n\nexport const getDefaultResourceLogo = (resourceScheme?: ThemeType) => {\n switch (resourceScheme) {\n case \"bookingsg\":\n return BOOKINGSG_RESOURCES_LOGO;\n case \"mylegacy\":\n return MYLEGACY_RESOURCES_LOGO;\n case \"ccube\":\n return CCUBE_RESOURCES_LOGO;\n case \"spf\":\n return SPF_RESOURCE_LOGO;\n case \"supportgowhere\":\n case \"sgw-digital-lobby\":\n return SUPPORTGOWHERE_RESOURCE_LOGO;\n case \"imda\":\n return IMDA_RESOURCE_LOGO;\n case \"tote-board\":\n return TOTEBOARD_RESOURCES_LOGO;\n case \"sportsg-orange\":\n return SPORTSG_ORANGE_RESOURCES_LOGO;\n default:\n return DEFAULT_RESOURCES_LOGO;\n }\n};\n"],"names":["DEFAULT_RESOURCES_LOGO","primary","brandName","logoSrc","BOOKINGSG_RESOURCES_LOGO","CCUBE_RESOURCES_LOGO","IMDA_RESOURCE_LOGO","MYLEGACY_RESOURCES_LOGO","SPF_RESOURCE_LOGO","SPORTSG_ORANGE_RESOURCES_LOGO","SUPPORTGOWHERE_RESOURCE_LOGO","TOTEBOARD_RESOURCES_LOGO","getDefaultResourceLogo","resourceScheme"],"mappings":"AAGA,MAAMA,EAA+C,CACjDC,QAAS,CACLC,UAAW,SACXC,QAAS,sDAIXC,EAAiD,CACnDH,QAAS,CACLC,UAAW,YACXC,QAAS,wCAIXE,EAA6C,CAC/CJ,QAAS,CACLC,UAAW,QACXC,QAAS,oDAIXG,EAA2C,CAC7CL,QAAS,CACLC,UAAW,OACXC,QACI,0EAINI,EAAgD,CAClDN,QAAS,CACLC,UAAW,WACXC,QAAS,sDAIXK,EAA0C,CAC5CP,QAAS,CACLC,UAAW,MACXC,QACI,yEAINM,EAAsD,CACxDR,QAAS,CACLC,UAAW,UACXC,QACI,6EAINO,EAAqD,CACvDT,QAAS,CACLC,UAAW,iBACXC,QACI,yEAINQ,EAAiD,CACnDV,QAAS,CACLC,UAAW,aACXC,QACI,gFAICS,EAA0BC,IACnC,OAAQA,GACJ,IAAK,YACD,OAAOT,EACX,IAAK,WACD,OAAOG,EACX,IAAK,QACD,OAAOF,EACX,IAAK,MACD,OAAOG,EACX,IAAK,iBACL,IAAK,oBACD,OAAOE,EACX,IAAK,OACD,OAAOJ,EACX,IAAK,aACD,OAAOK,EACX,IAAK,iBACD,OAAOF,EACX,QACI,OAAOT"}
|
package/navbar/types.d.ts
CHANGED
|
@@ -6,6 +6,15 @@ import type { TypographyLinkProps } from "../typography";
|
|
|
6
6
|
export interface NavItemLinkProps<T> extends NavItemCommonProps<T> {
|
|
7
7
|
itemType?: "link";
|
|
8
8
|
subMenu?: NavItemCommonProps<T>[] | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Renders `subMenu` as a multi-column layout on desktop. Items flow
|
|
11
|
+
* vertically (top-to-bottom) within each column before wrapping to the
|
|
12
|
+
* next. Has no effect on the mobile drawer, which always renders `subMenu`
|
|
13
|
+
* as an expandable vertical list.
|
|
14
|
+
*
|
|
15
|
+
* @minimum 1
|
|
16
|
+
*/
|
|
17
|
+
subMenuColumns?: number | undefined;
|
|
9
18
|
}
|
|
10
19
|
/**
|
|
11
20
|
* Props for a custom component slot navigation item.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{__rest as t}from"../_virtual/_tslib.js";import{jsx as r}from"react/jsx-runtime";import e from"../external/dompurify/dist/purify.es.js";import n from"react";import{NBComponent as i,NotificationBanner as o}from"./notification-banner.js";const s=s=>n.forwardRef(((n,a)=>r(i,Object.assign({forwardedRef:a},n,{children:s.length>0?s.map(((n,i)=>{var s;if("text"===n.type){const t=n.otherAttributes,o=e.sanitize(n.content);return r("p",Object.assign({},t,{dangerouslySetInnerHTML:{__html:o}}),i)}{const a=function(r){const{href:n}=r,i=t(r,["href"]);return"string"==typeof n&&e.isValidAttribute("a","href",n)?r:i}(null!==(s=n.otherAttributes)&&void 0!==s?s:{});return r(o.Link,Object.assign({},a,{children:n.content}),i)}})):(console.error("[NotificationBannerHOC] Empty data passed"),null)}))));export{s as withNotificationBanner};
|
|
2
2
|
//# sourceMappingURL=notification-banner-hoc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-banner-hoc.js","sources":["../../src/notification-banner/notification-banner-hoc.tsx"],"sourcesContent":["import DOMPurify from \"dompurify\";\nimport React from \"react\";\n\nimport { NBComponent, NotificationBanner } from \"./notification-banner\";\nimport type {\n ContentLinkAttributes,\n ContentTextAttributes,\n NotificationBannerWithForwardedRefProps,\n NotificationContentAttributes,\n} from \"./types\";\n\n/**\n * Higher-order component that wraps `NotificationBanner` and renders its\n * content from a structured data array.\n * *\n * @param data Content items to render inside the banner.\n */\nexport const withNotificationBanner = (\n data: NotificationContentAttributes[]\n) => {\n const ComponentToReturn = (\n props: NotificationBannerWithForwardedRefProps,\n ref: React.Ref<HTMLDivElement>\n ) => {\n const renderContent = () => {\n if (data.length > 0) {\n return data.map((attribute, index) => {\n if (attribute.type === \"text\") {\n const otherAttributes =\n attribute.otherAttributes as ContentTextAttributes;\n\n const sanitizedContent = DOMPurify.sanitize(\n attribute.content\n );\n return (\n <p\n key={index}\n {...otherAttributes}\n dangerouslySetInnerHTML={{\n __html: sanitizedContent,\n }}\n />\n );\n } else {\n const otherAttributes
|
|
1
|
+
{"version":3,"file":"notification-banner-hoc.js","sources":["../../src/notification-banner/notification-banner-hoc.tsx"],"sourcesContent":["import DOMPurify from \"dompurify\";\nimport React from \"react\";\n\nimport { NBComponent, NotificationBanner } from \"./notification-banner\";\nimport type {\n ContentLinkAttributes,\n ContentTextAttributes,\n NotificationBannerWithForwardedRefProps,\n NotificationContentAttributes,\n} from \"./types\";\n\nfunction sanitizeLinkAttributes(\n attrs: ContentLinkAttributes\n): ContentLinkAttributes {\n const { href, ...rest } = attrs;\n\n if (\n typeof href !== \"string\" ||\n !DOMPurify.isValidAttribute(\"a\", \"href\", href)\n ) {\n return rest;\n }\n\n return attrs;\n}\n\n/**\n * Higher-order component that wraps `NotificationBanner` and renders its\n * content from a structured data array.\n * *\n * @param data Content items to render inside the banner.\n */\nexport const withNotificationBanner = (\n data: NotificationContentAttributes[]\n) => {\n const ComponentToReturn = (\n props: NotificationBannerWithForwardedRefProps,\n ref: React.Ref<HTMLDivElement>\n ) => {\n const renderContent = () => {\n if (data.length > 0) {\n return data.map((attribute, index) => {\n if (attribute.type === \"text\") {\n const otherAttributes =\n attribute.otherAttributes as ContentTextAttributes;\n\n const sanitizedContent = DOMPurify.sanitize(\n attribute.content\n );\n return (\n <p\n key={index}\n {...otherAttributes}\n dangerouslySetInnerHTML={{\n __html: sanitizedContent,\n }}\n />\n );\n } else {\n const otherAttributes = sanitizeLinkAttributes(\n (attribute.otherAttributes ??\n {}) as ContentLinkAttributes\n );\n return (\n <NotificationBanner.Link\n key={index}\n {...otherAttributes}\n >\n {attribute.content}\n </NotificationBanner.Link>\n );\n }\n });\n }\n\n console.error(\"[NotificationBannerHOC] Empty data passed\");\n return null;\n };\n\n return (\n <NBComponent forwardedRef={ref} {...props}>\n {renderContent()}\n </NBComponent>\n );\n };\n\n return React.forwardRef(ComponentToReturn);\n};\n"],"names":["withNotificationBanner","data","React","forwardRef","props","ref","_jsx","NBComponent","Object","assign","forwardedRef","children","length","map","attribute","index","type","otherAttributes","sanitizedContent","DOMPurify","sanitize","content","dangerouslySetInnerHTML","__html","attrs","href","rest","__rest","isValidAttribute","sanitizeLinkAttributes","_a","NotificationBanner","Link","console","error"],"mappings":"kPAgCO,MAAMA,EACTC,GAqDOC,EAAMC,YAnDa,CACtBC,EACAC,IA2CIC,EAACC,EAAWC,OAAAC,OAAA,CAACC,aAAcL,GAASD,EAAK,CAAAO,SAxCrCV,EAAKW,OAAS,EACPX,EAAKY,KAAI,CAACC,EAAWC,WACxB,GAAuB,SAAnBD,EAAUE,KAAiB,CAC3B,MAAMC,EACFH,EAAUG,gBAERC,EAAmBC,EAAUC,SAC/BN,EAAUO,SAEd,OACIf,EAAA,IAAAE,OAAAC,OAAA,GAEQQ,EAAe,CACnBK,wBAAyB,CACrBC,OAAQL,KAHPH,EAOjB,CAAO,CACH,MAAME,EAhD9B,SACIO,GAEA,MAAMC,KAAEA,GAAkBD,EAATE,EAAIC,EAAKH,EAApB,CAAA,SAEN,MACoB,iBAATC,GACNN,EAAUS,iBAAiB,IAAK,OAAQH,GAKtCD,EAHIE,CAIf,CAmCgDG,CACM,QAAzBC,EAAAhB,EAAUG,uBAAe,IAAAa,EAAAA,EACtB,CAAA,GAER,OACIxB,EAACyB,EAAmBC,KAAIxB,OAAAC,OAAA,CAAA,EAEhBQ,EAAe,CAAAN,SAElBG,EAAUO,UAHNN,EAMjB,MAIRkB,QAAQC,MAAM,6CACP"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifesg/react-design-system",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.13",
|
|
4
4
|
"description": "A component design system for LifeSG web apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"design-system"
|
|
@@ -28,8 +28,7 @@
|
|
|
28
28
|
"default": "./index.js"
|
|
29
29
|
},
|
|
30
30
|
"./theme/styles/*.css": {
|
|
31
|
-
"
|
|
32
|
-
"require": "./theme/styles/*.css"
|
|
31
|
+
"default": "./theme/styles/*.css"
|
|
33
32
|
},
|
|
34
33
|
"./accordion": {
|
|
35
34
|
"types": "./accordion/index.d.ts",
|
package/pagination/pagination.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsxs as e,jsx as
|
|
1
|
+
import{jsxs as e,jsx as a}from"react/jsx-runtime";import{Chevron2LeftIcon as i}from"@lifesg/react-icons/chevron-2-left";import{Chevron2RightIcon as r}from"@lifesg/react-icons/chevron-2-right";import{ChevronLeftIcon as o}from"@lifesg/react-icons/chevron-left";import{ChevronLineLeftIcon as t}from"@lifesg/react-icons/chevron-line-left";import{ChevronLineRightIcon as l}from"@lifesg/react-icons/chevron-line-right";import{ChevronRightIcon as s}from"@lifesg/react-icons/chevron-right";import{EllipsisHorizontalIcon as n}from"@lifesg/react-icons/ellipsis-horizontal";import c from"clsx";import m,{useState as d,useEffect as p}from"react";import{Input as u}from"../input/input.js";import{InputSelect as h}from"../input-select/input-select.js";import{VisuallyHidden as g}from"../shared/accessibility/index.js";import{ClickableIcon as f}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"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as v}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{useIsMounted as b}from"../util/use-mount.js";import{useMaxWidthMediaQuery as N}from"../theme/utils/use-media-query.js";import{Typography as j}from"../typography/index.js";import{paginationList as x,paginationMenu as y,iconButton as k,iconButtonNavigation as C,inputSelectWrapper as M,paginationWrapper as O,paginationMobileInput as w,inputView as $,labelDivider as P,label as S,pageItem as z,pageItemSelected as B,ellipsisContainer as F,hover as H}from"./pagination.styles.js";const L=m.forwardRef((({id:m,"data-testid":L,className:I,variant:q="default",pageSize:A=10,totalItems:D,activePage:R,pageSizeOptions:V=E,showFirstAndLastNav:G,showPageSizeChanger:J=!1,onPageChange:K,onPageSizeChange:Q},T)=>{const U=b(),W=N("sm"),X="default"===q?U&&W?"compact":"full":q,Y="compact"===X,Z=J&&"full"===X,[_,ee]=d(!1),[ae,ie]=d(!1),[re,oe]=d(""),[te,le]=d(A),se=((e,a)=>{var i;return null!==(i=e.find((e=>e.value===a)))&&void 0!==i?i:e[0]})(V,te),ne=`${v()}-pagination`,ce=Math.ceil(D/te),me=1===R,de=R===ce,pe=R>1?()=>be(1):void 0,ue=R<ce?()=>be(ce):void 0,he=R>1?()=>be(R-1):void 0,ge=R<ce?()=>be(parseInt(R.toString())+1):void 0;p((()=>{R&&fe(R)}),[R]),p((()=>{le(A)}),[A]);const fe=e=>{oe(e.toString())},ve=()=>{ee(!1),ie(!1)},be=e=>{K&&(K(e),fe(e))},Ne=()=>{const e=Math.min(ce,R+5);be(e),fe(e),ee(!0),ie(!1)},je=()=>{const e=Math.max(1,R-5);be(e),fe(e),ee(!1),ie(!0)},xe=e=>{const a=e.target.value;if(void 0===a||0===a.length)oe("");else if(/^[0-9]+$/.test(a)){const e=parseInt(a.replace(/[^0-9]/g,""));fe(Math.max(1,Math.min(ce,e)))}else oe(a.replace(/[^0-9]/g,""))},ye=e=>{e.preventDefault(),re&&(null==K||K(parseInt(re)))},ke=()=>{ee(!0)},Ce=()=>{ee(!1)},Me=()=>{ie(!0)},Oe=()=>{ie(!1)},we=r=>e("div",{className:F,children:[a(f,{className:k,focusHighlight:!1,focusOutline:"browser","aria-label":"Previous 5 pages",onMouseEnter:Me,onMouseLeave:Oe,onFocus:Me,onBlur:Oe,onClick:je,children:a(ae?i:n,{"aria-hidden":!0})}),ae&&a("div",{className:H,children:"Previous 5 pages"})]},r),$e=i=>e("div",{className:F,children:[a(f,{className:k,focusHighlight:!1,focusOutline:"browser","aria-label":"Next 5 pages",onMouseEnter:ke,onMouseLeave:Ce,onFocus:ke,onBlur:Ce,onClick:Ne,children:a(_?r:n,{"aria-hidden":!0})}),_&&a("div",{className:H,children:"Next 5 pages"})]},i);return e("nav",{className:c(O,I),ref:T,id:m||"pagination-wrapper","data-testid":L||"pagination","aria-labelledby":ne,children:[a(g,{id:ne,"aria-hidden":!0,children:"pagination"}),a("div",{className:x,children:e("div",{className:y,children:[G&&a(f,{className:c(k,C),onClick:pe,disabled:me,focusHighlight:!1,"aria-label":"First page",focusOutline:"browser",children:a(t,{"aria-hidden":!0})}),a(f,{className:c(k,C),onClick:he,disabled:me,focusHighlight:!1,"aria-label":"Previous page",focusOutline:"browser",children:a(o,{"aria-hidden":!0})}),Y?e("div",{className:w,children:[a("form",{onSubmit:ye,children:a(u,{className:$,value:re,onChange:xe,autoComplete:"off",type:"numeric",id:(m||"pagination")+"-input","data-testid":(L||"pagination")+"-input","aria-label":`Page ${R} of ${ce}`})}),a(j.BodyBL,{className:P,children:"/"}),a(j.BodyBL,{className:S,children:ce})]}):[...Array(ce)].map(((e,i)=>{const r=i+1,o=ce-5,t=R===r;return ce<=7?a("button",{onClick:()=>be(r),className:c(z,t&&B),"aria-label":`page ${r} of ${ce}`,"aria-current":!!t&&"page",onMouseOver:ve,onFocus:ve,children:r},r):R+1>5&&2===r?we(r):R-1<=o&&r===ce-1-1?$e(r):r<=5&&R+1<=5||r<=1||r===R||r<=R+1&&r>=R-1-1||r>o&&R-1>o||r>ce-1?a("button",{onClick:()=>be(r),className:c(z,t&&B),"aria-label":`page ${r} of ${ce}`,"aria-current":!!t&&"page",onMouseOver:ve,onFocus:ve,children:r},r):null})),a(f,{className:c(k,C),onClick:ge,disabled:de,focusHighlight:!1,"aria-label":"Next page",focusOutline:"browser",children:a(s,{"aria-hidden":!0})}),G&&a(f,{className:c(k,C),onClick:ue,disabled:de,focusHighlight:!1,"aria-label":"Last page",focusOutline:"browser",children:a(l,{"aria-hidden":!0})})]})}),Z&&e("div",{className:M,children:[a(g,{id:`${ne}-page-size`,children:"Items per page"}),a(h,{"aria-labelledby":`${ne}-page-size`,options:V,valueExtractor:e=>e.value,listExtractor:e=>e.label,displayValueExtractor:e=>e.label,selectedOption:se,onSelectOption:e=>{const a=e.value,i=Math.ceil(D/a);le(a);Q&&Q(R>=i?i:R,a)}})]})]})})),E=[{value:10,label:"10 per page"},{value:20,label:"20 per page"},{value:30,label:"30 per page"}];export{L as Pagination};
|
|
2
2
|
//# sourceMappingURL=pagination.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","sources":["../../src/pagination/pagination.tsx"],"sourcesContent":["import { Chevron2LeftIcon } from \"@lifesg/react-icons/chevron-2-left\";\nimport { Chevron2RightIcon } from \"@lifesg/react-icons/chevron-2-right\";\nimport { ChevronLeftIcon } from \"@lifesg/react-icons/chevron-left\";\nimport { ChevronLineLeftIcon } from \"@lifesg/react-icons/chevron-line-left\";\nimport { ChevronLineRightIcon } from \"@lifesg/react-icons/chevron-line-right\";\nimport { ChevronRightIcon } from \"@lifesg/react-icons/chevron-right\";\nimport { EllipsisHorizontalIcon } from \"@lifesg/react-icons/ellipsis-horizontal\";\nimport clsx from \"clsx\";\nimport React, { useEffect, useState } from \"react\";\n\nimport { Input } from \"../input\";\nimport { InputSelect } from \"../input-select\";\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { useId, useIsMounted } from \"../util\";\nimport * as styles from \"./pagination.styles\";\nimport type { PageSizeItemProps, PaginationProps } from \"./types\";\n\nconst Component = (\n {\n id,\n \"data-testid\": dataTestId,\n className,\n pageSize = 10,\n totalItems,\n activePage,\n pageSizeOptions = DEFAULT_OPTIONS,\n showFirstAndLastNav,\n showPageSizeChanger = false,\n onPageChange,\n onPageSizeChange,\n }: PaginationProps,\n ref: React.Ref<HTMLDivElement>\n) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n\n const isMounted = useIsMounted();\n const isMobile = useMaxWidthMediaQuery(\"sm\");\n const [hoverRightButton, setHoverRightButton] = useState(false);\n const [hoverLeftButton, setHoverLeftButton] = useState(false);\n const [inputText, setInputText] = useState<string>(\"\");\n\n const [selectedOption, setSelectedOption] = useState<\n PageSizeItemProps | undefined\n >(pageSizeOptions[0]);\n const [pageSizeLocal, setPageSize] = useState<number>(\n !isMobile && showPageSizeChanger\n ? selectedOption\n ? selectedOption.value\n : pageSize\n : pageSize\n );\n\n const boundaryRange = 1;\n const siblingRange = 1;\n\n const internalId = useId();\n const paginationId = `${internalId}-pagination`;\n\n const totalPages = Math.ceil(totalItems / pageSizeLocal);\n const isFirstPage = activePage === 1;\n const isLastPage = activePage === totalPages;\n\n const firstPaginationItem =\n activePage > 1 ? () => handlePaginationItemClick(1) : undefined;\n const lastPaginationItem =\n activePage < totalPages\n ? () => handlePaginationItemClick(totalPages)\n : undefined;\n const prevPaginationItem =\n activePage > 1\n ? () => handlePaginationItemClick(activePage - 1)\n : undefined;\n const nextPaginationItem =\n activePage < totalPages\n ? () =>\n handlePaginationItemClick(parseInt(activePage.toString()) + 1)\n : undefined;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n if (activePage) {\n setInputValue(activePage);\n }\n }, [activePage]);\n\n useEffect(() => {\n setPageSize(pageSize);\n setSelectedOption(\n pageSizeOptions.find((option) => option.value === pageSize)\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pageSize]);\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const setInputValue = (value: number) => {\n setInputText(value.toString());\n };\n\n const closeAllTooltips = () => {\n setHoverRightButton(false);\n setHoverLeftButton(false);\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handlePaginationItemClick = (pageIndex: number) => {\n if (onPageChange) {\n onPageChange(pageIndex);\n setInputValue(pageIndex);\n }\n };\n\n const handleFastForwardClick = () => {\n const currentIndex = Math.min(totalPages, activePage + 5);\n handlePaginationItemClick(currentIndex);\n setInputValue(currentIndex);\n setHoverRightButton(true);\n setHoverLeftButton(false);\n };\n\n const handleFastBackwardClick = () => {\n const currentIndex = Math.max(1, activePage - 5);\n handlePaginationItemClick(currentIndex);\n setInputValue(currentIndex);\n setHoverRightButton(false);\n setHoverLeftButton(true);\n };\n\n const handleInput = (event: React.ChangeEvent<HTMLInputElement>) => {\n const value = event.target.value;\n const numericRegex = /^[0-9]+$/;\n if (value === undefined || value.length === 0) {\n setInputText(\"\");\n } else if (!numericRegex.test(value)) {\n setInputText(value.replace(/[^0-9]/g, \"\"));\n } else {\n const newPage = parseInt(value.replace(/[^0-9]/g, \"\"));\n setInputValue(Math.max(1, Math.min(totalPages, newPage)));\n }\n };\n\n const handleInputSubmit = (event: React.FormEvent) => {\n event.preventDefault();\n if (inputText) {\n onPageChange?.(parseInt(inputText));\n }\n };\n\n const onHoverRightButton = () => {\n setHoverRightButton(true);\n };\n\n const onBlurRightButton = () => {\n setHoverRightButton(false);\n };\n\n const onHoverLeftButton = () => {\n setHoverLeftButton(true);\n };\n\n const onBlurLeftButton = () => {\n setHoverLeftButton(false);\n };\n\n const handleListItemClick = (item: PageSizeItemProps) => {\n setSelectedOption(item);\n const pagesize = item.value;\n const totalPage = Math.ceil(totalItems / pagesize);\n\n setPageSize(pagesize);\n\n const page = activePage >= totalPage ? totalPage : activePage;\n\n if (onPageSizeChange) {\n onPageSizeChange(page, pagesize);\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderPaginationItems = () => {\n return [...Array(totalPages)].map((e, i) => {\n const pageIndex = i + 1;\n const startRange = boundaryRange + 2 + siblingRange * 2;\n const endRange = totalPages - startRange;\n const totalRange = (boundaryRange + siblingRange) * 2 + 3;\n const active = activePage === pageIndex;\n if (totalPages <= totalRange) {\n return (\n <button\n key={pageIndex}\n onClick={() => handlePaginationItemClick(pageIndex)}\n className={clsx(\n styles.pageItem,\n active && styles.pageItemSelected\n )}\n aria-label={`page ${pageIndex} of ${totalPages}`}\n aria-current={active ? \"page\" : false}\n onMouseOver={closeAllTooltips}\n onFocus={closeAllTooltips}\n >\n {pageIndex}\n </button>\n );\n }\n\n const ellipsisStart =\n activePage + siblingRange > startRange &&\n pageIndex === boundaryRange + 1;\n if (ellipsisStart) {\n return renderStartEllipsis(pageIndex);\n }\n\n const ellipsisEnd =\n activePage - siblingRange <= endRange &&\n pageIndex === totalPages - boundaryRange - 1;\n if (ellipsisEnd) {\n return renderEndEllipsis(pageIndex);\n }\n\n const paginationStart =\n (pageIndex <= startRange &&\n activePage + siblingRange <= startRange) ||\n pageIndex <= boundaryRange;\n const paginationMiddle =\n pageIndex === activePage ||\n (pageIndex <= activePage + siblingRange &&\n pageIndex >= activePage - siblingRange - 1);\n const paginationEnd =\n (pageIndex > endRange &&\n activePage - siblingRange > endRange) ||\n pageIndex > totalPages - boundaryRange;\n if (paginationStart || paginationMiddle || paginationEnd) {\n return (\n <button\n key={pageIndex}\n onClick={() => handlePaginationItemClick(pageIndex)}\n className={clsx(\n styles.pageItem,\n active && styles.pageItemSelected\n )}\n aria-label={`page ${pageIndex} of ${totalPages}`}\n aria-current={active ? \"page\" : false}\n onMouseOver={closeAllTooltips}\n onFocus={closeAllTooltips}\n >\n {pageIndex}\n </button>\n );\n }\n\n return null;\n });\n };\n\n const renderStartEllipsis = (pageIndex: number) => (\n <div key={pageIndex} className={styles.ellipsisContainer}>\n <ClickableIcon\n className={styles.iconButton}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={\"Previous 5 pages\"}\n onMouseEnter={onHoverLeftButton}\n onMouseLeave={onBlurLeftButton}\n onFocus={onHoverLeftButton}\n onBlur={onBlurLeftButton}\n onClick={handleFastBackwardClick}\n >\n {hoverLeftButton ? (\n <Chevron2LeftIcon aria-hidden />\n ) : (\n <EllipsisHorizontalIcon aria-hidden />\n )}\n </ClickableIcon>\n {hoverLeftButton && (\n <div className={styles.hover}>Previous 5 pages</div>\n )}\n </div>\n );\n\n const renderEndEllipsis = (pageIndex: number) => (\n <div key={pageIndex} className={styles.ellipsisContainer}>\n <ClickableIcon\n className={styles.iconButton}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={\"Next 5 pages\"}\n onMouseEnter={onHoverRightButton}\n onMouseLeave={onBlurRightButton}\n onFocus={onHoverRightButton}\n onBlur={onBlurRightButton}\n onClick={handleFastForwardClick}\n >\n {hoverRightButton ? (\n <Chevron2RightIcon aria-hidden />\n ) : (\n <EllipsisHorizontalIcon aria-hidden />\n )}\n </ClickableIcon>\n {hoverRightButton && (\n <div className={styles.hover}>Next 5 pages</div>\n )}\n </div>\n );\n\n const renderMobile = () => (\n <div className={styles.paginationMobileInput}>\n <form onSubmit={handleInputSubmit}>\n <Input\n className={styles.inputView}\n value={inputText}\n onChange={handleInput}\n autoComplete=\"off\"\n type=\"numeric\"\n id={(id || \"pagination\") + \"-input\"}\n data-testid={(dataTestId || \"pagination\") + \"-input\"}\n aria-label={`Page ${activePage} of ${totalPages}`}\n />\n </form>\n <Typography.BodyBL className={styles.labelDivider}>\n /\n </Typography.BodyBL>\n <Typography.BodyBL className={styles.label}>\n {totalPages}\n </Typography.BodyBL>\n </div>\n );\n\n return (\n <nav\n className={clsx(styles.paginationWrapper, className)}\n ref={ref}\n id={id || \"pagination-wrapper\"}\n data-testid={dataTestId || \"pagination\"}\n aria-labelledby={paginationId}\n >\n <VisuallyHidden id={paginationId} aria-hidden>\n pagination\n </VisuallyHidden>\n <div className={styles.paginationList}>\n <div className={styles.paginationMenu}>\n {showFirstAndLastNav && (\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonNavigation\n )}\n onClick={firstPaginationItem}\n disabled={isFirstPage}\n focusHighlight={false}\n aria-label=\"First page\"\n focusOutline=\"browser\"\n >\n <ChevronLineLeftIcon aria-hidden />\n </ClickableIcon>\n )}\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonNavigation\n )}\n onClick={prevPaginationItem}\n disabled={isFirstPage}\n focusHighlight={false}\n aria-label=\"Previous page\"\n focusOutline=\"browser\"\n >\n <ChevronLeftIcon aria-hidden />\n </ClickableIcon>\n {isMounted && isMobile\n ? renderMobile()\n : renderPaginationItems()}\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonNavigation\n )}\n onClick={nextPaginationItem}\n disabled={isLastPage}\n focusHighlight={false}\n aria-label=\"Next page\"\n focusOutline=\"browser\"\n >\n <ChevronRightIcon aria-hidden />\n </ClickableIcon>\n {showFirstAndLastNav && (\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonNavigation\n )}\n onClick={lastPaginationItem}\n disabled={isLastPage}\n focusHighlight={false}\n aria-label=\"Last page\"\n focusOutline=\"browser\"\n >\n <ChevronLineRightIcon aria-hidden />\n </ClickableIcon>\n )}\n </div>\n </div>\n {showPageSizeChanger && !isMobile && (\n <div className={styles.inputSelectWrapper}>\n <VisuallyHidden id={`${paginationId}-page-size`}>\n Items per page\n </VisuallyHidden>\n <InputSelect\n aria-labelledby={`${paginationId}-page-size`}\n options={pageSizeOptions}\n valueExtractor={(item) => item.value}\n listExtractor={(item) => item.label}\n displayValueExtractor={(item) => item.label}\n selectedOption={selectedOption}\n onSelectOption={handleListItemClick}\n />\n </div>\n )}\n </nav>\n );\n};\n// @catalog\n/**\n * A navigation control for moving through paged content.\n *\n * Use `Pagination` to let users navigate between pages of a data set.\n * @keywords navigation, pager, pages\n */\nexport const Pagination = React.forwardRef(Component);\n\nconst DEFAULT_OPTIONS: PageSizeItemProps[] = [\n { value: 10, label: \"10 per page\" },\n { value: 20, label: \"20 per page\" },\n { value: 30, label: \"30 per page\" },\n];\n"],"names":["Pagination","React","forwardRef","id","dataTestId","className","pageSize","totalItems","activePage","pageSizeOptions","DEFAULT_OPTIONS","showFirstAndLastNav","showPageSizeChanger","onPageChange","onPageSizeChange","ref","isMounted","useIsMounted","isMobile","useMaxWidthMediaQuery","hoverRightButton","setHoverRightButton","useState","hoverLeftButton","setHoverLeftButton","inputText","setInputText","selectedOption","setSelectedOption","pageSizeLocal","setPageSize","value","paginationId","useId","totalPages","Math","ceil","isFirstPage","isLastPage","firstPaginationItem","handlePaginationItemClick","undefined","lastPaginationItem","prevPaginationItem","nextPaginationItem","parseInt","toString","useEffect","setInputValue","find","option","closeAllTooltips","pageIndex","handleFastForwardClick","currentIndex","min","handleFastBackwardClick","max","handleInput","event","target","length","test","newPage","replace","handleInputSubmit","preventDefault","onHoverRightButton","onBlurRightButton","onHoverLeftButton","onBlurLeftButton","renderStartEllipsis","_jsxs","styles.ellipsisContainer","children","_jsx","ClickableIcon","styles.iconButton","focusHighlight","focusOutline","onMouseEnter","onMouseLeave","onFocus","onBlur","onClick","Chevron2LeftIcon","EllipsisHorizontalIcon","styles.hover","renderEndEllipsis","Chevron2RightIcon","clsx","styles.paginationWrapper","VisuallyHidden","styles.paginationList","styles.paginationMenu","styles.iconButtonNavigation","disabled","ChevronLineLeftIcon","ChevronLeftIcon","styles.paginationMobileInput","onSubmit","Input","styles.inputView","onChange","autoComplete","type","Typography","BodyBL","styles.labelDivider","styles.label","Array","map","e","i","endRange","boundaryRange","active","styles.pageItem","styles.pageItemSelected","onMouseOver","ChevronRightIcon","ChevronLineRightIcon","styles.inputSelectWrapper","InputSelect","options","valueExtractor","item","listExtractor","label","displayValueExtractor","onSelectOption","pagesize","totalPage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pagination.js","sources":["../../src/pagination/pagination.tsx"],"sourcesContent":["import { Chevron2LeftIcon } from \"@lifesg/react-icons/chevron-2-left\";\nimport { Chevron2RightIcon } from \"@lifesg/react-icons/chevron-2-right\";\nimport { ChevronLeftIcon } from \"@lifesg/react-icons/chevron-left\";\nimport { ChevronLineLeftIcon } from \"@lifesg/react-icons/chevron-line-left\";\nimport { ChevronLineRightIcon } from \"@lifesg/react-icons/chevron-line-right\";\nimport { ChevronRightIcon } from \"@lifesg/react-icons/chevron-right\";\nimport { EllipsisHorizontalIcon } from \"@lifesg/react-icons/ellipsis-horizontal\";\nimport clsx from \"clsx\";\nimport React, { useEffect, useState } from \"react\";\n\nimport { Input } from \"../input\";\nimport { InputSelect } from \"../input-select\";\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { useId, useIsMounted } from \"../util\";\nimport * as styles from \"./pagination.styles\";\nimport type { PageSizeItemProps, PaginationProps } from \"./types\";\n\nconst getPageSizeOption = (\n pageSizeOptions: PageSizeItemProps[],\n value: number\n) =>\n pageSizeOptions.find((option) => option.value === value) ??\n pageSizeOptions[0];\n\nconst Component = (\n {\n id,\n \"data-testid\": dataTestId,\n className,\n variant = \"default\",\n pageSize = 10,\n totalItems,\n activePage,\n pageSizeOptions = DEFAULT_OPTIONS,\n showFirstAndLastNav,\n showPageSizeChanger = false,\n onPageChange,\n onPageSizeChange,\n }: PaginationProps,\n ref: React.Ref<HTMLDivElement>\n) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n\n const isMounted = useIsMounted();\n const isMobile = useMaxWidthMediaQuery(\"sm\");\n const resolvedVariant =\n variant === \"default\"\n ? isMounted && isMobile\n ? \"compact\"\n : \"full\"\n : variant;\n const useInputLayout = resolvedVariant === \"compact\";\n const usesPageSizeChanger =\n showPageSizeChanger && resolvedVariant === \"full\";\n const [hoverRightButton, setHoverRightButton] = useState(false);\n const [hoverLeftButton, setHoverLeftButton] = useState(false);\n const [inputText, setInputText] = useState<string>(\"\");\n const [pageSizeLocal, setPageSize] = useState<number>(pageSize);\n const selectedOption = getPageSizeOption(pageSizeOptions, pageSizeLocal);\n\n const boundaryRange = 1;\n const siblingRange = 1;\n\n const internalId = useId();\n const paginationId = `${internalId}-pagination`;\n\n const totalPages = Math.ceil(totalItems / pageSizeLocal);\n const isFirstPage = activePage === 1;\n const isLastPage = activePage === totalPages;\n\n const firstPaginationItem =\n activePage > 1 ? () => handlePaginationItemClick(1) : undefined;\n const lastPaginationItem =\n activePage < totalPages\n ? () => handlePaginationItemClick(totalPages)\n : undefined;\n const prevPaginationItem =\n activePage > 1\n ? () => handlePaginationItemClick(activePage - 1)\n : undefined;\n const nextPaginationItem =\n activePage < totalPages\n ? () =>\n handlePaginationItemClick(parseInt(activePage.toString()) + 1)\n : undefined;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n if (activePage) {\n setInputValue(activePage);\n }\n }, [activePage]);\n\n useEffect(() => {\n setPageSize(pageSize);\n }, [pageSize]);\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const setInputValue = (value: number) => {\n setInputText(value.toString());\n };\n\n const closeAllTooltips = () => {\n setHoverRightButton(false);\n setHoverLeftButton(false);\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handlePaginationItemClick = (pageIndex: number) => {\n if (onPageChange) {\n onPageChange(pageIndex);\n setInputValue(pageIndex);\n }\n };\n\n const handleFastForwardClick = () => {\n const currentIndex = Math.min(totalPages, activePage + 5);\n handlePaginationItemClick(currentIndex);\n setInputValue(currentIndex);\n setHoverRightButton(true);\n setHoverLeftButton(false);\n };\n\n const handleFastBackwardClick = () => {\n const currentIndex = Math.max(1, activePage - 5);\n handlePaginationItemClick(currentIndex);\n setInputValue(currentIndex);\n setHoverRightButton(false);\n setHoverLeftButton(true);\n };\n\n const handleInput = (event: React.ChangeEvent<HTMLInputElement>) => {\n const value = event.target.value;\n const numericRegex = /^[0-9]+$/;\n if (value === undefined || value.length === 0) {\n setInputText(\"\");\n } else if (!numericRegex.test(value)) {\n setInputText(value.replace(/[^0-9]/g, \"\"));\n } else {\n const newPage = parseInt(value.replace(/[^0-9]/g, \"\"));\n setInputValue(Math.max(1, Math.min(totalPages, newPage)));\n }\n };\n\n const handleInputSubmit = (event: React.FormEvent) => {\n event.preventDefault();\n if (inputText) {\n onPageChange?.(parseInt(inputText));\n }\n };\n\n const onHoverRightButton = () => {\n setHoverRightButton(true);\n };\n\n const onBlurRightButton = () => {\n setHoverRightButton(false);\n };\n\n const onHoverLeftButton = () => {\n setHoverLeftButton(true);\n };\n\n const onBlurLeftButton = () => {\n setHoverLeftButton(false);\n };\n\n const handleListItemClick = (item: PageSizeItemProps) => {\n const pagesize = item.value;\n const totalPage = Math.ceil(totalItems / pagesize);\n\n setPageSize(pagesize);\n\n const page = activePage >= totalPage ? totalPage : activePage;\n\n if (onPageSizeChange) {\n onPageSizeChange(page, pagesize);\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderPaginationItems = () => {\n return [...Array(totalPages)].map((e, i) => {\n const pageIndex = i + 1;\n const startRange = boundaryRange + 2 + siblingRange * 2;\n const endRange = totalPages - startRange;\n const totalRange = (boundaryRange + siblingRange) * 2 + 3;\n const active = activePage === pageIndex;\n if (totalPages <= totalRange) {\n return (\n <button\n key={pageIndex}\n onClick={() => handlePaginationItemClick(pageIndex)}\n className={clsx(\n styles.pageItem,\n active && styles.pageItemSelected\n )}\n aria-label={`page ${pageIndex} of ${totalPages}`}\n aria-current={active ? \"page\" : false}\n onMouseOver={closeAllTooltips}\n onFocus={closeAllTooltips}\n >\n {pageIndex}\n </button>\n );\n }\n\n const ellipsisStart =\n activePage + siblingRange > startRange &&\n pageIndex === boundaryRange + 1;\n if (ellipsisStart) {\n return renderStartEllipsis(pageIndex);\n }\n\n const ellipsisEnd =\n activePage - siblingRange <= endRange &&\n pageIndex === totalPages - boundaryRange - 1;\n if (ellipsisEnd) {\n return renderEndEllipsis(pageIndex);\n }\n\n const paginationStart =\n (pageIndex <= startRange &&\n activePage + siblingRange <= startRange) ||\n pageIndex <= boundaryRange;\n const paginationMiddle =\n pageIndex === activePage ||\n (pageIndex <= activePage + siblingRange &&\n pageIndex >= activePage - siblingRange - 1);\n const paginationEnd =\n (pageIndex > endRange &&\n activePage - siblingRange > endRange) ||\n pageIndex > totalPages - boundaryRange;\n if (paginationStart || paginationMiddle || paginationEnd) {\n return (\n <button\n key={pageIndex}\n onClick={() => handlePaginationItemClick(pageIndex)}\n className={clsx(\n styles.pageItem,\n active && styles.pageItemSelected\n )}\n aria-label={`page ${pageIndex} of ${totalPages}`}\n aria-current={active ? \"page\" : false}\n onMouseOver={closeAllTooltips}\n onFocus={closeAllTooltips}\n >\n {pageIndex}\n </button>\n );\n }\n\n return null;\n });\n };\n\n const renderStartEllipsis = (pageIndex: number) => (\n <div key={pageIndex} className={styles.ellipsisContainer}>\n <ClickableIcon\n className={styles.iconButton}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={\"Previous 5 pages\"}\n onMouseEnter={onHoverLeftButton}\n onMouseLeave={onBlurLeftButton}\n onFocus={onHoverLeftButton}\n onBlur={onBlurLeftButton}\n onClick={handleFastBackwardClick}\n >\n {hoverLeftButton ? (\n <Chevron2LeftIcon aria-hidden />\n ) : (\n <EllipsisHorizontalIcon aria-hidden />\n )}\n </ClickableIcon>\n {hoverLeftButton && (\n <div className={styles.hover}>Previous 5 pages</div>\n )}\n </div>\n );\n\n const renderEndEllipsis = (pageIndex: number) => (\n <div key={pageIndex} className={styles.ellipsisContainer}>\n <ClickableIcon\n className={styles.iconButton}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={\"Next 5 pages\"}\n onMouseEnter={onHoverRightButton}\n onMouseLeave={onBlurRightButton}\n onFocus={onHoverRightButton}\n onBlur={onBlurRightButton}\n onClick={handleFastForwardClick}\n >\n {hoverRightButton ? (\n <Chevron2RightIcon aria-hidden />\n ) : (\n <EllipsisHorizontalIcon aria-hidden />\n )}\n </ClickableIcon>\n {hoverRightButton && (\n <div className={styles.hover}>Next 5 pages</div>\n )}\n </div>\n );\n\n const renderMobile = () => (\n <div className={styles.paginationMobileInput}>\n <form onSubmit={handleInputSubmit}>\n <Input\n className={styles.inputView}\n value={inputText}\n onChange={handleInput}\n autoComplete=\"off\"\n type=\"numeric\"\n id={(id || \"pagination\") + \"-input\"}\n data-testid={(dataTestId || \"pagination\") + \"-input\"}\n aria-label={`Page ${activePage} of ${totalPages}`}\n />\n </form>\n <Typography.BodyBL className={styles.labelDivider}>\n /\n </Typography.BodyBL>\n <Typography.BodyBL className={styles.label}>\n {totalPages}\n </Typography.BodyBL>\n </div>\n );\n\n return (\n <nav\n className={clsx(styles.paginationWrapper, className)}\n ref={ref}\n id={id || \"pagination-wrapper\"}\n data-testid={dataTestId || \"pagination\"}\n aria-labelledby={paginationId}\n >\n <VisuallyHidden id={paginationId} aria-hidden>\n pagination\n </VisuallyHidden>\n <div className={styles.paginationList}>\n <div className={styles.paginationMenu}>\n {showFirstAndLastNav && (\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonNavigation\n )}\n onClick={firstPaginationItem}\n disabled={isFirstPage}\n focusHighlight={false}\n aria-label=\"First page\"\n focusOutline=\"browser\"\n >\n <ChevronLineLeftIcon aria-hidden />\n </ClickableIcon>\n )}\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonNavigation\n )}\n onClick={prevPaginationItem}\n disabled={isFirstPage}\n focusHighlight={false}\n aria-label=\"Previous page\"\n focusOutline=\"browser\"\n >\n <ChevronLeftIcon aria-hidden />\n </ClickableIcon>\n {useInputLayout ? renderMobile() : renderPaginationItems()}\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonNavigation\n )}\n onClick={nextPaginationItem}\n disabled={isLastPage}\n focusHighlight={false}\n aria-label=\"Next page\"\n focusOutline=\"browser\"\n >\n <ChevronRightIcon aria-hidden />\n </ClickableIcon>\n {showFirstAndLastNav && (\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonNavigation\n )}\n onClick={lastPaginationItem}\n disabled={isLastPage}\n focusHighlight={false}\n aria-label=\"Last page\"\n focusOutline=\"browser\"\n >\n <ChevronLineRightIcon aria-hidden />\n </ClickableIcon>\n )}\n </div>\n </div>\n {usesPageSizeChanger && (\n <div className={styles.inputSelectWrapper}>\n <VisuallyHidden id={`${paginationId}-page-size`}>\n Items per page\n </VisuallyHidden>\n <InputSelect\n aria-labelledby={`${paginationId}-page-size`}\n options={pageSizeOptions}\n valueExtractor={(item) => item.value}\n listExtractor={(item) => item.label}\n displayValueExtractor={(item) => item.label}\n selectedOption={selectedOption}\n onSelectOption={handleListItemClick}\n />\n </div>\n )}\n </nav>\n );\n};\n// @catalog\n/**\n * A navigation control for moving through paged content.\n *\n * Use `Pagination` to let users navigate between pages of a data set.\n * @keywords navigation, pager, pages\n */\nexport const Pagination = React.forwardRef(Component);\n\nconst DEFAULT_OPTIONS: PageSizeItemProps[] = [\n { value: 10, label: \"10 per page\" },\n { value: 20, label: \"20 per page\" },\n { value: 30, label: \"30 per page\" },\n];\n"],"names":["Pagination","React","forwardRef","id","dataTestId","className","variant","pageSize","totalItems","activePage","pageSizeOptions","DEFAULT_OPTIONS","showFirstAndLastNav","showPageSizeChanger","onPageChange","onPageSizeChange","ref","isMounted","useIsMounted","isMobile","useMaxWidthMediaQuery","resolvedVariant","useInputLayout","usesPageSizeChanger","hoverRightButton","setHoverRightButton","useState","hoverLeftButton","setHoverLeftButton","inputText","setInputText","pageSizeLocal","setPageSize","selectedOption","value","_a","find","option","getPageSizeOption","paginationId","useId","totalPages","Math","ceil","isFirstPage","isLastPage","firstPaginationItem","handlePaginationItemClick","undefined","lastPaginationItem","prevPaginationItem","nextPaginationItem","parseInt","toString","useEffect","setInputValue","closeAllTooltips","pageIndex","handleFastForwardClick","currentIndex","min","handleFastBackwardClick","max","handleInput","event","target","length","test","newPage","replace","handleInputSubmit","preventDefault","onHoverRightButton","onBlurRightButton","onHoverLeftButton","onBlurLeftButton","renderStartEllipsis","_jsxs","styles.ellipsisContainer","children","_jsx","ClickableIcon","styles.iconButton","focusHighlight","focusOutline","onMouseEnter","onMouseLeave","onFocus","onBlur","onClick","Chevron2LeftIcon","EllipsisHorizontalIcon","styles.hover","renderEndEllipsis","Chevron2RightIcon","clsx","styles.paginationWrapper","VisuallyHidden","styles.paginationList","styles.paginationMenu","styles.iconButtonNavigation","disabled","ChevronLineLeftIcon","ChevronLeftIcon","styles.paginationMobileInput","onSubmit","Input","styles.inputView","onChange","autoComplete","type","Typography","BodyBL","styles.labelDivider","styles.label","Array","map","e","i","endRange","boundaryRange","active","styles.pageItem","styles.pageItemSelected","onMouseOver","ChevronRightIcon","ChevronLineRightIcon","styles.inputSelectWrapper","InputSelect","options","valueExtractor","item","listExtractor","label","displayValueExtractor","onSelectOption","pagesize","totalPage"],"mappings":"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"}
|
package/pagination/types.d.ts
CHANGED
|
@@ -5,6 +5,13 @@ export interface PaginationProps {
|
|
|
5
5
|
id?: string | undefined;
|
|
6
6
|
"data-testid"?: string | undefined;
|
|
7
7
|
className?: string | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Controls whether the pagination follows the responsive layout
|
|
10
|
+
* or always renders the full or compact layout.
|
|
11
|
+
*
|
|
12
|
+
* @default "default"
|
|
13
|
+
*/
|
|
14
|
+
variant?: "default" | "full" | "compact" | undefined;
|
|
8
15
|
/**
|
|
9
16
|
* Number of items displayed per page.
|
|
10
17
|
*
|
|
@@ -34,7 +41,7 @@ export interface PaginationProps {
|
|
|
34
41
|
*/
|
|
35
42
|
showFirstAndLastNav?: boolean | undefined;
|
|
36
43
|
/**
|
|
37
|
-
* When `true`, renders a dropdown
|
|
44
|
+
* When `true`, renders a dropdown in the full layout to change the `pageSize`.
|
|
38
45
|
*
|
|
39
46
|
* @default false
|
|
40
47
|
*/
|
|
@@ -29,6 +29,7 @@ export interface SelectHistogramProps extends Pick<AriaAttributes, "aria-labelle
|
|
|
29
29
|
histogramSlider: SelectHistogramSliderProps;
|
|
30
30
|
/**
|
|
31
31
|
* Controls how long option labels are truncated when they overflow.
|
|
32
|
+
* Specify `"none"` to display option labels in full.
|
|
32
33
|
*
|
|
33
34
|
* @default "end"
|
|
34
35
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DropdownVariantType, LabelDisplayType } from "./types";
|
|
1
|
+
import type { DropdownVariantType, LabelDisplayType, TruncateType } from "./types";
|
|
2
2
|
interface DropdownLabelProps {
|
|
3
3
|
bold?: boolean | undefined;
|
|
4
4
|
displayType?: LabelDisplayType | undefined;
|
|
@@ -8,7 +8,7 @@ interface DropdownLabelProps {
|
|
|
8
8
|
selected?: boolean | undefined;
|
|
9
9
|
disabled?: boolean | undefined;
|
|
10
10
|
sublabel?: string | undefined;
|
|
11
|
-
truncationType?:
|
|
11
|
+
truncationType?: TruncateType | undefined;
|
|
12
12
|
variant?: DropdownVariantType | undefined;
|
|
13
13
|
}
|
|
14
14
|
export declare const DropdownLabel: ({ bold, displayType, label, searchTerm, maxLines, selected, disabled, sublabel, truncationType, variant, }: DropdownLabelProps) => JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsxs as e,jsx as i,Fragment as r}from"react/jsx-runtime";import t from"clsx";import{useRef as l,useCallback as
|
|
1
|
+
import{jsxs as e,jsx as i,Fragment as r}from"react/jsx-runtime";import t from"clsx";import{useRef as l,useCallback as n,useMemo as s}from"react";import{useResizeDetector as m}from"../../external/react-resize-detector/build/index.esm.js";import"../../theme/theme-provider/index.js";import"../../theme/theme-provider/context.js";import"../../theme/tokens/border.js";import"../../theme/tokens/colour.js";import{Font as o}from"../../theme/tokens/font.js";import"../../theme/tokens/media-query.js";import{useApplyStyle as d}from"../../theme/utils/use-apply-styles.js";import"../../theme/utils/use-media-query.js";import{StringHelper as a}from"../../util/string-helper.js";import{tokens as c,primaryText as p,primaryTextBold as h,primaryTextDisabled as u,primaryTextSelected as f,primaryTextLabelInline as x,primaryTextTruncateEnd as b,secondaryText as y,secondaryTextLabelInline as j,secondaryTextTruncateEnd as v,secondaryTextNextLine as N,secondaryTextInline as T,label as g,labelVariantSmall as L,labelNextLine as S,baseTruncateStyle as k,truncateFirstLine as w,truncateLineSingle as z,truncateSecondLine as q,matchedText as C}from"./dropdown-label.styles.js";const $=({bold:$,displayType:O="inline",label:W,searchTerm:A,maxLines:B=2,selected:D,disabled:E,sublabel:F,truncationType:G="middle",variant:H="default"})=>{const I="small"===H?o.Spec["body-size-md"]:o.Spec["body-size-baseline"],J=o.Spec["font-family-body"],{ref:K,width:M}=m(),P="none"===G,Q=l(null),R=l(null);d(Q,{[c.primaryText.maxLines]:P?null:String(B)}),d(R,{[c.secondaryText.maxLines]:P?null:String(B)});const U=n((e=>{if(P||"inline"!==O||!M)return!1;return a.getTextWidth(e,`${I} '${J}'`)>M-50}),[P,M,O,I,J]),V=s((()=>U(W)),[U,W]),X=s((()=>F&&U(F)),[U,F]),Y="middle"===G&&(V||X)?"next-line":O,Z=t=>{if(!A)return t;const l=A.toLowerCase().trim(),n=t.toLowerCase().indexOf(l),s=n+A.length;return-1===n?t:e(r,{children:[W.slice(0,n),i("span",{className:C,children:W.slice(n,s)}),W.slice(s)]})},_=l=>e(r,{children:[i("div",{className:t(k,w,1===B&&z),"aria-hidden":!0,children:Z(l)}),i("div",{className:t(k,q,1===B&&z),"aria-hidden":!0,children:Z(l)})]});return e("div",{ref:K,className:t(g,"small"===H&&L,"next-line"===Y&&S),children:[i("div",{ref:Q,"aria-label":W,className:t(p,$&&h,E&&u,!E&&D&&f,"inline"===Y&&x,"end"===G&&b),children:"middle"===G&&V?_(W):Z(W)}),F&&i("div",{ref:R,"aria-label":F,className:t(y,"inline"===Y&&j,"end"===G&&v,"next-line"===O?N:T),children:"middle"===G&&X?_(F):F})]})};export{$ as DropdownLabel};
|
|
2
2
|
//# sourceMappingURL=dropdown-label.js.map
|