@keboola/design 13.1.2 → 13.2.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 (318) hide show
  1. package/AGENTS.md +63 -5
  2. package/CHANGELOG.md +49 -0
  3. package/COMPONENT-API.md +8 -8
  4. package/dist/{AIKit-BVCWP9Ks.js → AIKit-C5FbKjwa.js} +22 -22
  5. package/dist/AIKit-C5FbKjwa.js.map +1 -0
  6. package/dist/{Alert-UI-CIs-1.js → Alert-DuAGeYyM.js} +7 -7
  7. package/dist/{Alert-UI-CIs-1.js.map → Alert-DuAGeYyM.js.map} +1 -1
  8. package/dist/{AlertModal-mbSnuuka.js → AlertModal-BDle9ZVQ.js} +6 -6
  9. package/dist/AlertModal-BDle9ZVQ.js.map +1 -0
  10. package/dist/{AppShell-WSQabK8r.js → AppShell-B03fj1j7.js} +2 -2
  11. package/dist/{AppShell-WSQabK8r.js.map → AppShell-B03fj1j7.js.map} +1 -1
  12. package/dist/{AutoSaveTextarea-C5iIr2Ts.js → AutoSaveTextarea-jiqNeeE4.js} +3 -3
  13. package/dist/{AutoSaveTextarea-C5iIr2Ts.js.map → AutoSaveTextarea-jiqNeeE4.js.map} +1 -1
  14. package/dist/{Badge-Dz0cj6rj.js → Badge-Ba3epgcI.js} +2 -2
  15. package/dist/{Badge-Dz0cj6rj.js.map → Badge-Ba3epgcI.js.map} +1 -1
  16. package/dist/{BrandEditor-P8OZX2hi.js → BrandEditor-Dq168RJc.js} +154 -16
  17. package/dist/BrandEditor-Dq168RJc.js.map +1 -0
  18. package/dist/{BrandLogo-CKpVSZb6.js → BrandLogo-BfITD0im.js} +2 -2
  19. package/dist/{BrandLogo-CKpVSZb6.js.map → BrandLogo-BfITD0im.js.map} +1 -1
  20. package/dist/{Breadcrumb-BUoAZyhO.js → Breadcrumb-CUyYu5Bi.js} +10 -10
  21. package/dist/Breadcrumb-CUyYu5Bi.js.map +1 -0
  22. package/dist/{Button-B21oVcPU.js → Button-D2JqBAq7.js} +199 -7
  23. package/dist/Button-D2JqBAq7.js.map +1 -0
  24. package/dist/{Calendar-DFtmZzbF.js → Calendar-BnKi1kPu.js} +4 -4
  25. package/dist/{Calendar-DFtmZzbF.js.map → Calendar-BnKi1kPu.js.map} +1 -1
  26. package/dist/{Card-BQmBWHXl.js → Card-Bpc_ZlL4.js} +3 -3
  27. package/dist/Card-Bpc_ZlL4.js.map +1 -0
  28. package/dist/{Checkbox-8yIIgY7g.js → Checkbox-D9rafoKh.js} +6 -6
  29. package/dist/Checkbox-D9rafoKh.js.map +1 -0
  30. package/dist/{Clipboard-_xf6hMDD.js → Clipboard-BHWUodAx.js} +3 -3
  31. package/dist/{Clipboard-_xf6hMDD.js.map → Clipboard-BHWUodAx.js.map} +1 -1
  32. package/dist/{ClipboardButton-srUgWgwH.js → ClipboardButton-Urg-kZbh.js} +4 -4
  33. package/dist/{ClipboardButton-srUgWgwH.js.map → ClipboardButton-Urg-kZbh.js.map} +1 -1
  34. package/dist/{CodeEditor-Df7VVx08.js → CodeEditor-Y0iE-SwV.js} +5 -5
  35. package/dist/{CodeEditor-Df7VVx08.js.map → CodeEditor-Y0iE-SwV.js.map} +1 -1
  36. package/dist/{Collapsible-BQXWEOBC.js → Collapsible-DD4xTL75.js} +2 -2
  37. package/dist/{Collapsible-BQXWEOBC.js.map → Collapsible-DD4xTL75.js.map} +1 -1
  38. package/dist/{ColorInput-B3gBZ8Ya.js → ColorInput-D1nC0X6i.js} +5 -5
  39. package/dist/{ColorInput-B3gBZ8Ya.js.map → ColorInput-D1nC0X6i.js.map} +1 -1
  40. package/dist/{ColorModeSwitch-D8Cki137.js → ColorModeSwitch-Cxee8jnB.js} +4 -4
  41. package/dist/{ColorModeSwitch-D8Cki137.js.map → ColorModeSwitch-Cxee8jnB.js.map} +1 -1
  42. package/dist/{Combobox-BNhW0TDB.js → Combobox-B1Kjoy5J.js} +9 -9
  43. package/dist/Combobox-B1Kjoy5J.js.map +1 -0
  44. package/dist/{Command-BQPiZCNz.js → Command-BuOA3V18.js} +5 -5
  45. package/dist/Command-BuOA3V18.js.map +1 -0
  46. package/dist/{CopyField-Ba7h8MqZ.js → CopyField-DsOVtV2Q.js} +4 -4
  47. package/dist/{CopyField-Ba7h8MqZ.js.map → CopyField-DsOVtV2Q.js.map} +1 -1
  48. package/dist/{DateInput-D0nWUasV.js → DateInput-BlKkequE.js} +5 -5
  49. package/dist/{DateInput-D0nWUasV.js.map → DateInput-BlKkequE.js.map} +1 -1
  50. package/dist/{DatePicker-CtSa9b3V.js → DatePicker-CgHAu9KX.js} +3 -3
  51. package/dist/{DatePicker-CtSa9b3V.js.map → DatePicker-CgHAu9KX.js.map} +1 -1
  52. package/dist/{DateRangeInput-i6wE45-V.js → DateRangeInput-DOxJHw8V.js} +5 -5
  53. package/dist/{DateRangeInput-i6wE45-V.js.map → DateRangeInput-DOxJHw8V.js.map} +1 -1
  54. package/dist/{DateRangePicker-BAnuz6vO.js → DateRangePicker-CXpXPMoh.js} +8 -8
  55. package/dist/{DateRangePicker-BAnuz6vO.js.map → DateRangePicker-CXpXPMoh.js.map} +1 -1
  56. package/dist/{DiagramSource-C5_d8Gdj.js → DiagramSource-jTwmmi9g.js} +2 -2
  57. package/dist/{DiagramSource-C5_d8Gdj.js.map → DiagramSource-jTwmmi9g.js.map} +1 -1
  58. package/dist/{DiffView-ppTIzh2h.js → DiffView-Dy4z-n-1.js} +3 -3
  59. package/dist/{DiffView-ppTIzh2h.js.map → DiffView-Dy4z-n-1.js.map} +1 -1
  60. package/dist/{DropdownMenu-BJGLjpVc.js → DropdownMenu-DtRYcKEx.js} +8 -8
  61. package/dist/DropdownMenu-DtRYcKEx.js.map +1 -0
  62. package/dist/{FieldBox-D7DYtX_m.js → FieldBox-BrxLkY9C.js} +8 -6
  63. package/dist/FieldBox-BrxLkY9C.js.map +1 -0
  64. package/dist/{FieldItem-BHViBJS3.js → FieldItem-Cf1E3rfQ.js} +4 -4
  65. package/dist/{FieldItem-BHViBJS3.js.map → FieldItem-Cf1E3rfQ.js.map} +1 -1
  66. package/dist/{FileUpload-Ch2hrIWq.js → FileUpload-D6vPG3WB.js} +9 -9
  67. package/dist/FileUpload-D6vPG3WB.js.map +1 -0
  68. package/dist/{Form-VkzfVPyT.js → Form-CuaAn-lR.js} +10 -10
  69. package/dist/{Form-VkzfVPyT.js.map → Form-CuaAn-lR.js.map} +1 -1
  70. package/dist/{FormGroup-CmCppxOn.js → FormGroup-D4O96YPm.js} +4 -4
  71. package/dist/{FormGroup-CmCppxOn.js.map → FormGroup-D4O96YPm.js.map} +1 -1
  72. package/dist/{FullScreenModal-Cwnm8WdM.js → FullScreenModal-CUuAakh3.js} +20 -6
  73. package/dist/{FullScreenModal-Cwnm8WdM.js.map → FullScreenModal-CUuAakh3.js.map} +1 -1
  74. package/dist/HoverCard-Cy6nhg4u.js +31 -0
  75. package/dist/HoverCard-Cy6nhg4u.js.map +1 -0
  76. package/dist/InlineEdit-DSMIEUUa.js +370 -0
  77. package/dist/InlineEdit-DSMIEUUa.js.map +1 -0
  78. package/dist/{InputGroup-CrlMRz4X.js → InputGroup-Dm014ruw.js} +4 -4
  79. package/dist/{InputGroup-CrlMRz4X.js.map → InputGroup-Dm014ruw.js.map} +1 -1
  80. package/dist/{Kbd-J4n1J6i4.js → Kbd-Du93F3o4.js} +3 -3
  81. package/dist/{Kbd-J4n1J6i4.js.map → Kbd-Du93F3o4.js.map} +1 -1
  82. package/dist/{MermaidDiagram-B30x2yV7.js → MermaidDiagram-D2ThT8Q-.js} +3 -3
  83. package/dist/{MermaidDiagram-B30x2yV7.js.map → MermaidDiagram-D2ThT8Q-.js.map} +1 -1
  84. package/dist/{Modal-BkSuS9Yz.js → Modal-DQIauzar.js} +6 -6
  85. package/dist/Modal-DQIauzar.js.map +1 -0
  86. package/dist/{ModalTitle-BxopkIoQ.js → ModalTitle-CTECVgL8.js} +3 -3
  87. package/dist/ModalTitle-CTECVgL8.js.map +1 -0
  88. package/dist/{MultiActionButtonGroup-AWLj1Tg7.js → MultiActionButtonGroup-xKqiucAN.js} +5 -5
  89. package/dist/{MultiActionButtonGroup-AWLj1Tg7.js.map → MultiActionButtonGroup-xKqiucAN.js.map} +1 -1
  90. package/dist/{Navbar-B_DNpv5s.js → Navbar-CtVYcRFn.js} +18 -14
  91. package/dist/Navbar-CtVYcRFn.js.map +1 -0
  92. package/dist/{OtpInput-I8B8Vjdl.js → OtpInput-CY8yCaJk.js} +4 -4
  93. package/dist/{OtpInput-I8B8Vjdl.js.map → OtpInput-CY8yCaJk.js.map} +1 -1
  94. package/dist/{PageHeader-CgfyXpf1.js → PageHeader-CL1A6jFM.js} +21 -14
  95. package/dist/PageHeader-CL1A6jFM.js.map +1 -0
  96. package/dist/{PageLayout-DiAAILuS.js → PageLayout-C9aXTpqV.js} +2 -2
  97. package/dist/{PageLayout-DiAAILuS.js.map → PageLayout-C9aXTpqV.js.map} +1 -1
  98. package/dist/{PageToolbar-C06RKIif.js → PageToolbar-B_e7HGva.js} +6 -6
  99. package/dist/{PageToolbar-C06RKIif.js.map → PageToolbar-B_e7HGva.js.map} +1 -1
  100. package/dist/{Pagination-DH3f6LN0.js → Pagination-DDp6PRqf.js} +5 -5
  101. package/dist/Pagination-DDp6PRqf.js.map +1 -0
  102. package/dist/{Popconfirm-Dhzn7sy6.js → Popconfirm-BgV6a0sl.js} +5 -5
  103. package/dist/{Popconfirm-Dhzn7sy6.js.map → Popconfirm-BgV6a0sl.js.map} +1 -1
  104. package/dist/{Popover-CEk915I1.js → Popover-BU7nGOv-.js} +3 -3
  105. package/dist/Popover-BU7nGOv-.js.map +1 -0
  106. package/dist/{RadioGroup-CYEp8Wnx.js → RadioGroup-C2vk5acr.js} +6 -6
  107. package/dist/{RadioGroup-CYEp8Wnx.js.map → RadioGroup-C2vk5acr.js.map} +1 -1
  108. package/dist/{Resizable-D3vYToZH.js → Resizable-D8zs0kcq.js} +2 -2
  109. package/dist/{Resizable-D3vYToZH.js.map → Resizable-D8zs0kcq.js.map} +1 -1
  110. package/dist/{Search-DmkQo716.js → Search-CVrv3hqf.js} +4 -4
  111. package/dist/{Search-DmkQo716.js.map → Search-CVrv3hqf.js.map} +1 -1
  112. package/dist/{SearchInput-D3qMkHaW.js → SearchInput-BnU6YHgT.js} +4 -4
  113. package/dist/{SearchInput-D3qMkHaW.js.map → SearchInput-BnU6YHgT.js.map} +1 -1
  114. package/dist/{SectionNav-I2p2uXTd.js → SectionNav-XlhvXXdF.js} +11 -11
  115. package/dist/{SectionNav-I2p2uXTd.js.map → SectionNav-XlhvXXdF.js.map} +1 -1
  116. package/dist/{Select-B4uK0QVm.js → Select-CjQgU_6K.js} +6 -6
  117. package/dist/Select-CjQgU_6K.js.map +1 -0
  118. package/dist/{Sheet-D0fAE14T.js → Sheet-utw4_rUa.js} +9 -9
  119. package/dist/Sheet-utw4_rUa.js.map +1 -0
  120. package/dist/{Sidebar-D9ytIs8V.js → Sidebar-CKaxOPwY.js} +21 -18
  121. package/dist/Sidebar-CKaxOPwY.js.map +1 -0
  122. package/dist/{Slider-B0ou9r0B.js → Slider-Rcc2qVct.js} +5 -5
  123. package/dist/{Slider-B0ou9r0B.js.map → Slider-Rcc2qVct.js.map} +1 -1
  124. package/dist/{Stepper-BLkLhfnd.js → Stepper-BBPembeK.js} +3 -3
  125. package/dist/{Stepper-BLkLhfnd.js.map → Stepper-BBPembeK.js.map} +1 -1
  126. package/dist/{Switch-DZvNePOm.js → Switch-Dw4tvQls.js} +3 -3
  127. package/dist/Switch-Dw4tvQls.js.map +1 -0
  128. package/dist/{Table-BaVT5Tkn.js → Table-CgSC-fSo.js} +4 -4
  129. package/dist/{Table-BaVT5Tkn.js.map → Table-CgSC-fSo.js.map} +1 -1
  130. package/dist/{Tabs-CTDmye1N.js → Tabs-C0uvkPHc.js} +5 -5
  131. package/dist/Tabs-C0uvkPHc.js.map +1 -0
  132. package/dist/{TextInput-BWYXbfs4.js → TextInput-B5TDDOty.js} +5 -5
  133. package/dist/{TextInput-BWYXbfs4.js.map → TextInput-B5TDDOty.js.map} +1 -1
  134. package/dist/{ThemeProvider-VF38VfUa.js → ThemeProvider-Dt9b67sW.js} +22 -5
  135. package/dist/ThemeProvider-Dt9b67sW.js.map +1 -0
  136. package/dist/{TimePicker-CDGYrRxi.js → TimePicker-DyyV3nw8.js} +2 -2
  137. package/dist/{TimePicker-CDGYrRxi.js.map → TimePicker-DyyV3nw8.js.map} +1 -1
  138. package/dist/{Timeline-B-I6sb0M.js → Timeline-DUXgByUE.js} +3 -3
  139. package/dist/{Timeline-B-I6sb0M.js.map → Timeline-DUXgByUE.js.map} +1 -1
  140. package/dist/{Toast-NrOdDDru.js → Toast-BGnUL4jV.js} +2 -2
  141. package/dist/{Toast-NrOdDDru.js.map → Toast-BGnUL4jV.js.map} +1 -1
  142. package/dist/{ToggleGroup-Cy_10Mvu.js → ToggleGroup-BOz1yyz6.js} +3 -3
  143. package/dist/ToggleGroup-BOz1yyz6.js.map +1 -0
  144. package/dist/{Workbench-DmZzpkj7.js → Workbench-CxgNCs3I.js} +4 -4
  145. package/dist/{Workbench-DmZzpkj7.js.map → Workbench-CxgNCs3I.js.map} +1 -1
  146. package/dist/{ZoomableSvg-C65nta_r.js → ZoomableSvg-D8sXKpoV.js} +6 -6
  147. package/dist/{ZoomableSvg-C65nta_r.js.map → ZoomableSvg-D8sXKpoV.js.map} +1 -1
  148. package/dist/charts.js +1 -1
  149. package/dist/classNames-DcGnTh2N.js +21 -0
  150. package/dist/classNames-DcGnTh2N.js.map +1 -0
  151. package/dist/editors.js +5 -5
  152. package/dist/flint.js +2 -2
  153. package/dist/{icons-wcA70iQx.js → icons-ZIeZXXS7.js} +37 -4
  154. package/dist/icons-ZIeZXXS7.js.map +1 -0
  155. package/dist/icons.d.ts +2 -2
  156. package/dist/icons.js +2 -2
  157. package/dist/{index-B7k-09i1.d.ts → index-D-itZ3VP.d.ts} +14 -3
  158. package/dist/index.d.ts +388 -316
  159. package/dist/index.js +72 -70
  160. package/dist/internal/blocks/AIKit.js +1 -1
  161. package/dist/internal/blocks/AppShell.js +1 -1
  162. package/dist/internal/blocks/AuthLayout.js +2 -2
  163. package/dist/internal/blocks/AutoSaveTextarea.js +1 -1
  164. package/dist/internal/blocks/BrandEditor.js +1 -1
  165. package/dist/internal/blocks/ChartPanel.js +2 -2
  166. package/dist/internal/blocks/ChipEditor.js +4 -4
  167. package/dist/internal/blocks/ClipboardButton.js +1 -1
  168. package/dist/internal/blocks/ColorInput.js +1 -1
  169. package/dist/internal/blocks/ColorModeSwitch.js +1 -1
  170. package/dist/internal/blocks/Command.js +1 -1
  171. package/dist/internal/blocks/CopyField.js +1 -1
  172. package/dist/internal/blocks/DashboardHero.js +2 -2
  173. package/dist/internal/blocks/DashboardHero.js.map +1 -1
  174. package/dist/internal/blocks/DateInput.js +1 -1
  175. package/dist/internal/blocks/DateRangeInput.js +1 -1
  176. package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
  177. package/dist/internal/blocks/ExportMenu.js +4 -4
  178. package/dist/internal/blocks/FacebookButton.js +66 -0
  179. package/dist/internal/blocks/FacebookButton.js.map +1 -0
  180. package/dist/internal/blocks/Form/connectors/ComboboxField.js +2 -2
  181. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
  182. package/dist/internal/blocks/Form.js +1 -1
  183. package/dist/internal/blocks/FormGroup.js +1 -1
  184. package/dist/internal/blocks/GoogleButton.js +2 -2
  185. package/dist/internal/blocks/InlineEdit.js +2 -0
  186. package/dist/internal/blocks/MicrosoftButton.js +2 -2
  187. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  188. package/dist/internal/blocks/MultiCombobox.js +2 -2
  189. package/dist/internal/blocks/NumberInput.js +1 -1
  190. package/dist/internal/blocks/OtpInput.js +1 -1
  191. package/dist/internal/blocks/PageHeader.js +1 -1
  192. package/dist/internal/blocks/PageLayout.js +1 -1
  193. package/dist/internal/blocks/PageToolbar.js +1 -1
  194. package/dist/internal/blocks/PasswordInput.js +3 -3
  195. package/dist/internal/blocks/SearchInput.js +1 -1
  196. package/dist/internal/blocks/SearchInputWithNavigation.js +5 -5
  197. package/dist/internal/blocks/SectionNav.js +1 -1
  198. package/dist/internal/blocks/SplitButton.js +6 -5
  199. package/dist/internal/blocks/SplitButton.js.map +1 -1
  200. package/dist/internal/blocks/StatCard.js +2 -2
  201. package/dist/internal/blocks/TextInput.js +1 -1
  202. package/dist/internal/blocks/Textarea.js +1 -1
  203. package/dist/internal/blocks/TimeInput.js +4 -4
  204. package/dist/internal/components/Alert.js +1 -1
  205. package/dist/internal/components/AlertModal.js +1 -1
  206. package/dist/internal/components/Avatar.js +2 -2
  207. package/dist/internal/components/Badge.js +1 -1
  208. package/dist/internal/components/BrandLogo.js +1 -1
  209. package/dist/internal/components/Breadcrumb.js +1 -1
  210. package/dist/internal/components/Button.js +1 -1
  211. package/dist/internal/components/ButtonGroup.js +1 -1
  212. package/dist/internal/components/Calendar.js +1 -1
  213. package/dist/internal/components/Card.js +1 -1
  214. package/dist/internal/components/Checkbox.js +1 -1
  215. package/dist/internal/components/Clipboard.js +1 -1
  216. package/dist/internal/components/Collapsible.js +1 -1
  217. package/dist/internal/components/CollapsiblePanel.js +5 -5
  218. package/dist/internal/components/CollapsiblePanel.js.map +1 -1
  219. package/dist/internal/components/Combobox.js +1 -1
  220. package/dist/internal/components/DatePicker.js +1 -1
  221. package/dist/internal/components/DateRangePicker.js +1 -1
  222. package/dist/internal/components/DiffView.js +1 -1
  223. package/dist/internal/components/DotsLoader.js +1 -1
  224. package/dist/internal/components/DropdownMenu.js +1 -1
  225. package/dist/internal/components/FileUpload.js +1 -1
  226. package/dist/internal/components/FullScreenModal.js +1 -1
  227. package/dist/internal/components/HoverCard.js +1 -1
  228. package/dist/internal/components/InputGroup.js +1 -1
  229. package/dist/internal/components/Kbd.js +1 -1
  230. package/dist/internal/components/Label.js +2 -2
  231. package/dist/internal/components/Label.js.map +1 -1
  232. package/dist/internal/components/Link.js +1 -1
  233. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +2 -2
  234. package/dist/internal/components/Modal.js +1 -1
  235. package/dist/internal/components/Navbar.js +1 -1
  236. package/dist/internal/components/Pagination.js +1 -1
  237. package/dist/internal/components/PanelWithDetails.js +3 -3
  238. package/dist/internal/components/Popconfirm.js +1 -1
  239. package/dist/internal/components/Popover.js +1 -1
  240. package/dist/internal/components/Progress.js +1 -1
  241. package/dist/internal/components/RadioGroup.js +1 -1
  242. package/dist/internal/components/Resizable.js +1 -1
  243. package/dist/internal/components/ScrollArea.js +1 -1
  244. package/dist/internal/components/Search.js +1 -1
  245. package/dist/internal/components/Select.js +1 -1
  246. package/dist/internal/components/Separator.js +1 -1
  247. package/dist/internal/components/Sheet.js +1 -1
  248. package/dist/internal/components/Sidebar.js +1 -1
  249. package/dist/internal/components/Skeleton/Skeleton.js +1 -1
  250. package/dist/internal/components/Skeleton/SkeletonList.js +1 -1
  251. package/dist/internal/components/Slider.js +1 -1
  252. package/dist/internal/components/SpotlightBackdrop.js +1 -1
  253. package/dist/internal/components/Stepper.js +1 -1
  254. package/dist/internal/components/Switch.js +1 -1
  255. package/dist/internal/components/Table.js +1 -1
  256. package/dist/internal/components/Tabs.js +1 -1
  257. package/dist/internal/components/ThemeProvider.js +1 -1
  258. package/dist/internal/components/TimePicker.js +1 -1
  259. package/dist/internal/components/Timeline.js +1 -1
  260. package/dist/internal/components/Toast.js +2 -2
  261. package/dist/internal/components/Toggle.js +5 -5
  262. package/dist/internal/components/Toggle.js.map +1 -1
  263. package/dist/internal/components/ToggleGroup.js +1 -1
  264. package/dist/internal/components/Tooltip.js +1 -1
  265. package/dist/internal/components/Truncated.js +2 -2
  266. package/dist/internal/components/Workbench.js +1 -1
  267. package/dist/internal/components/ZoomableSvg.js +1 -1
  268. package/dist/internal/utils.js +2 -2
  269. package/dist/markdown-editor.js +116 -78
  270. package/dist/markdown-editor.js.map +1 -1
  271. package/dist/mermaid.js +1 -1
  272. package/dist/rjsf.js +12 -12
  273. package/dist/{styles-DBGXH5-_.js → styles-BDA5rQz3.js} +6 -6
  274. package/dist/styles-BDA5rQz3.js.map +1 -0
  275. package/dist/{styles-gzcjOyKv.js → styles-YQdM7G8c.js} +3 -3
  276. package/dist/{styles-gzcjOyKv.js.map → styles-YQdM7G8c.js.map} +1 -1
  277. package/dist/styles.css +1 -1
  278. package/dist/testing.js +1 -1
  279. package/dist/{toast-CyXEdaCZ.js → toast-D6Z6MOB5.js} +5 -5
  280. package/dist/toast-D6Z6MOB5.js.map +1 -0
  281. package/dist/{utils-Bd28bWgm.js → utils-p6tjltbX.js} +4 -4
  282. package/dist/utils-p6tjltbX.js.map +1 -0
  283. package/package.json +2 -1
  284. package/src/styles.css +179 -0
  285. package/src/theme.css +47 -3
  286. package/dist/AIKit-BVCWP9Ks.js.map +0 -1
  287. package/dist/AlertModal-mbSnuuka.js.map +0 -1
  288. package/dist/BrandEditor-P8OZX2hi.js.map +0 -1
  289. package/dist/Breadcrumb-BUoAZyhO.js.map +0 -1
  290. package/dist/Button-B21oVcPU.js.map +0 -1
  291. package/dist/Card-BQmBWHXl.js.map +0 -1
  292. package/dist/Checkbox-8yIIgY7g.js.map +0 -1
  293. package/dist/Combobox-BNhW0TDB.js.map +0 -1
  294. package/dist/Command-BQPiZCNz.js.map +0 -1
  295. package/dist/DropdownMenu-BJGLjpVc.js.map +0 -1
  296. package/dist/FieldBox-D7DYtX_m.js.map +0 -1
  297. package/dist/FileUpload-Ch2hrIWq.js.map +0 -1
  298. package/dist/HoverCard-B8OKu9XZ.js +0 -31
  299. package/dist/HoverCard-B8OKu9XZ.js.map +0 -1
  300. package/dist/Modal-BkSuS9Yz.js.map +0 -1
  301. package/dist/ModalTitle-BxopkIoQ.js.map +0 -1
  302. package/dist/Navbar-B_DNpv5s.js.map +0 -1
  303. package/dist/PageHeader-CgfyXpf1.js.map +0 -1
  304. package/dist/Pagination-DH3f6LN0.js.map +0 -1
  305. package/dist/Popover-CEk915I1.js.map +0 -1
  306. package/dist/Select-B4uK0QVm.js.map +0 -1
  307. package/dist/Sheet-D0fAE14T.js.map +0 -1
  308. package/dist/Sidebar-D9ytIs8V.js.map +0 -1
  309. package/dist/Switch-DZvNePOm.js.map +0 -1
  310. package/dist/Tabs-CTDmye1N.js.map +0 -1
  311. package/dist/ThemeProvider-VF38VfUa.js.map +0 -1
  312. package/dist/ToggleGroup-Cy_10Mvu.js.map +0 -1
  313. package/dist/classNames-BzrkDnOD.js +0 -9
  314. package/dist/classNames-BzrkDnOD.js.map +0 -1
  315. package/dist/icons-wcA70iQx.js.map +0 -1
  316. package/dist/styles-DBGXH5-_.js.map +0 -1
  317. package/dist/toast-CyXEdaCZ.js.map +0 -1
  318. package/dist/utils-Bd28bWgm.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CopyField-Ba7h8MqZ.js","names":["CopyIcon"],"sources":["../src/blocks/CopyField/CopyContext.tsx","../src/blocks/CopyField/CopyBox.tsx","../src/blocks/CopyField/CopyButton.tsx","../src/blocks/CopyField/CopyChildren.tsx","../src/blocks/CopyField/CopyFooter.tsx","../src/blocks/CopyField/CopyHidden.tsx","../src/blocks/CopyField/CopyLabel.tsx","../src/blocks/CopyField/CopyPrefix.tsx","../src/blocks/CopyField/CopyReveal.tsx","../src/blocks/CopyField/CopyRoot.tsx","../src/blocks/CopyField/CopySuffix.tsx","../src/blocks/CopyField/CopyField.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\ntype CopyContextValue = {\n /** Whether a copy just happened (drives the Copy → Check feedback for ~1.5s). */\n copied: boolean;\n /** Copies the real `value` to the clipboard, guarded against drag-select. */\n handleCopy: () => void;\n /** The real value copied to the clipboard, regardless of masking. */\n value: string;\n /** Render displayed content in monospace/code style. */\n mono: boolean;\n /** Whether to show the \"Copy\" hint tooltip on hover (else only \"Copied\" on copy). */\n hoverHint: boolean;\n /** Whether revealable `CopyField.Hidden` content is currently masked. */\n hidden: boolean;\n /** Toggles the masked ↔ revealed state. */\n toggleHidden: () => void;\n /**\n * Registers a revealable `CopyField.Hidden` so `CopyField.Reveal` knows to render.\n * Returns a cleanup that unregisters on unmount.\n */\n registerRevealable: () => () => void;\n /** True once at least one revealable `CopyField.Hidden` is mounted. */\n hasRevealable: boolean;\n /**\n * Registers the visible `CopyField.Label` so `CopyField.Box` only points `aria-labelledby`\n * at it when a label actually exists. Returns a cleanup that unregisters on unmount.\n */\n registerLabel: () => () => void;\n /** True once a `CopyField.Label` is mounted. */\n hasLabel: boolean;\n /** Minimum number of visible text lines for a multi-line box. */\n minLines: number;\n /** Maximum number of visible text lines before the box scrolls. */\n maxLines: number;\n /** Stable id of the visible label element (for `aria-labelledby`). */\n labelId: string;\n /** Stable id of the clickable box element. */\n boxId: string;\n};\n\nexport const CopyContext = createContext<CopyContextValue | null>(null);\n\nexport const useCopyContext = () => {\n const ctx = use(CopyContext);\n if (!ctx) throw new Error('CopyField.* components must be used within a CopyField.Root');\n return ctx;\n};\n","import type { CSSProperties, KeyboardEvent, ReactNode } from 'react';\n\nimport { Tooltip } from '../../components/Tooltip';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyBoxProps = {\n /** Additional CSS classes on the box. */\n className?: string;\n children: ReactNode;\n};\n\nconst LINE_HEIGHT_REM = 1.25;\nconst VERTICAL_PADDING_REM = 1.25;\n\n// Long delay — the hover \"Copy\" hint doesn't really help UX, it just pulls focus.\nconst COPY_HINT_DELAY_MS = 2000;\n\n/**\n * The clickable copy target. Click anywhere to copy; text stays drag-selectable.\n *\n * Rendered as a `role=\"button\"` div (not a native `<button>`) so it can host\n * genuinely interactive children like `CopyField.Reveal` — nesting a `<button>`\n * inside a `<button>` is invalid HTML.\n */\nexport const CopyBox = ({ className, children }: CopyBoxProps) => {\n const { copied, handleCopy, mono, minLines, maxLines, boxId, labelId, hasLabel, hoverHint } =\n useCopyContext();\n\n const multiline = maxLines > 1;\n const multilineStyle: CSSProperties | undefined = multiline\n ? {\n minHeight: `${minLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`,\n maxHeight: `${maxLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`,\n }\n : undefined;\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n handleCopy();\n };\n\n return (\n <Tooltip\n triggerAsChild\n placement=\"top\"\n tooltip={copied ? 'Copied' : hoverHint ? 'Copy' : null}\n forceShow={copied}\n delayDuration={COPY_HINT_DELAY_MS}\n >\n <div\n role=\"button\"\n tabIndex={0}\n id={boxId}\n aria-labelledby={hasLabel ? labelId : undefined}\n onClick={handleCopy}\n onKeyDown={handleKeyDown}\n style={multilineStyle}\n className={cn(\n 'tw:group tw:relative tw:flex tw:w-fit tw:max-w-full tw:cursor-pointer tw:gap-2 tw:rounded-2xl tw:[corner-shape:superellipse(2)] tw:border tw:border-border tw:bg-card tw:px-3 tw:py-2.5 tw:text-left tw:shadow-sm tw:transition-colors tw:hover:bg-muted',\n multiline ? 'tw:items-start tw:overflow-auto' : 'tw:items-center tw:overflow-hidden',\n mono && 'tw:font-mono tw:text-[13px]',\n className,\n )}\n >\n {children}\n </div>\n </Tooltip>\n );\n};\n","import { Check, Copy as CopyIcon } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyButtonProps = {\n className?: string;\n};\n\n/** Copy affordance icon — shows Copy/Check with feedback. */\nexport const CopyButton = ({ className }: CopyButtonProps) => {\n const { copied, maxLines } = useCopyContext();\n\n return (\n <span\n aria-hidden\n className={cn(\n 'tw:pointer-events-none tw:flex tw:shrink-0 tw:items-center tw:text-muted-foreground tw:group-hover:text-foreground',\n maxLines > 1 && 'tw:self-start tw:pt-0.5',\n className,\n )}\n >\n {copied ? <Check className=\"tw:size-4\" /> : <CopyIcon className=\"tw:size-4\" />}\n </span>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyChildrenProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** The displayed value. Truncates on a single line, wraps when multi-line. */\nexport const CopyChildren = ({ children, className }: CopyChildrenProps) => {\n const { maxLines } = useCopyContext();\n const multiline = maxLines > 1;\n\n return (\n <span\n className={cn(\n 'tw:min-w-0 tw:flex-1 tw:select-text tw:text-card-foreground',\n multiline ? 'tw:whitespace-pre-wrap tw:break-words' : 'tw:truncate',\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyFooterProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Small helper text below the box (mirrors `FormGroup.Help` / `HelpBlock` styling). */\nexport const CopyFooter = ({ children, className }: CopyFooterProps) => {\n if (!children) return null;\n\n return <p className={cn('tw:m-0 tw:text-xs tw:text-muted-foreground', className)}>{children}</p>;\n};\n","import { useEffect } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyHiddenProps = {\n children: ReactNode;\n /**\n * When true (default), `CopyField.Reveal` can unmask this content. When false the\n * content is always masked (e.g. an implicit token inside a longer string).\n */\n revealable?: boolean;\n className?: string;\n};\n\nconst MASK = '*'.repeat(12);\n\n/**\n * Masks its children with asterisks. The real value still lives on `CopyField.Root`,\n * so copy always copies the real value regardless of mask state.\n */\nexport const CopyHidden = ({ children, revealable = true, className }: CopyHiddenProps) => {\n const { hidden, registerRevealable } = useCopyContext();\n\n useEffect(() => {\n if (!revealable) return undefined;\n return registerRevealable();\n }, [revealable, registerRevealable]);\n\n const masked = revealable ? hidden : true;\n\n return <span className={cn('tw:select-none', className)}>{masked ? MASK : children}</span>;\n};\n","import { useEffect } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { Label } from '../../components/Label';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyLabelProps = {\n children: ReactNode;\n /** Content rendered right after the label text (e.g. an Info tooltip button). */\n leading?: ReactNode;\n /** Content pushed to the trailing edge of the row (e.g. a Switch). */\n trailing?: ReactNode;\n className?: string;\n};\n\n/**\n * Visible label above the box. The label carries an id and the box is wired via\n * `aria-labelledby` (not `htmlFor`, which would turn label clicks into a copy).\n *\n * Row layout: label text, then `leading` (gap), then `trailing` pushed to the far\n * edge with the space between them growing.\n */\nexport const CopyLabel = ({ children, leading, trailing, className }: CopyLabelProps) => {\n const { labelId, registerLabel } = useCopyContext();\n\n useEffect(() => registerLabel(), [registerLabel]);\n\n return (\n <div className={cn('tw:flex tw:items-center tw:gap-1', className)}>\n <Label id={labelId}>{children}</Label>\n {leading}\n {trailing != null && <span className=\"tw:ml-auto tw:flex tw:items-center\">{trailing}</span>}\n </div>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyAddonProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Muted, non-selectable prefix addon with a trailing divider (not part of the copied value). */\nexport const CopyPrefix = ({ children, className }: CopyAddonProps) => (\n <span\n aria-hidden\n className={cn(\n 'tw:shrink-0 tw:select-none tw:self-stretch tw:border-r tw:border-border tw:pr-2 tw:text-muted-foreground',\n className,\n )}\n >\n {children}\n </span>\n);\n","import type { MouseEvent } from 'react';\n\nimport { Eye, EyeOff } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyRevealProps = {\n className?: string;\n /** Names what the eye reveals, e.g. `password` → \"Show password\"; defaults to `value`. */\n subject?: string;\n};\n\n/** Eye toggle that reveals/masks `CopyField.Hidden` content. Renders nothing without revealable content. */\nexport const CopyReveal = ({ className, subject = 'value' }: CopyRevealProps) => {\n const { hidden, toggleHidden, hasRevealable, maxLines } = useCopyContext();\n\n if (!hasRevealable) return null;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n toggleHidden();\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n aria-label={`${hidden ? 'Show' : 'Hide'} ${subject}`}\n className={cn(\n 'tw:flex tw:shrink-0 tw:items-center tw:text-muted-foreground tw:hover:text-foreground',\n maxLines > 1 && 'tw:self-start tw:pt-0.5',\n className,\n )}\n >\n {hidden ? <Eye className=\"tw:size-4\" /> : <EyeOff className=\"tw:size-4\" />}\n </button>\n );\n};\n","import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn, copyToClipboard } from '../../utils';\n\nimport { CopyContext } from './CopyContext';\n\ntype CopyRootProps = {\n /** The value copied to the clipboard on click. */\n value: string;\n /** Render displayed content in monospace/code style. */\n mono?: boolean;\n /** Callback fired after a successful copy. */\n onCopy?: () => void;\n /** Start with revealable `CopyField.Hidden` content masked. */\n hiddenByDefault?: boolean;\n /** Minimum number of visible text lines for a multi-line box. */\n minLines?: number;\n /** Maximum number of visible text lines before the box scrolls. */\n maxLines?: number;\n /** Show the \"Copy\" hover hint (set `false` to only show \"Copied\" on copy). Defaults to `true`. */\n hoverHint?: boolean;\n /** Additional CSS classes on the outer container. */\n className?: string;\n children: ReactNode;\n};\n\n/**\n * Container for the Copy block. Owns the copied `value`, copy/mask state, and the\n * shared context consumed by `CopyField.Box`, `CopyField.Reveal`, `CopyField.Button`, etc.\n */\nexport const CopyRoot = ({\n value,\n mono = false,\n onCopy,\n hiddenByDefault = false,\n minLines = 1,\n maxLines,\n hoverHint = true,\n className,\n children,\n}: CopyRootProps) => {\n const [copied, setCopied] = useState(false);\n const [hidden, setHidden] = useState(hiddenByDefault);\n const [revealableCount, setRevealableCount] = useState(0);\n const [labelCount, setLabelCount] = useState(0);\n const resetTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const generatedId = useId();\n const labelId = `${generatedId}-label`;\n const boxId = `${generatedId}-box`;\n\n useEffect(() => () => clearTimeout(resetTimerRef.current), []);\n\n const handleCopy = useCallback(() => {\n const selection = window.getSelection();\n const boxEl = document.getElementById(boxId);\n if (\n selection &&\n !selection.isCollapsed &&\n selection.anchorNode &&\n boxEl?.contains(selection.anchorNode)\n ) {\n return;\n }\n\n copyToClipboard(value)\n .then(() => {\n onCopy?.();\n setCopied(true);\n clearTimeout(resetTimerRef.current);\n resetTimerRef.current = setTimeout(() => setCopied(false), 1500);\n })\n .catch((error: unknown) => {\n // eslint-disable-next-line no-console\n console.error('Copy to clipboard failed', error);\n });\n }, [value, onCopy, boxId]);\n\n const toggleHidden = useCallback(() => setHidden((prev) => !prev), []);\n\n const registerRevealable = useCallback(() => {\n setRevealableCount((count) => count + 1);\n return () => setRevealableCount((count) => count - 1);\n }, []);\n\n const registerLabel = useCallback(() => {\n setLabelCount((count) => count + 1);\n return () => setLabelCount((count) => count - 1);\n }, []);\n\n const contextValue = useMemo(\n () => ({\n copied,\n handleCopy,\n value,\n mono,\n hidden,\n toggleHidden,\n registerRevealable,\n hasRevealable: revealableCount > 0,\n registerLabel,\n hasLabel: labelCount > 0,\n minLines,\n maxLines: maxLines ?? minLines,\n hoverHint,\n labelId,\n boxId,\n }),\n [\n copied,\n handleCopy,\n value,\n mono,\n hidden,\n toggleHidden,\n registerRevealable,\n revealableCount,\n registerLabel,\n labelCount,\n minLines,\n maxLines,\n hoverHint,\n labelId,\n boxId,\n ],\n );\n\n return (\n <CopyContext value={contextValue}>\n <div className={cn('tw:flex tw:w-fit tw:max-w-full tw:flex-col tw:gap-1', className)}>\n {children}\n </div>\n </CopyContext>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyAddonProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Muted, non-selectable suffix addon with a leading divider (not part of the copied value). */\nexport const CopySuffix = ({ children, className }: CopyAddonProps) => (\n <span\n aria-hidden\n className={cn(\n 'tw:shrink-0 tw:select-none tw:self-stretch tw:border-l tw:border-border tw:pl-2 tw:text-muted-foreground',\n className,\n )}\n >\n {children}\n </span>\n);\n","import { CopyBox } from './CopyBox';\nimport { CopyButton } from './CopyButton';\nimport { CopyChildren } from './CopyChildren';\nimport { CopyFooter } from './CopyFooter';\nimport { CopyHidden } from './CopyHidden';\nimport { CopyLabel } from './CopyLabel';\nimport { CopyPrefix } from './CopyPrefix';\nimport { CopyReveal } from './CopyReveal';\nimport { CopyRoot } from './CopyRoot';\nimport { CopySuffix } from './CopySuffix';\n\n/**\n * Readonly value/command box that copies `value` on click.\n *\n * - A click that ends a text selection does not copy.\n * - `mono` for commands; `maxLines > 1` wraps and scrolls between `minLines` and `maxLines`.\n * - `CopyField.Hidden` masks content; copy still copies the real `value`.\n */\nexport const CopyField = {\n /** Owns `value`, mask and copy state. */\n Root: CopyRoot,\n /** Label above the box, with `leading`/`trailing` slots. */\n Label: CopyLabel,\n /** The clickable copy target. */\n Box: CopyBox,\n /** Not copied. */\n Prefix: CopyPrefix,\n /** The displayed value. */\n Children: CopyChildren,\n /** Not copied. */\n Suffix: CopySuffix,\n /** Masked display only; copy still copies the real value. */\n Hidden: CopyHidden,\n /** Toggles revealable `CopyField.Hidden` content. */\n Reveal: CopyReveal,\n /** Copy icon with Copy → Check feedback. */\n Button: CopyButton,\n /** Helper text below the box. */\n Footer: CopyFooter,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"CopyField-DsOVtV2Q.js","names":["CopyIcon"],"sources":["../src/blocks/CopyField/CopyContext.tsx","../src/blocks/CopyField/CopyBox.tsx","../src/blocks/CopyField/CopyButton.tsx","../src/blocks/CopyField/CopyChildren.tsx","../src/blocks/CopyField/CopyFooter.tsx","../src/blocks/CopyField/CopyHidden.tsx","../src/blocks/CopyField/CopyLabel.tsx","../src/blocks/CopyField/CopyPrefix.tsx","../src/blocks/CopyField/CopyReveal.tsx","../src/blocks/CopyField/CopyRoot.tsx","../src/blocks/CopyField/CopySuffix.tsx","../src/blocks/CopyField/CopyField.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\ntype CopyContextValue = {\n /** Whether a copy just happened (drives the Copy → Check feedback for ~1.5s). */\n copied: boolean;\n /** Copies the real `value` to the clipboard, guarded against drag-select. */\n handleCopy: () => void;\n /** The real value copied to the clipboard, regardless of masking. */\n value: string;\n /** Render displayed content in monospace/code style. */\n mono: boolean;\n /** Whether to show the \"Copy\" hint tooltip on hover (else only \"Copied\" on copy). */\n hoverHint: boolean;\n /** Whether revealable `CopyField.Hidden` content is currently masked. */\n hidden: boolean;\n /** Toggles the masked ↔ revealed state. */\n toggleHidden: () => void;\n /**\n * Registers a revealable `CopyField.Hidden` so `CopyField.Reveal` knows to render.\n * Returns a cleanup that unregisters on unmount.\n */\n registerRevealable: () => () => void;\n /** True once at least one revealable `CopyField.Hidden` is mounted. */\n hasRevealable: boolean;\n /**\n * Registers the visible `CopyField.Label` so `CopyField.Box` only points `aria-labelledby`\n * at it when a label actually exists. Returns a cleanup that unregisters on unmount.\n */\n registerLabel: () => () => void;\n /** True once a `CopyField.Label` is mounted. */\n hasLabel: boolean;\n /** Minimum number of visible text lines for a multi-line box. */\n minLines: number;\n /** Maximum number of visible text lines before the box scrolls. */\n maxLines: number;\n /** Stable id of the visible label element (for `aria-labelledby`). */\n labelId: string;\n /** Stable id of the clickable box element. */\n boxId: string;\n};\n\nexport const CopyContext = createContext<CopyContextValue | null>(null);\n\nexport const useCopyContext = () => {\n const ctx = use(CopyContext);\n if (!ctx) throw new Error('CopyField.* components must be used within a CopyField.Root');\n return ctx;\n};\n","import type { CSSProperties, KeyboardEvent, ReactNode } from 'react';\n\nimport { Tooltip } from '../../components/Tooltip';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyBoxProps = {\n /** Additional CSS classes on the box. */\n className?: string;\n children: ReactNode;\n};\n\nconst LINE_HEIGHT_REM = 1.25;\nconst VERTICAL_PADDING_REM = 1.25;\n\n// Long delay — the hover \"Copy\" hint doesn't really help UX, it just pulls focus.\nconst COPY_HINT_DELAY_MS = 2000;\n\n/**\n * The clickable copy target. Click anywhere to copy; text stays drag-selectable.\n *\n * Rendered as a `role=\"button\"` div (not a native `<button>`) so it can host\n * genuinely interactive children like `CopyField.Reveal` — nesting a `<button>`\n * inside a `<button>` is invalid HTML.\n */\nexport const CopyBox = ({ className, children }: CopyBoxProps) => {\n const { copied, handleCopy, mono, minLines, maxLines, boxId, labelId, hasLabel, hoverHint } =\n useCopyContext();\n\n const multiline = maxLines > 1;\n const multilineStyle: CSSProperties | undefined = multiline\n ? {\n minHeight: `${minLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`,\n maxHeight: `${maxLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`,\n }\n : undefined;\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n handleCopy();\n };\n\n return (\n <Tooltip\n triggerAsChild\n placement=\"top\"\n tooltip={copied ? 'Copied' : hoverHint ? 'Copy' : null}\n forceShow={copied}\n delayDuration={COPY_HINT_DELAY_MS}\n >\n <div\n role=\"button\"\n tabIndex={0}\n id={boxId}\n aria-labelledby={hasLabel ? labelId : undefined}\n onClick={handleCopy}\n onKeyDown={handleKeyDown}\n style={multilineStyle}\n className={cn(\n 'tw:group tw:relative tw:flex tw:w-fit tw:max-w-full tw:cursor-pointer tw:gap-2 tw:rounded-2xl tw:[corner-shape:superellipse(2)] tw:border tw:border-border tw:bg-card tw:px-3 tw:py-2.5 tw:text-left tw:shadow-sm tw:transition-colors tw:hover:bg-muted',\n multiline ? 'tw:items-start tw:overflow-auto' : 'tw:items-center tw:overflow-hidden',\n mono && 'tw:font-mono tw:text-[13px]',\n className,\n )}\n >\n {children}\n </div>\n </Tooltip>\n );\n};\n","import { Check, Copy as CopyIcon } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyButtonProps = {\n className?: string;\n};\n\n/** Copy affordance icon — shows Copy/Check with feedback. */\nexport const CopyButton = ({ className }: CopyButtonProps) => {\n const { copied, maxLines } = useCopyContext();\n\n return (\n <span\n aria-hidden\n className={cn(\n 'tw:pointer-events-none tw:flex tw:shrink-0 tw:items-center tw:text-muted-foreground tw:group-hover:text-foreground',\n maxLines > 1 && 'tw:self-start tw:pt-0.5',\n className,\n )}\n >\n {copied ? <Check className=\"tw:size-4\" /> : <CopyIcon className=\"tw:size-4\" />}\n </span>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyChildrenProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** The displayed value. Truncates on a single line, wraps when multi-line. */\nexport const CopyChildren = ({ children, className }: CopyChildrenProps) => {\n const { maxLines } = useCopyContext();\n const multiline = maxLines > 1;\n\n return (\n <span\n className={cn(\n 'tw:min-w-0 tw:flex-1 tw:select-text tw:text-card-foreground',\n multiline ? 'tw:whitespace-pre-wrap tw:break-words' : 'tw:truncate',\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyFooterProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Small helper text below the box (mirrors `FormGroup.Help` / `HelpBlock` styling). */\nexport const CopyFooter = ({ children, className }: CopyFooterProps) => {\n if (!children) return null;\n\n return <p className={cn('tw:m-0 tw:text-xs tw:text-muted-foreground', className)}>{children}</p>;\n};\n","import { useEffect } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyHiddenProps = {\n children: ReactNode;\n /**\n * When true (default), `CopyField.Reveal` can unmask this content. When false the\n * content is always masked (e.g. an implicit token inside a longer string).\n */\n revealable?: boolean;\n className?: string;\n};\n\nconst MASK = '*'.repeat(12);\n\n/**\n * Masks its children with asterisks. The real value still lives on `CopyField.Root`,\n * so copy always copies the real value regardless of mask state.\n */\nexport const CopyHidden = ({ children, revealable = true, className }: CopyHiddenProps) => {\n const { hidden, registerRevealable } = useCopyContext();\n\n useEffect(() => {\n if (!revealable) return undefined;\n return registerRevealable();\n }, [revealable, registerRevealable]);\n\n const masked = revealable ? hidden : true;\n\n return <span className={cn('tw:select-none', className)}>{masked ? MASK : children}</span>;\n};\n","import { useEffect } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { Label } from '../../components/Label';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyLabelProps = {\n children: ReactNode;\n /** Content rendered right after the label text (e.g. an Info tooltip button). */\n leading?: ReactNode;\n /** Content pushed to the trailing edge of the row (e.g. a Switch). */\n trailing?: ReactNode;\n className?: string;\n};\n\n/**\n * Visible label above the box. The label carries an id and the box is wired via\n * `aria-labelledby` (not `htmlFor`, which would turn label clicks into a copy).\n *\n * Row layout: label text, then `leading` (gap), then `trailing` pushed to the far\n * edge with the space between them growing.\n */\nexport const CopyLabel = ({ children, leading, trailing, className }: CopyLabelProps) => {\n const { labelId, registerLabel } = useCopyContext();\n\n useEffect(() => registerLabel(), [registerLabel]);\n\n return (\n <div className={cn('tw:flex tw:items-center tw:gap-1', className)}>\n <Label id={labelId}>{children}</Label>\n {leading}\n {trailing != null && <span className=\"tw:ml-auto tw:flex tw:items-center\">{trailing}</span>}\n </div>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyAddonProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Muted, non-selectable prefix addon with a trailing divider (not part of the copied value). */\nexport const CopyPrefix = ({ children, className }: CopyAddonProps) => (\n <span\n aria-hidden\n className={cn(\n 'tw:shrink-0 tw:select-none tw:self-stretch tw:border-r tw:border-border tw:pr-2 tw:text-muted-foreground',\n className,\n )}\n >\n {children}\n </span>\n);\n","import type { MouseEvent } from 'react';\n\nimport { Eye, EyeOff } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyRevealProps = {\n className?: string;\n /** Names what the eye reveals, e.g. `password` → \"Show password\"; defaults to `value`. */\n subject?: string;\n};\n\n/** Eye toggle that reveals/masks `CopyField.Hidden` content. Renders nothing without revealable content. */\nexport const CopyReveal = ({ className, subject = 'value' }: CopyRevealProps) => {\n const { hidden, toggleHidden, hasRevealable, maxLines } = useCopyContext();\n\n if (!hasRevealable) return null;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n toggleHidden();\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n aria-label={`${hidden ? 'Show' : 'Hide'} ${subject}`}\n className={cn(\n 'tw:flex tw:shrink-0 tw:items-center tw:text-muted-foreground tw:hover:text-foreground',\n maxLines > 1 && 'tw:self-start tw:pt-0.5',\n className,\n )}\n >\n {hidden ? <Eye className=\"tw:size-4\" /> : <EyeOff className=\"tw:size-4\" />}\n </button>\n );\n};\n","import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn, copyToClipboard } from '../../utils';\n\nimport { CopyContext } from './CopyContext';\n\ntype CopyRootProps = {\n /** The value copied to the clipboard on click. */\n value: string;\n /** Render displayed content in monospace/code style. */\n mono?: boolean;\n /** Callback fired after a successful copy. */\n onCopy?: () => void;\n /** Start with revealable `CopyField.Hidden` content masked. */\n hiddenByDefault?: boolean;\n /** Minimum number of visible text lines for a multi-line box. */\n minLines?: number;\n /** Maximum number of visible text lines before the box scrolls. */\n maxLines?: number;\n /** Show the \"Copy\" hover hint (set `false` to only show \"Copied\" on copy). Defaults to `true`. */\n hoverHint?: boolean;\n /** Additional CSS classes on the outer container. */\n className?: string;\n children: ReactNode;\n};\n\n/**\n * Container for the Copy block. Owns the copied `value`, copy/mask state, and the\n * shared context consumed by `CopyField.Box`, `CopyField.Reveal`, `CopyField.Button`, etc.\n */\nexport const CopyRoot = ({\n value,\n mono = false,\n onCopy,\n hiddenByDefault = false,\n minLines = 1,\n maxLines,\n hoverHint = true,\n className,\n children,\n}: CopyRootProps) => {\n const [copied, setCopied] = useState(false);\n const [hidden, setHidden] = useState(hiddenByDefault);\n const [revealableCount, setRevealableCount] = useState(0);\n const [labelCount, setLabelCount] = useState(0);\n const resetTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const generatedId = useId();\n const labelId = `${generatedId}-label`;\n const boxId = `${generatedId}-box`;\n\n useEffect(() => () => clearTimeout(resetTimerRef.current), []);\n\n const handleCopy = useCallback(() => {\n const selection = window.getSelection();\n const boxEl = document.getElementById(boxId);\n if (\n selection &&\n !selection.isCollapsed &&\n selection.anchorNode &&\n boxEl?.contains(selection.anchorNode)\n ) {\n return;\n }\n\n copyToClipboard(value)\n .then(() => {\n onCopy?.();\n setCopied(true);\n clearTimeout(resetTimerRef.current);\n resetTimerRef.current = setTimeout(() => setCopied(false), 1500);\n })\n .catch((error: unknown) => {\n // eslint-disable-next-line no-console\n console.error('Copy to clipboard failed', error);\n });\n }, [value, onCopy, boxId]);\n\n const toggleHidden = useCallback(() => setHidden((prev) => !prev), []);\n\n const registerRevealable = useCallback(() => {\n setRevealableCount((count) => count + 1);\n return () => setRevealableCount((count) => count - 1);\n }, []);\n\n const registerLabel = useCallback(() => {\n setLabelCount((count) => count + 1);\n return () => setLabelCount((count) => count - 1);\n }, []);\n\n const contextValue = useMemo(\n () => ({\n copied,\n handleCopy,\n value,\n mono,\n hidden,\n toggleHidden,\n registerRevealable,\n hasRevealable: revealableCount > 0,\n registerLabel,\n hasLabel: labelCount > 0,\n minLines,\n maxLines: maxLines ?? minLines,\n hoverHint,\n labelId,\n boxId,\n }),\n [\n copied,\n handleCopy,\n value,\n mono,\n hidden,\n toggleHidden,\n registerRevealable,\n revealableCount,\n registerLabel,\n labelCount,\n minLines,\n maxLines,\n hoverHint,\n labelId,\n boxId,\n ],\n );\n\n return (\n <CopyContext value={contextValue}>\n <div className={cn('tw:flex tw:w-fit tw:max-w-full tw:flex-col tw:gap-1', className)}>\n {children}\n </div>\n </CopyContext>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyAddonProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Muted, non-selectable suffix addon with a leading divider (not part of the copied value). */\nexport const CopySuffix = ({ children, className }: CopyAddonProps) => (\n <span\n aria-hidden\n className={cn(\n 'tw:shrink-0 tw:select-none tw:self-stretch tw:border-l tw:border-border tw:pl-2 tw:text-muted-foreground',\n className,\n )}\n >\n {children}\n </span>\n);\n","import { CopyBox } from './CopyBox';\nimport { CopyButton } from './CopyButton';\nimport { CopyChildren } from './CopyChildren';\nimport { CopyFooter } from './CopyFooter';\nimport { CopyHidden } from './CopyHidden';\nimport { CopyLabel } from './CopyLabel';\nimport { CopyPrefix } from './CopyPrefix';\nimport { CopyReveal } from './CopyReveal';\nimport { CopyRoot } from './CopyRoot';\nimport { CopySuffix } from './CopySuffix';\n\n/**\n * Readonly value/command box that copies `value` on click.\n *\n * - A click that ends a text selection does not copy.\n * - `mono` for commands; `maxLines > 1` wraps and scrolls between `minLines` and `maxLines`.\n * - `CopyField.Hidden` masks content; copy still copies the real `value`.\n */\nexport const CopyField = {\n /** Owns `value`, mask and copy state. */\n Root: CopyRoot,\n /** Label above the box, with `leading`/`trailing` slots. */\n Label: CopyLabel,\n /** The clickable copy target. */\n Box: CopyBox,\n /** Not copied. */\n Prefix: CopyPrefix,\n /** The displayed value. */\n Children: CopyChildren,\n /** Not copied. */\n Suffix: CopySuffix,\n /** Masked display only; copy still copies the real value. */\n Hidden: CopyHidden,\n /** Toggles revealable `CopyField.Hidden` content. */\n Reveal: CopyReveal,\n /** Copy icon with Copy → Check feedback. */\n Button: CopyButton,\n /** Helper text below the box. */\n Footer: CopyFooter,\n};\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { createChangeInputEvent } from "./utils-Bd28bWgm.js";
1
+ import { createChangeInputEvent } from "./utils-p6tjltbX.js";
2
2
  import { mergeRefs } from "./internal/utils/mergeRefs.js";
3
- import { Calendar, X } from "./icons-wcA70iQx.js";
4
- import { InputGroup } from "./InputGroup-CrlMRz4X.js";
3
+ import { Calendar, X } from "./icons-ZIeZXXS7.js";
4
+ import { InputGroup } from "./InputGroup-Dm014ruw.js";
5
5
  import { useControllableState } from "./useControllableState-CUYXMsfz.js";
6
- import { DatePicker } from "./DatePicker-CtSa9b3V.js";
6
+ import { DatePicker } from "./DatePicker-CgHAu9KX.js";
7
7
  import { useRef, useState } from "react";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/blocks/DateInput/helpers.ts
@@ -138,4 +138,4 @@ const DateInput = ({ ref, state, variant, focusVariant, sizing, className, value
138
138
  //#endregion
139
139
  export { DateInput };
140
140
 
141
- //# sourceMappingURL=DateInput-D0nWUasV.js.map
141
+ //# sourceMappingURL=DateInput-BlKkequE.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateInput-D0nWUasV.js","names":["CalendarIcon"],"sources":["../src/blocks/DateInput/helpers.ts","../src/blocks/DateInput/DateInput.tsx"],"sourcesContent":["export const formatDate = (date: Date | null | undefined, inputValue: string): string => {\n if (!date) {\n return inputValue;\n }\n return date.toLocaleDateString();\n};\n\n// Detect locale day/month/year order once, matching toLocaleDateString() output\nconst datePartOrder = new Intl.DateTimeFormat()\n .formatToParts(new Date(2000, 0, 2))\n .filter(\n (p): p is { type: 'day' | 'month' | 'year'; value: string } =>\n p.type === 'day' || p.type === 'month' || p.type === 'year',\n )\n .map((p) => p.type);\n\nexport const parseDate = (value: string): Date | null => {\n if (!value.trim()) return null;\n\n // Try locale-aware parsing first (matches toLocaleDateString round-trip)\n const nums = value.match(/\\d+/g)?.map(Number);\n if (nums && nums.length >= 3) {\n const parts = Object.fromEntries(datePartOrder.map((type, i) => [type, nums[i]]));\n const year = parts.year;\n const month = parts.month;\n const day = parts.day;\n\n if (\n year != null &&\n month != null &&\n day != null &&\n month >= 1 &&\n month <= 12 &&\n day >= 1 &&\n day <= 31\n ) {\n const date = new Date(year, month - 1, day);\n if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {\n return date;\n }\n }\n }\n\n // Fallback: detect ISO YYYY-MM-DD and construct as local midnight to avoid UTC offset issues\n const isoMatch = value.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/);\n if (isoMatch) {\n const y = Number(isoMatch[1]);\n const m = Number(isoMatch[2]) - 1;\n const d = Number(isoMatch[3]);\n const date = new Date(y, m, d);\n if (date.getFullYear() === y && date.getMonth() === m && date.getDate() === d) {\n return date;\n }\n return null;\n }\n\n const fallback = new Date(value);\n return isNaN(fallback.getTime()) ? null : fallback;\n};\n","import { useRef, useState } from 'react';\nimport type {\n ChangeEventHandler,\n ComponentProps,\n ComponentRef,\n FocusEventHandler,\n MouseEventHandler,\n} from 'react';\nimport type { Matcher } from 'react-day-picker';\n\nimport { DatePicker } from '../../components/DatePicker';\nimport { InputGroup } from '../../components/InputGroup';\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { Calendar as CalendarIcon, X } from '../../icons';\nimport { createChangeInputEvent, mergeRefs } from '../../utils';\n\nimport { formatDate, parseDate } from './helpers';\n\ntype InputGroupProps = Pick<\n ComponentProps<typeof InputGroup>,\n 'variant' | 'focusVariant' | 'state' | 'sizing'\n>;\n\ntype InputGroupInputProps = Omit<\n ComponentProps<typeof InputGroup.Input>,\n 'value' | 'defaultValue' | 'type'\n>;\n\ntype Props = InputGroupProps &\n InputGroupInputProps & {\n value?: Date | null;\n defaultValue?: Date | null;\n onValueChange?: (value: Date | null) => void;\n onValueBlur?: (value: Date | null) => void;\n allowClear?: boolean;\n disabledDays?: Matcher | Matcher[];\n endMonth?: Date;\n startMonth?: Date;\n };\n\nexport const DateInput = ({\n ref,\n\n // group props\n state,\n variant,\n focusVariant,\n sizing,\n className,\n\n // own props\n value,\n defaultValue,\n onValueChange,\n onValueBlur,\n onChange,\n onBlur,\n onFocus,\n allowClear = false,\n disabledDays,\n endMonth,\n startMonth,\n\n // input props\n disabled,\n readOnly,\n placeholder = 'Select a date',\n ...restInputProps\n}: Props) => {\n const inputRef = useRef<ComponentRef<'input'>>(null);\n\n const [inputValue, setInputValue] = useState('');\n const [hasFocus, setHasFocus] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [month, setMonth] = useState<Date>(new Date());\n\n // `onValueChange` is fired explicitly per-path below (not through the hook), because commits\n // happen on blur / picker-select rather than on every keystroke.\n const [currentValue, setCurrentValue] = useControllableState<Date | null>({\n prop: value,\n defaultProp: defaultValue ?? null,\n });\n\n const canClear = allowClear && !!currentValue && !disabled && !readOnly;\n const showPicker = !disabled && !readOnly;\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n setInputValue(newValue);\n onChange?.(event);\n\n const parsedDate = parseDate(newValue);\n if (parsedDate !== null || !newValue.trim()) {\n onValueChange?.(parsedDate);\n }\n };\n\n const handleFocus: FocusEventHandler<HTMLInputElement> = (event) => {\n const formatted = formatDate(currentValue, '');\n setInputValue(formatted);\n setHasFocus(true);\n onFocus?.(event);\n };\n\n const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {\n setHasFocus(false);\n onBlur?.(event);\n\n // If the field still shows the formatted current value (focused and blurred\n // without editing), keep it as-is. `formatDate` uses `toLocaleDateString`,\n // whose output is not reliably parseable by `parseDate` in every locale, so\n // round-tripping an untouched value could wrongly null it.\n const text = event.target.value;\n const parsedDate = text === formatDate(currentValue, '') ? currentValue : parseDate(text);\n onValueBlur?.(parsedDate);\n\n setCurrentValue(parsedDate);\n };\n\n const handleDatePickerChange = (newValue?: Date) => {\n const dateValue = newValue ?? null;\n\n setCurrentValue(dateValue);\n onValueChange?.(dateValue);\n\n setHasFocus(false);\n setIsOpen(false);\n };\n\n const handleClear: MouseEventHandler<HTMLButtonElement> = () => {\n if (!inputRef.current) return;\n inputRef.current.value = '';\n setInputValue('');\n setCurrentValue(null);\n onValueChange?.(null);\n onChange?.(createChangeInputEvent(inputRef.current));\n };\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n setMonth(currentValue ?? new Date());\n }\n setIsOpen(open);\n };\n\n const displayValue = hasFocus ? inputValue : formatDate(currentValue, '');\n\n return (\n <InputGroup\n state={state}\n variant={variant}\n sizing={sizing}\n focusVariant={focusVariant}\n className={className}\n >\n <InputGroup.Input\n {...restInputProps}\n ref={mergeRefs(ref ?? null, inputRef)}\n type=\"text\"\n value={displayValue}\n placeholder={placeholder}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={disabled}\n readOnly={readOnly}\n />\n\n {(canClear || showPicker) && (\n <InputGroup.Addon align=\"inline-end\">\n {canClear && (\n <InputGroup.Button\n aria-label=\"Clear date\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n >\n <X className=\"tw:size-4\" />\n </InputGroup.Button>\n )}\n {showPicker && (\n <DatePicker\n disabled={disabledDays}\n endMonth={endMonth}\n mode=\"single\"\n month={month}\n onMonthChange={setMonth}\n onOpenChange={handleOpenChange}\n onSelect={handleDatePickerChange}\n open={isOpen}\n selected={currentValue ?? undefined}\n startMonth={startMonth}\n >\n <InputGroup.Button aria-label=\"Select Date\">\n <CalendarIcon className=\"tw:size-4\" />\n </InputGroup.Button>\n </DatePicker>\n )}\n </InputGroup.Addon>\n )}\n </InputGroup>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"DateInput-BlKkequE.js","names":["CalendarIcon"],"sources":["../src/blocks/DateInput/helpers.ts","../src/blocks/DateInput/DateInput.tsx"],"sourcesContent":["export const formatDate = (date: Date | null | undefined, inputValue: string): string => {\n if (!date) {\n return inputValue;\n }\n return date.toLocaleDateString();\n};\n\n// Detect locale day/month/year order once, matching toLocaleDateString() output\nconst datePartOrder = new Intl.DateTimeFormat()\n .formatToParts(new Date(2000, 0, 2))\n .filter(\n (p): p is { type: 'day' | 'month' | 'year'; value: string } =>\n p.type === 'day' || p.type === 'month' || p.type === 'year',\n )\n .map((p) => p.type);\n\nexport const parseDate = (value: string): Date | null => {\n if (!value.trim()) return null;\n\n // Try locale-aware parsing first (matches toLocaleDateString round-trip)\n const nums = value.match(/\\d+/g)?.map(Number);\n if (nums && nums.length >= 3) {\n const parts = Object.fromEntries(datePartOrder.map((type, i) => [type, nums[i]]));\n const year = parts.year;\n const month = parts.month;\n const day = parts.day;\n\n if (\n year != null &&\n month != null &&\n day != null &&\n month >= 1 &&\n month <= 12 &&\n day >= 1 &&\n day <= 31\n ) {\n const date = new Date(year, month - 1, day);\n if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {\n return date;\n }\n }\n }\n\n // Fallback: detect ISO YYYY-MM-DD and construct as local midnight to avoid UTC offset issues\n const isoMatch = value.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/);\n if (isoMatch) {\n const y = Number(isoMatch[1]);\n const m = Number(isoMatch[2]) - 1;\n const d = Number(isoMatch[3]);\n const date = new Date(y, m, d);\n if (date.getFullYear() === y && date.getMonth() === m && date.getDate() === d) {\n return date;\n }\n return null;\n }\n\n const fallback = new Date(value);\n return isNaN(fallback.getTime()) ? null : fallback;\n};\n","import { useRef, useState } from 'react';\nimport type {\n ChangeEventHandler,\n ComponentProps,\n ComponentRef,\n FocusEventHandler,\n MouseEventHandler,\n} from 'react';\nimport type { Matcher } from 'react-day-picker';\n\nimport { DatePicker } from '../../components/DatePicker';\nimport { InputGroup } from '../../components/InputGroup';\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { Calendar as CalendarIcon, X } from '../../icons';\nimport { createChangeInputEvent, mergeRefs } from '../../utils';\n\nimport { formatDate, parseDate } from './helpers';\n\ntype InputGroupProps = Pick<\n ComponentProps<typeof InputGroup>,\n 'variant' | 'focusVariant' | 'state' | 'sizing'\n>;\n\ntype InputGroupInputProps = Omit<\n ComponentProps<typeof InputGroup.Input>,\n 'value' | 'defaultValue' | 'type'\n>;\n\ntype Props = InputGroupProps &\n InputGroupInputProps & {\n value?: Date | null;\n defaultValue?: Date | null;\n onValueChange?: (value: Date | null) => void;\n onValueBlur?: (value: Date | null) => void;\n allowClear?: boolean;\n disabledDays?: Matcher | Matcher[];\n endMonth?: Date;\n startMonth?: Date;\n };\n\nexport const DateInput = ({\n ref,\n\n // group props\n state,\n variant,\n focusVariant,\n sizing,\n className,\n\n // own props\n value,\n defaultValue,\n onValueChange,\n onValueBlur,\n onChange,\n onBlur,\n onFocus,\n allowClear = false,\n disabledDays,\n endMonth,\n startMonth,\n\n // input props\n disabled,\n readOnly,\n placeholder = 'Select a date',\n ...restInputProps\n}: Props) => {\n const inputRef = useRef<ComponentRef<'input'>>(null);\n\n const [inputValue, setInputValue] = useState('');\n const [hasFocus, setHasFocus] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [month, setMonth] = useState<Date>(new Date());\n\n // `onValueChange` is fired explicitly per-path below (not through the hook), because commits\n // happen on blur / picker-select rather than on every keystroke.\n const [currentValue, setCurrentValue] = useControllableState<Date | null>({\n prop: value,\n defaultProp: defaultValue ?? null,\n });\n\n const canClear = allowClear && !!currentValue && !disabled && !readOnly;\n const showPicker = !disabled && !readOnly;\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n setInputValue(newValue);\n onChange?.(event);\n\n const parsedDate = parseDate(newValue);\n if (parsedDate !== null || !newValue.trim()) {\n onValueChange?.(parsedDate);\n }\n };\n\n const handleFocus: FocusEventHandler<HTMLInputElement> = (event) => {\n const formatted = formatDate(currentValue, '');\n setInputValue(formatted);\n setHasFocus(true);\n onFocus?.(event);\n };\n\n const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {\n setHasFocus(false);\n onBlur?.(event);\n\n // If the field still shows the formatted current value (focused and blurred\n // without editing), keep it as-is. `formatDate` uses `toLocaleDateString`,\n // whose output is not reliably parseable by `parseDate` in every locale, so\n // round-tripping an untouched value could wrongly null it.\n const text = event.target.value;\n const parsedDate = text === formatDate(currentValue, '') ? currentValue : parseDate(text);\n onValueBlur?.(parsedDate);\n\n setCurrentValue(parsedDate);\n };\n\n const handleDatePickerChange = (newValue?: Date) => {\n const dateValue = newValue ?? null;\n\n setCurrentValue(dateValue);\n onValueChange?.(dateValue);\n\n setHasFocus(false);\n setIsOpen(false);\n };\n\n const handleClear: MouseEventHandler<HTMLButtonElement> = () => {\n if (!inputRef.current) return;\n inputRef.current.value = '';\n setInputValue('');\n setCurrentValue(null);\n onValueChange?.(null);\n onChange?.(createChangeInputEvent(inputRef.current));\n };\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n setMonth(currentValue ?? new Date());\n }\n setIsOpen(open);\n };\n\n const displayValue = hasFocus ? inputValue : formatDate(currentValue, '');\n\n return (\n <InputGroup\n state={state}\n variant={variant}\n sizing={sizing}\n focusVariant={focusVariant}\n className={className}\n >\n <InputGroup.Input\n {...restInputProps}\n ref={mergeRefs(ref ?? null, inputRef)}\n type=\"text\"\n value={displayValue}\n placeholder={placeholder}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={disabled}\n readOnly={readOnly}\n />\n\n {(canClear || showPicker) && (\n <InputGroup.Addon align=\"inline-end\">\n {canClear && (\n <InputGroup.Button\n aria-label=\"Clear date\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n >\n <X className=\"tw:size-4\" />\n </InputGroup.Button>\n )}\n {showPicker && (\n <DatePicker\n disabled={disabledDays}\n endMonth={endMonth}\n mode=\"single\"\n month={month}\n onMonthChange={setMonth}\n onOpenChange={handleOpenChange}\n onSelect={handleDatePickerChange}\n open={isOpen}\n selected={currentValue ?? undefined}\n startMonth={startMonth}\n >\n <InputGroup.Button aria-label=\"Select Date\">\n <CalendarIcon className=\"tw:size-4\" />\n </InputGroup.Button>\n </DatePicker>\n )}\n </InputGroup.Addon>\n )}\n </InputGroup>\n );\n};\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { Popover } from "./Popover-CEk915I1.js";
2
- import { Calendar } from "./Calendar-DFtmZzbF.js";
1
+ import { Popover } from "./Popover-BU7nGOv-.js";
2
+ import { Calendar } from "./Calendar-BnKi1kPu.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/components/DatePicker/DatePicker.tsx
5
5
  const DatePicker = ({ align = "end", alignOffset = -18, children, defaultOpen, onOpenChange, open, sideOffset = 12, ...calendarProps }) => /* @__PURE__ */ jsxs(Popover, {
@@ -21,4 +21,4 @@ DatePicker.displayName = "DatePicker";
21
21
  //#endregion
22
22
  export { DatePicker };
23
23
 
24
- //# sourceMappingURL=DatePicker-CtSa9b3V.js.map
24
+ //# sourceMappingURL=DatePicker-CgHAu9KX.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker-CtSa9b3V.js","names":[],"sources":["../src/components/DatePicker/DatePicker.tsx"],"sourcesContent":["import type { PropsWithChildren } from 'react';\nimport type { PopoverContentProps, PopoverProps } from '@radix-ui/react-popover';\n\nimport type { CalendarProps } from '../Calendar';\nimport { Calendar } from '../Calendar';\nimport { Popover } from '../Popover';\n\ntype OwnPopoverProps = PropsWithChildren &\n Pick<PopoverProps, 'open' | 'onOpenChange' | 'defaultOpen'> &\n Pick<PopoverContentProps, 'align' | 'alignOffset' | 'sideOffset'>;\n\ntype DatePickerProps = OwnPopoverProps & CalendarProps;\n\nexport const DatePicker = ({\n align = 'end',\n alignOffset = -18,\n children,\n defaultOpen,\n onOpenChange,\n open,\n sideOffset = 12,\n ...calendarProps\n}: DatePickerProps) => (\n <Popover defaultOpen={defaultOpen} open={open} onOpenChange={onOpenChange}>\n <Popover.Trigger asChild>{children}</Popover.Trigger>\n <Popover.Content\n align={align}\n alignOffset={alignOffset}\n className=\"tw:w-auto tw:p-0\"\n sideOffset={sideOffset}\n >\n <Calendar {...calendarProps} />\n </Popover.Content>\n </Popover>\n);\n\nDatePicker.displayName = 'DatePicker';\n"],"mappings":";;;;AAaA,MAAa,cAAc,EACzB,QAAQ,OACR,cAAc,KACd,UACA,aACA,cACA,MACA,aAAa,IACb,GAAG,oBAEH,qBAAC,SAAD;CAAsB;CAAmB;CAAoB;CAA7D,UAAA,CACE,oBAAC,QAAQ,SAAT;EAAiB,SAAA;EAAS;CAA0B,CAAA,GACpD,oBAAC,QAAQ,SAAT;EACS;EACM;EACb,WAAU;EACE;EAEZ,UAAA,oBAAC,UAAD,EAAU,GAAI,cAAgB,CAAA;CACf,CAAA,CACV;;AAGX,WAAW,cAAc"}
1
+ {"version":3,"file":"DatePicker-CgHAu9KX.js","names":[],"sources":["../src/components/DatePicker/DatePicker.tsx"],"sourcesContent":["import type { PropsWithChildren } from 'react';\nimport type { PopoverContentProps, PopoverProps } from '@radix-ui/react-popover';\n\nimport type { CalendarProps } from '../Calendar';\nimport { Calendar } from '../Calendar';\nimport { Popover } from '../Popover';\n\ntype OwnPopoverProps = PropsWithChildren &\n Pick<PopoverProps, 'open' | 'onOpenChange' | 'defaultOpen'> &\n Pick<PopoverContentProps, 'align' | 'alignOffset' | 'sideOffset'>;\n\ntype DatePickerProps = OwnPopoverProps & CalendarProps;\n\nexport const DatePicker = ({\n align = 'end',\n alignOffset = -18,\n children,\n defaultOpen,\n onOpenChange,\n open,\n sideOffset = 12,\n ...calendarProps\n}: DatePickerProps) => (\n <Popover defaultOpen={defaultOpen} open={open} onOpenChange={onOpenChange}>\n <Popover.Trigger asChild>{children}</Popover.Trigger>\n <Popover.Content\n align={align}\n alignOffset={alignOffset}\n className=\"tw:w-auto tw:p-0\"\n sideOffset={sideOffset}\n >\n <Calendar {...calendarProps} />\n </Popover.Content>\n </Popover>\n);\n\nDatePicker.displayName = 'DatePicker';\n"],"mappings":";;;;AAaA,MAAa,cAAc,EACzB,QAAQ,OACR,cAAc,KACd,UACA,aACA,cACA,MACA,aAAa,IACb,GAAG,oBAEH,qBAAC,SAAD;CAAsB;CAAmB;CAAoB;CAA7D,UAAA,CACE,oBAAC,QAAQ,SAAT;EAAiB,SAAA;EAAS;CAA0B,CAAA,GACpD,oBAAC,QAAQ,SAAT;EACS;EACM;EACb,WAAU;EACE;EAEZ,UAAA,oBAAC,UAAD,EAAU,GAAI,cAAgB,CAAA;CACf,CAAA,CACV;;AAGX,WAAW,cAAc"}
@@ -1,9 +1,9 @@
1
- import { createChangeInputEvent } from "./utils-Bd28bWgm.js";
1
+ import { createChangeInputEvent } from "./utils-p6tjltbX.js";
2
2
  import { mergeRefs } from "./internal/utils/mergeRefs.js";
3
- import { Calendar, X } from "./icons-wcA70iQx.js";
4
- import { InputGroup } from "./InputGroup-CrlMRz4X.js";
3
+ import { Calendar, X } from "./icons-ZIeZXXS7.js";
4
+ import { InputGroup } from "./InputGroup-Dm014ruw.js";
5
5
  import { useControllableState } from "./useControllableState-CUYXMsfz.js";
6
- import { DatePicker } from "./DatePicker-CtSa9b3V.js";
6
+ import { DatePicker } from "./DatePicker-CgHAu9KX.js";
7
7
  import { useRef, useState } from "react";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/blocks/DateRangeInput/helpers.ts
@@ -132,4 +132,4 @@ const DateRangeInput = ({ ref, state, variant, focusVariant, sizing, className,
132
132
  //#endregion
133
133
  export { DateRangeInput };
134
134
 
135
- //# sourceMappingURL=DateRangeInput-i6wE45-V.js.map
135
+ //# sourceMappingURL=DateRangeInput-DOxJHw8V.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateRangeInput-i6wE45-V.js","names":["CalendarIcon"],"sources":["../src/blocks/DateRangeInput/helpers.ts","../src/blocks/DateRangeInput/DateRangeInput.tsx"],"sourcesContent":["import type { DateRange } from 'react-day-picker';\n\nexport const formatDateRange = (\n range: DateRange | null | undefined,\n inputValue: string,\n): string => {\n if (!range) {\n return inputValue;\n }\n\n const { from, to } = range;\n const fromStr = from?.toLocaleDateString();\n const toStr = to?.toLocaleDateString();\n return `${fromStr} - ${toStr}`;\n};\n\nconst ISO_DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * Parses date-only ISO (`2024-01-15`) as local time, not UTC midnight.\n *\n * - UTC midnight reads back as the previous day west of UTC.\n * - Keeps `new Date` validation; `new Date(y, m - 1, d)` would roll `2024-13-45` over.\n * - Other accepted formats already parse as local time.\n */\nconst parseLocalDate = (value: string): Date =>\n ISO_DATE_ONLY.test(value) ? new Date(`${value}T00:00:00`) : new Date(value);\n\nexport const parseDateRange = (value: string): DateRange | null => {\n const parts = value.split(' - ');\n if (parts.length !== 2) {\n return null;\n }\n\n const [fromPart, toPart] = parts;\n if (!fromPart || !toPart) {\n return null;\n }\n\n const from = parseLocalDate(fromPart.trim());\n const to = parseLocalDate(toPart.trim());\n\n if (isNaN(from.getTime()) || isNaN(to.getTime())) {\n return null;\n }\n\n return { from, to };\n};\n","import { useRef, useState } from 'react';\nimport type { ChangeEventHandler, ComponentProps, ComponentRef, FocusEventHandler } from 'react';\nimport type { DateRange } from 'react-day-picker';\n\nimport { DatePicker } from '../../components/DatePicker';\nimport { InputGroup } from '../../components/InputGroup';\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { Calendar as CalendarIcon, X } from '../../icons';\nimport { createChangeInputEvent, mergeRefs } from '../../utils';\n\nimport { formatDateRange, parseDateRange } from './helpers';\n\ntype InputGroupProps = Pick<\n ComponentProps<typeof InputGroup>,\n 'variant' | 'focusVariant' | 'state' | 'sizing'\n>;\n\ntype InputGroupInputProps = Omit<\n ComponentProps<typeof InputGroup.Input>,\n 'value' | 'defaultValue' | 'type'\n>;\n\ntype Props = InputGroupProps &\n InputGroupInputProps & {\n value?: DateRange | null;\n defaultValue?: DateRange | null;\n onValueChange?: (value: DateRange | null) => void;\n onValueBlur?: (value: DateRange | null) => void;\n allowClear?: boolean;\n startMonth?: Date;\n endMonth?: Date;\n };\n\nexport const DateRangeInput = ({\n ref,\n\n // group props\n state,\n variant,\n focusVariant,\n sizing,\n className,\n\n // own props\n value: valueProp,\n defaultValue,\n onValueChange,\n onValueBlur,\n onChange,\n onBlur,\n onFocus,\n allowClear = false,\n startMonth,\n endMonth,\n\n // input props\n disabled,\n readOnly,\n placeholder = 'Select a date range',\n ...restInputProps\n}: Props) => {\n const inputRef = useRef<ComponentRef<'input'>>(null);\n\n const [inputValue, setInputValue] = useState('');\n const [hasFocus, setHasFocus] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [month, setMonth] = useState<Date>(new Date());\n\n // `onValueChange` is fired explicitly per-path below (not through the hook), because commits\n // happen on blur / picker-select rather than on every keystroke.\n const [currentValue, setCurrentValue] = useControllableState<DateRange | null>({\n prop: valueProp,\n defaultProp: defaultValue ?? null,\n });\n\n const canClear = allowClear && !!currentValue && !disabled && !readOnly;\n const showPicker = !disabled && !readOnly;\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n setInputValue(newValue);\n onChange?.(event);\n\n const parsedRange = parseDateRange(newValue);\n if (parsedRange !== null || !newValue.trim()) {\n onValueChange?.(parsedRange);\n }\n };\n\n const handleFocus: FocusEventHandler<HTMLInputElement> = (event) => {\n setInputValue(formatDateRange(currentValue, ''));\n setHasFocus(true);\n onFocus?.(event);\n };\n\n const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {\n setHasFocus(false);\n onBlur?.(event);\n\n // If the field still shows the formatted current value (focused and blurred\n // without editing), keep it as-is. `formatDateRange` uses `toLocaleDateString`,\n // whose output is not reliably parseable by `new Date(...)` in every locale, so\n // round-tripping an untouched value through `parseDateRange` could wrongly null it.\n const text = event.target.value;\n const parsedRange =\n text === formatDateRange(currentValue, '') ? currentValue : parseDateRange(text);\n onValueBlur?.(parsedRange);\n\n setCurrentValue(parsedRange);\n };\n\n const handleDatePickerChange = (newValue: DateRange | undefined) => {\n const rangeValue = newValue ?? null;\n\n setCurrentValue(rangeValue);\n onValueChange?.(rangeValue);\n\n setHasFocus(false);\n };\n\n const handleClear = () => {\n if (!inputRef.current) return;\n inputRef.current.value = '';\n setInputValue('');\n setCurrentValue(null);\n onValueChange?.(null);\n onChange?.(createChangeInputEvent(inputRef.current));\n };\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n setMonth(currentValue?.from ?? new Date());\n }\n setIsOpen(open);\n };\n\n const displayValue = hasFocus ? inputValue : formatDateRange(currentValue, '');\n\n return (\n <InputGroup\n state={state}\n variant={variant}\n sizing={sizing}\n focusVariant={focusVariant}\n className={className}\n >\n <InputGroup.Input\n {...restInputProps}\n ref={mergeRefs(ref ?? null, inputRef)}\n type=\"text\"\n value={displayValue}\n placeholder={placeholder}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={disabled}\n readOnly={readOnly}\n />\n\n {(canClear || showPicker) && (\n <InputGroup.Addon align=\"inline-end\">\n {canClear && (\n <InputGroup.Button\n aria-label=\"Clear date range\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n >\n <X className=\"tw:size-4\" />\n </InputGroup.Button>\n )}\n {showPicker && (\n <DatePicker\n endMonth={endMonth}\n mode=\"range\"\n month={month}\n onMonthChange={setMonth}\n onOpenChange={handleOpenChange}\n onSelect={handleDatePickerChange}\n open={isOpen}\n startMonth={startMonth}\n selected={currentValue ?? undefined}\n >\n <InputGroup.Button aria-label=\"Select date range\">\n <CalendarIcon className=\"tw:size-4\" />\n </InputGroup.Button>\n </DatePicker>\n )}\n </InputGroup.Addon>\n )}\n </InputGroup>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"DateRangeInput-DOxJHw8V.js","names":["CalendarIcon"],"sources":["../src/blocks/DateRangeInput/helpers.ts","../src/blocks/DateRangeInput/DateRangeInput.tsx"],"sourcesContent":["import type { DateRange } from 'react-day-picker';\n\nexport const formatDateRange = (\n range: DateRange | null | undefined,\n inputValue: string,\n): string => {\n if (!range) {\n return inputValue;\n }\n\n const { from, to } = range;\n const fromStr = from?.toLocaleDateString();\n const toStr = to?.toLocaleDateString();\n return `${fromStr} - ${toStr}`;\n};\n\nconst ISO_DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * Parses date-only ISO (`2024-01-15`) as local time, not UTC midnight.\n *\n * - UTC midnight reads back as the previous day west of UTC.\n * - Keeps `new Date` validation; `new Date(y, m - 1, d)` would roll `2024-13-45` over.\n * - Other accepted formats already parse as local time.\n */\nconst parseLocalDate = (value: string): Date =>\n ISO_DATE_ONLY.test(value) ? new Date(`${value}T00:00:00`) : new Date(value);\n\nexport const parseDateRange = (value: string): DateRange | null => {\n const parts = value.split(' - ');\n if (parts.length !== 2) {\n return null;\n }\n\n const [fromPart, toPart] = parts;\n if (!fromPart || !toPart) {\n return null;\n }\n\n const from = parseLocalDate(fromPart.trim());\n const to = parseLocalDate(toPart.trim());\n\n if (isNaN(from.getTime()) || isNaN(to.getTime())) {\n return null;\n }\n\n return { from, to };\n};\n","import { useRef, useState } from 'react';\nimport type { ChangeEventHandler, ComponentProps, ComponentRef, FocusEventHandler } from 'react';\nimport type { DateRange } from 'react-day-picker';\n\nimport { DatePicker } from '../../components/DatePicker';\nimport { InputGroup } from '../../components/InputGroup';\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { Calendar as CalendarIcon, X } from '../../icons';\nimport { createChangeInputEvent, mergeRefs } from '../../utils';\n\nimport { formatDateRange, parseDateRange } from './helpers';\n\ntype InputGroupProps = Pick<\n ComponentProps<typeof InputGroup>,\n 'variant' | 'focusVariant' | 'state' | 'sizing'\n>;\n\ntype InputGroupInputProps = Omit<\n ComponentProps<typeof InputGroup.Input>,\n 'value' | 'defaultValue' | 'type'\n>;\n\ntype Props = InputGroupProps &\n InputGroupInputProps & {\n value?: DateRange | null;\n defaultValue?: DateRange | null;\n onValueChange?: (value: DateRange | null) => void;\n onValueBlur?: (value: DateRange | null) => void;\n allowClear?: boolean;\n startMonth?: Date;\n endMonth?: Date;\n };\n\nexport const DateRangeInput = ({\n ref,\n\n // group props\n state,\n variant,\n focusVariant,\n sizing,\n className,\n\n // own props\n value: valueProp,\n defaultValue,\n onValueChange,\n onValueBlur,\n onChange,\n onBlur,\n onFocus,\n allowClear = false,\n startMonth,\n endMonth,\n\n // input props\n disabled,\n readOnly,\n placeholder = 'Select a date range',\n ...restInputProps\n}: Props) => {\n const inputRef = useRef<ComponentRef<'input'>>(null);\n\n const [inputValue, setInputValue] = useState('');\n const [hasFocus, setHasFocus] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [month, setMonth] = useState<Date>(new Date());\n\n // `onValueChange` is fired explicitly per-path below (not through the hook), because commits\n // happen on blur / picker-select rather than on every keystroke.\n const [currentValue, setCurrentValue] = useControllableState<DateRange | null>({\n prop: valueProp,\n defaultProp: defaultValue ?? null,\n });\n\n const canClear = allowClear && !!currentValue && !disabled && !readOnly;\n const showPicker = !disabled && !readOnly;\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n setInputValue(newValue);\n onChange?.(event);\n\n const parsedRange = parseDateRange(newValue);\n if (parsedRange !== null || !newValue.trim()) {\n onValueChange?.(parsedRange);\n }\n };\n\n const handleFocus: FocusEventHandler<HTMLInputElement> = (event) => {\n setInputValue(formatDateRange(currentValue, ''));\n setHasFocus(true);\n onFocus?.(event);\n };\n\n const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {\n setHasFocus(false);\n onBlur?.(event);\n\n // If the field still shows the formatted current value (focused and blurred\n // without editing), keep it as-is. `formatDateRange` uses `toLocaleDateString`,\n // whose output is not reliably parseable by `new Date(...)` in every locale, so\n // round-tripping an untouched value through `parseDateRange` could wrongly null it.\n const text = event.target.value;\n const parsedRange =\n text === formatDateRange(currentValue, '') ? currentValue : parseDateRange(text);\n onValueBlur?.(parsedRange);\n\n setCurrentValue(parsedRange);\n };\n\n const handleDatePickerChange = (newValue: DateRange | undefined) => {\n const rangeValue = newValue ?? null;\n\n setCurrentValue(rangeValue);\n onValueChange?.(rangeValue);\n\n setHasFocus(false);\n };\n\n const handleClear = () => {\n if (!inputRef.current) return;\n inputRef.current.value = '';\n setInputValue('');\n setCurrentValue(null);\n onValueChange?.(null);\n onChange?.(createChangeInputEvent(inputRef.current));\n };\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n setMonth(currentValue?.from ?? new Date());\n }\n setIsOpen(open);\n };\n\n const displayValue = hasFocus ? inputValue : formatDateRange(currentValue, '');\n\n return (\n <InputGroup\n state={state}\n variant={variant}\n sizing={sizing}\n focusVariant={focusVariant}\n className={className}\n >\n <InputGroup.Input\n {...restInputProps}\n ref={mergeRefs(ref ?? null, inputRef)}\n type=\"text\"\n value={displayValue}\n placeholder={placeholder}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={disabled}\n readOnly={readOnly}\n />\n\n {(canClear || showPicker) && (\n <InputGroup.Addon align=\"inline-end\">\n {canClear && (\n <InputGroup.Button\n aria-label=\"Clear date range\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n >\n <X className=\"tw:size-4\" />\n </InputGroup.Button>\n )}\n {showPicker && (\n <DatePicker\n endMonth={endMonth}\n mode=\"range\"\n month={month}\n onMonthChange={setMonth}\n onOpenChange={handleOpenChange}\n onSelect={handleDatePickerChange}\n open={isOpen}\n startMonth={startMonth}\n selected={currentValue ?? undefined}\n >\n <InputGroup.Button aria-label=\"Select date range\">\n <CalendarIcon className=\"tw:size-4\" />\n </InputGroup.Button>\n </DatePicker>\n )}\n </InputGroup.Addon>\n )}\n </InputGroup>\n );\n};\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
- import { cn } from "./classNames-BzrkDnOD.js";
1
+ import { cn } from "./classNames-DcGnTh2N.js";
2
2
  import { useArgoDesign } from "./context-U293r3v-.js";
3
- import { ChevronDown } from "./icons-wcA70iQx.js";
4
- import { Button } from "./Button-B21oVcPU.js";
5
- import { Popover } from "./Popover-CEk915I1.js";
6
- import { Calendar } from "./Calendar-DFtmZzbF.js";
7
- import { overlayTriggerVariants } from "./styles-gzcjOyKv.js";
8
- import { TimePicker, formatTime, pad, parseTime } from "./TimePicker-CDGYrRxi.js";
3
+ import { ChevronDown } from "./icons-ZIeZXXS7.js";
4
+ import { Button } from "./Button-D2JqBAq7.js";
5
+ import { Popover } from "./Popover-BU7nGOv-.js";
6
+ import { Calendar } from "./Calendar-BnKi1kPu.js";
7
+ import { overlayTriggerVariants } from "./styles-YQdM7G8c.js";
8
+ import { TimePicker, formatTime, pad, parseTime } from "./TimePicker-DyyV3nw8.js";
9
9
  import { useState } from "react";
10
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
11
  //#region src/components/DateRangePicker/DateRangePicker.tsx
@@ -152,4 +152,4 @@ DateRangePicker.displayName = "DateRangePicker";
152
152
  //#endregion
153
153
  export { DateRangePicker };
154
154
 
155
- //# sourceMappingURL=DateRangePicker-BAnuz6vO.js.map
155
+ //# sourceMappingURL=DateRangePicker-CXpXPMoh.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateRangePicker-BAnuz6vO.js","names":[],"sources":["../src/components/DateRangePicker/DateRangePicker.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { ReactNode } from 'react';\nimport type { DateRange as DayPickerDateRange, Matcher } from 'react-day-picker';\nimport type { PopoverContentProps, PopoverProps } from '@radix-ui/react-popover';\nimport type { VariantProps } from 'class-variance-authority';\n\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\nimport { Button } from '../Button';\nimport { Calendar } from '../Calendar';\nimport { overlayTriggerVariants } from '../OverlayTrigger/styles';\nimport { Popover } from '../Popover';\nimport { useArgoDesign } from '../ThemeProvider/context';\nimport { TimePicker } from '../TimePicker';\nimport { formatTime, pad, parseTime } from '../TimePicker/utils';\n\nexport type DateRange = {\n from: Date;\n to?: Date;\n};\n\nexport type DateRangePreset = {\n label: string;\n /** Omit for a `value` preset, or for a clear preset (\"All time\") that calls `onChange(undefined)`. */\n range?: DateRange;\n /** Echoed through `onPresetSelect` instead of `range` — e.g. a server-resolved token like `-7 days`. */\n value?: string;\n};\n\ntype DateRangePickerProps = {\n value: DateRange | undefined;\n onChange: (range: DateRange | undefined) => void;\n /** Replaces the trigger's whole range text, e.g. the active preset name; to restyle dates use `formatDate`. */\n label?: ReactNode;\n /** Formats each end of the range on the trigger in place of ISO; the from → to join stays. */\n formatDate?: (date: Date) => string;\n placeholder?: string;\n presets?: readonly DateRangePreset[];\n /** Called instead of `onChange` when a preset is picked, with the preset itself. */\n onPresetSelect?: (preset: DateRangePreset) => void;\n /** Adds a start/end time-of-day row; the emitted `from` / `to` then carry hours and minutes. */\n withTime?: boolean;\n /** Hold edits in a draft and emit only on Apply, so one range costs one `onChange`. */\n requireApply?: boolean;\n /** Days that cannot be picked, as a react-day-picker matcher — e.g. `{ after: new Date() }`. */\n disabledDays?: Matcher | Matcher[];\n variant?: Exclude<VariantProps<typeof overlayTriggerVariants>['variant'], 'argo'>;\n disabled?: boolean;\n className?: string;\n} & Pick<PopoverProps, 'open' | 'onOpenChange' | 'defaultOpen'> &\n Pick<PopoverContentProps, 'align' | 'alignOffset' | 'sideOffset'>;\n\nconst timeOf = (date: Date) => formatTime(date.getHours(), date.getMinutes());\n\nconst isoDate = (date: Date) =>\n `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n\nconst formatRange = (\n range: DateRange | undefined,\n format: (date: Date) => string,\n): string | null => {\n if (!range?.from) return null;\n return range.to ? `${format(range.from)} → ${format(range.to)}` : format(range.from);\n};\n\nconst withHoursMinutes = (target: Date, hour: number, minute: number) => {\n const next = new Date(target);\n next.setHours(hour, minute, 0, 0);\n return next;\n};\n\nconst withTimeOf = (target: Date, source: Date) =>\n withHoursMinutes(target, source.getHours(), source.getMinutes());\n\n/** Returns `target` at `time` (\"HH:mm\"); unparseable input leaves it alone. */\nconst atTime = (target: Date, time: string) => {\n const { hour, minute } = parseTime(time);\n return hour === null || minute === null ? target : withHoursMinutes(target, hour, minute);\n};\n\ntype TimeFieldProps = {\n label: string;\n date: Date | undefined;\n onChange: (time: string) => void;\n};\n\n/** Time-of-day for one end of the range, on the same `TimePicker` the rest of the app uses. */\nconst TimeField = ({ label, date, onChange }: TimeFieldProps) => (\n <div className=\"tw:flex tw:items-center tw:gap-2 tw:text-sm\">\n <span className=\"tw:text-muted-foreground\">{label}</span>\n <TimePicker selected={date ? timeOf(date) : null} onSelect={onChange}>\n <Button variant=\"outline\" size=\"small\" disabled={!date} aria-label={`${label} time`}>\n {date ? timeOf(date) : '--:--'}\n </Button>\n </TimePicker>\n </div>\n);\n\n/** Picks a `{ from, to }` range, with optional presets, time row and Apply step; single date: `DatePicker`. */\nexport const DateRangePicker = ({\n align = 'start',\n alignOffset,\n className,\n defaultOpen,\n disabled = false,\n disabledDays,\n formatDate,\n label,\n onChange,\n onOpenChange,\n onPresetSelect,\n open,\n placeholder = 'Pick a date range',\n presets,\n requireApply = false,\n sideOffset,\n value,\n variant,\n withTime = false,\n}: DateRangePickerProps) => {\n const isArgoDesign = useArgoDesign();\n const [draft, setDraft] = useState<DateRange | undefined>(value);\n\n const handleOpenChange = (nextOpen: boolean) => {\n // Reopening discards a cancelled draft.\n if (nextOpen) setDraft(value);\n onOpenChange?.(nextOpen);\n };\n\n const current = requireApply ? draft : value;\n\n const edit = (range: DateRange | undefined) => {\n if (requireApply) setDraft(range);\n else onChange(range);\n };\n\n const handleSelect = (range: DayPickerDateRange | undefined) => {\n if (!range?.from) {\n edit(undefined);\n return;\n }\n\n // Keeps the set time-of-day; otherwise a day click resets it to midnight.\n edit({\n from: current?.from ? withTimeOf(range.from, current.from) : range.from,\n to: range.to && current?.to ? withTimeOf(range.to, current.to) : range.to,\n });\n };\n\n const format =\n formatDate ?? ((date: Date) => (withTime ? `${isoDate(date)} ${timeOf(date)}` : isoDate(date)));\n const triggerLabel = label ?? formatRange(value, format);\n\n return (\n <Popover open={open} defaultOpen={defaultOpen} onOpenChange={handleOpenChange}>\n <Popover.Trigger\n disabled={disabled}\n className={cn(\n overlayTriggerVariants({ variant: isArgoDesign ? 'argo' : variant, sizing: 'medium' }),\n className,\n )}\n >\n <span className={cn('tw:truncate', !triggerLabel && 'tw:text-muted-foreground')}>\n {triggerLabel ?? placeholder}\n </span>\n <ChevronDown className=\"tw:size-4 tw:text-muted-foreground\" />\n </Popover.Trigger>\n <Popover.Content\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className=\"tw:w-auto tw:p-0\"\n >\n <div className=\"tw:flex\">\n {presets && presets.length > 0 ? (\n <div className=\"tw:flex tw:flex-col tw:gap-1 tw:border-r tw:border-solid tw:border-border tw:p-2\">\n {presets.map((preset) => (\n <Popover.Close asChild key={preset.label}>\n <Button\n variant=\"invisible\"\n size=\"small\"\n className=\"tw:justify-start\"\n onClick={() =>\n onPresetSelect ? onPresetSelect(preset) : onChange(preset.range)\n }\n >\n {preset.label}\n </Button>\n </Popover.Close>\n ))}\n </div>\n ) : null}\n <Calendar\n mode=\"range\"\n selected={current}\n onSelect={handleSelect}\n numberOfMonths={2}\n defaultMonth={current?.from}\n disabled={disabledDays}\n />\n </div>\n {(withTime || requireApply) && (\n <div className=\"tw:flex tw:items-center tw:gap-3 tw:border-t tw:border-solid tw:border-border tw:p-3\">\n {withTime && (\n <>\n <TimeField\n label=\"From\"\n date={current?.from}\n onChange={(time) =>\n current?.from && edit({ ...current, from: atTime(current.from, time) })\n }\n />\n <TimeField\n label=\"To\"\n date={current?.to}\n onChange={(time) =>\n current?.to && edit({ ...current, to: atTime(current.to, time) })\n }\n />\n </>\n )}\n {requireApply && (\n <div className=\"tw:ml-auto tw:flex tw:gap-2\">\n <Popover.Close asChild>\n <Button variant=\"outline\" size=\"small\">\n Cancel\n </Button>\n </Popover.Close>\n <Popover.Close asChild>\n <Button size=\"small\" disabled={!draft?.from} onClick={() => onChange(draft)}>\n Apply\n </Button>\n </Popover.Close>\n </div>\n )}\n </div>\n )}\n </Popover.Content>\n </Popover>\n );\n};\n\nDateRangePicker.displayName = 'DateRangePicker';\n"],"mappings":"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"}
1
+ {"version":3,"file":"DateRangePicker-CXpXPMoh.js","names":[],"sources":["../src/components/DateRangePicker/DateRangePicker.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { ReactNode } from 'react';\nimport type { DateRange as DayPickerDateRange, Matcher } from 'react-day-picker';\nimport type { PopoverContentProps, PopoverProps } from '@radix-ui/react-popover';\nimport type { VariantProps } from 'class-variance-authority';\n\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\nimport { Button } from '../Button';\nimport { Calendar } from '../Calendar';\nimport { overlayTriggerVariants } from '../OverlayTrigger/styles';\nimport { Popover } from '../Popover';\nimport { useArgoDesign } from '../ThemeProvider/context';\nimport { TimePicker } from '../TimePicker';\nimport { formatTime, pad, parseTime } from '../TimePicker/utils';\n\nexport type DateRange = {\n from: Date;\n to?: Date;\n};\n\nexport type DateRangePreset = {\n label: string;\n /** Omit for a `value` preset, or for a clear preset (\"All time\") that calls `onChange(undefined)`. */\n range?: DateRange;\n /** Echoed through `onPresetSelect` instead of `range` — e.g. a server-resolved token like `-7 days`. */\n value?: string;\n};\n\ntype DateRangePickerProps = {\n value: DateRange | undefined;\n onChange: (range: DateRange | undefined) => void;\n /** Replaces the trigger's whole range text, e.g. the active preset name; to restyle dates use `formatDate`. */\n label?: ReactNode;\n /** Formats each end of the range on the trigger in place of ISO; the from → to join stays. */\n formatDate?: (date: Date) => string;\n placeholder?: string;\n presets?: readonly DateRangePreset[];\n /** Called instead of `onChange` when a preset is picked, with the preset itself. */\n onPresetSelect?: (preset: DateRangePreset) => void;\n /** Adds a start/end time-of-day row; the emitted `from` / `to` then carry hours and minutes. */\n withTime?: boolean;\n /** Hold edits in a draft and emit only on Apply, so one range costs one `onChange`. */\n requireApply?: boolean;\n /** Days that cannot be picked, as a react-day-picker matcher — e.g. `{ after: new Date() }`. */\n disabledDays?: Matcher | Matcher[];\n variant?: Exclude<VariantProps<typeof overlayTriggerVariants>['variant'], 'argo'>;\n disabled?: boolean;\n className?: string;\n} & Pick<PopoverProps, 'open' | 'onOpenChange' | 'defaultOpen'> &\n Pick<PopoverContentProps, 'align' | 'alignOffset' | 'sideOffset'>;\n\nconst timeOf = (date: Date) => formatTime(date.getHours(), date.getMinutes());\n\nconst isoDate = (date: Date) =>\n `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n\nconst formatRange = (\n range: DateRange | undefined,\n format: (date: Date) => string,\n): string | null => {\n if (!range?.from) return null;\n return range.to ? `${format(range.from)} → ${format(range.to)}` : format(range.from);\n};\n\nconst withHoursMinutes = (target: Date, hour: number, minute: number) => {\n const next = new Date(target);\n next.setHours(hour, minute, 0, 0);\n return next;\n};\n\nconst withTimeOf = (target: Date, source: Date) =>\n withHoursMinutes(target, source.getHours(), source.getMinutes());\n\n/** Returns `target` at `time` (\"HH:mm\"); unparseable input leaves it alone. */\nconst atTime = (target: Date, time: string) => {\n const { hour, minute } = parseTime(time);\n return hour === null || minute === null ? target : withHoursMinutes(target, hour, minute);\n};\n\ntype TimeFieldProps = {\n label: string;\n date: Date | undefined;\n onChange: (time: string) => void;\n};\n\n/** Time-of-day for one end of the range, on the same `TimePicker` the rest of the app uses. */\nconst TimeField = ({ label, date, onChange }: TimeFieldProps) => (\n <div className=\"tw:flex tw:items-center tw:gap-2 tw:text-sm\">\n <span className=\"tw:text-muted-foreground\">{label}</span>\n <TimePicker selected={date ? timeOf(date) : null} onSelect={onChange}>\n <Button variant=\"outline\" size=\"small\" disabled={!date} aria-label={`${label} time`}>\n {date ? timeOf(date) : '--:--'}\n </Button>\n </TimePicker>\n </div>\n);\n\n/** Picks a `{ from, to }` range, with optional presets, time row and Apply step; single date: `DatePicker`. */\nexport const DateRangePicker = ({\n align = 'start',\n alignOffset,\n className,\n defaultOpen,\n disabled = false,\n disabledDays,\n formatDate,\n label,\n onChange,\n onOpenChange,\n onPresetSelect,\n open,\n placeholder = 'Pick a date range',\n presets,\n requireApply = false,\n sideOffset,\n value,\n variant,\n withTime = false,\n}: DateRangePickerProps) => {\n const isArgoDesign = useArgoDesign();\n const [draft, setDraft] = useState<DateRange | undefined>(value);\n\n const handleOpenChange = (nextOpen: boolean) => {\n // Reopening discards a cancelled draft.\n if (nextOpen) setDraft(value);\n onOpenChange?.(nextOpen);\n };\n\n const current = requireApply ? draft : value;\n\n const edit = (range: DateRange | undefined) => {\n if (requireApply) setDraft(range);\n else onChange(range);\n };\n\n const handleSelect = (range: DayPickerDateRange | undefined) => {\n if (!range?.from) {\n edit(undefined);\n return;\n }\n\n // Keeps the set time-of-day; otherwise a day click resets it to midnight.\n edit({\n from: current?.from ? withTimeOf(range.from, current.from) : range.from,\n to: range.to && current?.to ? withTimeOf(range.to, current.to) : range.to,\n });\n };\n\n const format =\n formatDate ?? ((date: Date) => (withTime ? `${isoDate(date)} ${timeOf(date)}` : isoDate(date)));\n const triggerLabel = label ?? formatRange(value, format);\n\n return (\n <Popover open={open} defaultOpen={defaultOpen} onOpenChange={handleOpenChange}>\n <Popover.Trigger\n disabled={disabled}\n className={cn(\n overlayTriggerVariants({ variant: isArgoDesign ? 'argo' : variant, sizing: 'medium' }),\n className,\n )}\n >\n <span className={cn('tw:truncate', !triggerLabel && 'tw:text-muted-foreground')}>\n {triggerLabel ?? placeholder}\n </span>\n <ChevronDown className=\"tw:size-4 tw:text-muted-foreground\" />\n </Popover.Trigger>\n <Popover.Content\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className=\"tw:w-auto tw:p-0\"\n >\n <div className=\"tw:flex\">\n {presets && presets.length > 0 ? (\n <div className=\"tw:flex tw:flex-col tw:gap-1 tw:border-r tw:border-solid tw:border-border tw:p-2\">\n {presets.map((preset) => (\n <Popover.Close asChild key={preset.label}>\n <Button\n variant=\"invisible\"\n size=\"small\"\n className=\"tw:justify-start\"\n onClick={() =>\n onPresetSelect ? onPresetSelect(preset) : onChange(preset.range)\n }\n >\n {preset.label}\n </Button>\n </Popover.Close>\n ))}\n </div>\n ) : null}\n <Calendar\n mode=\"range\"\n selected={current}\n onSelect={handleSelect}\n numberOfMonths={2}\n defaultMonth={current?.from}\n disabled={disabledDays}\n />\n </div>\n {(withTime || requireApply) && (\n <div className=\"tw:flex tw:items-center tw:gap-3 tw:border-t tw:border-solid tw:border-border tw:p-3\">\n {withTime && (\n <>\n <TimeField\n label=\"From\"\n date={current?.from}\n onChange={(time) =>\n current?.from && edit({ ...current, from: atTime(current.from, time) })\n }\n />\n <TimeField\n label=\"To\"\n date={current?.to}\n onChange={(time) =>\n current?.to && edit({ ...current, to: atTime(current.to, time) })\n }\n />\n </>\n )}\n {requireApply && (\n <div className=\"tw:ml-auto tw:flex tw:gap-2\">\n <Popover.Close asChild>\n <Button variant=\"outline\" size=\"small\">\n Cancel\n </Button>\n </Popover.Close>\n <Popover.Close asChild>\n <Button size=\"small\" disabled={!draft?.from} onClick={() => onChange(draft)}>\n Apply\n </Button>\n </Popover.Close>\n </div>\n )}\n </div>\n )}\n </Popover.Content>\n </Popover>\n );\n};\n\nDateRangePicker.displayName = 'DateRangePicker';\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { cn } from "./classNames-BzrkDnOD.js";
1
+ import { cn } from "./classNames-DcGnTh2N.js";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  //#region src/blocks/DiagramShared/DiagramSource.tsx
4
4
  const DiagramSource = ({ code }) => /* @__PURE__ */ jsx("pre", {
@@ -8,4 +8,4 @@ const DiagramSource = ({ code }) => /* @__PURE__ */ jsx("pre", {
8
8
  //#endregion
9
9
  export { DiagramSource };
10
10
 
11
- //# sourceMappingURL=DiagramSource-C5_d8Gdj.js.map
11
+ //# sourceMappingURL=DiagramSource-jTwmmi9g.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DiagramSource-C5_d8Gdj.js","names":[],"sources":["../src/blocks/DiagramShared/DiagramSource.tsx"],"sourcesContent":["import { cn } from '../../utils';\n\n// The raw source of a diagram/chart fence, shown muted when rendering failed —\n// the shared failure fallback of MermaidDiagram and FlintChart.\nexport const DiagramSource = ({ code }: { code: string }) => (\n <pre\n className={cn(\n 'tw:my-3 tw:overflow-auto tw:whitespace-pre-wrap tw:break-all',\n 'tw:py-3 tw:px-4',\n 'tw:bg-muted',\n 'tw:rounded-md tw:text-muted-foreground',\n 'tw:text-sm tw:font-mono',\n )}\n >\n <code>{code}</code>\n </pre>\n);\n"],"mappings":";;;AAIA,MAAa,iBAAiB,EAAE,WAC9B,oBAAC,OAAD;CACE,WAAW,GACT,gEACA,mBACA,eACA,0CACA,yBACF;CAEA,UAAA,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA;AACf,CAAA"}
1
+ {"version":3,"file":"DiagramSource-jTwmmi9g.js","names":[],"sources":["../src/blocks/DiagramShared/DiagramSource.tsx"],"sourcesContent":["import { cn } from '../../utils';\n\n// The raw source of a diagram/chart fence, shown muted when rendering failed —\n// the shared failure fallback of MermaidDiagram and FlintChart.\nexport const DiagramSource = ({ code }: { code: string }) => (\n <pre\n className={cn(\n 'tw:my-3 tw:overflow-auto tw:whitespace-pre-wrap tw:break-all',\n 'tw:py-3 tw:px-4',\n 'tw:bg-muted',\n 'tw:rounded-md tw:text-muted-foreground',\n 'tw:text-sm tw:font-mono',\n )}\n >\n <code>{code}</code>\n </pre>\n);\n"],"mappings":";;;AAIA,MAAa,iBAAiB,EAAE,WAC9B,oBAAC,OAAD;CACE,WAAW,GACT,gEACA,mBACA,eACA,0CACA,yBACF;CAEA,UAAA,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA;AACf,CAAA"}
@@ -1,4 +1,4 @@
1
- import { cn } from "./classNames-BzrkDnOD.js";
1
+ import { cn } from "./classNames-DcGnTh2N.js";
2
2
  import { useState } from "react";
3
3
  import { cva } from "class-variance-authority";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -377,7 +377,7 @@ const DiffView = ({ leftTitle, leftTitleGutter, rightTitle, rightTitleGutter, ol
377
377
  children: /* @__PURE__ */ jsxs("button", {
378
378
  type: "button",
379
379
  onClick: () => handleExpand(row.blockStart),
380
- className: cn("tw:w-full", "tw:text-center", "tw:bg-muted", "tw:text-foreground", "tw:hover:bg-accent", "tw:underline", "tw:p-2"),
380
+ className: cn("tw:w-full", "tw:text-center", "tw:bg-muted", "tw:text-foreground", "tw:hover:bg-hover", "tw:underline", "tw:p-2"),
381
381
  children: [
382
382
  "Expand ",
383
383
  row.lineCount,
@@ -426,4 +426,4 @@ const DiffView = ({ leftTitle, leftTitleGutter, rightTitle, rightTitleGutter, ol
426
426
  //#endregion
427
427
  export { DiffType, DiffView, computeDiffRows, computeLineInformation };
428
428
 
429
- //# sourceMappingURL=DiffView-ppTIzh2h.js.map
429
+ //# sourceMappingURL=DiffView-Dy4z-n-1.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DiffView-ppTIzh2h.js","names":["variants"],"sources":["../src/components/DiffView/DiffViewMark.tsx","../src/components/DiffView/DiffViewTd.tsx","../src/components/DiffView/DiffViewTh.tsx","../src/components/DiffView/util.ts","../src/components/DiffView/DiffView.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '../../utils';\n\n// `text-inherit` overrides the UA `mark` colour so the word highlight takes the\n// cell's text colour. That only works if the fill flips with the scheme too —\n// the light pastels are opaque, so under dark they put near-white text on a\n// light slab. Dark mode tints the same hue at a stronger alpha than the line\n// fill behind it, keeping the word-level mark the more prominent of the two.\nconst variants = cva(['tw:p-0.5', 'tw:text-inherit', 'tw:inline-flex'], {\n variants: {\n diff: {\n added: ['tw:bg-green-200', 'tw:[[data-theme=dark]_&]:bg-green-500/40'],\n removed: ['tw:bg-error-300', 'tw:[[data-theme=dark]_&]:bg-error-500/40'],\n },\n },\n});\n\ntype Props = ComponentProps<'span'> & VariantProps<typeof variants>;\n\nexport const DiffViewMark = ({ diff, children, className, ...props }: Props) => (\n <mark {...props} className={cn(variants({ diff, className }))}>\n {children}\n </mark>\n);\n","import type { ComponentProps } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '../../utils';\n\nconst variants = cva(\n [\n // reset global styles\n 'tw:[&_pre]:p-0',\n 'tw:[&_pre]:m-0',\n 'tw:[&_pre]:border-none',\n 'tw:[&_pre]:rounded-none',\n\n 'tw:align-top',\n // Not `bg-inherit`: the translucent dark-mode tint would paint twice.\n 'tw:[&_pre]:bg-transparent',\n 'tw:[&_pre]:text-inherit',\n 'tw:[&_pre]:px-2',\n 'tw:[&_pre]:!leading-7',\n 'tw:[&_pre]:text-sm',\n 'tw:[&_pre]:whitespace-pre-wrap',\n ],\n {\n defaultVariants: {\n variant: 'default',\n diff: 'default',\n },\n variants: {\n variant: {\n default: [],\n gutter: ['tw:w-14', 'tw:text-right', 'tw:whitespace-nowrap', 'tw:select-none'],\n code: [],\n },\n diff: {\n default: [],\n added: [],\n removed: [],\n },\n },\n // Fixed green/error ramps, not brand-overridable status tokens.\n // Each needs a light/dark pair and its own text colour, or dark mode hides the text.\n compoundVariants: [\n {\n variant: 'gutter',\n diff: 'default',\n className: ['tw:bg-muted', 'tw:text-muted-foreground'],\n },\n {\n variant: 'gutter',\n diff: 'added',\n className: [\n // `green-900` for contrast (6.1:1 on `green-200`).\n 'tw:bg-green-200 tw:text-green-900',\n 'tw:[[data-theme=dark]_&]:bg-green-500/25 tw:[[data-theme=dark]_&]:text-green-300',\n ],\n },\n {\n variant: 'gutter',\n diff: 'removed',\n className: [\n // `error-700` for contrast (5.4:1 on `error-200`).\n 'tw:bg-error-200 tw:text-error-700',\n 'tw:[[data-theme=dark]_&]:bg-error-500/25 tw:[[data-theme=dark]_&]:text-error-300',\n ],\n },\n {\n variant: 'code',\n diff: 'default',\n className: ['tw:bg-background', 'tw:text-foreground'],\n },\n {\n variant: 'code',\n diff: 'added',\n className: [\n 'tw:bg-green-100 tw:text-foreground',\n 'tw:[[data-theme=dark]_&]:bg-green-500/15',\n ],\n },\n {\n variant: 'code',\n diff: 'removed',\n className: [\n 'tw:bg-error-100 tw:text-foreground',\n 'tw:[[data-theme=dark]_&]:bg-error-500/15',\n ],\n },\n ],\n },\n);\n\ntype Props = ComponentProps<'td'> & VariantProps<typeof variants>;\n\nexport const DiffViewTd = ({ diff, variant = 'default', children, className, ...props }: Props) => {\n const needsCodeFormatting = variant === 'code' || variant === 'gutter';\n\n return (\n <td {...props} className={cn(variants({ variant, className, diff }))}>\n {needsCodeFormatting ? <pre>{children}</pre> : children}\n </td>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'th'> & {\n variant?: 'default' | 'gutter';\n};\n\nexport const DiffViewTh = ({ variant = 'default', children, className, ...props }: Props) => (\n <th\n {...props}\n className={cn(\n 'tw:bg-background',\n 'tw:py-3',\n // explicit `border-border`: v4 changed the default border color from gray-200 to\n // `currentColor`, so a bare `border-b` rendered a dark divider (the th's text colour)\n // instead of the light-grey header rule.\n 'tw:border-b',\n 'tw:border-border',\n { 'tw:w-14': variant === 'gutter' },\n { 'tw:last:pr-8': variant === 'default' },\n className,\n )}\n >\n {children}\n </th>\n);\n","import { diffLines, diffWords } from 'diff';\n\nexport const DiffType = {\n DEFAULT: 'default',\n ADDED: 'added',\n REMOVED: 'removed',\n} as const;\n\ntype DiffTypeValue = (typeof DiffType)[keyof typeof DiffType];\n\nexport type DiffInformation = {\n value: string | DiffInformation[];\n lineNumber: number;\n type: DiffTypeValue;\n};\n\nexport type LineInformation = {\n left: DiffInformation;\n right: DiffInformation;\n};\n\ntype ComputedLineInformation = {\n lineInformation: LineInformation[];\n diffLines: number[];\n};\n\ntype SidedDiffInformation = {\n left: DiffInformation[];\n right: DiffInformation[];\n};\n\nexport type WordInformation = {\n value: string;\n type: DiffTypeValue;\n lineNumber: number;\n};\n\nexport type SideInformation = {\n type: DiffTypeValue;\n lineNumber: number;\n words: WordInformation[];\n};\n\nexport type DiffRow =\n | { kind: 'fold'; blockStart: number; lineCount: number; key: string }\n | { kind: 'line'; left: SideInformation; right: SideInformation; key: string };\n\nconst EXTRA_LINES = 3;\n\n// Sentinel blockStart for the region after the last diff; keeps distance checks\n// inert and lets `expandedBlocks` key on a real value.\nconst TAIL_BLOCK = Number.POSITIVE_INFINITY;\n\ntype Counters = {\n left: number;\n right: number;\n global: number;\n};\n\ntype DiffChunk = ReturnType<typeof diffLines>[number];\n\nconst splitLines = (value: string): string[] => {\n if (value === '') return [];\n return value.replace(/\\n$/, '').split('\\n');\n};\n\nconst computeWordDiff = (oldValue: string, newValue: string): SidedDiffInformation => {\n const result: SidedDiffInformation = { left: [], right: [] };\n\n diffWords(oldValue, newValue).forEach(({ added, removed, value }) => {\n if (added) {\n result.right.push({ type: DiffType.ADDED, value, lineNumber: 0 });\n return;\n }\n if (removed) {\n result.left.push({ type: DiffType.REMOVED, value, lineNumber: 0 });\n return;\n }\n const unchanged: DiffInformation = { type: DiffType.DEFAULT, value, lineNumber: 0 };\n result.right.push(unchanged);\n result.left.push(unchanged);\n });\n\n return result;\n};\n\n// Look ahead one chunk in the diff array and return the paired added-line string,\n// or null if there isn't one at the same lineIndex position.\nconst findPairedAddedLine = (\n diffArray: DiffChunk[],\n blockIndex: number,\n lineIndex: number,\n): string | null => {\n const nextBlock = diffArray[blockIndex + 1];\n if (!nextBlock?.added) return null;\n return splitLines(nextBlock.value)[lineIndex] ?? null;\n};\n\nconst buildUnchangedLine = (value: string, counters: Counters): LineInformation => {\n counters.left += 1;\n counters.right += 1;\n return {\n left: { type: DiffType.DEFAULT, value, lineNumber: counters.left },\n right: { type: DiffType.DEFAULT, value, lineNumber: counters.right },\n };\n};\n\nconst buildAddedLine = (value: string, counters: Counters): LineInformation => {\n counters.right += 1;\n return {\n left: {} as DiffInformation,\n right: { type: DiffType.ADDED, value, lineNumber: counters.right },\n };\n};\n\nconst buildRemovedLine = (value: string, counters: Counters): LineInformation => {\n counters.left += 1;\n return {\n left: { type: DiffType.REMOVED, value: value || ' ', lineNumber: counters.left },\n right: {} as DiffInformation,\n };\n};\n\n// Removed + paired added → one modification row with word-level diff.\n// Returns `isActualChange: false` for the quirky case where the two sides\n// resolve to the same string; the caller then omits it from diffLines.\nconst buildModifiedLine = (\n leftValue: string,\n rightValue: string,\n counters: Counters,\n): { line: LineInformation; isActualChange: boolean } => {\n counters.left += 1;\n counters.right += 1;\n const displayLeft = leftValue || ' ';\n\n if (displayLeft === rightValue) {\n return {\n line: {\n left: { type: DiffType.DEFAULT, value: rightValue, lineNumber: counters.left },\n right: { type: DiffType.DEFAULT, value: rightValue, lineNumber: counters.right },\n },\n isActualChange: false,\n };\n }\n\n const { left, right } = computeWordDiff(leftValue, rightValue);\n return {\n line: {\n left: { type: DiffType.REMOVED, value: left, lineNumber: counters.left },\n right: { type: DiffType.ADDED, value: right, lineNumber: counters.right },\n },\n isActualChange: true,\n };\n};\n\nexport const computeLineInformation = (\n oldString: string,\n newString: string,\n ignoreWhitespace?: boolean,\n): ComputedLineInformation => {\n const diffArray = diffLines(oldString.trimEnd(), newString.trimEnd(), { ignoreWhitespace });\n const counters: Counters = { left: 0, right: 0, global: 0 };\n const lineInformation: LineInformation[] = [];\n const diffLineSet = new Set<number>();\n const consumedAddedLines = new Set<string>();\n\n diffArray.forEach((block, blockIndex) => {\n splitLines(block.value).forEach((value, lineIndex) => {\n if (consumedAddedLines.has(`${blockIndex}-${lineIndex}`)) return;\n\n if (block.removed) {\n const paired = findPairedAddedLine(diffArray, blockIndex, lineIndex);\n if (paired !== null) {\n consumedAddedLines.add(`${blockIndex + 1}-${lineIndex}`);\n const { line, isActualChange } = buildModifiedLine(value, paired, counters);\n lineInformation.push(line);\n if (isActualChange) diffLineSet.add(counters.global);\n } else {\n lineInformation.push(buildRemovedLine(value, counters));\n diffLineSet.add(counters.global);\n }\n } else if (block.added) {\n lineInformation.push(buildAddedLine(value, counters));\n diffLineSet.add(counters.global);\n } else {\n lineInformation.push(buildUnchangedLine(value, counters));\n }\n\n counters.global += 1;\n });\n });\n\n return {\n lineInformation,\n diffLines: [...diffLineSet].sort((a, b) => a - b),\n };\n};\n\ntype ContextSegment = { kind: 'context'; lines: LineInformation[]; firstIndex: number };\ntype ChangeSegment = { kind: 'change'; lines: LineInformation[]; firstIndex: number };\ntype Segment = ContextSegment | ChangeSegment;\n\nconst toSegments = (\n lineInformation: LineInformation[],\n diffLineSet: ReadonlySet<number>,\n): Segment[] => {\n const segments: Segment[] = [];\n let current: Segment | null = null;\n\n lineInformation.forEach((line, index) => {\n const isChange = diffLineSet.has(index);\n if (current === null || (current.kind === 'change') !== isChange) {\n current = isChange\n ? { kind: 'change', lines: [line], firstIndex: index }\n : { kind: 'context', lines: [line], firstIndex: index };\n segments.push(current);\n } else {\n current.lines.push(line);\n }\n });\n\n return segments;\n};\n\nconst normalizeSide = (side: DiffInformation): SideInformation => {\n const raw = Array.isArray(side.value)\n ? side.value\n : [{ value: side.value, type: DiffType.DEFAULT, lineNumber: 0 }];\n\n return {\n type: side.type,\n lineNumber: side.lineNumber,\n words: raw.filter((w): w is WordInformation => typeof w.value === 'string'),\n };\n};\n\nconst renderLineRow = (line: LineInformation): DiffRow => ({\n kind: 'line',\n left: normalizeSide(line.left),\n right: normalizeSide(line.right),\n key: `${line.left.lineNumber}-${line.right.lineNumber}`,\n});\n\nconst renderContextSegment = (\n segment: ContextSegment,\n nextChangeIndex: number,\n hasPrevChange: boolean,\n hasNextChange: boolean,\n expanded: ReadonlySet<number>,\n): DiffRow[] => {\n if (expanded.has(nextChangeIndex)) {\n return segment.lines.map(renderLineRow);\n }\n\n const total = segment.lines.length;\n const trail = hasPrevChange ? Math.min(EXTRA_LINES, total) : 0;\n let lead = hasNextChange ? Math.min(EXTRA_LINES, total - trail) : 0;\n let foldCount = total - trail - lead;\n\n // Quirk from the original: a single trailing unchanged line is always rendered\n // (no one-line fold at the tail). Absorb it into the lead slice.\n if (!hasNextChange && foldCount === 1) {\n foldCount = 0;\n lead = 1;\n }\n\n const rows: DiffRow[] = [];\n if (trail > 0) {\n rows.push(...segment.lines.slice(0, trail).map(renderLineRow));\n }\n if (foldCount > 0) {\n rows.push({\n kind: 'fold',\n blockStart: nextChangeIndex,\n lineCount: foldCount,\n key: hasNextChange\n ? `fold-${nextChangeIndex}`\n : `fold-tail-${segment.firstIndex + total - 1}`,\n });\n }\n if (lead > 0) {\n rows.push(...segment.lines.slice(trail + foldCount).map(renderLineRow));\n }\n return rows;\n};\n\nexport const computeDiffRows = (\n lineInformation: LineInformation[],\n diffLines: number[],\n expandedBlocks: number[],\n): DiffRow[] => {\n const diffLineSet = new Set(diffLines);\n const expanded = new Set(expandedBlocks);\n const segments = toSegments(lineInformation, diffLineSet);\n\n const rows: DiffRow[] = [];\n let hasPrevChange = false;\n\n segments.forEach((segment, i) => {\n if (segment.kind === 'change') {\n rows.push(...segment.lines.map(renderLineRow));\n hasPrevChange = true;\n return;\n }\n const nextChange = segments.slice(i + 1).find((s) => s.kind === 'change');\n const nextStart = nextChange?.firstIndex ?? TAIL_BLOCK;\n rows.push(...renderContextSegment(segment, nextStart, hasPrevChange, !!nextChange, expanded));\n });\n\n return rows;\n};\n","import { useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { DiffViewMark } from './DiffViewMark';\nimport { DiffViewTd } from './DiffViewTd';\nimport { DiffViewTh } from './DiffViewTh';\nimport { computeDiffRows, computeLineInformation } from './util';\n\ntype Props = {\n oldValue: string;\n newValue: string;\n ignoreWhitespace?: boolean;\n className?: string;\n\n leftTitleGutter?: ReactNode;\n leftTitle: ReactNode;\n rightTitle: ReactNode;\n rightTitleGutter?: ReactNode;\n};\n\nexport const DiffView = ({\n leftTitle,\n leftTitleGutter,\n rightTitle,\n rightTitleGutter,\n oldValue,\n newValue,\n ignoreWhitespace,\n className,\n}: Props) => {\n const [expandedBlocks, setExpandedBlocks] = useState<number[]>([]);\n const { lineInformation, diffLines } = computeLineInformation(\n oldValue,\n newValue,\n ignoreWhitespace,\n );\n const rows = computeDiffRows(lineInformation, diffLines, expandedBlocks);\n\n const handleExpand = (blockNumber: number) => {\n setExpandedBlocks((curr) => [...curr, blockNumber]);\n };\n\n return (\n <div\n className={cn(\n 'tailwindcss-preflight',\n 'tw:bg-muted',\n // Pin the text colour rather than inheriting it: the diff is routinely\n // portalled into a Modal, where an inherited colour comes from whatever\n // sits above the portal root instead of this surface.\n 'tw:text-foreground',\n // explicit `border-border` — v4's default border colour is `currentColor`, so a bare\n // `border` drew a dark frame instead of the light-grey outline.\n 'tw:border',\n 'tw:border-border',\n 'tw:rounded-2xl',\n 'tw:overflow-auto',\n className,\n )}\n >\n <table className=\"tw:w-full tw:table-fixed tw:bg-background\">\n {/* Not v4's `shadow-xs`: `tailwind-config`'s `boxShadow.sm` fallback still carries\n the v3 value, and only `shadow-sm` reads `--shadow-sm` from a brand's\n `theme.shadows` — `shadow-xs` has no token and would opt this header out. */}\n <thead className=\"tw:sticky tw:top-0 tw:z-10 tw:shadow-sm\">\n <tr>\n <DiffViewTh variant=\"gutter\">{leftTitleGutter}</DiffViewTh>\n <DiffViewTh>{leftTitle}</DiffViewTh>\n <DiffViewTh variant=\"gutter\">{rightTitleGutter}</DiffViewTh>\n <DiffViewTh>{rightTitle}</DiffViewTh>\n </tr>\n </thead>\n\n <tbody>\n {rows.map((row) => {\n if (row.kind === 'fold')\n return (\n <tr key={row.key}>\n <DiffViewTd colSpan={4}>\n <button\n type=\"button\"\n onClick={() => handleExpand(row.blockStart)}\n className={cn(\n 'tw:w-full',\n 'tw:text-center',\n 'tw:bg-muted',\n 'tw:text-foreground',\n 'tw:hover:bg-accent',\n 'tw:underline',\n 'tw:p-2',\n )}\n >\n Expand {row.lineCount} lines ...\n </button>\n </DiffViewTd>\n </tr>\n );\n\n return (\n <tr key={row.key}>\n <DiffViewTd variant=\"gutter\" diff={row.left.type}>\n {row.left.lineNumber}\n </DiffViewTd>\n\n <DiffViewTd variant=\"code\" diff={row.left.type}>\n {row.left.words.map((val, index) => {\n if (val.type === 'default') return val.value;\n return (\n // oxlint-disable-next-line react/no-array-index-key\n <DiffViewMark key={`${val.value}-${val.type}-${index}`} diff={val.type}>\n {val.value}\n </DiffViewMark>\n );\n })}\n </DiffViewTd>\n\n <DiffViewTd variant=\"gutter\" diff={row.right.type}>\n {row.right.lineNumber}\n </DiffViewTd>\n\n <DiffViewTd variant=\"code\" diff={row.right.type}>\n {row.right.words.map((val, index) => {\n if (val.type === 'default') return val.value;\n\n return (\n // oxlint-disable-next-line react/no-array-index-key\n <DiffViewMark key={`${val.value}-${val.type}-${index}`} diff={val.type}>\n {val.value}\n </DiffViewMark>\n );\n })}\n </DiffViewTd>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n};\n"],"mappings":";;;;;;AAUA,MAAMA,aAAW,IAAI;CAAC;CAAY;CAAmB;AAAgB,GAAG,EACtE,UAAU,EACR,MAAM;CACJ,OAAO,CAAC,mBAAmB,0CAA0C;CACrE,SAAS,CAAC,mBAAmB,0CAA0C;AACzE,EACF,EACF,CAAC;AAID,MAAa,gBAAgB,EAAE,MAAM,UAAU,WAAW,GAAG,YAC3D,oBAAC,QAAD;CAAM,GAAI;CAAO,WAAW,GAAGA,WAAS;EAAE;EAAM;CAAU,CAAC,CAAC;CACzD;AACG,CAAA;;;ACnBR,MAAM,WAAW,IACf;CAEE;CACA;CACA;CACA;CAEA;CAEA;CACA;CACA;CACA;CACA;CACA;AACF,GACA;CACE,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;CACA,UAAU;EACR,SAAS;GACP,SAAS,CAAC;GACV,QAAQ;IAAC;IAAW;IAAiB;IAAwB;GAAgB;GAC7E,MAAM,CAAC;EACT;EACA,MAAM;GACJ,SAAS,CAAC;GACV,OAAO,CAAC;GACR,SAAS,CAAC;EACZ;CACF;CAGA,kBAAkB;EAChB;GACE,SAAS;GACT,MAAM;GACN,WAAW,CAAC,eAAe,0BAA0B;EACvD;EACA;GACE,SAAS;GACT,MAAM;GACN,WAAW,CAET,qCACA,kFACF;EACF;EACA;GACE,SAAS;GACT,MAAM;GACN,WAAW,CAET,qCACA,kFACF;EACF;EACA;GACE,SAAS;GACT,MAAM;GACN,WAAW,CAAC,oBAAoB,oBAAoB;EACtD;EACA;GACE,SAAS;GACT,MAAM;GACN,WAAW,CACT,sCACA,0CACF;EACF;EACA;GACE,SAAS;GACT,MAAM;GACN,WAAW,CACT,sCACA,0CACF;EACF;CACF;AACF,CACF;AAIA,MAAa,cAAc,EAAE,MAAM,UAAU,WAAW,UAAU,WAAW,GAAG,YAAmB;CACjG,MAAM,sBAAsB,YAAY,UAAU,YAAY;CAE9D,OACE,oBAAC,MAAD;EAAI,GAAI;EAAO,WAAW,GAAG,SAAS;GAAE;GAAS;GAAW;EAAK,CAAC,CAAC;EAChE,UAAA,sBAAsB,oBAAC,OAAD,EAAM,SAAc,CAAA,IAAI;CAC7C,CAAA;AAER;;;AC5FA,MAAa,cAAc,EAAE,UAAU,WAAW,UAAU,WAAW,GAAG,YACxE,oBAAC,MAAD;CACE,GAAI;CACJ,WAAW,GACT,oBACA,WAIA,eACA,oBACA,EAAE,WAAW,YAAY,SAAS,GAClC,EAAE,gBAAgB,YAAY,UAAU,GACxC,SACF;CAEC;AACC,CAAA;;;ACvBN,MAAa,WAAW;CACtB,SAAS;CACT,OAAO;CACP,SAAS;AACX;AAyCA,MAAM,cAAc;AAIpB,MAAM,aAAa,OAAO;AAU1B,MAAM,cAAc,UAA4B;CAC9C,IAAI,UAAU,IAAI,OAAO,CAAC;CAC1B,OAAO,MAAM,QAAQ,OAAO,EAAE,CAAC,CAAC,MAAM,IAAI;AAC5C;AAEA,MAAM,mBAAmB,UAAkB,aAA2C;CACpF,MAAM,SAA+B;EAAE,MAAM,CAAC;EAAG,OAAO,CAAC;CAAE;CAE3D,UAAU,UAAU,QAAQ,CAAC,CAAC,SAAS,EAAE,OAAO,SAAS,YAAY;EACnE,IAAI,OAAO;GACT,OAAO,MAAM,KAAK;IAAE,MAAM,SAAS;IAAO;IAAO,YAAY;GAAE,CAAC;GAChE;EACF;EACA,IAAI,SAAS;GACX,OAAO,KAAK,KAAK;IAAE,MAAM,SAAS;IAAS;IAAO,YAAY;GAAE,CAAC;GACjE;EACF;EACA,MAAM,YAA6B;GAAE,MAAM,SAAS;GAAS;GAAO,YAAY;EAAE;EAClF,OAAO,MAAM,KAAK,SAAS;EAC3B,OAAO,KAAK,KAAK,SAAS;CAC5B,CAAC;CAED,OAAO;AACT;AAIA,MAAM,uBACJ,WACA,YACA,cACkB;CAClB,MAAM,YAAY,UAAU,aAAa;CACzC,IAAI,CAAC,WAAW,OAAO,OAAO;CAC9B,OAAO,WAAW,UAAU,KAAK,CAAC,CAAC,cAAc;AACnD;AAEA,MAAM,sBAAsB,OAAe,aAAwC;CACjF,SAAS,QAAQ;CACjB,SAAS,SAAS;CAClB,OAAO;EACL,MAAM;GAAE,MAAM,SAAS;GAAS;GAAO,YAAY,SAAS;EAAK;EACjE,OAAO;GAAE,MAAM,SAAS;GAAS;GAAO,YAAY,SAAS;EAAM;CACrE;AACF;AAEA,MAAM,kBAAkB,OAAe,aAAwC;CAC7E,SAAS,SAAS;CAClB,OAAO;EACL,MAAM,CAAC;EACP,OAAO;GAAE,MAAM,SAAS;GAAO;GAAO,YAAY,SAAS;EAAM;CACnE;AACF;AAEA,MAAM,oBAAoB,OAAe,aAAwC;CAC/E,SAAS,QAAQ;CACjB,OAAO;EACL,MAAM;GAAE,MAAM,SAAS;GAAS,OAAO,SAAS;GAAK,YAAY,SAAS;EAAK;EAC/E,OAAO,CAAC;CACV;AACF;AAKA,MAAM,qBACJ,WACA,YACA,aACuD;CACvD,SAAS,QAAQ;CACjB,SAAS,SAAS;CAGlB,KAFoB,aAAa,SAEb,YAClB,OAAO;EACL,MAAM;GACJ,MAAM;IAAE,MAAM,SAAS;IAAS,OAAO;IAAY,YAAY,SAAS;GAAK;GAC7E,OAAO;IAAE,MAAM,SAAS;IAAS,OAAO;IAAY,YAAY,SAAS;GAAM;EACjF;EACA,gBAAgB;CAClB;CAGF,MAAM,EAAE,MAAM,UAAU,gBAAgB,WAAW,UAAU;CAC7D,OAAO;EACL,MAAM;GACJ,MAAM;IAAE,MAAM,SAAS;IAAS,OAAO;IAAM,YAAY,SAAS;GAAK;GACvE,OAAO;IAAE,MAAM,SAAS;IAAO,OAAO;IAAO,YAAY,SAAS;GAAM;EAC1E;EACA,gBAAgB;CAClB;AACF;AAEA,MAAa,0BACX,WACA,WACA,qBAC4B;CAC5B,MAAM,YAAY,UAAU,UAAU,QAAQ,GAAG,UAAU,QAAQ,GAAG,EAAE,iBAAiB,CAAC;CAC1F,MAAM,WAAqB;EAAE,MAAM;EAAG,OAAO;EAAG,QAAQ;CAAE;CAC1D,MAAM,kBAAqC,CAAC;CAC5C,MAAM,8BAAc,IAAI,IAAY;CACpC,MAAM,qCAAqB,IAAI,IAAY;CAE3C,UAAU,SAAS,OAAO,eAAe;EACvC,WAAW,MAAM,KAAK,CAAC,CAAC,SAAS,OAAO,cAAc;GACpD,IAAI,mBAAmB,IAAI,GAAG,WAAW,GAAG,WAAW,GAAG;GAE1D,IAAI,MAAM,SAAS;IACjB,MAAM,SAAS,oBAAoB,WAAW,YAAY,SAAS;IACnE,IAAI,WAAW,MAAM;KACnB,mBAAmB,IAAI,GAAG,aAAa,EAAE,GAAG,WAAW;KACvD,MAAM,EAAE,MAAM,mBAAmB,kBAAkB,OAAO,QAAQ,QAAQ;KAC1E,gBAAgB,KAAK,IAAI;KACzB,IAAI,gBAAgB,YAAY,IAAI,SAAS,MAAM;IACrD,OAAO;KACL,gBAAgB,KAAK,iBAAiB,OAAO,QAAQ,CAAC;KACtD,YAAY,IAAI,SAAS,MAAM;IACjC;GACF,OAAO,IAAI,MAAM,OAAO;IACtB,gBAAgB,KAAK,eAAe,OAAO,QAAQ,CAAC;IACpD,YAAY,IAAI,SAAS,MAAM;GACjC,OACE,gBAAgB,KAAK,mBAAmB,OAAO,QAAQ,CAAC;GAG1D,SAAS,UAAU;EACrB,CAAC;CACH,CAAC;CAED,OAAO;EACL;EACA,WAAW,CAAC,GAAG,WAAW,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;CAClD;AACF;AAMA,MAAM,cACJ,iBACA,gBACc;CACd,MAAM,WAAsB,CAAC;CAC7B,IAAI,UAA0B;CAE9B,gBAAgB,SAAS,MAAM,UAAU;EACvC,MAAM,WAAW,YAAY,IAAI,KAAK;EACtC,IAAI,YAAY,QAAS,QAAQ,SAAS,aAAc,UAAU;GAChE,UAAU,WACN;IAAE,MAAM;IAAU,OAAO,CAAC,IAAI;IAAG,YAAY;GAAM,IACnD;IAAE,MAAM;IAAW,OAAO,CAAC,IAAI;IAAG,YAAY;GAAM;GACxD,SAAS,KAAK,OAAO;EACvB,OACE,QAAQ,MAAM,KAAK,IAAI;CAE3B,CAAC;CAED,OAAO;AACT;AAEA,MAAM,iBAAiB,SAA2C;CAChE,MAAM,MAAM,MAAM,QAAQ,KAAK,KAAK,IAChC,KAAK,QACL,CAAC;EAAE,OAAO,KAAK;EAAO,MAAM,SAAS;EAAS,YAAY;CAAE,CAAC;CAEjE,OAAO;EACL,MAAM,KAAK;EACX,YAAY,KAAK;EACjB,OAAO,IAAI,QAAQ,MAA4B,OAAO,EAAE,UAAU,QAAQ;CAC5E;AACF;AAEA,MAAM,iBAAiB,UAAoC;CACzD,MAAM;CACN,MAAM,cAAc,KAAK,IAAI;CAC7B,OAAO,cAAc,KAAK,KAAK;CAC/B,KAAK,GAAG,KAAK,KAAK,WAAW,GAAG,KAAK,MAAM;AAC7C;AAEA,MAAM,wBACJ,SACA,iBACA,eACA,eACA,aACc;CACd,IAAI,SAAS,IAAI,eAAe,GAC9B,OAAO,QAAQ,MAAM,IAAI,aAAa;CAGxC,MAAM,QAAQ,QAAQ,MAAM;CAC5B,MAAM,QAAQ,gBAAgB,KAAK,IAAI,aAAa,KAAK,IAAI;CAC7D,IAAI,OAAO,gBAAgB,KAAK,IAAI,aAAa,QAAQ,KAAK,IAAI;CAClE,IAAI,YAAY,QAAQ,QAAQ;CAIhC,IAAI,CAAC,iBAAiB,cAAc,GAAG;EACrC,YAAY;EACZ,OAAO;CACT;CAEA,MAAM,OAAkB,CAAC;CACzB,IAAI,QAAQ,GACV,KAAK,KAAK,GAAG,QAAQ,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC;CAE/D,IAAI,YAAY,GACd,KAAK,KAAK;EACR,MAAM;EACN,YAAY;EACZ,WAAW;EACX,KAAK,gBACD,QAAQ,oBACR,aAAa,QAAQ,aAAa,QAAQ;CAChD,CAAC;CAEH,IAAI,OAAO,GACT,KAAK,KAAK,GAAG,QAAQ,MAAM,MAAM,QAAQ,SAAS,CAAC,CAAC,IAAI,aAAa,CAAC;CAExE,OAAO;AACT;AAEA,MAAa,mBACX,iBACA,WACA,mBACc;CACd,MAAM,cAAc,IAAI,IAAI,SAAS;CACrC,MAAM,WAAW,IAAI,IAAI,cAAc;CACvC,MAAM,WAAW,WAAW,iBAAiB,WAAW;CAExD,MAAM,OAAkB,CAAC;CACzB,IAAI,gBAAgB;CAEpB,SAAS,SAAS,SAAS,MAAM;EAC/B,IAAI,QAAQ,SAAS,UAAU;GAC7B,KAAK,KAAK,GAAG,QAAQ,MAAM,IAAI,aAAa,CAAC;GAC7C,gBAAgB;GAChB;EACF;EACA,MAAM,aAAa,SAAS,MAAM,IAAI,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,SAAS,QAAQ;EACxE,MAAM,YAAY,YAAY,cAAc;EAC5C,KAAK,KAAK,GAAG,qBAAqB,SAAS,WAAW,eAAe,CAAC,CAAC,YAAY,QAAQ,CAAC;CAC9F,CAAC;CAED,OAAO;AACT;;;AChSA,MAAa,YAAY,EACvB,WACA,iBACA,YACA,kBACA,UACA,UACA,kBACA,gBACW;CACX,MAAM,CAAC,gBAAgB,qBAAqB,SAAmB,CAAC,CAAC;CACjE,MAAM,EAAE,iBAAiB,cAAc,uBACrC,UACA,UACA,gBACF;CACA,MAAM,OAAO,gBAAgB,iBAAiB,WAAW,cAAc;CAEvE,MAAM,gBAAgB,gBAAwB;EAC5C,mBAAmB,SAAS,CAAC,GAAG,MAAM,WAAW,CAAC;CACpD;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,GACT,yBACA,eAIA,sBAGA,aACA,oBACA,kBACA,oBACA,SACF;EAEA,UAAA,qBAAC,SAAD;GAAO,WAAU;GAAjB,UAAA,CAIE,oBAAC,SAAD;IAAO,WAAU;IACf,UAAA,qBAAC,MAAD,EAAA,UAAA;KACE,oBAAC,YAAD;MAAY,SAAQ;MAAU,UAAA;KAA4B,CAAA;KAC1D,oBAAC,YAAD,EAAA,UAAa,UAAsB,CAAA;KACnC,oBAAC,YAAD;MAAY,SAAQ;MAAU,UAAA;KAA6B,CAAA;KAC3D,oBAAC,YAAD,EAAA,UAAa,WAAuB,CAAA;IAClC,EAAA,CAAA;GACC,CAAA,GAEP,oBAAC,SAAD,EAAA,UACG,KAAK,KAAK,QAAQ;IACjB,IAAI,IAAI,SAAS,QACf,OACE,oBAAC,MAAD,EAAA,UACE,oBAAC,YAAD;KAAY,SAAS;KACnB,UAAA,qBAAC,UAAD;MACE,MAAK;MACL,eAAe,aAAa,IAAI,UAAU;MAC1C,WAAW,GACT,aACA,kBACA,eACA,sBACA,sBACA,gBACA,QACF;MAXF,UAAA;OAYC;OACS,IAAI;OAAU;MAChB;;IACE,CAAA,EACV,GAlBK,IAAI,GAkBT;IAGR,OACE,qBAAC,MAAD,EAAA,UAAA;KACE,oBAAC,YAAD;MAAY,SAAQ;MAAS,MAAM,IAAI,KAAK;MACzC,UAAA,IAAI,KAAK;KACA,CAAA;KAEZ,oBAAC,YAAD;MAAY,SAAQ;MAAO,MAAM,IAAI,KAAK;MACvC,UAAA,IAAI,KAAK,MAAM,KAAK,KAAK,UAAU;OAClC,IAAI,IAAI,SAAS,WAAW,OAAO,IAAI;OACvC,OAEE,oBAAC,cAAD;QAAwD,MAAM,IAAI;QAC/D,UAAA,IAAI;OACO,GAFK,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK,GAAG,OAEjC;MAElB,CAAC;KACS,CAAA;KAEZ,oBAAC,YAAD;MAAY,SAAQ;MAAS,MAAM,IAAI,MAAM;MAC1C,UAAA,IAAI,MAAM;KACD,CAAA;KAEZ,oBAAC,YAAD;MAAY,SAAQ;MAAO,MAAM,IAAI,MAAM;MACxC,UAAA,IAAI,MAAM,MAAM,KAAK,KAAK,UAAU;OACnC,IAAI,IAAI,SAAS,WAAW,OAAO,IAAI;OAEvC,OAEE,oBAAC,cAAD;QAAwD,MAAM,IAAI;QAC/D,UAAA,IAAI;OACO,GAFK,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK,GAAG,OAEjC;MAElB,CAAC;KACS,CAAA;IACV,EAAA,GAjCK,IAAI,GAiCT;GAER,CAAC,EACI,CAAA,CACF;;CACJ,CAAA;AAET"}
1
+ {"version":3,"file":"DiffView-Dy4z-n-1.js","names":["variants"],"sources":["../src/components/DiffView/DiffViewMark.tsx","../src/components/DiffView/DiffViewTd.tsx","../src/components/DiffView/DiffViewTh.tsx","../src/components/DiffView/util.ts","../src/components/DiffView/DiffView.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '../../utils';\n\n// `text-inherit` overrides the UA `mark` colour so the word highlight takes the\n// cell's text colour. That only works if the fill flips with the scheme too —\n// the light pastels are opaque, so under dark they put near-white text on a\n// light slab. Dark mode tints the same hue at a stronger alpha than the line\n// fill behind it, keeping the word-level mark the more prominent of the two.\nconst variants = cva(['tw:p-0.5', 'tw:text-inherit', 'tw:inline-flex'], {\n variants: {\n diff: {\n added: ['tw:bg-green-200', 'tw:[[data-theme=dark]_&]:bg-green-500/40'],\n removed: ['tw:bg-error-300', 'tw:[[data-theme=dark]_&]:bg-error-500/40'],\n },\n },\n});\n\ntype Props = ComponentProps<'span'> & VariantProps<typeof variants>;\n\nexport const DiffViewMark = ({ diff, children, className, ...props }: Props) => (\n <mark {...props} className={cn(variants({ diff, className }))}>\n {children}\n </mark>\n);\n","import type { ComponentProps } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '../../utils';\n\nconst variants = cva(\n [\n // reset global styles\n 'tw:[&_pre]:p-0',\n 'tw:[&_pre]:m-0',\n 'tw:[&_pre]:border-none',\n 'tw:[&_pre]:rounded-none',\n\n 'tw:align-top',\n // Not `bg-inherit`: the translucent dark-mode tint would paint twice.\n 'tw:[&_pre]:bg-transparent',\n 'tw:[&_pre]:text-inherit',\n 'tw:[&_pre]:px-2',\n 'tw:[&_pre]:!leading-7',\n 'tw:[&_pre]:text-sm',\n 'tw:[&_pre]:whitespace-pre-wrap',\n ],\n {\n defaultVariants: {\n variant: 'default',\n diff: 'default',\n },\n variants: {\n variant: {\n default: [],\n gutter: ['tw:w-14', 'tw:text-right', 'tw:whitespace-nowrap', 'tw:select-none'],\n code: [],\n },\n diff: {\n default: [],\n added: [],\n removed: [],\n },\n },\n // Fixed green/error ramps, not brand-overridable status tokens.\n // Each needs a light/dark pair and its own text colour, or dark mode hides the text.\n compoundVariants: [\n {\n variant: 'gutter',\n diff: 'default',\n className: ['tw:bg-muted', 'tw:text-muted-foreground'],\n },\n {\n variant: 'gutter',\n diff: 'added',\n className: [\n // `green-900` for contrast (6.1:1 on `green-200`).\n 'tw:bg-green-200 tw:text-green-900',\n 'tw:[[data-theme=dark]_&]:bg-green-500/25 tw:[[data-theme=dark]_&]:text-green-300',\n ],\n },\n {\n variant: 'gutter',\n diff: 'removed',\n className: [\n // `error-700` for contrast (5.4:1 on `error-200`).\n 'tw:bg-error-200 tw:text-error-700',\n 'tw:[[data-theme=dark]_&]:bg-error-500/25 tw:[[data-theme=dark]_&]:text-error-300',\n ],\n },\n {\n variant: 'code',\n diff: 'default',\n className: ['tw:bg-background', 'tw:text-foreground'],\n },\n {\n variant: 'code',\n diff: 'added',\n className: [\n 'tw:bg-green-100 tw:text-foreground',\n 'tw:[[data-theme=dark]_&]:bg-green-500/15',\n ],\n },\n {\n variant: 'code',\n diff: 'removed',\n className: [\n 'tw:bg-error-100 tw:text-foreground',\n 'tw:[[data-theme=dark]_&]:bg-error-500/15',\n ],\n },\n ],\n },\n);\n\ntype Props = ComponentProps<'td'> & VariantProps<typeof variants>;\n\nexport const DiffViewTd = ({ diff, variant = 'default', children, className, ...props }: Props) => {\n const needsCodeFormatting = variant === 'code' || variant === 'gutter';\n\n return (\n <td {...props} className={cn(variants({ variant, className, diff }))}>\n {needsCodeFormatting ? <pre>{children}</pre> : children}\n </td>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'th'> & {\n variant?: 'default' | 'gutter';\n};\n\nexport const DiffViewTh = ({ variant = 'default', children, className, ...props }: Props) => (\n <th\n {...props}\n className={cn(\n 'tw:bg-background',\n 'tw:py-3',\n // explicit `border-border`: v4 changed the default border color from gray-200 to\n // `currentColor`, so a bare `border-b` rendered a dark divider (the th's text colour)\n // instead of the light-grey header rule.\n 'tw:border-b',\n 'tw:border-border',\n { 'tw:w-14': variant === 'gutter' },\n { 'tw:last:pr-8': variant === 'default' },\n className,\n )}\n >\n {children}\n </th>\n);\n","import { diffLines, diffWords } from 'diff';\n\nexport const DiffType = {\n DEFAULT: 'default',\n ADDED: 'added',\n REMOVED: 'removed',\n} as const;\n\ntype DiffTypeValue = (typeof DiffType)[keyof typeof DiffType];\n\nexport type DiffInformation = {\n value: string | DiffInformation[];\n lineNumber: number;\n type: DiffTypeValue;\n};\n\nexport type LineInformation = {\n left: DiffInformation;\n right: DiffInformation;\n};\n\ntype ComputedLineInformation = {\n lineInformation: LineInformation[];\n diffLines: number[];\n};\n\ntype SidedDiffInformation = {\n left: DiffInformation[];\n right: DiffInformation[];\n};\n\nexport type WordInformation = {\n value: string;\n type: DiffTypeValue;\n lineNumber: number;\n};\n\nexport type SideInformation = {\n type: DiffTypeValue;\n lineNumber: number;\n words: WordInformation[];\n};\n\nexport type DiffRow =\n | { kind: 'fold'; blockStart: number; lineCount: number; key: string }\n | { kind: 'line'; left: SideInformation; right: SideInformation; key: string };\n\nconst EXTRA_LINES = 3;\n\n// Sentinel blockStart for the region after the last diff; keeps distance checks\n// inert and lets `expandedBlocks` key on a real value.\nconst TAIL_BLOCK = Number.POSITIVE_INFINITY;\n\ntype Counters = {\n left: number;\n right: number;\n global: number;\n};\n\ntype DiffChunk = ReturnType<typeof diffLines>[number];\n\nconst splitLines = (value: string): string[] => {\n if (value === '') return [];\n return value.replace(/\\n$/, '').split('\\n');\n};\n\nconst computeWordDiff = (oldValue: string, newValue: string): SidedDiffInformation => {\n const result: SidedDiffInformation = { left: [], right: [] };\n\n diffWords(oldValue, newValue).forEach(({ added, removed, value }) => {\n if (added) {\n result.right.push({ type: DiffType.ADDED, value, lineNumber: 0 });\n return;\n }\n if (removed) {\n result.left.push({ type: DiffType.REMOVED, value, lineNumber: 0 });\n return;\n }\n const unchanged: DiffInformation = { type: DiffType.DEFAULT, value, lineNumber: 0 };\n result.right.push(unchanged);\n result.left.push(unchanged);\n });\n\n return result;\n};\n\n// Look ahead one chunk in the diff array and return the paired added-line string,\n// or null if there isn't one at the same lineIndex position.\nconst findPairedAddedLine = (\n diffArray: DiffChunk[],\n blockIndex: number,\n lineIndex: number,\n): string | null => {\n const nextBlock = diffArray[blockIndex + 1];\n if (!nextBlock?.added) return null;\n return splitLines(nextBlock.value)[lineIndex] ?? null;\n};\n\nconst buildUnchangedLine = (value: string, counters: Counters): LineInformation => {\n counters.left += 1;\n counters.right += 1;\n return {\n left: { type: DiffType.DEFAULT, value, lineNumber: counters.left },\n right: { type: DiffType.DEFAULT, value, lineNumber: counters.right },\n };\n};\n\nconst buildAddedLine = (value: string, counters: Counters): LineInformation => {\n counters.right += 1;\n return {\n left: {} as DiffInformation,\n right: { type: DiffType.ADDED, value, lineNumber: counters.right },\n };\n};\n\nconst buildRemovedLine = (value: string, counters: Counters): LineInformation => {\n counters.left += 1;\n return {\n left: { type: DiffType.REMOVED, value: value || ' ', lineNumber: counters.left },\n right: {} as DiffInformation,\n };\n};\n\n// Removed + paired added → one modification row with word-level diff.\n// Returns `isActualChange: false` for the quirky case where the two sides\n// resolve to the same string; the caller then omits it from diffLines.\nconst buildModifiedLine = (\n leftValue: string,\n rightValue: string,\n counters: Counters,\n): { line: LineInformation; isActualChange: boolean } => {\n counters.left += 1;\n counters.right += 1;\n const displayLeft = leftValue || ' ';\n\n if (displayLeft === rightValue) {\n return {\n line: {\n left: { type: DiffType.DEFAULT, value: rightValue, lineNumber: counters.left },\n right: { type: DiffType.DEFAULT, value: rightValue, lineNumber: counters.right },\n },\n isActualChange: false,\n };\n }\n\n const { left, right } = computeWordDiff(leftValue, rightValue);\n return {\n line: {\n left: { type: DiffType.REMOVED, value: left, lineNumber: counters.left },\n right: { type: DiffType.ADDED, value: right, lineNumber: counters.right },\n },\n isActualChange: true,\n };\n};\n\nexport const computeLineInformation = (\n oldString: string,\n newString: string,\n ignoreWhitespace?: boolean,\n): ComputedLineInformation => {\n const diffArray = diffLines(oldString.trimEnd(), newString.trimEnd(), { ignoreWhitespace });\n const counters: Counters = { left: 0, right: 0, global: 0 };\n const lineInformation: LineInformation[] = [];\n const diffLineSet = new Set<number>();\n const consumedAddedLines = new Set<string>();\n\n diffArray.forEach((block, blockIndex) => {\n splitLines(block.value).forEach((value, lineIndex) => {\n if (consumedAddedLines.has(`${blockIndex}-${lineIndex}`)) return;\n\n if (block.removed) {\n const paired = findPairedAddedLine(diffArray, blockIndex, lineIndex);\n if (paired !== null) {\n consumedAddedLines.add(`${blockIndex + 1}-${lineIndex}`);\n const { line, isActualChange } = buildModifiedLine(value, paired, counters);\n lineInformation.push(line);\n if (isActualChange) diffLineSet.add(counters.global);\n } else {\n lineInformation.push(buildRemovedLine(value, counters));\n diffLineSet.add(counters.global);\n }\n } else if (block.added) {\n lineInformation.push(buildAddedLine(value, counters));\n diffLineSet.add(counters.global);\n } else {\n lineInformation.push(buildUnchangedLine(value, counters));\n }\n\n counters.global += 1;\n });\n });\n\n return {\n lineInformation,\n diffLines: [...diffLineSet].sort((a, b) => a - b),\n };\n};\n\ntype ContextSegment = { kind: 'context'; lines: LineInformation[]; firstIndex: number };\ntype ChangeSegment = { kind: 'change'; lines: LineInformation[]; firstIndex: number };\ntype Segment = ContextSegment | ChangeSegment;\n\nconst toSegments = (\n lineInformation: LineInformation[],\n diffLineSet: ReadonlySet<number>,\n): Segment[] => {\n const segments: Segment[] = [];\n let current: Segment | null = null;\n\n lineInformation.forEach((line, index) => {\n const isChange = diffLineSet.has(index);\n if (current === null || (current.kind === 'change') !== isChange) {\n current = isChange\n ? { kind: 'change', lines: [line], firstIndex: index }\n : { kind: 'context', lines: [line], firstIndex: index };\n segments.push(current);\n } else {\n current.lines.push(line);\n }\n });\n\n return segments;\n};\n\nconst normalizeSide = (side: DiffInformation): SideInformation => {\n const raw = Array.isArray(side.value)\n ? side.value\n : [{ value: side.value, type: DiffType.DEFAULT, lineNumber: 0 }];\n\n return {\n type: side.type,\n lineNumber: side.lineNumber,\n words: raw.filter((w): w is WordInformation => typeof w.value === 'string'),\n };\n};\n\nconst renderLineRow = (line: LineInformation): DiffRow => ({\n kind: 'line',\n left: normalizeSide(line.left),\n right: normalizeSide(line.right),\n key: `${line.left.lineNumber}-${line.right.lineNumber}`,\n});\n\nconst renderContextSegment = (\n segment: ContextSegment,\n nextChangeIndex: number,\n hasPrevChange: boolean,\n hasNextChange: boolean,\n expanded: ReadonlySet<number>,\n): DiffRow[] => {\n if (expanded.has(nextChangeIndex)) {\n return segment.lines.map(renderLineRow);\n }\n\n const total = segment.lines.length;\n const trail = hasPrevChange ? Math.min(EXTRA_LINES, total) : 0;\n let lead = hasNextChange ? Math.min(EXTRA_LINES, total - trail) : 0;\n let foldCount = total - trail - lead;\n\n // Quirk from the original: a single trailing unchanged line is always rendered\n // (no one-line fold at the tail). Absorb it into the lead slice.\n if (!hasNextChange && foldCount === 1) {\n foldCount = 0;\n lead = 1;\n }\n\n const rows: DiffRow[] = [];\n if (trail > 0) {\n rows.push(...segment.lines.slice(0, trail).map(renderLineRow));\n }\n if (foldCount > 0) {\n rows.push({\n kind: 'fold',\n blockStart: nextChangeIndex,\n lineCount: foldCount,\n key: hasNextChange\n ? `fold-${nextChangeIndex}`\n : `fold-tail-${segment.firstIndex + total - 1}`,\n });\n }\n if (lead > 0) {\n rows.push(...segment.lines.slice(trail + foldCount).map(renderLineRow));\n }\n return rows;\n};\n\nexport const computeDiffRows = (\n lineInformation: LineInformation[],\n diffLines: number[],\n expandedBlocks: number[],\n): DiffRow[] => {\n const diffLineSet = new Set(diffLines);\n const expanded = new Set(expandedBlocks);\n const segments = toSegments(lineInformation, diffLineSet);\n\n const rows: DiffRow[] = [];\n let hasPrevChange = false;\n\n segments.forEach((segment, i) => {\n if (segment.kind === 'change') {\n rows.push(...segment.lines.map(renderLineRow));\n hasPrevChange = true;\n return;\n }\n const nextChange = segments.slice(i + 1).find((s) => s.kind === 'change');\n const nextStart = nextChange?.firstIndex ?? TAIL_BLOCK;\n rows.push(...renderContextSegment(segment, nextStart, hasPrevChange, !!nextChange, expanded));\n });\n\n return rows;\n};\n","import { useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { DiffViewMark } from './DiffViewMark';\nimport { DiffViewTd } from './DiffViewTd';\nimport { DiffViewTh } from './DiffViewTh';\nimport { computeDiffRows, computeLineInformation } from './util';\n\ntype Props = {\n oldValue: string;\n newValue: string;\n ignoreWhitespace?: boolean;\n className?: string;\n\n leftTitleGutter?: ReactNode;\n leftTitle: ReactNode;\n rightTitle: ReactNode;\n rightTitleGutter?: ReactNode;\n};\n\nexport const DiffView = ({\n leftTitle,\n leftTitleGutter,\n rightTitle,\n rightTitleGutter,\n oldValue,\n newValue,\n ignoreWhitespace,\n className,\n}: Props) => {\n const [expandedBlocks, setExpandedBlocks] = useState<number[]>([]);\n const { lineInformation, diffLines } = computeLineInformation(\n oldValue,\n newValue,\n ignoreWhitespace,\n );\n const rows = computeDiffRows(lineInformation, diffLines, expandedBlocks);\n\n const handleExpand = (blockNumber: number) => {\n setExpandedBlocks((curr) => [...curr, blockNumber]);\n };\n\n return (\n <div\n className={cn(\n 'tailwindcss-preflight',\n 'tw:bg-muted',\n // Pin the text colour rather than inheriting it: the diff is routinely\n // portalled into a Modal, where an inherited colour comes from whatever\n // sits above the portal root instead of this surface.\n 'tw:text-foreground',\n // explicit `border-border` — v4's default border colour is `currentColor`, so a bare\n // `border` drew a dark frame instead of the light-grey outline.\n 'tw:border',\n 'tw:border-border',\n 'tw:rounded-2xl',\n 'tw:overflow-auto',\n className,\n )}\n >\n <table className=\"tw:w-full tw:table-fixed tw:bg-background\">\n {/* Not v4's `shadow-xs`: `tailwind-config`'s `boxShadow.sm` fallback still carries\n the v3 value, and only `shadow-sm` reads `--shadow-sm` from a brand's\n `theme.shadows` — `shadow-xs` has no token and would opt this header out. */}\n <thead className=\"tw:sticky tw:top-0 tw:z-10 tw:shadow-sm\">\n <tr>\n <DiffViewTh variant=\"gutter\">{leftTitleGutter}</DiffViewTh>\n <DiffViewTh>{leftTitle}</DiffViewTh>\n <DiffViewTh variant=\"gutter\">{rightTitleGutter}</DiffViewTh>\n <DiffViewTh>{rightTitle}</DiffViewTh>\n </tr>\n </thead>\n\n <tbody>\n {rows.map((row) => {\n if (row.kind === 'fold')\n return (\n <tr key={row.key}>\n <DiffViewTd colSpan={4}>\n <button\n type=\"button\"\n onClick={() => handleExpand(row.blockStart)}\n className={cn(\n 'tw:w-full',\n 'tw:text-center',\n 'tw:bg-muted',\n 'tw:text-foreground',\n 'tw:hover:bg-hover',\n 'tw:underline',\n 'tw:p-2',\n )}\n >\n Expand {row.lineCount} lines ...\n </button>\n </DiffViewTd>\n </tr>\n );\n\n return (\n <tr key={row.key}>\n <DiffViewTd variant=\"gutter\" diff={row.left.type}>\n {row.left.lineNumber}\n </DiffViewTd>\n\n <DiffViewTd variant=\"code\" diff={row.left.type}>\n {row.left.words.map((val, index) => {\n if (val.type === 'default') return val.value;\n return (\n // oxlint-disable-next-line react/no-array-index-key\n <DiffViewMark key={`${val.value}-${val.type}-${index}`} diff={val.type}>\n {val.value}\n </DiffViewMark>\n );\n })}\n </DiffViewTd>\n\n <DiffViewTd variant=\"gutter\" diff={row.right.type}>\n {row.right.lineNumber}\n </DiffViewTd>\n\n <DiffViewTd variant=\"code\" diff={row.right.type}>\n {row.right.words.map((val, index) => {\n if (val.type === 'default') return val.value;\n\n return (\n // oxlint-disable-next-line react/no-array-index-key\n <DiffViewMark key={`${val.value}-${val.type}-${index}`} diff={val.type}>\n {val.value}\n </DiffViewMark>\n );\n })}\n </DiffViewTd>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n};\n"],"mappings":"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"}