@lifesg/react-design-system 4.0.0-alpha.5 → 4.0.0-alpha.6

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 (445) hide show
  1. package/accordion/types.d.ts +1 -1
  2. package/breadcrumb/breadcrumb.d.ts +7 -0
  3. package/breadcrumb/breadcrumb.js.map +1 -1
  4. package/breadcrumb/types.d.ts +31 -0
  5. package/button/button.d.ts +1 -0
  6. package/button/button.js.map +1 -1
  7. package/button/types.d.ts +42 -9
  8. package/calendar/calendar.d.ts +3 -0
  9. package/calendar/calendar.js.map +1 -1
  10. package/calendar/types.d.ts +43 -7
  11. package/card/card.d.ts +1 -0
  12. package/card/card.js.map +1 -1
  13. package/card/types.d.ts +1 -0
  14. package/checkbox/checkbox.d.ts +3 -0
  15. package/checkbox/checkbox.js.map +1 -1
  16. package/checkbox/types.d.ts +19 -3
  17. package/cjs/breadcrumb/breadcrumb.js.map +1 -1
  18. package/cjs/button/button.js.map +1 -1
  19. package/cjs/calendar/calendar.js.map +1 -1
  20. package/cjs/card/card.js.map +1 -1
  21. package/cjs/checkbox/checkbox.js.map +1 -1
  22. package/cjs/data-table/data-table.js +1 -1
  23. package/cjs/data-table/data-table.js.map +1 -1
  24. package/cjs/data-table/data-table.styles.js +1 -1
  25. package/cjs/data-table/data-table.styles.js.map +1 -1
  26. package/cjs/data-table/data-table.styles_rxganh.css +27 -0
  27. package/cjs/external/dompurify/dist/purify.es.js +2 -2
  28. package/cjs/external/dompurify/dist/purify.es.js.map +1 -1
  29. package/cjs/external/lodash/_setCacheHas.js.map +1 -1
  30. package/cjs/external/lodash/lodash.js +1 -1
  31. package/cjs/external/lodash/lodash.js.map +1 -1
  32. package/cjs/form/form-label-addon.js +1 -1
  33. package/cjs/form/form-label-addon.js.map +1 -1
  34. package/cjs/form/index.js +1 -1
  35. package/cjs/form/index.js.map +1 -1
  36. package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.js +1 -1
  37. package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
  38. package/cjs/histogram-slider/histogram-slider.js.map +1 -1
  39. package/cjs/image-button/image-button.js.map +1 -1
  40. package/cjs/index.js +1 -1
  41. package/cjs/input/input.js.map +1 -1
  42. package/cjs/input-group/input-group.js.map +1 -1
  43. package/cjs/input-multi-select/input-multi-select.js.map +1 -1
  44. package/cjs/input-nested-multi-select/input-nested-multi-select.js.map +1 -1
  45. package/cjs/input-nested-select/input-nested-select.js.map +1 -1
  46. package/cjs/input-range-select/input-range-select.js.map +1 -1
  47. package/cjs/input-range-slider/input-range-slider.js.map +1 -1
  48. package/cjs/input-select/input-select.js.map +1 -1
  49. package/cjs/input-slider/input-slider.js.map +1 -1
  50. package/cjs/input-textarea/textarea.js.map +1 -1
  51. package/cjs/language-switcher/language-switcher.js.map +1 -1
  52. package/cjs/layout/index.js +1 -1
  53. package/cjs/layout/index.js.map +1 -1
  54. package/cjs/link-list/link-list.js.map +1 -1
  55. package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
  56. package/cjs/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
  57. package/cjs/markup/markup.js.map +1 -1
  58. package/cjs/masked-input/masked-input.js.map +1 -1
  59. package/cjs/masthead/masthead.js.map +1 -1
  60. package/cjs/menu/menu.js +1 -1
  61. package/cjs/menu/menu.js.map +1 -1
  62. package/cjs/modal/index.js.map +1 -1
  63. package/cjs/modal/modal-box.js +1 -1
  64. package/cjs/modal/modal-box.js.map +1 -1
  65. package/cjs/modal-v2/index.js +1 -1
  66. package/cjs/modal-v2/index.js.map +1 -1
  67. package/cjs/modal-v2/modal-v2.js +1 -1
  68. package/cjs/modal-v2/modal-v2.js.map +1 -1
  69. package/cjs/modal-v2/slots/card.js +1 -1
  70. package/cjs/modal-v2/slots/card.js.map +1 -1
  71. package/cjs/navbar/navbar.js.map +1 -1
  72. package/cjs/notification-banner/notification-banner-hoc.js.map +1 -1
  73. package/cjs/notification-banner/notification-banner.js.map +1 -1
  74. package/cjs/otp-input/otp-input.js.map +1 -1
  75. package/cjs/otp-verification/otp-verification.js.map +1 -1
  76. package/cjs/overlay/overlay.js.map +1 -1
  77. package/cjs/pagination/pagination.js.map +1 -1
  78. package/cjs/phone-number-input/phone-number-input.js.map +1 -1
  79. package/cjs/pill/pill.js.map +1 -1
  80. package/cjs/popover/popover-inline/popover-inline.js.map +1 -1
  81. package/cjs/popover/popover-trigger.js.map +1 -1
  82. package/cjs/popover/popover.js +1 -1
  83. package/cjs/popover/popover.js.map +1 -1
  84. package/cjs/predictive-text-input/predictive-text-input.js.map +1 -1
  85. package/cjs/progress-indicator/progress-indicator.js.map +1 -1
  86. package/cjs/radio-button/radio-button.js.map +1 -1
  87. package/cjs/schedule/schedule.js.map +1 -1
  88. package/cjs/schedule/shared/with-optional-popover.js +1 -1
  89. package/cjs/schedule/shared/with-optional-popover.js.map +1 -1
  90. package/cjs/select-histogram/select-histogram.js.map +1 -1
  91. package/cjs/sidenav/sidenav.js.map +1 -1
  92. package/cjs/singpass-button/singpass-button.js.map +1 -1
  93. package/cjs/smart-app-banner/smart-app-banner.js.map +1 -1
  94. package/cjs/tab/tab.js.map +1 -1
  95. package/cjs/table/table.js.map +1 -1
  96. package/cjs/table/table.styles.js +1 -1
  97. package/cjs/table/table.styles.js.map +1 -1
  98. package/{table/table.styles_1af5ipv.css → cjs/table/table.styles_1vjx31g.css} +1 -1
  99. package/cjs/tag/tag.js.map +1 -1
  100. package/cjs/text-list/index.js.map +1 -1
  101. package/cjs/theme/theme-provider/breakpoint.js +1 -1
  102. package/cjs/theme/theme-provider/breakpoint.js.map +1 -1
  103. package/cjs/theme/theme-provider/hooks.js.map +1 -1
  104. package/cjs/theme/theme-provider/index.js.map +1 -1
  105. package/cjs/theme/tokens/border.js.map +1 -1
  106. package/cjs/theme/tokens/breakpoint.js.map +1 -1
  107. package/cjs/theme/tokens/colour.js.map +1 -1
  108. package/cjs/theme/tokens/component.js.map +1 -1
  109. package/cjs/theme/tokens/font.js.map +1 -1
  110. package/cjs/theme/tokens/media-query.js.map +1 -1
  111. package/cjs/theme/tokens/motion.js.map +1 -1
  112. package/cjs/theme/tokens/radius.js.map +1 -1
  113. package/cjs/theme/tokens/shadow.js.map +1 -1
  114. package/cjs/theme/tokens/spacing.js.map +1 -1
  115. package/cjs/theme/types.js.map +1 -1
  116. package/cjs/theme/utils/css-variable.js.map +1 -1
  117. package/cjs/theme/utils/font.js.map +1 -1
  118. package/cjs/theme/utils/use-apply-styles.js +1 -1
  119. package/cjs/theme/utils/use-apply-styles.js.map +1 -1
  120. package/cjs/theme/utils/use-design-token-override.js.map +1 -1
  121. package/cjs/theme/utils/use-design-token.js.map +1 -1
  122. package/cjs/theme/utils/use-media-query.js.map +1 -1
  123. package/cjs/time-range-picker/combobox-picker/combobox-picker.js +1 -1
  124. package/cjs/time-range-picker/combobox-picker/combobox-picker.js.map +1 -1
  125. package/cjs/time-range-picker/common.styles.js +1 -1
  126. package/cjs/time-range-picker/common.styles.js.map +1 -1
  127. package/{time-range-picker/common.styles_1qwp4xa.css → cjs/time-range-picker/common.styles_cnkkax.css} +2 -1
  128. package/cjs/time-range-picker/dial-picker/dial-picker.js +1 -1
  129. package/cjs/time-range-picker/dial-picker/dial-picker.js.map +1 -1
  130. package/cjs/time-range-picker/time-range-picker.js.map +1 -1
  131. package/cjs/time-slot-bar/time-slot-bar.js.map +1 -1
  132. package/cjs/time-slot-bar-week/time-slot-bar-week.js.map +1 -1
  133. package/cjs/time-slot-week-view/time-slot-week-view.js.map +1 -1
  134. package/cjs/timeline/timeline.js.map +1 -1
  135. package/cjs/timepicker/timepicker.js +1 -1
  136. package/cjs/timepicker/timepicker.js.map +1 -1
  137. package/cjs/timepicker/timepicker.styles.js +1 -1
  138. package/cjs/timepicker/timepicker.styles.js.map +1 -1
  139. package/cjs/timepicker/timepicker.styles_lyizvq.css +2 -0
  140. package/cjs/timetable/timetable-row/with-optional-popover.js +1 -1
  141. package/cjs/timetable/timetable-row/with-optional-popover.js.map +1 -1
  142. package/cjs/timetable/timetable.js +1 -1
  143. package/cjs/timetable/timetable.js.map +1 -1
  144. package/cjs/toast/toast.js.map +1 -1
  145. package/cjs/toggle/toggle.js.map +1 -1
  146. package/cjs/typography/index.js.map +1 -1
  147. package/cjs/uneditable-section/index.js.map +1 -1
  148. package/cjs/unit-number/unit-number-input.js.map +1 -1
  149. package/cjs/util/merge-refs.js.map +1 -1
  150. package/cjs/util/use-throttle.js +2 -0
  151. package/cjs/util/use-throttle.js.map +1 -0
  152. package/countdown-timer/types.d.ts +3 -3
  153. package/data-table/data-table.js +1 -1
  154. package/data-table/data-table.js.map +1 -1
  155. package/data-table/data-table.styles.d.ts +2 -1
  156. package/data-table/data-table.styles.js +1 -1
  157. package/data-table/data-table.styles.js.map +1 -1
  158. package/data-table/data-table.styles_rxganh.css +27 -0
  159. package/date-range-input/types.d.ts +1 -1
  160. package/drawer/types.d.ts +1 -1
  161. package/e-signature/types.d.ts +1 -1
  162. package/external/dompurify/dist/purify.es.js +2 -2
  163. package/external/dompurify/dist/purify.es.js.map +1 -1
  164. package/external/lodash/_setCacheHas.js.map +1 -1
  165. package/external/lodash/lodash.js +1 -1
  166. package/external/lodash/lodash.js.map +1 -1
  167. package/file-upload/types.d.ts +0 -1
  168. package/filter/types.d.ts +6 -10
  169. package/form/form-label-addon.js +1 -1
  170. package/form/form-label-addon.js.map +1 -1
  171. package/form/index.d.ts +65 -8
  172. package/form/index.js +1 -1
  173. package/form/index.js.map +1 -1
  174. package/form/types.d.ts +155 -6
  175. package/fullscreen-image-carousel/fullscreen-image-carousel.d.ts +7 -0
  176. package/fullscreen-image-carousel/fullscreen-image-carousel.js +1 -1
  177. package/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
  178. package/fullscreen-image-carousel/types.d.ts +91 -3
  179. package/histogram-slider/histogram-slider.d.ts +6 -0
  180. package/histogram-slider/histogram-slider.js.map +1 -1
  181. package/histogram-slider/types.d.ts +63 -3
  182. package/image-button/image-button.d.ts +6 -0
  183. package/image-button/image-button.js.map +1 -1
  184. package/image-button/types.d.ts +11 -1
  185. package/index.js +1 -1
  186. package/input/input.d.ts +6 -0
  187. package/input/input.js.map +1 -1
  188. package/input/types.d.ts +38 -2
  189. package/input-group/input-group.d.ts +7 -0
  190. package/input-group/input-group.js.map +1 -1
  191. package/input-group/types.d.ts +84 -8
  192. package/input-multi-select/input-multi-select.d.ts +6 -0
  193. package/input-multi-select/input-multi-select.js.map +1 -1
  194. package/input-multi-select/types.d.ts +46 -5
  195. package/input-nested-multi-select/input-nested-multi-select.d.ts +8 -0
  196. package/input-nested-multi-select/input-nested-multi-select.js.map +1 -1
  197. package/input-nested-multi-select/types.d.ts +35 -5
  198. package/input-nested-select/input-nested-select.d.ts +9 -2
  199. package/input-nested-select/input-nested-select.js.map +1 -1
  200. package/input-nested-select/types.d.ts +77 -8
  201. package/input-range-select/input-range-select.d.ts +6 -0
  202. package/input-range-select/input-range-select.js.map +1 -1
  203. package/input-range-select/types.d.ts +68 -1
  204. package/input-range-slider/input-range-slider.d.ts +7 -0
  205. package/input-range-slider/input-range-slider.js.map +1 -1
  206. package/input-range-slider/types.d.ts +91 -6
  207. package/input-select/input-select.d.ts +5 -0
  208. package/input-select/input-select.js.map +1 -1
  209. package/input-select/types.d.ts +70 -14
  210. package/input-slider/input-slider.d.ts +6 -0
  211. package/input-slider/input-slider.js.map +1 -1
  212. package/input-slider/types.d.ts +21 -2
  213. package/input-textarea/textarea.d.ts +3 -0
  214. package/input-textarea/textarea.js.map +1 -1
  215. package/input-textarea/types.d.ts +24 -1
  216. package/language-switcher/language-switcher.d.ts +6 -0
  217. package/language-switcher/language-switcher.js.map +1 -1
  218. package/language-switcher/types.d.ts +23 -0
  219. package/layout/index.d.ts +16 -2
  220. package/layout/index.js +1 -1
  221. package/layout/index.js.map +1 -1
  222. package/layout/types.d.ts +61 -3
  223. package/link-list/internal-types.d.ts +57 -3
  224. package/link-list/link-list.d.ts +6 -0
  225. package/link-list/link-list.js.map +1 -1
  226. package/link-list/types.d.ts +3 -0
  227. package/local-nav/local-nav-dropdown/local-nav-dropdown.d.ts +11 -0
  228. package/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
  229. package/local-nav/local-nav-menu/local-nav-menu.d.ts +6 -0
  230. package/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
  231. package/local-nav/types.d.ts +51 -0
  232. package/markup/markup.d.ts +6 -0
  233. package/markup/markup.js.map +1 -1
  234. package/markup/types.d.ts +6 -2
  235. package/masked-input/masked-input.d.ts +6 -0
  236. package/masked-input/masked-input.js.map +1 -1
  237. package/masked-input/types.d.ts +83 -8
  238. package/masthead/masthead.d.ts +6 -0
  239. package/masthead/masthead.js.map +1 -1
  240. package/masthead/types.d.ts +9 -0
  241. package/menu/menu.d.ts +27 -4
  242. package/menu/menu.js +1 -1
  243. package/menu/menu.js.map +1 -1
  244. package/menu/types.d.ts +32 -0
  245. package/modal/index.d.ts +13 -0
  246. package/modal/index.js.map +1 -1
  247. package/modal/modal-box.js +1 -1
  248. package/modal/modal-box.js.map +1 -1
  249. package/modal/types.d.ts +54 -7
  250. package/modal-v2/index.d.ts +1 -15
  251. package/modal-v2/index.js +1 -1
  252. package/modal-v2/index.js.map +1 -1
  253. package/modal-v2/modal-v2.d.ts +32 -1
  254. package/modal-v2/modal-v2.js +1 -1
  255. package/modal-v2/modal-v2.js.map +1 -1
  256. package/modal-v2/slots/card.js +1 -1
  257. package/modal-v2/slots/card.js.map +1 -1
  258. package/modal-v2/types.d.ts +75 -8
  259. package/navbar/navbar.d.ts +7 -0
  260. package/navbar/navbar.js.map +1 -1
  261. package/navbar/types.d.ts +200 -13
  262. package/notification-banner/notification-banner-hoc.d.ts +6 -0
  263. package/notification-banner/notification-banner-hoc.js.map +1 -1
  264. package/notification-banner/notification-banner.d.ts +7 -0
  265. package/notification-banner/notification-banner.js.map +1 -1
  266. package/notification-banner/types.d.ts +57 -2
  267. package/otp-input/otp-input.d.ts +7 -0
  268. package/otp-input/otp-input.js.map +1 -1
  269. package/otp-input/types.d.ts +54 -11
  270. package/otp-verification/internal-types.d.ts +22 -5
  271. package/otp-verification/otp-verification.d.ts +6 -0
  272. package/otp-verification/otp-verification.js.map +1 -1
  273. package/otp-verification/types.d.ts +125 -6
  274. package/overlay/overlay.d.ts +7 -0
  275. package/overlay/overlay.js.map +1 -1
  276. package/overlay/types.d.ts +57 -2
  277. package/package.json +1 -1
  278. package/pagination/pagination.d.ts +5 -0
  279. package/pagination/pagination.js.map +1 -1
  280. package/pagination/types.d.ts +48 -0
  281. package/phone-number-input/phone-number-input.d.ts +7 -0
  282. package/phone-number-input/phone-number-input.js.map +1 -1
  283. package/phone-number-input/types.d.ts +78 -13
  284. package/pill/pill.d.ts +6 -0
  285. package/pill/pill.js.map +1 -1
  286. package/pill/types.d.ts +19 -0
  287. package/popover/popover-inline/popover-inline.d.ts +5 -0
  288. package/popover/popover-inline/popover-inline.js.map +1 -1
  289. package/popover/popover-trigger.d.ts +6 -0
  290. package/popover/popover-trigger.js.map +1 -1
  291. package/popover/popover.d.ts +6 -0
  292. package/popover/popover.js +1 -1
  293. package/popover/popover.js.map +1 -1
  294. package/popover/types.d.ts +150 -3
  295. package/predictive-text-input/predictive-text-input.d.ts +6 -0
  296. package/predictive-text-input/predictive-text-input.js.map +1 -1
  297. package/predictive-text-input/types.d.ts +65 -11
  298. package/progress-indicator/progress-indicator.d.ts +7 -0
  299. package/progress-indicator/progress-indicator.js.map +1 -1
  300. package/progress-indicator/types.d.ts +18 -0
  301. package/radio-button/radio-button.d.ts +5 -0
  302. package/radio-button/radio-button.js.map +1 -1
  303. package/radio-button/types.d.ts +11 -0
  304. package/schedule/internal-types.d.ts +18 -0
  305. package/schedule/schedule-day-view/types.d.ts +2 -1
  306. package/schedule/schedule-week-view/types.d.ts +2 -1
  307. package/schedule/schedule.d.ts +3 -0
  308. package/schedule/schedule.js.map +1 -1
  309. package/schedule/shared/with-optional-popover.js +1 -1
  310. package/schedule/shared/with-optional-popover.js.map +1 -1
  311. package/schedule/types.d.ts +129 -10
  312. package/select-histogram/select-histogram.d.ts +5 -0
  313. package/select-histogram/select-histogram.js.map +1 -1
  314. package/select-histogram/types.d.ts +57 -4
  315. package/shared/dropdown-list/types.d.ts +52 -19
  316. package/shared/dropdown-wrapper/types.d.ts +6 -0
  317. package/sidenav/sidenav.d.ts +10 -0
  318. package/sidenav/sidenav.js.map +1 -1
  319. package/sidenav/types.d.ts +70 -21
  320. package/singpass-button/singpass-button.d.ts +6 -0
  321. package/singpass-button/singpass-button.js.map +1 -1
  322. package/singpass-button/types.d.ts +29 -2
  323. package/smart-app-banner/smart-app-banner.d.ts +5 -0
  324. package/smart-app-banner/smart-app-banner.js.map +1 -1
  325. package/smart-app-banner/types.d.ts +54 -0
  326. package/tab/tab.d.ts +7 -0
  327. package/tab/tab.js.map +1 -1
  328. package/tab/types.d.ts +55 -6
  329. package/table/table.d.ts +21 -0
  330. package/table/table.js.map +1 -1
  331. package/table/table.styles.js +1 -1
  332. package/table/table.styles.js.map +1 -1
  333. package/{cjs/table/table.styles_1af5ipv.css → table/table.styles_1vjx31g.css} +1 -1
  334. package/tag/tag.d.ts +5 -0
  335. package/tag/tag.js.map +1 -1
  336. package/tag/types.d.ts +24 -0
  337. package/text-list/index.d.ts +17 -0
  338. package/text-list/index.js.map +1 -1
  339. package/text-list/types.d.ts +33 -4
  340. package/theme/theme-provider/breakpoint.d.ts +0 -1
  341. package/theme/theme-provider/breakpoint.js +1 -1
  342. package/theme/theme-provider/breakpoint.js.map +1 -1
  343. package/theme/theme-provider/hooks.d.ts +16 -0
  344. package/theme/theme-provider/hooks.js.map +1 -1
  345. package/theme/theme-provider/index.d.ts +7 -0
  346. package/theme/theme-provider/index.js.map +1 -1
  347. package/theme/theme-provider/types.d.ts +14 -0
  348. package/theme/tokens/border.d.ts +3 -0
  349. package/theme/tokens/border.js.map +1 -1
  350. package/theme/tokens/breakpoint.d.ts +3 -0
  351. package/theme/tokens/breakpoint.js.map +1 -1
  352. package/theme/tokens/colour.d.ts +3 -0
  353. package/theme/tokens/colour.js.map +1 -1
  354. package/theme/tokens/component.d.ts +1 -0
  355. package/theme/tokens/component.js.map +1 -1
  356. package/theme/tokens/font.d.ts +2 -0
  357. package/theme/tokens/font.js.map +1 -1
  358. package/theme/tokens/media-query.d.ts +1 -0
  359. package/theme/tokens/media-query.js.map +1 -1
  360. package/theme/tokens/motion.d.ts +1 -0
  361. package/theme/tokens/motion.js.map +1 -1
  362. package/theme/tokens/radius.d.ts +1 -0
  363. package/theme/tokens/radius.js.map +1 -1
  364. package/theme/tokens/shadow.d.ts +1 -0
  365. package/theme/tokens/shadow.js.map +1 -1
  366. package/theme/tokens/spacing.d.ts +1 -0
  367. package/theme/tokens/spacing.js.map +1 -1
  368. package/theme/types.d.ts +23 -3
  369. package/theme/types.js.map +1 -1
  370. package/theme/utils/css-variable.d.ts +10 -2
  371. package/theme/utils/css-variable.js.map +1 -1
  372. package/theme/utils/font.d.ts +2 -1
  373. package/theme/utils/font.js.map +1 -1
  374. package/theme/utils/use-apply-styles.d.ts +8 -2
  375. package/theme/utils/use-apply-styles.js +1 -1
  376. package/theme/utils/use-apply-styles.js.map +1 -1
  377. package/theme/utils/use-design-token-override.d.ts +9 -1
  378. package/theme/utils/use-design-token-override.js.map +1 -1
  379. package/theme/utils/use-design-token.d.ts +9 -0
  380. package/theme/utils/use-design-token.js.map +1 -1
  381. package/theme/utils/use-media-query.d.ts +41 -3
  382. package/theme/utils/use-media-query.js.map +1 -1
  383. package/time-range-picker/combobox-picker/combobox-picker.js +1 -1
  384. package/time-range-picker/combobox-picker/combobox-picker.js.map +1 -1
  385. package/time-range-picker/common.styles.d.ts +1 -0
  386. package/time-range-picker/common.styles.js +1 -1
  387. package/time-range-picker/common.styles.js.map +1 -1
  388. package/{cjs/time-range-picker/common.styles_1qwp4xa.css → time-range-picker/common.styles_cnkkax.css} +2 -1
  389. package/time-range-picker/dial-picker/dial-picker.js +1 -1
  390. package/time-range-picker/dial-picker/dial-picker.js.map +1 -1
  391. package/time-range-picker/time-range-picker.d.ts +5 -0
  392. package/time-range-picker/time-range-picker.js.map +1 -1
  393. package/time-range-picker/types.d.ts +85 -25
  394. package/time-slot-bar/internal-types.d.ts +1 -0
  395. package/time-slot-bar/time-slot-bar.d.ts +7 -0
  396. package/time-slot-bar/time-slot-bar.js.map +1 -1
  397. package/time-slot-bar/types.d.ts +112 -20
  398. package/time-slot-bar-week/time-slot-bar-week.d.ts +8 -0
  399. package/time-slot-bar-week/time-slot-bar-week.js.map +1 -1
  400. package/time-slot-bar-week/types.d.ts +74 -13
  401. package/time-slot-week-view/time-slot-week-view.d.ts +7 -0
  402. package/time-slot-week-view/time-slot-week-view.js.map +1 -1
  403. package/time-slot-week-view/types.d.ts +53 -10
  404. package/timeline/timeline.d.ts +6 -0
  405. package/timeline/timeline.js.map +1 -1
  406. package/timeline/types.d.ts +58 -4
  407. package/timepicker/timepicker.d.ts +5 -0
  408. package/timepicker/timepicker.js +1 -1
  409. package/timepicker/timepicker.js.map +1 -1
  410. package/timepicker/timepicker.styles.d.ts +1 -0
  411. package/timepicker/timepicker.styles.js +1 -1
  412. package/timepicker/timepicker.styles.js.map +1 -1
  413. package/timepicker/timepicker.styles_lyizvq.css +2 -0
  414. package/timepicker/types.d.ts +49 -14
  415. package/timetable/timetable-row/with-optional-popover.js +1 -1
  416. package/timetable/timetable-row/with-optional-popover.js.map +1 -1
  417. package/timetable/timetable.d.ts +6 -0
  418. package/timetable/timetable.js +1 -1
  419. package/timetable/timetable.js.map +1 -1
  420. package/timetable/types.d.ts +175 -50
  421. package/toast/toast.d.ts +6 -0
  422. package/toast/toast.js.map +1 -1
  423. package/toast/types.d.ts +42 -8
  424. package/toggle/toggle.d.ts +6 -0
  425. package/toggle/toggle.js.map +1 -1
  426. package/toggle/types.d.ts +95 -17
  427. package/typography/index.d.ts +29 -0
  428. package/typography/index.js.map +1 -1
  429. package/typography/types.d.ts +51 -8
  430. package/uneditable-section/index.d.ts +15 -0
  431. package/uneditable-section/index.js.map +1 -1
  432. package/uneditable-section/types.d.ts +66 -23
  433. package/unit-number/types.d.ts +30 -4
  434. package/unit-number/unit-number-input.d.ts +6 -0
  435. package/unit-number/unit-number-input.js.map +1 -1
  436. package/util/index.d.ts +1 -0
  437. package/util/merge-refs.d.ts +1 -1
  438. package/util/merge-refs.js.map +1 -1
  439. package/util/use-throttle.d.ts +1 -0
  440. package/util/use-throttle.js +2 -0
  441. package/util/use-throttle.js.map +1 -0
  442. package/cjs/data-table/data-table.styles_1iqq1g7.css +0 -26
  443. package/cjs/timepicker/timepicker.styles_1jm33yw.css +0 -1
  444. package/data-table/data-table.styles_1iqq1g7.css +0 -26
  445. package/timepicker/timepicker.styles_1jm33yw.css +0 -1
@@ -1,3 +1,10 @@
1
- import type { InputNestedSelectProps, L1OptionProps, L2OptionProps, L3OptionProps } from "./types";
2
- export type CombinedOptionProps<V1, V2, V3> = L1OptionProps<V1, V2, V3> | L2OptionProps<V2, V3> | L3OptionProps<V3>;
1
+ import type { InputNestedSelectProps } from "./types";
2
+ /**
3
+ * A single-select input that presents options in a hierarchy, up to three levels deep.
4
+ *
5
+ * Use `InputNestedSelect` when users need to choose a value from a
6
+ * hierarchical option tree. The dropdown renders as an expandable tree.
7
+ * Parent nodes collapse or expand their children, and only one leaf or category
8
+ * value can be selected at a time.
9
+ */
3
10
  export declare const InputNestedSelect: <V1, V2, V3>({ placeholder, options: _options, disabled, error, className, "data-testid": testId, id, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, selectedKeyPath: _selectedKeyPath, mode, valueToStringFunction, enableSearch, searchPlaceholder, selectableCategory, hideNoResultsDisplay, noResultsDescription, customLabels, readOnly, onBlur, onSearch, onSelectOption, onShowOptions, onHideOptions, onRetry, optionsLoadState, optionTruncationType, variant, alignment, dropdownZIndex, dropdownWidth, dropdownRootNode, }: InputNestedSelectProps<V1, V2, V3>) => JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"input-nested-select.js","sources":["../../src/input-nested-select/input-nested-select.tsx"],"sourcesContent":["import type { OpenChangeReason } from \"@floating-ui/react\";\nimport isEmpty from \"lodash/isEmpty\";\nimport type React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport type {\n NestedDropdownListItemProps,\n NestedDropdownListLocalItem,\n} from \"../shared/dropdown-list\";\nimport {\n buildKeyPathToSet,\n ExpandableElement,\n findItemByKeyPath,\n NestedDropdownList,\n} from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n LabelContainer,\n PlaceholderLabel,\n ValueLabel,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper\";\nimport { InputBox } from \"../shared/input-wrapper/input-wrapper\";\nimport { StringHelper, useId } from \"../util\";\nimport type {\n InputNestedSelectProps,\n L1OptionProps,\n L2OptionProps,\n L3OptionProps,\n} from \"./types\";\n\nexport type CombinedOptionProps<V1, V2, V3> =\n | L1OptionProps<V1, V2, V3>\n | L2OptionProps<V2, V3>\n | L3OptionProps<V3>;\n\ninterface SelectedItemType<V1, V2, V3> {\n label: string;\n value: V1 | V2 | V3;\n}\n\nexport const InputNestedSelect = <V1, V2, V3>({\n placeholder = \"Select\",\n options: _options,\n disabled,\n error,\n className,\n \"data-testid\": testId,\n id,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n selectedKeyPath: _selectedKeyPath,\n mode,\n valueToStringFunction,\n enableSearch,\n searchPlaceholder,\n selectableCategory,\n hideNoResultsDisplay,\n noResultsDescription,\n customLabels,\n readOnly,\n onBlur,\n onSearch,\n onSelectOption,\n onShowOptions,\n onHideOptions,\n onRetry,\n optionsLoadState = \"success\",\n optionTruncationType = \"end\",\n variant = \"default\",\n alignment,\n dropdownZIndex,\n dropdownWidth,\n dropdownRootNode,\n}: InputNestedSelectProps<V1, V2, V3>): JSX.Element => {\n // =========================================================================\n // CONST, STATE\n // =========================================================================\n const options = _options as NestedDropdownListItemProps<V1 | V2 | V3>[];\n const [selectedKeyPaths, setSelectedKeyPaths] = useState<Set<string>>(\n _selectedKeyPath\n ? buildKeyPathToSet([_selectedKeyPath])\n : new Set<string>()\n );\n const [selectedItem, setSelectedItem] =\n useState<SelectedItemType<V1, V2, V3>>();\n\n const [showOptions, setShowOptions] = useState<boolean>(false);\n const [focused, setFocused] = useState<boolean>(false);\n const internalId = useId();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const selectorRef = useRef<HTMLButtonElement>(null);\n const labelContainerRef = useRef<HTMLDivElement>(null);\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n setSelectedKeyPaths(\n _selectedKeyPath\n ? buildKeyPathToSet([_selectedKeyPath])\n : new Set<string>()\n );\n const selectedItem = findItemByKeyPath(options, _selectedKeyPath || []);\n setSelectedItem(selectedItem ?? undefined);\n }, [_selectedKeyPath, options]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleListItemClick = (\n listItem: NestedDropdownListLocalItem<V1 | V2 | V3>\n ) => {\n const {\n keyPath,\n item: { label, value },\n } = listItem;\n setSelectedKeyPaths(buildKeyPathToSet([keyPath]));\n setSelectedItem({ label, value });\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n selectorRef.current?.focus();\n onSelectOption?.(keyPath, value);\n };\n\n const handleNodeFocus = () => {\n if (!focused && !showOptions) {\n setFocused(true);\n }\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n focused &&\n !showOptions &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleOpen = () => {\n setShowOptions(true);\n triggerOptionDisplayCallback(true);\n setFocused(true);\n };\n\n const handleClose = (reason: OpenChangeReason | undefined) => {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n // click to toggle should not blur the input\n if (reason !== \"click\") {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleDismiss = () => {\n selectorRef.current?.focus();\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n };\n\n // =========================================================================\n // HELPER FUNCTION\n // =========================================================================\n const getDisplayValue = (): string => {\n if (!selectedItem) return \"\";\n const { label, value } = selectedItem;\n\n if (valueToStringFunction) {\n return valueToStringFunction(value);\n } else {\n return label;\n }\n };\n\n const truncateValue = (value: string) => {\n if (optionTruncationType === \"middle\") {\n let widthOfElement = 0;\n if (labelContainerRef && labelContainerRef.current) {\n widthOfElement =\n labelContainerRef.current.getBoundingClientRect().width;\n }\n return StringHelper.truncateOneLine(value, widthOfElement, 120, 6);\n }\n\n return value;\n };\n\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (!show && onHideOptions) {\n onHideOptions();\n }\n\n if (show && onShowOptions) {\n onShowOptions();\n }\n };\n\n // =========================================================================\n // RENDER FUNCTION\n // =========================================================================\n const renderLabel = () => {\n if (isEmpty(selectedItem)) {\n return (\n <PlaceholderLabel truncateType={optionTruncationType}>\n {placeholder}\n </PlaceholderLabel>\n );\n } else {\n return (\n <ValueLabel truncateType={optionTruncationType}>\n {truncateValue(getDisplayValue())}\n </ValueLabel>\n );\n }\n };\n\n const renderSelectorContent = () => (\n <LabelContainer ref={labelContainerRef} disabled={disabled}>\n {renderLabel()}\n </LabelContainer>\n );\n\n const renderElement = () => {\n return (\n <InputBox\n className={className}\n data-testid={testId}\n id={id}\n ref={nodeRef}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n focused={focused}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n >\n <ExpandableElement\n ref={selectorRef}\n disabled={disabled}\n expanded={showOptions}\n listboxId={internalId}\n popupRole=\"tree\"\n readOnly={readOnly}\n variant={variant}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n >\n {renderSelectorContent()}\n </ExpandableElement>\n </InputBox>\n );\n };\n\n const renderDropdown = () => {\n return (\n <NestedDropdownList\n listboxId={internalId}\n listItems={options}\n selectedKeyPaths={selectedKeyPaths}\n selectableCategory={selectableCategory}\n itemsLoadState={optionsLoadState}\n itemTruncationType={optionTruncationType}\n enableSearch={enableSearch}\n searchPlaceholder={searchPlaceholder}\n hideNoResultsDisplay={hideNoResultsDisplay}\n noResultsDescription={noResultsDescription}\n customLabels={customLabels}\n onSelectItem={handleListItemClick}\n onRetry={onRetry}\n onSearch={onSearch}\n variant={variant}\n mode={mode}\n width={dropdownWidth}\n matchElementWidth\n />\n );\n };\n\n return (\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={showOptions}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n );\n};\n"],"names":["InputNestedSelect","placeholder","options","_options","disabled","error","className","testId","id","ariaLabelledBy","ariaDescribedBy","ariaInvalid","selectedKeyPath","_selectedKeyPath","mode","valueToStringFunction","enableSearch","searchPlaceholder","selectableCategory","hideNoResultsDisplay","noResultsDescription","customLabels","readOnly","onBlur","onSearch","onSelectOption","onShowOptions","onHideOptions","onRetry","optionsLoadState","optionTruncationType","variant","alignment","dropdownZIndex","dropdownWidth","dropdownRootNode","selectedKeyPaths","setSelectedKeyPaths","useState","buildKeyPathToSet","Set","selectedItem","setSelectedItem","showOptions","setShowOptions","focused","setFocused","internalId","useId","nodeRef","useRef","selectorRef","labelContainerRef","useEffect","findItemByKeyPath","undefined","handleListItemClick","listItem","keyPath","item","label","value","triggerOptionDisplayCallback","_a","current","focus","handleNodeFocus","handleNodeBlur","e","contains","relatedTarget","getDisplayValue","truncateValue","widthOfElement","getBoundingClientRect","width","StringHelper","truncateOneLine","show","_jsx","ElementWithDropdown","enabled","isOpen","renderElement","InputBox","ref","tabIndex","onFocus","ExpandableElement","expanded","listboxId","popupRole","children","LabelContainer","isEmpty","PlaceholderLabel","truncateType","ValueLabel","renderDropdown","NestedDropdownList","listItems","itemsLoadState","itemTruncationType","onSelectItem","matchElementWidth","onOpen","onClose","reason","onDismiss","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
1
+ {"version":3,"file":"input-nested-select.js","sources":["../../src/input-nested-select/input-nested-select.tsx"],"sourcesContent":["import type { OpenChangeReason } from \"@floating-ui/react\";\nimport isEmpty from \"lodash/isEmpty\";\nimport type React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport type {\n NestedDropdownListItemProps,\n NestedDropdownListLocalItem,\n} from \"../shared/dropdown-list\";\nimport {\n buildKeyPathToSet,\n ExpandableElement,\n findItemByKeyPath,\n NestedDropdownList,\n} from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n LabelContainer,\n PlaceholderLabel,\n ValueLabel,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper\";\nimport { InputBox } from \"../shared/input-wrapper/input-wrapper\";\nimport { StringHelper, useId } from \"../util\";\nimport type { InputNestedSelectProps } from \"./types\";\n\ninterface SelectedItemType<V1, V2, V3> {\n label: string;\n value: V1 | V2 | V3;\n}\n\n/**\n * A single-select input that presents options in a hierarchy, up to three levels deep.\n *\n * Use `InputNestedSelect` when users need to choose a value from a\n * hierarchical option tree. The dropdown renders as an expandable tree.\n * Parent nodes collapse or expand their children, and only one leaf or category\n * value can be selected at a time.\n */\nexport const InputNestedSelect = <V1, V2, V3>({\n placeholder = \"Select\",\n options: _options,\n disabled,\n error,\n className,\n \"data-testid\": testId,\n id,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n selectedKeyPath: _selectedKeyPath,\n mode,\n valueToStringFunction,\n enableSearch,\n searchPlaceholder,\n selectableCategory,\n hideNoResultsDisplay,\n noResultsDescription,\n customLabels,\n readOnly,\n onBlur,\n onSearch,\n onSelectOption,\n onShowOptions,\n onHideOptions,\n onRetry,\n optionsLoadState = \"success\",\n optionTruncationType = \"end\",\n variant = \"default\",\n alignment,\n dropdownZIndex,\n dropdownWidth,\n dropdownRootNode,\n}: InputNestedSelectProps<V1, V2, V3>): JSX.Element => {\n // =========================================================================\n // CONST, STATE\n // =========================================================================\n const options = _options as NestedDropdownListItemProps<V1 | V2 | V3>[];\n const [selectedKeyPaths, setSelectedKeyPaths] = useState<Set<string>>(\n _selectedKeyPath\n ? buildKeyPathToSet([_selectedKeyPath])\n : new Set<string>()\n );\n const [selectedItem, setSelectedItem] =\n useState<SelectedItemType<V1, V2, V3>>();\n\n const [showOptions, setShowOptions] = useState<boolean>(false);\n const [focused, setFocused] = useState<boolean>(false);\n const internalId = useId();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const selectorRef = useRef<HTMLButtonElement>(null);\n const labelContainerRef = useRef<HTMLDivElement>(null);\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n setSelectedKeyPaths(\n _selectedKeyPath\n ? buildKeyPathToSet([_selectedKeyPath])\n : new Set<string>()\n );\n const selectedItem = findItemByKeyPath(options, _selectedKeyPath || []);\n setSelectedItem(selectedItem ?? undefined);\n }, [_selectedKeyPath, options]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleListItemClick = (\n listItem: NestedDropdownListLocalItem<V1 | V2 | V3>\n ) => {\n const {\n keyPath,\n item: { label, value },\n } = listItem;\n setSelectedKeyPaths(buildKeyPathToSet([keyPath]));\n setSelectedItem({ label, value });\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n selectorRef.current?.focus();\n onSelectOption?.(keyPath, value);\n };\n\n const handleNodeFocus = () => {\n if (!focused && !showOptions) {\n setFocused(true);\n }\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n focused &&\n !showOptions &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleOpen = () => {\n setShowOptions(true);\n triggerOptionDisplayCallback(true);\n setFocused(true);\n };\n\n const handleClose = (reason: OpenChangeReason | undefined) => {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n // click to toggle should not blur the input\n if (reason !== \"click\") {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleDismiss = () => {\n selectorRef.current?.focus();\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n };\n\n // =========================================================================\n // HELPER FUNCTION\n // =========================================================================\n const getDisplayValue = (): string => {\n if (!selectedItem) return \"\";\n const { label, value } = selectedItem;\n\n if (valueToStringFunction) {\n return valueToStringFunction(value);\n } else {\n return label;\n }\n };\n\n const truncateValue = (value: string) => {\n if (optionTruncationType === \"middle\") {\n let widthOfElement = 0;\n if (labelContainerRef && labelContainerRef.current) {\n widthOfElement =\n labelContainerRef.current.getBoundingClientRect().width;\n }\n return StringHelper.truncateOneLine(value, widthOfElement, 120, 6);\n }\n\n return value;\n };\n\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (!show && onHideOptions) {\n onHideOptions();\n }\n\n if (show && onShowOptions) {\n onShowOptions();\n }\n };\n\n // =========================================================================\n // RENDER FUNCTION\n // =========================================================================\n const renderLabel = () => {\n if (isEmpty(selectedItem)) {\n return (\n <PlaceholderLabel truncateType={optionTruncationType}>\n {placeholder}\n </PlaceholderLabel>\n );\n } else {\n return (\n <ValueLabel truncateType={optionTruncationType}>\n {truncateValue(getDisplayValue())}\n </ValueLabel>\n );\n }\n };\n\n const renderSelectorContent = () => (\n <LabelContainer ref={labelContainerRef} disabled={disabled}>\n {renderLabel()}\n </LabelContainer>\n );\n\n const renderElement = () => {\n return (\n <InputBox\n className={className}\n data-testid={testId}\n id={id}\n ref={nodeRef}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n focused={focused}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n >\n <ExpandableElement\n ref={selectorRef}\n disabled={disabled}\n expanded={showOptions}\n listboxId={internalId}\n popupRole=\"tree\"\n readOnly={readOnly}\n variant={variant}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n >\n {renderSelectorContent()}\n </ExpandableElement>\n </InputBox>\n );\n };\n\n const renderDropdown = () => {\n return (\n <NestedDropdownList\n listboxId={internalId}\n listItems={options}\n selectedKeyPaths={selectedKeyPaths}\n selectableCategory={selectableCategory}\n itemsLoadState={optionsLoadState}\n itemTruncationType={optionTruncationType}\n enableSearch={enableSearch}\n searchPlaceholder={searchPlaceholder}\n hideNoResultsDisplay={hideNoResultsDisplay}\n noResultsDescription={noResultsDescription}\n customLabels={customLabels}\n onSelectItem={handleListItemClick}\n onRetry={onRetry}\n onSearch={onSearch}\n variant={variant}\n mode={mode}\n width={dropdownWidth}\n matchElementWidth\n />\n );\n };\n\n return (\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={showOptions}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n );\n};\n"],"names":["InputNestedSelect","placeholder","options","_options","disabled","error","className","testId","id","ariaLabelledBy","ariaDescribedBy","ariaInvalid","selectedKeyPath","_selectedKeyPath","mode","valueToStringFunction","enableSearch","searchPlaceholder","selectableCategory","hideNoResultsDisplay","noResultsDescription","customLabels","readOnly","onBlur","onSearch","onSelectOption","onShowOptions","onHideOptions","onRetry","optionsLoadState","optionTruncationType","variant","alignment","dropdownZIndex","dropdownWidth","dropdownRootNode","selectedKeyPaths","setSelectedKeyPaths","useState","buildKeyPathToSet","Set","selectedItem","setSelectedItem","showOptions","setShowOptions","focused","setFocused","internalId","useId","nodeRef","useRef","selectorRef","labelContainerRef","useEffect","findItemByKeyPath","undefined","handleListItemClick","listItem","keyPath","item","label","value","triggerOptionDisplayCallback","_a","current","focus","handleNodeFocus","handleNodeBlur","e","contains","relatedTarget","getDisplayValue","truncateValue","widthOfElement","getBoundingClientRect","width","StringHelper","truncateOneLine","show","_jsx","ElementWithDropdown","enabled","isOpen","renderElement","InputBox","ref","tabIndex","onFocus","ExpandableElement","expanded","listboxId","popupRole","children","LabelContainer","isEmpty","PlaceholderLabel","truncateType","ValueLabel","renderDropdown","NestedDropdownList","listItems","itemsLoadState","itemTruncationType","onSelectItem","matchElementWidth","onOpen","onClose","reason","onDismiss","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
@@ -2,52 +2,121 @@ import type { RefObject } from "react";
2
2
  import type { InputSelectOptionsProps, InputSelectSharedProps } from "../input-select";
3
3
  import type { DropdownCustomLabelProps, DropdownSearchProps, DropdownVariantType, ExpandMode } from "../shared/dropdown-list/types";
4
4
  import type { DropdownAlignmentType } from "../shared/dropdown-wrapper/types";
5
+ /**
6
+ * Options and load-state configuration used by `InputNestedSelect` & `InputNestedMultiSelect`.
7
+ */
5
8
  export interface InputNestedSelectOptionsProps<V1, V2, V3> extends Omit<InputSelectOptionsProps<V1>, "options"> {
6
9
  options: L1OptionProps<V1, V2, V3>[];
7
10
  }
11
+ /**
12
+ * Shared behavioral and visual configuration for `InputNestedSelect` & `InputNestedMultiSelect`.
13
+ *
14
+ * The three type parameters describe the value types at each nesting level.
15
+ */
8
16
  export interface InputNestedSelectSharedProps<V1, V2, V3> extends Omit<InputSelectSharedProps<V1>, "options"> {
9
17
  readOnly?: boolean | undefined;
10
18
  /** Specifies if items are expanded or collapsed when the dropdown is opened */
11
19
  mode?: ExpandMode | undefined;
20
+ /**
21
+ * Controls the height of the trigger and dropdown items.
22
+ *
23
+ * @default "default"
24
+ */
12
25
  variant?: DropdownVariantType | undefined;
26
+ /** Aligns the dropdown relative to the trigger element. */
13
27
  alignment?: DropdownAlignmentType | undefined;
28
+ /** CSS `z-index` applied to the dropdown overlay. */
14
29
  dropdownZIndex?: number | undefined;
15
30
  /**
16
- * The root element that contains the dropdown element. Defaults to the document body.
31
+ * The root element that contains the dropdown element.
32
+ *
33
+ * @remarks Specify this if you need to change the parent of the
34
+ * dropdown in the HTML DOM.
35
+ * Possible use case: sharing a stacking context.
36
+ *
37
+ * Note: if a parent of the trigger has a higher `z-index` than the dropdown,
38
+ * the dropdown may be obscured.
17
39
  *
18
- * If the parent that contains the trigger element has a higher z-index than the dropdown,
19
- * the dropdown may not be visible. Specify the parent element here instead
40
+ * @default `document.body`
20
41
  */
21
42
  dropdownRootNode?: RefObject<HTMLElement> | undefined;
22
43
  /** Function to convert selected value into a string */
23
44
  valueToStringFunction?: ((value: V1 | V2 | V3) => string) | undefined;
24
45
  }
46
+ /**
47
+ * Props for `InputNestedSelect` component.
48
+ *
49
+ * The three type parameters describe the value types at each nesting level.
50
+ */
25
51
  export interface InputNestedSelectProps<V1, V2, V3> extends React.HTMLAttributes<HTMLElement>, InputNestedSelectOptionsProps<V1, V2, V3>, InputNestedSelectSharedProps<V1, V2, V3>, DropdownSearchProps<L1OptionProps<V1, V2, V3>> {
26
- /** Specifies key path of the selected option */
52
+ /**
53
+ * Key path identifying the currently selected option. Each entry is the
54
+ * `key` of the option at that nesting level, ordered from level 1 to the
55
+ * selected level. Drives the controlled selection state.
56
+ */
27
57
  selectedKeyPath?: string[] | undefined;
28
- /** If specified, the category label is selectable */
58
+ /**
59
+ * When `true`, parent category labels are themselves selectable as options,
60
+ * not just expand/collapse toggles.
61
+ */
29
62
  selectableCategory?: boolean | undefined;
30
- /** Called when an option is selected. Returns the option's key path and value */
63
+ /**
64
+ * Called when the user selects an option.
65
+ *
66
+ * @param keyPath Key path from level 1 to the selected option.
67
+ * @param value Value of the selected option.
68
+ */
31
69
  onSelectOption?: ((keyPath: string[], value: V1 | V2 | V3) => void) | undefined;
32
- /** Custom width for the dropdown */
70
+ /**
71
+ * Custom width for the dropdown. When specified, the dropdown uses this
72
+ * width instead of matching the trigger element width.
73
+ */
33
74
  dropdownWidth?: string | undefined;
75
+ /**
76
+ * Called when focus leaves both the trigger and the dropdown.
77
+ */
34
78
  onBlur?: (() => void) | undefined;
79
+ /**
80
+ * Overrides the default labels shown inside the dropdown and on the trigger.
81
+ */
35
82
  customLabels?: DropdownCustomLabelProps | undefined;
36
83
  }
37
- /** To be exposed for Form component inheritance */
84
+ /**
85
+ * A subset of `InputNestedSelectProps` used by form components that manage
86
+ * the `error` state themselves.
87
+ */
38
88
  export type InputNestedSelectPartialProps<V1, V2, V3> = Omit<InputNestedSelectProps<V1, V2, V3>, "error">;
39
89
  interface BaseOptionProps {
40
90
  label: string;
41
91
  key: string;
42
92
  }
93
+ /**
94
+ * A top-level (level-1) option that may contain level-2 sub-options.
95
+ *
96
+ * `V1` is the value type for this level; `V2` and `V3` are the value types for
97
+ * nested levels 2 and 3 respectively.
98
+ */
43
99
  export interface L1OptionProps<V1, V2, V3> extends BaseOptionProps {
44
100
  value: V1;
101
+ /** Nested level-2 options belonging to this category. */
45
102
  subItems?: L2OptionProps<V2, V3>[] | undefined;
46
103
  }
104
+ /**
105
+ * A level-2 option that may contain level-3 leaf options.
106
+ *
107
+ * `V2` is the value type for this level; `V3` is the value type for the nested
108
+ * level-3 options.
109
+ */
47
110
  export interface L2OptionProps<V2, V3> extends BaseOptionProps {
48
111
  value: V2;
112
+ /** Nested level-3 leaf options belonging to this item. */
49
113
  subItems?: L3OptionProps<V3>[] | undefined;
50
114
  }
115
+ /**
116
+ * A level-3 leaf option with no further nesting.
117
+ *
118
+ * `V3` is the value type for this level.
119
+ */
51
120
  export interface L3OptionProps<V3> extends BaseOptionProps {
52
121
  value: V3;
53
122
  subItems?: undefined;
@@ -1,2 +1,8 @@
1
1
  import type { InputRangeSelectProps } from "./types";
2
+ /**
3
+ * A paired combobox input for selecting a start and end value from dropdown lists.
4
+ *
5
+ * Use `InputRangeSelect` when a consumer must choose a range by picking two
6
+ * values — one for "from" and one for "to" — each from their own option list.
7
+ */
2
8
  export declare const InputRangeSelect: <T, V>({ selectedOptions, placeholders, options, disabled, className, readOnly, error, "data-testid": testId, id, enableSearch, searchFunction, searchPlaceholder, valueExtractor, valueToStringFunction, listExtractor, displayValueExtractor, onSelectOption, onShowOptions, onHideOptions, onRetry, optionsLoadState, optionTruncationType, renderCustomSelectedOption, renderListItem, renderCustomCallToAction, alignment, dropdownZIndex, dropdownRootNode, dropdownWidth, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...otherProps }: InputRangeSelectProps<T, V>) => JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"input-range-select.js","sources":["../../src/input-range-select/input-range-select.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { concatIds, VisuallyHidden } from \"../shared/accessibility\";\nimport type { DropdownListApi } from \"../shared/dropdown-list\";\nimport { DropdownList, DropdownListState } from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n PlaceholderLabel,\n ValueLabel,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper\";\nimport { ClearButton, InputWrapper } from \"../shared/input-wrapper\";\nimport * as inputWrapperStyles from \"../shared/input-wrapper/input-wrapper.styles\";\nimport { RangeInputInnerContainer } from \"../shared/range-input-inner-container\";\nimport { useId } from \"../util\";\nimport { StringHelper } from \"../util/string-helper\";\nimport * as styles from \"./input-range-select.styles\";\nimport type { InputRangeSelectProps } from \"./types\";\n\ntype RangeType = \"from\" | \"to\";\n\nexport const InputRangeSelect = <T, V>({\n selectedOptions,\n placeholders = { from: \"Select\", to: \"Select\" },\n options,\n disabled,\n className,\n readOnly,\n error,\n \"data-testid\": testId,\n id,\n enableSearch = false,\n searchFunction,\n searchPlaceholder,\n valueExtractor,\n valueToStringFunction,\n listExtractor,\n displayValueExtractor,\n onSelectOption,\n onShowOptions,\n onHideOptions,\n onRetry,\n optionsLoadState = { from: \"success\", to: \"success\" },\n optionTruncationType = \"middle\",\n renderCustomSelectedOption,\n renderListItem,\n renderCustomCallToAction,\n alignment,\n dropdownZIndex,\n dropdownRootNode,\n dropdownWidth,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: InputRangeSelectProps<T, V>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [selectedFromValue, setSelectedFromValue] = useState<T | undefined>();\n const [selectedToValue, setSelectedToValue] = useState<T | undefined>();\n const [focusedInput, setFocusedInput] = useState<RangeType | \"none\">(\n \"none\"\n );\n const isOpen = focusedInput !== \"none\";\n\n const labelButtonRef = {\n from: useRef<HTMLButtonElement>(null),\n to: useRef<HTMLButtonElement>(null),\n };\n const dropdownRef = useRef<DropdownListApi>(null);\n\n const internalId = useId();\n const listboxId = `${internalId}-range-listbox`;\n const fromLabelId = `${internalId}-from-label`;\n const toLabelId = `${internalId}-to-label`;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelectedFromValue(selectedOptions?.from);\n setSelectedToValue(selectedOptions?.to);\n }, [selectedOptions]);\n\n useEffect(() => {\n if (!isOpen) return;\n\n if (focusedInput === \"to\") {\n dropdownRef.current?.refocus({ index: 0 });\n }\n }, [isOpen, focusedInput]);\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (!show) onHideOptions?.();\n if (show) onShowOptions?.();\n };\n\n const getDisplayValue = (rangeType: RangeType): string => {\n const selected =\n rangeType === \"from\" ? selectedFromValue : selectedToValue;\n if (!selected) return \"\";\n\n if (displayValueExtractor) return displayValueExtractor(selected);\n\n if (valueExtractor) {\n const value = valueExtractor(selected);\n return valueToStringFunction\n ? valueToStringFunction(value)\n : value?.toString?.() ?? \"\";\n }\n\n return selected.toString();\n };\n\n const truncateValue = (type: RangeType, value: string) => {\n if (optionTruncationType === \"middle\") {\n let widthOfElement = 0;\n if (labelButtonRef[type]?.current) {\n widthOfElement =\n labelButtonRef[type].current.getBoundingClientRect().width;\n }\n return StringHelper.truncateOneLine(value, widthOfElement, 120, 8);\n }\n return value;\n };\n\n const getCurrentFocused = (): \"none\" | \"start\" | \"end\" => {\n switch (focusedInput) {\n case \"from\":\n return \"start\";\n case \"to\":\n return \"end\";\n case \"none\":\n return focusedInput;\n }\n };\n\n const currentOptions = useMemo(() => {\n if (focusedInput === \"none\") return [];\n return options?.[focusedInput] ?? [];\n }, [focusedInput, options]);\n\n const currentSelectedItems = useMemo(() => {\n if (focusedInput === \"none\") return [];\n const selected =\n focusedInput === \"from\" ? selectedFromValue : selectedToValue;\n return selected ? [selected] : [];\n }, [focusedInput, selectedFromValue, selectedToValue]);\n\n const openDropdownFor = (rangeType: RangeType) => {\n if (disabled || readOnly) return;\n\n const nextFocusedInput =\n rangeType === \"to\" && !selectedFromValue ? \"from\" : rangeType;\n\n setFocusedInput(nextFocusedInput);\n triggerOptionDisplayCallback(true);\n };\n\n const focusButton = (type: RangeType) => {\n labelButtonRef[type].current?.focus();\n };\n\n const getButtonLabelledBy = (rangeType: RangeType) => {\n const rangeLabelId = rangeType === \"from\" ? fromLabelId : toLabelId;\n return concatIds(rangeLabelId, ariaLabelledBy);\n };\n\n const getDropdownAriaLabel = () => {\n if (focusedInput === \"from\") {\n return `Selecting for: ${placeholders?.from}`;\n }\n\n if (focusedInput === \"to\") {\n return `Selecting for: ${placeholders?.to}`;\n }\n\n return undefined;\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleSelectorClick =\n (rangeType: RangeType) => (event: React.MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n openDropdownFor(rangeType);\n };\n\n const handleSelectorKeyDown =\n (rangeType: RangeType) =>\n (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled || readOnly) return;\n\n switch (event.key) {\n case \"Enter\":\n case \" \":\n case \"ArrowDown\":\n event.preventDefault();\n openDropdownFor(rangeType);\n break;\n default:\n break;\n }\n };\n\n const handleListItemClick = (item: T, extractedValue: V) => {\n if (focusedInput === \"none\") return;\n\n if (focusedInput === \"from\") {\n setSelectedFromValue(item);\n onSelectOption?.({ from: item }, extractedValue);\n\n setSelectedToValue(undefined);\n setFocusedInput(\"to\");\n triggerOptionDisplayCallback(true);\n focusButton(\"to\");\n return;\n }\n\n setSelectedToValue(item);\n onSelectOption?.({ to: item }, extractedValue);\n\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n focusButton(\"to\");\n };\n\n const handleDismiss = () => {\n const last = focusedInput;\n\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n\n if (last === \"to\") focusButton(\"to\");\n else focusButton(\"from\");\n\n if (!selectedFromValue || !selectedToValue) {\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n }\n };\n\n const handleClose = () => {\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n\n if (!selectedFromValue || !selectedToValue) {\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n }\n };\n\n const handleOpen = () => {\n if (disabled || readOnly) return;\n\n if (focusedInput === \"none\") {\n setFocusedInput(\"from\");\n triggerOptionDisplayCallback(true);\n }\n };\n\n const handleClear = (event: React.MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n onSelectOption?.({ from: undefined, to: undefined }, undefined);\n\n focusButton(\"from\");\n };\n\n // =============================================================================\n // RENDER\n // =============================================================================\n const renderLabel = (rangeType: RangeType) => {\n const selected =\n rangeType === \"from\" ? selectedFromValue : selectedToValue;\n\n if (!selected) {\n return (\n <PlaceholderLabel truncateType={optionTruncationType}>\n {truncateValue(rangeType, placeholders?.[rangeType] || \"\")}\n </PlaceholderLabel>\n );\n }\n\n if (renderCustomSelectedOption) {\n return renderCustomSelectedOption(selected);\n }\n\n return (\n <ValueLabel truncateType={optionTruncationType}>\n {truncateValue(rangeType, getDisplayValue(rangeType))}\n </ValueLabel>\n );\n };\n\n const renderSelectorContent = (rangeType: RangeType) => (\n <button\n type=\"button\"\n role=\"combobox\"\n aria-labelledby={getButtonLabelledBy(rangeType)}\n aria-describedby={ariaDescribedBy}\n aria-expanded={isOpen && focusedInput === rangeType}\n aria-controls={listboxId}\n aria-disabled={disabled}\n aria-readonly={readOnly}\n onClick={handleSelectorClick(rangeType)}\n onKeyDown={handleSelectorKeyDown(rangeType)}\n ref={labelButtonRef[rangeType]}\n tabIndex={0}\n className={styles.rangeSelectorButton}\n >\n {renderLabel(rangeType)}\n </button>\n );\n\n const renderElement = () => {\n return (\n <InputWrapper\n className={clsx(styles.styledInputWrapper, className)}\n data-testid={testId}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n focused={isOpen}\n >\n <VisuallyHidden id={fromLabelId}>\n {placeholders?.from || \"Select From\"}\n </VisuallyHidden>\n <VisuallyHidden id={toLabelId}>\n {placeholders?.to || \"Select To\"}\n </VisuallyHidden>\n\n <RangeInputInnerContainer\n currentActive={getCurrentFocused()}\n error={error}\n >\n {renderSelectorContent(\"from\")}\n {renderSelectorContent(\"to\")}\n </RangeInputInnerContainer>\n\n {!isOpen &&\n selectedFromValue &&\n selectedToValue &&\n !readOnly &&\n !disabled && (\n <div\n className={inputWrapperStyles.clearButtonContainer}\n >\n <ClearButton\n onClick={handleClear}\n type=\"button\"\n aria-label=\"Clear\"\n />\n </div>\n )}\n </InputWrapper>\n );\n };\n\n const renderDropdown = () => {\n return (\n <DropdownList\n ref={dropdownRef}\n data-testid={`${testId}-dropdown`}\n listboxId={listboxId}\n ariaLabel={getDropdownAriaLabel()}\n listItems={currentOptions}\n onSelectItem={handleListItemClick}\n onDismiss={handleDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n selectedItems={currentSelectedItems}\n itemsLoadState={optionsLoadState[focusedInput as RangeType]}\n itemTruncationType={optionTruncationType}\n onRetry={onRetry}\n width={dropdownWidth}\n matchElementWidth={!dropdownWidth}\n enableSearch={enableSearch}\n searchFunction={searchFunction}\n searchPlaceholder={searchPlaceholder}\n renderListItem={renderListItem}\n renderCustomCallToAction={renderCustomCallToAction}\n />\n );\n };\n\n return (\n <div id={id} {...otherProps}>\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={isOpen}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle={false}\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n </div>\n );\n};\n"],"names":["InputRangeSelect","_a","selectedOptions","placeholders","from","to","options","disabled","className","readOnly","error","testId","id","enableSearch","searchFunction","searchPlaceholder","valueExtractor","valueToStringFunction","listExtractor","displayValueExtractor","onSelectOption","onShowOptions","onHideOptions","onRetry","optionsLoadState","optionTruncationType","renderCustomSelectedOption","renderListItem","renderCustomCallToAction","alignment","dropdownZIndex","dropdownRootNode","dropdownWidth","ariaLabelledBy","ariaDescribedBy","otherProps","__rest","selectedFromValue","setSelectedFromValue","useState","selectedToValue","setSelectedToValue","focusedInput","setFocusedInput","isOpen","labelButtonRef","useRef","dropdownRef","internalId","useId","listboxId","fromLabelId","toLabelId","useEffect","current","refocus","index","triggerOptionDisplayCallback","show","getDisplayValue","rangeType","selected","value","_b","toString","call","truncateValue","type","widthOfElement","getBoundingClientRect","width","StringHelper","truncateOneLine","getCurrentFocused","currentOptions","useMemo","currentSelectedItems","openDropdownFor","focusButton","focus","getButtonLabelledBy","concatIds","handleSelectorClick","event","stopPropagation","preventDefault","handleSelectorKeyDown","key","handleListItemClick","item","extractedValue","undefined","handleDismiss","last","handleClear","renderLabel","_jsx","ValueLabel","truncateType","children","PlaceholderLabel","renderSelectorContent","role","onClick","onKeyDown","ref","tabIndex","styles.rangeSelectorButton","Object","assign","DropdownListState","ElementWithDropdown","enabled","renderElement","_jsxs","InputWrapper","clsx","styles.styledInputWrapper","focused","VisuallyHidden","RangeInputInnerContainer","currentActive","inputWrapperStyles.clearButtonContainer","ClearButton","renderDropdown","DropdownList","ariaLabel","listItems","onSelectItem","onDismiss","selectedItems","itemsLoadState","itemTruncationType","matchElementWidth","onOpen","onClose","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
1
+ {"version":3,"file":"input-range-select.js","sources":["../../src/input-range-select/input-range-select.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { concatIds, VisuallyHidden } from \"../shared/accessibility\";\nimport type { DropdownListApi } from \"../shared/dropdown-list\";\nimport { DropdownList, DropdownListState } from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n PlaceholderLabel,\n ValueLabel,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper\";\nimport { ClearButton, InputWrapper } from \"../shared/input-wrapper\";\nimport * as inputWrapperStyles from \"../shared/input-wrapper/input-wrapper.styles\";\nimport { RangeInputInnerContainer } from \"../shared/range-input-inner-container\";\nimport { useId } from \"../util\";\nimport { StringHelper } from \"../util/string-helper\";\nimport * as styles from \"./input-range-select.styles\";\nimport type { InputRangeSelectProps } from \"./types\";\n\ntype RangeType = \"from\" | \"to\";\n\n/**\n * A paired combobox input for selecting a start and end value from dropdown lists.\n *\n * Use `InputRangeSelect` when a consumer must choose a range by picking two\n * values — one for \"from\" and one for \"to\" — each from their own option list.\n */\nexport const InputRangeSelect = <T, V>({\n selectedOptions,\n placeholders = { from: \"Select\", to: \"Select\" },\n options,\n disabled,\n className,\n readOnly,\n error,\n \"data-testid\": testId,\n id,\n enableSearch = false,\n searchFunction,\n searchPlaceholder,\n valueExtractor,\n valueToStringFunction,\n listExtractor,\n displayValueExtractor,\n onSelectOption,\n onShowOptions,\n onHideOptions,\n onRetry,\n optionsLoadState = { from: \"success\", to: \"success\" },\n optionTruncationType = \"middle\",\n renderCustomSelectedOption,\n renderListItem,\n renderCustomCallToAction,\n alignment,\n dropdownZIndex,\n dropdownRootNode,\n dropdownWidth,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: InputRangeSelectProps<T, V>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [selectedFromValue, setSelectedFromValue] = useState<T | undefined>();\n const [selectedToValue, setSelectedToValue] = useState<T | undefined>();\n const [focusedInput, setFocusedInput] = useState<RangeType | \"none\">(\n \"none\"\n );\n const isOpen = focusedInput !== \"none\";\n\n const labelButtonRef = {\n from: useRef<HTMLButtonElement>(null),\n to: useRef<HTMLButtonElement>(null),\n };\n const dropdownRef = useRef<DropdownListApi>(null);\n\n const internalId = useId();\n const listboxId = `${internalId}-range-listbox`;\n const fromLabelId = `${internalId}-from-label`;\n const toLabelId = `${internalId}-to-label`;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelectedFromValue(selectedOptions?.from);\n setSelectedToValue(selectedOptions?.to);\n }, [selectedOptions]);\n\n useEffect(() => {\n if (!isOpen) return;\n\n if (focusedInput === \"to\") {\n dropdownRef.current?.refocus({ index: 0 });\n }\n }, [isOpen, focusedInput]);\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (!show) onHideOptions?.();\n if (show) onShowOptions?.();\n };\n\n const getDisplayValue = (rangeType: RangeType): string => {\n const selected =\n rangeType === \"from\" ? selectedFromValue : selectedToValue;\n if (!selected) return \"\";\n\n if (displayValueExtractor) return displayValueExtractor(selected);\n\n if (valueExtractor) {\n const value = valueExtractor(selected);\n return valueToStringFunction\n ? valueToStringFunction(value)\n : value?.toString?.() ?? \"\";\n }\n\n return selected.toString();\n };\n\n const truncateValue = (type: RangeType, value: string) => {\n if (optionTruncationType === \"middle\") {\n let widthOfElement = 0;\n if (labelButtonRef[type]?.current) {\n widthOfElement =\n labelButtonRef[type].current.getBoundingClientRect().width;\n }\n return StringHelper.truncateOneLine(value, widthOfElement, 120, 8);\n }\n return value;\n };\n\n const getCurrentFocused = (): \"none\" | \"start\" | \"end\" => {\n switch (focusedInput) {\n case \"from\":\n return \"start\";\n case \"to\":\n return \"end\";\n case \"none\":\n return focusedInput;\n }\n };\n\n const currentOptions = useMemo(() => {\n if (focusedInput === \"none\") return [];\n return options?.[focusedInput] ?? [];\n }, [focusedInput, options]);\n\n const currentSelectedItems = useMemo(() => {\n if (focusedInput === \"none\") return [];\n const selected =\n focusedInput === \"from\" ? selectedFromValue : selectedToValue;\n return selected ? [selected] : [];\n }, [focusedInput, selectedFromValue, selectedToValue]);\n\n const openDropdownFor = (rangeType: RangeType) => {\n if (disabled || readOnly) return;\n\n const nextFocusedInput =\n rangeType === \"to\" && !selectedFromValue ? \"from\" : rangeType;\n\n setFocusedInput(nextFocusedInput);\n triggerOptionDisplayCallback(true);\n };\n\n const focusButton = (type: RangeType) => {\n labelButtonRef[type].current?.focus();\n };\n\n const getButtonLabelledBy = (rangeType: RangeType) => {\n const rangeLabelId = rangeType === \"from\" ? fromLabelId : toLabelId;\n return concatIds(rangeLabelId, ariaLabelledBy);\n };\n\n const getDropdownAriaLabel = () => {\n if (focusedInput === \"from\") {\n return `Selecting for: ${placeholders?.from}`;\n }\n\n if (focusedInput === \"to\") {\n return `Selecting for: ${placeholders?.to}`;\n }\n\n return undefined;\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleSelectorClick =\n (rangeType: RangeType) => (event: React.MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n openDropdownFor(rangeType);\n };\n\n const handleSelectorKeyDown =\n (rangeType: RangeType) =>\n (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled || readOnly) return;\n\n switch (event.key) {\n case \"Enter\":\n case \" \":\n case \"ArrowDown\":\n event.preventDefault();\n openDropdownFor(rangeType);\n break;\n default:\n break;\n }\n };\n\n const handleListItemClick = (item: T, extractedValue: V) => {\n if (focusedInput === \"none\") return;\n\n if (focusedInput === \"from\") {\n setSelectedFromValue(item);\n onSelectOption?.({ from: item }, extractedValue);\n\n setSelectedToValue(undefined);\n setFocusedInput(\"to\");\n triggerOptionDisplayCallback(true);\n focusButton(\"to\");\n return;\n }\n\n setSelectedToValue(item);\n onSelectOption?.({ to: item }, extractedValue);\n\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n focusButton(\"to\");\n };\n\n const handleDismiss = () => {\n const last = focusedInput;\n\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n\n if (last === \"to\") focusButton(\"to\");\n else focusButton(\"from\");\n\n if (!selectedFromValue || !selectedToValue) {\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n }\n };\n\n const handleClose = () => {\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n\n if (!selectedFromValue || !selectedToValue) {\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n }\n };\n\n const handleOpen = () => {\n if (disabled || readOnly) return;\n\n if (focusedInput === \"none\") {\n setFocusedInput(\"from\");\n triggerOptionDisplayCallback(true);\n }\n };\n\n const handleClear = (event: React.MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n onSelectOption?.({ from: undefined, to: undefined }, undefined);\n\n focusButton(\"from\");\n };\n\n // =============================================================================\n // RENDER\n // =============================================================================\n const renderLabel = (rangeType: RangeType) => {\n const selected =\n rangeType === \"from\" ? selectedFromValue : selectedToValue;\n\n if (!selected) {\n return (\n <PlaceholderLabel truncateType={optionTruncationType}>\n {truncateValue(rangeType, placeholders?.[rangeType] || \"\")}\n </PlaceholderLabel>\n );\n }\n\n if (renderCustomSelectedOption) {\n return renderCustomSelectedOption(selected);\n }\n\n return (\n <ValueLabel truncateType={optionTruncationType}>\n {truncateValue(rangeType, getDisplayValue(rangeType))}\n </ValueLabel>\n );\n };\n\n const renderSelectorContent = (rangeType: RangeType) => (\n <button\n type=\"button\"\n role=\"combobox\"\n aria-labelledby={getButtonLabelledBy(rangeType)}\n aria-describedby={ariaDescribedBy}\n aria-expanded={isOpen && focusedInput === rangeType}\n aria-controls={listboxId}\n aria-disabled={disabled}\n aria-readonly={readOnly}\n onClick={handleSelectorClick(rangeType)}\n onKeyDown={handleSelectorKeyDown(rangeType)}\n ref={labelButtonRef[rangeType]}\n tabIndex={0}\n className={styles.rangeSelectorButton}\n >\n {renderLabel(rangeType)}\n </button>\n );\n\n const renderElement = () => {\n return (\n <InputWrapper\n className={clsx(styles.styledInputWrapper, className)}\n data-testid={testId}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n focused={isOpen}\n >\n <VisuallyHidden id={fromLabelId}>\n {placeholders?.from || \"Select From\"}\n </VisuallyHidden>\n <VisuallyHidden id={toLabelId}>\n {placeholders?.to || \"Select To\"}\n </VisuallyHidden>\n\n <RangeInputInnerContainer\n currentActive={getCurrentFocused()}\n error={error}\n >\n {renderSelectorContent(\"from\")}\n {renderSelectorContent(\"to\")}\n </RangeInputInnerContainer>\n\n {!isOpen &&\n selectedFromValue &&\n selectedToValue &&\n !readOnly &&\n !disabled && (\n <div\n className={inputWrapperStyles.clearButtonContainer}\n >\n <ClearButton\n onClick={handleClear}\n type=\"button\"\n aria-label=\"Clear\"\n />\n </div>\n )}\n </InputWrapper>\n );\n };\n\n const renderDropdown = () => {\n return (\n <DropdownList\n ref={dropdownRef}\n data-testid={`${testId}-dropdown`}\n listboxId={listboxId}\n ariaLabel={getDropdownAriaLabel()}\n listItems={currentOptions}\n onSelectItem={handleListItemClick}\n onDismiss={handleDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n selectedItems={currentSelectedItems}\n itemsLoadState={optionsLoadState[focusedInput as RangeType]}\n itemTruncationType={optionTruncationType}\n onRetry={onRetry}\n width={dropdownWidth}\n matchElementWidth={!dropdownWidth}\n enableSearch={enableSearch}\n searchFunction={searchFunction}\n searchPlaceholder={searchPlaceholder}\n renderListItem={renderListItem}\n renderCustomCallToAction={renderCustomCallToAction}\n />\n );\n };\n\n return (\n <div id={id} {...otherProps}>\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={isOpen}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle={false}\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n </div>\n );\n};\n"],"names":["InputRangeSelect","_a","selectedOptions","placeholders","from","to","options","disabled","className","readOnly","error","testId","id","enableSearch","searchFunction","searchPlaceholder","valueExtractor","valueToStringFunction","listExtractor","displayValueExtractor","onSelectOption","onShowOptions","onHideOptions","onRetry","optionsLoadState","optionTruncationType","renderCustomSelectedOption","renderListItem","renderCustomCallToAction","alignment","dropdownZIndex","dropdownRootNode","dropdownWidth","ariaLabelledBy","ariaDescribedBy","otherProps","__rest","selectedFromValue","setSelectedFromValue","useState","selectedToValue","setSelectedToValue","focusedInput","setFocusedInput","isOpen","labelButtonRef","useRef","dropdownRef","internalId","useId","listboxId","fromLabelId","toLabelId","useEffect","current","refocus","index","triggerOptionDisplayCallback","show","getDisplayValue","rangeType","selected","value","_b","toString","call","truncateValue","type","widthOfElement","getBoundingClientRect","width","StringHelper","truncateOneLine","getCurrentFocused","currentOptions","useMemo","currentSelectedItems","openDropdownFor","focusButton","focus","getButtonLabelledBy","concatIds","handleSelectorClick","event","stopPropagation","preventDefault","handleSelectorKeyDown","key","handleListItemClick","item","extractedValue","undefined","handleDismiss","last","handleClear","renderLabel","_jsx","ValueLabel","truncateType","children","PlaceholderLabel","renderSelectorContent","role","onClick","onKeyDown","ref","tabIndex","styles.rangeSelectorButton","Object","assign","DropdownListState","ElementWithDropdown","enabled","renderElement","_jsxs","InputWrapper","clsx","styles.styledInputWrapper","focused","VisuallyHidden","RangeInputInnerContainer","currentActive","inputWrapperStyles.clearButtonContainer","ClearButton","renderDropdown","DropdownList","ariaLabel","listItems","onSelectItem","onDismiss","selectedItems","itemsLoadState","itemTruncationType","matchElementWidth","onOpen","onClose","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
@@ -2,26 +2,93 @@ import type { RefObject } from "react";
2
2
  import type { InputSelectOptionsProps, InputSelectSharedProps } from "../input-select/types";
3
3
  import type { DropdownDisplayProps, DropdownSearchProps, ItemsLoadStateType } from "../shared/dropdown-list/types";
4
4
  import type { DropdownAlignmentType } from "../shared/dropdown-wrapper";
5
+ /**
6
+ * Options configuration for `InputRangeSelect`.
7
+ */
5
8
  export interface InputRangeSelectOptionsProps<T> extends Omit<InputSelectOptionsProps<T>, "options" | "optionsLoadState"> {
9
+ /**
10
+ * The list of selectable items for each end of the range.
11
+ */
6
12
  options: InputRangeProp<T[]>;
13
+ /**
14
+ * The async load state for each end's option list.
15
+ *
16
+ * @default { from: "success", to: "success" }
17
+ */
7
18
  optionsLoadState?: InputRangeProp<ItemsLoadStateType | undefined>;
8
19
  }
20
+ /**
21
+ * A representation of a paired "from" and "to" value.
22
+ */
9
23
  export interface InputRangeProp<T> {
10
24
  from?: T | undefined;
11
25
  to?: T | undefined;
12
26
  }
27
+ /**
28
+ * Props for the `InputRangeSelect`component.
29
+ *
30
+ * `T` is the option item type; `V` is the extracted value type returned by
31
+ * `valueExtractor`.
32
+ */
13
33
  export interface InputRangeSelectProps<T, V> extends React.HTMLAttributes<HTMLElement>, InputRangeSelectOptionsProps<T>, Omit<InputSelectSharedProps<T>, "options">, DropdownDisplayProps<T, V>, DropdownSearchProps<T> {
14
34
  readOnly?: boolean | undefined;
35
+ /**
36
+ * Placeholder text shown in each selector when no value is selected.
37
+ *
38
+ * @default { from: "Select", to: "Select" }
39
+ */
15
40
  placeholders?: InputRangeProp<string> | undefined;
41
+ /**
42
+ * The currently selected option for each end of the range.
43
+ * Controls the displayed value for both selectors.
44
+ */
16
45
  selectedOptions?: InputRangeProp<T> | undefined;
46
+ /** Aligns the dropdown relative to the trigger element. */
17
47
  alignment?: DropdownAlignmentType | undefined;
48
+ /** CSS `z-index` applied to the dropdown overlay. */
18
49
  dropdownZIndex?: number | undefined;
50
+ /**
51
+ * The root element that contains the dropdown element.
52
+ *
53
+ * @remarks Specify this if you need to change the parent of the
54
+ * dropdown in the HTML DOM.
55
+ * Possible use case: sharing a stacking context.
56
+ *
57
+ * Note: if a parent of the trigger has a higher `z-index` than the dropdown,
58
+ * the dropdown may be obscured.
59
+ *
60
+ * @default `document.body`
61
+ */
19
62
  dropdownRootNode?: RefObject<HTMLElement> | undefined;
63
+ /**
64
+ * Custom width for the dropdown. When specified, the dropdown uses this
65
+ * width instead of matching the trigger element width.
66
+ */
20
67
  dropdownWidth?: string | undefined;
68
+ /**
69
+ * Called when a selection is made in either the "from" or "to" dropdown,
70
+ * or when the current range selection is cleared.
71
+ *
72
+ * @param option The partial or full range selection after the interaction.
73
+ * @param extractedValue The value produced by `valueExtractor` for the
74
+ * chosen item, or `undefined` when cleared.
75
+ */
21
76
  onSelectOption?: ((option: InputRangeProp<T>, extractedValue: V | undefined) => void) | undefined;
77
+ /**
78
+ * Derives a display string for the selected option shown in the trigger
79
+ * button. Takes precedence over `valueExtractor` + `valueToStringFunction`
80
+ * for display purposes.
81
+ */
22
82
  displayValueExtractor?: ((option: T) => string) | undefined;
83
+ /** Function to convert selected value into a string */
23
84
  valueToStringFunction?: ((value: V) => string) | undefined;
85
+ /**
86
+ * Renders a custom element for the currently selected option.
87
+ */
24
88
  renderCustomSelectedOption?: ((option: T) => JSX.Element) | undefined;
25
89
  }
26
- /** To be exposed for Form component inheritance */
90
+ /**
91
+ * A subset of `InputRangeSelectProps` used by form components that manage
92
+ * the `error` state themselves.
93
+ */
27
94
  export type InputRangeSelectPartialProps<T, V> = Omit<InputRangeSelectProps<T, V>, "error">;
@@ -1,2 +1,9 @@
1
1
  import type { InputRangeSliderProps } from "./types";
2
+ /**
3
+ * A draggable track slider for selecting one or more numeric values within a
4
+ * bounded range.
5
+ *
6
+ * Use `InputRangeSlider` when the selection does not need to be precise;
7
+ * the user picks a value or a range by dragging thumb controls along a track.
8
+ */
2
9
  export declare const InputRangeSlider: ({ id, value, min, max, step, minRange, numOfThumbs, colors, disabled, readOnly, showSliderLabels, sliderLabelPrefix, sliderLabelSuffix, showIndicatorLabel, indicatorLabelPrefix, indicatorLabelSuffix, ariaLabels, ariaDescriptions, "aria-invalid": ariaInvalid, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, renderSliderLabel, onChange, onChangeEnd, className, ...otherProps }: InputRangeSliderProps) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"input-range-slider.js","sources":["../../src/input-range-slider/input-range-slider.tsx"],"sourcesContent":["import { announce, clearAnnouncer } from \"@react-aria/live-announcer\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useState } from \"react\";\nimport ReactSlider from \"react-slider\";\n\nimport { concatIds, VisuallyHidden } from \"../shared/accessibility\";\nimport { Colour } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport * as styles from \"./input-range-slider.styles\";\nimport { Thumb, Track } from \"./slider-components\";\nimport type { InputRangeSliderProps } from \"./types\";\n\nexport const InputRangeSlider = ({\n id,\n value,\n min = 0,\n max = 100,\n step = 1,\n minRange = 0,\n numOfThumbs = 2,\n colors,\n disabled,\n readOnly,\n showSliderLabels,\n sliderLabelPrefix,\n sliderLabelSuffix,\n showIndicatorLabel,\n indicatorLabelPrefix,\n indicatorLabelSuffix,\n ariaLabels,\n ariaDescriptions,\n \"aria-invalid\": ariaInvalid,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n renderSliderLabel,\n onChange,\n onChangeEnd,\n className,\n ...otherProps\n}: InputRangeSliderProps) => {\n // =========================================================================\n // CONST, STATE, REF\n // =========================================================================\n const [selection, setSelection] = useState<number[]>(initialiseSelection());\n const [focusedThumbIndex, setFocusedThumbIndex] = useState<number | null>(\n null\n );\n const internalId = useId();\n const trackColors = getTrackColors();\n const indicatorTextId = `${internalId}-indicator`;\n const instructionTextId = `${internalId}-instruction`;\n const resolvedAriaLabels = getResolvedAriaLabels();\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n if (value !== selection) {\n setSelection(initialiseSelection());\n }\n }, [value]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleChange = (value: number | readonly number[], index: number) => {\n if (readOnly || disabled) {\n return;\n }\n\n if (typeof value === \"number\") {\n const nextValue = [value];\n setSelection(nextValue);\n onChange?.(nextValue);\n return;\n }\n\n if (index > -1 && selection[index] === value[index]) {\n // skip unnecessary update when dragging the start thumb across the end thumb\n return;\n }\n\n const nextValue = [...value];\n setSelection(nextValue);\n onChange?.(nextValue);\n };\n\n const handleChangeEnd = (value: number | readonly number[]) => {\n if (readOnly || disabled) {\n return;\n }\n\n if (typeof value === \"number\") {\n const val = [value];\n setSelection(val);\n onChangeEnd?.(val);\n return;\n }\n\n const newSelection = [...value];\n setSelection(newSelection);\n onChangeEnd?.(newSelection);\n };\n\n const handleThumbKeyDown = (\n event: React.KeyboardEvent<HTMLDivElement>,\n index: number\n ) => {\n if (disabled || readOnly) {\n return;\n }\n\n const message = getBlockedMovementMessage(event.key, index);\n\n if (!message) {\n return;\n }\n\n clearAnnouncer(\"assertive\");\n announce(message, \"assertive\");\n };\n\n const handleNativeRangeChange = (\n event: React.ChangeEvent<HTMLInputElement>,\n index: number\n ) => {\n if (disabled || readOnly) {\n return;\n }\n\n const nextRawValue = Number(event.currentTarget.value);\n\n const nextSelection = [...selection];\n nextSelection[index] = clampValueForThumb(\n nextRawValue,\n index,\n selection\n );\n\n setSelection(nextSelection);\n onChange?.(nextSelection);\n onChangeEnd?.(nextSelection);\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n function initialiseSelection() {\n if (value && value.length === numOfThumbs) {\n return value;\n }\n\n const values: number[] = [];\n for (let i = 0; i < numOfThumbs; i++) {\n values.push(min + step * i);\n }\n return values;\n }\n\n function getResolvedAriaLabels() {\n return Array.from({ length: numOfThumbs }, (_, index) => {\n return ariaLabels?.[index] || getDefaultAriaLabel(index);\n });\n }\n\n function getDefaultAriaLabel(index: number) {\n if (numOfThumbs === 1) {\n return \"\";\n }\n\n if (index === 0) {\n return \"Minimum value slider\";\n }\n\n if (index === numOfThumbs - 1) {\n return \"Maximum value slider\";\n }\n\n return \"Indeterminate value slider\";\n }\n\n function getThumbDescriptionText(index: number) {\n return ariaDescriptions?.[index];\n }\n\n function getTrackColors() {\n const defaultColors = getDefaultColors();\n return new Array(numOfThumbs + 1).fill(0).map((_, i) => {\n return colors?.[i] || defaultColors[i];\n });\n }\n\n function getDefaultColors() {\n const inactiveColor =\n disabled || readOnly\n ? Colour[\"border-disabled\"]\n : Colour[\"border-strong\"];\n const activeColor =\n disabled || readOnly\n ? Colour[\"border-selected-disabled\"]\n : Colour[\"border-selected\"];\n\n if (numOfThumbs === 1) {\n return [activeColor, inactiveColor];\n }\n\n const defaultColors: typeof colors = [inactiveColor];\n\n for (let index = 0; index < numOfThumbs - 1; index++) {\n defaultColors.push(activeColor);\n }\n\n defaultColors.push(inactiveColor);\n return defaultColors;\n }\n\n function getValueText(currentValue: number) {\n return `${sliderLabelPrefix || \"\"}${currentValue}${\n sliderLabelSuffix || \"\"\n }`;\n }\n\n function getThumbDescriptionIds(thumbDescriptionId?: string) {\n return concatIds(\n ariaDescribedBy,\n showIndicatorLabel ? indicatorTextId : undefined,\n disabled || readOnly ? undefined : instructionTextId,\n thumbDescriptionId\n );\n }\n\n function isIncreaseKey(key: string) {\n return [\"ArrowRight\", \"ArrowUp\", \"PageUp\", \"End\"].includes(key);\n }\n\n function isDecreaseKey(key: string) {\n return [\"ArrowLeft\", \"ArrowDown\", \"PageDown\", \"Home\"].includes(key);\n }\n\n function getSliderTypeText(label?: string) {\n if (!label) {\n return \"slider\";\n }\n\n return label.toLowerCase();\n }\n\n function getSliderTargetText(label?: string) {\n if (!label) {\n return \"slider\";\n }\n\n return label.replace(/ slider$/i, \"\").toLowerCase();\n }\n\n function getBlockedMovementMessage(key: string, index: number) {\n if (numOfThumbs < 2) {\n return \"\";\n }\n\n const currentValue = selection[index];\n const previousValue = index > 0 ? selection[index - 1] : undefined;\n const nextValue =\n index < selection.length - 1 ? selection[index + 1] : undefined;\n\n const currentLabel = resolvedAriaLabels[index];\n const previousLabel =\n index > 0 ? resolvedAriaLabels[index - 1] : undefined;\n const nextLabel =\n index < resolvedAriaLabels.length - 1\n ? resolvedAriaLabels[index + 1]\n : undefined;\n\n if (isIncreaseKey(key)) {\n if (\n nextValue !== undefined &&\n currentValue >= nextValue - minRange\n ) {\n return `The ${getSliderTypeText(\n currentLabel\n )} has reached its limit. Increase the ${getSliderTargetText(\n nextLabel\n )} to set a higher ${getSliderTargetText(currentLabel)}.`;\n }\n }\n\n if (isDecreaseKey(key)) {\n if (\n previousValue !== undefined &&\n currentValue <= previousValue + minRange\n ) {\n return `The ${getSliderTypeText(\n currentLabel\n )} has reached its limit. Decrease the ${getSliderTargetText(\n previousLabel\n )} to set a lower ${getSliderTargetText(currentLabel)}.`;\n }\n }\n\n return \"\";\n }\n\n function getThumbMin(index: number, values = selection) {\n if (index === 0) {\n return min;\n }\n\n return values[index - 1] + minRange;\n }\n\n function getThumbMax(index: number, values = selection) {\n if (index === values.length - 1) {\n return max;\n }\n\n return values[index + 1] - minRange;\n }\n\n function clampValueForThumb(\n nextValue: number,\n index: number,\n values: number[]\n ) {\n const minAllowed = getThumbMin(index, values);\n const maxAllowed = getThumbMax(index, values);\n\n return Math.min(maxAllowed, Math.max(minAllowed, nextValue));\n }\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const formatLabel = (value: number) => {\n if (renderSliderLabel) {\n return renderSliderLabel(value);\n }\n\n return (\n <Typography.BodyBL className={styles.labelText}>\n {sliderLabelPrefix}\n {value}\n {sliderLabelSuffix}\n </Typography.BodyBL>\n );\n };\n\n const formatIndicationLabel = () => {\n let formattedSelection = \"\";\n\n if (selection.length === 1) {\n formattedSelection = `${selection[0]}`;\n } else if (selection.length === 2) {\n formattedSelection = `${selection[0]} - ${selection[1]}`;\n } else if (selection.length > 2) {\n const minValue = Math.min(...selection);\n const maxValue = Math.max(...selection);\n formattedSelection = `${minValue} - ${maxValue}`;\n }\n\n return (\n <Typography.BodyBL className={styles.labelText}>\n {indicatorLabelPrefix}\n {formattedSelection}\n {indicatorLabelSuffix}\n </Typography.BodyBL>\n );\n };\n\n return (\n <div\n {...otherProps}\n id={id}\n role=\"group\"\n aria-labelledby={ariaLabelledBy}\n aria-disabled={disabled}\n className={clsx(styles.wrapper, className)}\n >\n {!disabled && !readOnly && (\n <VisuallyHidden id={instructionTextId}>\n Use left and right arrow keys to adjust the slider.\n </VisuallyHidden>\n )}\n\n {showIndicatorLabel && (\n <div\n id={indicatorTextId}\n className={styles.indicatorLabelContainer}\n >\n {formatIndicationLabel()}\n </div>\n )}\n\n {selection.map((thumbValue, index) => {\n const thumbLabelTextId = `${internalId}-thumb-label-${index}`;\n const thumbDescriptionText = getThumbDescriptionText(index);\n const thumbDescriptionTextId = thumbDescriptionText\n ? `${internalId}-thumb-description-${index}`\n : undefined;\n\n return (\n <VisuallyHidden key={`native-slider-${index}`}>\n {thumbDescriptionTextId && (\n <span id={thumbDescriptionTextId}>\n {thumbDescriptionText}\n </span>\n )}\n <span id={thumbLabelTextId}>\n {resolvedAriaLabels[index]}\n </span>\n\n <input\n data-testid={`slider-input-${index}`}\n type=\"range\"\n min={getThumbMin(index)}\n max={getThumbMax(index)}\n step={step}\n value={thumbValue}\n aria-disabled={disabled || undefined}\n readOnly={readOnly}\n aria-labelledby={concatIds(\n ariaLabelledBy,\n thumbLabelTextId\n )}\n aria-describedby={getThumbDescriptionIds(\n thumbDescriptionTextId\n )}\n aria-valuetext={getValueText(thumbValue)}\n aria-invalid={ariaInvalid}\n onFocus={() => setFocusedThumbIndex(index)}\n onBlur={() => setFocusedThumbIndex(null)}\n onChange={(event) =>\n handleNativeRangeChange(event, index)\n }\n onKeyDown={(event) => {\n handleThumbKeyDown(event, index);\n }}\n />\n </VisuallyHidden>\n );\n })}\n\n {/* Native range inputs provide the accessible interaction model.\n The visible react-slider is presentation-only. */}\n <ReactSlider\n step={step}\n min={min}\n max={max}\n value={selection}\n disabled={disabled || readOnly}\n onChange={handleChange}\n onAfterChange={handleChangeEnd}\n minDistance={minRange}\n aria-hidden\n className={styles.slider}\n renderThumb={(thumbProps, state) => {\n return (\n <Thumb\n data-testid={`slider-thumb-${state.index}`}\n {...thumbProps}\n key={thumbProps.key}\n tabIndex={-1}\n aria-hidden\n focused={focusedThumbIndex === state.index}\n disabled={disabled}\n readOnly={readOnly}\n />\n );\n }}\n renderTrack={(trackProps, state) => {\n return (\n <Track\n data-testid={`slider-track-${state.index}`}\n {...trackProps}\n key={trackProps.key}\n color={trackColors[state.index]}\n />\n );\n }}\n />\n\n {showSliderLabels && (\n <div className={styles.labelContainer}>\n <div>{formatLabel(min)}</div>\n <div>{formatLabel(max)}</div>\n </div>\n )}\n </div>\n );\n};\n"],"names":["InputRangeSlider","_a","id","value","min","max","step","minRange","numOfThumbs","colors","disabled","readOnly","showSliderLabels","sliderLabelPrefix","sliderLabelSuffix","showIndicatorLabel","indicatorLabelPrefix","indicatorLabelSuffix","ariaLabels","ariaDescriptions","ariaInvalid","ariaLabelledBy","ariaDescribedBy","renderSliderLabel","onChange","onChangeEnd","className","otherProps","__rest","selection","setSelection","useState","initialiseSelection","focusedThumbIndex","setFocusedThumbIndex","internalId","useId","trackColors","defaultColors","inactiveColor","Colour","activeColor","index","push","getDefaultColors","Array","fill","map","_","i","getTrackColors","indicatorTextId","instructionTextId","resolvedAriaLabels","from","length","getDefaultAriaLabel","useEffect","handleThumbKeyDown","event","message","key","currentValue","previousValue","undefined","nextValue","currentLabel","previousLabel","nextLabel","includes","isIncreaseKey","getSliderTypeText","getSliderTargetText","isDecreaseKey","getBlockedMovementMessage","clearAnnouncer","announce","handleNativeRangeChange","nextRawValue","Number","currentTarget","nextSelection","values","minAllowed","getThumbMin","maxAllowed","getThumbMax","Math","clampValueForThumb","label","toLowerCase","replace","formatLabel","_jsxs","Typography","BodyBL","styles.labelText","children","Object","assign","role","clsx","styles.wrapper","_jsx","VisuallyHidden","styles.indicatorLabelContainer","formattedSelection","formatIndicationLabel","thumbValue","thumbLabelTextId","thumbDescriptionText","getThumbDescriptionText","thumbDescriptionTextId","type","concatIds","thumbDescriptionId","onFocus","onBlur","onKeyDown","ReactSlider","onAfterChange","val","newSelection","minDistance","styles.slider","renderThumb","thumbProps","state","_createElement","Thumb","tabIndex","focused","renderTrack","trackProps","Track","color","styles.labelContainer"],"mappings":"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"}
1
+ {"version":3,"file":"input-range-slider.js","sources":["../../src/input-range-slider/input-range-slider.tsx"],"sourcesContent":["import { announce, clearAnnouncer } from \"@react-aria/live-announcer\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useState } from \"react\";\nimport ReactSlider from \"react-slider\";\n\nimport { concatIds, VisuallyHidden } from \"../shared/accessibility\";\nimport { Colour } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport * as styles from \"./input-range-slider.styles\";\nimport { Thumb, Track } from \"./slider-components\";\nimport type { InputRangeSliderProps } from \"./types\";\n\n/**\n * A draggable track slider for selecting one or more numeric values within a\n * bounded range.\n *\n * Use `InputRangeSlider` when the selection does not need to be precise;\n * the user picks a value or a range by dragging thumb controls along a track.\n */\nexport const InputRangeSlider = ({\n id,\n value,\n min = 0,\n max = 100,\n step = 1,\n minRange = 0,\n numOfThumbs = 2,\n colors,\n disabled,\n readOnly,\n showSliderLabels,\n sliderLabelPrefix,\n sliderLabelSuffix,\n showIndicatorLabel,\n indicatorLabelPrefix,\n indicatorLabelSuffix,\n ariaLabels,\n ariaDescriptions,\n \"aria-invalid\": ariaInvalid,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n renderSliderLabel,\n onChange,\n onChangeEnd,\n className,\n ...otherProps\n}: InputRangeSliderProps) => {\n // =========================================================================\n // CONST, STATE, REF\n // =========================================================================\n const [selection, setSelection] = useState<number[]>(initialiseSelection());\n const [focusedThumbIndex, setFocusedThumbIndex] = useState<number | null>(\n null\n );\n const internalId = useId();\n const trackColors = getTrackColors();\n const indicatorTextId = `${internalId}-indicator`;\n const instructionTextId = `${internalId}-instruction`;\n const resolvedAriaLabels = getResolvedAriaLabels();\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n if (value !== selection) {\n setSelection(initialiseSelection());\n }\n }, [value]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleChange = (value: number | readonly number[], index: number) => {\n if (readOnly || disabled) {\n return;\n }\n\n if (typeof value === \"number\") {\n const nextValue = [value];\n setSelection(nextValue);\n onChange?.(nextValue);\n return;\n }\n\n if (index > -1 && selection[index] === value[index]) {\n // skip unnecessary update when dragging the start thumb across the end thumb\n return;\n }\n\n const nextValue = [...value];\n setSelection(nextValue);\n onChange?.(nextValue);\n };\n\n const handleChangeEnd = (value: number | readonly number[]) => {\n if (readOnly || disabled) {\n return;\n }\n\n if (typeof value === \"number\") {\n const val = [value];\n setSelection(val);\n onChangeEnd?.(val);\n return;\n }\n\n const newSelection = [...value];\n setSelection(newSelection);\n onChangeEnd?.(newSelection);\n };\n\n const handleThumbKeyDown = (\n event: React.KeyboardEvent<HTMLDivElement>,\n index: number\n ) => {\n if (disabled || readOnly) {\n return;\n }\n\n const message = getBlockedMovementMessage(event.key, index);\n\n if (!message) {\n return;\n }\n\n clearAnnouncer(\"assertive\");\n announce(message, \"assertive\");\n };\n\n const handleNativeRangeChange = (\n event: React.ChangeEvent<HTMLInputElement>,\n index: number\n ) => {\n if (disabled || readOnly) {\n return;\n }\n\n const nextRawValue = Number(event.currentTarget.value);\n\n const nextSelection = [...selection];\n nextSelection[index] = clampValueForThumb(\n nextRawValue,\n index,\n selection\n );\n\n setSelection(nextSelection);\n onChange?.(nextSelection);\n onChangeEnd?.(nextSelection);\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n function initialiseSelection() {\n if (value && value.length === numOfThumbs) {\n return value;\n }\n\n const values: number[] = [];\n for (let i = 0; i < numOfThumbs; i++) {\n values.push(min + step * i);\n }\n return values;\n }\n\n function getResolvedAriaLabels() {\n return Array.from({ length: numOfThumbs }, (_, index) => {\n return ariaLabels?.[index] || getDefaultAriaLabel(index);\n });\n }\n\n function getDefaultAriaLabel(index: number) {\n if (numOfThumbs === 1) {\n return \"\";\n }\n\n if (index === 0) {\n return \"Minimum value slider\";\n }\n\n if (index === numOfThumbs - 1) {\n return \"Maximum value slider\";\n }\n\n return \"Indeterminate value slider\";\n }\n\n function getThumbDescriptionText(index: number) {\n return ariaDescriptions?.[index];\n }\n\n function getTrackColors() {\n const defaultColors = getDefaultColors();\n return new Array(numOfThumbs + 1).fill(0).map((_, i) => {\n return colors?.[i] || defaultColors[i];\n });\n }\n\n function getDefaultColors() {\n const inactiveColor =\n disabled || readOnly\n ? Colour[\"border-disabled\"]\n : Colour[\"border-strong\"];\n const activeColor =\n disabled || readOnly\n ? Colour[\"border-selected-disabled\"]\n : Colour[\"border-selected\"];\n\n if (numOfThumbs === 1) {\n return [activeColor, inactiveColor];\n }\n\n const defaultColors: typeof colors = [inactiveColor];\n\n for (let index = 0; index < numOfThumbs - 1; index++) {\n defaultColors.push(activeColor);\n }\n\n defaultColors.push(inactiveColor);\n return defaultColors;\n }\n\n function getValueText(currentValue: number) {\n return `${sliderLabelPrefix || \"\"}${currentValue}${\n sliderLabelSuffix || \"\"\n }`;\n }\n\n function getThumbDescriptionIds(thumbDescriptionId?: string) {\n return concatIds(\n ariaDescribedBy,\n showIndicatorLabel ? indicatorTextId : undefined,\n disabled || readOnly ? undefined : instructionTextId,\n thumbDescriptionId\n );\n }\n\n function isIncreaseKey(key: string) {\n return [\"ArrowRight\", \"ArrowUp\", \"PageUp\", \"End\"].includes(key);\n }\n\n function isDecreaseKey(key: string) {\n return [\"ArrowLeft\", \"ArrowDown\", \"PageDown\", \"Home\"].includes(key);\n }\n\n function getSliderTypeText(label?: string) {\n if (!label) {\n return \"slider\";\n }\n\n return label.toLowerCase();\n }\n\n function getSliderTargetText(label?: string) {\n if (!label) {\n return \"slider\";\n }\n\n return label.replace(/ slider$/i, \"\").toLowerCase();\n }\n\n function getBlockedMovementMessage(key: string, index: number) {\n if (numOfThumbs < 2) {\n return \"\";\n }\n\n const currentValue = selection[index];\n const previousValue = index > 0 ? selection[index - 1] : undefined;\n const nextValue =\n index < selection.length - 1 ? selection[index + 1] : undefined;\n\n const currentLabel = resolvedAriaLabels[index];\n const previousLabel =\n index > 0 ? resolvedAriaLabels[index - 1] : undefined;\n const nextLabel =\n index < resolvedAriaLabels.length - 1\n ? resolvedAriaLabels[index + 1]\n : undefined;\n\n if (isIncreaseKey(key)) {\n if (\n nextValue !== undefined &&\n currentValue >= nextValue - minRange\n ) {\n return `The ${getSliderTypeText(\n currentLabel\n )} has reached its limit. Increase the ${getSliderTargetText(\n nextLabel\n )} to set a higher ${getSliderTargetText(currentLabel)}.`;\n }\n }\n\n if (isDecreaseKey(key)) {\n if (\n previousValue !== undefined &&\n currentValue <= previousValue + minRange\n ) {\n return `The ${getSliderTypeText(\n currentLabel\n )} has reached its limit. Decrease the ${getSliderTargetText(\n previousLabel\n )} to set a lower ${getSliderTargetText(currentLabel)}.`;\n }\n }\n\n return \"\";\n }\n\n function getThumbMin(index: number, values = selection) {\n if (index === 0) {\n return min;\n }\n\n return values[index - 1] + minRange;\n }\n\n function getThumbMax(index: number, values = selection) {\n if (index === values.length - 1) {\n return max;\n }\n\n return values[index + 1] - minRange;\n }\n\n function clampValueForThumb(\n nextValue: number,\n index: number,\n values: number[]\n ) {\n const minAllowed = getThumbMin(index, values);\n const maxAllowed = getThumbMax(index, values);\n\n return Math.min(maxAllowed, Math.max(minAllowed, nextValue));\n }\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const formatLabel = (value: number) => {\n if (renderSliderLabel) {\n return renderSliderLabel(value);\n }\n\n return (\n <Typography.BodyBL className={styles.labelText}>\n {sliderLabelPrefix}\n {value}\n {sliderLabelSuffix}\n </Typography.BodyBL>\n );\n };\n\n const formatIndicationLabel = () => {\n let formattedSelection = \"\";\n\n if (selection.length === 1) {\n formattedSelection = `${selection[0]}`;\n } else if (selection.length === 2) {\n formattedSelection = `${selection[0]} - ${selection[1]}`;\n } else if (selection.length > 2) {\n const minValue = Math.min(...selection);\n const maxValue = Math.max(...selection);\n formattedSelection = `${minValue} - ${maxValue}`;\n }\n\n return (\n <Typography.BodyBL className={styles.labelText}>\n {indicatorLabelPrefix}\n {formattedSelection}\n {indicatorLabelSuffix}\n </Typography.BodyBL>\n );\n };\n\n return (\n <div\n {...otherProps}\n id={id}\n role=\"group\"\n aria-labelledby={ariaLabelledBy}\n aria-disabled={disabled}\n className={clsx(styles.wrapper, className)}\n >\n {!disabled && !readOnly && (\n <VisuallyHidden id={instructionTextId}>\n Use left and right arrow keys to adjust the slider.\n </VisuallyHidden>\n )}\n\n {showIndicatorLabel && (\n <div\n id={indicatorTextId}\n className={styles.indicatorLabelContainer}\n >\n {formatIndicationLabel()}\n </div>\n )}\n\n {selection.map((thumbValue, index) => {\n const thumbLabelTextId = `${internalId}-thumb-label-${index}`;\n const thumbDescriptionText = getThumbDescriptionText(index);\n const thumbDescriptionTextId = thumbDescriptionText\n ? `${internalId}-thumb-description-${index}`\n : undefined;\n\n return (\n <VisuallyHidden key={`native-slider-${index}`}>\n {thumbDescriptionTextId && (\n <span id={thumbDescriptionTextId}>\n {thumbDescriptionText}\n </span>\n )}\n <span id={thumbLabelTextId}>\n {resolvedAriaLabels[index]}\n </span>\n\n <input\n data-testid={`slider-input-${index}`}\n type=\"range\"\n min={getThumbMin(index)}\n max={getThumbMax(index)}\n step={step}\n value={thumbValue}\n aria-disabled={disabled || undefined}\n readOnly={readOnly}\n aria-labelledby={concatIds(\n ariaLabelledBy,\n thumbLabelTextId\n )}\n aria-describedby={getThumbDescriptionIds(\n thumbDescriptionTextId\n )}\n aria-valuetext={getValueText(thumbValue)}\n aria-invalid={ariaInvalid}\n onFocus={() => setFocusedThumbIndex(index)}\n onBlur={() => setFocusedThumbIndex(null)}\n onChange={(event) =>\n handleNativeRangeChange(event, index)\n }\n onKeyDown={(event) => {\n handleThumbKeyDown(event, index);\n }}\n />\n </VisuallyHidden>\n );\n })}\n\n {/* Native range inputs provide the accessible interaction model.\n The visible react-slider is presentation-only. */}\n <ReactSlider\n step={step}\n min={min}\n max={max}\n value={selection}\n disabled={disabled || readOnly}\n onChange={handleChange}\n onAfterChange={handleChangeEnd}\n minDistance={minRange}\n aria-hidden\n className={styles.slider}\n renderThumb={(thumbProps, state) => {\n return (\n <Thumb\n data-testid={`slider-thumb-${state.index}`}\n {...thumbProps}\n key={thumbProps.key}\n tabIndex={-1}\n aria-hidden\n focused={focusedThumbIndex === state.index}\n disabled={disabled}\n readOnly={readOnly}\n />\n );\n }}\n renderTrack={(trackProps, state) => {\n return (\n <Track\n data-testid={`slider-track-${state.index}`}\n {...trackProps}\n key={trackProps.key}\n color={trackColors[state.index]}\n />\n );\n }}\n />\n\n {showSliderLabels && (\n <div className={styles.labelContainer}>\n <div>{formatLabel(min)}</div>\n <div>{formatLabel(max)}</div>\n </div>\n )}\n </div>\n );\n};\n"],"names":["InputRangeSlider","_a","id","value","min","max","step","minRange","numOfThumbs","colors","disabled","readOnly","showSliderLabels","sliderLabelPrefix","sliderLabelSuffix","showIndicatorLabel","indicatorLabelPrefix","indicatorLabelSuffix","ariaLabels","ariaDescriptions","ariaInvalid","ariaLabelledBy","ariaDescribedBy","renderSliderLabel","onChange","onChangeEnd","className","otherProps","__rest","selection","setSelection","useState","initialiseSelection","focusedThumbIndex","setFocusedThumbIndex","internalId","useId","trackColors","defaultColors","inactiveColor","Colour","activeColor","index","push","getDefaultColors","Array","fill","map","_","i","getTrackColors","indicatorTextId","instructionTextId","resolvedAriaLabels","from","length","getDefaultAriaLabel","useEffect","handleThumbKeyDown","event","message","key","currentValue","previousValue","undefined","nextValue","currentLabel","previousLabel","nextLabel","includes","isIncreaseKey","getSliderTypeText","getSliderTargetText","isDecreaseKey","getBlockedMovementMessage","clearAnnouncer","announce","handleNativeRangeChange","nextRawValue","Number","currentTarget","nextSelection","values","minAllowed","getThumbMin","maxAllowed","getThumbMax","Math","clampValueForThumb","label","toLowerCase","replace","formatLabel","_jsxs","Typography","BodyBL","styles.labelText","children","Object","assign","role","clsx","styles.wrapper","_jsx","VisuallyHidden","styles.indicatorLabelContainer","formattedSelection","formatIndicationLabel","thumbValue","thumbLabelTextId","thumbDescriptionText","getThumbDescriptionText","thumbDescriptionTextId","type","concatIds","thumbDescriptionId","onFocus","onBlur","onKeyDown","ReactSlider","onAfterChange","val","newSelection","minDistance","styles.slider","renderThumb","thumbProps","state","_createElement","Thumb","tabIndex","focused","renderTrack","trackProps","Track","color","styles.labelContainer"],"mappings":"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"}