@tcn/ui 0.10.0 → 0.12.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 (202) hide show
  1. package/dist/feedback/index.d.ts +1 -0
  2. package/dist/feedback/index.d.ts.map +1 -1
  3. package/dist/feedback/index.js +6 -4
  4. package/dist/feedback/index.js.map +1 -1
  5. package/dist/feedback/progress/progress.d.ts +7 -0
  6. package/dist/feedback/progress/progress.d.ts.map +1 -0
  7. package/dist/feedback/progress/progress.js +38 -0
  8. package/dist/feedback/progress/progress.js.map +1 -0
  9. package/dist/feedback/progress/progress_bar.d.ts +0 -1
  10. package/dist/feedback/progress/progress_bar.d.ts.map +1 -1
  11. package/dist/feedback/progress/progress_bar.js +6 -46
  12. package/dist/feedback/progress/progress_bar.js.map +1 -1
  13. package/dist/form/field/common/status_input/status_input.js +4 -3
  14. package/dist/form/field/common/status_input/status_input.js.map +1 -1
  15. package/dist/form/field/h_field/h_field.d.ts.map +1 -1
  16. package/dist/form/field/h_field/h_field.js +33 -35
  17. package/dist/form/field/h_field/h_field.js.map +1 -1
  18. package/dist/form/field/v_field/v_field.d.ts.map +1 -1
  19. package/dist/form/field/v_field/v_field.js +34 -36
  20. package/dist/form/field/v_field/v_field.js.map +1 -1
  21. package/dist/frame.css +1 -1
  22. package/dist/inputs/color_input/color_input.d.ts.map +1 -1
  23. package/dist/inputs/color_input/color_input.js +47 -46
  24. package/dist/inputs/color_input/color_input.js.map +1 -1
  25. package/dist/inputs/combo_box/combo_box.d.ts.map +1 -1
  26. package/dist/inputs/combo_box/combo_box.js +61 -58
  27. package/dist/inputs/combo_box/combo_box.js.map +1 -1
  28. package/dist/inputs/index.d.ts +1 -0
  29. package/dist/inputs/index.d.ts.map +1 -1
  30. package/dist/inputs/index.js +34 -31
  31. package/dist/inputs/index.js.map +1 -1
  32. package/dist/inputs/input/input.js +9 -9
  33. package/dist/inputs/input/input.js.map +1 -1
  34. package/dist/inputs/input_group/input_group.d.ts +5 -0
  35. package/dist/inputs/input_group/input_group.d.ts.map +1 -0
  36. package/dist/inputs/input_group/input_group.js +20 -0
  37. package/dist/inputs/input_group/input_group.js.map +1 -0
  38. package/dist/inputs/phone_number_input/countries_phone_information.d.ts +2 -2
  39. package/dist/inputs/phone_number_input/countries_phone_information.d.ts.map +1 -1
  40. package/dist/inputs/phone_number_input/countries_phone_information.js +5 -353
  41. package/dist/inputs/phone_number_input/countries_phone_information.js.map +1 -1
  42. package/dist/inputs/phone_number_input/phone_number_context.d.ts +24 -0
  43. package/dist/inputs/phone_number_input/phone_number_context.d.ts.map +1 -0
  44. package/dist/inputs/phone_number_input/phone_number_context.js +23 -0
  45. package/dist/inputs/phone_number_input/phone_number_context.js.map +1 -0
  46. package/dist/inputs/phone_number_input/phone_number_country_select_adapter.d.ts +19 -0
  47. package/dist/inputs/phone_number_input/phone_number_country_select_adapter.d.ts.map +1 -0
  48. package/dist/inputs/phone_number_input/phone_number_country_select_adapter.js +77 -0
  49. package/dist/inputs/phone_number_input/phone_number_country_select_adapter.js.map +1 -0
  50. package/dist/inputs/phone_number_input/phone_number_input.d.ts +16 -14
  51. package/dist/inputs/phone_number_input/phone_number_input.d.ts.map +1 -1
  52. package/dist/inputs/phone_number_input/phone_number_input.js +104 -274
  53. package/dist/inputs/phone_number_input/phone_number_input.js.map +1 -1
  54. package/dist/inputs/phone_number_input/phone_number_input_adapter.d.ts +6 -0
  55. package/dist/inputs/phone_number_input/phone_number_input_adapter.d.ts.map +1 -0
  56. package/dist/inputs/phone_number_input/phone_number_input_adapter.js +95 -0
  57. package/dist/inputs/phone_number_input/phone_number_input_adapter.js.map +1 -0
  58. package/dist/inputs/phone_number_input/sip_input.d.ts +12 -0
  59. package/dist/inputs/phone_number_input/sip_input.d.ts.map +1 -0
  60. package/dist/inputs/phone_number_input/sip_input.js +111 -0
  61. package/dist/inputs/phone_number_input/sip_input.js.map +1 -0
  62. package/dist/inputs/select/select.d.ts.map +1 -1
  63. package/dist/inputs/select/select.js +3 -2
  64. package/dist/inputs/select/select.js.map +1 -1
  65. package/dist/inputs/suggestions/suggestion_list.d.ts +4 -1
  66. package/dist/inputs/suggestions/suggestion_list.d.ts.map +1 -1
  67. package/dist/inputs/suggestions/suggestion_list.js +148 -121
  68. package/dist/inputs/suggestions/suggestion_list.js.map +1 -1
  69. package/dist/inputs/textarea/textarea.js +8 -8
  70. package/dist/inputs/textarea/textarea.js.map +1 -1
  71. package/dist/inputs/unit_input/unit_input.d.ts.map +1 -1
  72. package/dist/inputs/unit_input/unit_input.js +39 -39
  73. package/dist/inputs/unit_input/unit_input.js.map +1 -1
  74. package/dist/overlay/frame/frame.d.ts +8 -4
  75. package/dist/overlay/frame/frame.d.ts.map +1 -1
  76. package/dist/overlay/frame/frame.js +88 -24
  77. package/dist/overlay/frame/frame.js.map +1 -1
  78. package/dist/overlay/popper/base/dismissal_decorator.js.map +1 -1
  79. package/dist/overlay/popper/legacy/popper.d.ts.map +1 -1
  80. package/dist/overlay/popper/legacy/popper.js +52 -50
  81. package/dist/overlay/popper/legacy/popper.js.map +1 -1
  82. package/dist/phone_number_input.css +1 -1
  83. package/dist/progress_bar-CPP0Jyv-.js +38 -0
  84. package/dist/progress_bar-CPP0Jyv-.js.map +1 -0
  85. package/dist/progress_bar.css +1 -1
  86. package/dist/stacks/box/bottom_resize_handle.d.ts +2 -8
  87. package/dist/stacks/box/bottom_resize_handle.d.ts.map +1 -1
  88. package/dist/stacks/box/bottom_resize_handle.js.map +1 -1
  89. package/dist/stacks/box/box.d.ts +2 -2
  90. package/dist/stacks/box/box.d.ts.map +1 -1
  91. package/dist/stacks/box/box.js.map +1 -1
  92. package/dist/stacks/box/end_resize_handle.d.ts +2 -8
  93. package/dist/stacks/box/end_resize_handle.d.ts.map +1 -1
  94. package/dist/stacks/box/end_resize_handle.js.map +1 -1
  95. package/dist/stacks/box/left_resize_handle.d.ts +2 -8
  96. package/dist/stacks/box/left_resize_handle.d.ts.map +1 -1
  97. package/dist/stacks/box/left_resize_handle.js.map +1 -1
  98. package/dist/stacks/box/resize_handlers.d.ts +3 -2
  99. package/dist/stacks/box/resize_handlers.d.ts.map +1 -1
  100. package/dist/stacks/box/resize_handlers.js +41 -37
  101. package/dist/stacks/box/resize_handlers.js.map +1 -1
  102. package/dist/stacks/box/right_resize_handle.d.ts +2 -8
  103. package/dist/stacks/box/right_resize_handle.d.ts.map +1 -1
  104. package/dist/stacks/box/right_resize_handle.js.map +1 -1
  105. package/dist/stacks/box/start_resize_handle.d.ts +2 -8
  106. package/dist/stacks/box/start_resize_handle.d.ts.map +1 -1
  107. package/dist/stacks/box/start_resize_handle.js +4 -4
  108. package/dist/stacks/box/start_resize_handle.js.map +1 -1
  109. package/dist/stacks/box/top_resize_handle.d.ts +2 -8
  110. package/dist/stacks/box/top_resize_handle.d.ts.map +1 -1
  111. package/dist/stacks/box/top_resize_handle.js +4 -4
  112. package/dist/stacks/box/top_resize_handle.js.map +1 -1
  113. package/dist/stacks/box/types.d.ts +18 -0
  114. package/dist/stacks/box/types.d.ts.map +1 -0
  115. package/dist/stacks/h_collapsible_box.js +25 -25
  116. package/dist/stacks/h_collapsible_box.js.map +1 -1
  117. package/dist/stacks/index.d.ts +1 -0
  118. package/dist/stacks/index.d.ts.map +1 -1
  119. package/dist/stacks/v_collapsible_box.js +25 -25
  120. package/dist/stacks/v_collapsible_box.js.map +1 -1
  121. package/dist/suggestion_list.css +1 -1
  122. package/dist/surfaces/modal/modal.d.ts +3 -4
  123. package/dist/surfaces/modal/modal.d.ts.map +1 -1
  124. package/dist/surfaces/modal/modal.js +10 -8
  125. package/dist/surfaces/modal/modal.js.map +1 -1
  126. package/dist/surfaces/window/window.d.ts +3 -4
  127. package/dist/surfaces/window/window.d.ts.map +1 -1
  128. package/dist/surfaces/window/window.js +26 -14
  129. package/dist/surfaces/window/window.js.map +1 -1
  130. package/dist/themes/stylesheets/reset.css +1 -1
  131. package/dist/themes/stylesheets/reset.js +8 -1
  132. package/dist/themes/stylesheets/reset.js.map +1 -1
  133. package/dist/themes/themes/ergo/ergo_theme.css +1 -1
  134. package/dist/themes/themes/ergo/ergo_theme.js +186 -19
  135. package/dist/themes/themes/ergo/ergo_theme.js.map +1 -1
  136. package/dist/typography/body_text/body_text.d.ts.map +1 -1
  137. package/dist/typography/body_text/body_text.js +12 -10
  138. package/dist/typography/body_text/body_text.js.map +1 -1
  139. package/dist/utils/dnd/hooks/use_drag_container.d.ts.map +1 -1
  140. package/dist/utils/dnd/hooks/use_drag_container.js +22 -19
  141. package/dist/utils/dnd/hooks/use_drag_container.js.map +1 -1
  142. package/package.json +4 -2
  143. package/src/feedback/index.ts +1 -0
  144. package/src/feedback/progress/progress.module.css +5 -0
  145. package/src/feedback/progress/progress.stories.tsx +48 -0
  146. package/src/feedback/progress/progress.tsx +39 -0
  147. package/src/feedback/progress/progress_bar.module.css +4 -28
  148. package/src/feedback/progress/progress_bar.stories.tsx +1 -1
  149. package/src/feedback/progress/progress_bar.tsx +14 -26
  150. package/src/form/field/h_field/h_field.tsx +0 -4
  151. package/src/form/field/v_field/v_field.stories.tsx +8 -0
  152. package/src/form/field/v_field/v_field.tsx +1 -4
  153. package/src/form/field_set/field_set.stories.tsx +2 -1
  154. package/src/inputs/__docs__/inputs.mdx +81 -0
  155. package/src/inputs/__docs__/inputs.stories.tsx +268 -0
  156. package/src/inputs/color_input/color_input.tsx +17 -17
  157. package/src/inputs/combo_box/combo_box.tsx +17 -13
  158. package/src/inputs/index.ts +2 -0
  159. package/src/inputs/input/input.tsx +1 -1
  160. package/src/inputs/input_group/input_group.tsx +26 -0
  161. package/src/inputs/phone_number_input/countries_phone_information.ts +6 -353
  162. package/src/inputs/phone_number_input/phone_number_context.tsx +32 -0
  163. package/src/inputs/phone_number_input/phone_number_country_select_adapter.tsx +126 -0
  164. package/src/inputs/phone_number_input/phone_number_input.module.css +5 -63
  165. package/src/inputs/phone_number_input/phone_number_input.stories.tsx +180 -150
  166. package/src/inputs/phone_number_input/phone_number_input.tsx +133 -400
  167. package/src/inputs/phone_number_input/phone_number_input_adapter.tsx +123 -0
  168. package/src/inputs/phone_number_input/sip_input.tsx +147 -0
  169. package/src/inputs/select/select.stories.tsx +23 -2
  170. package/src/inputs/select/select.tsx +13 -14
  171. package/src/inputs/suggestions/suggestion_list.module.css +1 -0
  172. package/src/inputs/suggestions/suggestion_list.stories.tsx +12 -8
  173. package/src/inputs/suggestions/suggestion_list.tsx +82 -42
  174. package/src/inputs/textarea/textarea.tsx +1 -1
  175. package/src/inputs/unit_input/unit_input.tsx +17 -17
  176. package/src/overlay/frame/frame.module.css +2 -4
  177. package/src/overlay/frame/frame.stories.tsx +13 -10
  178. package/src/overlay/frame/frame.tsx +121 -15
  179. package/src/overlay/popper/base/dismissal_decorator.tsx +1 -1
  180. package/src/overlay/popper/legacy/popper.tsx +5 -1
  181. package/src/stacks/box/bottom_resize_handle.tsx +2 -8
  182. package/src/stacks/box/box.tsx +14 -2
  183. package/src/stacks/box/end_resize_handle.tsx +3 -8
  184. package/src/stacks/box/left_resize_handle.tsx +3 -8
  185. package/src/stacks/box/resize_handlers.ts +28 -12
  186. package/src/stacks/box/right_resize_handle.tsx +2 -8
  187. package/src/stacks/box/start_resize_handle.tsx +4 -9
  188. package/src/stacks/box/top_resize_handle.tsx +4 -8
  189. package/src/stacks/box/types.ts +44 -0
  190. package/src/stacks/h_collapsible_box.tsx +2 -2
  191. package/src/stacks/index.ts +1 -0
  192. package/src/stacks/v_collapsible_box.tsx +2 -2
  193. package/src/surfaces/modal/modal.tsx +6 -4
  194. package/src/surfaces/window/window.stories.tsx +9 -1
  195. package/src/surfaces/window/window.tsx +19 -7
  196. package/src/themes/stories/controls_fieldset.tsx +1 -1
  197. package/src/themes/stylesheets/reset.css +8 -1
  198. package/src/themes/themes/ergo/ergo_theme.css +186 -19
  199. package/src/typography/body_text/body_text.tsx +2 -0
  200. package/src/utils/dnd/__stories__/draggable.stories.tsx +14 -8
  201. package/src/utils/dnd/hooks/use_drag_container.ts +13 -3
  202. package/src/inputs/phone_number_input/__tests__/utils.test.ts +0 -52
@@ -1 +1 @@
1
- {"version":3,"file":"suggestion_list.js","sources":["../../../src/inputs/suggestions/suggestion_list.tsx"],"sourcesContent":["import { BodyText } from '../../typography/index.js';\nimport { VStack } from '../../stacks/v_stack.js';\nimport { ZStack } from '../../stacks/z_stack.js';\nimport { clsx } from 'clsx';\nimport React, { useLayoutEffect, Children, isValidElement } from 'react';\nimport { useRef, useState } from 'react';\nimport { FocusRedirect } from '../../utils/index.js';\nimport { SuggestionItem } from './suggestion_item.js';\nimport { OptionProps, Option } from '../options/option.js';\nimport styles from './suggestion_list.module.css';\n\nimport { Button } from '../../actions/index.js';\nimport { Popper } from '../../overlay/popper/legacy/popper.js';\n\nconst MAX_RESULTS = 50;\nconst BATCH_SIZE = 50;\n\nexport interface SuggestionListProps\n extends Omit<React.HTMLAttributes<HTMLInputElement>, 'onChange'> {\n value?: string;\n scrollToValue?: string;\n anchorElement: HTMLElement | null;\n children?: React.ReactNode;\n onChange?: (value: string) => void;\n onOptionSelect?: (\n value: string,\n label: string | undefined,\n isSuggestion: boolean,\n obfuscate: boolean\n ) => void;\n noSuggestionMessage?: React.ReactNode;\n trimCustomInput?: boolean;\n haveValueAsOption?: boolean;\n onClose?: (\n inputValue: string,\n cursorStartPosition: number | null,\n cursorEndPosition: number | null\n ) => void;\n}\n\nexport function SuggestionList({\n value = '',\n scrollToValue,\n anchorElement,\n children,\n onOptionSelect,\n noSuggestionMessage = '-- No Matches --',\n onClose,\n onChange,\n onKeyUp,\n onKeyDown,\n trimCustomInput = false,\n haveValueAsOption = false,\n ...props\n}: SuggestionListProps) {\n // Extract valid Option components from children\n const suggestions = Children.toArray(children).filter(\n (child): child is React.ReactElement<OptionProps> =>\n isValidElement(child) && child.type === Option\n );\n\n const [selectedIndex, setSelectedIndex] = useState(() => {\n if (scrollToValue != null) {\n const index = suggestions.findIndex(option => option.props.value === scrollToValue);\n if (index !== -1) {\n return index;\n }\n }\n return -1;\n });\n\n const keyPressedDownRef = useRef('');\n const [maxResults, setMaxResults] = useState(MAX_RESULTS);\n const [focusedIndex, setFocusedIndex] = useState(selectedIndex);\n const [internalValue, setInternalValue] = useState(value);\n const internalInputRef = useRef<HTMLInputElement | null>(null);\n const [totalMatchedLength, setTotalMatchedLength] = useState(suggestions.length);\n const [matchedOptions, setMatchedOptions] = useState<React.ReactElement<OptionProps>[]>(\n () => getMatchedOptions(value, MAX_RESULTS)\n );\n const [suggestionsWidth, setSuggestionsWidth] = useState<string | undefined>();\n const [suggestionsHeight, setSuggestionsHeight] = useState<string | undefined>();\n\n function handleKeyUp(event: React.KeyboardEvent<HTMLInputElement>) {\n const key = event.key;\n const input = event.currentTarget;\n\n const isSameKey = (keyPressedDownRef.current = key);\n keyPressedDownRef.current = '';\n\n // Enter and Escape remove the popover, so we want to handle this on keyup.\n // This prevents from another element from getting the key events.\n if (isSameKey) {\n switch (key) {\n case 'Enter': {\n if (matchedOptions[focusedIndex] == null) {\n const value = trimCustomInput ? input.value.trim() : input.value;\n\n if (value === '') {\n return;\n }\n\n const lowercaseValue = value.toLocaleLowerCase();\n const option = suggestions.find(\n option =>\n option.props.value.toLocaleLowerCase() === lowercaseValue ||\n (option.props.label != null &&\n option.props.label.toLocaleLowerCase() === lowercaseValue)\n );\n\n const isSuggestion = option != null;\n const label = option?.props.label || value;\n const optionValue = option?.props.value || value;\n\n requestAnimationFrame(() => {\n onOptionSelect &&\n onOptionSelect(\n optionValue,\n label,\n isSuggestion,\n option?.props.obfuscate ?? false\n );\n });\n\n break;\n }\n const selectedOption = matchedOptions[focusedIndex];\n const optionProps = selectedOption.props;\n\n // Don't select disabled options\n if (optionProps.disabled) {\n break;\n }\n\n requestAnimationFrame(() => {\n onOptionSelect &&\n onOptionSelect(\n optionProps.value,\n optionProps.label,\n true,\n optionProps.obfuscate ?? false\n );\n });\n break;\n }\n case 'Escape': {\n onClose && onClose(input.value, input.selectionStart, input.selectionEnd);\n break;\n }\n }\n }\n\n onKeyUp && onKeyUp(event);\n }\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {\n const key = event.key;\n keyPressedDownRef.current = key;\n\n // We handle these key events on keydown to be responsive navigation.\n switch (key) {\n case 'ArrowDown': {\n let newIndex = focusedIndex + 1;\n\n // Skip disabled options\n while (\n newIndex < matchedOptions.length &&\n matchedOptions[newIndex]?.props.disabled\n ) {\n newIndex++;\n }\n\n if (newIndex === matchedOptions.length) {\n // Wrap around to first non-disabled option\n newIndex = 0;\n while (\n newIndex < matchedOptions.length &&\n matchedOptions[newIndex]?.props.disabled\n ) {\n newIndex++;\n }\n // If all options are disabled, stay at -1\n if (newIndex === matchedOptions.length) {\n newIndex = -1;\n }\n }\n\n setFocusedIndex(newIndex);\n event.preventDefault();\n break;\n }\n case 'Tab': {\n let step = 1;\n if (event.shiftKey) {\n step = -1;\n }\n let newIndex = focusedIndex + step;\n // Skip disabled options\n if (step > 0) {\n while (\n newIndex < matchedOptions.length &&\n matchedOptions[newIndex]?.props.disabled\n ) {\n newIndex++;\n }\n } else {\n while (newIndex >= 0 && matchedOptions[newIndex]?.props.disabled) {\n newIndex--;\n }\n }\n\n if (newIndex === matchedOptions.length) {\n // Wrap around to first non-disabled option\n newIndex = 0;\n while (\n newIndex < matchedOptions.length &&\n matchedOptions[newIndex]?.props.disabled\n ) {\n newIndex++;\n }\n // If all options are disabled, stay at -1\n if (newIndex === matchedOptions.length) {\n newIndex = -1;\n }\n } else if (newIndex <= -1) {\n // Wrap around to last non-disabled option\n newIndex = matchedOptions.length - 1;\n while (newIndex >= 0 && matchedOptions[newIndex]?.props.disabled) {\n newIndex--;\n }\n // If all options are disabled, stay at -1\n if (newIndex === -1) {\n newIndex = -1;\n }\n }\n\n setFocusedIndex(newIndex);\n event.preventDefault();\n break;\n }\n case 'ArrowUp': {\n let newIndex = focusedIndex - 1;\n\n // Skip disabled options\n while (newIndex >= 0 && matchedOptions[newIndex]?.props.disabled) {\n newIndex--;\n }\n\n if (newIndex === -1) {\n // Wrap around to last non-disabled option\n newIndex = matchedOptions.length - 1;\n while (newIndex >= 0 && matchedOptions[newIndex]?.props.disabled) {\n newIndex--;\n }\n // If all options are disabled, stay at -1\n if (newIndex === -1) {\n newIndex = -1;\n }\n }\n\n setFocusedIndex(newIndex);\n event.preventDefault();\n break;\n }\n }\n onKeyDown && onKeyDown(event);\n }\n\n function getMatchedOptions(value: string, maxResults: number) {\n const results = suggestions.filter(option => {\n const props = option.props;\n const label = String(props.label).toLocaleLowerCase();\n const keywords = props.keywords?.map(k => k.toLocaleLowerCase()) || [];\n const optionValue = String(props.value).toLocaleLowerCase();\n const searchValue = value.toLocaleLowerCase();\n const obfuscate = props.obfuscate ?? false;\n\n // Obfuscated options can only be searched by label or keywords, not by value\n if (obfuscate) {\n return label.includes(searchValue) || keywords.some(k => k.includes(searchValue));\n }\n\n return (\n label.includes(searchValue) ||\n keywords.some(k => k.includes(searchValue)) ||\n optionValue.includes(searchValue)\n );\n });\n\n if (\n haveValueAsOption &&\n value.trim().length > 0 &&\n !results.some(r => r.props.value === value)\n ) {\n results.unshift(\n <Option key=\"value\" value={value} label={value} keywords={[value]}>\n {value}\n </Option>\n );\n }\n\n setTotalMatchedLength(results.length);\n return results.slice(0, maxResults);\n }\n\n function focusInput() {\n const input = internalInputRef.current;\n if (input != null) {\n input.focus();\n }\n }\n\n function handleUseClose() {\n const input = internalInputRef.current;\n if (input != null) {\n onClose && onClose(input.value, input.selectionStart, input.selectionEnd);\n }\n }\n\n function handleChange(event: React.ChangeEvent<HTMLInputElement>) {\n const input = event.currentTarget;\n\n setMaxResults(MAX_RESULTS);\n setInternalValue(event.target.value);\n\n const newMatches = getMatchedOptions(input.value, MAX_RESULTS);\n setMatchedOptions(newMatches);\n\n onChange && onChange(event.target.value);\n }\n\n function handleShowMore() {\n const newMaxResults = maxResults + BATCH_SIZE;\n setMaxResults(newMaxResults);\n const newMatches = getMatchedOptions(internalValue, newMaxResults);\n setMatchedOptions(newMatches);\n }\n\n useLayoutEffect(() => {\n const input = internalInputRef.current;\n\n if (input != null && input.value.length > 0) {\n input.select();\n } else if (input != null) {\n input.focus();\n }\n }, []);\n\n useLayoutEffect(() => {\n if (anchorElement != null) {\n const rect = anchorElement.getBoundingClientRect();\n setSuggestionsWidth(`${rect.width}px`);\n setSuggestionsHeight(`${rect.height}px`);\n\n if (internalInputRef.current != null && anchorElement instanceof HTMLInputElement) {\n internalInputRef.current.value = anchorElement.value;\n internalInputRef.current.selectionStart = anchorElement.selectionStart;\n internalInputRef.current.selectionEnd = anchorElement.selectionEnd;\n }\n }\n }, [anchorElement]);\n\n useLayoutEffect(() => {\n if (scrollToValue != null) {\n const index = matchedOptions.findIndex(\n option => option.props.value === scrollToValue\n );\n setSelectedIndex(index);\n }\n }, [matchedOptions, scrollToValue]);\n\n useLayoutEffect(() => {\n setFocusedIndex(internalValue === '' ? selectedIndex : -1);\n }, [internalValue, selectedIndex]);\n\n return (\n <Popper\n open\n anchorElement={anchorElement}\n onClose={handleUseClose}\n verticalAnchor=\"top\"\n verticalOrigin=\"top\"\n verticalOffset={-4}\n >\n <VStack\n minHeight={`calc(${suggestionsHeight}, 8px)`}\n maxHeight=\"300px\"\n minWidth={suggestionsWidth}\n width=\"auto\"\n hAlign=\"start\"\n className={clsx(styles['suggestion-list'], 'tcn-suggestion-list')}\n >\n <input\n ref={internalInputRef}\n key={-1}\n value={internalValue}\n onKeyUp={handleKeyUp}\n onKeyDown={handleKeyDown}\n onChange={handleChange}\n className={clsx(styles.input, 'tcn-suggestion-list-search-input')}\n {...props}\n />\n <VStack>\n {matchedOptions.map((option, index) => (\n <SuggestionItem\n key={index}\n option={option}\n isSelected={index === selectedIndex && internalValue !== ''}\n isFocused={index === focusedIndex}\n onClick={onOptionSelect}\n />\n ))}\n {totalMatchedLength > matchedOptions.length && (\n <>\n <Button marginBlock=\"8px\" hierarchy=\"tertiary\" onClick={handleShowMore}>\n Show More\n </Button>\n </>\n )}\n </VStack>\n {matchedOptions.length === 0 && (\n <ZStack\n padding=\"8px\"\n className={clsx(styles['no-results'], 'tcn-suggestion-list-no-results')}\n >\n <BodyText>{noSuggestionMessage}</BodyText>\n </ZStack>\n )}\n <FocusRedirect key={matchedOptions.length + 1} onRedirect={focusInput} />\n </VStack>\n </Popper>\n );\n}\n"],"names":["MAX_RESULTS","BATCH_SIZE","SuggestionList","value","scrollToValue","anchorElement","children","onOptionSelect","noSuggestionMessage","onClose","onChange","onKeyUp","onKeyDown","trimCustomInput","haveValueAsOption","props","suggestions","Children","child","isValidElement","Option","selectedIndex","setSelectedIndex","useState","index","option","keyPressedDownRef","useRef","maxResults","setMaxResults","focusedIndex","setFocusedIndex","internalValue","setInternalValue","internalInputRef","totalMatchedLength","setTotalMatchedLength","matchedOptions","setMatchedOptions","getMatchedOptions","suggestionsWidth","setSuggestionsWidth","suggestionsHeight","setSuggestionsHeight","handleKeyUp","event","key","input","isSameKey","lowercaseValue","isSuggestion","label","optionValue","optionProps","handleKeyDown","newIndex","step","results","keywords","k","searchValue","r","jsx","focusInput","handleUseClose","handleChange","newMatches","handleShowMore","newMaxResults","useLayoutEffect","rect","Popper","jsxs","VStack","clsx","styles","SuggestionItem","Fragment","Button","ZStack","BodyText","FocusRedirect"],"mappings":"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"}
1
+ {"version":3,"file":"suggestion_list.js","sources":["../../../src/inputs/suggestions/suggestion_list.tsx"],"sourcesContent":["import { BodyText } from '../../typography/index.js';\nimport { VStack } from '../../stacks/v_stack.js';\nimport { ZStack } from '../../stacks/z_stack.js';\nimport { clsx } from 'clsx';\nimport React, { useLayoutEffect, Children, isValidElement } from 'react';\nimport { useRef, useState } from 'react';\nimport { FocusRedirect } from '../../utils/index.js';\nimport { SuggestionItem } from './suggestion_item.js';\nimport { OptionProps, Option } from '../options/option.js';\nimport styles from './suggestion_list.module.css';\n\nimport { Button } from '../../actions/index.js';\nimport { Popper } from '../../overlay/popper/legacy/popper.js';\n\nconst MAX_RESULTS = 50;\nconst BATCH_SIZE = 50;\n\nexport interface SuggestionListProps\n extends Omit<React.HTMLAttributes<HTMLInputElement>, 'onChange'> {\n value?: string;\n initialSearchValue?: string;\n scrollToValue?: string;\n anchorElement: HTMLElement | null;\n open?: boolean;\n children?: React.ReactNode;\n onChange?: (value: string) => void;\n onOptionSelect?: (\n value: string,\n label: string | undefined,\n isSuggestion: boolean,\n obfuscate: boolean\n ) => void;\n noSuggestionMessage?: React.ReactNode;\n trimCustomInput?: boolean;\n haveValueAsOption?: boolean;\n restoreFocus?: boolean;\n onClose?: (\n inputValue: string,\n cursorStartPosition: number | null,\n cursorEndPosition: number | null\n ) => void;\n}\n\nexport function SuggestionList({\n value = '',\n initialSearchValue: searchValue,\n scrollToValue,\n anchorElement,\n open = false,\n children,\n onOptionSelect,\n noSuggestionMessage = '-- No Matches --',\n onClose,\n onChange,\n onKeyUp,\n onKeyDown,\n trimCustomInput = false,\n haveValueAsOption = false,\n restoreFocus = true,\n ...props\n}: SuggestionListProps) {\n // Extract valid Option components from children\n const suggestions = React.useMemo(\n () =>\n Children.toArray(children).filter(\n (child): child is React.ReactElement<OptionProps> =>\n isValidElement(child) && child.type === Option\n ),\n [children]\n );\n\n const [selectedIndex, setSelectedIndex] = useState(() => {\n if (scrollToValue != null) {\n const index = suggestions.findIndex(option => option.props.value === scrollToValue);\n if (index !== -1) {\n return index;\n }\n }\n return -1;\n });\n\n const keyPressedDownRef = useRef('');\n const KeyDownRegistered = useRef(false);\n const [maxResults, setMaxResults] = useState(MAX_RESULTS);\n const [focusedIndex, setFocusedIndex] = useState(selectedIndex);\n const [internalValue, setInternalValue] = useState(value);\n const internalInputRef = useRef<HTMLInputElement | null>(null);\n const [totalMatchedLength, setTotalMatchedLength] = useState(suggestions.length);\n const [matchedOptions, setMatchedOptions] = useState<React.ReactElement<OptionProps>[]>(\n () => []\n );\n const [suggestionsWidth, setSuggestionsWidth] = useState<string | undefined>();\n const [suggestionsHeight, setSuggestionsHeight] = useState<string | undefined>();\n\n function handleKeyUp(event: React.KeyboardEvent<HTMLInputElement>) {\n if (!KeyDownRegistered.current) {\n return;\n }\n KeyDownRegistered.current = false;\n\n const key = event.key;\n const input = event.currentTarget;\n\n const isSameKey = (keyPressedDownRef.current = key);\n keyPressedDownRef.current = '';\n\n // Enter and Escape remove the popover, so we want to handle this on keyup.\n // This prevents from another element from getting the key events.\n if (isSameKey) {\n switch (key) {\n case 'Enter': {\n if (matchedOptions[focusedIndex] == null) {\n const value = trimCustomInput ? input.value.trim() : input.value;\n\n if (value === '') {\n return;\n }\n\n const lowercaseValue = value.toLocaleLowerCase();\n const option = suggestions.find(\n option =>\n option.props.value.toLocaleLowerCase() === lowercaseValue ||\n (option.props.label != null &&\n option.props.label.toLocaleLowerCase() === lowercaseValue)\n );\n\n const isSuggestion = option != null;\n const label = option?.props.label || value;\n const optionValue = option?.props.value || value;\n\n requestAnimationFrame(() => {\n onOptionSelect &&\n onOptionSelect(\n optionValue,\n label,\n isSuggestion,\n option?.props.obfuscate ?? false\n );\n });\n\n break;\n }\n const selectedOption = matchedOptions[focusedIndex];\n const optionProps = selectedOption.props;\n\n // Don't select disabled options\n if (optionProps.disabled) {\n break;\n }\n\n requestAnimationFrame(() => {\n onOptionSelect &&\n onOptionSelect(\n optionProps.value,\n optionProps.label,\n true,\n optionProps.obfuscate ?? false\n );\n });\n break;\n }\n case 'Escape': {\n onClose && onClose(input.value, input.selectionStart, input.selectionEnd);\n break;\n }\n }\n }\n\n onKeyUp && onKeyUp(event);\n }\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {\n const key = event.key;\n keyPressedDownRef.current = key;\n KeyDownRegistered.current = true;\n // We handle these key events on keydown to be responsive navigation.\n switch (key) {\n case 'ArrowDown': {\n let newIndex = focusedIndex + 1;\n\n // Skip disabled options\n while (\n newIndex < matchedOptions.length &&\n matchedOptions[newIndex]?.props.disabled\n ) {\n newIndex++;\n }\n\n if (newIndex === matchedOptions.length) {\n // Wrap around to first non-disabled option\n newIndex = 0;\n while (\n newIndex < matchedOptions.length &&\n matchedOptions[newIndex]?.props.disabled\n ) {\n newIndex++;\n }\n // If all options are disabled, stay at -1\n if (newIndex === matchedOptions.length) {\n newIndex = -1;\n }\n }\n\n setFocusedIndex(newIndex);\n event.preventDefault();\n break;\n }\n case 'Tab': {\n let step = 1;\n if (event.shiftKey) {\n step = -1;\n }\n let newIndex = focusedIndex + step;\n // Skip disabled options\n if (step > 0) {\n while (\n newIndex < matchedOptions.length &&\n matchedOptions[newIndex]?.props.disabled\n ) {\n newIndex++;\n }\n } else {\n while (newIndex >= 0 && matchedOptions[newIndex]?.props.disabled) {\n newIndex--;\n }\n }\n\n if (newIndex === matchedOptions.length) {\n // Wrap around to first non-disabled option\n newIndex = 0;\n while (\n newIndex < matchedOptions.length &&\n matchedOptions[newIndex]?.props.disabled\n ) {\n newIndex++;\n }\n // If all options are disabled, stay at -1\n if (newIndex === matchedOptions.length) {\n newIndex = -1;\n }\n } else if (newIndex <= -1) {\n // Wrap around to last non-disabled option\n newIndex = matchedOptions.length - 1;\n while (newIndex >= 0 && matchedOptions[newIndex]?.props.disabled) {\n newIndex--;\n }\n // If all options are disabled, stay at -1\n if (newIndex === -1) {\n newIndex = -1;\n }\n }\n\n setFocusedIndex(newIndex);\n event.preventDefault();\n break;\n }\n case 'ArrowUp': {\n let newIndex = focusedIndex - 1;\n\n // Skip disabled options\n while (newIndex >= 0 && matchedOptions[newIndex]?.props.disabled) {\n newIndex--;\n }\n\n if (newIndex === -1) {\n // Wrap around to last non-disabled option\n newIndex = matchedOptions.length - 1;\n while (newIndex >= 0 && matchedOptions[newIndex]?.props.disabled) {\n newIndex--;\n }\n // If all options are disabled, stay at -1\n if (newIndex === -1) {\n newIndex = -1;\n }\n }\n\n setFocusedIndex(newIndex);\n event.preventDefault();\n break;\n }\n }\n onKeyDown && onKeyDown(event);\n }\n\n const getMatchedOptions = React.useCallback(\n function getMatchedOptions(value: string, maxResults: number) {\n const results = suggestions.filter(option => {\n const props = option.props;\n const label = String(props.label).toLocaleLowerCase();\n const keywords = props.keywords?.map(k => k.toLocaleLowerCase()) || [];\n const optionValue = String(props.value).toLocaleLowerCase();\n const searchValue = value.toLocaleLowerCase();\n const obfuscate = props.obfuscate ?? false;\n\n // Obfuscated options can only be searched by label or keywords, not by value\n if (obfuscate) {\n return (\n label.includes(searchValue) || keywords.some(k => k.includes(searchValue))\n );\n }\n\n return (\n label.includes(searchValue) ||\n keywords.some(k => k.includes(searchValue)) ||\n optionValue.includes(searchValue)\n );\n });\n\n if (\n haveValueAsOption &&\n value.trim().length > 0 &&\n !results.some(r => r.props.value === value)\n ) {\n results.unshift(\n <Option key=\"value\" value={value} label={value} keywords={[value]}>\n {value}\n </Option>\n );\n }\n\n setTotalMatchedLength(results.length);\n return results.slice(0, maxResults);\n },\n [suggestions, haveValueAsOption]\n );\n\n function focusInput() {\n const input = internalInputRef.current;\n if (input != null) {\n input.focus();\n }\n }\n\n function handleUseClose() {\n const input = internalInputRef.current;\n if (input != null) {\n onClose && onClose(input.value, input.selectionStart, input.selectionEnd);\n }\n }\n\n function handleChange(event: React.ChangeEvent<HTMLInputElement>) {\n const input = event.currentTarget;\n\n setMaxResults(MAX_RESULTS);\n setInternalValue(event.target.value);\n\n const newMatches = getMatchedOptions(input.value, MAX_RESULTS);\n setMatchedOptions(newMatches);\n\n onChange && onChange(event.target.value);\n }\n\n function handleShowMore() {\n const newMaxResults = maxResults + BATCH_SIZE;\n setMaxResults(newMaxResults);\n const newMatches = getMatchedOptions(internalValue, newMaxResults);\n setMatchedOptions(newMatches);\n }\n\n useLayoutEffect(() => {\n const input = internalInputRef.current;\n\n if (!open) {\n return;\n }\n\n if (input != null && input.value.length > 0) {\n input.select();\n } else if (input != null) {\n input.focus();\n }\n }, [open]);\n\n useLayoutEffect(() => {\n if (anchorElement != null) {\n const rect = anchorElement.getBoundingClientRect();\n setSuggestionsWidth(`${rect.width}px`);\n setSuggestionsHeight(`${rect.height}px`);\n\n if (internalInputRef.current != null && anchorElement instanceof HTMLInputElement) {\n internalInputRef.current.value = anchorElement.value;\n internalInputRef.current.selectionStart = anchorElement.selectionStart;\n internalInputRef.current.selectionEnd = anchorElement.selectionEnd;\n }\n }\n }, [anchorElement]);\n\n useLayoutEffect(() => {\n if (scrollToValue != null) {\n const index = matchedOptions.findIndex(\n option => option.props.value === scrollToValue\n );\n setSelectedIndex(index);\n }\n }, [matchedOptions, scrollToValue]);\n\n useLayoutEffect(() => {\n setFocusedIndex(internalValue === '' ? selectedIndex : -1);\n }, [internalValue, selectedIndex]);\n\n useLayoutEffect(() => {\n setInternalValue(searchValue ?? '');\n }, [searchValue]);\n\n useLayoutEffect(() => {\n const newMatches = getMatchedOptions(value, MAX_RESULTS);\n setMatchedOptions(newMatches);\n }, [value, getMatchedOptions]);\n\n return (\n <Popper\n open={open}\n anchorElement={anchorElement}\n onClose={handleUseClose}\n verticalAnchor=\"top\"\n verticalOrigin=\"top\"\n verticalOffset={-4}\n restoreFocus={restoreFocus}\n >\n <VStack\n minHeight={`calc(${suggestionsHeight}, 8px)`}\n maxHeight=\"300px\"\n minWidth={suggestionsWidth}\n width=\"auto\"\n hAlign=\"start\"\n className={clsx(styles['suggestion-list'], 'tcn-suggestion-list')}\n >\n <input\n ref={internalInputRef}\n key={-1}\n value={internalValue}\n onKeyUp={handleKeyUp}\n onKeyDown={handleKeyDown}\n onChange={handleChange}\n className={clsx(styles.input, 'tcn-suggestion-list-search-input')}\n {...props}\n />\n <VStack>\n {matchedOptions.map((option, index) => (\n <SuggestionItem\n key={index}\n option={option}\n isSelected={index === selectedIndex && internalValue !== ''}\n isFocused={index === focusedIndex}\n onClick={onOptionSelect}\n />\n ))}\n {totalMatchedLength > matchedOptions.length && (\n <>\n <Button\n key=\"show-more\"\n marginBlock=\"8px\"\n hierarchy=\"tertiary\"\n onClick={handleShowMore}\n >\n Show More\n </Button>\n </>\n )}\n </VStack>\n {matchedOptions.length === 0 && (\n <ZStack\n padding=\"8px\"\n className={clsx(styles['no-results'], 'tcn-suggestion-list-no-results')}\n >\n <BodyText>{noSuggestionMessage}</BodyText>\n </ZStack>\n )}\n <FocusRedirect key={matchedOptions.length + 1} onRedirect={focusInput} />\n </VStack>\n </Popper>\n );\n}\n"],"names":["MAX_RESULTS","BATCH_SIZE","SuggestionList","value","searchValue","scrollToValue","anchorElement","open","children","onOptionSelect","noSuggestionMessage","onClose","onChange","onKeyUp","onKeyDown","trimCustomInput","haveValueAsOption","restoreFocus","props","suggestions","React","Children","child","isValidElement","Option","selectedIndex","setSelectedIndex","useState","index","option","keyPressedDownRef","useRef","KeyDownRegistered","maxResults","setMaxResults","focusedIndex","setFocusedIndex","internalValue","setInternalValue","internalInputRef","totalMatchedLength","setTotalMatchedLength","matchedOptions","setMatchedOptions","suggestionsWidth","setSuggestionsWidth","suggestionsHeight","setSuggestionsHeight","handleKeyUp","event","key","input","isSameKey","lowercaseValue","isSuggestion","label","optionValue","optionProps","handleKeyDown","newIndex","step","getMatchedOptions","results","keywords","k","r","jsx","focusInput","handleUseClose","handleChange","newMatches","handleShowMore","newMaxResults","useLayoutEffect","rect","Popper","jsxs","VStack","clsx","styles","SuggestionItem","Fragment","Button","ZStack","BodyText","FocusRedirect"],"mappings":"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"}
@@ -1,14 +1,14 @@
1
- import { jsx as l } from "react/jsx-runtime";
2
- import { clsx as f } from "clsx";
3
- import n from "react";
4
- import '../../textarea.css';const d = "_textarea_8286394", i = { textarea: d }, b = n.forwardRef(function({ className: r, width: s, height: o, style: x, onChange: t, ...e }, c) {
5
- return /* @__PURE__ */ l(
1
+ import { jsx as n } from "react/jsx-runtime";
2
+ import { clsx as x } from "clsx";
3
+ import f from "react";
4
+ import '../../textarea.css';const d = "_textarea_8286394", i = { textarea: d }, b = f.forwardRef(function({ className: r, width: o, height: s, style: c, onChange: t, ...e }, l) {
5
+ return /* @__PURE__ */ n(
6
6
  "textarea",
7
7
  {
8
- style: { width: s, height: o, ...x },
9
- className: f(r, i.textarea, "tcn-textarea"),
8
+ style: { width: o, height: s, ...c },
9
+ className: x(r, i.textarea, "tcn-textarea", "tcn-control"),
10
10
  "data-is-disabled": e.disabled || !1,
11
- ref: c,
11
+ ref: l,
12
12
  onChange: (a) => {
13
13
  t && t(a.currentTarget.value, a);
14
14
  },
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.js","sources":["../../../src/inputs/textarea/textarea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React from 'react';\nimport { TextareaHTMLAttributes } from 'react';\nimport styles from './textarea.module.css';\n\nexport interface TextareaProps\n extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange'> {\n value?: string;\n width?: string;\n height?: string;\n disabled?: boolean;\n placeholder?: string;\n onChange?: (value: string, event: React.ChangeEvent<HTMLTextAreaElement>) => void;\n}\n\nexport const Textarea = React.forwardRef(function Textarea(\n { className, width, height, style, onChange, ...props }: TextareaProps,\n ref: React.Ref<HTMLTextAreaElement>\n) {\n return (\n <textarea\n style={{ width, height, ...style }}\n className={clsx(className, styles.textarea, 'tcn-textarea')}\n data-is-disabled={props.disabled || false}\n ref={ref}\n onChange={e => {\n onChange && onChange(e.currentTarget.value, e);\n }}\n {...props}\n />\n );\n});\n"],"names":["Textarea","React","className","width","height","style","onChange","props","ref","jsx","clsx","styles","e"],"mappings":";;;oDAeaA,IAAWC,EAAM,WAAW,SACvC,EAAE,WAAAC,GAAW,OAAAC,GAAO,QAAAC,GAAQ,OAAAC,GAAO,UAAAC,GAAU,GAAGC,EAAA,GAChDC,GACA;AACA,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO,EAAE,OAAAN,GAAO,QAAAC,GAAQ,GAAGC,EAAA;AAAA,MAC3B,WAAWK,EAAKR,GAAWS,EAAO,UAAU,cAAc;AAAA,MAC1D,oBAAkBJ,EAAM,YAAY;AAAA,MACpC,KAAAC;AAAA,MACA,UAAU,CAAAI,MAAK;AACb,QAAAN,KAAYA,EAASM,EAAE,cAAc,OAAOA,CAAC;AAAA,MAC/C;AAAA,MACC,GAAGL;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;"}
1
+ {"version":3,"file":"textarea.js","sources":["../../../src/inputs/textarea/textarea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React from 'react';\nimport { TextareaHTMLAttributes } from 'react';\nimport styles from './textarea.module.css';\n\nexport interface TextareaProps\n extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange'> {\n value?: string;\n width?: string;\n height?: string;\n disabled?: boolean;\n placeholder?: string;\n onChange?: (value: string, event: React.ChangeEvent<HTMLTextAreaElement>) => void;\n}\n\nexport const Textarea = React.forwardRef(function Textarea(\n { className, width, height, style, onChange, ...props }: TextareaProps,\n ref: React.Ref<HTMLTextAreaElement>\n) {\n return (\n <textarea\n style={{ width, height, ...style }}\n className={clsx(className, styles.textarea, 'tcn-textarea', 'tcn-control')}\n data-is-disabled={props.disabled || false}\n ref={ref}\n onChange={e => {\n onChange && onChange(e.currentTarget.value, e);\n }}\n {...props}\n />\n );\n});\n"],"names":["Textarea","React","className","width","height","style","onChange","props","ref","jsx","clsx","styles","e"],"mappings":";;;oDAeaA,IAAWC,EAAM,WAAW,SACvC,EAAE,WAAAC,GAAW,OAAAC,GAAO,QAAAC,GAAQ,OAAAC,GAAO,UAAAC,GAAU,GAAGC,EAAA,GAChDC,GACA;AACA,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO,EAAE,OAAAN,GAAO,QAAAC,GAAQ,GAAGC,EAAA;AAAA,MAC3B,WAAWK,EAAKR,GAAWS,EAAO,UAAU,gBAAgB,aAAa;AAAA,MACzE,oBAAkBJ,EAAM,YAAY;AAAA,MACpC,KAAAC;AAAA,MACA,UAAU,CAAAI,MAAK;AACb,QAAAN,KAAYA,EAASM,EAAE,cAAc,OAAOA,CAAC;AAAA,MAC/C;AAAA,MACC,GAAGL;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;"}
@@ -1 +1 @@
1
- {"version":3,"file":"unit_input.d.ts","sourceRoot":"","sources":["../../../src/inputs/unit_input/unit_input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAGtC,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAYnD,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,CAAC;IAChF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;IAC9E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,SAAS,oFAsFpB,CAAC"}
1
+ {"version":3,"file":"unit_input.d.ts","sourceRoot":"","sources":["../../../src/inputs/unit_input/unit_input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAGtC,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAYnD,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,CAAC;IAChF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;IAC9E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,SAAS,oFAsFpB,CAAC"}
@@ -1,76 +1,76 @@
1
- import { jsxs as g, jsx as o } from "react/jsx-runtime";
2
- import y, { useRef as k } from "react";
3
- import { clsx as l } from "clsx";
1
+ import { jsxs as g, jsx as m } from "react/jsx-runtime";
2
+ import y, { useRef as E } from "react";
3
+ import { clsx as o } from "clsx";
4
4
  import "../../utils/click_away_listener.js";
5
5
  import "../../utils/focus_redirect.js";
6
6
  import "../../utils/scroll_away_listener.js";
7
- import { useForkRef as E } from "../../utils/hooks/use_fork_ref.js";
7
+ import { useForkRef as V } from "../../utils/hooks/use_fork_ref.js";
8
8
  import "../../utils/hooks/use_resize_observer.js";
9
9
  import "../../utils/dnd/context.js";
10
10
  import "../../draggable.module-BgelQsuJ.js";
11
- import { HStack as V } from "../../stacks/h_stack.js";
12
- import { Input as h } from "../input/input.js";
13
- import { Select as v } from "../select/select.js";
14
- import { ZStack as w } from "../../stacks/z_stack.js";
15
- import '../../unit_input.css';const H = "_unit-input_4bd8bc8", j = "_unit-input-flex-box_8db2f9b", F = "_unit-input-number_c95f85a", U = "_unit-input-select_1bbbad9", s = { "unit-input": H, "unit-input-flex-box": j, "unit-input-number": F, "unit-input-select": U };
16
- function A(p) {
11
+ import { Input as v } from "../input/input.js";
12
+ import { Select as w } from "../select/select.js";
13
+ import { InputGroup as h } from "../input_group/input_group.js";
14
+ import '../../unit_input.css';const j = "_unit-input_4bd8bc8", k = "_unit-input-flex-box_8db2f9b", F = "_unit-input-number_c95f85a", H = "_unit-input-select_1bbbad9", l = { "unit-input": j, "unit-input-flex-box": k, "unit-input-number": F, "unit-input-select": H };
15
+ function U(p) {
17
16
  return p.replace(/[^.\d-]/g, "").replace(/(?!^)-/g, "").replace(/(\..*?)\.+/g, "$1");
18
17
  }
19
- const W = y.forwardRef(function({
20
- value: B,
18
+ const Q = y.forwardRef(function({
19
+ value: A,
21
20
  unit: r,
22
21
  children: d,
23
22
  onChange: t,
24
23
  inputRef: b,
25
24
  unitRef: x,
26
- disabled: c,
25
+ disabled: s,
27
26
  ...R
28
- }, N) {
29
- const a = k(null), S = E(b, a);
30
- function _(e, u) {
31
- if (u == null)
27
+ }, I) {
28
+ const c = E(null), N = V(b, c);
29
+ function _(u, e) {
30
+ if (e == null)
32
31
  return;
33
- const n = u.currentTarget, f = n.selectionStart || 0, i = A(e), m = Number(i);
34
- n.value = i, i.length < e.length && n.setSelectionRange(f - 1, f - 1), i === "" ? t && t(null, r || "") : isNaN(m) || t && t(m, r || "");
32
+ const n = e.currentTarget, a = n.selectionStart || 0, i = U(u), f = Number(i);
33
+ n.value = i, i.length < u.length && n.setSelectionRange(a - 1, a - 1), i === "" ? t && t(null, r || "") : isNaN(f) || t && t(f, r || "");
35
34
  }
36
- function I(e) {
37
- const u = a.current;
38
- if (u == null)
35
+ function S(u) {
36
+ const e = c.current;
37
+ if (e == null)
39
38
  return;
40
- const n = Number(u.value);
41
- isNaN(n) ? t && t(null, e) : t && t(n, e);
39
+ const n = Number(e.value);
40
+ isNaN(n) ? t && t(null, u) : t && t(n, u);
42
41
  }
43
42
  return /* @__PURE__ */ g(
44
- V,
43
+ h,
45
44
  {
46
- ref: N,
47
- className: l(s["unit-input"], "tcn-unit-input"),
45
+ ref: I,
46
+ className: o(l["unit-input"], "tcn-unit-input"),
48
47
  height: "auto",
49
48
  ...R,
50
49
  children: [
51
- /* @__PURE__ */ o(w, { width: "flex", children: /* @__PURE__ */ o(
52
- h,
50
+ /* @__PURE__ */ m(
51
+ v,
53
52
  {
54
- className: l(s["unit-input-number"], "tcn-unit-input-number"),
55
- ref: S,
53
+ width: "flex",
54
+ className: o(l["unit-input-number"], "tcn-unit-input-number"),
55
+ ref: N,
56
56
  onChange: _,
57
- disabled: c,
57
+ disabled: s,
58
58
  style: {
59
59
  borderEndEndRadius: 0,
60
60
  borderStartEndRadius: 0,
61
61
  textAlign: "start"
62
62
  }
63
63
  }
64
- ) }),
65
- /* @__PURE__ */ o(
66
- v,
64
+ ),
65
+ /* @__PURE__ */ m(
66
+ w,
67
67
  {
68
- className: l(s["unit-input-select"], "tcn-unit-input-select"),
68
+ className: o(l["unit-input-select"], "tcn-unit-input-select"),
69
69
  ref: x,
70
70
  width: "auto",
71
71
  value: r,
72
- onChange: I,
73
- disabled: c,
72
+ onChange: S,
73
+ disabled: s,
74
74
  style: { borderStartStartRadius: 0, borderEndStartRadius: 0 },
75
75
  children: d
76
76
  }
@@ -80,6 +80,6 @@ const W = y.forwardRef(function({
80
80
  );
81
81
  });
82
82
  export {
83
- W as UnitInput
83
+ Q as UnitInput
84
84
  };
85
85
  //# sourceMappingURL=unit_input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"unit_input.js","sources":["../../../src/inputs/unit_input/unit_input.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport { clsx } from 'clsx';\nimport { useForkRef } from '../../utils/index.js';\nimport { HStack, type HStackProps } from '../../stacks/h_stack.js';\nimport { Input } from '../input/input.js';\nimport { Select } from '../select/select.js';\nimport { OptionProps } from '../options/option.js';\nimport styles from './unit_input.module.css';\n\nimport { ZStack } from '../../stacks/z_stack.js';\n\nfunction getDisplayValue(value: string) {\n return value\n .replace(/[^.\\d-]/g, '') // Remove invalid characters\n .replace(/(?!^)-/g, '') // Ensure `-` only at the start\n .replace(/(\\..*?)\\.+/g, '$1'); // Allow only one dot\n}\n\nexport interface UnitInputProps extends Omit<HStackProps, 'onChange' | 'children'> {\n value?: number | null;\n unit?: string;\n children: React.ReactElement<OptionProps> | React.ReactElement<OptionProps>[];\n onChange?: (value: number | null, unit: string) => void;\n inputRef?: React.Ref<HTMLInputElement>;\n unitRef?: React.Ref<HTMLButtonElement>;\n disabled?: boolean;\n}\n\nexport const UnitInput = React.forwardRef(function UnitInput(\n {\n value,\n unit,\n children,\n onChange,\n inputRef,\n unitRef,\n disabled,\n ...props\n }: UnitInputProps,\n ref: React.Ref<HTMLElement>\n) {\n const internalInputRef = useRef<HTMLInputElement>(null);\n const forkedInputRef = useForkRef(inputRef, internalInputRef);\n\n function valueHandler(value: string, event?: React.ChangeEvent<HTMLInputElement>) {\n if (event == null) {\n return;\n }\n\n const input = event.currentTarget;\n const cursorPosition = input.selectionStart || 0;\n const displayValue = getDisplayValue(value);\n const potentialValue = Number(displayValue);\n\n input.value = displayValue;\n\n if (displayValue.length < value.length) {\n input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);\n }\n\n if (displayValue === '') {\n onChange && onChange(null, unit || '');\n } else if (!isNaN(potentialValue)) {\n onChange && onChange(potentialValue, unit || '');\n }\n }\n\n function unitHandler(unit: string) {\n const input = internalInputRef.current;\n if (input == null) {\n return;\n }\n\n const potentialValue = Number(input.value);\n if (isNaN(potentialValue)) {\n onChange && onChange(null, unit);\n } else {\n onChange && onChange(potentialValue, unit);\n }\n }\n\n return (\n <HStack\n ref={ref}\n className={clsx(styles['unit-input'], 'tcn-unit-input')}\n height=\"auto\"\n {...props}\n >\n <ZStack width=\"flex\">\n <Input\n className={clsx(styles['unit-input-number'], 'tcn-unit-input-number')}\n ref={forkedInputRef}\n onChange={valueHandler}\n disabled={disabled}\n style={{\n borderEndEndRadius: 0,\n borderStartEndRadius: 0,\n textAlign: 'start',\n }}\n />\n </ZStack>\n <Select\n className={clsx(styles['unit-input-select'], 'tcn-unit-input-select')}\n ref={unitRef}\n width=\"auto\"\n value={unit}\n onChange={unitHandler}\n disabled={disabled}\n style={{ borderStartStartRadius: 0, borderEndStartRadius: 0 }}\n >\n {children}\n </Select>\n </HStack>\n );\n});\n"],"names":["getDisplayValue","value","UnitInput","React","unit","children","onChange","inputRef","unitRef","disabled","props","ref","internalInputRef","useRef","forkedInputRef","useForkRef","valueHandler","event","input","cursorPosition","displayValue","potentialValue","unitHandler","jsxs","HStack","clsx","styles","jsx","ZStack","Input","Select"],"mappings":";;;;;;;;;;;;;;;AAWA,SAASA,EAAgBC,GAAe;AACtC,SAAOA,EACJ,QAAQ,YAAY,EAAE,EACtB,QAAQ,WAAW,EAAE,EACrB,QAAQ,eAAe,IAAI;AAChC;AAYO,MAAMC,IAAYC,EAAM,WAAW,SACxC;AAAA,EACE,OAAAF;AAAA,EACA,MAAAG;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAmBC,EAAyB,IAAI,GAChDC,IAAiBC,EAAWR,GAAUK,CAAgB;AAE5D,WAASI,EAAaf,GAAegB,GAA6C;AAChF,QAAIA,KAAS;AACX;AAGF,UAAMC,IAAQD,EAAM,eACdE,IAAiBD,EAAM,kBAAkB,GACzCE,IAAepB,EAAgBC,CAAK,GACpCoB,IAAiB,OAAOD,CAAY;AAE1C,IAAAF,EAAM,QAAQE,GAEVA,EAAa,SAASnB,EAAM,UAC9BiB,EAAM,kBAAkBC,IAAiB,GAAGA,IAAiB,CAAC,GAG5DC,MAAiB,KACnBd,KAAYA,EAAS,MAAMF,KAAQ,EAAE,IAC3B,MAAMiB,CAAc,KAC9Bf,KAAYA,EAASe,GAAgBjB,KAAQ,EAAE;AAAA,EAEnD;AAEA,WAASkB,EAAYlB,GAAc;AACjC,UAAMc,IAAQN,EAAiB;AAC/B,QAAIM,KAAS;AACX;AAGF,UAAMG,IAAiB,OAAOH,EAAM,KAAK;AACzC,IAAI,MAAMG,CAAc,IACtBf,KAAYA,EAAS,MAAMF,CAAI,IAE/BE,KAAYA,EAASe,GAAgBjB,CAAI;AAAA,EAE7C;AAEA,SACE,gBAAAmB;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,KAAAb;AAAA,MACA,WAAWc,EAAKC,EAAO,YAAY,GAAG,gBAAgB;AAAA,MACtD,QAAO;AAAA,MACN,GAAGhB;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAiB,EAACC,GAAA,EAAO,OAAM,QACZ,UAAA,gBAAAD;AAAA,UAACE;AAAA,UAAA;AAAA,YACC,WAAWJ,EAAKC,EAAO,mBAAmB,GAAG,uBAAuB;AAAA,YACpE,KAAKZ;AAAA,YACL,UAAUE;AAAA,YACV,UAAAP;AAAA,YACA,OAAO;AAAA,cACL,oBAAoB;AAAA,cACpB,sBAAsB;AAAA,cACtB,WAAW;AAAA,YAAA;AAAA,UACb;AAAA,QAAA,GAEJ;AAAA,QACA,gBAAAkB;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,WAAWL,EAAKC,EAAO,mBAAmB,GAAG,uBAAuB;AAAA,YACpE,KAAKlB;AAAA,YACL,OAAM;AAAA,YACN,OAAOJ;AAAA,YACP,UAAUkB;AAAA,YACV,UAAAb;AAAA,YACA,OAAO,EAAE,wBAAwB,GAAG,sBAAsB,EAAA;AAAA,YAEzD,UAAAJ;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAGN,CAAC;"}
1
+ {"version":3,"file":"unit_input.js","sources":["../../../src/inputs/unit_input/unit_input.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport { clsx } from 'clsx';\nimport { useForkRef } from '../../utils/index.js';\nimport { type HStackProps } from '../../stacks/h_stack.js';\nimport { Input } from '../input/input.js';\nimport { Select } from '../select/select.js';\nimport { OptionProps } from '../options/option.js';\nimport styles from './unit_input.module.css';\n\nimport { InputGroup } from '../input_group/input_group.js';\n\nfunction getDisplayValue(value: string) {\n return value\n .replace(/[^.\\d-]/g, '') // Remove invalid characters\n .replace(/(?!^)-/g, '') // Ensure `-` only at the start\n .replace(/(\\..*?)\\.+/g, '$1'); // Allow only one dot\n}\n\nexport interface UnitInputProps extends Omit<HStackProps, 'onChange' | 'children'> {\n value?: number | null;\n unit?: string;\n children: React.ReactElement<OptionProps> | React.ReactElement<OptionProps>[];\n onChange?: (value: number | null, unit: string) => void;\n inputRef?: React.Ref<HTMLInputElement>;\n unitRef?: React.Ref<HTMLButtonElement>;\n disabled?: boolean;\n}\n\nexport const UnitInput = React.forwardRef(function UnitInput(\n {\n value,\n unit,\n children,\n onChange,\n inputRef,\n unitRef,\n disabled,\n ...props\n }: UnitInputProps,\n ref: React.Ref<HTMLElement>\n) {\n const internalInputRef = useRef<HTMLInputElement>(null);\n const forkedInputRef = useForkRef(inputRef, internalInputRef);\n\n function valueHandler(value: string, event?: React.ChangeEvent<HTMLInputElement>) {\n if (event == null) {\n return;\n }\n\n const input = event.currentTarget;\n const cursorPosition = input.selectionStart || 0;\n const displayValue = getDisplayValue(value);\n const potentialValue = Number(displayValue);\n\n input.value = displayValue;\n\n if (displayValue.length < value.length) {\n input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);\n }\n\n if (displayValue === '') {\n onChange && onChange(null, unit || '');\n } else if (!isNaN(potentialValue)) {\n onChange && onChange(potentialValue, unit || '');\n }\n }\n\n function unitHandler(unit: string) {\n const input = internalInputRef.current;\n if (input == null) {\n return;\n }\n\n const potentialValue = Number(input.value);\n if (isNaN(potentialValue)) {\n onChange && onChange(null, unit);\n } else {\n onChange && onChange(potentialValue, unit);\n }\n }\n\n return (\n <InputGroup\n ref={ref}\n className={clsx(styles['unit-input'], 'tcn-unit-input')}\n height=\"auto\"\n {...props}\n >\n <Input\n width=\"flex\"\n className={clsx(styles['unit-input-number'], 'tcn-unit-input-number')}\n ref={forkedInputRef}\n onChange={valueHandler}\n disabled={disabled}\n style={{\n borderEndEndRadius: 0,\n borderStartEndRadius: 0,\n textAlign: 'start',\n }}\n />\n\n <Select\n className={clsx(styles['unit-input-select'], 'tcn-unit-input-select')}\n ref={unitRef}\n width=\"auto\"\n value={unit}\n onChange={unitHandler}\n disabled={disabled}\n style={{ borderStartStartRadius: 0, borderEndStartRadius: 0 }}\n >\n {children}\n </Select>\n </InputGroup>\n );\n});\n"],"names":["getDisplayValue","value","UnitInput","React","unit","children","onChange","inputRef","unitRef","disabled","props","ref","internalInputRef","useRef","forkedInputRef","useForkRef","valueHandler","event","input","cursorPosition","displayValue","potentialValue","unitHandler","jsxs","InputGroup","clsx","styles","jsx","Input","Select"],"mappings":";;;;;;;;;;;;;;AAWA,SAASA,EAAgBC,GAAe;AACtC,SAAOA,EACJ,QAAQ,YAAY,EAAE,EACtB,QAAQ,WAAW,EAAE,EACrB,QAAQ,eAAe,IAAI;AAChC;AAYO,MAAMC,IAAYC,EAAM,WAAW,SACxC;AAAA,EACE,OAAAF;AAAA,EACA,MAAAG;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAmBC,EAAyB,IAAI,GAChDC,IAAiBC,EAAWR,GAAUK,CAAgB;AAE5D,WAASI,EAAaf,GAAegB,GAA6C;AAChF,QAAIA,KAAS;AACX;AAGF,UAAMC,IAAQD,EAAM,eACdE,IAAiBD,EAAM,kBAAkB,GACzCE,IAAepB,EAAgBC,CAAK,GACpCoB,IAAiB,OAAOD,CAAY;AAE1C,IAAAF,EAAM,QAAQE,GAEVA,EAAa,SAASnB,EAAM,UAC9BiB,EAAM,kBAAkBC,IAAiB,GAAGA,IAAiB,CAAC,GAG5DC,MAAiB,KACnBd,KAAYA,EAAS,MAAMF,KAAQ,EAAE,IAC3B,MAAMiB,CAAc,KAC9Bf,KAAYA,EAASe,GAAgBjB,KAAQ,EAAE;AAAA,EAEnD;AAEA,WAASkB,EAAYlB,GAAc;AACjC,UAAMc,IAAQN,EAAiB;AAC/B,QAAIM,KAAS;AACX;AAGF,UAAMG,IAAiB,OAAOH,EAAM,KAAK;AACzC,IAAI,MAAMG,CAAc,IACtBf,KAAYA,EAAS,MAAMF,CAAI,IAE/BE,KAAYA,EAASe,GAAgBjB,CAAI;AAAA,EAE7C;AAEA,SACE,gBAAAmB;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,KAAAb;AAAA,MACA,WAAWc,EAAKC,EAAO,YAAY,GAAG,gBAAgB;AAAA,MACtD,QAAO;AAAA,MACN,GAAGhB;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAiB;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,WAAWH,EAAKC,EAAO,mBAAmB,GAAG,uBAAuB;AAAA,YACpE,KAAKZ;AAAA,YACL,UAAUE;AAAA,YACV,UAAAP;AAAA,YACA,OAAO;AAAA,cACL,oBAAoB;AAAA,cACpB,sBAAsB;AAAA,cACtB,WAAW;AAAA,YAAA;AAAA,UACb;AAAA,QAAA;AAAA,QAGF,gBAAAkB;AAAA,UAACE;AAAA,UAAA;AAAA,YACC,WAAWJ,EAAKC,EAAO,mBAAmB,GAAG,uBAAuB;AAAA,YACpE,KAAKlB;AAAA,YACL,OAAM;AAAA,YACN,OAAOJ;AAAA,YACP,UAAUkB;AAAA,YACV,UAAAb;AAAA,YACA,OAAO,EAAE,wBAAwB,GAAG,sBAAsB,EAAA;AAAA,YAEzD,UAAAJ;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAGN,CAAC;"}
@@ -1,11 +1,15 @@
1
1
  import { default as React } from 'react';
2
- import { ZStackProps } from '../../stacks/index.js';
2
+ import { BoxProps } from '../../stacks/index.js';
3
3
  export interface FrameOwnProps {
4
4
  isOpen?: boolean;
5
- children?: React.ReactNode;
6
5
  draggable?: boolean;
7
6
  veil?: boolean;
7
+ resizable?: boolean;
8
8
  }
9
- export type FrameProps = ZStackProps & FrameOwnProps;
10
- export declare const Frame: React.ForwardRefExoticComponent<ZStackProps<HTMLElement> & FrameOwnProps & React.RefAttributes<HTMLDialogElement>>;
9
+ export type FrameProps = Omit<BoxProps, 'enableResizeOnLeft' | 'enableResizeOnRight' | 'enableResizeOnTop' | 'enableResizeOnBottom'> & FrameOwnProps;
10
+ export declare const Frame: React.ForwardRefExoticComponent<Omit<BoxProps<HTMLElement>, "enableResizeOnTop" | "enableResizeOnBottom" | "enableResizeOnLeft" | "enableResizeOnRight"> & FrameOwnProps & React.RefAttributes<HTMLElement>>;
11
+ interface FrameDialogProps extends BoxProps {
12
+ }
13
+ export declare const FrameDialog: React.ForwardRefExoticComponent<FrameDialogProps & React.RefAttributes<HTMLElement>>;
14
+ export {};
11
15
  //# sourceMappingURL=frame.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../../src/overlay/frame/frame.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAQjE,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;AAErD,eAAO,MAAM,KAAK,oHA+BhB,CAAC"}
1
+ {"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../../src/overlay/frame/frame.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAOnE,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,CAC3B,QAAQ,EACN,oBAAoB,GACpB,qBAAqB,GACrB,mBAAmB,GACnB,sBAAsB,CACzB,GACC,aAAa,CAAC;AAEhB,eAAO,MAAM,KAAK,8MAiChB,CAAC;AACH,UAAU,gBAAiB,SAAQ,QAAQ;CAAG;AAE9C,eAAO,MAAM,WAAW,sFA6FvB,CAAC"}
@@ -1,35 +1,99 @@
1
- import { jsx as r } from "react/jsx-runtime";
2
- import c from "react";
3
- import "../../stacks/box/box.js";
1
+ import { jsx as m } from "react/jsx-runtime";
2
+ import { clsx as O } from "clsx";
3
+ import y, { useCallback as _ } from "react";
4
+ import { flushSync as l } from "react-dom";
5
+ import { Box as k } from "../../stacks/box/box.js";
4
6
  import "../../stacks/h_collapsible_box.js";
5
7
  import "../../stacks/h_stack.js";
6
8
  import "../../stacks/spacer.js";
7
9
  import "../../stacks/v_collapsible_box.js";
8
10
  import "../../stacks/v_stack.js";
9
- import { ZStack as t } from "../../stacks/z_stack.js";
10
- import { Draggable as s } from "../../utils/dnd/draggable/draggable.js";
11
- import { Portal as n } from "../portal/portal.js";
12
- import { clsx as p } from "clsx";
13
- import '../../frame.css';const d = "_frame_ce82001", h = { frame: d }, D = c.forwardRef(function({
14
- children: e,
15
- isOpen: m = !1,
16
- draggable: o = !0,
17
- veil: a = !1,
18
- className: i,
19
- ...f
20
- }, l) {
21
- return m ? /* @__PURE__ */ r(n, { children: /* @__PURE__ */ r(t, { width: "100%", height: "100%", "data-is-veil": a, className: "tcn-frame-veil", children: /* @__PURE__ */ r(s, { draggable: o, children: /* @__PURE__ */ r(
22
- t,
11
+ import { ZStack as w } from "../../stacks/z_stack.js";
12
+ import { useDragContainer as z } from "../../utils/dnd/context.js";
13
+ import { Draggable as C } from "../../utils/dnd/draggable/draggable.js";
14
+ import { Portal as B } from "../portal/portal.js";
15
+ import '../../frame.css';const N = "_frame-dialog_2a77c1d", S = { "frame-dialog": N }, Q = y.forwardRef(function({
16
+ children: c,
17
+ isOpen: d = !1,
18
+ draggable: n = !0,
19
+ veil: h = !1,
20
+ resizable: t = !0,
21
+ className: s,
22
+ ...a
23
+ }, p) {
24
+ return d ? /* @__PURE__ */ m(B, { children: /* @__PURE__ */ m(w, { width: "100%", height: "100%", "data-is-veil": h, className: "tcn-frame-veil", children: /* @__PURE__ */ m(C, { draggable: n, children: /* @__PURE__ */ m(
25
+ b,
23
26
  {
24
- as: "dialog",
25
- ref: l,
26
- className: p(h.frame, "tcn-frame", i),
27
- ...f,
28
- children: e
27
+ className: s,
28
+ ref: p,
29
+ enableResizeOnLeft: t,
30
+ enableResizeOnRight: t,
31
+ enableResizeOnTop: t,
32
+ enableResizeOnBottom: t,
33
+ draggable: n,
34
+ ...a,
35
+ children: c
29
36
  }
30
37
  ) }) }) }) : null;
31
- });
38
+ }), b = y.forwardRef(
39
+ function({
40
+ as: c = "div",
41
+ role: d = "dialog",
42
+ children: n,
43
+ className: h,
44
+ draggable: t,
45
+ onWidthResize: s,
46
+ onHeightResize: a,
47
+ ...p
48
+ }, P) {
49
+ const r = z(), g = y.useCallback(
50
+ (u, e, x, i, f) => {
51
+ t && (f || (e === "right" && l(() => {
52
+ r.setPosition((o) => ({
53
+ x: o.x + i / 2,
54
+ y: o.y
55
+ }));
56
+ }), e === "left" && l(() => {
57
+ r.setPosition((o) => ({
58
+ x: o.x - i / 2,
59
+ y: o.y
60
+ }));
61
+ }), s?.(u, e, x, i, f)));
62
+ },
63
+ [s, r, t]
64
+ ), F = _(
65
+ (u, e, x, i, f) => {
66
+ t && (f || (e === "bottom" && l(() => {
67
+ r.setPosition((o) => ({
68
+ x: o.x,
69
+ y: o.y + i / 2
70
+ }));
71
+ }), e === "top" && l(() => {
72
+ r.setPosition((o) => ({
73
+ x: o.x,
74
+ y: o.y - i / 2
75
+ }));
76
+ }), a?.(u, e, x, i, f)));
77
+ },
78
+ [a, r, t]
79
+ );
80
+ return /* @__PURE__ */ m(
81
+ k,
82
+ {
83
+ className: O(S["frame-dialog"], "tcn-frame-dialog", h),
84
+ ref: P,
85
+ onWidthResize: g,
86
+ onHeightResize: F,
87
+ as: c,
88
+ role: d,
89
+ ...p,
90
+ children: n
91
+ }
92
+ );
93
+ }
94
+ );
32
95
  export {
33
- D as Frame
96
+ Q as Frame,
97
+ b as FrameDialog
34
98
  };
35
99
  //# sourceMappingURL=frame.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"frame.js","sources":["../../../src/overlay/frame/frame.tsx"],"sourcesContent":["import React from 'react';\nimport { ZStack, type ZStackProps } from '../../stacks/index.js';\nimport { Draggable } from '../../utils/dnd/draggable/draggable.js';\nimport { Portal } from '../portal/portal.js';\n\n// Styles\nimport { clsx } from 'clsx';\nimport styles from './frame.module.css';\n\nexport interface FrameOwnProps {\n isOpen?: boolean;\n children?: React.ReactNode;\n draggable?: boolean;\n veil?: boolean;\n}\n\nexport type FrameProps = ZStackProps & FrameOwnProps;\n\nexport const Frame = React.forwardRef<HTMLDialogElement, FrameProps>(function Frame(\n {\n children,\n isOpen = false,\n draggable = true,\n veil = false,\n className,\n ...rest\n }: FrameProps,\n ref\n) {\n if (!isOpen) {\n return null;\n }\n\n return (\n <Portal>\n <ZStack width=\"100%\" height=\"100%\" data-is-veil={veil} className=\"tcn-frame-veil\">\n <Draggable draggable={draggable}>\n <ZStack\n as=\"dialog\"\n ref={ref}\n className={clsx(styles['frame'], 'tcn-frame', className)}\n {...rest}\n >\n {children}\n </ZStack>\n </Draggable>\n </ZStack>\n </Portal>\n );\n});\n"],"names":["Frame","React","children","isOpen","draggable","veil","className","rest","ref","jsx","Portal","ZStack","Draggable","clsx","styles"],"mappings":";;;;;;;;;;;;8CAkBaA,IAAQC,EAAM,WAA0C,SACnE;AAAA,EACE,UAAAC;AAAA,EACA,QAAAC,IAAS;AAAA,EACT,WAAAC,IAAY;AAAA,EACZ,MAAAC,IAAO;AAAA,EACP,WAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,SAAKL,IAKH,gBAAAM,EAACC,GAAA,EACC,UAAA,gBAAAD,EAACE,GAAA,EAAO,OAAM,QAAO,QAAO,QAAO,gBAAcN,GAAM,WAAU,kBAC/D,UAAA,gBAAAI,EAACG,KAAU,WAAAR,GACT,UAAA,gBAAAK;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,IAAG;AAAA,MACH,KAAAH;AAAA,MACA,WAAWK,EAAKC,EAAO,OAAU,aAAaR,CAAS;AAAA,MACtD,GAAGC;AAAA,MAEH,UAAAL;AAAA,IAAA;AAAA,EAAA,EACH,CACF,GACF,GACF,IAjBO;AAmBX,CAAC;"}
1
+ {"version":3,"file":"frame.js","sources":["../../../src/overlay/frame/frame.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React, { useCallback } from 'react';\nimport { flushSync } from 'react-dom';\nimport { Box, ZStack, type BoxProps } from '../../stacks/index.js';\nimport { useDragContainer } from '../../utils/dnd/context.js';\nimport { Draggable } from '../../utils/dnd/draggable/draggable.js';\nimport { Portal } from '../portal/portal.js';\n\n// Styles\nimport styles from './frame.module.css';\nexport interface FrameOwnProps {\n isOpen?: boolean;\n draggable?: boolean;\n veil?: boolean;\n resizable?: boolean;\n}\n\nexport type FrameProps = Omit<\n BoxProps,\n | 'enableResizeOnLeft'\n | 'enableResizeOnRight'\n | 'enableResizeOnTop'\n | 'enableResizeOnBottom'\n> &\n FrameOwnProps;\n\nexport const Frame = React.forwardRef<HTMLElement, FrameProps>(function Frame(\n {\n children,\n isOpen = false,\n draggable = true,\n veil = false,\n resizable = true,\n className,\n ...rest\n }: FrameProps,\n ref\n) {\n if (!isOpen) return null;\n return (\n <Portal>\n <ZStack width=\"100%\" height=\"100%\" data-is-veil={veil} className=\"tcn-frame-veil\">\n <Draggable draggable={draggable}>\n <FrameDialog\n className={className}\n ref={ref}\n enableResizeOnLeft={resizable}\n enableResizeOnRight={resizable}\n enableResizeOnTop={resizable}\n enableResizeOnBottom={resizable}\n draggable={draggable}\n {...rest}\n >\n {children}\n </FrameDialog>\n </Draggable>\n </ZStack>\n </Portal>\n );\n});\ninterface FrameDialogProps extends BoxProps {}\n\nexport const FrameDialog = React.forwardRef<HTMLElement, FrameDialogProps>(\n function FrameDialog(\n {\n as = 'div',\n role = 'dialog',\n children,\n className,\n draggable,\n onWidthResize,\n onHeightResize,\n ...rest\n }: FrameDialogProps,\n ref: React.Ref<HTMLElement>\n ) {\n const drag = useDragContainer();\n\n const handleWidthResize = React.useCallback(\n (\n width: number,\n origin: 'left' | 'right',\n totalDelta: number,\n currentDelta: number,\n atLimit: boolean\n ) => {\n if (!draggable) return;\n if (atLimit) return;\n if (origin === 'right') {\n flushSync(() => {\n drag.setPosition(prev => ({\n x: prev.x + currentDelta / 2,\n y: prev.y,\n }));\n });\n }\n if (origin === 'left') {\n flushSync(() => {\n drag.setPosition(prev => ({\n x: prev.x - currentDelta / 2,\n y: prev.y,\n }));\n });\n }\n\n onWidthResize?.(width, origin, totalDelta, currentDelta, atLimit);\n },\n [onWidthResize, drag, draggable]\n );\n\n const handleHeightResize = useCallback(\n (\n height: number,\n origin: 'top' | 'bottom',\n totalDelta: number,\n currentDelta: number,\n atLimit: boolean\n ) => {\n if (!draggable) return;\n if (atLimit) return;\n if (origin === 'bottom') {\n flushSync(() => {\n drag.setPosition(prev => ({\n x: prev.x,\n y: prev.y + currentDelta / 2,\n }));\n });\n }\n if (origin === 'top') {\n flushSync(() => {\n drag.setPosition(prev => ({\n x: prev.x,\n y: prev.y - currentDelta / 2,\n }));\n });\n }\n onHeightResize?.(height, origin, totalDelta, currentDelta, atLimit);\n },\n [onHeightResize, drag, draggable]\n );\n\n return (\n <Box\n className={clsx(styles['frame-dialog'], 'tcn-frame-dialog', className)}\n ref={ref}\n onWidthResize={handleWidthResize}\n onHeightResize={handleHeightResize}\n as={as}\n role={role}\n {...rest}\n >\n {children}\n </Box>\n );\n }\n);\n"],"names":["Frame","React","children","isOpen","draggable","veil","resizable","className","rest","ref","jsx","Portal","ZStack","Draggable","FrameDialog","as","role","onWidthResize","onHeightResize","drag","useDragContainer","handleWidthResize","width","origin","totalDelta","currentDelta","atLimit","flushSync","prev","handleHeightResize","useCallback","height","Box","clsx","styles"],"mappings":";;;;;;;;;;;;;;8DA0BaA,IAAQC,EAAM,WAAoC,SAC7D;AAAA,EACE,UAAAC;AAAA,EACA,QAAAC,IAAS;AAAA,EACT,WAAAC,IAAY;AAAA,EACZ,MAAAC,IAAO;AAAA,EACP,WAAAC,IAAY;AAAA,EACZ,WAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,SAAKN,IAEH,gBAAAO,EAACC,GAAA,EACC,UAAA,gBAAAD,EAACE,GAAA,EAAO,OAAM,QAAO,QAAO,QAAO,gBAAcP,GAAM,WAAU,kBAC/D,UAAA,gBAAAK,EAACG,KAAU,WAAAT,GACT,UAAA,gBAAAM;AAAA,IAACI;AAAA,IAAA;AAAA,MACC,WAAAP;AAAA,MACA,KAAAE;AAAA,MACA,oBAAoBH;AAAA,MACpB,qBAAqBA;AAAA,MACrB,mBAAmBA;AAAA,MACnB,sBAAsBA;AAAA,MACtB,WAAAF;AAAA,MACC,GAAGI;AAAA,MAEH,UAAAN;AAAA,IAAA;AAAA,EAAA,EACH,CACF,GACF,GACF,IAnBkB;AAqBtB,CAAC,GAGYY,IAAcb,EAAM;AAAA,EAC/B,SACE;AAAA,IACE,IAAAc,IAAK;AAAA,IACL,MAAAC,IAAO;AAAA,IACP,UAAAd;AAAA,IACA,WAAAK;AAAA,IACA,WAAAH;AAAA,IACA,eAAAa;AAAA,IACA,gBAAAC;AAAA,IACA,GAAGV;AAAA,EAAA,GAELC,GACA;AACA,UAAMU,IAAOC,EAAA,GAEPC,IAAoBpB,EAAM;AAAA,MAC9B,CACEqB,GACAC,GACAC,GACAC,GACAC,MACG;AACH,QAAKtB,MACDsB,MACAH,MAAW,WACbI,EAAU,MAAM;AACd,UAAAR,EAAK,YAAY,CAAAS,OAAS;AAAA,YACxB,GAAGA,EAAK,IAAIH,IAAe;AAAA,YAC3B,GAAGG,EAAK;AAAA,UAAA,EACR;AAAA,QACJ,CAAC,GAECL,MAAW,UACbI,EAAU,MAAM;AACd,UAAAR,EAAK,YAAY,CAAAS,OAAS;AAAA,YACxB,GAAGA,EAAK,IAAIH,IAAe;AAAA,YAC3B,GAAGG,EAAK;AAAA,UAAA,EACR;AAAA,QACJ,CAAC,GAGHX,IAAgBK,GAAOC,GAAQC,GAAYC,GAAcC,CAAO;AAAA,MAClE;AAAA,MACA,CAACT,GAAeE,GAAMf,CAAS;AAAA,IAAA,GAG3ByB,IAAqBC;AAAA,MACzB,CACEC,GACAR,GACAC,GACAC,GACAC,MACG;AACH,QAAKtB,MACDsB,MACAH,MAAW,YACbI,EAAU,MAAM;AACd,UAAAR,EAAK,YAAY,CAAAS,OAAS;AAAA,YACxB,GAAGA,EAAK;AAAA,YACR,GAAGA,EAAK,IAAIH,IAAe;AAAA,UAAA,EAC3B;AAAA,QACJ,CAAC,GAECF,MAAW,SACbI,EAAU,MAAM;AACd,UAAAR,EAAK,YAAY,CAAAS,OAAS;AAAA,YACxB,GAAGA,EAAK;AAAA,YACR,GAAGA,EAAK,IAAIH,IAAe;AAAA,UAAA,EAC3B;AAAA,QACJ,CAAC,GAEHP,IAAiBa,GAAQR,GAAQC,GAAYC,GAAcC,CAAO;AAAA,MACpE;AAAA,MACA,CAACR,GAAgBC,GAAMf,CAAS;AAAA,IAAA;AAGlC,WACE,gBAAAM;AAAA,MAACsB;AAAA,MAAA;AAAA,QACC,WAAWC,EAAKC,EAAO,cAAc,GAAG,oBAAoB3B,CAAS;AAAA,QACrE,KAAAE;AAAA,QACA,eAAeY;AAAA,QACf,gBAAgBQ;AAAA,QAChB,IAAAd;AAAA,QACA,MAAAC;AAAA,QACC,GAAGR;AAAA,QAEH,UAAAN;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"dismissal_decorator.js","sources":["../../../../src/overlay/popper/base/dismissal_decorator.tsx"],"sourcesContent":["import { forwardRef, type PropsWithChildren } from 'react';\nimport { ClickAwayListener } from '../../../utils/click_away_listener.js';\nimport { ScrollAwayListener } from '../../../utils/scroll_away_listener.js';\nimport { MouseLeaveRegion } from '../../../utils/mouse_leave_region.js';\n\nexport enum PopperDismissal {\n CLICK_AWAY = 'clickAway',\n SCROLL_AWAY = 'scrollAway',\n MOUSE_LEAVE = 'mouseLeave',\n VEIL_CLICK = 'veilClick',\n}\n\nexport interface PopperDismissalDecoratorProps {\n dismissals?: PopperDismissal[];\n onDismissal?: (dismissal: PopperDismissal) => void;\n isException?: (dismissal: PopperDismissal, target: HTMLElement) => boolean;\n acceptedRefs?: React.RefObject<HTMLElement>[];\n}\n\nexport const PopperDismissalDecorator = forwardRef<\n HTMLElement,\n PropsWithChildren<PopperDismissalDecoratorProps>\n>(function DismissalDecorator(\n { onDismissal, isException, dismissals = [], children, acceptedRefs = [] },\n ref\n) {\n const hasClickAway = dismissals.includes(PopperDismissal.CLICK_AWAY);\n const hasScrollAway = dismissals.includes(PopperDismissal.SCROLL_AWAY);\n const hasMouseLeave = dismissals.includes(PopperDismissal.MOUSE_LEAVE);\n // TODO:\n // const hasVeilClick = dismissals.includes(PopperDismissal.VEIL_CLICK);\n\n const buildHandleDismissal = (dismissal: PopperDismissal) => () => {\n onDismissal?.(dismissal);\n };\n\n function buildExceptionHandler(dismissal: PopperDismissal) {\n if (dismissal in dismissals) {\n return target => isException?.(dismissal, target) ?? false;\n }\n return () => false;\n }\n\n let content: React.ReactNode = (\n <>\n {children}\n {hasMouseLeave && (\n <MouseLeaveRegion\n elementsRefs={acceptedRefs}\n onMouseLeave={buildHandleDismissal(PopperDismissal.MOUSE_LEAVE)}\n />\n )}\n </>\n );\n\n if (hasScrollAway) {\n content = (\n <ScrollAwayListener\n onScrollAway={buildHandleDismissal(PopperDismissal.SCROLL_AWAY)}\n isException={buildExceptionHandler(PopperDismissal.SCROLL_AWAY)}\n >\n {content}\n </ScrollAwayListener>\n );\n }\n\n if (hasClickAway) {\n content = (\n <ClickAwayListener\n onClickAway={buildHandleDismissal(PopperDismissal.CLICK_AWAY)}\n refs={acceptedRefs}\n isException={buildExceptionHandler(PopperDismissal.CLICK_AWAY)}\n >\n {content}\n </ClickAwayListener>\n );\n }\n\n return content;\n});\n"],"names":["PopperDismissal","PopperDismissalDecorator","forwardRef","onDismissal","isException","dismissals","children","acceptedRefs","ref","hasClickAway","hasScrollAway","hasMouseLeave","buildHandleDismissal","dismissal","buildExceptionHandler","target","content","jsxs","Fragment","jsx","MouseLeaveRegion","ScrollAwayListener","ClickAwayListener"],"mappings":";;;;;AAKO,IAAKA,sBAAAA,OACVA,EAAA,aAAa,aACbA,EAAA,cAAc,cACdA,EAAA,cAAc,cACdA,EAAA,aAAa,aAJHA,IAAAA,KAAA,CAAA,CAAA;AAcL,MAAMC,IAA2BC,EAGtC,SACA,EAAE,aAAAC,GAAa,aAAAC,GAAa,YAAAC,IAAa,CAAA,GAAI,UAAAC,GAAU,cAAAC,IAAe,CAAA,EAAC,GACvEC,GACA;AACA,QAAMC,IAAeJ,EAAW;AAAA,IAAS;AAAA;AAAA,EAAA,GACnCK,IAAgBL,EAAW;AAAA,IAAS;AAAA;AAAA,EAAA,GACpCM,IAAgBN,EAAW;AAAA,IAAS;AAAA;AAAA,EAAA,GAIpCO,IAAuB,CAACC,MAA+B,MAAM;AACjE,IAAAV,IAAcU,CAAS;AAAA,EACzB;AAEA,WAASC,EAAsBD,GAA4B;AACzD,WAAIA,KAAaR,IACR,CAAAU,MAAUX,IAAcS,GAAWE,CAAM,KAAK,KAEhD,MAAM;AAAA,EACf;AAEA,MAAIC,IACF,gBAAAC,EAAAC,GAAA,EACG,UAAA;AAAA,IAAAZ;AAAA,IACAK,KACC,gBAAAQ;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,cAAcb;AAAA,QACd,cAAcK;AAAA,UAAqB;AAAA;AAAA,QAAA;AAAA,MAA2B;AAAA,IAAA;AAAA,EAChE,GAEJ;AAGF,SAAIF,MACFM,IACE,gBAAAG;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,cAAcT;AAAA,QAAqB;AAAA;AAAA,MAAA;AAAA,MACnC,aAAaE;AAAA,QAAsB;AAAA;AAAA,MAAA;AAAA,MAElC,UAAAE;AAAA,IAAA;AAAA,EAAA,IAKHP,MACFO,IACE,gBAAAG;AAAA,IAACG;AAAA,IAAA;AAAA,MACC,aAAaV;AAAA,QAAqB;AAAA;AAAA,MAAA;AAAA,MAClC,MAAML;AAAA,MACN,aAAaO;AAAA,QAAsB;AAAA;AAAA,MAAA;AAAA,MAElC,UAAAE;AAAA,IAAA;AAAA,EAAA,IAKAA;AACT,CAAC;"}
1
+ {"version":3,"file":"dismissal_decorator.js","sources":["../../../../src/overlay/popper/base/dismissal_decorator.tsx"],"sourcesContent":["import { forwardRef, type PropsWithChildren } from 'react';\nimport { ClickAwayListener } from '../../../utils/click_away_listener.js';\nimport { ScrollAwayListener } from '../../../utils/scroll_away_listener.js';\nimport { MouseLeaveRegion } from '../../../utils/mouse_leave_region.js';\n\nexport enum PopperDismissal {\n CLICK_AWAY = 'clickAway',\n SCROLL_AWAY = 'scrollAway',\n MOUSE_LEAVE = 'mouseLeave',\n VEIL_CLICK = 'veilClick',\n}\n\nexport interface PopperDismissalDecoratorProps {\n dismissals?: PopperDismissal[];\n onDismissal?: (dismissal: PopperDismissal) => void;\n isException?: (dismissal: PopperDismissal, target: HTMLElement) => boolean;\n acceptedRefs?: React.RefObject<HTMLElement>[];\n}\n\nexport const PopperDismissalDecorator = forwardRef<\n HTMLElement,\n PropsWithChildren<PopperDismissalDecoratorProps>\n>(function DismissalDecorator(\n { onDismissal, isException, dismissals = [], children, acceptedRefs = [] },\n ref\n) {\n const hasClickAway = dismissals.includes(PopperDismissal.CLICK_AWAY);\n const hasScrollAway = dismissals.includes(PopperDismissal.SCROLL_AWAY);\n const hasMouseLeave = dismissals.includes(PopperDismissal.MOUSE_LEAVE);\n // TODO:\n // const hasVeilClick = dismissals.includes(PopperDismissal.VEIL_CLICK);\n\n const buildHandleDismissal = (dismissal: PopperDismissal) => () => {\n onDismissal?.(dismissal);\n };\n\n function buildExceptionHandler(dismissal: PopperDismissal) {\n if (dismissal in dismissals) {\n return (target: HTMLElement) => isException?.(dismissal, target) ?? false;\n }\n return () => false;\n }\n\n let content: React.ReactNode = (\n <>\n {children}\n {hasMouseLeave && (\n <MouseLeaveRegion\n elementsRefs={acceptedRefs}\n onMouseLeave={buildHandleDismissal(PopperDismissal.MOUSE_LEAVE)}\n />\n )}\n </>\n );\n\n if (hasScrollAway) {\n content = (\n <ScrollAwayListener\n onScrollAway={buildHandleDismissal(PopperDismissal.SCROLL_AWAY)}\n isException={buildExceptionHandler(PopperDismissal.SCROLL_AWAY)}\n >\n {content}\n </ScrollAwayListener>\n );\n }\n\n if (hasClickAway) {\n content = (\n <ClickAwayListener\n onClickAway={buildHandleDismissal(PopperDismissal.CLICK_AWAY)}\n refs={acceptedRefs}\n isException={buildExceptionHandler(PopperDismissal.CLICK_AWAY)}\n >\n {content}\n </ClickAwayListener>\n );\n }\n\n return content;\n});\n"],"names":["PopperDismissal","PopperDismissalDecorator","forwardRef","onDismissal","isException","dismissals","children","acceptedRefs","ref","hasClickAway","hasScrollAway","hasMouseLeave","buildHandleDismissal","dismissal","buildExceptionHandler","target","content","jsxs","Fragment","jsx","MouseLeaveRegion","ScrollAwayListener","ClickAwayListener"],"mappings":";;;;;AAKO,IAAKA,sBAAAA,OACVA,EAAA,aAAa,aACbA,EAAA,cAAc,cACdA,EAAA,cAAc,cACdA,EAAA,aAAa,aAJHA,IAAAA,KAAA,CAAA,CAAA;AAcL,MAAMC,IAA2BC,EAGtC,SACA,EAAE,aAAAC,GAAa,aAAAC,GAAa,YAAAC,IAAa,CAAA,GAAI,UAAAC,GAAU,cAAAC,IAAe,CAAA,EAAC,GACvEC,GACA;AACA,QAAMC,IAAeJ,EAAW;AAAA,IAAS;AAAA;AAAA,EAAA,GACnCK,IAAgBL,EAAW;AAAA,IAAS;AAAA;AAAA,EAAA,GACpCM,IAAgBN,EAAW;AAAA,IAAS;AAAA;AAAA,EAAA,GAIpCO,IAAuB,CAACC,MAA+B,MAAM;AACjE,IAAAV,IAAcU,CAAS;AAAA,EACzB;AAEA,WAASC,EAAsBD,GAA4B;AACzD,WAAIA,KAAaR,IACR,CAACU,MAAwBX,IAAcS,GAAWE,CAAM,KAAK,KAE/D,MAAM;AAAA,EACf;AAEA,MAAIC,IACF,gBAAAC,EAAAC,GAAA,EACG,UAAA;AAAA,IAAAZ;AAAA,IACAK,KACC,gBAAAQ;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,cAAcb;AAAA,QACd,cAAcK;AAAA,UAAqB;AAAA;AAAA,QAAA;AAAA,MAA2B;AAAA,IAAA;AAAA,EAChE,GAEJ;AAGF,SAAIF,MACFM,IACE,gBAAAG;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,cAAcT;AAAA,QAAqB;AAAA;AAAA,MAAA;AAAA,MACnC,aAAaE;AAAA,QAAsB;AAAA;AAAA,MAAA;AAAA,MAElC,UAAAE;AAAA,IAAA;AAAA,EAAA,IAKHP,MACFO,IACE,gBAAAG;AAAA,IAACG;AAAA,IAAA;AAAA,MACC,aAAaV;AAAA,QAAqB;AAAA;AAAA,MAAA;AAAA,MAClC,MAAML;AAAA,MACN,aAAaO;AAAA,QAAsB;AAAA;AAAA,MAAA;AAAA,MAElC,UAAAE;AAAA,IAAA;AAAA,EAAA,IAKAA;AACT,CAAC;"}
@@ -1 +1 @@
1
- {"version":3,"file":"popper.d.ts","sourceRoot":"","sources":["../../../../src/overlay/popper/legacy/popper.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4C,MAAM,OAAO,CAAC;AAKjE,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC,cAAc,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC7C,cAAc,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC9C,gBAAgB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC;IACxE,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;IAC/C,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC;IACxD,qBAAqB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC;IACzD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAGD,wBAAgB,MAAM,CAAC,EACrB,aAAa,EACb,cAAyB,EACzB,cAAsB,EACtB,cAAkB,EAClB,gBAA0B,EAC1B,gBAA0B,EAC1B,gBAAoB,EACpB,YAAoB,EACpB,IAAY,EACZ,WAAW,EACX,aAAkB,EAClB,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,gBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,GACtB,EAAE,WAAW,kDA8Kb"}
1
+ {"version":3,"file":"popper.d.ts","sourceRoot":"","sources":["../../../../src/overlay/popper/legacy/popper.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4C,MAAM,OAAO,CAAC;AAKjE,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC,cAAc,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC7C,cAAc,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC9C,gBAAgB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC;IACxE,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;IAC/C,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC;IACxD,qBAAqB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC;IACzD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAGD,wBAAgB,MAAM,CAAC,EACrB,aAAa,EACb,cAAyB,EACzB,cAAsB,EACtB,cAAkB,EAClB,gBAA0B,EAC1B,gBAA0B,EAC1B,gBAAoB,EACpB,YAAoB,EACpB,IAAY,EACZ,WAAW,EACX,aAAkB,EAClB,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,gBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,GACtB,EAAE,WAAW,kDAkLb"}