@transferwise/components 46.140.1 → 46.142.0

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 (221) hide show
  1. package/build/avatarLayout/AvatarLayout.js +15 -1
  2. package/build/avatarLayout/AvatarLayout.js.map +1 -1
  3. package/build/avatarLayout/AvatarLayout.mjs +15 -1
  4. package/build/avatarLayout/AvatarLayout.mjs.map +1 -1
  5. package/build/avatarView/AvatarView.js +6 -2
  6. package/build/avatarView/AvatarView.js.map +1 -1
  7. package/build/avatarView/AvatarView.mjs +6 -2
  8. package/build/avatarView/AvatarView.mjs.map +1 -1
  9. package/build/avatarView/Dot.js +8 -0
  10. package/build/avatarView/Dot.js.map +1 -1
  11. package/build/avatarView/Dot.mjs +8 -0
  12. package/build/avatarView/Dot.mjs.map +1 -1
  13. package/build/avatarWrapper/AvatarWrapper.js +3 -4
  14. package/build/avatarWrapper/AvatarWrapper.js.map +1 -1
  15. package/build/avatarWrapper/AvatarWrapper.mjs +4 -5
  16. package/build/avatarWrapper/AvatarWrapper.mjs.map +1 -1
  17. package/build/button/LegacyButton.js.map +1 -1
  18. package/build/button/LegacyButton.mjs.map +1 -1
  19. package/build/common/circle/Circle.js +6 -2
  20. package/build/common/circle/Circle.js.map +1 -1
  21. package/build/common/circle/Circle.mjs +6 -2
  22. package/build/common/circle/Circle.mjs.map +1 -1
  23. package/build/common/hooks/useHasIntersected/useHasIntersected.js +6 -4
  24. package/build/common/hooks/useHasIntersected/useHasIntersected.js.map +1 -1
  25. package/build/common/hooks/useHasIntersected/useHasIntersected.mjs +6 -4
  26. package/build/common/hooks/useHasIntersected/useHasIntersected.mjs.map +1 -1
  27. package/build/common/liveRegion/LiveRegion.js +4 -1
  28. package/build/common/liveRegion/LiveRegion.js.map +1 -1
  29. package/build/common/liveRegion/LiveRegion.mjs +4 -1
  30. package/build/common/liveRegion/LiveRegion.mjs.map +1 -1
  31. package/build/dateInput/DateInput.js +10 -10
  32. package/build/dateInput/DateInput.js.map +1 -1
  33. package/build/dateInput/DateInput.mjs +10 -10
  34. package/build/dateInput/DateInput.mjs.map +1 -1
  35. package/build/dateLookup/monthCalendar/table/MonthCalendarTable.js +1 -1
  36. package/build/dateLookup/monthCalendar/table/MonthCalendarTable.js.map +1 -1
  37. package/build/dateLookup/monthCalendar/table/MonthCalendarTable.mjs +1 -1
  38. package/build/dateLookup/monthCalendar/table/MonthCalendarTable.mjs.map +1 -1
  39. package/build/dateLookup/yearCalendar/table/YearCalendarTable.js +1 -1
  40. package/build/dateLookup/yearCalendar/table/YearCalendarTable.js.map +1 -1
  41. package/build/dateLookup/yearCalendar/table/YearCalendarTable.mjs +1 -1
  42. package/build/dateLookup/yearCalendar/table/YearCalendarTable.mjs.map +1 -1
  43. package/build/expressiveMoneyInput/ExpressiveMoneyInput.js.map +1 -1
  44. package/build/expressiveMoneyInput/ExpressiveMoneyInput.mjs.map +1 -1
  45. package/build/expressiveMoneyInput/amountInput/AmountInput.js +18 -12
  46. package/build/expressiveMoneyInput/amountInput/AmountInput.js.map +1 -1
  47. package/build/expressiveMoneyInput/amountInput/AmountInput.mjs +19 -13
  48. package/build/expressiveMoneyInput/amountInput/AmountInput.mjs.map +1 -1
  49. package/build/expressiveMoneyInput/hooks/useInputStyle.js +8 -6
  50. package/build/expressiveMoneyInput/hooks/useInputStyle.js.map +1 -1
  51. package/build/expressiveMoneyInput/hooks/useInputStyle.mjs +9 -7
  52. package/build/expressiveMoneyInput/hooks/useInputStyle.mjs.map +1 -1
  53. package/build/field/Field.js +63 -32
  54. package/build/field/Field.js.map +1 -1
  55. package/build/field/Field.messages.js +14 -0
  56. package/build/field/Field.messages.js.map +1 -0
  57. package/build/field/Field.messages.mjs +10 -0
  58. package/build/field/Field.messages.mjs.map +1 -0
  59. package/build/field/Field.mjs +65 -34
  60. package/build/field/Field.mjs.map +1 -1
  61. package/build/header/Header.js +1 -1
  62. package/build/header/Header.js.map +1 -1
  63. package/build/header/Header.mjs +1 -1
  64. package/build/header/Header.mjs.map +1 -1
  65. package/build/i18n/en.json +1 -0
  66. package/build/i18n/en.json.js +1 -0
  67. package/build/i18n/en.json.js.map +1 -1
  68. package/build/i18n/en.json.mjs +1 -0
  69. package/build/i18n/en.json.mjs.map +1 -1
  70. package/build/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.js.map +1 -1
  71. package/build/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.mjs.map +1 -1
  72. package/build/inputs/SelectInput/Options/SelectInputOptions.js +34 -22
  73. package/build/inputs/SelectInput/Options/SelectInputOptions.js.map +1 -1
  74. package/build/inputs/SelectInput/Options/SelectInputOptions.mjs +35 -23
  75. package/build/inputs/SelectInput/Options/SelectInputOptions.mjs.map +1 -1
  76. package/build/inputs/SelectInput/Popover/SelectInputPopover.js.map +1 -1
  77. package/build/inputs/SelectInput/Popover/SelectInputPopover.mjs.map +1 -1
  78. package/build/inputs/SelectInput/SelectInput.js +8 -6
  79. package/build/inputs/SelectInput/SelectInput.js.map +1 -1
  80. package/build/inputs/SelectInput/SelectInput.mjs +9 -7
  81. package/build/inputs/SelectInput/SelectInput.mjs.map +1 -1
  82. package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.js.map +1 -1
  83. package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.mjs.map +1 -1
  84. package/build/inputs/TextArea.js +5 -0
  85. package/build/inputs/TextArea.js.map +1 -1
  86. package/build/inputs/TextArea.mjs +6 -1
  87. package/build/inputs/TextArea.mjs.map +1 -1
  88. package/build/inputs/contexts.js +16 -0
  89. package/build/inputs/contexts.js.map +1 -1
  90. package/build/inputs/contexts.mjs +16 -2
  91. package/build/inputs/contexts.mjs.map +1 -1
  92. package/build/main.css +42 -8
  93. package/build/nudge/Nudge.js +31 -15
  94. package/build/nudge/Nudge.js.map +1 -1
  95. package/build/nudge/Nudge.mjs +32 -16
  96. package/build/nudge/Nudge.mjs.map +1 -1
  97. package/build/phoneNumberInput/PhoneNumberInput.js +9 -12
  98. package/build/phoneNumberInput/PhoneNumberInput.js.map +1 -1
  99. package/build/phoneNumberInput/PhoneNumberInput.mjs +9 -12
  100. package/build/phoneNumberInput/PhoneNumberInput.mjs.map +1 -1
  101. package/build/promoCard/PromoCardGroup.js +34 -16
  102. package/build/promoCard/PromoCardGroup.js.map +1 -1
  103. package/build/promoCard/PromoCardGroup.mjs +35 -17
  104. package/build/promoCard/PromoCardGroup.mjs.map +1 -1
  105. package/build/segmentedControl/SegmentedControl.js +6 -1
  106. package/build/segmentedControl/SegmentedControl.js.map +1 -1
  107. package/build/segmentedControl/SegmentedControl.mjs +7 -2
  108. package/build/segmentedControl/SegmentedControl.mjs.map +1 -1
  109. package/build/styles/avatarView/AvatarView.css +4 -4
  110. package/build/styles/avatarView/Dot.css +4 -4
  111. package/build/styles/css/neptune.css +15 -1
  112. package/build/styles/expressiveMoneyInput/ExpressiveMoneyInput.css +2 -0
  113. package/build/styles/expressiveMoneyInput/amountInput/AmountInput.css +2 -0
  114. package/build/styles/field/Field.css +19 -3
  115. package/build/styles/main.css +42 -8
  116. package/build/styles/styles/less/neptune.css +15 -1
  117. package/build/tabs/Tabs.js +1 -1
  118. package/build/tabs/Tabs.js.map +1 -1
  119. package/build/tabs/Tabs.mjs +1 -1
  120. package/build/tabs/Tabs.mjs.map +1 -1
  121. package/build/tooltip/Tooltip.js +6 -3
  122. package/build/tooltip/Tooltip.js.map +1 -1
  123. package/build/tooltip/Tooltip.mjs +6 -3
  124. package/build/tooltip/Tooltip.mjs.map +1 -1
  125. package/build/types/avatarView/AvatarView.d.ts +1 -1
  126. package/build/types/avatarView/AvatarView.d.ts.map +1 -1
  127. package/build/types/avatarView/Dot.d.ts.map +1 -1
  128. package/build/types/avatarWrapper/AvatarWrapper.d.ts.map +1 -1
  129. package/build/types/common/circle/Circle.d.ts +1 -1
  130. package/build/types/common/circle/Circle.d.ts.map +1 -1
  131. package/build/types/common/hooks/useHasIntersected/useHasIntersected.d.ts.map +1 -1
  132. package/build/types/common/liveRegion/LiveRegion.d.ts.map +1 -1
  133. package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts.map +1 -1
  134. package/build/types/expressiveMoneyInput/ExpressiveMoneyInput.d.ts.map +1 -1
  135. package/build/types/expressiveMoneyInput/amountInput/AmountInput.d.ts.map +1 -1
  136. package/build/types/expressiveMoneyInput/hooks/useInputStyle.d.ts +2 -2
  137. package/build/types/expressiveMoneyInput/hooks/useInputStyle.d.ts.map +1 -1
  138. package/build/types/expressiveMoneyInput/hooks/useSelectionRange.d.ts.map +1 -1
  139. package/build/types/field/Field.d.ts.map +1 -1
  140. package/build/types/field/Field.messages.d.ts +8 -0
  141. package/build/types/field/Field.messages.d.ts.map +1 -0
  142. package/build/types/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.d.ts.map +1 -1
  143. package/build/types/inputs/SelectInput/Options/SelectInputOptions.d.ts.map +1 -1
  144. package/build/types/inputs/SelectInput/Popover/SelectInputPopover.d.ts.map +1 -1
  145. package/build/types/inputs/SelectInput/SelectInput.d.ts.map +1 -1
  146. package/build/types/inputs/TextArea.d.ts.map +1 -1
  147. package/build/types/inputs/contexts.d.ts +6 -0
  148. package/build/types/inputs/contexts.d.ts.map +1 -1
  149. package/build/types/nudge/Nudge.d.ts.map +1 -1
  150. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  151. package/build/types/promoCard/PromoCardGroup.d.ts.map +1 -1
  152. package/build/types/segmentedControl/SegmentedControl.d.ts.map +1 -1
  153. package/build/types/test-utils/index.d.ts +2 -0
  154. package/build/types/test-utils/index.d.ts.map +1 -1
  155. package/build/types/tooltip/Tooltip.d.ts.map +1 -1
  156. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  157. package/build/uploadInput/UploadInput.js +29 -25
  158. package/build/uploadInput/UploadInput.js.map +1 -1
  159. package/build/uploadInput/UploadInput.mjs +29 -25
  160. package/build/uploadInput/UploadInput.mjs.map +1 -1
  161. package/package.json +3 -3
  162. package/src/avatarLayout/AvatarLayout.story.tsx +1 -1
  163. package/src/avatarLayout/AvatarLayout.tsx +4 -0
  164. package/src/avatarView/AvatarView.css +4 -4
  165. package/src/avatarView/AvatarView.story.tsx +17 -13
  166. package/src/avatarView/AvatarView.tsx +5 -1
  167. package/src/avatarView/Dot.css +4 -4
  168. package/src/avatarView/Dot.less +6 -6
  169. package/src/avatarView/Dot.tsx +2 -0
  170. package/src/avatarWrapper/AvatarWrapper.test.tsx +33 -3
  171. package/src/avatarWrapper/AvatarWrapper.tsx +5 -6
  172. package/src/button/LegacyButton.tsx +1 -1
  173. package/src/button/_stories/Button.test.story.tsx +3 -3
  174. package/src/common/circle/Circle.tsx +5 -1
  175. package/src/common/hooks/useContainerSize.test.tsx +1 -1
  176. package/src/common/hooks/useHasIntersected/useHasIntersected.ts +12 -4
  177. package/src/common/liveRegion/LiveRegion.tsx +5 -2
  178. package/src/dateInput/DateInput.tsx +10 -10
  179. package/src/dateLookup/monthCalendar/table/MonthCalendarTable.tsx +1 -5
  180. package/src/dateLookup/yearCalendar/table/YearCalendarTable.tsx +1 -1
  181. package/src/expressiveMoneyInput/ExpressiveMoneyInput.css +2 -0
  182. package/src/expressiveMoneyInput/ExpressiveMoneyInput.test.story.tsx +43 -0
  183. package/src/expressiveMoneyInput/ExpressiveMoneyInput.tsx +1 -1
  184. package/src/expressiveMoneyInput/amountInput/AmountInput.css +2 -0
  185. package/src/expressiveMoneyInput/amountInput/AmountInput.less +2 -0
  186. package/src/expressiveMoneyInput/amountInput/AmountInput.tsx +23 -16
  187. package/src/expressiveMoneyInput/hooks/useInputStyle.ts +20 -8
  188. package/src/expressiveMoneyInput/hooks/useSelectionRange.ts +2 -0
  189. package/src/field/Field.css +19 -3
  190. package/src/field/Field.less +17 -3
  191. package/src/field/Field.messages.ts +8 -0
  192. package/src/field/Field.story.tsx +5 -1
  193. package/src/field/Field.test.tsx +90 -0
  194. package/src/field/Field.tsx +84 -37
  195. package/src/header/Header.tsx +2 -2
  196. package/src/i18n/en.json +1 -0
  197. package/src/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.tsx +4 -0
  198. package/src/inputs/SelectInput/Options/SelectInputOptions.tsx +43 -27
  199. package/src/inputs/SelectInput/Popover/SelectInputPopover.tsx +4 -0
  200. package/src/inputs/SelectInput/SelectInput.tsx +21 -15
  201. package/src/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx +1 -1
  202. package/src/inputs/TextArea.story.tsx +97 -0
  203. package/src/inputs/TextArea.test.story.tsx +142 -0
  204. package/src/inputs/TextArea.tsx +7 -2
  205. package/src/inputs/contexts.tsx +18 -1
  206. package/src/main.css +42 -8
  207. package/src/nudge/Nudge.tsx +29 -20
  208. package/src/phoneNumberInput/PhoneNumberInput.test.tsx +16 -0
  209. package/src/phoneNumberInput/PhoneNumberInput.tsx +11 -13
  210. package/src/promoCard/PromoCard.story.tsx +3 -3
  211. package/src/promoCard/PromoCardGroup.tsx +39 -21
  212. package/src/segmentedControl/SegmentedControl.test.tsx +25 -0
  213. package/src/segmentedControl/SegmentedControl.tsx +7 -1
  214. package/src/select/Select.story.tsx +1 -1
  215. package/src/styles/less/core/_typography.less +28 -6
  216. package/src/styles/less/neptune.css +15 -1
  217. package/src/tabs/Tabs.tsx +1 -1
  218. package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.story.tsx +1 -0
  219. package/src/tooltip/Tooltip.tsx +3 -0
  220. package/src/uploadInput/UploadInput.test.tsx +19 -0
  221. package/src/uploadInput/UploadInput.tsx +28 -24
@@ -1 +1 @@
1
- {"version":3,"file":"SelectInput.js","sources":["../../../src/inputs/SelectInput/SelectInput.tsx"],"sourcesContent":["import mergeProps from 'merge-props';\nimport { useEffect, useRef, useState, useDeferredValue } from 'react';\nimport { Listbox as ListboxBase } from '@headlessui/react';\nimport { useScreenSize } from '../../common/hooks/useScreenSize';\nimport { Breakpoint } from '../../common/propsValues/breakpoint';\nimport { useEffectEvent } from '../../common/hooks/useEffectEvent';\nimport { useInputAttributes } from '../contexts';\n\nimport { SelectInputBottomSheet } from './BottomSheet';\nimport { SelectInputPopover } from './Popover';\nimport { SelectInputOptions } from './Options';\nimport { DefaultRenderTrigger } from './DefaultRenderTrigger';\n\nimport {\n SelectInputOptionContentWithinTriggerContext,\n SelectInputTriggerButtonPropsContext,\n} from './SelectInput.contexts';\nimport { searchableString, sortByRelevance } from './SelectInput.utils';\nimport { SelectInputProps } from './SelectInput.types';\n\nconst noop = () => {};\n\n/**\n * SelectInput component allows users to select an option from a dropdown list.\n * Supports filtering, multiple selection, and customization.\n */\nexport function SelectInput<T = string, M extends boolean = false>({\n id: idProp,\n parentId,\n name,\n multiple,\n placeholder,\n autocomplete,\n items,\n defaultValue,\n value: controlledValue,\n compareValues,\n renderValue = String,\n renderFooter,\n renderTrigger = DefaultRenderTrigger,\n filterable,\n filterPlaceholder,\n sortFilteredOptions,\n disabled,\n size = 'md',\n className,\n UNSAFE_triggerButtonProps,\n triggerRef: externalTriggerRef,\n onFilterChange = noop,\n onChange,\n onOpen,\n onClose,\n onClear,\n}: SelectInputProps<T, M>) {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const id = idProp ?? inputAttributes.id;\n\n const [open, setOpen] = useState(false);\n\n const initialized = useRef(false);\n const handleClose = useEffectEvent(onClose ?? (() => {}));\n const handleOpen = useEffectEvent(onOpen ?? (() => {}));\n useEffect(() => {\n if (initialized.current) {\n if (open) {\n handleOpen?.();\n } else {\n handleClose?.();\n }\n } else {\n initialized.current = true;\n }\n }, [handleClose, handleOpen, open]);\n\n const [filterQuery, _setFilterQuery] = useState('');\n const deferredFilterQuery = useDeferredValue(filterQuery);\n const setFilterQuery = useEffectEvent((query: string) => {\n _setFilterQuery(query);\n if (query !== filterQuery) {\n onFilterChange({\n query,\n queryNormalized: query ? searchableString(query) : null,\n });\n }\n });\n\n const internalTriggerRef = useRef<HTMLButtonElement | null>(null);\n\n const screenSm = useScreenSize(Breakpoint.SMALL);\n const OptionsOverlay = screenSm ? SelectInputPopover : SelectInputBottomSheet;\n\n const searchInputRef = useRef<HTMLInputElement>(null);\n const listboxRef = useRef<HTMLDivElement>(null);\n const controllerRef = filterable ? searchInputRef : listboxRef;\n\n /**\n * Attempts to resolve the `listbox` label\n * @see https://storybook.wise.design/?path=/docs/forms-selectinput-accessibility--docs#labelling\n */\n const getListBoxLabelProps = (): {\n listBoxLabel?: string;\n listBoxLabelledBy?: string;\n } => {\n if (UNSAFE_triggerButtonProps?.['aria-label']) {\n return {\n listBoxLabel: UNSAFE_triggerButtonProps['aria-label'],\n };\n }\n\n if (UNSAFE_triggerButtonProps?.['aria-labelledby']) {\n return {\n listBoxLabelledBy: UNSAFE_triggerButtonProps['aria-labelledby'],\n };\n }\n\n if (inputAttributes['aria-labelledby']) {\n return {\n listBoxLabelledBy: inputAttributes['aria-labelledby'],\n };\n }\n\n return {};\n };\n\n return (\n <ListboxBase\n name={name}\n multiple={multiple}\n defaultValue={defaultValue as M extends true ? T[] : T}\n value={controlledValue as M extends true ? T[] : T}\n by={compareValues}\n disabled={disabled}\n onChange={\n ((value) => {\n if (!multiple) {\n setOpen(false);\n }\n onChange?.(value);\n }) satisfies SelectInputProps<T, M>['onChange']\n }\n >\n {({ disabled: uiDisabled, value }) => {\n const placeholderShown =\n multiple && Array.isArray(value) ? value.length === 0 : value == null;\n return (\n <OptionsOverlay\n placement=\"bottom-start\"\n open={open}\n renderTrigger={({ ref, getInteractionProps }) => (\n <SelectInputTriggerButtonPropsContext.Provider\n // eslint-disable-next-line react/jsx-no-constructed-context-values\n value={{\n ref: (node) => {\n ref(node);\n if (externalTriggerRef) {\n // eslint-disable-next-line no-param-reassign\n externalTriggerRef.current = node;\n } else {\n internalTriggerRef.current = node;\n }\n },\n size,\n ...inputAttributes,\n ...UNSAFE_triggerButtonProps,\n id,\n ...mergeProps(\n {\n onClick: () => {\n setOpen((prev) => !prev);\n },\n onKeyDown: (event: React.KeyboardEvent) => {\n if (\n event.key === ' ' ||\n event.key === 'Enter' ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n setOpen((prev) => !prev);\n }\n },\n },\n getInteractionProps(),\n ),\n }}\n >\n {renderTrigger({\n content: !placeholderShown ? (\n <SelectInputOptionContentWithinTriggerContext.Provider value>\n {multiple && Array.isArray(value)\n ? (value as readonly NonNullable<T>[])\n .map((option) => renderValue(option, true))\n .filter((node) => node != null)\n .join(', ')\n : renderValue(value as NonNullable<T>, true)}\n </SelectInputOptionContentWithinTriggerContext.Provider>\n ) : (\n placeholder\n ),\n placeholderShown,\n clear:\n onClear != null\n ? () => {\n onClear();\n (externalTriggerRef?.current ?? internalTriggerRef.current)?.focus({\n preventScroll: true,\n });\n }\n : undefined,\n disabled: uiDisabled,\n size,\n className,\n })}\n </SelectInputTriggerButtonPropsContext.Provider>\n )}\n initialFocusRef={controllerRef}\n size={filterable ? 'lg' : 'md'}\n padding=\"none\"\n onClose={() => {\n setOpen(false);\n }}\n onCloseEnd={() => {\n setFilterQuery('');\n }}\n >\n <SelectInputOptions\n id={id ? `${id}Search` : undefined}\n parentId={parentId}\n items={items}\n compareValues={compareValues}\n renderValue={renderValue}\n renderFooter={renderFooter}\n filterable={filterable}\n filterPlaceholder={filterPlaceholder}\n sortFilteredOptions={sortFilteredOptions}\n searchInputRef={searchInputRef}\n listboxRef={listboxRef}\n filterQuery={deferredFilterQuery}\n autocomplete={autocomplete}\n name={name}\n onFilterChange={setFilterQuery}\n onAutocompleteSelect={(matchedValue) => {\n onChange?.(matchedValue as M extends true ? T[] : T);\n if (!multiple) {\n setOpen(false);\n }\n }}\n {...getListBoxLabelProps()}\n />\n </OptionsOverlay>\n );\n }}\n </ListboxBase>\n );\n}\n\n// Attach sortByRelevance to the component for convenience\nSelectInput.sortByRelevance = sortByRelevance;\n"],"names":["noop","SelectInput","id","idProp","parentId","name","multiple","placeholder","autocomplete","items","defaultValue","value","controlledValue","compareValues","renderValue","String","renderFooter","renderTrigger","DefaultRenderTrigger","filterable","filterPlaceholder","sortFilteredOptions","disabled","size","className","UNSAFE_triggerButtonProps","triggerRef","externalTriggerRef","onFilterChange","onChange","onOpen","onClose","onClear","inputAttributes","useInputAttributes","nonLabelable","open","setOpen","useState","initialized","useRef","handleClose","useEffectEvent","handleOpen","useEffect","current","filterQuery","_setFilterQuery","deferredFilterQuery","useDeferredValue","setFilterQuery","query","queryNormalized","searchableString","internalTriggerRef","screenSm","useScreenSize","Breakpoint","SMALL","OptionsOverlay","SelectInputPopover","SelectInputBottomSheet","searchInputRef","listboxRef","controllerRef","getListBoxLabelProps","listBoxLabel","listBoxLabelledBy","_jsx","ListboxBase","by","children","uiDisabled","placeholderShown","Array","isArray","length","placement","ref","getInteractionProps","SelectInputTriggerButtonPropsContext","Provider","node","mergeProps","onClick","prev","onKeyDown","event","key","content","SelectInputOptionContentWithinTriggerContext","map","option","filter","join","clear","focus","preventScroll","undefined","initialFocusRef","padding","onCloseEnd","SelectInputOptions","onAutocompleteSelect","matchedValue","sortByRelevance"],"mappings":"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"}
1
+ {"version":3,"file":"SelectInput.js","sources":["../../../src/inputs/SelectInput/SelectInput.tsx"],"sourcesContent":["import mergeProps from 'merge-props';\nimport { useCallback, useEffect, useRef, useState, useDeferredValue } from 'react';\nimport { Listbox as ListboxBase } from '@headlessui/react';\nimport { useScreenSize } from '../../common/hooks/useScreenSize';\nimport { Breakpoint } from '../../common/propsValues/breakpoint';\nimport { useEffectEvent } from '../../common/hooks/useEffectEvent';\nimport { useInputAttributes } from '../contexts';\n\nimport { SelectInputBottomSheet } from './BottomSheet';\nimport { SelectInputPopover } from './Popover';\nimport { SelectInputOptions } from './Options';\nimport { DefaultRenderTrigger } from './DefaultRenderTrigger';\n\nimport {\n SelectInputOptionContentWithinTriggerContext,\n SelectInputTriggerButtonPropsContext,\n} from './SelectInput.contexts';\nimport { searchableString, sortByRelevance } from './SelectInput.utils';\nimport { SelectInputProps } from './SelectInput.types';\n\nconst noop = () => {};\n\n/**\n * SelectInput component allows users to select an option from a dropdown list.\n * Supports filtering, multiple selection, and customization.\n */\nexport function SelectInput<T = string, M extends boolean = false>({\n id: idProp,\n parentId,\n name,\n multiple,\n placeholder,\n autocomplete,\n items,\n defaultValue,\n value: controlledValue,\n compareValues,\n renderValue = String,\n renderFooter,\n renderTrigger = DefaultRenderTrigger,\n filterable,\n filterPlaceholder,\n sortFilteredOptions,\n disabled,\n size = 'md',\n className,\n UNSAFE_triggerButtonProps,\n triggerRef: externalTriggerRef,\n onFilterChange = noop,\n onChange,\n onOpen,\n onClose,\n onClear,\n}: SelectInputProps<T, M>) {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const id = idProp ?? inputAttributes.id;\n\n const [open, setOpen] = useState(false);\n\n const initialized = useRef(false);\n const handleClose = useEffectEvent(onClose ?? (() => {}));\n const handleOpen = useEffectEvent(onOpen ?? (() => {}));\n\n useEffect(() => {\n if (initialized.current) {\n if (open) {\n handleOpen?.();\n } else {\n handleClose?.();\n }\n } else {\n initialized.current = true;\n }\n }, [open]);\n\n const [filterQuery, _setFilterQuery] = useState('');\n const deferredFilterQuery = useDeferredValue(filterQuery);\n const previousFilterQueryRef = useRef(filterQuery);\n\n const setFilterQuery = useCallback(\n (query: string) => {\n _setFilterQuery(query);\n if (query !== previousFilterQueryRef.current) {\n onFilterChange({\n query,\n queryNormalized: query ? searchableString(query) : null,\n });\n previousFilterQueryRef.current = query;\n }\n },\n [onFilterChange],\n );\n\n const internalTriggerRef = useRef<HTMLButtonElement | null>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const listboxRef = useRef<HTMLDivElement>(null);\n const controllerRef = filterable ? searchInputRef : listboxRef;\n\n const screenSm = useScreenSize(Breakpoint.SMALL);\n const OptionsOverlay = screenSm ? SelectInputPopover : SelectInputBottomSheet;\n\n /**\n * Attempts to resolve the `listbox` label\n * @see https://storybook.wise.design/?path=/docs/forms-selectinput-accessibility--docs#labelling\n */\n const getListBoxLabelProps = (): {\n listBoxLabel?: string;\n listBoxLabelledBy?: string;\n } => {\n if (UNSAFE_triggerButtonProps?.['aria-label']) {\n return {\n listBoxLabel: UNSAFE_triggerButtonProps['aria-label'],\n };\n }\n\n if (UNSAFE_triggerButtonProps?.['aria-labelledby']) {\n return {\n listBoxLabelledBy: UNSAFE_triggerButtonProps['aria-labelledby'],\n };\n }\n\n if (inputAttributes['aria-labelledby']) {\n return {\n listBoxLabelledBy: inputAttributes['aria-labelledby'],\n };\n }\n\n return {};\n };\n\n return (\n <ListboxBase\n name={name}\n multiple={multiple}\n defaultValue={defaultValue as M extends true ? T[] : T}\n value={controlledValue as M extends true ? T[] : T}\n by={compareValues}\n disabled={disabled}\n onChange={\n ((value) => {\n if (!multiple) {\n setOpen(false);\n }\n onChange?.(value);\n }) satisfies SelectInputProps<T, M>['onChange']\n }\n >\n {({ disabled: uiDisabled, value }) => {\n const placeholderShown =\n multiple && Array.isArray(value) ? value.length === 0 : value == null;\n return (\n <OptionsOverlay\n placement=\"bottom-start\"\n open={open}\n renderTrigger={({ ref, getInteractionProps }) => (\n <SelectInputTriggerButtonPropsContext.Provider\n // eslint-disable-next-line react/jsx-no-constructed-context-values\n value={{\n ref: (node) => {\n ref(node);\n if (externalTriggerRef) {\n // eslint-disable-next-line no-param-reassign\n externalTriggerRef.current = node;\n } else {\n internalTriggerRef.current = node;\n }\n },\n size,\n ...inputAttributes,\n ...UNSAFE_triggerButtonProps,\n id,\n ...mergeProps(\n {\n onClick: () => {\n setOpen((prev) => !prev);\n },\n onKeyDown: (event: React.KeyboardEvent) => {\n if (\n event.key === ' ' ||\n event.key === 'Enter' ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n setOpen((prev) => !prev);\n }\n },\n },\n getInteractionProps(),\n ),\n }}\n >\n {renderTrigger({\n content: !placeholderShown ? (\n <SelectInputOptionContentWithinTriggerContext.Provider value>\n {multiple && Array.isArray(value)\n ? (value as readonly NonNullable<T>[])\n .map((option) => renderValue(option, true))\n .filter((node) => node != null)\n .join(', ')\n : renderValue(value as NonNullable<T>, true)}\n </SelectInputOptionContentWithinTriggerContext.Provider>\n ) : (\n placeholder\n ),\n placeholderShown,\n clear:\n onClear != null\n ? () => {\n onClear();\n (externalTriggerRef?.current ?? internalTriggerRef.current)?.focus({\n preventScroll: true,\n });\n }\n : undefined,\n disabled: uiDisabled,\n size,\n className,\n })}\n </SelectInputTriggerButtonPropsContext.Provider>\n )}\n initialFocusRef={controllerRef}\n size={filterable ? 'lg' : 'md'}\n padding=\"none\"\n onClose={() => {\n setOpen(false);\n }}\n onCloseEnd={() => {\n setFilterQuery('');\n }}\n >\n <SelectInputOptions\n id={id ? `${id}Search` : undefined}\n parentId={parentId}\n items={items}\n compareValues={compareValues}\n renderValue={renderValue}\n renderFooter={renderFooter}\n filterable={filterable}\n filterPlaceholder={filterPlaceholder}\n sortFilteredOptions={sortFilteredOptions}\n searchInputRef={searchInputRef}\n listboxRef={listboxRef}\n filterQuery={deferredFilterQuery}\n autocomplete={autocomplete}\n name={name}\n onFilterChange={setFilterQuery}\n onAutocompleteSelect={(matchedValue) => {\n onChange?.(matchedValue as M extends true ? T[] : T);\n if (!multiple) {\n setOpen(false);\n }\n }}\n {...getListBoxLabelProps()}\n />\n </OptionsOverlay>\n );\n }}\n </ListboxBase>\n );\n}\n\n// Attach sortByRelevance to the component for convenience\nSelectInput.sortByRelevance = sortByRelevance;\n"],"names":["noop","SelectInput","id","idProp","parentId","name","multiple","placeholder","autocomplete","items","defaultValue","value","controlledValue","compareValues","renderValue","String","renderFooter","renderTrigger","DefaultRenderTrigger","filterable","filterPlaceholder","sortFilteredOptions","disabled","size","className","UNSAFE_triggerButtonProps","triggerRef","externalTriggerRef","onFilterChange","onChange","onOpen","onClose","onClear","inputAttributes","useInputAttributes","nonLabelable","open","setOpen","useState","initialized","useRef","handleClose","useEffectEvent","handleOpen","useEffect","current","filterQuery","_setFilterQuery","deferredFilterQuery","useDeferredValue","previousFilterQueryRef","setFilterQuery","useCallback","query","queryNormalized","searchableString","internalTriggerRef","searchInputRef","listboxRef","controllerRef","screenSm","useScreenSize","Breakpoint","SMALL","OptionsOverlay","SelectInputPopover","SelectInputBottomSheet","getListBoxLabelProps","listBoxLabel","listBoxLabelledBy","_jsx","ListboxBase","by","children","uiDisabled","placeholderShown","Array","isArray","length","placement","ref","getInteractionProps","SelectInputTriggerButtonPropsContext","Provider","node","mergeProps","onClick","prev","onKeyDown","event","key","content","SelectInputOptionContentWithinTriggerContext","map","option","filter","join","clear","focus","preventScroll","undefined","initialFocusRef","padding","onCloseEnd","SelectInputOptions","onAutocompleteSelect","matchedValue","sortByRelevance"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import mergeProps from 'merge-props';
2
- import { useState, useRef, useEffect, useDeferredValue } from 'react';
2
+ import { useState, useRef, useEffect, useDeferredValue, useCallback } from 'react';
3
3
  import { Listbox } from '@headlessui/react';
4
4
  import { useScreenSize } from '../../common/hooks/useScreenSize.mjs';
5
5
  import { Breakpoint } from '../../common/propsValues/breakpoint.mjs';
@@ -64,24 +64,26 @@ function SelectInput({
64
64
  } else {
65
65
  initialized.current = true;
66
66
  }
67
- }, [handleClose, handleOpen, open]);
67
+ }, [open]);
68
68
  const [filterQuery, _setFilterQuery] = useState('');
69
69
  const deferredFilterQuery = useDeferredValue(filterQuery);
70
- const setFilterQuery = useEffectEvent(query => {
70
+ const previousFilterQueryRef = useRef(filterQuery);
71
+ const setFilterQuery = useCallback(query => {
71
72
  _setFilterQuery(query);
72
- if (query !== filterQuery) {
73
+ if (query !== previousFilterQueryRef.current) {
73
74
  onFilterChange({
74
75
  query,
75
76
  queryNormalized: query ? searchableString(query) : null
76
77
  });
78
+ previousFilterQueryRef.current = query;
77
79
  }
78
- });
80
+ }, [onFilterChange]);
79
81
  const internalTriggerRef = useRef(null);
80
- const screenSm = useScreenSize(Breakpoint.SMALL);
81
- const OptionsOverlay = screenSm ? SelectInputPopover : SelectInputBottomSheet;
82
82
  const searchInputRef = useRef(null);
83
83
  const listboxRef = useRef(null);
84
84
  const controllerRef = filterable ? searchInputRef : listboxRef;
85
+ const screenSm = useScreenSize(Breakpoint.SMALL);
86
+ const OptionsOverlay = screenSm ? SelectInputPopover : SelectInputBottomSheet;
85
87
  /**
86
88
  * Attempts to resolve the `listbox` label
87
89
  * @see https://storybook.wise.design/?path=/docs/forms-selectinput-accessibility--docs#labelling
@@ -1 +1 @@
1
- {"version":3,"file":"SelectInput.mjs","sources":["../../../src/inputs/SelectInput/SelectInput.tsx"],"sourcesContent":["import mergeProps from 'merge-props';\nimport { useEffect, useRef, useState, useDeferredValue } from 'react';\nimport { Listbox as ListboxBase } from '@headlessui/react';\nimport { useScreenSize } from '../../common/hooks/useScreenSize';\nimport { Breakpoint } from '../../common/propsValues/breakpoint';\nimport { useEffectEvent } from '../../common/hooks/useEffectEvent';\nimport { useInputAttributes } from '../contexts';\n\nimport { SelectInputBottomSheet } from './BottomSheet';\nimport { SelectInputPopover } from './Popover';\nimport { SelectInputOptions } from './Options';\nimport { DefaultRenderTrigger } from './DefaultRenderTrigger';\n\nimport {\n SelectInputOptionContentWithinTriggerContext,\n SelectInputTriggerButtonPropsContext,\n} from './SelectInput.contexts';\nimport { searchableString, sortByRelevance } from './SelectInput.utils';\nimport { SelectInputProps } from './SelectInput.types';\n\nconst noop = () => {};\n\n/**\n * SelectInput component allows users to select an option from a dropdown list.\n * Supports filtering, multiple selection, and customization.\n */\nexport function SelectInput<T = string, M extends boolean = false>({\n id: idProp,\n parentId,\n name,\n multiple,\n placeholder,\n autocomplete,\n items,\n defaultValue,\n value: controlledValue,\n compareValues,\n renderValue = String,\n renderFooter,\n renderTrigger = DefaultRenderTrigger,\n filterable,\n filterPlaceholder,\n sortFilteredOptions,\n disabled,\n size = 'md',\n className,\n UNSAFE_triggerButtonProps,\n triggerRef: externalTriggerRef,\n onFilterChange = noop,\n onChange,\n onOpen,\n onClose,\n onClear,\n}: SelectInputProps<T, M>) {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const id = idProp ?? inputAttributes.id;\n\n const [open, setOpen] = useState(false);\n\n const initialized = useRef(false);\n const handleClose = useEffectEvent(onClose ?? (() => {}));\n const handleOpen = useEffectEvent(onOpen ?? (() => {}));\n useEffect(() => {\n if (initialized.current) {\n if (open) {\n handleOpen?.();\n } else {\n handleClose?.();\n }\n } else {\n initialized.current = true;\n }\n }, [handleClose, handleOpen, open]);\n\n const [filterQuery, _setFilterQuery] = useState('');\n const deferredFilterQuery = useDeferredValue(filterQuery);\n const setFilterQuery = useEffectEvent((query: string) => {\n _setFilterQuery(query);\n if (query !== filterQuery) {\n onFilterChange({\n query,\n queryNormalized: query ? searchableString(query) : null,\n });\n }\n });\n\n const internalTriggerRef = useRef<HTMLButtonElement | null>(null);\n\n const screenSm = useScreenSize(Breakpoint.SMALL);\n const OptionsOverlay = screenSm ? SelectInputPopover : SelectInputBottomSheet;\n\n const searchInputRef = useRef<HTMLInputElement>(null);\n const listboxRef = useRef<HTMLDivElement>(null);\n const controllerRef = filterable ? searchInputRef : listboxRef;\n\n /**\n * Attempts to resolve the `listbox` label\n * @see https://storybook.wise.design/?path=/docs/forms-selectinput-accessibility--docs#labelling\n */\n const getListBoxLabelProps = (): {\n listBoxLabel?: string;\n listBoxLabelledBy?: string;\n } => {\n if (UNSAFE_triggerButtonProps?.['aria-label']) {\n return {\n listBoxLabel: UNSAFE_triggerButtonProps['aria-label'],\n };\n }\n\n if (UNSAFE_triggerButtonProps?.['aria-labelledby']) {\n return {\n listBoxLabelledBy: UNSAFE_triggerButtonProps['aria-labelledby'],\n };\n }\n\n if (inputAttributes['aria-labelledby']) {\n return {\n listBoxLabelledBy: inputAttributes['aria-labelledby'],\n };\n }\n\n return {};\n };\n\n return (\n <ListboxBase\n name={name}\n multiple={multiple}\n defaultValue={defaultValue as M extends true ? T[] : T}\n value={controlledValue as M extends true ? T[] : T}\n by={compareValues}\n disabled={disabled}\n onChange={\n ((value) => {\n if (!multiple) {\n setOpen(false);\n }\n onChange?.(value);\n }) satisfies SelectInputProps<T, M>['onChange']\n }\n >\n {({ disabled: uiDisabled, value }) => {\n const placeholderShown =\n multiple && Array.isArray(value) ? value.length === 0 : value == null;\n return (\n <OptionsOverlay\n placement=\"bottom-start\"\n open={open}\n renderTrigger={({ ref, getInteractionProps }) => (\n <SelectInputTriggerButtonPropsContext.Provider\n // eslint-disable-next-line react/jsx-no-constructed-context-values\n value={{\n ref: (node) => {\n ref(node);\n if (externalTriggerRef) {\n // eslint-disable-next-line no-param-reassign\n externalTriggerRef.current = node;\n } else {\n internalTriggerRef.current = node;\n }\n },\n size,\n ...inputAttributes,\n ...UNSAFE_triggerButtonProps,\n id,\n ...mergeProps(\n {\n onClick: () => {\n setOpen((prev) => !prev);\n },\n onKeyDown: (event: React.KeyboardEvent) => {\n if (\n event.key === ' ' ||\n event.key === 'Enter' ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n setOpen((prev) => !prev);\n }\n },\n },\n getInteractionProps(),\n ),\n }}\n >\n {renderTrigger({\n content: !placeholderShown ? (\n <SelectInputOptionContentWithinTriggerContext.Provider value>\n {multiple && Array.isArray(value)\n ? (value as readonly NonNullable<T>[])\n .map((option) => renderValue(option, true))\n .filter((node) => node != null)\n .join(', ')\n : renderValue(value as NonNullable<T>, true)}\n </SelectInputOptionContentWithinTriggerContext.Provider>\n ) : (\n placeholder\n ),\n placeholderShown,\n clear:\n onClear != null\n ? () => {\n onClear();\n (externalTriggerRef?.current ?? internalTriggerRef.current)?.focus({\n preventScroll: true,\n });\n }\n : undefined,\n disabled: uiDisabled,\n size,\n className,\n })}\n </SelectInputTriggerButtonPropsContext.Provider>\n )}\n initialFocusRef={controllerRef}\n size={filterable ? 'lg' : 'md'}\n padding=\"none\"\n onClose={() => {\n setOpen(false);\n }}\n onCloseEnd={() => {\n setFilterQuery('');\n }}\n >\n <SelectInputOptions\n id={id ? `${id}Search` : undefined}\n parentId={parentId}\n items={items}\n compareValues={compareValues}\n renderValue={renderValue}\n renderFooter={renderFooter}\n filterable={filterable}\n filterPlaceholder={filterPlaceholder}\n sortFilteredOptions={sortFilteredOptions}\n searchInputRef={searchInputRef}\n listboxRef={listboxRef}\n filterQuery={deferredFilterQuery}\n autocomplete={autocomplete}\n name={name}\n onFilterChange={setFilterQuery}\n onAutocompleteSelect={(matchedValue) => {\n onChange?.(matchedValue as M extends true ? T[] : T);\n if (!multiple) {\n setOpen(false);\n }\n }}\n {...getListBoxLabelProps()}\n />\n </OptionsOverlay>\n );\n }}\n </ListboxBase>\n );\n}\n\n// Attach sortByRelevance to the component for convenience\nSelectInput.sortByRelevance = sortByRelevance;\n"],"names":["noop","SelectInput","id","idProp","parentId","name","multiple","placeholder","autocomplete","items","defaultValue","value","controlledValue","compareValues","renderValue","String","renderFooter","renderTrigger","DefaultRenderTrigger","filterable","filterPlaceholder","sortFilteredOptions","disabled","size","className","UNSAFE_triggerButtonProps","triggerRef","externalTriggerRef","onFilterChange","onChange","onOpen","onClose","onClear","inputAttributes","useInputAttributes","nonLabelable","open","setOpen","useState","initialized","useRef","handleClose","useEffectEvent","handleOpen","useEffect","current","filterQuery","_setFilterQuery","deferredFilterQuery","useDeferredValue","setFilterQuery","query","queryNormalized","searchableString","internalTriggerRef","screenSm","useScreenSize","Breakpoint","SMALL","OptionsOverlay","SelectInputPopover","SelectInputBottomSheet","searchInputRef","listboxRef","controllerRef","getListBoxLabelProps","listBoxLabel","listBoxLabelledBy","_jsx","ListboxBase","by","children","uiDisabled","placeholderShown","Array","isArray","length","placement","ref","getInteractionProps","SelectInputTriggerButtonPropsContext","Provider","node","mergeProps","onClick","prev","onKeyDown","event","key","content","SelectInputOptionContentWithinTriggerContext","map","option","filter","join","clear","focus","preventScroll","undefined","initialFocusRef","padding","onCloseEnd","SelectInputOptions","onAutocompleteSelect","matchedValue","sortByRelevance"],"mappings":"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"}
1
+ {"version":3,"file":"SelectInput.mjs","sources":["../../../src/inputs/SelectInput/SelectInput.tsx"],"sourcesContent":["import mergeProps from 'merge-props';\nimport { useCallback, useEffect, useRef, useState, useDeferredValue } from 'react';\nimport { Listbox as ListboxBase } from '@headlessui/react';\nimport { useScreenSize } from '../../common/hooks/useScreenSize';\nimport { Breakpoint } from '../../common/propsValues/breakpoint';\nimport { useEffectEvent } from '../../common/hooks/useEffectEvent';\nimport { useInputAttributes } from '../contexts';\n\nimport { SelectInputBottomSheet } from './BottomSheet';\nimport { SelectInputPopover } from './Popover';\nimport { SelectInputOptions } from './Options';\nimport { DefaultRenderTrigger } from './DefaultRenderTrigger';\n\nimport {\n SelectInputOptionContentWithinTriggerContext,\n SelectInputTriggerButtonPropsContext,\n} from './SelectInput.contexts';\nimport { searchableString, sortByRelevance } from './SelectInput.utils';\nimport { SelectInputProps } from './SelectInput.types';\n\nconst noop = () => {};\n\n/**\n * SelectInput component allows users to select an option from a dropdown list.\n * Supports filtering, multiple selection, and customization.\n */\nexport function SelectInput<T = string, M extends boolean = false>({\n id: idProp,\n parentId,\n name,\n multiple,\n placeholder,\n autocomplete,\n items,\n defaultValue,\n value: controlledValue,\n compareValues,\n renderValue = String,\n renderFooter,\n renderTrigger = DefaultRenderTrigger,\n filterable,\n filterPlaceholder,\n sortFilteredOptions,\n disabled,\n size = 'md',\n className,\n UNSAFE_triggerButtonProps,\n triggerRef: externalTriggerRef,\n onFilterChange = noop,\n onChange,\n onOpen,\n onClose,\n onClear,\n}: SelectInputProps<T, M>) {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const id = idProp ?? inputAttributes.id;\n\n const [open, setOpen] = useState(false);\n\n const initialized = useRef(false);\n const handleClose = useEffectEvent(onClose ?? (() => {}));\n const handleOpen = useEffectEvent(onOpen ?? (() => {}));\n\n useEffect(() => {\n if (initialized.current) {\n if (open) {\n handleOpen?.();\n } else {\n handleClose?.();\n }\n } else {\n initialized.current = true;\n }\n }, [open]);\n\n const [filterQuery, _setFilterQuery] = useState('');\n const deferredFilterQuery = useDeferredValue(filterQuery);\n const previousFilterQueryRef = useRef(filterQuery);\n\n const setFilterQuery = useCallback(\n (query: string) => {\n _setFilterQuery(query);\n if (query !== previousFilterQueryRef.current) {\n onFilterChange({\n query,\n queryNormalized: query ? searchableString(query) : null,\n });\n previousFilterQueryRef.current = query;\n }\n },\n [onFilterChange],\n );\n\n const internalTriggerRef = useRef<HTMLButtonElement | null>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const listboxRef = useRef<HTMLDivElement>(null);\n const controllerRef = filterable ? searchInputRef : listboxRef;\n\n const screenSm = useScreenSize(Breakpoint.SMALL);\n const OptionsOverlay = screenSm ? SelectInputPopover : SelectInputBottomSheet;\n\n /**\n * Attempts to resolve the `listbox` label\n * @see https://storybook.wise.design/?path=/docs/forms-selectinput-accessibility--docs#labelling\n */\n const getListBoxLabelProps = (): {\n listBoxLabel?: string;\n listBoxLabelledBy?: string;\n } => {\n if (UNSAFE_triggerButtonProps?.['aria-label']) {\n return {\n listBoxLabel: UNSAFE_triggerButtonProps['aria-label'],\n };\n }\n\n if (UNSAFE_triggerButtonProps?.['aria-labelledby']) {\n return {\n listBoxLabelledBy: UNSAFE_triggerButtonProps['aria-labelledby'],\n };\n }\n\n if (inputAttributes['aria-labelledby']) {\n return {\n listBoxLabelledBy: inputAttributes['aria-labelledby'],\n };\n }\n\n return {};\n };\n\n return (\n <ListboxBase\n name={name}\n multiple={multiple}\n defaultValue={defaultValue as M extends true ? T[] : T}\n value={controlledValue as M extends true ? T[] : T}\n by={compareValues}\n disabled={disabled}\n onChange={\n ((value) => {\n if (!multiple) {\n setOpen(false);\n }\n onChange?.(value);\n }) satisfies SelectInputProps<T, M>['onChange']\n }\n >\n {({ disabled: uiDisabled, value }) => {\n const placeholderShown =\n multiple && Array.isArray(value) ? value.length === 0 : value == null;\n return (\n <OptionsOverlay\n placement=\"bottom-start\"\n open={open}\n renderTrigger={({ ref, getInteractionProps }) => (\n <SelectInputTriggerButtonPropsContext.Provider\n // eslint-disable-next-line react/jsx-no-constructed-context-values\n value={{\n ref: (node) => {\n ref(node);\n if (externalTriggerRef) {\n // eslint-disable-next-line no-param-reassign\n externalTriggerRef.current = node;\n } else {\n internalTriggerRef.current = node;\n }\n },\n size,\n ...inputAttributes,\n ...UNSAFE_triggerButtonProps,\n id,\n ...mergeProps(\n {\n onClick: () => {\n setOpen((prev) => !prev);\n },\n onKeyDown: (event: React.KeyboardEvent) => {\n if (\n event.key === ' ' ||\n event.key === 'Enter' ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n setOpen((prev) => !prev);\n }\n },\n },\n getInteractionProps(),\n ),\n }}\n >\n {renderTrigger({\n content: !placeholderShown ? (\n <SelectInputOptionContentWithinTriggerContext.Provider value>\n {multiple && Array.isArray(value)\n ? (value as readonly NonNullable<T>[])\n .map((option) => renderValue(option, true))\n .filter((node) => node != null)\n .join(', ')\n : renderValue(value as NonNullable<T>, true)}\n </SelectInputOptionContentWithinTriggerContext.Provider>\n ) : (\n placeholder\n ),\n placeholderShown,\n clear:\n onClear != null\n ? () => {\n onClear();\n (externalTriggerRef?.current ?? internalTriggerRef.current)?.focus({\n preventScroll: true,\n });\n }\n : undefined,\n disabled: uiDisabled,\n size,\n className,\n })}\n </SelectInputTriggerButtonPropsContext.Provider>\n )}\n initialFocusRef={controllerRef}\n size={filterable ? 'lg' : 'md'}\n padding=\"none\"\n onClose={() => {\n setOpen(false);\n }}\n onCloseEnd={() => {\n setFilterQuery('');\n }}\n >\n <SelectInputOptions\n id={id ? `${id}Search` : undefined}\n parentId={parentId}\n items={items}\n compareValues={compareValues}\n renderValue={renderValue}\n renderFooter={renderFooter}\n filterable={filterable}\n filterPlaceholder={filterPlaceholder}\n sortFilteredOptions={sortFilteredOptions}\n searchInputRef={searchInputRef}\n listboxRef={listboxRef}\n filterQuery={deferredFilterQuery}\n autocomplete={autocomplete}\n name={name}\n onFilterChange={setFilterQuery}\n onAutocompleteSelect={(matchedValue) => {\n onChange?.(matchedValue as M extends true ? T[] : T);\n if (!multiple) {\n setOpen(false);\n }\n }}\n {...getListBoxLabelProps()}\n />\n </OptionsOverlay>\n );\n }}\n </ListboxBase>\n );\n}\n\n// Attach sortByRelevance to the component for convenience\nSelectInput.sortByRelevance = sortByRelevance;\n"],"names":["noop","SelectInput","id","idProp","parentId","name","multiple","placeholder","autocomplete","items","defaultValue","value","controlledValue","compareValues","renderValue","String","renderFooter","renderTrigger","DefaultRenderTrigger","filterable","filterPlaceholder","sortFilteredOptions","disabled","size","className","UNSAFE_triggerButtonProps","triggerRef","externalTriggerRef","onFilterChange","onChange","onOpen","onClose","onClear","inputAttributes","useInputAttributes","nonLabelable","open","setOpen","useState","initialized","useRef","handleClose","useEffectEvent","handleOpen","useEffect","current","filterQuery","_setFilterQuery","deferredFilterQuery","useDeferredValue","previousFilterQueryRef","setFilterQuery","useCallback","query","queryNormalized","searchableString","internalTriggerRef","searchInputRef","listboxRef","controllerRef","screenSm","useScreenSize","Breakpoint","SMALL","OptionsOverlay","SelectInputPopover","SelectInputBottomSheet","getListBoxLabelProps","listBoxLabel","listBoxLabelledBy","_jsx","ListboxBase","by","children","uiDisabled","placeholderShown","Array","isArray","length","placement","ref","getInteractionProps","SelectInputTriggerButtonPropsContext","Provider","node","mergeProps","onClick","prev","onKeyDown","event","key","content","SelectInputOptionContentWithinTriggerContext","map","option","filter","join","clear","focus","preventScroll","undefined","initialFocusRef","padding","onCloseEnd","SelectInputOptions","onAutocompleteSelect","matchedValue","sortByRelevance"],"mappings":";;;;;;;;;;;;;;;AAoBA,MAAMA,IAAI,GAAGA,MAAK,CAAE,CAAC;AAErB;;;AAGG;AACG,SAAUC,WAAWA,CAAwC;AACjEC,EAAAA,EAAE,EAAEC,MAAM;EACVC,QAAQ;EACRC,IAAI;EACJC,QAAQ;EACRC,WAAW;EACXC,YAAY;EACZC,KAAK;EACLC,YAAY;AACZC,EAAAA,KAAK,EAAEC,eAAe;EACtBC,aAAa;AACbC,EAAAA,WAAW,GAAGC,MAAM;EACpBC,YAAY;AACZC,EAAAA,aAAa,GAAGC,oBAAoB;EACpCC,UAAU;EACVC,iBAAiB;EACjBC,mBAAmB;EACnBC,QAAQ;AACRC,EAAAA,IAAI,GAAG,IAAI;EACXC,SAAS;EACTC,yBAAyB;AACzBC,EAAAA,UAAU,EAAEC,kBAAkB;AAC9BC,EAAAA,cAAc,GAAG5B,IAAI;EACrB6B,QAAQ;EACRC,MAAM;EACNC,OAAO;AACPC,EAAAA;AAAO,CACgB,EAAA;EACvB,MAAMC,eAAe,GAAGC,kBAAkB,CAAC;AAAEC,IAAAA,YAAY,EAAE;AAAI,GAAE,CAAC;AAClE,EAAA,MAAMjC,EAAE,GAAGC,MAAM,IAAI8B,eAAe,CAAC/B,EAAE;EAEvC,MAAM,CAACkC,IAAI,EAAEC,OAAO,CAAC,GAAGC,QAAQ,CAAC,KAAK,CAAC;AAEvC,EAAA,MAAMC,WAAW,GAAGC,MAAM,CAAC,KAAK,CAAC;EACjC,MAAMC,WAAW,GAAGC,cAAc,CAACX,OAAO,KAAK,MAAK,CAAE,CAAC,CAAC,CAAC;EACzD,MAAMY,UAAU,GAAGD,cAAc,CAACZ,MAAM,KAAK,MAAK,CAAE,CAAC,CAAC,CAAC;AAEvDc,EAAAA,SAAS,CAAC,MAAK;IACb,IAAIL,WAAW,CAACM,OAAO,EAAE;AACvB,MAAA,IAAIT,IAAI,EAAE;AACRO,QAAAA,UAAU,IAAI;AAChB,MAAA,CAAC,MAAM;AACLF,QAAAA,WAAW,IAAI;AACjB,MAAA;AACF,IAAA,CAAC,MAAM;MACLF,WAAW,CAACM,OAAO,GAAG,IAAI;AAC5B,IAAA;AACF,EAAA,CAAC,EAAE,CAACT,IAAI,CAAC,CAAC;EAEV,MAAM,CAACU,WAAW,EAAEC,eAAe,CAAC,GAAGT,QAAQ,CAAC,EAAE,CAAC;AACnD,EAAA,MAAMU,mBAAmB,GAAGC,gBAAgB,CAACH,WAAW,CAAC;AACzD,EAAA,MAAMI,sBAAsB,GAAGV,MAAM,CAACM,WAAW,CAAC;AAElD,EAAA,MAAMK,cAAc,GAAGC,WAAW,CAC/BC,KAAa,IAAI;IAChBN,eAAe,CAACM,KAAK,CAAC;AACtB,IAAA,IAAIA,KAAK,KAAKH,sBAAsB,CAACL,OAAO,EAAE;AAC5CjB,MAAAA,cAAc,CAAC;QACbyB,KAAK;AACLC,QAAAA,eAAe,EAAED,KAAK,GAAGE,gBAAgB,CAACF,KAAK,CAAC,GAAG;AACpD,OAAA,CAAC;MACFH,sBAAsB,CAACL,OAAO,GAAGQ,KAAK;AACxC,IAAA;AACF,EAAA,CAAC,EACD,CAACzB,cAAc,CAAC,CACjB;AAED,EAAA,MAAM4B,kBAAkB,GAAGhB,MAAM,CAA2B,IAAI,CAAC;AACjE,EAAA,MAAMiB,cAAc,GAAGjB,MAAM,CAAmB,IAAI,CAAC;AACrD,EAAA,MAAMkB,UAAU,GAAGlB,MAAM,CAAiB,IAAI,CAAC;AAC/C,EAAA,MAAMmB,aAAa,GAAGxC,UAAU,GAAGsC,cAAc,GAAGC,UAAU;AAE9D,EAAA,MAAME,QAAQ,GAAGC,aAAa,CAACC,UAAU,CAACC,KAAK,CAAC;AAChD,EAAA,MAAMC,cAAc,GAAGJ,QAAQ,GAAGK,kBAAkB,GAAGC,sBAAsB;AAE7E;;;AAGG;EACH,MAAMC,oBAAoB,GAAGA,MAGzB;AACF,IAAA,IAAI1C,yBAAyB,GAAG,YAAY,CAAC,EAAE;MAC7C,OAAO;QACL2C,YAAY,EAAE3C,yBAAyB,CAAC,YAAY;OACrD;AACH,IAAA;AAEA,IAAA,IAAIA,yBAAyB,GAAG,iBAAiB,CAAC,EAAE;MAClD,OAAO;QACL4C,iBAAiB,EAAE5C,yBAAyB,CAAC,iBAAiB;OAC/D;AACH,IAAA;AAEA,IAAA,IAAIQ,eAAe,CAAC,iBAAiB,CAAC,EAAE;MACtC,OAAO;QACLoC,iBAAiB,EAAEpC,eAAe,CAAC,iBAAiB;OACrD;AACH,IAAA;AAEA,IAAA,OAAO,EAAE;EACX,CAAC;EAED,oBACEqC,GAAA,CAACC,OAAW,EAAA;AACVlE,IAAAA,IAAI,EAAEA,IAAK;AACXC,IAAAA,QAAQ,EAAEA,QAAS;AACnBI,IAAAA,YAAY,EAAEA,YAAyC;AACvDC,IAAAA,KAAK,EAAEC,eAA4C;AACnD4D,IAAAA,EAAE,EAAE3D,aAAc;AAClBS,IAAAA,QAAQ,EAAEA,QAAS;IACnBO,QAAQ,EACJlB,KAAK,IAAI;MACT,IAAI,CAACL,QAAQ,EAAE;QACb+B,OAAO,CAAC,KAAK,CAAC;AAChB,MAAA;MACAR,QAAQ,GAAGlB,KAAK,CAAC;IACnB,CACD;AAAA8D,IAAAA,QAAA,EAEAA,CAAC;AAAEnD,MAAAA,QAAQ,EAAEoD,UAAU;AAAE/D,MAAAA;AAAK,KAAE,KAAI;AACnC,MAAA,MAAMgE,gBAAgB,GACpBrE,QAAQ,IAAIsE,KAAK,CAACC,OAAO,CAAClE,KAAK,CAAC,GAAGA,KAAK,CAACmE,MAAM,KAAK,CAAC,GAAGnE,KAAK,IAAI,IAAI;MACvE,oBACE2D,GAAA,CAACN,cAAc,EAAA;AACbe,QAAAA,SAAS,EAAC,cAAc;AACxB3C,QAAAA,IAAI,EAAEA,IAAK;AACXnB,QAAAA,aAAa,EAAEA,CAAC;UAAE+D,GAAG;AAAEC,UAAAA;AAAmB,SAAE,kBAC1CX,GAAA,CAACY,oCAAoC,CAACC,QAAQ,EAAA;AAC5C;AACAxE,UAAAA,KAAK,EAAE;YACLqE,GAAG,EAAGI,IAAI,IAAI;cACZJ,GAAG,CAACI,IAAI,CAAC;AACT,cAAA,IAAIzD,kBAAkB,EAAE;AACtB;gBACAA,kBAAkB,CAACkB,OAAO,GAAGuC,IAAI;AACnC,cAAA,CAAC,MAAM;gBACL5B,kBAAkB,CAACX,OAAO,GAAGuC,IAAI;AACnC,cAAA;YACF,CAAC;YACD7D,IAAI;AACJ,YAAA,GAAGU,eAAe;AAClB,YAAA,GAAGR,yBAAyB;YAC5BvB,EAAE;AACF,YAAA,GAAGmF,UAAU,CACX;cACEC,OAAO,EAAEA,MAAK;AACZjD,gBAAAA,OAAO,CAAEkD,IAAI,IAAK,CAACA,IAAI,CAAC;cAC1B,CAAC;cACDC,SAAS,EAAGC,KAA0B,IAAI;gBACxC,IACEA,KAAK,CAACC,GAAG,KAAK,GAAG,IACjBD,KAAK,CAACC,GAAG,KAAK,OAAO,IACrBD,KAAK,CAACC,GAAG,KAAK,WAAW,IACzBD,KAAK,CAACC,GAAG,KAAK,SAAS,EACvB;AACArD,kBAAAA,OAAO,CAAEkD,IAAI,IAAK,CAACA,IAAI,CAAC;AAC1B,gBAAA;AACF,cAAA;aACD,EACDN,mBAAmB,EAAE;WAEvB;UAAAR,QAAA,EAEDxD,aAAa,CAAC;YACb0E,OAAO,EAAE,CAAChB,gBAAgB,gBACxBL,GAAA,CAACsB,4CAA4C,CAACT,QAAQ,EAAA;cAACxE,KAAK,EAAA,IAAA;AAAA8D,cAAAA,QAAA,EACzDnE,QAAQ,IAAIsE,KAAK,CAACC,OAAO,CAAClE,KAAK,CAAC,GAC5BA,KAAmC,CACjCkF,GAAG,CAAEC,MAAM,IAAKhF,WAAW,CAACgF,MAAM,EAAE,IAAI,CAAC,CAAC,CAC1CC,MAAM,CAAEX,IAAI,IAAKA,IAAI,IAAI,IAAI,CAAC,CAC9BY,IAAI,CAAC,IAAI,CAAC,GACblF,WAAW,CAACH,KAAuB,EAAE,IAAI;aACQ,CAAC,GAExDJ,WACD;YACDoE,gBAAgB;AAChBsB,YAAAA,KAAK,EACHjE,OAAO,IAAI,IAAI,GACX,MAAK;AACHA,cAAAA,OAAO,EAAE;cACT,CAACL,kBAAkB,EAAEkB,OAAO,IAAIW,kBAAkB,CAACX,OAAO,GAAGqD,KAAK,CAAC;AACjEC,gBAAAA,aAAa,EAAE;AAChB,eAAA,CAAC;AACJ,YAAA,CAAC,GACDC,SAAS;AACf9E,YAAAA,QAAQ,EAAEoD,UAAU;YACpBnD,IAAI;AACJC,YAAAA;WACD;AAAC,SAC2C,CAC/C;AACF6E,QAAAA,eAAe,EAAE1C,aAAc;AAC/BpC,QAAAA,IAAI,EAAEJ,UAAU,GAAG,IAAI,GAAG,IAAK;AAC/BmF,QAAAA,OAAO,EAAC,MAAM;QACdvE,OAAO,EAAEA,MAAK;UACZM,OAAO,CAAC,KAAK,CAAC;QAChB,CAAE;QACFkE,UAAU,EAAEA,MAAK;UACfpD,cAAc,CAAC,EAAE,CAAC;QACpB,CAAE;QAAAsB,QAAA,eAEFH,GAAA,CAACkC,kBAAkB,EAAA;AACjBtG,UAAAA,EAAE,EAAEA,EAAE,GAAG,GAAGA,EAAE,CAAA,MAAA,CAAQ,GAAGkG,SAAU;AACnChG,UAAAA,QAAQ,EAAEA,QAAS;AACnBK,UAAAA,KAAK,EAAEA,KAAM;AACbI,UAAAA,aAAa,EAAEA,aAAc;AAC7BC,UAAAA,WAAW,EAAEA,WAAY;AACzBE,UAAAA,YAAY,EAAEA,YAAa;AAC3BG,UAAAA,UAAU,EAAEA,UAAW;AACvBC,UAAAA,iBAAiB,EAAEA,iBAAkB;AACrCC,UAAAA,mBAAmB,EAAEA,mBAAoB;AACzCoC,UAAAA,cAAc,EAAEA,cAAe;AAC/BC,UAAAA,UAAU,EAAEA,UAAW;AACvBZ,UAAAA,WAAW,EAAEE,mBAAoB;AACjCxC,UAAAA,YAAY,EAAEA,YAAa;AAC3BH,UAAAA,IAAI,EAAEA,IAAK;AACXuB,UAAAA,cAAc,EAAEuB,cAAe;UAC/BsD,oBAAoB,EAAGC,YAAY,IAAI;YACrC7E,QAAQ,GAAG6E,YAAwC,CAAC;YACpD,IAAI,CAACpG,QAAQ,EAAE;cACb+B,OAAO,CAAC,KAAK,CAAC;AAChB,YAAA;UACF,CAAE;AAAA,UAAA,GACE8B,oBAAoB;SAAG;AAE/B,OAAgB,CAAC;AAErB,IAAA;AAAC,GACU,CAAC;AAElB;AAEA;AACAlE,WAAW,CAAC0G,eAAe,GAAGA,eAAe;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectInputTriggerButton.js","sources":["../../../../src/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx"],"sourcesContent":["import { ListboxButton } from '@headlessui/react';\nimport mergeProps from 'merge-props';\nimport { useContext } from 'react';\nimport { PolymorphicWithOverrides } from '../../../common/polymorphicWithOverrides/PolymorphicWithOverrides';\nimport { Merge } from '../../../utils';\nimport { SelectInputTriggerButtonPropsContext } from '../SelectInput.contexts';\n\nexport type SelectInputTriggerButtonElementType = 'button' | React.ComponentType;\n\nexport type SelectInputTriggerButtonProps<\n T extends SelectInputTriggerButtonElementType = 'button',\n> = Merge<React.ComponentPropsWithoutRef<T>, { as?: T }>;\n\n/**\n * The trigger button component for SelectInput.\n * Uses Headless UI's ListboxButton with polymorphic support to allow\n * rendering as different element types.\n */\nexport function SelectInputTriggerButton<T extends SelectInputTriggerButtonElementType = 'button'>({\n as = 'button' as T,\n ...restProps\n}: SelectInputTriggerButtonProps<T>) {\n const { ref, onClick, onKeyDown, size, ...interactionProps } = useContext(\n SelectInputTriggerButtonPropsContext,\n );\n\n return (\n <ListboxButton\n ref={ref}\n as={PolymorphicWithOverrides}\n role=\"combobox\"\n __overrides={{ as, size, ...interactionProps } as Record<string, unknown>}\n {...mergeProps({ onClick, onKeyDown }, restProps)}\n />\n );\n}\n"],"names":["SelectInputTriggerButton","as","restProps","ref","onClick","onKeyDown","size","interactionProps","useContext","SelectInputTriggerButtonPropsContext","_jsx","ListboxButton","PolymorphicWithOverrides","role","__overrides","mergeProps"],"mappings":";;;;;;;;;;;;;AAkBM,SAAUA,wBAAwBA,CAA2D;AACjGC,EAAAA,EAAE,GAAG,QAAa;EAClB,GAAGC;AAAS,CACqB,EAAA;EACjC,MAAM;IAAEC,GAAG;IAAEC,OAAO;IAAEC,SAAS;IAAEC,IAAI;IAAE,GAAGC;AAAgB,GAAE,GAAGC,gBAAU,CACvEC,yDAAoC,CACrC;EAED,oBACEC,cAAA,CAACC,mBAAa,EAAA;AACZR,IAAAA,GAAG,EAAEA,GAAI;AACTF,IAAAA,EAAE,EAAEW,iDAAyB;AAC7BC,IAAAA,IAAI,EAAC,UAAU;AACfC,IAAAA,WAAW,EAAE;MAAEb,EAAE;MAAEK,IAAI;MAAE,GAAGC;KAA8C;AAAA,IAAA,GACtEQ,2BAAU,CAAC;MAAEX,OAAO;AAAEC,MAAAA;AAAS,KAAE,EAAEH,SAAS;AAAC,GAAC,CAClD;AAEN;;;;"}
1
+ {"version":3,"file":"SelectInputTriggerButton.js","sources":["../../../../src/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx"],"sourcesContent":["import { ListboxButton } from '@headlessui/react';\nimport mergeProps from 'merge-props';\nimport { useContext } from 'react';\nimport { PolymorphicWithOverrides } from '../../../common/polymorphicWithOverrides/PolymorphicWithOverrides';\nimport { Merge } from '../../../utils';\nimport { SelectInputTriggerButtonPropsContext } from '../SelectInput.contexts';\n\nexport type SelectInputTriggerButtonElementType = 'button' | React.ComponentType;\n\nexport type SelectInputTriggerButtonProps<\n T extends SelectInputTriggerButtonElementType = 'button',\n> = Merge<React.ComponentPropsWithoutRef<T>, { as?: T }>;\n\n/**\n * The trigger button component for SelectInput.\n * Uses Headless UI's ListboxButton with polymorphic support to allow\n * rendering as different element types.\n */\nexport function SelectInputTriggerButton<T extends SelectInputTriggerButtonElementType = 'button'>({\n as = 'button' as T,\n ...restProps\n}: SelectInputTriggerButtonProps<T>) {\n const { ref, onClick, onKeyDown, size, ...interactionProps } = useContext(\n SelectInputTriggerButtonPropsContext,\n );\n\n return (\n <ListboxButton\n ref={ref}\n as={PolymorphicWithOverrides}\n role=\"combobox\"\n __overrides={{ as, size, ...interactionProps }}\n {...mergeProps({ onClick, onKeyDown }, restProps)}\n />\n );\n}\n"],"names":["SelectInputTriggerButton","as","restProps","ref","onClick","onKeyDown","size","interactionProps","useContext","SelectInputTriggerButtonPropsContext","_jsx","ListboxButton","PolymorphicWithOverrides","role","__overrides","mergeProps"],"mappings":";;;;;;;;;;;;;AAkBM,SAAUA,wBAAwBA,CAA2D;AACjGC,EAAAA,EAAE,GAAG,QAAa;EAClB,GAAGC;AAAS,CACqB,EAAA;EACjC,MAAM;IAAEC,GAAG;IAAEC,OAAO;IAAEC,SAAS;IAAEC,IAAI;IAAE,GAAGC;AAAgB,GAAE,GAAGC,gBAAU,CACvEC,yDAAoC,CACrC;EAED,oBACEC,cAAA,CAACC,mBAAa,EAAA;AACZR,IAAAA,GAAG,EAAEA,GAAI;AACTF,IAAAA,EAAE,EAAEW,iDAAyB;AAC7BC,IAAAA,IAAI,EAAC,UAAU;AACfC,IAAAA,WAAW,EAAE;MAAEb,EAAE;MAAEK,IAAI;MAAE,GAAGC;KAAmB;AAAA,IAAA,GAC3CQ,2BAAU,CAAC;MAAEX,OAAO;AAAEC,MAAAA;AAAS,KAAE,EAAEH,SAAS;AAAC,GAAC,CAClD;AAEN;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectInputTriggerButton.mjs","sources":["../../../../src/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx"],"sourcesContent":["import { ListboxButton } from '@headlessui/react';\nimport mergeProps from 'merge-props';\nimport { useContext } from 'react';\nimport { PolymorphicWithOverrides } from '../../../common/polymorphicWithOverrides/PolymorphicWithOverrides';\nimport { Merge } from '../../../utils';\nimport { SelectInputTriggerButtonPropsContext } from '../SelectInput.contexts';\n\nexport type SelectInputTriggerButtonElementType = 'button' | React.ComponentType;\n\nexport type SelectInputTriggerButtonProps<\n T extends SelectInputTriggerButtonElementType = 'button',\n> = Merge<React.ComponentPropsWithoutRef<T>, { as?: T }>;\n\n/**\n * The trigger button component for SelectInput.\n * Uses Headless UI's ListboxButton with polymorphic support to allow\n * rendering as different element types.\n */\nexport function SelectInputTriggerButton<T extends SelectInputTriggerButtonElementType = 'button'>({\n as = 'button' as T,\n ...restProps\n}: SelectInputTriggerButtonProps<T>) {\n const { ref, onClick, onKeyDown, size, ...interactionProps } = useContext(\n SelectInputTriggerButtonPropsContext,\n );\n\n return (\n <ListboxButton\n ref={ref}\n as={PolymorphicWithOverrides}\n role=\"combobox\"\n __overrides={{ as, size, ...interactionProps } as Record<string, unknown>}\n {...mergeProps({ onClick, onKeyDown }, restProps)}\n />\n );\n}\n"],"names":["SelectInputTriggerButton","as","restProps","ref","onClick","onKeyDown","size","interactionProps","useContext","SelectInputTriggerButtonPropsContext","_jsx","ListboxButton","PolymorphicWithOverrides","role","__overrides","mergeProps"],"mappings":";;;;;;;AAkBM,SAAUA,wBAAwBA,CAA2D;AACjGC,EAAAA,EAAE,GAAG,QAAa;EAClB,GAAGC;AAAS,CACqB,EAAA;EACjC,MAAM;IAAEC,GAAG;IAAEC,OAAO;IAAEC,SAAS;IAAEC,IAAI;IAAE,GAAGC;AAAgB,GAAE,GAAGC,UAAU,CACvEC,oCAAoC,CACrC;EAED,oBACEC,GAAA,CAACC,aAAa,EAAA;AACZR,IAAAA,GAAG,EAAEA,GAAI;AACTF,IAAAA,EAAE,EAAEW,wBAAyB;AAC7BC,IAAAA,IAAI,EAAC,UAAU;AACfC,IAAAA,WAAW,EAAE;MAAEb,EAAE;MAAEK,IAAI;MAAE,GAAGC;KAA8C;AAAA,IAAA,GACtEQ,UAAU,CAAC;MAAEX,OAAO;AAAEC,MAAAA;AAAS,KAAE,EAAEH,SAAS;AAAC,GAAC,CAClD;AAEN;;;;"}
1
+ {"version":3,"file":"SelectInputTriggerButton.mjs","sources":["../../../../src/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx"],"sourcesContent":["import { ListboxButton } from '@headlessui/react';\nimport mergeProps from 'merge-props';\nimport { useContext } from 'react';\nimport { PolymorphicWithOverrides } from '../../../common/polymorphicWithOverrides/PolymorphicWithOverrides';\nimport { Merge } from '../../../utils';\nimport { SelectInputTriggerButtonPropsContext } from '../SelectInput.contexts';\n\nexport type SelectInputTriggerButtonElementType = 'button' | React.ComponentType;\n\nexport type SelectInputTriggerButtonProps<\n T extends SelectInputTriggerButtonElementType = 'button',\n> = Merge<React.ComponentPropsWithoutRef<T>, { as?: T }>;\n\n/**\n * The trigger button component for SelectInput.\n * Uses Headless UI's ListboxButton with polymorphic support to allow\n * rendering as different element types.\n */\nexport function SelectInputTriggerButton<T extends SelectInputTriggerButtonElementType = 'button'>({\n as = 'button' as T,\n ...restProps\n}: SelectInputTriggerButtonProps<T>) {\n const { ref, onClick, onKeyDown, size, ...interactionProps } = useContext(\n SelectInputTriggerButtonPropsContext,\n );\n\n return (\n <ListboxButton\n ref={ref}\n as={PolymorphicWithOverrides}\n role=\"combobox\"\n __overrides={{ as, size, ...interactionProps }}\n {...mergeProps({ onClick, onKeyDown }, restProps)}\n />\n );\n}\n"],"names":["SelectInputTriggerButton","as","restProps","ref","onClick","onKeyDown","size","interactionProps","useContext","SelectInputTriggerButtonPropsContext","_jsx","ListboxButton","PolymorphicWithOverrides","role","__overrides","mergeProps"],"mappings":";;;;;;;AAkBM,SAAUA,wBAAwBA,CAA2D;AACjGC,EAAAA,EAAE,GAAG,QAAa;EAClB,GAAGC;AAAS,CACqB,EAAA;EACjC,MAAM;IAAEC,GAAG;IAAEC,OAAO;IAAEC,SAAS;IAAEC,IAAI;IAAE,GAAGC;AAAgB,GAAE,GAAGC,UAAU,CACvEC,oCAAoC,CACrC;EAED,oBACEC,GAAA,CAACC,aAAa,EAAA;AACZR,IAAAA,GAAG,EAAEA,GAAI;AACTF,IAAAA,EAAE,EAAEW,wBAAyB;AAC7BC,IAAAA,IAAI,EAAC,UAAU;AACfC,IAAAA,WAAW,EAAE;MAAEb,EAAE;MAAEK,IAAI;MAAE,GAAGC;KAAmB;AAAA,IAAA,GAC3CQ,UAAU,CAAC;MAAEX,OAAO;AAAEC,MAAAA;AAAS,KAAE,EAAEH,SAAS;AAAC,GAAC,CAClD;AAEN;;;;"}
@@ -8,12 +8,17 @@ var jsxRuntime = require('react/jsx-runtime');
8
8
 
9
9
  const TextArea = /*#__PURE__*/React.forwardRef(function TextArea({
10
10
  className,
11
+ maxLength,
11
12
  ...restProps
12
13
  }, reference) {
13
14
  const inputAttributes = contexts.useInputAttributes();
15
+ const value = restProps.value ?? restProps.defaultValue ?? '';
16
+ const currentLength = typeof value === 'string' ? value.length : String(value).length;
17
+ contexts.useTextareaCharacterCount(currentLength, maxLength);
14
18
  return /*#__PURE__*/jsxRuntime.jsx("textarea", {
15
19
  ref: reference,
16
20
  className: clsx.clsx(className, _common.inputClassNameBase(), 'np-text-area'),
21
+ maxLength: maxLength,
17
22
  ...inputAttributes,
18
23
  ...restProps
19
24
  });
@@ -1 +1 @@
1
- {"version":3,"file":"TextArea.js","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n"],"names":["TextArea","forwardRef","className","restProps","reference","inputAttributes","useInputAttributes","_jsx","ref","clsx","inputClassNameBase"],"mappings":";;;;;;;;MAcaA,QAAQ,gBAAGC,gBAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAE,GAAGC;AAAS,CAAiB,EAC1CC,SAAyD,EAAA;AAEzD,EAAA,MAAMC,eAAe,GAAGC,2BAAkB,EAAE;AAE5C,EAAA,oBACEC,cAAA,CAAA,UAAA,EAAA;AACEC,IAAAA,GAAG,EAAEJ,SAAU;IACfF,SAAS,EAAEO,SAAI,CAACP,SAAS,EAAEQ,0BAAkB,EAAE,EAAE,cAAc,CAAE;AAAA,IAAA,GAC7DL,eAAe;IAAA,GACfF;AAAS,GAAC,CACd;AAEN,CAAC;;;;"}
1
+ {"version":3,"file":"TextArea.js","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useTextareaCharacterCount, useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, maxLength, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n const value = restProps.value ?? restProps.defaultValue ?? '';\n const currentLength = typeof value === 'string' ? value.length : String(value).length;\n\n useTextareaCharacterCount(currentLength, maxLength);\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n maxLength={maxLength}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n"],"names":["TextArea","forwardRef","className","maxLength","restProps","reference","inputAttributes","useInputAttributes","value","defaultValue","currentLength","length","String","useTextareaCharacterCount","_jsx","ref","clsx","inputClassNameBase"],"mappings":";;;;;;;;MAcaA,QAAQ,gBAAGC,gBAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAEC,SAAS;EAAE,GAAGC;AAAS,CAAiB,EACrDC,SAAyD,EAAA;AAEzD,EAAA,MAAMC,eAAe,GAAGC,2BAAkB,EAAE;EAC5C,MAAMC,KAAK,GAAGJ,SAAS,CAACI,KAAK,IAAIJ,SAAS,CAACK,YAAY,IAAI,EAAE;AAC7D,EAAA,MAAMC,aAAa,GAAG,OAAOF,KAAK,KAAK,QAAQ,GAAGA,KAAK,CAACG,MAAM,GAAGC,MAAM,CAACJ,KAAK,CAAC,CAACG,MAAM;AAErFE,EAAAA,kCAAyB,CAACH,aAAa,EAAEP,SAAS,CAAC;AAEnD,EAAA,oBACEW,cAAA,CAAA,UAAA,EAAA;AACEC,IAAAA,GAAG,EAAEV,SAAU;IACfH,SAAS,EAAEc,SAAI,CAACd,SAAS,EAAEe,0BAAkB,EAAE,EAAE,cAAc,CAAE;AACjEd,IAAAA,SAAS,EAAEA,SAAU;AAAA,IAAA,GACjBG,eAAe;IAAA,GACfF;AAAS,GAAC,CACd;AAEN,CAAC;;;;"}
@@ -1,17 +1,22 @@
1
1
  import { clsx } from 'clsx';
2
2
  import { forwardRef } from 'react';
3
3
  import { inputClassNameBase } from './_common.mjs';
4
- import { useInputAttributes } from './contexts.mjs';
4
+ import { useInputAttributes, useTextareaCharacterCount } from './contexts.mjs';
5
5
  import { jsx } from 'react/jsx-runtime';
6
6
 
7
7
  const TextArea = /*#__PURE__*/forwardRef(function TextArea({
8
8
  className,
9
+ maxLength,
9
10
  ...restProps
10
11
  }, reference) {
11
12
  const inputAttributes = useInputAttributes();
13
+ const value = restProps.value ?? restProps.defaultValue ?? '';
14
+ const currentLength = typeof value === 'string' ? value.length : String(value).length;
15
+ useTextareaCharacterCount(currentLength, maxLength);
12
16
  return /*#__PURE__*/jsx("textarea", {
13
17
  ref: reference,
14
18
  className: clsx(className, inputClassNameBase(), 'np-text-area'),
19
+ maxLength: maxLength,
15
20
  ...inputAttributes,
16
21
  ...restProps
17
22
  });
@@ -1 +1 @@
1
- {"version":3,"file":"TextArea.mjs","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n"],"names":["TextArea","forwardRef","className","restProps","reference","inputAttributes","useInputAttributes","_jsx","ref","clsx","inputClassNameBase"],"mappings":";;;;;;MAcaA,QAAQ,gBAAGC,UAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAE,GAAGC;AAAS,CAAiB,EAC1CC,SAAyD,EAAA;AAEzD,EAAA,MAAMC,eAAe,GAAGC,kBAAkB,EAAE;AAE5C,EAAA,oBACEC,GAAA,CAAA,UAAA,EAAA;AACEC,IAAAA,GAAG,EAAEJ,SAAU;IACfF,SAAS,EAAEO,IAAI,CAACP,SAAS,EAAEQ,kBAAkB,EAAE,EAAE,cAAc,CAAE;AAAA,IAAA,GAC7DL,eAAe;IAAA,GACfF;AAAS,GAAC,CACd;AAEN,CAAC;;;;"}
1
+ {"version":3,"file":"TextArea.mjs","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useTextareaCharacterCount, useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, maxLength, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n const value = restProps.value ?? restProps.defaultValue ?? '';\n const currentLength = typeof value === 'string' ? value.length : String(value).length;\n\n useTextareaCharacterCount(currentLength, maxLength);\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n maxLength={maxLength}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n"],"names":["TextArea","forwardRef","className","maxLength","restProps","reference","inputAttributes","useInputAttributes","value","defaultValue","currentLength","length","String","useTextareaCharacterCount","_jsx","ref","clsx","inputClassNameBase"],"mappings":";;;;;;MAcaA,QAAQ,gBAAGC,UAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAEC,SAAS;EAAE,GAAGC;AAAS,CAAiB,EACrDC,SAAyD,EAAA;AAEzD,EAAA,MAAMC,eAAe,GAAGC,kBAAkB,EAAE;EAC5C,MAAMC,KAAK,GAAGJ,SAAS,CAACI,KAAK,IAAIJ,SAAS,CAACK,YAAY,IAAI,EAAE;AAC7D,EAAA,MAAMC,aAAa,GAAG,OAAOF,KAAK,KAAK,QAAQ,GAAGA,KAAK,CAACG,MAAM,GAAGC,MAAM,CAACJ,KAAK,CAAC,CAACG,MAAM;AAErFE,EAAAA,yBAAyB,CAACH,aAAa,EAAEP,SAAS,CAAC;AAEnD,EAAA,oBACEW,GAAA,CAAA,UAAA,EAAA;AACEC,IAAAA,GAAG,EAAEV,SAAU;IACfH,SAAS,EAAEc,IAAI,CAACd,SAAS,EAAEe,kBAAkB,EAAE,EAAE,cAAc,CAAE;AACjEd,IAAAA,SAAS,EAAEA,SAAU;AAAA,IAAA,GACjBG,eAAe;IAAA,GACfF;AAAS,GAAC,CACd;AAEN,CAAC;;;;"}
@@ -25,6 +25,20 @@ function useInputAttributes({
25
25
  function useFieldLabelRef() {
26
26
  return React.useContext(FieldLabelContext)?.ref;
27
27
  }
28
+ const TextareaCharacterCountContext = /*#__PURE__*/React.createContext(undefined);
29
+ const TextareaCharacterCountProvider = TextareaCharacterCountContext.Provider;
30
+ function useTextareaCharacterCount(current, max) {
31
+ const setCharacterCount = React.useContext(TextareaCharacterCountContext);
32
+ React.useEffect(() => {
33
+ if (setCharacterCount && max != null) {
34
+ setCharacterCount({
35
+ current,
36
+ max
37
+ });
38
+ return () => setCharacterCount(null);
39
+ }
40
+ }, [setCharacterCount, current, max]);
41
+ }
28
42
  function withInputAttributes(Component, args) {
29
43
  function ComponentWithInputAttributes(props) {
30
44
  return /*#__PURE__*/jsxRuntime.jsx(Component, {
@@ -40,7 +54,9 @@ exports.FieldLabelContextProvider = FieldLabelContextProvider;
40
54
  exports.InputDescribedByProvider = InputDescribedByProvider;
41
55
  exports.InputIdContextProvider = InputIdContextProvider;
42
56
  exports.InputInvalidProvider = InputInvalidProvider;
57
+ exports.TextareaCharacterCountProvider = TextareaCharacterCountProvider;
43
58
  exports.useFieldLabelRef = useFieldLabelRef;
44
59
  exports.useInputAttributes = useInputAttributes;
60
+ exports.useTextareaCharacterCount = useTextareaCharacterCount;
45
61
  exports.withInputAttributes = withInputAttributes;
46
62
  //# sourceMappingURL=contexts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"contexts.js","sources":["../../src/inputs/contexts.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\ntype FieldLabelContextType = {\n id?: string;\n ref?: React.RefObject<HTMLLabelElement>;\n};\n\nconst FieldLabelContext = createContext<FieldLabelContextType | undefined>(undefined);\nexport const FieldLabelContextProvider = FieldLabelContext.Provider;\n\nconst InputIdContext = createContext<string | undefined>(undefined);\nexport const InputIdContextProvider = InputIdContext.Provider;\n\nconst InputDescribedByContext = createContext<string | undefined>(undefined);\nexport const InputDescribedByProvider = InputDescribedByContext.Provider;\n\nconst InputInvalidContext = createContext<boolean | undefined>(undefined);\nexport const InputInvalidProvider = InputInvalidContext.Provider;\n\ninterface UseInputAttributesArgs {\n /** Set this to `true` if the underlying element is not directly [labelable as per the HTML specification](https://html.spec.whatwg.org/multipage/forms.html#category-label). */\n nonLabelable?: boolean;\n}\n\nexport function useInputAttributes({ nonLabelable }: UseInputAttributesArgs = {}) {\n const labelId = useContext(FieldLabelContext)?.id;\n return {\n id: useContext(InputIdContext),\n 'aria-labelledby': nonLabelable ? labelId : undefined,\n 'aria-describedby': useContext(InputDescribedByContext),\n 'aria-invalid': useContext(InputInvalidContext),\n } satisfies React.HTMLAttributes<HTMLElement>;\n}\n\nexport function useFieldLabelRef() {\n return useContext(FieldLabelContext)?.ref;\n}\n\nexport interface WithInputAttributesProps {\n inputAttributes: ReturnType<typeof useInputAttributes>;\n}\n\nexport function withInputAttributes<T extends Partial<WithInputAttributesProps>>(\n Component: React.ComponentType<T>,\n args?: UseInputAttributesArgs,\n) {\n function ComponentWithInputAttributes(props: Omit<T, keyof WithInputAttributesProps>) {\n return <Component inputAttributes={useInputAttributes(args)} {...(props as T)} />;\n }\n\n ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;\n\n return ComponentWithInputAttributes;\n}\n"],"names":["FieldLabelContext","createContext","undefined","FieldLabelContextProvider","Provider","InputIdContext","InputIdContextProvider","InputDescribedByContext","InputDescribedByProvider","InputInvalidContext","InputInvalidProvider","useInputAttributes","nonLabelable","labelId","useContext","id","useFieldLabelRef","ref","withInputAttributes","Component","args","ComponentWithInputAttributes","props","_jsx","inputAttributes","displayName","name"],"mappings":";;;;;AAOA,MAAMA,iBAAiB,gBAAGC,mBAAa,CAAoCC,SAAS,CAAC;AAC9E,MAAMC,yBAAyB,GAAGH,iBAAiB,CAACI;AAE3D,MAAMC,cAAc,gBAAGJ,mBAAa,CAAqBC,SAAS,CAAC;AAC5D,MAAMI,sBAAsB,GAAGD,cAAc,CAACD;AAErD,MAAMG,uBAAuB,gBAAGN,mBAAa,CAAqBC,SAAS,CAAC;AACrE,MAAMM,wBAAwB,GAAGD,uBAAuB,CAACH;AAEhE,MAAMK,mBAAmB,gBAAGR,mBAAa,CAAsBC,SAAS,CAAC;AAClE,MAAMQ,oBAAoB,GAAGD,mBAAmB,CAACL;SAOxCO,kBAAkBA,CAAC;AAAEC,EAAAA;IAAyC,EAAE,EAAA;AAC9E,EAAA,MAAMC,OAAO,GAAGC,gBAAU,CAACd,iBAAiB,CAAC,EAAEe,EAAE;EACjD,OAAO;AACLA,IAAAA,EAAE,EAAED,gBAAU,CAACT,cAAc,CAAC;AAC9B,IAAA,iBAAiB,EAAEO,YAAY,GAAGC,OAAO,GAAGX,SAAS;AACrD,IAAA,kBAAkB,EAAEY,gBAAU,CAACP,uBAAuB,CAAC;IACvD,cAAc,EAAEO,gBAAU,CAACL,mBAAmB;GACH;AAC/C;SAEgBO,gBAAgBA,GAAA;AAC9B,EAAA,OAAOF,gBAAU,CAACd,iBAAiB,CAAC,EAAEiB,GAAG;AAC3C;AAMM,SAAUC,mBAAmBA,CACjCC,SAAiC,EACjCC,IAA6B,EAAA;EAE7B,SAASC,4BAA4BA,CAACC,KAA8C,EAAA;IAClF,oBAAOC,cAAA,CAACJ,SAAS,EAAA;AAACK,MAAAA,eAAe,EAAEb,kBAAkB,CAACS,IAAI,CAAE;MAAA,GAAME;AAAW,MAAI;AACnF,EAAA;AAEAD,EAAAA,4BAA4B,CAACI,WAAW,GAAG,CAAA,oBAAA,EAAuBN,SAAS,CAACM,WAAW,IAAIN,SAAS,CAACO,IAAI,IAAI,WAAW,CAAA,CAAA,CAAG;AAE3H,EAAA,OAAOL,4BAA4B;AACrC;;;;;;;;;;"}
1
+ {"version":3,"file":"contexts.js","sources":["../../src/inputs/contexts.tsx"],"sourcesContent":["import { createContext, useContext, useEffect } from 'react';\n\ntype FieldLabelContextType = {\n id?: string;\n ref?: React.RefObject<HTMLLabelElement>;\n};\n\nconst FieldLabelContext = createContext<FieldLabelContextType | undefined>(undefined);\nexport const FieldLabelContextProvider = FieldLabelContext.Provider;\n\nconst InputIdContext = createContext<string | undefined>(undefined);\nexport const InputIdContextProvider = InputIdContext.Provider;\n\nconst InputDescribedByContext = createContext<string | undefined>(undefined);\nexport const InputDescribedByProvider = InputDescribedByContext.Provider;\n\nconst InputInvalidContext = createContext<boolean | undefined>(undefined);\nexport const InputInvalidProvider = InputInvalidContext.Provider;\n\ninterface UseInputAttributesArgs {\n /** Set this to `true` if the underlying element is not directly [labelable as per the HTML specification](https://html.spec.whatwg.org/multipage/forms.html#category-label). */\n nonLabelable?: boolean;\n}\n\nexport function useInputAttributes({ nonLabelable }: UseInputAttributesArgs = {}) {\n const labelId = useContext(FieldLabelContext)?.id;\n return {\n id: useContext(InputIdContext),\n 'aria-labelledby': nonLabelable ? labelId : undefined,\n 'aria-describedby': useContext(InputDescribedByContext),\n 'aria-invalid': useContext(InputInvalidContext),\n } satisfies React.HTMLAttributes<HTMLElement>;\n}\n\nexport function useFieldLabelRef() {\n return useContext(FieldLabelContext)?.ref;\n}\n\nexport type TextareaCharacterCountState = { current: number; max: number } | null;\n\nconst TextareaCharacterCountContext = createContext<\n ((state: TextareaCharacterCountState) => void) | undefined\n>(undefined);\nexport const TextareaCharacterCountProvider = TextareaCharacterCountContext.Provider;\n\nexport function useTextareaCharacterCount(current: number, max: number | undefined) {\n const setCharacterCount = useContext(TextareaCharacterCountContext);\n useEffect(() => {\n if (setCharacterCount && max != null) {\n setCharacterCount({ current, max });\n return () => setCharacterCount(null);\n }\n }, [setCharacterCount, current, max]);\n}\n\nexport interface WithInputAttributesProps {\n inputAttributes: ReturnType<typeof useInputAttributes>;\n}\n\nexport function withInputAttributes<T extends Partial<WithInputAttributesProps>>(\n Component: React.ComponentType<T>,\n args?: UseInputAttributesArgs,\n) {\n function ComponentWithInputAttributes(props: Omit<T, keyof WithInputAttributesProps>) {\n return <Component inputAttributes={useInputAttributes(args)} {...(props as T)} />;\n }\n\n ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;\n\n return ComponentWithInputAttributes;\n}\n"],"names":["FieldLabelContext","createContext","undefined","FieldLabelContextProvider","Provider","InputIdContext","InputIdContextProvider","InputDescribedByContext","InputDescribedByProvider","InputInvalidContext","InputInvalidProvider","useInputAttributes","nonLabelable","labelId","useContext","id","useFieldLabelRef","ref","TextareaCharacterCountContext","TextareaCharacterCountProvider","useTextareaCharacterCount","current","max","setCharacterCount","useEffect","withInputAttributes","Component","args","ComponentWithInputAttributes","props","_jsx","inputAttributes","displayName","name"],"mappings":";;;;;AAOA,MAAMA,iBAAiB,gBAAGC,mBAAa,CAAoCC,SAAS,CAAC;AAC9E,MAAMC,yBAAyB,GAAGH,iBAAiB,CAACI;AAE3D,MAAMC,cAAc,gBAAGJ,mBAAa,CAAqBC,SAAS,CAAC;AAC5D,MAAMI,sBAAsB,GAAGD,cAAc,CAACD;AAErD,MAAMG,uBAAuB,gBAAGN,mBAAa,CAAqBC,SAAS,CAAC;AACrE,MAAMM,wBAAwB,GAAGD,uBAAuB,CAACH;AAEhE,MAAMK,mBAAmB,gBAAGR,mBAAa,CAAsBC,SAAS,CAAC;AAClE,MAAMQ,oBAAoB,GAAGD,mBAAmB,CAACL;SAOxCO,kBAAkBA,CAAC;AAAEC,EAAAA;IAAyC,EAAE,EAAA;AAC9E,EAAA,MAAMC,OAAO,GAAGC,gBAAU,CAACd,iBAAiB,CAAC,EAAEe,EAAE;EACjD,OAAO;AACLA,IAAAA,EAAE,EAAED,gBAAU,CAACT,cAAc,CAAC;AAC9B,IAAA,iBAAiB,EAAEO,YAAY,GAAGC,OAAO,GAAGX,SAAS;AACrD,IAAA,kBAAkB,EAAEY,gBAAU,CAACP,uBAAuB,CAAC;IACvD,cAAc,EAAEO,gBAAU,CAACL,mBAAmB;GACH;AAC/C;SAEgBO,gBAAgBA,GAAA;AAC9B,EAAA,OAAOF,gBAAU,CAACd,iBAAiB,CAAC,EAAEiB,GAAG;AAC3C;AAIA,MAAMC,6BAA6B,gBAAGjB,mBAAa,CAEjDC,SAAS,CAAC;AACL,MAAMiB,8BAA8B,GAAGD,6BAA6B,CAACd;AAEtE,SAAUgB,yBAAyBA,CAACC,OAAe,EAAEC,GAAuB,EAAA;AAChF,EAAA,MAAMC,iBAAiB,GAAGT,gBAAU,CAACI,6BAA6B,CAAC;AACnEM,EAAAA,eAAS,CAAC,MAAK;AACb,IAAA,IAAID,iBAAiB,IAAID,GAAG,IAAI,IAAI,EAAE;AACpCC,MAAAA,iBAAiB,CAAC;QAAEF,OAAO;AAAEC,QAAAA;AAAG,OAAE,CAAC;AACnC,MAAA,OAAO,MAAMC,iBAAiB,CAAC,IAAI,CAAC;AACtC,IAAA;EACF,CAAC,EAAE,CAACA,iBAAiB,EAAEF,OAAO,EAAEC,GAAG,CAAC,CAAC;AACvC;AAMM,SAAUG,mBAAmBA,CACjCC,SAAiC,EACjCC,IAA6B,EAAA;EAE7B,SAASC,4BAA4BA,CAACC,KAA8C,EAAA;IAClF,oBAAOC,cAAA,CAACJ,SAAS,EAAA;AAACK,MAAAA,eAAe,EAAEpB,kBAAkB,CAACgB,IAAI,CAAE;MAAA,GAAME;AAAW,MAAI;AACnF,EAAA;AAEAD,EAAAA,4BAA4B,CAACI,WAAW,GAAG,CAAA,oBAAA,EAAuBN,SAAS,CAACM,WAAW,IAAIN,SAAS,CAACO,IAAI,IAAI,WAAW,CAAA,CAAA,CAAG;AAE3H,EAAA,OAAOL,4BAA4B;AACrC;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { createContext, useContext } from 'react';
1
+ import { createContext, useContext, useEffect } from 'react';
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
 
4
4
  const FieldLabelContext = /*#__PURE__*/createContext(undefined);
@@ -23,6 +23,20 @@ function useInputAttributes({
23
23
  function useFieldLabelRef() {
24
24
  return useContext(FieldLabelContext)?.ref;
25
25
  }
26
+ const TextareaCharacterCountContext = /*#__PURE__*/createContext(undefined);
27
+ const TextareaCharacterCountProvider = TextareaCharacterCountContext.Provider;
28
+ function useTextareaCharacterCount(current, max) {
29
+ const setCharacterCount = useContext(TextareaCharacterCountContext);
30
+ useEffect(() => {
31
+ if (setCharacterCount && max != null) {
32
+ setCharacterCount({
33
+ current,
34
+ max
35
+ });
36
+ return () => setCharacterCount(null);
37
+ }
38
+ }, [setCharacterCount, current, max]);
39
+ }
26
40
  function withInputAttributes(Component, args) {
27
41
  function ComponentWithInputAttributes(props) {
28
42
  return /*#__PURE__*/jsx(Component, {
@@ -34,5 +48,5 @@ function withInputAttributes(Component, args) {
34
48
  return ComponentWithInputAttributes;
35
49
  }
36
50
 
37
- export { FieldLabelContextProvider, InputDescribedByProvider, InputIdContextProvider, InputInvalidProvider, useFieldLabelRef, useInputAttributes, withInputAttributes };
51
+ export { FieldLabelContextProvider, InputDescribedByProvider, InputIdContextProvider, InputInvalidProvider, TextareaCharacterCountProvider, useFieldLabelRef, useInputAttributes, useTextareaCharacterCount, withInputAttributes };
38
52
  //# sourceMappingURL=contexts.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"contexts.mjs","sources":["../../src/inputs/contexts.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\ntype FieldLabelContextType = {\n id?: string;\n ref?: React.RefObject<HTMLLabelElement>;\n};\n\nconst FieldLabelContext = createContext<FieldLabelContextType | undefined>(undefined);\nexport const FieldLabelContextProvider = FieldLabelContext.Provider;\n\nconst InputIdContext = createContext<string | undefined>(undefined);\nexport const InputIdContextProvider = InputIdContext.Provider;\n\nconst InputDescribedByContext = createContext<string | undefined>(undefined);\nexport const InputDescribedByProvider = InputDescribedByContext.Provider;\n\nconst InputInvalidContext = createContext<boolean | undefined>(undefined);\nexport const InputInvalidProvider = InputInvalidContext.Provider;\n\ninterface UseInputAttributesArgs {\n /** Set this to `true` if the underlying element is not directly [labelable as per the HTML specification](https://html.spec.whatwg.org/multipage/forms.html#category-label). */\n nonLabelable?: boolean;\n}\n\nexport function useInputAttributes({ nonLabelable }: UseInputAttributesArgs = {}) {\n const labelId = useContext(FieldLabelContext)?.id;\n return {\n id: useContext(InputIdContext),\n 'aria-labelledby': nonLabelable ? labelId : undefined,\n 'aria-describedby': useContext(InputDescribedByContext),\n 'aria-invalid': useContext(InputInvalidContext),\n } satisfies React.HTMLAttributes<HTMLElement>;\n}\n\nexport function useFieldLabelRef() {\n return useContext(FieldLabelContext)?.ref;\n}\n\nexport interface WithInputAttributesProps {\n inputAttributes: ReturnType<typeof useInputAttributes>;\n}\n\nexport function withInputAttributes<T extends Partial<WithInputAttributesProps>>(\n Component: React.ComponentType<T>,\n args?: UseInputAttributesArgs,\n) {\n function ComponentWithInputAttributes(props: Omit<T, keyof WithInputAttributesProps>) {\n return <Component inputAttributes={useInputAttributes(args)} {...(props as T)} />;\n }\n\n ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;\n\n return ComponentWithInputAttributes;\n}\n"],"names":["FieldLabelContext","createContext","undefined","FieldLabelContextProvider","Provider","InputIdContext","InputIdContextProvider","InputDescribedByContext","InputDescribedByProvider","InputInvalidContext","InputInvalidProvider","useInputAttributes","nonLabelable","labelId","useContext","id","useFieldLabelRef","ref","withInputAttributes","Component","args","ComponentWithInputAttributes","props","_jsx","inputAttributes","displayName","name"],"mappings":";;;AAOA,MAAMA,iBAAiB,gBAAGC,aAAa,CAAoCC,SAAS,CAAC;AAC9E,MAAMC,yBAAyB,GAAGH,iBAAiB,CAACI;AAE3D,MAAMC,cAAc,gBAAGJ,aAAa,CAAqBC,SAAS,CAAC;AAC5D,MAAMI,sBAAsB,GAAGD,cAAc,CAACD;AAErD,MAAMG,uBAAuB,gBAAGN,aAAa,CAAqBC,SAAS,CAAC;AACrE,MAAMM,wBAAwB,GAAGD,uBAAuB,CAACH;AAEhE,MAAMK,mBAAmB,gBAAGR,aAAa,CAAsBC,SAAS,CAAC;AAClE,MAAMQ,oBAAoB,GAAGD,mBAAmB,CAACL;SAOxCO,kBAAkBA,CAAC;AAAEC,EAAAA;IAAyC,EAAE,EAAA;AAC9E,EAAA,MAAMC,OAAO,GAAGC,UAAU,CAACd,iBAAiB,CAAC,EAAEe,EAAE;EACjD,OAAO;AACLA,IAAAA,EAAE,EAAED,UAAU,CAACT,cAAc,CAAC;AAC9B,IAAA,iBAAiB,EAAEO,YAAY,GAAGC,OAAO,GAAGX,SAAS;AACrD,IAAA,kBAAkB,EAAEY,UAAU,CAACP,uBAAuB,CAAC;IACvD,cAAc,EAAEO,UAAU,CAACL,mBAAmB;GACH;AAC/C;SAEgBO,gBAAgBA,GAAA;AAC9B,EAAA,OAAOF,UAAU,CAACd,iBAAiB,CAAC,EAAEiB,GAAG;AAC3C;AAMM,SAAUC,mBAAmBA,CACjCC,SAAiC,EACjCC,IAA6B,EAAA;EAE7B,SAASC,4BAA4BA,CAACC,KAA8C,EAAA;IAClF,oBAAOC,GAAA,CAACJ,SAAS,EAAA;AAACK,MAAAA,eAAe,EAAEb,kBAAkB,CAACS,IAAI,CAAE;MAAA,GAAME;AAAW,MAAI;AACnF,EAAA;AAEAD,EAAAA,4BAA4B,CAACI,WAAW,GAAG,CAAA,oBAAA,EAAuBN,SAAS,CAACM,WAAW,IAAIN,SAAS,CAACO,IAAI,IAAI,WAAW,CAAA,CAAA,CAAG;AAE3H,EAAA,OAAOL,4BAA4B;AACrC;;;;"}
1
+ {"version":3,"file":"contexts.mjs","sources":["../../src/inputs/contexts.tsx"],"sourcesContent":["import { createContext, useContext, useEffect } from 'react';\n\ntype FieldLabelContextType = {\n id?: string;\n ref?: React.RefObject<HTMLLabelElement>;\n};\n\nconst FieldLabelContext = createContext<FieldLabelContextType | undefined>(undefined);\nexport const FieldLabelContextProvider = FieldLabelContext.Provider;\n\nconst InputIdContext = createContext<string | undefined>(undefined);\nexport const InputIdContextProvider = InputIdContext.Provider;\n\nconst InputDescribedByContext = createContext<string | undefined>(undefined);\nexport const InputDescribedByProvider = InputDescribedByContext.Provider;\n\nconst InputInvalidContext = createContext<boolean | undefined>(undefined);\nexport const InputInvalidProvider = InputInvalidContext.Provider;\n\ninterface UseInputAttributesArgs {\n /** Set this to `true` if the underlying element is not directly [labelable as per the HTML specification](https://html.spec.whatwg.org/multipage/forms.html#category-label). */\n nonLabelable?: boolean;\n}\n\nexport function useInputAttributes({ nonLabelable }: UseInputAttributesArgs = {}) {\n const labelId = useContext(FieldLabelContext)?.id;\n return {\n id: useContext(InputIdContext),\n 'aria-labelledby': nonLabelable ? labelId : undefined,\n 'aria-describedby': useContext(InputDescribedByContext),\n 'aria-invalid': useContext(InputInvalidContext),\n } satisfies React.HTMLAttributes<HTMLElement>;\n}\n\nexport function useFieldLabelRef() {\n return useContext(FieldLabelContext)?.ref;\n}\n\nexport type TextareaCharacterCountState = { current: number; max: number } | null;\n\nconst TextareaCharacterCountContext = createContext<\n ((state: TextareaCharacterCountState) => void) | undefined\n>(undefined);\nexport const TextareaCharacterCountProvider = TextareaCharacterCountContext.Provider;\n\nexport function useTextareaCharacterCount(current: number, max: number | undefined) {\n const setCharacterCount = useContext(TextareaCharacterCountContext);\n useEffect(() => {\n if (setCharacterCount && max != null) {\n setCharacterCount({ current, max });\n return () => setCharacterCount(null);\n }\n }, [setCharacterCount, current, max]);\n}\n\nexport interface WithInputAttributesProps {\n inputAttributes: ReturnType<typeof useInputAttributes>;\n}\n\nexport function withInputAttributes<T extends Partial<WithInputAttributesProps>>(\n Component: React.ComponentType<T>,\n args?: UseInputAttributesArgs,\n) {\n function ComponentWithInputAttributes(props: Omit<T, keyof WithInputAttributesProps>) {\n return <Component inputAttributes={useInputAttributes(args)} {...(props as T)} />;\n }\n\n ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;\n\n return ComponentWithInputAttributes;\n}\n"],"names":["FieldLabelContext","createContext","undefined","FieldLabelContextProvider","Provider","InputIdContext","InputIdContextProvider","InputDescribedByContext","InputDescribedByProvider","InputInvalidContext","InputInvalidProvider","useInputAttributes","nonLabelable","labelId","useContext","id","useFieldLabelRef","ref","TextareaCharacterCountContext","TextareaCharacterCountProvider","useTextareaCharacterCount","current","max","setCharacterCount","useEffect","withInputAttributes","Component","args","ComponentWithInputAttributes","props","_jsx","inputAttributes","displayName","name"],"mappings":";;;AAOA,MAAMA,iBAAiB,gBAAGC,aAAa,CAAoCC,SAAS,CAAC;AAC9E,MAAMC,yBAAyB,GAAGH,iBAAiB,CAACI;AAE3D,MAAMC,cAAc,gBAAGJ,aAAa,CAAqBC,SAAS,CAAC;AAC5D,MAAMI,sBAAsB,GAAGD,cAAc,CAACD;AAErD,MAAMG,uBAAuB,gBAAGN,aAAa,CAAqBC,SAAS,CAAC;AACrE,MAAMM,wBAAwB,GAAGD,uBAAuB,CAACH;AAEhE,MAAMK,mBAAmB,gBAAGR,aAAa,CAAsBC,SAAS,CAAC;AAClE,MAAMQ,oBAAoB,GAAGD,mBAAmB,CAACL;SAOxCO,kBAAkBA,CAAC;AAAEC,EAAAA;IAAyC,EAAE,EAAA;AAC9E,EAAA,MAAMC,OAAO,GAAGC,UAAU,CAACd,iBAAiB,CAAC,EAAEe,EAAE;EACjD,OAAO;AACLA,IAAAA,EAAE,EAAED,UAAU,CAACT,cAAc,CAAC;AAC9B,IAAA,iBAAiB,EAAEO,YAAY,GAAGC,OAAO,GAAGX,SAAS;AACrD,IAAA,kBAAkB,EAAEY,UAAU,CAACP,uBAAuB,CAAC;IACvD,cAAc,EAAEO,UAAU,CAACL,mBAAmB;GACH;AAC/C;SAEgBO,gBAAgBA,GAAA;AAC9B,EAAA,OAAOF,UAAU,CAACd,iBAAiB,CAAC,EAAEiB,GAAG;AAC3C;AAIA,MAAMC,6BAA6B,gBAAGjB,aAAa,CAEjDC,SAAS,CAAC;AACL,MAAMiB,8BAA8B,GAAGD,6BAA6B,CAACd;AAEtE,SAAUgB,yBAAyBA,CAACC,OAAe,EAAEC,GAAuB,EAAA;AAChF,EAAA,MAAMC,iBAAiB,GAAGT,UAAU,CAACI,6BAA6B,CAAC;AACnEM,EAAAA,SAAS,CAAC,MAAK;AACb,IAAA,IAAID,iBAAiB,IAAID,GAAG,IAAI,IAAI,EAAE;AACpCC,MAAAA,iBAAiB,CAAC;QAAEF,OAAO;AAAEC,QAAAA;AAAG,OAAE,CAAC;AACnC,MAAA,OAAO,MAAMC,iBAAiB,CAAC,IAAI,CAAC;AACtC,IAAA;EACF,CAAC,EAAE,CAACA,iBAAiB,EAAEF,OAAO,EAAEC,GAAG,CAAC,CAAC;AACvC;AAMM,SAAUG,mBAAmBA,CACjCC,SAAiC,EACjCC,IAA6B,EAAA;EAE7B,SAASC,4BAA4BA,CAACC,KAA8C,EAAA;IAClF,oBAAOC,GAAA,CAACJ,SAAS,EAAA;AAACK,MAAAA,eAAe,EAAEpB,kBAAkB,CAACgB,IAAI,CAAE;MAAA,GAAME;AAAW,MAAI;AACnF,EAAA;AAEAD,EAAAA,4BAA4B,CAACI,WAAW,GAAG,CAAA,oBAAA,EAAuBN,SAAS,CAACM,WAAW,IAAIN,SAAS,CAACO,IAAI,IAAI,WAAW,CAAA,CAAA,CAAG;AAE3H,EAAA,OAAOL,4BAA4B;AACrC;;;;"}
package/build/main.css CHANGED
@@ -3238,7 +3238,16 @@ a,
3238
3238
  .np-text-display-extra-large,
3239
3239
  .np-text-display-large,
3240
3240
  .np-text-display-medium,
3241
- .np-text-display-small {
3241
+ .np-text-display-small,
3242
+ .display-1--forced,
3243
+ .display-2--forced,
3244
+ .display-3--forced,
3245
+ .display-4--forced,
3246
+ .display-5--forced,
3247
+ .np-text-display-extra-large--forced,
3248
+ .np-text-display-large--forced,
3249
+ .np-text-display-medium--forced,
3250
+ .np-text-display-small--forced {
3242
3251
  font-family: 'Wise Sans', 'Inter', sans-serif;
3243
3252
  font-family: var(--font-family-display);
3244
3253
  font-synthesis: none;
@@ -3285,9 +3294,14 @@ a,
3285
3294
  * of Japanese ones for the logged out ones (exposed by the Editorial DS). Unfortunately,
3286
3295
  * font files are browser-cached and we carried over to launchpad, where it causes issues
3287
3296
  * for unsupported locales, especially those that share glyphs, like Japanese and Chinese.
3297
+ * There are exceptions for small UI parts where Wise Sans is fine or expected — e.g. the
3298
+ * numeric input of ExpressiveMoneyInput.
3299
+ * Add `--forced` BEM modifier to the original class name to guarantee it.
3288
3300
  */
3289
3301
  font-family: 'Inter', Helvetica, Arial, sans-serif;
3290
3302
  font-family: var(--font-family-regular);
3303
+ line-height: 1.2;
3304
+ line-height: var(--line-height-title);
3291
3305
  }
3292
3306
 
3293
3307
  /* DEPRECATED(.np-text-display-extra-large): use .np-text-display-large instead */
@@ -26633,10 +26647,10 @@ a[data-toggle="tooltip"] {
26633
26647
  }
26634
26648
 
26635
26649
  .np-dot-mask {
26636
- -webkit-mask-image: radial-gradient(circle at bottom calc(100% - (var(--np-dot-size) / 2)) left calc(100% - (var(--np-dot-size) / 2)), transparent 0, transparent calc(var(--np-dot-size) / 2 + var(--np-dot-offset)), black 0);
26637
- mask-image: radial-gradient(circle at bottom calc(100% - (var(--np-dot-size) / 2)) left calc(100% - (var(--np-dot-size) / 2)), transparent 0, transparent calc(var(--np-dot-size) / 2 + var(--np-dot-offset)), black 0);
26638
- -webkit-mask-image: radial-gradient(circle at bottom calc(100% - calc(var(--np-dot-size) / 2)) left calc(100% - calc(var(--np-dot-size) / 2)), transparent 0, transparent calc(var(--np-dot-size) / 2 + var(--np-dot-offset)), black 0);
26639
- mask-image: radial-gradient(circle at bottom calc(100% - calc(var(--np-dot-size) / 2)) left calc(100% - calc(var(--np-dot-size) / 2)), transparent 0, transparent calc(var(--np-dot-size) / 2 + var(--np-dot-offset)), black 0);
26650
+ -webkit-mask-image: radial-gradient(circle at bottom calc(100% - (var(--np-dot-size) / 2)) left calc(100% - (var(--np-dot-size) / 2)), transparent 0, transparent calc(var(--np-dot-size) / 2 + var(--np-dot-offset)), black calc(var(--np-dot-size) / 2 + var(--np-dot-offset) + 0.5px));
26651
+ mask-image: radial-gradient(circle at bottom calc(100% - (var(--np-dot-size) / 2)) left calc(100% - (var(--np-dot-size) / 2)), transparent 0, transparent calc(var(--np-dot-size) / 2 + var(--np-dot-offset)), black calc(var(--np-dot-size) / 2 + var(--np-dot-offset) + 0.5px));
26652
+ -webkit-mask-image: radial-gradient(circle at bottom calc(100% - calc(var(--np-dot-size) / 2)) left calc(100% - calc(var(--np-dot-size) / 2)), transparent 0, transparent calc(var(--np-dot-size) / 2 + var(--np-dot-offset)), black calc(var(--np-dot-size) / 2 + var(--np-dot-offset) + 0.5px));
26653
+ mask-image: radial-gradient(circle at bottom calc(100% - calc(var(--np-dot-size) / 2)) left calc(100% - calc(var(--np-dot-size) / 2)), transparent 0, transparent calc(var(--np-dot-size) / 2 + var(--np-dot-offset)), black calc(var(--np-dot-size) / 2 + var(--np-dot-offset) + 0.5px));
26640
26654
  }
26641
26655
 
26642
26656
  .np-dot-badge {
@@ -29935,18 +29949,36 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
29935
29949
  stroke-dasharray: var(--wds-list-item-spotlight-strokeDashSize) var(--wds-list-item-spotlight-strokeDashSize);
29936
29950
  }
29937
29951
 
29938
- .np-field-control,
29939
- .np-field__prompt {
29952
+ .np-field-control {
29940
29953
  margin-top: 4px;
29941
29954
  margin-top: var(--size-4);
29942
29955
  }
29943
29956
 
29957
+ .np-field-validation {
29958
+ display: flex;
29959
+ align-items: flex-start;
29960
+ margin-top: 4px;
29961
+ margin-top: var(--size-4);
29962
+ gap: 8px;
29963
+ gap: var(--size-8);
29964
+ }
29965
+
29966
+ .np-field-textarea-char-counter {
29967
+ min-width: 55px;
29968
+ text-align: right;
29969
+ margin-left: auto;
29970
+ padding: 4px 0;
29971
+ padding: var(--size-4) 0;
29972
+ color: #768e9c;
29973
+ color: var(--color-content-tertiary);
29974
+ }
29975
+
29944
29976
  .np-field .form-group--typeahead[class],
29945
29977
  .np-field .np-checkbox-label[class] {
29946
29978
  margin-bottom: 0;
29947
29979
  }
29948
29980
 
29949
- .np-field:has(.wds-radio-group) .np-field__prompt {
29981
+ .np-field:has(.wds-radio-group) .np-field-validation {
29950
29982
  margin-top: 12px;
29951
29983
  margin-top: var(--size-12);
29952
29984
  }
@@ -31052,6 +31084,7 @@ button.np-link {
31052
31084
  flex-grow: 1;
31053
31085
  text-align: right;
31054
31086
  background-color: transparent;
31087
+ line-height: inherit;
31055
31088
  }
31056
31089
 
31057
31090
  .wds-amount-input-input:focus-visible {
@@ -31062,6 +31095,7 @@ button.np-link {
31062
31095
  flex-grow: 0;
31063
31096
  display: flex;
31064
31097
  align-items: center;
31098
+ line-height: inherit;
31065
31099
  }
31066
31100
 
31067
31101
  .wds-currency-selector:disabled {
@@ -60,36 +60,52 @@ const Nudge = ({
60
60
  action
61
61
  }) => {
62
62
  const intl = reactIntl.useIntl();
63
- const [isDismissed, setIsDismissed] = React.useState(false);
64
- const [isMounted, setIsMounted] = React.useState(false);
63
+ const getIsDismissed = React.useCallback(() => persistDismissal && id ? !!getLocalStorage()?.find(item => item === id) : false, [persistDismissal, id]);
64
+ const [nudgeState, setNudgeState] = React.useState(() => ({
65
+ isDismissed: getIsDismissed(),
66
+ isMounted: false
67
+ }));
68
+ React.useEffect(() => {
69
+ // eslint-disable-next-line react-hooks/set-state-in-effect -- Setting mount state in mount effect
70
+ setNudgeState(prev => ({
71
+ ...prev,
72
+ isMounted: true
73
+ }));
74
+ }, []);
75
+ React.useEffect(() => {
76
+ // eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing dismissed state from localStorage on prop change
77
+ setNudgeState(prev => ({
78
+ ...prev,
79
+ isDismissed: getIsDismissed()
80
+ }));
81
+ }, [getIsDismissed, id, persistDismissal]);
82
+ const {
83
+ isDismissed
84
+ } = nudgeState;
65
85
  const handleOnDismiss = () => {
66
86
  const dismissedNudgesStorage = getLocalStorage();
67
87
  if (persistDismissal && id) {
68
88
  try {
69
89
  localStorage.setItem(STORAGE_NAME, JSON.stringify([...dismissedNudgesStorage, id]));
70
- } catch (error) {}
71
- setIsDismissed(true);
90
+ } catch {}
91
+ setNudgeState(prev => ({
92
+ ...prev,
93
+ isDismissed: true
94
+ }));
72
95
  }
73
96
  if (onDismiss) {
74
97
  onDismiss();
75
98
  }
76
99
  };
77
100
  React.useEffect(() => {
78
- if (persistDismissal && id) {
101
+ if (persistDismissal && id && isPreviouslyDismissed) {
79
102
  const dismissedNudgesStorage = getLocalStorage();
80
- let isDismissed = false;
81
- if (dismissedNudgesStorage?.find(item => item === id)) {
82
- setIsDismissed(true);
83
- isDismissed = true;
84
- }
85
- if (isPreviouslyDismissed) {
86
- isPreviouslyDismissed(isDismissed);
87
- }
103
+ const wasDismissed = !!dismissedNudgesStorage?.find(item => item === id);
104
+ isPreviouslyDismissed(wasDismissed);
88
105
  }
89
- setIsMounted(true);
90
106
  // eslint-disable-next-line react-hooks/exhaustive-deps
91
107
  }, [id, persistDismissal]);
92
- if (persistDismissal && (isDismissed || !isMounted)) {
108
+ if (persistDismissal && (isDismissed || !nudgeState.isMounted)) {
93
109
  return null;
94
110
  }
95
111
  return /*#__PURE__*/jsxRuntime.jsxs("div", {