@lifesg/react-design-system 4.0.0-alpha.7 → 4.0.0-alpha.9

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.
Files changed (268) hide show
  1. package/accordion/accordion-item.js.map +1 -1
  2. package/accordion/accordion.js.map +1 -1
  3. package/alert/alert.js.map +1 -1
  4. package/button/button.js +1 -1
  5. package/button/button.js.map +1 -1
  6. package/button/button.styles.d.ts +1 -0
  7. package/button/button.styles.js +1 -1
  8. package/button/button.styles.js.map +1 -1
  9. package/button/button.styles_19i4dfq.css +21 -0
  10. package/cjs/accordion/accordion-item.js.map +1 -1
  11. package/cjs/accordion/accordion.js.map +1 -1
  12. package/cjs/alert/alert.js.map +1 -1
  13. package/cjs/button/button.js +1 -1
  14. package/cjs/button/button.js.map +1 -1
  15. package/cjs/button/button.styles.js +1 -1
  16. package/cjs/button/button.styles.js.map +1 -1
  17. package/cjs/button/button.styles_19i4dfq.css +21 -0
  18. package/cjs/countdown-timer/countdown-timer.js.map +1 -1
  19. package/cjs/data-table/data-table.js +1 -1
  20. package/cjs/data-table/data-table.js.map +1 -1
  21. package/cjs/data-table/data-table.styles.js +1 -1
  22. package/cjs/data-table/data-table.styles.js.map +1 -1
  23. package/{data-table/data-table.styles_rxganh.css → cjs/data-table/data-table.styles_1tnlmhe.css} +7 -6
  24. package/cjs/date-range-input/date-range-input.js.map +1 -1
  25. package/cjs/e-signature/e-signature-canvas.js.map +1 -1
  26. package/cjs/error-display/error-display-data.js +1 -1
  27. package/cjs/error-display/error-display-data.js.map +1 -1
  28. package/cjs/error-display/inactivity-timer.js.map +1 -1
  29. package/cjs/external/dompurify/dist/purify.es.js +2 -2
  30. package/cjs/external/dompurify/dist/purify.es.js.map +1 -1
  31. package/cjs/file-download/file-list-card/file-list-card.js.map +1 -1
  32. package/cjs/file-upload/custom-sensors.js.map +1 -1
  33. package/cjs/file-upload/file-list/file-list.js.map +1 -1
  34. package/cjs/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
  35. package/cjs/filter/addons/filter-item-checkbox.js.map +1 -1
  36. package/cjs/filter/addons/filter-item-checkbox.styles.js +1 -1
  37. package/cjs/filter/addons/filter-item-checkbox.styles.js.map +1 -1
  38. package/{filter/addons/filter-item-checkbox.styles_7degw7.css → cjs/filter/addons/filter-item-checkbox.styles_6nbpdl.css} +1 -1
  39. package/cjs/filter/filter-item.js.map +1 -1
  40. package/cjs/filter/filter-item.styles.js +1 -1
  41. package/cjs/filter/filter-item.styles.js.map +1 -1
  42. package/cjs/filter/{filter-item.styles_cphjnj.css → filter-item.styles_1yixp8h.css} +1 -1
  43. package/cjs/filter/filter-modal.styles.js +1 -1
  44. package/cjs/filter/filter-modal.styles.js.map +1 -1
  45. package/{filter/filter-modal.styles_qw3xlg.css → cjs/filter/filter-modal.styles_kuth21.css} +1 -1
  46. package/cjs/filter/filter-sidebar.styles.js +1 -1
  47. package/cjs/filter/filter-sidebar.styles.js.map +1 -1
  48. package/cjs/filter/{filter-sidebar.styles_1otwpjl.css → filter-sidebar.styles_rbfq4f.css} +1 -1
  49. package/cjs/filter/filter.js.map +1 -1
  50. package/cjs/form/form-textarea/form-textarea.js +1 -1
  51. package/cjs/form/form-textarea/form-textarea.js.map +1 -1
  52. package/cjs/fullscreen-image-carousel/stateful-image.js.map +1 -1
  53. package/cjs/histogram-slider/histogram-slider.js.map +1 -1
  54. package/cjs/input-range-slider/input-range-slider.js.map +1 -1
  55. package/cjs/input-slider/input-slider.js.map +1 -1
  56. package/cjs/input-textarea/textarea-counter.js.map +1 -1
  57. package/cjs/input-textarea/textarea.js +1 -1
  58. package/cjs/input-textarea/textarea.js.map +1 -1
  59. package/cjs/input-textarea/textarea.styles.js +1 -1
  60. package/cjs/input-textarea/textarea.styles.js.map +1 -1
  61. package/cjs/input-textarea/{textarea.styles_q77m5x.css → textarea.styles_6we7bs.css} +3 -1
  62. package/cjs/modal/index.js.map +1 -1
  63. package/cjs/modal-v2/modal-v2.js +1 -1
  64. package/cjs/modal-v2/modal-v2.js.map +1 -1
  65. package/cjs/modal-v2/slots/card.js +1 -1
  66. package/cjs/modal-v2/slots/card.js.map +1 -1
  67. package/cjs/modal-v2/slots/header.js +2 -0
  68. package/cjs/modal-v2/slots/header.js.map +1 -0
  69. package/cjs/modal-v2/slots/slot-styles.js +1 -1
  70. package/cjs/modal-v2/slots/slot-styles.js.map +1 -1
  71. package/cjs/modal-v2/slots/{slot-styles_13sd376.css → slot-styles_10ut1v7.css} +5 -1
  72. package/cjs/navbar/navbar-items.js +1 -1
  73. package/cjs/navbar/navbar-items.js.map +1 -1
  74. package/cjs/navbar/navbar-items.styles.js +1 -1
  75. package/cjs/navbar/navbar-items.styles.js.map +1 -1
  76. package/cjs/navbar/{navbar-items.styles_1i3ltot.css → navbar-items.styles_1b1zx.css} +9 -8
  77. package/cjs/navbar/navbar-logo-data.js +1 -1
  78. package/cjs/navbar/navbar-logo-data.js.map +1 -1
  79. package/cjs/navbar/navbar.js.map +1 -1
  80. package/cjs/otp-input/otp-input.js.map +1 -1
  81. package/cjs/overlay/overlay.js.map +1 -1
  82. package/cjs/pagination/pagination.js.map +1 -1
  83. package/cjs/phone-number-input/phone-number-input.js.map +1 -1
  84. package/cjs/predictive-text-input/predictive-text-input.js.map +1 -1
  85. package/cjs/shared/dropdown-list/dropdown-list.js.map +1 -1
  86. package/cjs/shared/internal-calendar/calendar-manager.js.map +1 -1
  87. package/cjs/shared/standalone-date-input/standalone-date-input.js.map +1 -1
  88. package/cjs/singpass-button/singpass-button.styles.js +1 -1
  89. package/cjs/singpass-button/singpass-button.styles.js.map +1 -1
  90. package/cjs/singpass-button/{singpass-button.styles_1miyex3.css → singpass-button.styles_1fj2lru.css} +1 -1
  91. package/cjs/smart-app-banner/smart-app-banner.styles.js +1 -1
  92. package/cjs/smart-app-banner/smart-app-banner.styles.js.map +1 -1
  93. package/cjs/smart-app-banner/{smart-app-banner.styles_15u6yv4.css → smart-app-banner.styles_r6yjq9.css} +1 -1
  94. package/cjs/theme/types.js +1 -1
  95. package/cjs/theme/types.js.map +1 -1
  96. package/cjs/time-slot-bar/time-slot-bar.js.map +1 -1
  97. package/cjs/time-slot-bar-week/time-slot-bar-week-days.js.map +1 -1
  98. package/cjs/timetable/timetable.js.map +1 -1
  99. package/cjs/toast/toast.styles.js +1 -1
  100. package/cjs/toast/toast.styles.js.map +1 -1
  101. package/{toast/toast.styles_1e0l60w.css → cjs/toast/toast.styles_57j3lf.css} +1 -1
  102. package/cjs/toggle/toggle-icon.js +1 -1
  103. package/cjs/toggle/toggle-icon.js.map +1 -1
  104. package/cjs/toggle/toggle-icon.styles.js +1 -1
  105. package/cjs/toggle/toggle-icon.styles.js.map +1 -1
  106. package/cjs/toggle/{toggle-icon.styles_ba71y.css → toggle-icon.styles_o6dxr3.css} +3 -2
  107. package/cjs/toggle/toggle.js +1 -1
  108. package/cjs/toggle/toggle.js.map +1 -1
  109. package/cjs/toggle/toggle.styles.js +1 -1
  110. package/cjs/toggle/toggle.styles.js.map +1 -1
  111. package/cjs/toggle/toggle.styles_11tmfsr.css +41 -0
  112. package/cjs/unit-number/unit-number-input.js.map +1 -1
  113. package/cjs/util/is-styled-components.js.map +1 -1
  114. package/cjs/util/string-helper.js +1 -1
  115. package/cjs/util/string-helper.js.map +1 -1
  116. package/cjs/util/use-event-listener.js.map +1 -1
  117. package/cjs/util/use-state-actions.js.map +1 -1
  118. package/countdown-timer/countdown-timer.js.map +1 -1
  119. package/data-table/data-table.d.ts +1 -1
  120. package/data-table/data-table.js +1 -1
  121. package/data-table/data-table.js.map +1 -1
  122. package/data-table/data-table.styles.d.ts +1 -0
  123. package/data-table/data-table.styles.js +1 -1
  124. package/data-table/data-table.styles.js.map +1 -1
  125. package/{cjs/data-table/data-table.styles_rxganh.css → data-table/data-table.styles_1tnlmhe.css} +7 -6
  126. package/data-table/types.d.ts +4 -2
  127. package/date-range-input/date-range-input.js.map +1 -1
  128. package/docs/component-catalog.json +1 -1
  129. package/e-signature/e-signature-canvas.js.map +1 -1
  130. package/error-display/error-display-data.js +1 -1
  131. package/error-display/error-display-data.js.map +1 -1
  132. package/error-display/inactivity-timer.js.map +1 -1
  133. package/external/dompurify/dist/purify.es.js +2 -2
  134. package/external/dompurify/dist/purify.es.js.map +1 -1
  135. package/file-download/file-list-card/file-list-card.js.map +1 -1
  136. package/file-upload/custom-sensors.d.ts +2 -2
  137. package/file-upload/custom-sensors.js.map +1 -1
  138. package/file-upload/file-list/file-list.js.map +1 -1
  139. package/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
  140. package/filter/addons/filter-item-checkbox.js.map +1 -1
  141. package/filter/addons/filter-item-checkbox.styles.js +1 -1
  142. package/filter/addons/filter-item-checkbox.styles.js.map +1 -1
  143. package/{cjs/filter/addons/filter-item-checkbox.styles_7degw7.css → filter/addons/filter-item-checkbox.styles_6nbpdl.css} +1 -1
  144. package/filter/filter-item.js.map +1 -1
  145. package/filter/filter-item.styles.js +1 -1
  146. package/filter/filter-item.styles.js.map +1 -1
  147. package/filter/{filter-item.styles_cphjnj.css → filter-item.styles_1yixp8h.css} +1 -1
  148. package/filter/filter-modal.styles.js +1 -1
  149. package/filter/filter-modal.styles.js.map +1 -1
  150. package/{cjs/filter/filter-modal.styles_qw3xlg.css → filter/filter-modal.styles_kuth21.css} +1 -1
  151. package/filter/filter-sidebar.styles.js +1 -1
  152. package/filter/filter-sidebar.styles.js.map +1 -1
  153. package/filter/{filter-sidebar.styles_1otwpjl.css → filter-sidebar.styles_rbfq4f.css} +1 -1
  154. package/filter/filter.js.map +1 -1
  155. package/form/form-textarea/form-textarea.js +1 -1
  156. package/form/form-textarea/form-textarea.js.map +1 -1
  157. package/fullscreen-image-carousel/stateful-image.js.map +1 -1
  158. package/fullscreen-image-carousel/types.d.ts +2 -2
  159. package/histogram-slider/histogram-slider.js.map +1 -1
  160. package/input-range-slider/input-range-slider.js.map +1 -1
  161. package/input-slider/input-slider.js.map +1 -1
  162. package/input-textarea/textarea-counter.js.map +1 -1
  163. package/input-textarea/textarea.js +1 -1
  164. package/input-textarea/textarea.js.map +1 -1
  165. package/input-textarea/textarea.styles.d.ts +2 -0
  166. package/input-textarea/textarea.styles.js +1 -1
  167. package/input-textarea/textarea.styles.js.map +1 -1
  168. package/input-textarea/{textarea.styles_q77m5x.css → textarea.styles_6we7bs.css} +3 -1
  169. package/input-textarea/types.d.ts +7 -0
  170. package/modal/index.d.ts +4 -0
  171. package/modal/index.js.map +1 -1
  172. package/modal/types.d.ts +2 -0
  173. package/modal-v2/modal-v2.d.ts +6 -0
  174. package/modal-v2/modal-v2.js +1 -1
  175. package/modal-v2/modal-v2.js.map +1 -1
  176. package/modal-v2/slots/card.js +1 -1
  177. package/modal-v2/slots/card.js.map +1 -1
  178. package/modal-v2/slots/header.d.ts +5 -0
  179. package/modal-v2/slots/header.js +2 -0
  180. package/modal-v2/slots/header.js.map +1 -0
  181. package/modal-v2/slots/index.d.ts +1 -0
  182. package/modal-v2/slots/slot-styles.d.ts +4 -0
  183. package/modal-v2/slots/slot-styles.js +1 -1
  184. package/modal-v2/slots/slot-styles.js.map +1 -1
  185. package/modal-v2/slots/{slot-styles_13sd376.css → slot-styles_10ut1v7.css} +5 -1
  186. package/modal-v2/types.d.ts +21 -0
  187. package/navbar/navbar-items.js +1 -1
  188. package/navbar/navbar-items.js.map +1 -1
  189. package/navbar/navbar-items.styles.d.ts +2 -1
  190. package/navbar/navbar-items.styles.js +1 -1
  191. package/navbar/navbar-items.styles.js.map +1 -1
  192. package/navbar/{navbar-items.styles_1i3ltot.css → navbar-items.styles_1b1zx.css} +9 -8
  193. package/navbar/navbar-logo-data.js +1 -1
  194. package/navbar/navbar-logo-data.js.map +1 -1
  195. package/navbar/navbar.js.map +1 -1
  196. package/otp-input/otp-input.js.map +1 -1
  197. package/overlay/overlay.js.map +1 -1
  198. package/package.json +1 -1
  199. package/pagination/pagination.js.map +1 -1
  200. package/phone-number-input/phone-number-input.js.map +1 -1
  201. package/predictive-text-input/predictive-text-input.js.map +1 -1
  202. package/shared/dropdown-list/dropdown-list.js.map +1 -1
  203. package/shared/internal-calendar/calendar-manager.js.map +1 -1
  204. package/shared/standalone-date-input/standalone-date-input.js.map +1 -1
  205. package/singpass-button/singpass-button.styles.js +1 -1
  206. package/singpass-button/singpass-button.styles.js.map +1 -1
  207. package/singpass-button/{singpass-button.styles_1miyex3.css → singpass-button.styles_1fj2lru.css} +1 -1
  208. package/smart-app-banner/smart-app-banner.styles.js +1 -1
  209. package/smart-app-banner/smart-app-banner.styles.js.map +1 -1
  210. package/smart-app-banner/{smart-app-banner.styles_15u6yv4.css → smart-app-banner.styles_r6yjq9.css} +1 -1
  211. package/theme/styles/a11y-playground.css +358 -87
  212. package/theme/styles/bookingsg.css +391 -85
  213. package/theme/styles/careercompass.css +396 -90
  214. package/theme/styles/ccube.css +402 -45
  215. package/theme/styles/imda.css +348 -85
  216. package/theme/styles/lifesg.css +377 -87
  217. package/theme/styles/mylegacy.css +382 -85
  218. package/theme/styles/oneservice.css +349 -86
  219. package/theme/styles/pa.css +172 -104
  220. package/theme/styles/rbs.css +403 -46
  221. package/theme/styles/sgw-digital-lobby.css +352 -87
  222. package/theme/styles/smgs.css +401 -95
  223. package/theme/styles/spf.css +208 -99
  224. package/theme/styles/supportgowhere.css +387 -90
  225. package/theme/styles/tote-board.css +816 -0
  226. package/theme/types.d.ts +1 -1
  227. package/theme/types.js +1 -1
  228. package/theme/types.js.map +1 -1
  229. package/time-slot-bar/time-slot-bar.js.map +1 -1
  230. package/time-slot-bar-week/time-slot-bar-week-days.js.map +1 -1
  231. package/timetable/timetable.js.map +1 -1
  232. package/toast/toast.styles.js +1 -1
  233. package/toast/toast.styles.js.map +1 -1
  234. package/{cjs/toast/toast.styles_1e0l60w.css → toast/toast.styles_57j3lf.css} +1 -1
  235. package/toggle/toggle-icon.d.ts +2 -1
  236. package/toggle/toggle-icon.js +1 -1
  237. package/toggle/toggle-icon.js.map +1 -1
  238. package/toggle/toggle-icon.styles.d.ts +1 -0
  239. package/toggle/toggle-icon.styles.js +1 -1
  240. package/toggle/toggle-icon.styles.js.map +1 -1
  241. package/toggle/{toggle-icon.styles_ba71y.css → toggle-icon.styles_o6dxr3.css} +3 -2
  242. package/toggle/toggle.js +1 -1
  243. package/toggle/toggle.js.map +1 -1
  244. package/toggle/toggle.styles.d.ts +18 -15
  245. package/toggle/toggle.styles.js +1 -1
  246. package/toggle/toggle.styles.js.map +1 -1
  247. package/toggle/toggle.styles_11tmfsr.css +41 -0
  248. package/tools/storybook-argtypes/services/arg-types-row-builder.d.ts +6 -0
  249. package/tools/storybook-argtypes/types.d.ts +13 -1
  250. package/unit-number/unit-number-input.js.map +1 -1
  251. package/util/is-styled-components.js.map +1 -1
  252. package/util/string-helper.d.ts +2 -2
  253. package/util/string-helper.js +1 -1
  254. package/util/string-helper.js.map +1 -1
  255. package/util/use-event-listener.js.map +1 -1
  256. package/util/use-state-actions.js.map +1 -1
  257. package/button/button.styles_1pxy0co.css +0 -20
  258. package/cjs/button/button.styles_1pxy0co.css +0 -20
  259. package/cjs/form/form-textarea/form-textarea.styles.js +0 -2
  260. package/cjs/form/form-textarea/form-textarea.styles.js.map +0 -1
  261. package/cjs/form/form-textarea/form-textarea.styles_1kneyif.css +0 -3
  262. package/cjs/toggle/toggle.styles_1t5qrye.css +0 -38
  263. package/form/form-textarea/form-textarea.styles.d.ts +0 -3
  264. package/form/form-textarea/form-textarea.styles.js +0 -2
  265. package/form/form-textarea/form-textarea.styles.js.map +0 -1
  266. package/form/form-textarea/form-textarea.styles_1kneyif.css +0 -3
  267. package/theme/styles/default.css +0 -158
  268. package/toggle/toggle.styles_1t5qrye.css +0 -38
@@ -1 +1 @@
1
- {"version":3,"file":"toggle.js","sources":["../../../src/toggle/toggle.tsx"],"sourcesContent":["import { ChevronDownIcon } from \"@lifesg/react-icons/chevron-down\";\nimport { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport clsx from \"clsx\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { Alert } from \"../alert\";\nimport { Markup } from \"../markup\";\nimport { TextList } from \"../text-list\";\nimport { useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport * as styles from \"./toggle.styles\";\nimport type { ToggleIconType } from \"./toggle-icon\";\nimport { ToggleIcon } from \"./toggle-icon\";\nimport type { ToggleProps } from \"./types\";\n\n// @catalog\n/**\n * A selectable control for checkbox and radio interaction patterns.\n *\n * Use `Toggle` to present a labeled option that the user can select or\n * deselect.\n */\nexport const Toggle = ({\n type = \"checkbox\",\n indicator,\n checked,\n styleType = \"default\",\n children,\n childrenMaxLines,\n subLabel,\n disabled,\n error,\n name,\n id,\n className,\n compositeSection,\n removable,\n focusableWhenDisabled,\n useContentWidth,\n onRemove,\n onChange,\n \"data-testid\": testId,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: ToggleProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n collapsible = true,\n errors,\n children: compositeSectionChildren,\n initialExpanded,\n } = compositeSection || {};\n const [selected, setSelected] = useState<boolean | undefined>(checked);\n const [expanded, setExpanded] = useState<boolean>(!!initialExpanded);\n const hasCompositeSectionError = useMemo(() => {\n const hasErrorList = Array.isArray(errors) && errors?.length > 0;\n const hasErrorElement = !Array.isArray(errors) && !!errors;\n return hasErrorList || hasErrorElement;\n }, [errors]);\n const uniqueId = useId();\n const generatedId = id ? `${id}` : `tg-${uniqueId}`;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const labelRef = useRef<HTMLLabelElement>(null);\n\n useApplyStyle(labelRef, {\n [styles.tokens.label.desktopLineClamp]:\n childrenMaxLines?.desktop == null\n ? null\n : `${childrenMaxLines.desktop}`,\n [styles.tokens.label.tabletLineClamp]:\n childrenMaxLines?.tablet == null\n ? null\n : `${childrenMaxLines.tablet}`,\n [styles.tokens.label.mobileLineClamp]:\n childrenMaxLines?.mobile == null\n ? null\n : `${childrenMaxLines.mobile}`,\n });\n\n const isFocusableWhenDisabled = !!disabled && !!focusableWhenDisabled;\n const isNativeDisabled = !!disabled && !focusableWhenDisabled;\n const isInteractionBlocked = !!disabled;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelected(checked);\n }, [checked]);\n\n useEffect(() => {\n if (selected) {\n setExpanded(initialExpanded ?? true);\n }\n }, [selected]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (isInteractionBlocked) {\n event.preventDefault();\n return;\n }\n\n if (onChange) {\n onChange(event);\n return;\n }\n\n switch (type) {\n case \"checkbox\":\n setSelected((prevSelected) => {\n return !prevSelected;\n });\n break;\n case \"radio\":\n case \"yes\":\n case \"no\":\n if (!selected) {\n setSelected(true);\n }\n break;\n }\n };\n\n const handleExpandCollapseClick = () => {\n if (!disabled) {\n setExpanded(!expanded);\n }\n };\n\n const handleOnRemove = () => {\n if (!disabled) {\n if (onRemove) {\n onRemove();\n return;\n }\n }\n };\n\n const handleContainerClick = () => {\n inputRef?.current?.click();\n };\n\n const handleInputClick = (e: React.MouseEvent<HTMLInputElement>) => {\n e.stopPropagation();\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n\n const getContainerStateClass = () => {\n if (styleType === \"no-border\") {\n if (error) {\n return clsx(\n styles.colorBorderError,\n !disabled && styles.toggleContainerError\n );\n }\n\n if (disabled) {\n return selected\n ? styles.toggleContainerNoBorderDisabledSelected\n : styles.toggleContainerNoBorderDisabled;\n }\n\n if (selected) {\n return styles.toggleContainerNoBorderSelected;\n }\n\n return styles.toggleContainerNoBorder;\n }\n\n if (error) {\n return disabled\n ? styles.colorBorderError\n : styles.toggleContainerError;\n }\n\n if (disabled) {\n return selected\n ? styles.toggleContainerDisabledSelected\n : styles.toggleContainerDisabled;\n }\n\n if (selected) {\n return styles.toggleContainerSelected;\n }\n\n return styles.toggleContainer;\n };\n\n const getContainerHoverClass = () => {\n if (disabled) {\n return undefined;\n }\n\n if (!error && selected) {\n return styles.toggleContainerHoverSelected;\n }\n\n return styles.toggleContainerHoverDefault;\n };\n\n const getTextContainerStateClass = () => {\n if (disabled) {\n return selected\n ? styles.toggleTextContainerDisabledSelected\n : styles.colorTextDisabled;\n }\n\n if (selected) {\n return styles.toggleTextContainerSelected;\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderIndicator = () => {\n let toggleIconType: ToggleIconType;\n\n switch (type) {\n case \"yes\":\n toggleIconType = \"tick\";\n break;\n case \"no\":\n toggleIconType = \"cross\";\n break;\n case \"checkbox\":\n case \"radio\":\n toggleIconType = type;\n break;\n }\n\n return (\n <ToggleIcon\n type={toggleIconType}\n active={selected}\n disabled={disabled}\n />\n );\n };\n\n const renderSubLabel = () => {\n if (!subLabel) {\n return null;\n }\n\n let component: string | JSX.Element;\n\n if (typeof subLabel === \"function\") {\n component = subLabel();\n } else {\n component = subLabel;\n }\n\n // Hide sublabel from screen readers as the main input already has aria-describedby that points to the sublabel\n return (\n <div\n data-id=\"toggle-sublabel\"\n id={`${generatedId}-sublabel`}\n aria-hidden\n className={styles.subLabel}\n >\n {component}\n </div>\n );\n };\n\n const renderCompositeChildren = () => {\n return (\n (!collapsible || expanded) && (\n <div\n data-id=\"toggle-composite-children\"\n className={clsx(\n styles.children,\n !collapsible && styles.childrenIsFinalItem,\n disabled && styles.colorTextDisabled\n )}\n >\n <Markup baseTextSize=\"body-md\">\n {compositeSectionChildren}\n </Markup>\n </div>\n )\n );\n };\n\n const renderExpandButton = () => {\n const collapsedWithoutErrors = !expanded && !hasCompositeSectionError;\n\n return (\n collapsible && (\n <button\n className={clsx(\n styles.expandButton,\n disabled && styles.disabledColorCursor,\n collapsedWithoutErrors &&\n styles.expandButtonPaddingTopRequired\n )}\n disabled={disabled}\n onClick={handleExpandCollapseClick}\n data-testid={expanded ? \"collapse-button\" : \"expand-button\"}\n >\n {expanded ? \"Show less\" : \"Show more\"}\n {expanded ? (\n <ChevronUpIcon aria-hidden />\n ) : (\n <ChevronDownIcon aria-hidden />\n )}\n </button>\n )\n );\n };\n\n const renderToggleWithRemoveButton = () => {\n const ariaDescriptions =\n [\n typeof subLabel === \"string\" ? `${generatedId}-sublabel` : null,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n return (\n <div\n id={`${generatedId}-header-container`}\n className={styles.headerContainer}\n >\n <div\n className={clsx(\n styles.indicatorLabelContainer,\n removable && styles.indicatorLabelContainerAddPadding\n )}\n >\n <div\n id={`${generatedId}-input-container`}\n onClick={handleContainerClick}\n className={styles.inputContainer}\n >\n <input\n ref={inputRef}\n name={name}\n id={`${generatedId}-input`}\n type={type === \"checkbox\" ? \"checkbox\" : \"radio\"}\n data-testid=\"toggle-input\"\n className={clsx(\n styles.input,\n disabled && styles.toggleInputDisabled\n )}\n disabled={isNativeDisabled}\n aria-disabled={isFocusableWhenDisabled}\n onChange={handleOnChange}\n onClick={handleInputClick}\n checked={selected}\n tabIndex={isFocusableWhenDisabled ? 0 : undefined}\n aria-describedby={ariaDescriptions}\n {...otherProps}\n />\n {indicator && renderIndicator()}\n <div\n className={clsx(\n styles.textContainer,\n getTextContainerStateClass()\n )}\n >\n <label\n ref={labelRef}\n htmlFor={`${generatedId}-input`}\n data-testid={`toggle-label`}\n id={`${generatedId}-label`}\n className={clsx(\n styles.label,\n selected\n ? styles.toggleLabelSelected\n : styles.toggleLabelDefault\n )}\n >\n {children}\n </label>\n {subLabel && renderSubLabel()}\n </div>\n </div>\n </div>\n {removable && (\n <button\n type=\"button\"\n className={clsx(\n styles.removeButton,\n disabled && styles.disabledColorCursor\n )}\n onClick={handleOnRemove}\n id={`${generatedId}-remove-button`}\n >\n Remove\n </button>\n )}\n </div>\n );\n };\n\n const renderErrorList = (errors: string[]) => {\n return (\n <>\n <Typography.BodyMD\n weight=\"semibold\"\n className={clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n )}\n >\n Error\n </Typography.BodyMD>\n <TextList.Ul\n className={clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n )}\n >\n {errors?.map((item, index) => {\n return (\n <li\n key={index}\n id={`${generatedId}-error-list-item-${index}`}\n >\n <Typography.BodyMD\n weight=\"semibold\"\n className={clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n )}\n >\n {item}\n </Typography.BodyMD>\n </li>\n );\n })}\n </TextList.Ul>\n </>\n );\n };\n\n const renderError = () => {\n return (\n collapsible &&\n !expanded &&\n hasCompositeSectionError && (\n <div\n className={clsx(\n styles.errorContainer,\n disabled && styles.disabledColorCursor\n )}\n onClick={handleExpandCollapseClick}\n id={`${generatedId}-error-alert`}\n >\n <Alert\n type={disabled ? \"description\" : \"error\"}\n className={styles.alertContainer}\n showIcon\n >\n {Array.isArray(errors)\n ? renderErrorList(errors)\n : errors}\n </Alert>\n </div>\n )\n );\n };\n\n const renderCompositeSection = () => {\n return (\n compositeSectionChildren && (\n <div>\n {renderCompositeChildren()}\n {renderError()}\n {renderExpandButton()}\n </div>\n )\n );\n };\n\n return (\n <div\n className={clsx(\n styles.container,\n getContainerStateClass(),\n getContainerHoverClass(),\n !indicator && styles.noIndicatorContainer,\n useContentWidth && styles.useContentWidthContainer,\n className\n )}\n id={id}\n data-testid={testId}\n >\n {renderToggleWithRemoveButton()}\n {renderCompositeSection()}\n </div>\n );\n};\n"],"names":["_a","type","indicator","checked","styleType","children","childrenMaxLines","subLabel","disabled","error","name","id","className","compositeSection","removable","focusableWhenDisabled","useContentWidth","onRemove","onChange","testId","ariaDescribedBy","otherProps","__rest","collapsible","errors","compositeSectionChildren","initialExpanded","selected","setSelected","useState","expanded","setExpanded","hasCompositeSectionError","useMemo","hasErrorList","Array","isArray","length","hasErrorElement","uniqueId","useId","generatedId","inputRef","useRef","labelRef","useApplyStyle","styles.tokens","label","desktopLineClamp","desktop","tabletLineClamp","tablet","mobileLineClamp","mobile","isFocusableWhenDisabled","isNativeDisabled","isInteractionBlocked","useEffect","handleOnChange","event","preventDefault","prevSelected","handleExpandCollapseClick","handleOnRemove","handleContainerClick","current","click","handleInputClick","e","stopPropagation","renderIndicator","toggleIconType","_jsx","ToggleIcon","active","renderSubLabel","component","styles.subLabel","renderExpandButton","collapsedWithoutErrors","_jsxs","clsx","styles.expandButton","styles.disabledColorCursor","styles.expandButtonPaddingTopRequired","onClick","ChevronUpIcon","ChevronDownIcon","renderErrorList","_Fragment","Typography","BodyMD","weight","styles.colorTextError","styles.colorTextDisabled","TextList","Ul","map","item","index","styles.container","styles.colorBorderError","styles.toggleContainerError","styles.toggleContainerNoBorderDisabledSelected","styles.toggleContainerNoBorderDisabled","styles.toggleContainerNoBorderSelected","styles.toggleContainerNoBorder","styles.toggleContainerDisabledSelected","styles.toggleContainerDisabled","styles.toggleContainerSelected","styles.toggleContainer","styles.toggleContainerHoverSelected","styles.toggleContainerHoverDefault","getContainerHoverClass","styles.noIndicatorContainer","styles.useContentWidthContainer","ariaDescriptions","filter","Boolean","join","undefined","styles.headerContainer","styles.indicatorLabelContainer","styles.indicatorLabelContainerAddPadding","styles.inputContainer","ref","styles.input","styles.toggleInputDisabled","tabIndex","styles.textContainer","styles.toggleTextContainerDisabledSelected","styles.toggleTextContainerSelected","htmlFor","styles.label","styles.toggleLabelSelected","styles.toggleLabelDefault","styles.removeButton","renderToggleWithRemoveButton","styles.children","styles.childrenIsFinalItem","Markup","baseTextSize","styles.errorContainer","Alert","styles.alertContainer","showIcon"],"mappings":"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"}
1
+ {"version":3,"file":"toggle.js","sources":["../../../src/toggle/toggle.tsx"],"sourcesContent":["import { ChevronDownIcon } from \"@lifesg/react-icons/chevron-down\";\nimport { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport clsx from \"clsx\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { Alert } from \"../alert\";\nimport { Markup } from \"../markup\";\nimport { TextList } from \"../text-list\";\nimport { useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport * as styles from \"./toggle.styles\";\nimport type { ToggleIconType } from \"./toggle-icon\";\nimport { ToggleIcon } from \"./toggle-icon\";\nimport type { ToggleProps } from \"./types\";\n\n// @catalog\n/**\n * A selectable control for checkbox and radio interaction patterns.\n *\n * Use `Toggle` to present a labeled option that the user can select or\n * deselect.\n */\nexport const Toggle = ({\n type = \"checkbox\",\n indicator,\n checked,\n styleType = \"default\",\n children,\n childrenMaxLines,\n subLabel,\n disabled,\n error,\n name,\n id,\n className,\n compositeSection,\n removable,\n focusableWhenDisabled,\n useContentWidth,\n onRemove,\n onChange,\n \"data-testid\": testId,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: ToggleProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n collapsible = true,\n errors,\n children: compositeSectionChildren,\n initialExpanded,\n } = compositeSection || {};\n const [selected, setSelected] = useState<boolean | undefined>(checked);\n const [expanded, setExpanded] = useState<boolean>(!!initialExpanded);\n const hasCompositeSectionError = useMemo(() => {\n const hasErrorList = Array.isArray(errors) && errors?.length > 0;\n const hasErrorElement = !Array.isArray(errors) && !!errors;\n return hasErrorList || hasErrorElement;\n }, [errors]);\n const uniqueId = useId();\n const generatedId = id ? `${id}` : `tg-${uniqueId}`;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const labelRef = useRef<HTMLLabelElement>(null);\n\n useApplyStyle(labelRef, {\n [styles.tokens.label.desktopLineClamp]:\n childrenMaxLines?.desktop == null\n ? null\n : `${childrenMaxLines.desktop}`,\n [styles.tokens.label.tabletLineClamp]:\n childrenMaxLines?.tablet == null\n ? null\n : `${childrenMaxLines.tablet}`,\n [styles.tokens.label.mobileLineClamp]:\n childrenMaxLines?.mobile == null\n ? null\n : `${childrenMaxLines.mobile}`,\n });\n\n const isFocusableWhenDisabled = !!disabled && !!focusableWhenDisabled;\n const isNativeDisabled = !!disabled && !focusableWhenDisabled;\n const isInteractionBlocked = !!disabled;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelected(checked);\n }, [checked]);\n\n useEffect(() => {\n if (selected) {\n setExpanded(initialExpanded ?? true);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selected]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (isInteractionBlocked) {\n event.preventDefault();\n return;\n }\n\n if (onChange) {\n onChange(event);\n return;\n }\n\n switch (type) {\n case \"checkbox\":\n setSelected((prevSelected) => {\n return !prevSelected;\n });\n break;\n case \"radio\":\n case \"yes\":\n case \"no\":\n if (!selected) {\n setSelected(true);\n }\n break;\n }\n };\n\n const handleExpandCollapseClick = () => {\n if (!disabled) {\n setExpanded(!expanded);\n }\n };\n\n const handleOnRemove = () => {\n if (!disabled) {\n if (onRemove) {\n onRemove();\n return;\n }\n }\n };\n\n const handleContainerClick = () => {\n inputRef?.current?.click();\n };\n\n const handleInputClick = (e: React.MouseEvent<HTMLInputElement>) => {\n e.stopPropagation();\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n\n const getContainerBorderClass = () => {\n if (!selected && error) return styles.borderError;\n if (styleType === \"no-border\") return styles.borderNone;\n if (selected && disabled) return styles.borderSelectedDisabled;\n if (disabled) return styles.borderDisabled;\n if (error) return styles.borderError;\n if (selected) return styles.borderSelected;\n return styles.borderDefault;\n };\n\n const getContainerBgClass = () => {\n if (selected) {\n if (error) return styles.bgError;\n return disabled ? styles.bgSelectedDisabled : styles.bgSelected;\n }\n\n if (disabled && styleType !== \"no-border\") return styles.bgDisabled;\n return styles.bgDefault;\n };\n\n const getContainerHoverClass = () => {\n if (disabled) return null;\n if (selected)\n return error\n ? styles.toggleContainerHoverError\n : styles.toggleContainerHoverSelected;\n return styles.toggleContainerHoverDefault;\n };\n\n const getTextContainerClass = () => {\n if (selected) {\n if (error) return styles.colorTextError;\n\n if (disabled) return styles.toggleTextContainerDisabledSelected;\n\n return styles.toggleTextContainerSelected;\n }\n\n if (disabled) return styles.colorTextDisabled;\n return styles.colorTextDefault;\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderIndicator = () => {\n let toggleIconType: ToggleIconType;\n\n switch (type) {\n case \"yes\":\n toggleIconType = \"tick\";\n break;\n case \"no\":\n toggleIconType = \"cross\";\n break;\n case \"checkbox\":\n case \"radio\":\n toggleIconType = type;\n break;\n }\n\n return (\n <ToggleIcon\n type={toggleIconType}\n active={selected}\n disabled={disabled}\n error={error}\n />\n );\n };\n\n const renderSubLabel = () => {\n if (!subLabel) {\n return null;\n }\n\n let component: string | JSX.Element;\n\n if (typeof subLabel === \"function\") {\n component = subLabel();\n } else {\n component = subLabel;\n }\n\n // Hide sublabel from screen readers as the main input already has aria-describedby that points to the sublabel\n return (\n <div\n data-id=\"toggle-sublabel\"\n id={`${generatedId}-sublabel`}\n aria-hidden\n className={styles.subLabel}\n >\n {component}\n </div>\n );\n };\n\n const renderCompositeChildren = () => {\n return (\n (!collapsible || expanded) && (\n <div\n data-id=\"toggle-composite-children\"\n className={clsx(\n styles.children,\n !collapsible && styles.childrenIsFinalItem,\n disabled\n ? styles.colorTextDisabled\n : styles.colorTextDefault\n )}\n >\n <Markup baseTextSize=\"body-md\">\n {compositeSectionChildren}\n </Markup>\n </div>\n )\n );\n };\n\n const renderExpandButton = () => {\n const collapsedWithoutErrors = !expanded && !hasCompositeSectionError;\n\n return (\n collapsible && (\n <button\n className={clsx(\n styles.expandButton,\n disabled\n ? styles.disabledColorCursor\n : styles.colorTextPrimary,\n collapsedWithoutErrors &&\n styles.expandButtonPaddingTopRequired\n )}\n disabled={disabled}\n onClick={handleExpandCollapseClick}\n data-testid={expanded ? \"collapse-button\" : \"expand-button\"}\n >\n {expanded ? (\n <>\n Show less\n <ChevronUpIcon aria-hidden />\n </>\n ) : (\n <>\n Show more\n <ChevronDownIcon aria-hidden />\n </>\n )}\n </button>\n )\n );\n };\n\n const renderToggleWithRemoveButton = () => {\n const ariaDescriptions =\n [\n typeof subLabel === \"string\" ? `${generatedId}-sublabel` : null,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n return (\n <div\n id={`${generatedId}-header-container`}\n className={styles.headerContainer}\n >\n <div\n className={clsx(\n styles.indicatorLabelContainer,\n removable && styles.indicatorLabelContainerAddPadding\n )}\n >\n <div\n id={`${generatedId}-input-container`}\n onClick={handleContainerClick}\n className={styles.inputContainer}\n >\n <input\n ref={inputRef}\n name={name}\n id={`${generatedId}-input`}\n type={type === \"checkbox\" ? \"checkbox\" : \"radio\"}\n data-testid=\"toggle-input\"\n className={clsx(\n styles.input,\n disabled && styles.disabledColorCursor\n )}\n disabled={isNativeDisabled}\n aria-disabled={isFocusableWhenDisabled}\n onChange={handleOnChange}\n onClick={handleInputClick}\n checked={selected}\n tabIndex={isFocusableWhenDisabled ? 0 : undefined}\n aria-describedby={ariaDescriptions}\n {...otherProps}\n />\n {indicator && renderIndicator()}\n <div\n className={clsx(\n styles.textContainer,\n getTextContainerClass()\n )}\n >\n <label\n ref={labelRef}\n htmlFor={`${generatedId}-input`}\n data-testid={`toggle-label`}\n id={`${generatedId}-label`}\n className={clsx(\n styles.label,\n selected\n ? styles.toggleLabelSelected\n : styles.toggleLabelDefault\n )}\n >\n {children}\n </label>\n {subLabel && renderSubLabel()}\n </div>\n </div>\n </div>\n {removable && (\n <button\n type=\"button\"\n className={clsx(\n styles.removeButton,\n disabled && styles.disabledColorCursor\n )}\n onClick={handleOnRemove}\n id={`${generatedId}-remove-button`}\n >\n Remove\n </button>\n )}\n </div>\n );\n };\n\n const renderErrorList = (errors: string[]) => {\n const className = clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n );\n\n return (\n <>\n <Typography.BodyMD weight=\"semibold\" className={className}>\n Error\n </Typography.BodyMD>\n <TextList.Ul className={className}>\n {errors?.map((item, index) => {\n return (\n <li\n key={index}\n id={`${generatedId}-error-list-item-${index}`}\n >\n <Typography.BodyMD\n weight=\"semibold\"\n className={className}\n >\n {item}\n </Typography.BodyMD>\n </li>\n );\n })}\n </TextList.Ul>\n </>\n );\n };\n\n const renderError = () => {\n return (\n collapsible &&\n !expanded &&\n hasCompositeSectionError && (\n <div\n className={clsx(\n styles.errorContainer,\n disabled\n ? styles.disabledColorCursor\n : styles.colorTextDefault\n )}\n onClick={handleExpandCollapseClick}\n id={`${generatedId}-error-alert`}\n >\n <Alert\n type={disabled ? \"description\" : \"error\"}\n className={styles.alertContainer}\n showIcon\n >\n {Array.isArray(errors)\n ? renderErrorList(errors)\n : errors}\n </Alert>\n </div>\n )\n );\n };\n\n const renderCompositeSection = () => {\n return (\n compositeSectionChildren && (\n <div>\n {renderCompositeChildren()}\n {renderError()}\n {renderExpandButton()}\n </div>\n )\n );\n };\n\n return (\n <div\n className={clsx(\n styles.container,\n getContainerBorderClass(),\n getContainerBgClass(),\n getContainerHoverClass(),\n !indicator && styles.containerNoIndicator,\n useContentWidth && styles.containerUseContentWidth,\n className\n )}\n id={id}\n data-testid={testId}\n >\n {renderToggleWithRemoveButton()}\n {renderCompositeSection()}\n </div>\n );\n};\n"],"names":["_a","type","indicator","checked","styleType","children","childrenMaxLines","subLabel","disabled","error","name","id","className","compositeSection","removable","focusableWhenDisabled","useContentWidth","onRemove","onChange","testId","ariaDescribedBy","otherProps","__rest","collapsible","errors","compositeSectionChildren","initialExpanded","selected","setSelected","useState","expanded","setExpanded","hasCompositeSectionError","useMemo","hasErrorList","Array","isArray","length","hasErrorElement","uniqueId","useId","generatedId","inputRef","useRef","labelRef","useApplyStyle","styles.tokens","label","desktopLineClamp","desktop","tabletLineClamp","tablet","mobileLineClamp","mobile","isFocusableWhenDisabled","isNativeDisabled","isInteractionBlocked","useEffect","handleOnChange","event","preventDefault","prevSelected","handleExpandCollapseClick","handleOnRemove","handleContainerClick","current","click","handleInputClick","e","stopPropagation","renderIndicator","toggleIconType","_jsx","ToggleIcon","active","renderSubLabel","component","styles.subLabel","renderExpandButton","collapsedWithoutErrors","clsx","styles.expandButton","styles.disabledColorCursor","styles.colorTextPrimary","styles.expandButtonPaddingTopRequired","onClick","_jsxs","_Fragment","ChevronUpIcon","ChevronDownIcon","renderErrorList","styles.colorTextError","styles.colorTextDisabled","Typography","BodyMD","weight","TextList","Ul","map","item","index","styles.container","styles.borderError","styles.borderNone","styles.borderSelectedDisabled","styles.borderDisabled","styles.borderSelected","styles.borderDefault","styles.bgError","styles.bgSelectedDisabled","styles.bgSelected","styles.bgDisabled","styles.bgDefault","styles.toggleContainerHoverError","styles.toggleContainerHoverSelected","styles.toggleContainerHoverDefault","styles.containerNoIndicator","styles.containerUseContentWidth","ariaDescriptions","filter","Boolean","join","undefined","styles.headerContainer","styles.indicatorLabelContainer","styles.indicatorLabelContainerAddPadding","styles.inputContainer","ref","styles.input","tabIndex","styles.textContainer","styles.toggleTextContainerDisabledSelected","styles.toggleTextContainerSelected","styles.colorTextDefault","htmlFor","styles.label","styles.toggleLabelSelected","styles.toggleLabelDefault","styles.removeButton","renderToggleWithRemoveButton","styles.children","styles.childrenIsFinalItem","Markup","baseTextSize","styles.errorContainer","Alert","styles.alertContainer","showIcon"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";require("./toggle.styles_1t5qrye.css");exports.alertContainer="aeqryui",exports.children="c1mf9nso",exports.childrenIsFinalItem="c9t56r4",exports.colorBorderError="c17z2k4k",exports.colorTextDisabled="c1y0x62l",exports.colorTextError="c1gmwtb7",exports.container="c11szvws",exports.disabledColorCursor="d194isif",exports.errorContainer="e1q8ywpe",exports.expandButton="ehwglic",exports.expandButtonPaddingTopRequired="ejwzsce",exports.headerContainer="h1fyul7s",exports.indicatorLabelContainer="i1l466bv",exports.indicatorLabelContainerAddPadding="ih3od2r",exports.input="i14lgw6r",exports.inputContainer="iangfw6",exports.label="l1oixyvr",exports.noIndicatorContainer="n12ofp2c",exports.removeButton="r1izng22",exports.subLabel="s17sf3sp",exports.textContainer="tybgacj",exports.toggleContainer="t1cyflot",exports.toggleContainerDisabled="t1l2ct9g",exports.toggleContainerDisabledSelected="t1qqpl3b",exports.toggleContainerError="t1graj5g",exports.toggleContainerHoverDefault="txm5wyu",exports.toggleContainerHoverSelected="t1nsq3eo",exports.toggleContainerNoBorder="tnwn55u",exports.toggleContainerNoBorderDisabled="td5xote",exports.toggleContainerNoBorderDisabledSelected="tfiow01",exports.toggleContainerNoBorderSelected="t15nuck4",exports.toggleContainerSelected="t1tat3es",exports.toggleInputDisabled="tovnc4j",exports.toggleLabelDefault="t1elmp69",exports.toggleLabelSelected="tv1hw4w",exports.toggleTextContainerDisabledSelected="t1aku79x",exports.toggleTextContainerSelected="tvkjim3",exports.tokens={label:{desktopLineClamp:"--fds-internal-toggle-label-desktopLineClamp",tabletLineClamp:"--fds-internal-toggle-label-tabletLineClamp",mobileLineClamp:"--fds-internal-toggle-label-mobileLineClamp"}},exports.useContentWidthContainer="u1l0nsei";
1
+ "use strict";require("./toggle.styles_11tmfsr.css");exports.alertContainer="a15al1qe",exports.bgDefault="b1l0nsei",exports.bgDisabled="bd5xote",exports.bgError="bfiow01",exports.bgSelected="b17z2k4k",exports.bgSelectedDisabled="b15nuck4",exports.borderDefault="b1fyul7s",exports.borderDisabled="b11szvws",exports.borderError="bybgacj",exports.borderNone="bvkjim3",exports.borderSelected="b1aku79x",exports.borderSelectedDisabled="b12ofp2c",exports.children="cz4bsiy",exports.childrenIsFinalItem="c1k186w3",exports.colorTextDefault="cnwn55u",exports.colorTextDisabled="c1l2ct9g",exports.colorTextError="c1qqpl3b",exports.colorTextPrimary="c1graj5g",exports.container="c14lgw6r",exports.containerNoIndicator="covnc4j",exports.containerUseContentWidth="cangfw6",exports.disabledColorCursor="d9t56r4",exports.errorContainer="eeqryui",exports.expandButton="e1y0x62l",exports.expandButtonPaddingTopRequired="e1gmwtb7",exports.headerContainer="h1tat3es",exports.indicatorLabelContainer="ijwzsce",exports.indicatorLabelContainerAddPadding="i1q8ywpe",exports.input="i17sf3sp",exports.inputContainer="i1l466bv",exports.label="lh3od2r",exports.removeButton="r1mf9nso",exports.subLabel="shwglic",exports.textContainer="t1nsq3eo",exports.toggleContainerHoverDefault="tv1hw4w",exports.toggleContainerHoverError="t1oixyvr",exports.toggleContainerHoverSelected="t1elmp69",exports.toggleLabelDefault="t1izng22",exports.toggleLabelSelected="t194isif",exports.toggleTextContainerDisabledSelected="txm5wyu",exports.toggleTextContainerSelected="t1cyflot",exports.tokens={label:{desktopLineClamp:"--fds-internal-toggle-label-desktopLineClamp",tabletLineClamp:"--fds-internal-toggle-label-tabletLineClamp",mobileLineClamp:"--fds-internal-toggle-label-mobileLineClamp"}};
2
2
  //# sourceMappingURL=toggle.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toggle.styles.js","sources":["../../../src/toggle/toggle.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Colour, Font, MediaQuery, Radius } from \"../theme\";\nimport * as toggleIconStyles from \"./toggle-icon.styles\";\n\nexport const tokens = {\n label: {\n desktopLineClamp: \"--fds-internal-toggle-label-desktopLineClamp\",\n tabletLineClamp: \"--fds-internal-toggle-label-tabletLineClamp\",\n mobileLineClamp: \"--fds-internal-toggle-label-mobileLineClamp\",\n },\n} as const;\n\n// =============================================================================\n// STYLING\n// =============================================================================\n\nexport const headerContainer = css`\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n`;\n\nexport const textContainer = css`\n display: flex;\n flex-direction: column;\n overflow-wrap: anywhere;\n width: 100%;\n overflow: hidden;\n color: ${Colour.text};\n`;\n\nexport const toggleTextContainerSelected = css`\n color: ${Colour[\"text-selected\"]};\n`;\n\nexport const toggleTextContainerDisabledSelected = css`\n color: ${Colour[\"text-selected-disabled\"]};\n`;\n\nexport const container = css`\n position: relative;\n display: inline-flex;\n min-width: 10.375rem;\n border-radius: ${Radius[\"sm\"]};\n border-width: 1px;\n border-style: solid;\n overflow: hidden;\n flex-direction: column;\n height: fit-content;\n background: ${Colour.bg};\n\n &:focus-within {\n outline: 2px solid ${Colour[\"focus-ring\"]};\n outline-offset: 0;\n }\n`;\n\nexport const noIndicatorContainer = css`\n justify-content: center;\n`;\n\nexport const useContentWidthContainer = css`\n min-width: unset;\n`;\n\nexport const colorBorderError = css`\n border-color: ${Colour[\"border-error\"]};\n`;\n\nexport const toggleContainerNoBorderDisabledSelected = css`\n border: none;\n background: ${Colour[\"bg-selected-disabled\"]};\n`;\n\nexport const toggleContainerNoBorderDisabled = css`\n border: none;\n`;\n\nexport const toggleContainerNoBorderSelected = css`\n border: none;\n background: ${Colour[\"bg-selected\"]};\n`;\n\nexport const toggleContainerNoBorder = css`\n border: none;\n`;\n\nexport const toggleContainerError = css`\n border-color: ${Colour[\"border-error\"]};\n`;\n\nexport const toggleContainerDisabledSelected = css`\n border-color: ${Colour[\"border-selected-disabled\"]};\n background: ${Colour[\"bg-selected-disabled\"]};\n`;\n\nexport const toggleContainerDisabled = css`\n border-color: ${Colour[\"border-disabled\"]};\n background: ${Colour[\"bg-disabled\"]};\n`;\n\nexport const toggleContainerSelected = css`\n border-color: ${Colour[\"border-selected\"]};\n background: ${Colour[\"bg-selected\"]};\n`;\n\nexport const toggleContainerHoverSelected = css`\n &:has(.${headerContainer}:hover) {\n @media (pointer: fine) {\n background: ${Colour[\"bg-selected-hover\"]};\n\n & .${textContainer} {\n color: ${Colour[\"text-selected-hover\"]};\n }\n\n & .${toggleIconStyles.wrapperBase} {\n color: ${Colour[\"icon-selected-hover\"]};\n }\n }\n }\n`;\n\nexport const toggleContainer = css`\n border-color: ${Colour.border};\n`;\n\nexport const toggleContainerHoverDefault = css`\n &:has(.${headerContainer}:hover) {\n @media (pointer: fine) {\n background: ${Colour[\"bg-hover-subtle\"]};\n }\n }\n`;\n\nexport const input = css`\n position: absolute;\n height: 100%;\n width: 100%;\n cursor: pointer;\n top: 0;\n left: 0;\n opacity: 0;\n\n /* Hide appearance but keep it focusable using keyboard interactions */\n appearance: none;\n background: transparent;\n border: none;\n`;\n\nexport const toggleInputDisabled = css`\n cursor: not-allowed;\n`;\n\nexport const inputContainer = css`\n display: flex;\n`;\n\nexport const label = css`\n overflow: hidden;\n display: -webkit-box;\n text-overflow: ellipsis;\n -webkit-box-orient: vertical;\n overflow-wrap: break-word;\n\n ${tokens.label.desktopLineClamp}: initial;\n ${tokens.label.tabletLineClamp}: initial;\n ${tokens.label.mobileLineClamp}: initial;\n\n -webkit-line-clamp: var(${tokens.label.desktopLineClamp}, none);\n ${MediaQuery.MaxWidth.lg} {\n -webkit-line-clamp: var(${tokens.label.tabletLineClamp}, none);\n }\n ${MediaQuery.MaxWidth.sm} {\n -webkit-line-clamp: var(${tokens.label.mobileLineClamp}, none);\n }\n`;\n\nexport const toggleLabelDefault = css`\n ${Font[\"body-baseline-regular\"]}\n`;\n\nexport const toggleLabelSelected = css`\n ${Font[\"body-baseline-semibold\"]}\n`;\n\nexport const subLabel = css`\n ${Font[\"body-md-regular\"]}\n margin-top: 0.5rem;\n\n z-index: 1; // forces sublabel to render above the input\n pointer-events: none; // to allow click events to be passed to the input\n\n strong,\n b {\n ${Font[\"body-md-semibold\"]}\n }\n`;\n\nexport const indicatorLabelContainer = css`\n display: flex;\n height: 100%;\n width: 100%;\n position: relative;\n padding: 0.6875rem 1rem;\n`;\n\nexport const indicatorLabelContainerAddPadding = css`\n padding: 0.6875rem 0rem 0.6875rem 1rem;\n`;\n\nexport const removeButton = css`\n color: ${Colour[\"text-error\"]};\n white-space: nowrap;\n ${Font[\"body-md-semibold\"]}\n height: fit-content;\n padding: 0.6875rem 1rem 0.6875rem 0.5rem;\n border: none;\n background: none;\n cursor: pointer;\n`;\n\nexport const disabledColorCursor = css`\n color: ${Colour[\"text-disabled\"]};\n cursor: not-allowed;\n`;\n\nexport const expandButton = css`\n color: ${Colour[\"text-primary\"]};\n ${Font[\"body-baseline-semibold\"]}\n display: flex;\n align-items: center;\n justify-content: flex-end;\n border: none;\n background-color: ${Colour.bg};\n cursor: pointer;\n padding: 0 1rem 0.6875rem 1rem;\n width: 100%;\n\n svg {\n width: 1em;\n height: 1em;\n margin-left: 0.5rem;\n }\n`;\n\nexport const expandButtonPaddingTopRequired = css`\n padding-top: 0.6875rem;\n`;\n\nexport const errorContainer = css`\n width: 100%;\n color: ${Colour[\"text-error\"]};\n border: none;\n background: ${Colour.bg};\n cursor: pointer;\n padding: 0.6875rem 1rem 0.5rem 1rem;\n`;\n\nexport const children = css`\n padding: 0 1rem;\n padding-top: 0.6875rem;\n padding-bottom: 0.5rem;\n background-color: ${Colour.bg};\n color: ${Colour.text};\n`;\n\nexport const childrenIsFinalItem = css`\n padding-bottom: 0.6875rem;\n`;\n\nexport const colorTextDisabled = css`\n color: ${Colour[\"text-disabled\"]};\n`;\n\nexport const colorTextError = css`\n color: ${Colour[\"text-error\"]};\n`;\n\nexport const alertContainer = css`\n width: 100%;\n user-select: none;\n`;\n"],"names":["label","desktopLineClamp","tabletLineClamp","mobileLineClamp"],"mappings":"iGAuR2B,2BApBN,uCAQW,mCAzMH,qCA6MC,kCAIH,6BA3OL,uCAsLU,kCA4BL,gCAvBF,iDAmBkB,kCArOf,2CAsLQ,qDAQU,wBAxE5B,kCAmBS,wBAIT,wCApGe,gCAyJR,4BAzBJ,iCAnKK,kCAoGE,2CA1BQ,mDALQ,wCAJX,+CAuCO,+CApBC,2CAvBL,kDATQ,0DALQ,kDASR,2CAuBR,uCAgDJ,qCA4BD,uCAIC,sDAlJgB,+CAJR,yBA3BlB,CAClBA,MAAO,CACHC,iBAAkB,+CAClBC,gBAAiB,8CACjBC,gBAAiB,iFAqDY"}
1
+ {"version":3,"file":"toggle.styles.js","sources":["../../../src/toggle/toggle.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Colour, Font, MediaQuery, Radius } from \"../theme\";\nimport * as toggleIconStyles from \"./toggle-icon.styles\";\n\nexport const tokens = {\n label: {\n desktopLineClamp: \"--fds-internal-toggle-label-desktopLineClamp\",\n tabletLineClamp: \"--fds-internal-toggle-label-tabletLineClamp\",\n mobileLineClamp: \"--fds-internal-toggle-label-mobileLineClamp\",\n },\n} as const;\n\n// =============================================================================\n// BASIC STYLING\n// =============================================================================\n\nexport const borderDefault = css`\n border: solid 1px ${Colour.border};\n`;\n\nexport const borderError = css`\n border: solid 1px ${Colour[\"border-error\"]};\n`;\n\nexport const borderNone = css`\n border: solid 1px transparent;\n`;\n\nexport const borderSelected = css`\n border: solid 1px ${Colour[\"border-selected\"]};\n`;\n\nexport const borderDisabled = css`\n border: solid 1px ${Colour[\"border-disabled\"]};\n`;\n\nexport const borderSelectedDisabled = css`\n border: solid 1px ${Colour[\"border-selected-disabled\"]};\n`;\n\nexport const bgDefault = css`\n background: ${Colour.bg};\n`;\n\nexport const bgSelected = css`\n background: ${Colour[\"bg-selected\"]};\n`;\n\nexport const bgError = css`\n background: ${Colour[\"bg-error\"]};\n`;\n\nexport const bgDisabled = css`\n background: ${Colour[\"bg-disabled\"]};\n`;\n\nexport const bgSelectedDisabled = css`\n background: ${Colour[\"bg-selected-disabled\"]};\n`;\n\nexport const colorTextDefault = css`\n color: ${Colour.text};\n`;\n\nexport const colorTextPrimary = css`\n color: ${Colour[\"text-primary\"]};\n`;\n\nexport const colorTextError = css`\n color: ${Colour[\"text-error\"]};\n`;\n\nexport const colorTextDisabled = css`\n color: ${Colour[\"text-disabled\"]};\n`;\n\n// =============================================================================\n// STYLING\n// =============================================================================\n\nexport const headerContainer = css`\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n`;\n\nexport const textContainer = css`\n display: flex;\n flex-direction: column;\n overflow-wrap: anywhere;\n width: 100%;\n overflow: hidden;\n`;\n\nexport const toggleTextContainerSelected = css`\n color: ${Colour[\"text-selected\"]};\n`;\n\nexport const toggleTextContainerDisabledSelected = css`\n color: ${Colour[\"text-selected-disabled\"]};\n`;\n\nexport const container = css`\n position: relative;\n display: inline-flex;\n min-width: 10.375rem;\n border-radius: ${Radius[\"sm\"]};\n overflow: hidden;\n flex-direction: column;\n height: fit-content;\n\n &:focus-within {\n outline: 2px solid ${Colour[\"focus-ring\"]};\n outline-offset: 0;\n }\n\n &.${borderError}, &.${bgError} {\n &:focus-within {\n outline: 2px solid ${Colour[\"border-error-focus\"]};\n }\n }\n`;\n\nexport const containerNoIndicator = css`\n justify-content: center;\n`;\n\nexport const containerUseContentWidth = css`\n min-width: unset;\n`;\n\nexport const toggleContainerHoverError = css`\n &:has(.${headerContainer}:hover) {\n @media (pointer: fine) {\n background: ${Colour[\"bg-error-hover\"]};\n }\n }\n`;\n\nexport const toggleContainerHoverSelected = css`\n &:has(.${headerContainer}:hover) {\n @media (pointer: fine) {\n background: ${Colour[\"bg-selected-hover\"]};\n\n & .${textContainer} {\n color: ${Colour[\"text-selected-hover\"]};\n }\n\n & .${toggleIconStyles.wrapperBase} {\n color: ${Colour[\"icon-selected-hover\"]};\n }\n }\n }\n`;\n\nexport const toggleContainerHoverDefault = css`\n &:has(.${headerContainer}:hover) {\n @media (pointer: fine) {\n background: ${Colour[\"bg-hover-subtle\"]};\n }\n }\n`;\n\nexport const input = css`\n position: absolute;\n height: 100%;\n width: 100%;\n cursor: pointer;\n top: 0;\n left: 0;\n opacity: 0;\n\n /* Hide appearance but keep it focusable using keyboard interactions */\n appearance: none;\n background: transparent;\n border: none;\n`;\n\nexport const inputContainer = css`\n display: flex;\n`;\n\nexport const label = css`\n overflow: hidden;\n display: -webkit-box;\n text-overflow: ellipsis;\n -webkit-box-orient: vertical;\n overflow-wrap: break-word;\n\n ${tokens.label.desktopLineClamp}: initial;\n ${tokens.label.tabletLineClamp}: initial;\n ${tokens.label.mobileLineClamp}: initial;\n\n -webkit-line-clamp: var(${tokens.label.desktopLineClamp}, none);\n ${MediaQuery.MaxWidth.lg} {\n -webkit-line-clamp: var(${tokens.label.tabletLineClamp}, none);\n }\n ${MediaQuery.MaxWidth.sm} {\n -webkit-line-clamp: var(${tokens.label.mobileLineClamp}, none);\n }\n`;\n\nexport const toggleLabelDefault = css`\n ${Font[\"body-baseline-regular\"]}\n`;\n\nexport const toggleLabelSelected = css`\n ${Font[\"body-baseline-semibold\"]}\n`;\n\nexport const subLabel = css`\n ${Font[\"body-md-regular\"]}\n margin-top: 0.5rem;\n\n z-index: 1; // forces sublabel to render above the input\n pointer-events: none; // to allow click events to be passed to the input\n\n strong,\n b {\n ${Font[\"body-md-semibold\"]}\n }\n`;\n\nexport const indicatorLabelContainer = css`\n display: flex;\n height: 100%;\n width: 100%;\n position: relative;\n padding: 0.6875rem 1rem;\n`;\n\nexport const indicatorLabelContainerAddPadding = css`\n padding: 0.6875rem 0rem 0.6875rem 1rem;\n`;\n\nexport const removeButton = css`\n color: ${Colour[\"text-error\"]};\n white-space: nowrap;\n ${Font[\"body-md-semibold\"]}\n height: fit-content;\n padding: 0.6875rem 1rem 0.6875rem 0.5rem;\n border: none;\n background: none;\n cursor: pointer;\n`;\n\nexport const disabledColorCursor = css`\n color: ${Colour[\"text-disabled\"]};\n cursor: not-allowed;\n`;\n\nexport const expandButton = css`\n ${Font[\"body-baseline-semibold\"]}\n display: flex;\n align-items: center;\n justify-content: flex-end;\n border: none;\n background-color: ${Colour.bg};\n cursor: pointer;\n padding: 0 1rem 0.6875rem 1rem;\n width: 100%;\n\n svg {\n width: 1em;\n height: 1em;\n margin-left: 0.5rem;\n }\n`;\n\nexport const expandButtonPaddingTopRequired = css`\n padding-top: 0.6875rem;\n`;\n\nexport const errorContainer = css`\n width: 100%;\n border: none;\n background: ${Colour.bg};\n cursor: pointer;\n padding: 0.6875rem 1rem 0.5rem 1rem;\n`;\n\nexport const children = css`\n padding: 0 1rem;\n padding-top: 0.6875rem;\n padding-bottom: 0.5rem;\n background-color: ${Colour.bg};\n`;\n\nexport const childrenIsFinalItem = css`\n padding-bottom: 0.6875rem;\n`;\n\nexport const alertContainer = css`\n width: 100%;\n user-select: none;\n`;\n"],"names":["label","desktopLineClamp","tabletLineClamp","mobileLineClamp"],"mappings":"iGAqS2B,6BA5PL,8BAYC,0BAJH,6BAJG,sCAYQ,iCAxCL,kCAgBC,+BAZH,6BAID,iCAII,0CAQQ,4BAqPd,sCAOW,oCApOH,oCAYC,kCAJH,oCAJE,6BAsCP,wCAqBW,2CAII,sCAuHL,iCA2BL,+BAtBF,kDAkBkB,mCA7Lf,2CA+IQ,oDAQU,yBApE5B,kCAeS,yBAIT,+BAqDO,4BAzBJ,gCA5HK,+CAqEc,4CAxBF,gDAQG,sCA+DV,uCAIC,uDA5GgB,8CAJR,0BA1FlB,CAClBA,MAAO,CACHC,iBAAkB,+CAClBC,gBAAiB,8CACjBC,gBAAiB"}
@@ -0,0 +1,41 @@
1
+ @layer fds{.b1fyul7s{border:solid 1px var(--fds-colour-border);}
2
+ .bybgacj{border:solid 1px var(--fds-colour-border-error);}
3
+ .bvkjim3{border:solid 1px transparent;}
4
+ .b1aku79x{border:solid 1px var(--fds-colour-border-selected);}
5
+ .b11szvws{border:solid 1px var(--fds-colour-border-disabled);}
6
+ .b12ofp2c{border:solid 1px var(--fds-colour-border-selected-disabled);}
7
+ .b1l0nsei{background:var(--fds-colour-bg);}
8
+ .b17z2k4k{background:var(--fds-colour-bg-selected);}
9
+ .bfiow01{background:var(--fds-colour-bg-error);}
10
+ .bd5xote{background:var(--fds-colour-bg-disabled);}
11
+ .b15nuck4{background:var(--fds-colour-bg-selected-disabled);}
12
+ .cnwn55u{color:var(--fds-colour-text);}
13
+ .c1graj5g{color:var(--fds-colour-text-primary);}
14
+ .c1qqpl3b{color:var(--fds-colour-text-error);}
15
+ .c1l2ct9g{color:var(--fds-colour-text-disabled);}
16
+ .h1tat3es{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;}
17
+ .t1nsq3eo{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow-wrap:anywhere;width:100%;overflow:hidden;}
18
+ .t1cyflot{color:var(--fds-colour-text-selected);}
19
+ .txm5wyu{color:var(--fds-colour-text-selected-disabled);}
20
+ .c14lgw6r{position:relative;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;min-width:10.375rem;border-radius:var(--fds-radius-sm);overflow:hidden;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.c14lgw6r:focus-within{outline:2px solid var(--fds-colour-focus-ring);outline-offset:0;}.c14lgw6r.bybgacj:focus-within,.c14lgw6r.bfiow01:focus-within{outline:2px solid var(--fds-colour-border-error-focus);}
21
+ .covnc4j{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}
22
+ .cangfw6{min-width:unset;}
23
+ @media (pointer: fine){.t1oixyvr:has(.h1tat3es:hover){background:var(--fds-colour-bg-error-hover);}}
24
+ @media (pointer: fine){.t1elmp69:has(.h1tat3es:hover){background:var(--fds-colour-bg-selected-hover);}.t1elmp69:has(.h1tat3es:hover) .t1nsq3eo{color:var(--fds-colour-text-selected-hover);}.t1elmp69:has(.h1tat3es:hover) .wxufi5f{color:var(--fds-colour-icon-selected-hover);}}
25
+ @media (pointer: fine){.tv1hw4w:has(.h1tat3es:hover){background:var(--fds-colour-bg-hover-subtle);}}
26
+ .i17sf3sp{position:absolute;height:100%;width:100%;cursor:pointer;top:0;left:0;opacity:0;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background:transparent;border:none;}
27
+ .i1l466bv{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}
28
+ .lh3od2r{overflow:hidden;display:-webkit-box;text-overflow:ellipsis;-webkit-box-orient:vertical;overflow-wrap:break-word;--fds-internal-toggle-label-desktopLineClamp:initial;--fds-internal-toggle-label-tabletLineClamp:initial;--fds-internal-toggle-label-mobileLineClamp:initial;-webkit-line-clamp:var(--fds-internal-toggle-label-desktopLineClamp, none);}:where(body.fds-breakpoint-lg-max) .lh3od2r{-webkit-line-clamp:var(--fds-internal-toggle-label-tabletLineClamp, none);}:where(body.fds-breakpoint-sm-max) .lh3od2r{-webkit-line-clamp:var(--fds-internal-toggle-label-mobileLineClamp, none);}
29
+ .t1izng22{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-baseline);font-weight:var(--fds-font-weight-regular);line-height:var(--fds-font-body-lh-baseline);letter-spacing:var(--fds-font-body-ls-baseline);}
30
+ .t194isif{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-baseline);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-baseline);letter-spacing:var(--fds-font-body-ls-baseline);}
31
+ .shwglic{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-md);font-weight:var(--fds-font-weight-regular);line-height:var(--fds-font-body-lh-md);letter-spacing:var(--fds-font-body-ls-md);margin-top:0.5rem;z-index:1;pointer-events:none;}.shwglic strong,.shwglic b{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-md);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-md);letter-spacing:var(--fds-font-body-ls-md);}
32
+ .ijwzsce{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%;width:100%;position:relative;padding:0.6875rem 1rem;}
33
+ .i1q8ywpe{padding:0.6875rem 0rem 0.6875rem 1rem;}
34
+ .r1mf9nso{color:var(--fds-colour-text-error);white-space:nowrap;font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-md);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-md);letter-spacing:var(--fds-font-body-ls-md);height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;padding:0.6875rem 1rem 0.6875rem 0.5rem;border:none;background:none;cursor:pointer;}
35
+ .d9t56r4{color:var(--fds-colour-text-disabled);cursor:not-allowed;}
36
+ .e1y0x62l{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-baseline);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-baseline);letter-spacing:var(--fds-font-body-ls-baseline);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;border:none;background-color:var(--fds-colour-bg);cursor:pointer;padding:0 1rem 0.6875rem 1rem;width:100%;}.e1y0x62l svg{width:1em;height:1em;margin-left:0.5rem;}
37
+ .e1gmwtb7{padding-top:0.6875rem;}
38
+ .eeqryui{width:100%;border:none;background:var(--fds-colour-bg);cursor:pointer;padding:0.6875rem 1rem 0.5rem 1rem;}
39
+ .cz4bsiy{padding:0 1rem;padding-top:0.6875rem;padding-bottom:0.5rem;background-color:var(--fds-colour-bg);}
40
+ .c1k186w3{padding-bottom:0.6875rem;}
41
+ .a15al1qe{width:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}}
@@ -1 +1 @@
1
- {"version":3,"file":"unit-number-input.js","sources":["../../../src/unit-number/unit-number-input.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { Input } from \"../input\";\nimport * as inputGroupStyles from \"../input-group/input-group.styles\";\nimport { concatIds, VisuallyHidden } from \"../shared/accessibility\";\nimport { InputWrapper } from \"../shared/input-wrapper\";\nimport { Typography } from \"../typography\";\nimport { StringHelper, useId, useNextInputState } from \"../util\";\nimport type { UnitNumberInputProps } from \"./types\";\nimport * as styles from \"./unit-number-input.styles\";\n\ntype FieldType = \"floor\" | \"unit\" | \"none\";\ntype ValueFieldTypes = Exclude<FieldType, \"none\">;\n\n// @catalog\n/**\n * A two-field input for entering Singapore-style unit numbers in `floor-unit` format.\n *\n * Use `UnitNumberInput` when you need a structured unit number entry that splits\n * floor and unit into separate fields.\n */\nexport const UnitNumberInput = ({\n disabled,\n error,\n value,\n onChange,\n onBlur,\n onChangeRaw,\n onBlurRaw,\n readOnly,\n placeholder = \"00-8888\",\n autoComplete,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n className,\n ...otherProps\n}: UnitNumberInputProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [floorValue, _setFloorValue] = useState<string>(\"\");\n const [unitValue, _setUnitValue] = useState<string>(\"\");\n const [currentFocus, _setCurrentFocus] = useState<FieldType>(\"none\");\n const internalId = useId();\n const floorLabelId = `${internalId}-floor-label`;\n const unitLabelId = `${internalId}-unit-label`;\n const liveMessageId = `${internalId}-live-message`;\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const floorInputRef = useRef<HTMLInputElement>(null);\n const unitInputRef = useRef<HTMLInputElement>(null);\n\n /**\n * Have to use refs to allow the state values to be accessible\n * by the event listener callback functions\n * Reference:\n * https://stackoverflow.com/questions/55265255/react-usestate-hook-event-handler-using-initial-state\n */\n\n const floorValueStateRef = useRef<string>(floorValue);\n const unitValueStateRef = useRef<string>(unitValue);\n const currentFocusStateRef = useRef<FieldType>(currentFocus);\n\n const formatter = (value: string) =>\n value.toLocaleUpperCase().replace(/[^0-9A-Za-z]/g, \"\");\n const getNextFloorInputState = useNextInputState({\n ref: floorInputRef,\n formatter,\n });\n const getNextUnitInputState = useNextInputState({\n ref: unitInputRef,\n formatter,\n });\n\n const liveMessage = useMemo(() => {\n let msg = \"\";\n const floorMsg = formatPhraseWithPrefix(\"Hash\", floorValue);\n const unitMsg = formatPhraseWithPrefix(\"Dash\", unitValue);\n switch (currentFocus) {\n case \"floor\":\n msg = floorMsg;\n break;\n case \"unit\":\n msg = floorValue ? [floorMsg, unitMsg].join(\" \") : unitMsg;\n break;\n default:\n msg = \"\";\n }\n return msg;\n }, [currentFocus, floorValue, unitValue]);\n\n // =============================================================================\n // REF FUNCTIONS\n // =============================================================================\n const setFloorValue = (data: string) => {\n floorValueStateRef.current = data;\n _setFloorValue(data);\n };\n\n const setUnitValue = (data: string) => {\n unitValueStateRef.current = data;\n _setUnitValue(data);\n };\n\n const setCurrentFocus = (data: FieldType) => {\n currentFocusStateRef.current = data;\n _setCurrentFocus(data);\n };\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n // Auto focus feature\n if (\n currentFocus === \"floor\" &&\n floorValue.length === 3 &&\n unitInputRef.current\n ) {\n unitInputRef.current.focus();\n }\n }, [floorValue]);\n\n useEffect(() => {\n updateValues(value);\n }, [value]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n setCurrentFocus(event.target.name as FieldType);\n event.target.select();\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n const targetName = event.target.name as FieldType;\n const targetValue = event.target.value;\n const formattedInput = formatInput(targetValue);\n\n if (targetName === \"floor\") {\n setFloorValue(formattedInput);\n if (formattedInput !== floorValue) {\n performOnChangeHandler(formattedInput, targetName);\n }\n } else if (targetName === \"unit\") {\n setUnitValue(formattedInput);\n if (formattedInput !== unitValue) {\n performOnChangeHandler(formattedInput, targetName);\n }\n }\n };\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const targetName = event.target.name as FieldType;\n\n if (targetName === \"floor\") {\n const nextInputState = getNextFloorInputState();\n if (!nextInputState) return;\n\n const { nextValue, updateCaretPosition } = nextInputState;\n updateCaretPosition();\n setFloorValue(nextValue);\n performOnChangeHandler(nextValue, targetName);\n } else if (targetName === \"unit\") {\n const nextInputState = getNextUnitInputState();\n if (!nextInputState) return;\n\n const { nextValue, updateCaretPosition } = nextInputState;\n updateCaretPosition();\n setUnitValue(nextValue);\n performOnChangeHandler(nextValue, targetName);\n }\n };\n\n const handleNodeClick = () => {\n if (currentFocus === \"none\" && floorInputRef.current) {\n floorInputRef.current.focus();\n }\n };\n\n const handleNodeBlur = (event: React.FocusEvent) => {\n if (nodeRef.current && nodeRef.current.contains(event.relatedTarget)) {\n // internal element received focus\n return;\n }\n if (currentFocusStateRef.current !== \"none\") {\n setCurrentFocus(\"none\");\n performOnBlurHandler();\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n /**\n * Allow going to the field before if user presses Backspace\n * on an empty field\n */\n if (event.code === \"Backspace\" || event.key === \"Backspace\") {\n if (currentFocus === \"unit\" && unitValue.length === 0) {\n floorInputRef.current?.focus();\n }\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const formatInput = (value: string) => {\n return /^[0-9]$/.test(value)\n ? StringHelper.padValue(value, true)\n : value.toLocaleUpperCase();\n };\n\n const updateValues = (value: string | undefined) => {\n if (value === INVALID_VALUE) {\n return;\n } else if (value === undefined || value.length === 0) {\n setFloorValue(\"\");\n setUnitValue(\"\");\n } else {\n const valueArr = value.split(\"-\");\n if (valueArr.length === 2) {\n // Valid value\n const floor = valueArr[0];\n const unit = valueArr[1];\n setFloorValue(\n currentFocus === \"floor\" ? floor : formatInput(floor)\n );\n setUnitValue(\n currentFocus === \"unit\" ? unit : formatInput(unit)\n );\n }\n }\n };\n\n const performOnChangeHandler = (\n changeValue: string,\n field: ValueFieldTypes\n ) => {\n if (!onChange && !onChangeRaw) {\n return;\n }\n\n const values: Record<ValueFieldTypes, string> = {\n floor: floorValueStateRef.current,\n unit: unitValueStateRef.current,\n };\n\n // Update the specific field value\n values[field] = changeValue;\n\n if (onChange) {\n const returnValue = getFormattedValue(values);\n onChange(returnValue);\n }\n\n if (onChangeRaw) {\n onChangeRaw([values.floor, values.unit]);\n }\n };\n\n const performOnBlurHandler = () => {\n if (!onBlur && !onBlurRaw) {\n return;\n }\n\n const values: Record<ValueFieldTypes, string> = {\n floor: formatInput(floorValueStateRef.current),\n unit: formatInput(unitValueStateRef.current),\n };\n\n if (onBlur) {\n const returnValue = getFormattedValue(values);\n onBlur(returnValue);\n }\n\n if (onBlurRaw) {\n onBlurRaw([values.floor, values.unit]);\n }\n };\n\n const getFormattedValue = (values: Record<ValueFieldTypes, string>) => {\n const valueArr = [values.floor, values.unit];\n\n if (values.floor.length > 0 && values.unit.length > 0) {\n return valueArr.join(\"-\");\n } else if (valueArr.every((value) => value === \"\")) {\n return \"\";\n } else {\n return INVALID_VALUE;\n }\n };\n\n const getPlaceholder = (value: string) => {\n return value.split(\"-\");\n };\n\n function formatPhraseWithPrefix(prefix: string, v: string) {\n return v ? `${prefix} ${Array.from(v).join(\" \")}` : \"\";\n }\n\n // =============================================================================\n // RENDER FUNCTION\n // =============================================================================\n const renderInputs = () => (\n <>\n <Input\n name=\"floor\"\n maxLength={3}\n value={floorValue}\n ref={floorInputRef}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n disabled={disabled}\n readOnly={readOnly}\n type=\"text\"\n pattern=\"[0-9A-Z]{2,3}\"\n data-testid=\"floor-input\"\n aria-labelledby={concatIds(ariaLabelledBy, floorLabelId)}\n aria-describedby={concatIds(ariaDescribedBy, liveMessageId)}\n aria-invalid={ariaInvalid}\n placeholder={\n currentFocus === \"floor\" && !readOnly && !disabled\n ? \"\"\n : getPlaceholder(placeholder)[0]\n }\n autoComplete={autoComplete}\n styleType=\"no-border\"\n className={clsx(styles.input, styles.floorInput)}\n />\n <VisuallyHidden aria-hidden id={floorLabelId}>\n Enter floor number\n </VisuallyHidden>\n <Typography.BodyBL\n className={clsx(\n styles.unitNumberDivider,\n floorValue.length === 0 && styles.unitNumberDividerInactive\n )}\n >\n -\n </Typography.BodyBL>\n <Input\n name=\"unit\"\n maxLength={5}\n value={unitValue}\n ref={unitInputRef}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n readOnly={readOnly}\n type=\"text\"\n pattern=\"[0-9A-Z]{2,5}\"\n data-testid=\"unit-input\"\n aria-labelledby={concatIds(ariaLabelledBy, unitLabelId)}\n aria-describedby={concatIds(ariaDescribedBy, liveMessageId)}\n aria-invalid={ariaInvalid}\n placeholder={\n currentFocus === \"unit\" && !readOnly && !disabled\n ? \"\"\n : getPlaceholder(placeholder)[1]\n }\n autoComplete={autoComplete}\n styleType=\"no-border\"\n className={clsx(\n styles.input,\n styles.floorInput,\n styles.unitInput\n )}\n />\n <VisuallyHidden aria-hidden id={unitLabelId}>\n Enter unit number\n </VisuallyHidden>\n {/** Live message for AT reader to read with the combination of prefix and current value for both floor input and unit input */}\n <VisuallyHidden id={liveMessageId} aria-live=\"polite\">\n {liveMessage}\n </VisuallyHidden>\n </>\n );\n\n const renderReadOnly = (displayValue: string) => {\n const displayValueArr = displayValue.split(\"-\");\n const liveMessageForReadOnly = [\n formatPhraseWithPrefix(\"Hash\", displayValueArr[0]),\n formatPhraseWithPrefix(\"Dash\", displayValueArr[1]),\n ].join(\" \");\n\n return (\n <div\n data-testid=\"readonly-display\"\n tabIndex={0}\n role=\"textbox\"\n aria-readonly\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n className={styles.readOnlyContainer}\n >\n <Typography.BodyBL>{displayValueArr[0]}</Typography.BodyBL>\n <Typography.BodyBL className={styles.unitNumberDivider}>\n -\n </Typography.BodyBL>\n <Typography.BodyBL>{displayValueArr[1]}</Typography.BodyBL>\n <VisuallyHidden>{liveMessageForReadOnly}</VisuallyHidden>\n </div>\n );\n };\n\n return (\n <InputWrapper\n {...otherProps}\n ref={nodeRef}\n onClick={handleNodeClick}\n disabled={disabled}\n error={error}\n readOnly={readOnly}\n tabIndex={-1}\n onBlur={handleNodeBlur}\n className={className}\n >\n <div\n data-testid=\"addon\"\n className={clsx(\n styles.hashContainer,\n inputGroupStyles.labelAddonContainer\n )}\n data-disabled={disabled}\n data-read-only={readOnly}\n >\n #\n </div>\n {readOnly && value ? renderReadOnly(value) : renderInputs()}\n </InputWrapper>\n );\n};\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\nconst INVALID_VALUE = \"Invalid unit number\";\n"],"names":["INVALID_VALUE","_a","disabled","error","value","onChange","onBlur","onChangeRaw","onBlurRaw","readOnly","placeholder","autoComplete","ariaLabelledBy","ariaDescribedBy","ariaInvalid","className","otherProps","__rest","floorValue","_setFloorValue","useState","unitValue","_setUnitValue","currentFocus","_setCurrentFocus","internalId","useId","floorLabelId","unitLabelId","liveMessageId","nodeRef","useRef","floorInputRef","unitInputRef","floorValueStateRef","unitValueStateRef","currentFocusStateRef","formatter","toLocaleUpperCase","replace","getNextFloorInputState","useNextInputState","ref","getNextUnitInputState","liveMessage","useMemo","msg","floorMsg","formatPhraseWithPrefix","unitMsg","join","setFloorValue","data","current","setUnitValue","setCurrentFocus","useEffect","length","focus","updateValues","handleFocus","event","target","name","select","handleBlur","targetName","targetValue","formattedInput","formatInput","performOnChangeHandler","handleChange","nextInputState","nextValue","updateCaretPosition","handleKeyDown","code","key","test","StringHelper","padValue","undefined","valueArr","split","floor","unit","changeValue","field","values","returnValue","getFormattedValue","performOnBlurHandler","every","getPlaceholder","prefix","v","Array","from","_jsxs","InputWrapper","Object","assign","onClick","tabIndex","contains","relatedTarget","children","_jsx","clsx","styles.hashContainer","inputGroupStyles.labelAddonContainer","displayValue","displayValueArr","liveMessageForReadOnly","role","styles.readOnlyContainer","Typography","BodyBL","styles.unitNumberDivider","VisuallyHidden","renderReadOnly","_Fragment","Input","maxLength","onFocus","type","pattern","concatIds","styleType","styles.input","styles.floorInput","id","styles.unitNumberDividerInactive","onKeyDown","styles.unitInput"],"mappings":"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"}
1
+ {"version":3,"file":"unit-number-input.js","sources":["../../../src/unit-number/unit-number-input.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { Input } from \"../input\";\nimport * as inputGroupStyles from \"../input-group/input-group.styles\";\nimport { concatIds, VisuallyHidden } from \"../shared/accessibility\";\nimport { InputWrapper } from \"../shared/input-wrapper\";\nimport { Typography } from \"../typography\";\nimport { StringHelper, useId, useNextInputState } from \"../util\";\nimport type { UnitNumberInputProps } from \"./types\";\nimport * as styles from \"./unit-number-input.styles\";\n\ntype FieldType = \"floor\" | \"unit\" | \"none\";\ntype ValueFieldTypes = Exclude<FieldType, \"none\">;\n\n// @catalog\n/**\n * A two-field input for entering Singapore-style unit numbers in `floor-unit` format.\n *\n * Use `UnitNumberInput` when you need a structured unit number entry that splits\n * floor and unit into separate fields.\n */\nexport const UnitNumberInput = ({\n disabled,\n error,\n value,\n onChange,\n onBlur,\n onChangeRaw,\n onBlurRaw,\n readOnly,\n placeholder = \"00-8888\",\n autoComplete,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n className,\n ...otherProps\n}: UnitNumberInputProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [floorValue, _setFloorValue] = useState<string>(\"\");\n const [unitValue, _setUnitValue] = useState<string>(\"\");\n const [currentFocus, _setCurrentFocus] = useState<FieldType>(\"none\");\n const internalId = useId();\n const floorLabelId = `${internalId}-floor-label`;\n const unitLabelId = `${internalId}-unit-label`;\n const liveMessageId = `${internalId}-live-message`;\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const floorInputRef = useRef<HTMLInputElement>(null);\n const unitInputRef = useRef<HTMLInputElement>(null);\n\n /**\n * Have to use refs to allow the state values to be accessible\n * by the event listener callback functions\n * Reference:\n * https://stackoverflow.com/questions/55265255/react-usestate-hook-event-handler-using-initial-state\n */\n\n const floorValueStateRef = useRef<string>(floorValue);\n const unitValueStateRef = useRef<string>(unitValue);\n const currentFocusStateRef = useRef<FieldType>(currentFocus);\n\n const formatter = (value: string) =>\n value.toLocaleUpperCase().replace(/[^0-9A-Za-z]/g, \"\");\n const getNextFloorInputState = useNextInputState({\n ref: floorInputRef,\n formatter,\n });\n const getNextUnitInputState = useNextInputState({\n ref: unitInputRef,\n formatter,\n });\n\n const liveMessage = useMemo(() => {\n let msg = \"\";\n const floorMsg = formatPhraseWithPrefix(\"Hash\", floorValue);\n const unitMsg = formatPhraseWithPrefix(\"Dash\", unitValue);\n switch (currentFocus) {\n case \"floor\":\n msg = floorMsg;\n break;\n case \"unit\":\n msg = floorValue ? [floorMsg, unitMsg].join(\" \") : unitMsg;\n break;\n default:\n msg = \"\";\n }\n return msg;\n }, [currentFocus, floorValue, unitValue]);\n\n // =============================================================================\n // REF FUNCTIONS\n // =============================================================================\n const setFloorValue = (data: string) => {\n floorValueStateRef.current = data;\n _setFloorValue(data);\n };\n\n const setUnitValue = (data: string) => {\n unitValueStateRef.current = data;\n _setUnitValue(data);\n };\n\n const setCurrentFocus = (data: FieldType) => {\n currentFocusStateRef.current = data;\n _setCurrentFocus(data);\n };\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n // Auto focus feature\n if (\n currentFocus === \"floor\" &&\n floorValue.length === 3 &&\n unitInputRef.current\n ) {\n unitInputRef.current.focus();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [floorValue]);\n\n useEffect(() => {\n updateValues(value);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n setCurrentFocus(event.target.name as FieldType);\n event.target.select();\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n const targetName = event.target.name as FieldType;\n const targetValue = event.target.value;\n const formattedInput = formatInput(targetValue);\n\n if (targetName === \"floor\") {\n setFloorValue(formattedInput);\n if (formattedInput !== floorValue) {\n performOnChangeHandler(formattedInput, targetName);\n }\n } else if (targetName === \"unit\") {\n setUnitValue(formattedInput);\n if (formattedInput !== unitValue) {\n performOnChangeHandler(formattedInput, targetName);\n }\n }\n };\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const targetName = event.target.name as FieldType;\n\n if (targetName === \"floor\") {\n const nextInputState = getNextFloorInputState();\n if (!nextInputState) return;\n\n const { nextValue, updateCaretPosition } = nextInputState;\n updateCaretPosition();\n setFloorValue(nextValue);\n performOnChangeHandler(nextValue, targetName);\n } else if (targetName === \"unit\") {\n const nextInputState = getNextUnitInputState();\n if (!nextInputState) return;\n\n const { nextValue, updateCaretPosition } = nextInputState;\n updateCaretPosition();\n setUnitValue(nextValue);\n performOnChangeHandler(nextValue, targetName);\n }\n };\n\n const handleNodeClick = () => {\n if (currentFocus === \"none\" && floorInputRef.current) {\n floorInputRef.current.focus();\n }\n };\n\n const handleNodeBlur = (event: React.FocusEvent) => {\n if (nodeRef.current && nodeRef.current.contains(event.relatedTarget)) {\n // internal element received focus\n return;\n }\n if (currentFocusStateRef.current !== \"none\") {\n setCurrentFocus(\"none\");\n performOnBlurHandler();\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n /**\n * Allow going to the field before if user presses Backspace\n * on an empty field\n */\n if (event.code === \"Backspace\" || event.key === \"Backspace\") {\n if (currentFocus === \"unit\" && unitValue.length === 0) {\n floorInputRef.current?.focus();\n }\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const formatInput = (value: string) => {\n return /^[0-9]$/.test(value)\n ? StringHelper.padValue(value, true)\n : value.toLocaleUpperCase();\n };\n\n const updateValues = (value: string | undefined) => {\n if (value === INVALID_VALUE) {\n return;\n } else if (value === undefined || value.length === 0) {\n setFloorValue(\"\");\n setUnitValue(\"\");\n } else {\n const valueArr = value.split(\"-\");\n if (valueArr.length === 2) {\n // Valid value\n const floor = valueArr[0];\n const unit = valueArr[1];\n setFloorValue(\n currentFocus === \"floor\" ? floor : formatInput(floor)\n );\n setUnitValue(\n currentFocus === \"unit\" ? unit : formatInput(unit)\n );\n }\n }\n };\n\n const performOnChangeHandler = (\n changeValue: string,\n field: ValueFieldTypes\n ) => {\n if (!onChange && !onChangeRaw) {\n return;\n }\n\n const values: Record<ValueFieldTypes, string> = {\n floor: floorValueStateRef.current,\n unit: unitValueStateRef.current,\n };\n\n // Update the specific field value\n values[field] = changeValue;\n\n if (onChange) {\n const returnValue = getFormattedValue(values);\n onChange(returnValue);\n }\n\n if (onChangeRaw) {\n onChangeRaw([values.floor, values.unit]);\n }\n };\n\n const performOnBlurHandler = () => {\n if (!onBlur && !onBlurRaw) {\n return;\n }\n\n const values: Record<ValueFieldTypes, string> = {\n floor: formatInput(floorValueStateRef.current),\n unit: formatInput(unitValueStateRef.current),\n };\n\n if (onBlur) {\n const returnValue = getFormattedValue(values);\n onBlur(returnValue);\n }\n\n if (onBlurRaw) {\n onBlurRaw([values.floor, values.unit]);\n }\n };\n\n const getFormattedValue = (values: Record<ValueFieldTypes, string>) => {\n const valueArr = [values.floor, values.unit];\n\n if (values.floor.length > 0 && values.unit.length > 0) {\n return valueArr.join(\"-\");\n } else if (valueArr.every((value) => value === \"\")) {\n return \"\";\n } else {\n return INVALID_VALUE;\n }\n };\n\n const getPlaceholder = (value: string) => {\n return value.split(\"-\");\n };\n\n function formatPhraseWithPrefix(prefix: string, v: string) {\n return v ? `${prefix} ${Array.from(v).join(\" \")}` : \"\";\n }\n\n // =============================================================================\n // RENDER FUNCTION\n // =============================================================================\n const renderInputs = () => (\n <>\n <Input\n name=\"floor\"\n maxLength={3}\n value={floorValue}\n ref={floorInputRef}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n disabled={disabled}\n readOnly={readOnly}\n type=\"text\"\n pattern=\"[0-9A-Z]{2,3}\"\n data-testid=\"floor-input\"\n aria-labelledby={concatIds(ariaLabelledBy, floorLabelId)}\n aria-describedby={concatIds(ariaDescribedBy, liveMessageId)}\n aria-invalid={ariaInvalid}\n placeholder={\n currentFocus === \"floor\" && !readOnly && !disabled\n ? \"\"\n : getPlaceholder(placeholder)[0]\n }\n autoComplete={autoComplete}\n styleType=\"no-border\"\n className={clsx(styles.input, styles.floorInput)}\n />\n <VisuallyHidden aria-hidden id={floorLabelId}>\n Enter floor number\n </VisuallyHidden>\n <Typography.BodyBL\n className={clsx(\n styles.unitNumberDivider,\n floorValue.length === 0 && styles.unitNumberDividerInactive\n )}\n >\n -\n </Typography.BodyBL>\n <Input\n name=\"unit\"\n maxLength={5}\n value={unitValue}\n ref={unitInputRef}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n readOnly={readOnly}\n type=\"text\"\n pattern=\"[0-9A-Z]{2,5}\"\n data-testid=\"unit-input\"\n aria-labelledby={concatIds(ariaLabelledBy, unitLabelId)}\n aria-describedby={concatIds(ariaDescribedBy, liveMessageId)}\n aria-invalid={ariaInvalid}\n placeholder={\n currentFocus === \"unit\" && !readOnly && !disabled\n ? \"\"\n : getPlaceholder(placeholder)[1]\n }\n autoComplete={autoComplete}\n styleType=\"no-border\"\n className={clsx(\n styles.input,\n styles.floorInput,\n styles.unitInput\n )}\n />\n <VisuallyHidden aria-hidden id={unitLabelId}>\n Enter unit number\n </VisuallyHidden>\n {/** Live message for AT reader to read with the combination of prefix and current value for both floor input and unit input */}\n <VisuallyHidden id={liveMessageId} aria-live=\"polite\">\n {liveMessage}\n </VisuallyHidden>\n </>\n );\n\n const renderReadOnly = (displayValue: string) => {\n const displayValueArr = displayValue.split(\"-\");\n const liveMessageForReadOnly = [\n formatPhraseWithPrefix(\"Hash\", displayValueArr[0]),\n formatPhraseWithPrefix(\"Dash\", displayValueArr[1]),\n ].join(\" \");\n\n return (\n <div\n data-testid=\"readonly-display\"\n tabIndex={0}\n role=\"textbox\"\n aria-readonly\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n className={styles.readOnlyContainer}\n >\n <Typography.BodyBL>{displayValueArr[0]}</Typography.BodyBL>\n <Typography.BodyBL className={styles.unitNumberDivider}>\n -\n </Typography.BodyBL>\n <Typography.BodyBL>{displayValueArr[1]}</Typography.BodyBL>\n <VisuallyHidden>{liveMessageForReadOnly}</VisuallyHidden>\n </div>\n );\n };\n\n return (\n <InputWrapper\n {...otherProps}\n ref={nodeRef}\n onClick={handleNodeClick}\n disabled={disabled}\n error={error}\n readOnly={readOnly}\n tabIndex={-1}\n onBlur={handleNodeBlur}\n className={className}\n >\n <div\n data-testid=\"addon\"\n className={clsx(\n styles.hashContainer,\n inputGroupStyles.labelAddonContainer\n )}\n data-disabled={disabled}\n data-read-only={readOnly}\n >\n #\n </div>\n {readOnly && value ? renderReadOnly(value) : renderInputs()}\n </InputWrapper>\n );\n};\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\nconst INVALID_VALUE = \"Invalid unit number\";\n"],"names":["INVALID_VALUE","_a","disabled","error","value","onChange","onBlur","onChangeRaw","onBlurRaw","readOnly","placeholder","autoComplete","ariaLabelledBy","ariaDescribedBy","ariaInvalid","className","otherProps","__rest","floorValue","_setFloorValue","useState","unitValue","_setUnitValue","currentFocus","_setCurrentFocus","internalId","useId","floorLabelId","unitLabelId","liveMessageId","nodeRef","useRef","floorInputRef","unitInputRef","floorValueStateRef","unitValueStateRef","currentFocusStateRef","formatter","toLocaleUpperCase","replace","getNextFloorInputState","useNextInputState","ref","getNextUnitInputState","liveMessage","useMemo","msg","floorMsg","formatPhraseWithPrefix","unitMsg","join","setFloorValue","data","current","setUnitValue","setCurrentFocus","useEffect","length","focus","updateValues","handleFocus","event","target","name","select","handleBlur","targetName","targetValue","formattedInput","formatInput","performOnChangeHandler","handleChange","nextInputState","nextValue","updateCaretPosition","handleKeyDown","code","key","test","StringHelper","padValue","undefined","valueArr","split","floor","unit","changeValue","field","values","returnValue","getFormattedValue","performOnBlurHandler","every","getPlaceholder","prefix","v","Array","from","_jsxs","InputWrapper","Object","assign","onClick","tabIndex","contains","relatedTarget","children","_jsx","clsx","styles.hashContainer","inputGroupStyles.labelAddonContainer","displayValue","displayValueArr","liveMessageForReadOnly","role","styles.readOnlyContainer","Typography","BodyBL","styles.unitNumberDivider","VisuallyHidden","renderReadOnly","_Fragment","Input","maxLength","onFocus","type","pattern","concatIds","styleType","styles.input","styles.floorInput","id","styles.unitNumberDividerInactive","onKeyDown","styles.unitInput"],"mappings":"4sBAuBO,MAuaDA,EAAgB,8CAvaUC,IAAA,IAAAC,SAC5BA,EAAQC,MACRA,EAAKC,MACLA,EAAKC,SACLA,EAAQC,OACRA,EAAMC,YACNA,EAAWC,UACXA,EAASC,SACTA,EAAQC,YACRA,EAAc,UAASC,aACvBA,EACA,kBAAmBC,EACnB,mBAAoBC,EACpB,eAAgBC,EAAWC,UAC3BA,GAASd,EACNe,EAAUC,EAAAA,OAAAhB,EAfe,oLAoB5B,MAAOiB,EAAYC,GAAkBC,EAAAA,SAAiB,KAC/CC,EAAWC,GAAiBF,EAAAA,SAAiB,KAC7CG,EAAcC,GAAoBJ,EAAAA,SAAoB,QACvDK,EAAaC,EAAAA,QACbC,EAAe,GAAGF,gBAClBG,EAAc,GAAGH,eACjBI,EAAgB,GAAGJ,iBAEnBK,EAAUC,EAAAA,OAAuB,MACjCC,EAAgBD,EAAAA,OAAyB,MACzCE,EAAeF,EAAAA,OAAyB,MASxCG,EAAqBH,EAAAA,OAAeb,GACpCiB,EAAoBJ,EAAAA,OAAeV,GACnCe,EAAuBL,EAAAA,OAAkBR,GAEzCc,EAAajC,GACfA,EAAMkC,oBAAoBC,QAAQ,gBAAiB,IACjDC,EAAyBC,EAAAA,kBAAkB,CAC7CC,IAAKV,EACLK,cAEEM,EAAwBF,EAAAA,kBAAkB,CAC5CC,IAAKT,EACLI,cAGEO,EAAcC,EAAAA,SAAQ,KACxB,IAAIC,EAAM,GACV,MAAMC,EAAWC,GAAuB,OAAQ9B,GAC1C+B,EAAUD,GAAuB,OAAQ3B,GAC/C,OAAQE,GACJ,IAAK,QACDuB,EAAMC,EACN,MACJ,IAAK,OACDD,EAAM5B,EAAa,CAAC6B,EAAUE,GAASC,KAAK,KAAOD,EACnD,MACJ,QACIH,EAAM,GAEd,OAAOA,CAAG,GACX,CAACvB,EAAcL,EAAYG,IAKxB8B,EAAiBC,IACnBlB,EAAmBmB,QAAUD,EAC7BjC,EAAeiC,EAAK,EAGlBE,EAAgBF,IAClBjB,EAAkBkB,QAAUD,EAC5B9B,EAAc8B,EAAK,EAGjBG,EAAmBH,IACrBhB,EAAqBiB,QAAUD,EAC/B5B,EAAiB4B,EAAK,EAM1BI,EAAAA,WAAU,KAGe,UAAjBjC,GACsB,IAAtBL,EAAWuC,QACXxB,EAAaoB,SAEbpB,EAAaoB,QAAQK,OACzB,GAED,CAACxC,IAEJsC,EAAAA,WAAU,KACNG,GAAavD,EAAM,GAEpB,CAACA,IAKJ,MAAMwD,EAAeC,IACjBN,EAAgBM,EAAMC,OAAOC,MAC7BF,EAAMC,OAAOE,QAAQ,EAGnBC,GAAcJ,IAChB,MAAMK,EAAaL,EAAMC,OAAOC,KAC1BI,EAAcN,EAAMC,OAAO1D,MAC3BgE,EAAiBC,GAAYF,GAEhB,UAAfD,GACAf,EAAciB,GACVA,IAAmBlD,GACnBoD,GAAuBF,EAAgBF,IAErB,SAAfA,IACPZ,EAAac,GACTA,IAAmB/C,GACnBiD,GAAuBF,EAAgBF,GAE/C,EAGEK,GAAgBV,IAClB,MAAMK,EAAaL,EAAMC,OAAOC,KAEhC,GAAmB,UAAfG,EAAwB,CACxB,MAAMM,EAAiBhC,IACvB,IAAKgC,EAAgB,OAErB,MAAMC,UAAEA,EAASC,oBAAEA,GAAwBF,EAC3CE,IACAvB,EAAcsB,GACdH,GAAuBG,EAAWP,EACtC,MAAO,GAAmB,SAAfA,EAAuB,CAC9B,MAAMM,EAAiB7B,IACvB,IAAK6B,EAAgB,OAErB,MAAMC,UAAEA,EAASC,oBAAEA,GAAwBF,EAC3CE,IACApB,EAAamB,GACbH,GAAuBG,EAAWP,EACtC,GAoBES,GAAiBd,UAKA,cAAfA,EAAMe,MAAsC,cAAdf,EAAMgB,KACf,SAAjBtD,GAAgD,IAArBF,EAAUoC,SAChB,QAArBxD,EAAA+B,EAAcqB,eAAO,IAAApD,GAAAA,EAAEyD,QAE/B,EAMEW,GAAejE,GACV,UAAU0E,KAAK1E,GAChB2E,eAAaC,SAAS5E,GAAO,GAC7BA,EAAMkC,oBAGVqB,GAAgBvD,IAClB,GAAIA,IAAUJ,EAEP,QAAciF,IAAV7E,GAAwC,IAAjBA,EAAMqD,OACpCN,EAAc,IACdG,EAAa,QACV,CACH,MAAM4B,EAAW9E,EAAM+E,MAAM,KAC7B,GAAwB,IAApBD,EAASzB,OAAc,CAEvB,MAAM2B,EAAQF,EAAS,GACjBG,EAAOH,EAAS,GACtB/B,EACqB,UAAjB5B,EAA2B6D,EAAQf,GAAYe,IAEnD9B,EACqB,SAAjB/B,EAA0B8D,EAAOhB,GAAYgB,GAErD,CACJ,GAGEf,GAAyB,CAC3BgB,EACAC,KAEA,IAAKlF,IAAaE,EACd,OAGJ,MAAMiF,EAA0C,CAC5CJ,MAAOlD,EAAmBmB,QAC1BgC,KAAMlD,EAAkBkB,SAM5B,GAFAmC,EAAOD,GAASD,EAEZjF,EAAU,CACV,MAAMoF,EAAcC,GAAkBF,GACtCnF,EAASoF,EACb,CAEIlF,GACAA,EAAY,CAACiF,EAAOJ,MAAOI,EAAOH,MACtC,EAGEM,GAAuB,KACzB,IAAKrF,IAAWE,EACZ,OAGJ,MAAMgF,EAA0C,CAC5CJ,MAAOf,GAAYnC,EAAmBmB,SACtCgC,KAAMhB,GAAYlC,EAAkBkB,UAGxC,GAAI/C,EAAQ,CACR,MAAMmF,EAAcC,GAAkBF,GACtClF,EAAOmF,EACX,CAEIjF,GACAA,EAAU,CAACgF,EAAOJ,MAAOI,EAAOH,MACpC,EAGEK,GAAqBF,IACvB,MAAMN,EAAW,CAACM,EAAOJ,MAAOI,EAAOH,MAEvC,OAAIG,EAAOJ,MAAM3B,OAAS,GAAK+B,EAAOH,KAAK5B,OAAS,EACzCyB,EAAShC,KAAK,KACdgC,EAASU,OAAOxF,GAAoB,KAAVA,IAC1B,GAEAJ,CACX,EAGE6F,GAAkBzF,GACbA,EAAM+E,MAAM,KAGvB,SAASnC,GAAuB8C,EAAgBC,GAC5C,OAAOA,EAAI,GAAGD,KAAUE,MAAMC,KAAKF,GAAG7C,KAAK,OAAS,EACxD,CA+GA,OACIgD,OAACC,EAAAA,aAAYC,OAAAC,OAAA,CAAA,EACLrF,GACJ0B,IAAKZ,EACLwE,QA/OgB,KACC,SAAjB/E,GAA2BS,EAAcqB,SACzCrB,EAAcqB,QAAQK,OAC1B,EA6OIxD,SAAUA,EACVC,MAAOA,EACPM,SAAUA,EACV8F,UAAU,EACVjG,OA9OgBuD,IAChB/B,EAAQuB,SAAWvB,EAAQuB,QAAQmD,SAAS3C,EAAM4C,gBAIjB,SAAjCrE,EAAqBiB,UACrBE,EAAgB,QAChBoC,KACJ,EAuOI5E,UAAWA,EAAS2F,SAAA,CAEpBC,EAAAA,IAAA,MAAA,CAAA,cACgB,QACZ5F,UAAW6F,EAAAA,QACPC,gBACAC,EAAAA,qBACH,gBACc5G,EAAQ,iBACPO,EAAQiG,SAAA,MAI3BjG,GAAYL,EAnDE,CAAC2G,IACpB,MAAMC,EAAkBD,EAAa5B,MAAM,KACrC8B,EAAyB,CAC3BjE,GAAuB,OAAQgE,EAAgB,IAC/ChE,GAAuB,OAAQgE,EAAgB,KACjD9D,KAAK,KAEP,OACIgD,OAAA,MAAA,CAAA,cACgB,mBACZK,SAAU,EACVW,KAAK,UAAS,iBAAA,EAAA,kBAEGtG,EAAc,mBACbC,EAAe,eACnBC,EACdC,UAAWoG,EAAAA,kBAAwBT,SAAA,CAEnCC,EAAAA,IAACS,EAAAA,WAAWC,OAAM,CAAAX,SAAEM,EAAgB,KACpCL,MAACS,EAAAA,WAAWC,OAAM,CAACtG,UAAWuG,EAAAA,kBAAwBZ,SAAA,MAGtDC,EAAAA,IAACS,EAAAA,WAAWC,OAAM,CAAAX,SAAEM,EAAgB,KACpCL,MAACY,EAAAA,eAAc,CAAAb,SAAEO,MACf,EA2BeO,CAAepH,GAhIxC8F,OAAAuB,EAAAA,SAAA,CAAAf,SAAA,CACIC,EAAAA,IAACe,EAAAA,MAAK,CACF3D,KAAK,QACL4D,UAAW,EACXvH,MAAOc,EACPwB,IAAKV,EACL4F,QAAShE,EACTtD,OAAQ2D,GACR5D,SAAUkE,GACVrE,SAAUA,EACVO,SAAUA,EACVoH,KAAK,OACLC,QAAQ,8BACI,cAAa,kBACRC,EAAAA,UAAUnH,EAAgBe,GAAa,mBACtCoG,YAAUlH,EAAiBgB,GAAc,eAC7Cf,EACdJ,YACqB,UAAjBa,GAA6Bd,GAAaP,EAEpC2F,GAAenF,GAAa,GAD5B,GAGVC,aAAcA,EACdqH,UAAU,YACVjH,UAAW6F,EAAAA,QAAKqB,QAAcC,EAAAA,cAElCvB,EAAAA,IAACY,EAAAA,eAAc,CAAA,eAAA,EAAaY,GAAIxG,EAAY+E,SAAA,uBAG5CC,MAACS,EAAAA,WAAWC,OAAM,CACdtG,UAAW6F,EAAAA,QACPU,oBACsB,IAAtBpG,EAAWuC,QAAgB2E,EAAAA,2BAC9B1B,SAAA,MAILC,EAAAA,IAACe,EAAAA,MAAK,CACF3D,KAAK,OACL4D,UAAW,EACXvH,MAAOiB,EACPqB,IAAKT,EACL2F,QAAShE,EACTtD,OAAQ2D,GACR5D,SAAUkE,GACV8D,UAAW1D,GACXzE,SAAUA,EACVO,SAAUA,EACVoH,KAAK,OACLC,QAAQ,8BACI,aAAY,kBACPC,EAAAA,UAAUnH,EAAgBgB,sBACzBmG,EAAAA,UAAUlH,EAAiBgB,GAAc,eAC7Cf,EACdJ,YACqB,SAAjBa,GAA4Bd,GAAaP,EAEnC2F,GAAenF,GAAa,GAD5B,GAGVC,aAAcA,EACdqH,UAAU,YACVjH,UAAW6F,EAAAA,QACPqB,EAAAA,MACAC,aACAI,EAAAA,aAGR3B,EAAAA,IAACY,iBAAc,CAAA,eAAA,EAAaY,GAAIvG,EAAW8E,SAAA,sBAI3CC,EAAAA,IAACY,EAAAA,eAAc,CAACY,GAAItG,EAAa,YAAY,SAAQ6E,SAChD9D,UAyDM"}
@@ -1 +1 @@
1
- {"version":3,"file":"is-styled-components.js","sources":["../../../src/util/is-styled-components.ts"],"sourcesContent":["/*\n Extracted isStyledComponent function from styled-components repo \n Refer to the original implementation here:\n https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/utils/isStyledComponent.ts\n*/\n\ntype StyledComponentBrand = { readonly _sc: symbol };\n\nexport default function isStyledComponent(\n target: any\n): target is StyledComponentBrand {\n return (\n target != null &&\n (typeof target === \"function\" || typeof target === \"object\") &&\n \"styledComponentId\" in target\n );\n}\n"],"names":["target"],"mappings":"oFAQc,SACVA,GAEA,OACc,MAAVA,IACmB,mBAAXA,GAA2C,iBAAXA,IACxC,sBAAuBA,CAE/B"}
1
+ {"version":3,"file":"is-styled-components.js","sources":["../../../src/util/is-styled-components.ts"],"sourcesContent":["/*\n Extracted isStyledComponent function from styled-components repo \n Refer to the original implementation here:\n https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/utils/isStyledComponent.ts\n*/\n\ntype StyledComponentBrand = { readonly _sc: symbol };\n\nexport default function isStyledComponent(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n target: any\n): target is StyledComponentBrand {\n return (\n target != null &&\n (typeof target === \"function\" || typeof target === \"object\") &&\n \"styledComponentId\" in target\n );\n}\n"],"names":["target"],"mappings":"oFAQc,SAEVA,GAEA,OACc,MAAVA,IACmB,mBAAXA,GAA2C,iBAAXA,IACxC,sBAAuBA,CAE/B"}
@@ -1,2 +1,2 @@
1
- "use strict";class t{static transformWithSpaces(t,e){const n="(.{"+e+"})";return t.replace(/[^\dA-Z]/gi,"").replace(new RegExp(n,"g"),"$1 ").trim()}static padValue(t,e){if("0"===t)return e?t:t.padStart(2,"0");if(""===t)return t;return parseInt(t).toString().padStart(2,"0")}static shouldTruncateToTwoLines(t,e){const n=Math.floor(e/9);return t.length>=2*n||1===t.split(" ").length&&t.length>n}static truncateOneLine(t,e,n,r,s=8){let a=0;e>n&&(a=Math.floor((e-n)/s));const i=r+a;if(i<t.length){const e=Math.floor(i/2);return t.substring(0,e)+" ... "+t.substring(t.length-e,t.length)}return t}static truncateTwoLines(t,e,n,r=1.2){const s=Math.floor(2*e/(.6*n))*(2/r);if(t.length<=s)return t;const a=Math.floor(.6*s),i=Math.floor(.2*s);return`${t.substring(0,a)}...${t.substring(t.length-i)}`}static getTextWidth(e,n){if("undefined"==typeof document)return 0;const r=(t.getTextWidth.canvas||(t.getTextWidth.canvas=document.createElement("canvas"))).getContext("2d");r.font=n;return r.measureText(e).width}static maskValue(e,n){if(!e)return e;const{maskRange:r,unmaskRange:s,maskChar:a="•",maskRegex:i,maskTransformer:u}=n;if(u)return u(e);if(i)return e.replace(i,a);if(r){const{startIndex:n,endIndex:s}=t.determineStartAndEndIndex(r[0],r[1]);return e.substring(0,n)+a.repeat(e.substring(n,s+1).length)+e.substring(s+1)}if(s){const{startIndex:n,endIndex:r}=t.determineStartAndEndIndex(s[0],s[1]);return a.repeat(e.substring(0,n).length)+e.substring(n,r+1)+a.repeat(e.substring(r+1).length)}return e}static determineStartAndEndIndex(t,e){return t<e?{startIndex:t,endIndex:e}:{startIndex:e,endIndex:t}}static formatOrdinal(e){const n=t.ordinalPluralRules.select(e);return`${e}${t.suffixes.get(n)}`}static getMaskedDescription(t,e,n){if(!t||"masked"!==e||!n)return"";const[r,s]=n,a=r>0,i=s<t.length-1,u=a?t.substring(0,r):"",o=i?t.substring(s+1):"";return a&&i?`Starting with ${u} and ending with ${o}`:a?`Starting with ${u}`:i?`Ending with ${o}`:""}static joinNonEmptyStrings(t,e=", "){return t.filter(Boolean).join(e)}}t.ordinalPluralRules=new Intl.PluralRules("en",{type:"ordinal"}),t.suffixes=new Map([["one","st"],["two","nd"],["few","rd"],["other","th"]]),exports.StringHelper=t;
1
+ "use strict";class t{static transformWithSpaces(t,e){const n="(.{"+e+"})";return t.replace(/[^\dA-Z]/gi,"").replace(new RegExp(n,"g"),"$1 ").trim()}static padValue(t,e){if("0"===t)return e?t:t.padStart(2,"0");if(""===t)return t;return parseInt(t).toString().padStart(2,"0")}static shouldTruncateToTwoLines(t,e){const n=Math.floor(e/9);return t.length>=2*n||1===t.split(" ").length&&t.length>n}static truncateOneLine(t,e,n,r,s=8){let i=0;e>n&&(i=Math.floor((e-n)/s));const a=r+i;if(a<t.length){const e=Math.floor(a/2);return t.substring(0,e)+" ... "+t.substring(t.length-e,t.length)}return t}static truncateTwoLines(t,e,n,r=1.2){const s=Math.floor(2*e/(.6*n))*(2/r);if(t.length<=s)return t;const i=Math.floor(.6*s),a=Math.floor(.2*s);return`${t.substring(0,i)}...${t.substring(t.length-a)}`}static getTextWidth(t,e){if("undefined"==typeof document)return 0;const n=(this.getTextWidth.canvas||(this.getTextWidth.canvas=document.createElement("canvas"))).getContext("2d");n.font=e;return n.measureText(t).width}static maskValue(t,e){if(!t)return t;const{maskRange:n,unmaskRange:r,maskChar:s="•",maskRegex:i,maskTransformer:a}=e;if(a)return a(t);if(i)return t.replace(i,s);if(n){const{startIndex:e,endIndex:r}=this.determineStartAndEndIndex(n[0],n[1]);return t.substring(0,e)+s.repeat(t.substring(e,r+1).length)+t.substring(r+1)}if(r){const{startIndex:e,endIndex:n}=this.determineStartAndEndIndex(r[0],r[1]);return s.repeat(t.substring(0,e).length)+t.substring(e,n+1)+s.repeat(t.substring(n+1).length)}return t}static determineStartAndEndIndex(t,e){return t<e?{startIndex:t,endIndex:e}:{startIndex:e,endIndex:t}}static formatOrdinal(t){const e=this.ordinalPluralRules.select(t);return`${t}${this.suffixes.get(e)}`}static getMaskedDescription(t,e,n){if(!t||"masked"!==e||!n)return"";const[r,s]=n,i=r>0,a=s<t.length-1,u=i?t.substring(0,r):"",o=a?t.substring(s+1):"";return i&&a?`Starting with ${u} and ending with ${o}`:i?`Starting with ${u}`:a?`Ending with ${o}`:""}static joinNonEmptyStrings(t,e=", "){return t.filter(Boolean).join(e)}}t.ordinalPluralRules=new Intl.PluralRules("en",{type:"ordinal"}),t.suffixes=new Map([["one","st"],["two","nd"],["few","rd"],["other","th"]]),exports.StringHelper=t;
2
2
  //# sourceMappingURL=string-helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"string-helper.js","sources":["../../../src/util/string-helper.ts"],"sourcesContent":["// =============================================================================\n// TYPINGS\n// =============================================================================\ninterface MaskValueOptions {\n maskRange?: number[] | undefined;\n unmaskRange?: number[] | undefined;\n maskRegex?: RegExp | undefined;\n maskTransformer?: ((value: string) => string) | undefined;\n maskChar?: string | undefined;\n}\n\n// =============================================================================\n// EXPORTS\n// =============================================================================\nexport class StringHelper {\n public static transformWithSpaces(\n value: string | any,\n groupLength: number\n ): string {\n const regex = \"(.{\" + groupLength + \"})\";\n return value\n .replace(/[^\\dA-Z]/gi, \"\")\n .replace(new RegExp(regex, \"g\"), \"$1 \")\n .trim();\n }\n\n /**\n * Pads single digit values with a zero and trims leading zero for\n * values of length more than 2\n * @param value the string value\n * @param retainSingleZero setting true will allow single zero value\n */\n public static padValue(value: string, retainSingleZero?: boolean): string {\n if (value === \"0\") {\n return retainSingleZero ? value : value.padStart(2, \"0\");\n }\n\n if (value === \"\") {\n return value;\n }\n\n const trimmedValue = parseInt(value);\n return trimmedValue.toString().padStart(2, \"0\");\n }\n\n /**\n * Checks if the text is required to be truncated and broken into two lines based\n * on the available width of container. **Note: This is relevant to font size 18px or 1.125rem only **\n * @param text input text\n * @param widthOfElement element width in px\n */\n public static shouldTruncateToTwoLines(\n text: string,\n widthOfElement: number\n ): boolean {\n // This is arbitrary and based on tests to derive that every 9px increment ~= 1 char length.\n // But this applies to font size 18px or 1.125rem only\n const estimatedCharOnLine = Math.floor(widthOfElement / 9);\n return (\n text.length >= estimatedCharOnLine * 2 ||\n (text.split(\" \").length === 1 && text.length > estimatedCharOnLine)\n );\n }\n\n /**\n * Performs a truncation by adding ellipsis in the middle of the text.\n * @param text input text\n * @param widthOfElement the dynamic width of the container in px\n * @param minDivSize the minimum container size (using size on mobileS viewport as baseline)\n * @param baselineCharLength the baseline amount of characters to be displayed before truncation kicks. This\n * will be increased if there is more space available (derived from `widthOfElement`)\n * @param incrementFactor the size (in px).\n */\n public static truncateOneLine(\n text: string,\n widthOfElement: number,\n minDivSize: number,\n baselineCharLength: number,\n incrementFactor = 8 // Arbitrary based on tests and applies to font size of 18px or 1.125rem\n ): string {\n let additionalCharAllowed = 0;\n if (widthOfElement > minDivSize) {\n additionalCharAllowed = Math.floor(\n (widthOfElement - minDivSize) / incrementFactor\n );\n }\n const allowedCharLength = baselineCharLength + additionalCharAllowed;\n if (allowedCharLength < text.length) {\n const thresholdIndex = Math.floor(allowedCharLength / 2); // We will cut it halfway to derive x num of characters\n return (\n text.substring(0, thresholdIndex) + // Use the first x\n \" ... \" +\n text.substring(text.length - thresholdIndex, text.length) // Use the last x\n );\n }\n\n return text;\n }\n\n /**\n * Performs a truncation by adding ellipsis in the middle of the text.\n * @param text input text\n * @param widthOfElement the dynamic width of the container in px\n * @param fontSize the fontsize of the text\n * @param lineHeight the line height of the text\n */\n public static truncateTwoLines(\n text: string,\n widthOfElement: number,\n fontSize: number,\n lineHeight = 1.2\n ): string {\n // Estimate characters per line based on width and font size\n const charsPerLine = Math.floor(\n (widthOfElement * 2) / (fontSize * 0.6) // 0.6 is an approximation for average char width\n );\n\n // Calculate total characters allowed in two lines\n const totalCharsAllowed = charsPerLine * (2 / lineHeight);\n\n if (text.length <= totalCharsAllowed) {\n return text; // No truncation needed\n }\n\n // Calculate the number of characters to keep\n const keepFromStart = Math.floor(totalCharsAllowed * 0.6); // Keep 60% from start\n const keepFromEnd = Math.floor(totalCharsAllowed * 0.2); // Keep 20% from end\n\n // Truncate the text\n const start = text.substring(0, keepFromStart);\n const end = text.substring(text.length - keepFromEnd);\n\n return `${start}...${end}`;\n }\n\n /**\n * Returns the width of the text in the specified font\n * https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\n */\n public static getTextWidth(text: string, font: string): number {\n if (typeof document === \"undefined\") {\n return 0;\n }\n\n // create a reusable canvas object for better performance\n const canvas =\n (StringHelper.getTextWidth as any).canvas ||\n ((StringHelper.getTextWidth as any).canvas =\n document.createElement(\"canvas\"));\n const context = canvas.getContext(\"2d\");\n context.font = font;\n\n const metrics = context.measureText(text);\n return metrics.width;\n }\n\n public static maskValue(value: string, options: MaskValueOptions): string {\n if (!value) {\n return value;\n }\n\n const {\n maskRange,\n unmaskRange,\n maskChar = \"•\",\n maskRegex,\n maskTransformer,\n } = options;\n\n if (maskTransformer) {\n return maskTransformer(value);\n } else if (maskRegex) {\n return value.replace(maskRegex, maskChar);\n } else if (maskRange) {\n const { startIndex, endIndex } =\n StringHelper.determineStartAndEndIndex(\n maskRange[0],\n maskRange[1]\n );\n return (\n value.substring(0, startIndex) +\n maskChar.repeat(\n value.substring(startIndex, endIndex + 1).length\n ) +\n value.substring(endIndex + 1)\n );\n } else if (unmaskRange) {\n const { startIndex, endIndex } =\n StringHelper.determineStartAndEndIndex(\n unmaskRange[0],\n unmaskRange[1]\n );\n return (\n maskChar.repeat(value.substring(0, startIndex).length) +\n value.substring(startIndex, endIndex + 1) +\n maskChar.repeat(value.substring(endIndex + 1).length)\n );\n }\n\n return value;\n }\n\n private static determineStartAndEndIndex(index0: number, index1: number) {\n return index0 < index1\n ? { startIndex: index0, endIndex: index1 }\n : { startIndex: index1, endIndex: index0 };\n }\n\n private static ordinalPluralRules = new Intl.PluralRules(\"en\", {\n type: \"ordinal\",\n });\n\n private static suffixes = new Map([\n [\"one\", \"st\"],\n [\"two\", \"nd\"],\n [\"few\", \"rd\"],\n [\"other\", \"th\"],\n ]);\n\n public static formatOrdinal(n: number) {\n const rule = StringHelper.ordinalPluralRules.select(n);\n const suffix = StringHelper.suffixes.get(rule);\n return `${n}${suffix}`;\n }\n\n public static getMaskedDescription(\n value: string,\n displayMaskState: \"masked\" | \"unmasked\",\n maskRange?: number[]\n ): string {\n if (!value || displayMaskState !== \"masked\" || !maskRange) return \"\";\n\n const [startIndex, endIndex] = maskRange;\n const hasStart = startIndex > 0;\n const hasEnd = endIndex < value.length - 1;\n\n const start = hasStart ? value.substring(0, startIndex) : \"\";\n const end = hasEnd ? value.substring(endIndex + 1) : \"\";\n\n if (hasStart && hasEnd)\n return `Starting with ${start} and ending with ${end}`;\n if (hasStart) return `Starting with ${start}`;\n if (hasEnd) return `Ending with ${end}`;\n\n return \"\";\n }\n\n public static joinNonEmptyStrings(\n strings: (string | undefined | null)[],\n delimiter = \", \"\n ): string {\n return strings.filter(Boolean).join(delimiter);\n }\n}\n"],"names":["StringHelper","transformWithSpaces","value","groupLength","regex","replace","RegExp","trim","padValue","retainSingleZero","padStart","parseInt","toString","shouldTruncateToTwoLines","text","widthOfElement","estimatedCharOnLine","Math","floor","length","split","truncateOneLine","minDivSize","baselineCharLength","incrementFactor","additionalCharAllowed","allowedCharLength","thresholdIndex","substring","truncateTwoLines","fontSize","lineHeight","totalCharsAllowed","keepFromStart","keepFromEnd","getTextWidth","font","document","context","canvas","createElement","getContext","measureText","width","maskValue","options","maskRange","unmaskRange","maskChar","maskRegex","maskTransformer","startIndex","endIndex","determineStartAndEndIndex","repeat","index0","index1","formatOrdinal","n","rule","ordinalPluralRules","select","suffixes","get","getMaskedDescription","displayMaskState","hasStart","hasEnd","start","end","joinNonEmptyStrings","strings","delimiter","filter","Boolean","join","Intl","PluralRules","type","Map"],"mappings":"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"}
1
+ {"version":3,"file":"string-helper.js","sources":["../../../src/util/string-helper.ts"],"sourcesContent":["// =============================================================================\n// TYPINGS\n// =============================================================================\ninterface MaskValueOptions {\n maskRange?: number[] | undefined;\n unmaskRange?: number[] | undefined;\n maskRegex?: RegExp | undefined;\n maskTransformer?: ((value: string) => string) | undefined;\n maskChar?: string | undefined;\n}\n\n// =============================================================================\n// EXPORTS\n// =============================================================================\nexport class StringHelper {\n public static transformWithSpaces(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value: string | any,\n groupLength: number\n ): string {\n const regex = \"(.{\" + groupLength + \"})\";\n return value\n .replace(/[^\\dA-Z]/gi, \"\")\n .replace(new RegExp(regex, \"g\"), \"$1 \")\n .trim();\n }\n\n /**\n * Pads single digit values with a zero and trims leading zero for\n * values of length more than 2\n * @param value the string value\n * @param retainSingleZero setting true will allow single zero value\n */\n public static padValue(value: string, retainSingleZero?: boolean): string {\n if (value === \"0\") {\n return retainSingleZero ? value : value.padStart(2, \"0\");\n }\n\n if (value === \"\") {\n return value;\n }\n\n const trimmedValue = parseInt(value);\n return trimmedValue.toString().padStart(2, \"0\");\n }\n\n /**\n * Checks if the text is required to be truncated and broken into two lines based\n * on the available width of container. **Note: This is relevant to font size 18px or 1.125rem only **\n * @param text input text\n * @param widthOfElement element width in px\n */\n public static shouldTruncateToTwoLines(\n text: string,\n widthOfElement: number\n ): boolean {\n // This is arbitrary and based on tests to derive that every 9px increment ~= 1 char length.\n // But this applies to font size 18px or 1.125rem only\n const estimatedCharOnLine = Math.floor(widthOfElement / 9);\n return (\n text.length >= estimatedCharOnLine * 2 ||\n (text.split(\" \").length === 1 && text.length > estimatedCharOnLine)\n );\n }\n\n /**\n * Performs a truncation by adding ellipsis in the middle of the text.\n * @param text input text\n * @param widthOfElement the dynamic width of the container in px\n * @param minDivSize the minimum container size (using size on mobileS viewport as baseline)\n * @param baselineCharLength the baseline amount of characters to be displayed before truncation kicks. This\n * will be increased if there is more space available (derived from `widthOfElement`)\n * @param incrementFactor the size (in px).\n */\n public static truncateOneLine(\n text: string,\n widthOfElement: number,\n minDivSize: number,\n baselineCharLength: number,\n incrementFactor = 8 // Arbitrary based on tests and applies to font size of 18px or 1.125rem\n ): string {\n let additionalCharAllowed = 0;\n if (widthOfElement > minDivSize) {\n additionalCharAllowed = Math.floor(\n (widthOfElement - minDivSize) / incrementFactor\n );\n }\n const allowedCharLength = baselineCharLength + additionalCharAllowed;\n if (allowedCharLength < text.length) {\n const thresholdIndex = Math.floor(allowedCharLength / 2); // We will cut it halfway to derive x num of characters\n return (\n text.substring(0, thresholdIndex) + // Use the first x\n \" ... \" +\n text.substring(text.length - thresholdIndex, text.length) // Use the last x\n );\n }\n\n return text;\n }\n\n /**\n * Performs a truncation by adding ellipsis in the middle of the text.\n * @param text input text\n * @param widthOfElement the dynamic width of the container in px\n * @param fontSize the fontsize of the text\n * @param lineHeight the line height of the text\n */\n public static truncateTwoLines(\n text: string,\n widthOfElement: number,\n fontSize: number,\n lineHeight = 1.2\n ): string {\n // Estimate characters per line based on width and font size\n const charsPerLine = Math.floor(\n (widthOfElement * 2) / (fontSize * 0.6) // 0.6 is an approximation for average char width\n );\n\n // Calculate total characters allowed in two lines\n const totalCharsAllowed = charsPerLine * (2 / lineHeight);\n\n if (text.length <= totalCharsAllowed) {\n return text; // No truncation needed\n }\n\n // Calculate the number of characters to keep\n const keepFromStart = Math.floor(totalCharsAllowed * 0.6); // Keep 60% from start\n const keepFromEnd = Math.floor(totalCharsAllowed * 0.2); // Keep 20% from end\n\n // Truncate the text\n const start = text.substring(0, keepFromStart);\n const end = text.substring(text.length - keepFromEnd);\n\n return `${start}...${end}`;\n }\n\n /**\n * Returns the width of the text in the specified font\n * https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\n */\n public static getTextWidth(text: string, font: string): number {\n if (typeof document === \"undefined\") {\n return 0;\n }\n\n // create a reusable canvas object for better performance\n const canvas =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.getTextWidth as any).canvas ||\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((this.getTextWidth as any).canvas =\n document.createElement(\"canvas\"));\n const context = canvas.getContext(\"2d\");\n context.font = font;\n\n const metrics = context.measureText(text);\n return metrics.width;\n }\n\n public static maskValue(value: string, options: MaskValueOptions): string {\n if (!value) {\n return value;\n }\n\n const {\n maskRange,\n unmaskRange,\n maskChar = \"•\",\n maskRegex,\n maskTransformer,\n } = options;\n\n if (maskTransformer) {\n return maskTransformer(value);\n } else if (maskRegex) {\n return value.replace(maskRegex, maskChar);\n } else if (maskRange) {\n const { startIndex, endIndex } = this.determineStartAndEndIndex(\n maskRange[0],\n maskRange[1]\n );\n return (\n value.substring(0, startIndex) +\n maskChar.repeat(\n value.substring(startIndex, endIndex + 1).length\n ) +\n value.substring(endIndex + 1)\n );\n } else if (unmaskRange) {\n const { startIndex, endIndex } = this.determineStartAndEndIndex(\n unmaskRange[0],\n unmaskRange[1]\n );\n return (\n maskChar.repeat(value.substring(0, startIndex).length) +\n value.substring(startIndex, endIndex + 1) +\n maskChar.repeat(value.substring(endIndex + 1).length)\n );\n }\n\n return value;\n }\n\n private static determineStartAndEndIndex(index0: number, index1: number) {\n return index0 < index1\n ? { startIndex: index0, endIndex: index1 }\n : { startIndex: index1, endIndex: index0 };\n }\n\n private static readonly ordinalPluralRules = new Intl.PluralRules(\"en\", {\n type: \"ordinal\",\n });\n\n private static readonly suffixes = new Map([\n [\"one\", \"st\"],\n [\"two\", \"nd\"],\n [\"few\", \"rd\"],\n [\"other\", \"th\"],\n ]);\n\n public static formatOrdinal(n: number) {\n const rule = this.ordinalPluralRules.select(n);\n const suffix = this.suffixes.get(rule);\n return `${n}${suffix}`;\n }\n\n public static getMaskedDescription(\n value: string,\n displayMaskState: \"masked\" | \"unmasked\",\n maskRange?: number[]\n ): string {\n if (!value || displayMaskState !== \"masked\" || !maskRange) return \"\";\n\n const [startIndex, endIndex] = maskRange;\n const hasStart = startIndex > 0;\n const hasEnd = endIndex < value.length - 1;\n\n const start = hasStart ? value.substring(0, startIndex) : \"\";\n const end = hasEnd ? value.substring(endIndex + 1) : \"\";\n\n if (hasStart && hasEnd)\n return `Starting with ${start} and ending with ${end}`;\n if (hasStart) return `Starting with ${start}`;\n if (hasEnd) return `Ending with ${end}`;\n\n return \"\";\n }\n\n public static joinNonEmptyStrings(\n strings: (string | undefined | null)[],\n delimiter = \", \"\n ): string {\n return strings.filter(Boolean).join(delimiter);\n }\n}\n"],"names":["StringHelper","transformWithSpaces","value","groupLength","regex","replace","RegExp","trim","padValue","retainSingleZero","padStart","parseInt","toString","shouldTruncateToTwoLines","text","widthOfElement","estimatedCharOnLine","Math","floor","length","split","truncateOneLine","minDivSize","baselineCharLength","incrementFactor","additionalCharAllowed","allowedCharLength","thresholdIndex","substring","truncateTwoLines","fontSize","lineHeight","totalCharsAllowed","keepFromStart","keepFromEnd","getTextWidth","font","document","context","this","canvas","createElement","getContext","measureText","width","maskValue","options","maskRange","unmaskRange","maskChar","maskRegex","maskTransformer","startIndex","endIndex","determineStartAndEndIndex","repeat","index0","index1","formatOrdinal","n","rule","ordinalPluralRules","select","suffixes","get","getMaskedDescription","displayMaskState","hasStart","hasEnd","start","end","joinNonEmptyStrings","strings","delimiter","filter","Boolean","join","Intl","PluralRules","type","Map"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-event-listener.js","sources":["../../../src/util/use-event-listener.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\ntype Target = \"window\" | \"document\" | HTMLElement | null;\ntype Element = Window | Document | HTMLElement | null;\ntype EventHandler<K extends keyof WindowEventMap> = (\n event: WindowEventMap[K]\n) => void;\n\nexport const useEventListener = <K extends keyof WindowEventMap>(\n eventName: K,\n handler: EventHandler<K>,\n target: Target = \"window\",\n options?: AddEventListenerOptions | boolean\n) => {\n // Create a ref that stores handler\n const savedHandler = useRef<EventHandler<K>>();\n // Update ref.current value if handler changes.\n // This allows our effect below to always get latest handler ...\n useEffect(() => {\n savedHandler.current = handler;\n }, [handler]);\n\n useEffect(\n () => {\n let element: Element;\n switch (target) {\n case \"window\":\n element = window;\n break;\n case \"document\":\n element = document;\n break;\n default:\n element = target;\n }\n\n // Make sure element supports addEventListener\n if (!element || !element.addEventListener) return;\n\n // Create event listener that calls handler function stored in ref\n const eventListener = ((event: WindowEventMap[K]) =>\n savedHandler.current?.(event)) as EventListener;\n // Add event listener\n element.addEventListener(eventName, eventListener, options);\n // Remove event listener on cleanup\n return () => {\n element?.removeEventListener(eventName, eventListener, options);\n };\n },\n [eventName, target] // Re-run if eventName or element changes\n );\n};\n"],"names":["eventName","handler","target","options","savedHandler","useRef","useEffect","current","element","window","document","addEventListener","eventListener","event","_a","call","removeEventListener"],"mappings":"6DAQgC,CAC5BA,EACAC,EACAC,EAAiB,SACjBC,KAGA,MAAMC,EAAeC,EAAAA,SAGrBC,EAAAA,WAAU,KACNF,EAAaG,QAAUN,CAAO,GAC/B,CAACA,IAEJK,EAAAA,WACI,KACI,IAAIE,EACJ,OAAQN,GACJ,IAAK,SACDM,EAAUC,OACV,MACJ,IAAK,WACDD,EAAUE,SACV,MACJ,QACIF,EAAUN,EAIlB,IAAKM,IAAYA,EAAQG,iBAAkB,OAG3C,MAAMC,EAAkBC,IAA4B,IAAAC,EAChD,OAAoB,UAApBV,EAAaG,eAAO,IAAAO,OAAA,EAAAA,EAAAC,KAAAX,EAAGS,EAAM,EAIjC,OAFAL,EAAQG,iBAAiBX,EAAWY,EAAeT,GAE5C,KACHK,SAAAA,EAASQ,oBAAoBhB,EAAWY,EAAeT,EAAQ,CAClE,GAEL,CAACH,EAAWE,GACf"}
1
+ {"version":3,"file":"use-event-listener.js","sources":["../../../src/util/use-event-listener.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\ntype Target = \"window\" | \"document\" | HTMLElement | null;\ntype Element = Window | Document | HTMLElement | null;\ntype EventHandler<K extends keyof WindowEventMap> = (\n event: WindowEventMap[K]\n) => void;\n\nexport const useEventListener = <K extends keyof WindowEventMap>(\n eventName: K,\n handler: EventHandler<K>,\n target: Target = \"window\",\n options?: AddEventListenerOptions | boolean\n) => {\n // Create a ref that stores handler\n const savedHandler = useRef<EventHandler<K>>();\n // Update ref.current value if handler changes.\n // This allows our effect below to always get latest handler ...\n useEffect(() => {\n savedHandler.current = handler;\n }, [handler]);\n\n useEffect(\n () => {\n let element: Element;\n switch (target) {\n case \"window\":\n element = window;\n break;\n case \"document\":\n element = document;\n break;\n default:\n element = target;\n }\n\n // Make sure element supports addEventListener\n if (!element || !element.addEventListener) return;\n\n // Create event listener that calls handler function stored in ref\n const eventListener = ((event: WindowEventMap[K]) =>\n savedHandler.current?.(event)) as EventListener;\n // Add event listener\n element.addEventListener(eventName, eventListener, options);\n // Remove event listener on cleanup\n return () => {\n element?.removeEventListener(eventName, eventListener, options);\n };\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [eventName, target] // Re-run if eventName or element changes\n );\n};\n"],"names":["eventName","handler","target","options","savedHandler","useRef","useEffect","current","element","window","document","addEventListener","eventListener","event","_a","call","removeEventListener"],"mappings":"6DAQgC,CAC5BA,EACAC,EACAC,EAAiB,SACjBC,KAGA,MAAMC,EAAeC,EAAAA,SAGrBC,EAAAA,WAAU,KACNF,EAAaG,QAAUN,CAAO,GAC/B,CAACA,IAEJK,EAAAA,WACI,KACI,IAAIE,EACJ,OAAQN,GACJ,IAAK,SACDM,EAAUC,OACV,MACJ,IAAK,WACDD,EAAUE,SACV,MACJ,QACIF,EAAUN,EAIlB,IAAKM,IAAYA,EAAQG,iBAAkB,OAG3C,MAAMC,EAAkBC,IAA4B,IAAAC,EAChD,OAAoB,UAApBV,EAAaG,eAAO,IAAAO,OAAA,EAAAA,EAAAC,KAAAX,EAAGS,EAAM,EAIjC,OAFAL,EAAQG,iBAAiBX,EAAWY,EAAeT,GAE5C,KACHK,SAAAA,EAASQ,oBAAoBhB,EAAWY,EAAeT,EAAQ,CAClE,GAGL,CAACH,EAAWE,GACf"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-state-actions.js","sources":["../../../src/util/use-state-actions.ts"],"sourcesContent":["import { useReducer } from \"react\";\n\nimport type { RequiredKeys } from \"./utility-types\";\n\ntype ReducerObj<State> = {\n [action: string]: (state: State, payload: any) => State;\n};\n\ntype Actions<State, Reducers extends ReducerObj<State>> = {\n [T in keyof Reducers]: Reducers[T] extends (state: State) => State\n ? () => void\n : Reducers[T] extends (\n state: State,\n payload: Parameters<Reducers[T]>[1]\n ) => State\n ? (\n ...args: RequiredKeys<Parameters<Reducers[T]>[1]> extends never\n ? [payload?: Parameters<Reducers[T]>[1]]\n : [payload: Parameters<Reducers[T]>[1]]\n ) => void\n : never;\n};\n\ninterface StateActions<State, Reducers> {\n /** reducer initial state */\n initialState: State;\n /** specify functions that return the new state. must be immutable */\n reducers: Reducers;\n /** identify the reducer for debugging */\n name?: string;\n /** enable debugging */\n debug?: boolean;\n}\n\n/**\n * An interface around `React.useReducer` to limit boilerplate. Each action\n * is a function that takes in state and payload, then returns the updated state\n * immutably. Inspired by redux toolkit's createSlice api.\n *\n * Example:\n * ```\n * const initialState = { count: 0 };\n * const reducers = {\n * increment: (state) => ({ ...state, count: state.count + 1 }),\n * multiplyBy: (state, multiplier: number) => ({\n * ...state,\n * count: state.count * multiplier,\n * }),\n * };\n * const [state, actions] = useStateActions({ initialState, reducers });\n * actions.increment();\n * actions.multiplyBy(2);\n * ```\n *\n */\nexport const useStateActions = <State, Reducers extends ReducerObj<State>>({\n initialState,\n reducers,\n name,\n debug,\n}: StateActions<State, Reducers>): [State, Actions<State, Reducers>] => {\n const reducer = (state: State, action: { type: string; payload: any }) => {\n if (reducers[action.type]) {\n return reducers[action.type](state, action.payload);\n }\n return state;\n };\n const [state, dispatch] = useReducer(reducer, initialState);\n const actions = Object.fromEntries(\n Object.keys(reducers).map((actionType) => {\n return [\n actionType,\n (payload: unknown) => {\n if (debug) {\n logAction(name, actionType, payload);\n }\n dispatch({\n type: actionType,\n payload,\n });\n },\n ];\n })\n );\n return [state, actions] as [State, Actions<State, Reducers>];\n};\n\nconst logAction = (\n name: string | undefined,\n type: string,\n payload: unknown\n) => {\n const args = [];\n if (name) args.push(`[${name}]`);\n args.push(type, payload);\n\n console.log(...args);\n};\n"],"names":["logAction","name","type","payload","args","push","console","log","initialState","reducers","debug","state","dispatch","useReducer","action","Object","fromEntries","keys","map","actionType"],"mappings":"oCAuDO,MAgCDA,EAAY,CACdC,EACAC,EACAC,KAEA,MAAMC,EAAO,GACHA,EAAKC,KAAK,IAAIJ,MACxBG,EAAKC,KAAKH,EAAMC,GAEhBG,QAAQC,OAAOH,EAAK,0BAzCO,EAC3BI,eACAC,WACAR,OACAS,YAEA,MAMOC,EAAOC,GAAYC,EAAAA,YANV,CAACF,EAAcG,IACvBL,EAASK,EAAOZ,MACTO,EAASK,EAAOZ,MAAMS,EAAOG,EAAOX,SAExCQ,GAEmCH,GAiB9C,MAAO,CAACG,EAhBQI,OAAOC,YACnBD,OAAOE,KAAKR,GAAUS,KAAKC,GAChB,CACHA,EACChB,IACOO,GACAV,EAAUC,EAAMkB,EAAYhB,GAEhCS,EAAS,CACLV,KAAMiB,EACNhB,WACF,MAK0C"}
1
+ {"version":3,"file":"use-state-actions.js","sources":["../../../src/util/use-state-actions.ts"],"sourcesContent":["import { useReducer } from \"react\";\n\nimport type { RequiredKeys } from \"./utility-types\";\n\ntype ReducerObj<State> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [action: string]: (state: State, payload: any) => State;\n};\n\ntype Actions<State, Reducers extends ReducerObj<State>> = {\n [T in keyof Reducers]: Reducers[T] extends (state: State) => State\n ? () => void\n : Reducers[T] extends (\n state: State,\n payload: Parameters<Reducers[T]>[1]\n ) => State\n ? (\n ...args: RequiredKeys<Parameters<Reducers[T]>[1]> extends never\n ? [payload?: Parameters<Reducers[T]>[1]]\n : [payload: Parameters<Reducers[T]>[1]]\n ) => void\n : never;\n};\n\ninterface StateActions<State, Reducers> {\n /** reducer initial state */\n initialState: State;\n /** specify functions that return the new state. must be immutable */\n reducers: Reducers;\n /** identify the reducer for debugging */\n name?: string;\n /** enable debugging */\n debug?: boolean;\n}\n\n/**\n * An interface around `React.useReducer` to limit boilerplate. Each action\n * is a function that takes in state and payload, then returns the updated state\n * immutably. Inspired by redux toolkit's createSlice api.\n *\n * Example:\n * ```\n * const initialState = { count: 0 };\n * const reducers = {\n * increment: (state) => ({ ...state, count: state.count + 1 }),\n * multiplyBy: (state, multiplier: number) => ({\n * ...state,\n * count: state.count * multiplier,\n * }),\n * };\n * const [state, actions] = useStateActions({ initialState, reducers });\n * actions.increment();\n * actions.multiplyBy(2);\n * ```\n *\n */\nexport const useStateActions = <State, Reducers extends ReducerObj<State>>({\n initialState,\n reducers,\n name,\n debug,\n}: StateActions<State, Reducers>): [State, Actions<State, Reducers>] => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const reducer = (state: State, action: { type: string; payload: any }) => {\n if (reducers[action.type]) {\n return reducers[action.type](state, action.payload);\n }\n return state;\n };\n const [state, dispatch] = useReducer(reducer, initialState);\n const actions = Object.fromEntries(\n Object.keys(reducers).map((actionType) => {\n return [\n actionType,\n (payload: unknown) => {\n if (debug) {\n logAction(name, actionType, payload);\n }\n dispatch({\n type: actionType,\n payload,\n });\n },\n ];\n })\n );\n return [state, actions] as [State, Actions<State, Reducers>];\n};\n\nconst logAction = (\n name: string | undefined,\n type: string,\n payload: unknown\n) => {\n const args = [];\n if (name) args.push(`[${name}]`);\n args.push(type, payload);\n\n console.log(...args);\n};\n"],"names":["logAction","name","type","payload","args","push","console","log","initialState","reducers","debug","state","dispatch","useReducer","action","Object","fromEntries","keys","map","actionType"],"mappings":"oCAwDO,MAiCDA,EAAY,CACdC,EACAC,EACAC,KAEA,MAAMC,EAAO,GACHA,EAAKC,KAAK,IAAIJ,MACxBG,EAAKC,KAAKH,EAAMC,GAEhBG,QAAQC,OAAOH,EAAK,0BA1CO,EAC3BI,eACAC,WACAR,OACAS,YAGA,MAMOC,EAAOC,GAAYC,EAAAA,YANV,CAACF,EAAcG,IACvBL,EAASK,EAAOZ,MACTO,EAASK,EAAOZ,MAAMS,EAAOG,EAAOX,SAExCQ,GAEmCH,GAiB9C,MAAO,CAACG,EAhBQI,OAAOC,YACnBD,OAAOE,KAAKR,GAAUS,KAAKC,GAChB,CACHA,EACChB,IACOO,GACAV,EAAUC,EAAMkB,EAAYhB,GAEhCS,EAAS,CACLV,KAAMiB,EACNhB,WACF,MAK0C"}