@neo4j-ndl/react 4.1.4 → 4.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. package/lib/cjs/_common/CodeBlockWrapper.js +5 -4
  2. package/lib/cjs/_common/CodeBlockWrapper.js.map +1 -1
  3. package/lib/cjs/_common/utils.js +4 -2
  4. package/lib/cjs/_common/utils.js.map +1 -1
  5. package/lib/cjs/accordion/Accordion.js +9 -6
  6. package/lib/cjs/accordion/Accordion.js.map +1 -1
  7. package/lib/cjs/accordion/accordion-types.js.map +1 -1
  8. package/lib/cjs/accordion/stories/accordion.stories.js +1 -1
  9. package/lib/cjs/accordion/stories/accordion.stories.js.map +1 -1
  10. package/lib/cjs/avatar/Avatar.js +1 -1
  11. package/lib/cjs/avatar/Avatar.js.map +1 -1
  12. package/lib/cjs/banner/Banner.js +3 -2
  13. package/lib/cjs/banner/Banner.js.map +1 -1
  14. package/lib/cjs/banner/stories/banner.stories.js +1 -1
  15. package/lib/cjs/banner/stories/banner.stories.js.map +1 -1
  16. package/lib/cjs/box/Box.js +14 -2
  17. package/lib/cjs/box/Box.js.map +1 -1
  18. package/lib/cjs/box/stories/box.stories.js +2 -2
  19. package/lib/cjs/box/stories/box.stories.js.map +1 -1
  20. package/lib/cjs/breadcrumbs/Breadcrumbs.js +10 -7
  21. package/lib/cjs/breadcrumbs/Breadcrumbs.js.map +1 -1
  22. package/lib/cjs/button/stories/button.stories.js +2 -2
  23. package/lib/cjs/button/stories/button.stories.js.map +1 -1
  24. package/lib/cjs/checkbox/Checkbox.js +2 -1
  25. package/lib/cjs/checkbox/Checkbox.js.map +1 -1
  26. package/lib/cjs/checkbox/stories/checkbox.stories.js +1 -1
  27. package/lib/cjs/checkbox/stories/checkbox.stories.js.map +1 -1
  28. package/lib/cjs/clipboard-button/ClipboardButton.js +6 -3
  29. package/lib/cjs/clipboard-button/ClipboardButton.js.map +1 -1
  30. package/lib/cjs/color-picker/ColorPicker.js +2 -1
  31. package/lib/cjs/color-picker/ColorPicker.js.map +1 -1
  32. package/lib/cjs/data-grid/Components.js +9 -6
  33. package/lib/cjs/data-grid/Components.js.map +1 -1
  34. package/lib/cjs/data-grid/DataGrid.js +16 -4
  35. package/lib/cjs/data-grid/DataGrid.js.map +1 -1
  36. package/lib/cjs/data-grid/data-grid-nav/data-grid-nav.js +28 -14
  37. package/lib/cjs/data-grid/data-grid-nav/data-grid-nav.js.map +1 -1
  38. package/lib/cjs/data-grid/data-grid-nav/helpers.js +2 -1
  39. package/lib/cjs/data-grid/data-grid-nav/helpers.js.map +1 -1
  40. package/lib/cjs/data-grid/stories/datagrid-component-overriding.story.js +1 -3
  41. package/lib/cjs/data-grid/stories/datagrid-component-overriding.story.js.map +1 -1
  42. package/lib/cjs/data-grid/stories/datagrid-in-dialog.story.js +2 -1
  43. package/lib/cjs/data-grid/stories/datagrid-in-dialog.story.js.map +1 -1
  44. package/lib/cjs/data-grid/stories/datagrid-keyboard-navigation.story.js +2 -1
  45. package/lib/cjs/data-grid/stories/datagrid-keyboard-navigation.story.js.map +1 -1
  46. package/lib/cjs/data-grid/stories/datagrid-kitchen-sink.story.js +1 -2
  47. package/lib/cjs/data-grid/stories/datagrid-kitchen-sink.story.js.map +1 -1
  48. package/lib/cjs/data-grid/stories/datagrid-search-and-filters.stories.js +13 -10
  49. package/lib/cjs/data-grid/stories/datagrid-search-and-filters.stories.js.map +1 -1
  50. package/lib/cjs/date-picker/DatePicker.js +2 -1
  51. package/lib/cjs/date-picker/DatePicker.js.map +1 -1
  52. package/lib/cjs/date-picker/stories/date-picker-range.story.js +1 -1
  53. package/lib/cjs/date-picker/stories/date-picker-range.story.js.map +1 -1
  54. package/lib/cjs/date-picker/stories/date-picker.stories.js +1 -1
  55. package/lib/cjs/date-picker/stories/date-picker.stories.js.map +1 -1
  56. package/lib/cjs/dialog/Dialog.js +20 -13
  57. package/lib/cjs/dialog/Dialog.js.map +1 -1
  58. package/lib/cjs/dialog/dialog-context.js +35 -6
  59. package/lib/cjs/dialog/dialog-context.js.map +1 -1
  60. package/lib/cjs/dialog/stories/dialog.stories.js +1 -1
  61. package/lib/cjs/dialog/stories/dialog.stories.js.map +1 -1
  62. package/lib/cjs/divider/stories/divider.stories.js +1 -1
  63. package/lib/cjs/divider/stories/divider.stories.js.map +1 -1
  64. package/lib/cjs/drawer/Drawer.js +9 -8
  65. package/lib/cjs/drawer/Drawer.js.map +1 -1
  66. package/lib/cjs/dropdown-button/DropdownButton.js +14 -2
  67. package/lib/cjs/dropdown-button/DropdownButton.js.map +1 -1
  68. package/lib/cjs/dropzone/Dropzone.js +3 -2
  69. package/lib/cjs/dropzone/Dropzone.js.map +1 -1
  70. package/lib/cjs/dropzone/stories/dropzone-csv-files.story.js +1 -3
  71. package/lib/cjs/dropzone/stories/dropzone-csv-files.story.js.map +1 -1
  72. package/lib/cjs/dropzone/stories/dropzone-custom-extensions.story.js +1 -3
  73. package/lib/cjs/dropzone/stories/dropzone-custom-extensions.story.js.map +1 -1
  74. package/lib/cjs/dropzone/stories/dropzone-default.story.js +1 -3
  75. package/lib/cjs/dropzone/stories/dropzone-default.story.js.map +1 -1
  76. package/lib/cjs/dropzone/stories/dropzone-disabled.story.js +1 -3
  77. package/lib/cjs/dropzone/stories/dropzone-disabled.story.js.map +1 -1
  78. package/lib/cjs/flex/Flex.js +14 -2
  79. package/lib/cjs/flex/Flex.js.map +1 -1
  80. package/lib/cjs/graph-label/GraphLabel.js +18 -4
  81. package/lib/cjs/graph-label/GraphLabel.js.map +1 -1
  82. package/lib/cjs/icon-button/stories/icon-button.stories.js +1 -1
  83. package/lib/cjs/icon-button/stories/icon-button.stories.js.map +1 -1
  84. package/lib/cjs/icon-button-array/IconButtonArray.js +14 -2
  85. package/lib/cjs/icon-button-array/IconButtonArray.js.map +1 -1
  86. package/lib/cjs/icon-button-array/index.js +1 -1
  87. package/lib/cjs/icon-button-array/index.js.map +1 -1
  88. package/lib/cjs/icon-button-array/stories/icon-button-array.stories.js +1 -1
  89. package/lib/cjs/icon-button-array/stories/icon-button-array.stories.js.map +1 -1
  90. package/lib/cjs/icons/generated/custom/index.js +4 -2
  91. package/lib/cjs/icons/generated/custom/index.js.map +1 -1
  92. package/lib/cjs/icons/wrapIcon.js +1 -1
  93. package/lib/cjs/icons/wrapIcon.js.map +1 -1
  94. package/lib/cjs/inline-edit/InlineEdit.js +18 -6
  95. package/lib/cjs/inline-edit/InlineEdit.js.map +1 -1
  96. package/lib/cjs/kbd/Kbd.js +5 -3
  97. package/lib/cjs/kbd/Kbd.js.map +1 -1
  98. package/lib/cjs/kbd/stories/kbd.stories.js +1 -1
  99. package/lib/cjs/kbd/stories/kbd.stories.js.map +1 -1
  100. package/lib/cjs/loading-bar/LoadingBar.js +14 -2
  101. package/lib/cjs/loading-bar/LoadingBar.js.map +1 -1
  102. package/lib/cjs/loading-spinner/LoadingSpinner.js +1 -1
  103. package/lib/cjs/loading-spinner/LoadingSpinner.js.map +1 -1
  104. package/lib/cjs/logo/stories/logo.stories.js +1 -1
  105. package/lib/cjs/logo/stories/logo.stories.js.map +1 -1
  106. package/lib/cjs/menu/Menu.js +9 -6
  107. package/lib/cjs/menu/Menu.js.map +1 -1
  108. package/lib/cjs/popover/Popover.js +6 -4
  109. package/lib/cjs/popover/Popover.js.map +1 -1
  110. package/lib/cjs/popover/stories/popover-custom-offset.story.js +2 -1
  111. package/lib/cjs/popover/stories/popover-custom-offset.story.js.map +1 -1
  112. package/lib/cjs/popover/stories/popover-separate-anchor.story.js +1 -1
  113. package/lib/cjs/popover/stories/popover-separate-anchor.story.js.map +1 -1
  114. package/lib/cjs/progress-bar/ProgressBar.js +1 -1
  115. package/lib/cjs/progress-bar/ProgressBar.js.map +1 -1
  116. package/lib/cjs/radio/Radio.js +2 -1
  117. package/lib/cjs/radio/Radio.js.map +1 -1
  118. package/lib/cjs/radio/stories/radio.stories.js +1 -1
  119. package/lib/cjs/radio/stories/radio.stories.js.map +1 -1
  120. package/lib/cjs/select/Overrides.js +1 -1
  121. package/lib/cjs/select/Overrides.js.map +1 -1
  122. package/lib/cjs/select/Select.js +18 -6
  123. package/lib/cjs/select/Select.js.map +1 -1
  124. package/lib/cjs/side-navigation/SideNavigation.js +5 -4
  125. package/lib/cjs/side-navigation/SideNavigation.js.map +1 -1
  126. package/lib/cjs/skeleton/Skeleton.js +14 -2
  127. package/lib/cjs/skeleton/Skeleton.js.map +1 -1
  128. package/lib/cjs/skeleton/stories/skeleton.stories.js +1 -1
  129. package/lib/cjs/skeleton/stories/skeleton.stories.js.map +1 -1
  130. package/lib/cjs/spotlight/Spotlight.js +33 -14
  131. package/lib/cjs/spotlight/Spotlight.js.map +1 -1
  132. package/lib/cjs/spotlight/SpotlightProvider.js +6 -3
  133. package/lib/cjs/spotlight/SpotlightProvider.js.map +1 -1
  134. package/lib/cjs/spotlight/SpotlightTarget.js +14 -2
  135. package/lib/cjs/spotlight/SpotlightTarget.js.map +1 -1
  136. package/lib/cjs/spotlight/SpotlightTour.js +1 -1
  137. package/lib/cjs/spotlight/SpotlightTour.js.map +1 -1
  138. package/lib/cjs/spotlight/stories/spotlight.stories.js +1 -1
  139. package/lib/cjs/spotlight/stories/spotlight.stories.js.map +1 -1
  140. package/lib/cjs/spotlight/use-indicator.js +2 -1
  141. package/lib/cjs/spotlight/use-indicator.js.map +1 -1
  142. package/lib/cjs/status-label/StatusLabel.js +1 -1
  143. package/lib/cjs/status-label/StatusLabel.js.map +1 -1
  144. package/lib/cjs/switch/Switch.js +2 -1
  145. package/lib/cjs/switch/Switch.js.map +1 -1
  146. package/lib/cjs/switch/stories/switch.stories.js +1 -1
  147. package/lib/cjs/switch/stories/switch.stories.js.map +1 -1
  148. package/lib/cjs/tabs/stories/tabs-disabled.story.js +1 -1
  149. package/lib/cjs/tabs/stories/tabs-disabled.story.js.map +1 -1
  150. package/lib/cjs/tabs/stories/tabs-fill-variants.story.js +1 -1
  151. package/lib/cjs/tabs/stories/tabs-fill-variants.story.js.map +1 -1
  152. package/lib/cjs/tabs/stories/tabs-overflow.story.js +1 -1
  153. package/lib/cjs/tabs/stories/tabs-overflow.story.js.map +1 -1
  154. package/lib/cjs/tabs/stories/tabs-sizes.story.js +1 -1
  155. package/lib/cjs/tabs/stories/tabs-sizes.story.js.map +1 -1
  156. package/lib/cjs/tabs/use-tabs-scroll-overflow.js +8 -4
  157. package/lib/cjs/tabs/use-tabs-scroll-overflow.js.map +1 -1
  158. package/lib/cjs/tag/Tag.js +14 -2
  159. package/lib/cjs/tag/Tag.js.map +1 -1
  160. package/lib/cjs/text-area/TextArea.js +14 -2
  161. package/lib/cjs/text-area/TextArea.js.map +1 -1
  162. package/lib/cjs/text-area/stories/text-area.stories.js +1 -1
  163. package/lib/cjs/text-area/stories/text-area.stories.js.map +1 -1
  164. package/lib/cjs/text-input/TextInput.js +14 -2
  165. package/lib/cjs/text-input/TextInput.js.map +1 -1
  166. package/lib/cjs/text-link/TextLink.js +14 -2
  167. package/lib/cjs/text-link/TextLink.js.map +1 -1
  168. package/lib/cjs/text-overflow/TextOverflow.js +2 -1
  169. package/lib/cjs/text-overflow/TextOverflow.js.map +1 -1
  170. package/lib/cjs/text-overflow/stories/text-overflow.stories.js +1 -1
  171. package/lib/cjs/text-overflow/stories/text-overflow.stories.js.map +1 -1
  172. package/lib/cjs/text-overflow/text-overflow-utils.js +12 -6
  173. package/lib/cjs/text-overflow/text-overflow-utils.js.map +1 -1
  174. package/lib/cjs/text-overflow/use-ellipsis-observer.js +2 -1
  175. package/lib/cjs/text-overflow/use-ellipsis-observer.js.map +1 -1
  176. package/lib/cjs/text-overflow/use-truncate-with-button.js +4 -2
  177. package/lib/cjs/text-overflow/use-truncate-with-button.js.map +1 -1
  178. package/lib/cjs/theme/ThemeProvider.js +2 -1
  179. package/lib/cjs/theme/ThemeProvider.js.map +1 -1
  180. package/lib/cjs/time-picker/TimePicker.js +22 -8
  181. package/lib/cjs/time-picker/TimePicker.js.map +1 -1
  182. package/lib/cjs/time-picker/stories/time-picker.stories.js +1 -1
  183. package/lib/cjs/time-picker/stories/time-picker.stories.js.map +1 -1
  184. package/lib/cjs/timezone-picker/TimeZonePicker.js +8 -4
  185. package/lib/cjs/timezone-picker/TimeZonePicker.js.map +1 -1
  186. package/lib/cjs/timezone-picker/generate-timezone-options.js +15 -9
  187. package/lib/cjs/timezone-picker/generate-timezone-options.js.map +1 -1
  188. package/lib/cjs/timezone-picker/stories/timezone-picker.stories.js +1 -1
  189. package/lib/cjs/timezone-picker/stories/timezone-picker.stories.js.map +1 -1
  190. package/lib/cjs/toast/Toast.js +11 -6
  191. package/lib/cjs/toast/Toast.js.map +1 -1
  192. package/lib/cjs/tooltip/Tooltip.js +35 -15
  193. package/lib/cjs/tooltip/Tooltip.js.map +1 -1
  194. package/lib/cjs/tree-view/TreeItemWrapper.js +3 -1
  195. package/lib/cjs/tree-view/TreeItemWrapper.js.map +1 -1
  196. package/lib/cjs/tree-view/TreeView.js +2 -1
  197. package/lib/cjs/tree-view/TreeView.js.map +1 -1
  198. package/lib/cjs/tree-view/TreeViewItem.js +3 -1
  199. package/lib/cjs/tree-view/TreeViewItem.js.map +1 -1
  200. package/lib/cjs/tree-view/TreeViewTextItem.js +1 -2
  201. package/lib/cjs/tree-view/TreeViewTextItem.js.map +1 -1
  202. package/lib/cjs/tree-view/TreeViewTrail.js +14 -2
  203. package/lib/cjs/tree-view/TreeViewTrail.js.map +1 -1
  204. package/lib/cjs/wizard/Wizard.js +3 -2
  205. package/lib/cjs/wizard/Wizard.js.map +1 -1
  206. package/lib/esm/_common/CodeBlockWrapper.js +5 -4
  207. package/lib/esm/_common/CodeBlockWrapper.js.map +1 -1
  208. package/lib/esm/_common/utils.js +4 -2
  209. package/lib/esm/_common/utils.js.map +1 -1
  210. package/lib/esm/accordion/Accordion.js +9 -6
  211. package/lib/esm/accordion/Accordion.js.map +1 -1
  212. package/lib/esm/accordion/accordion-types.js.map +1 -1
  213. package/lib/esm/accordion/stories/accordion.stories.js +1 -1
  214. package/lib/esm/accordion/stories/accordion.stories.js.map +1 -1
  215. package/lib/esm/avatar/Avatar.js +1 -1
  216. package/lib/esm/avatar/Avatar.js.map +1 -1
  217. package/lib/esm/banner/Banner.js +3 -2
  218. package/lib/esm/banner/Banner.js.map +1 -1
  219. package/lib/esm/banner/stories/banner.stories.js +1 -1
  220. package/lib/esm/banner/stories/banner.stories.js.map +1 -1
  221. package/lib/esm/box/Box.js +14 -2
  222. package/lib/esm/box/Box.js.map +1 -1
  223. package/lib/esm/box/stories/box.stories.js +2 -2
  224. package/lib/esm/box/stories/box.stories.js.map +1 -1
  225. package/lib/esm/breadcrumbs/Breadcrumbs.js +10 -7
  226. package/lib/esm/breadcrumbs/Breadcrumbs.js.map +1 -1
  227. package/lib/esm/button/stories/button.stories.js +1 -1
  228. package/lib/esm/button/stories/button.stories.js.map +1 -1
  229. package/lib/esm/checkbox/Checkbox.js +2 -1
  230. package/lib/esm/checkbox/Checkbox.js.map +1 -1
  231. package/lib/esm/checkbox/stories/checkbox.stories.js +1 -1
  232. package/lib/esm/checkbox/stories/checkbox.stories.js.map +1 -1
  233. package/lib/esm/clipboard-button/ClipboardButton.js +6 -3
  234. package/lib/esm/clipboard-button/ClipboardButton.js.map +1 -1
  235. package/lib/esm/color-picker/ColorPicker.js +2 -1
  236. package/lib/esm/color-picker/ColorPicker.js.map +1 -1
  237. package/lib/esm/data-grid/Components.js +9 -6
  238. package/lib/esm/data-grid/Components.js.map +1 -1
  239. package/lib/esm/data-grid/DataGrid.js +16 -4
  240. package/lib/esm/data-grid/DataGrid.js.map +1 -1
  241. package/lib/esm/data-grid/data-grid-nav/data-grid-nav.js +28 -14
  242. package/lib/esm/data-grid/data-grid-nav/data-grid-nav.js.map +1 -1
  243. package/lib/esm/data-grid/data-grid-nav/helpers.js +2 -1
  244. package/lib/esm/data-grid/data-grid-nav/helpers.js.map +1 -1
  245. package/lib/esm/data-grid/stories/datagrid-component-overriding.story.js +1 -3
  246. package/lib/esm/data-grid/stories/datagrid-component-overriding.story.js.map +1 -1
  247. package/lib/esm/data-grid/stories/datagrid-in-dialog.story.js +2 -1
  248. package/lib/esm/data-grid/stories/datagrid-in-dialog.story.js.map +1 -1
  249. package/lib/esm/data-grid/stories/datagrid-keyboard-navigation.story.js +2 -1
  250. package/lib/esm/data-grid/stories/datagrid-keyboard-navigation.story.js.map +1 -1
  251. package/lib/esm/data-grid/stories/datagrid-kitchen-sink.story.js +1 -2
  252. package/lib/esm/data-grid/stories/datagrid-kitchen-sink.story.js.map +1 -1
  253. package/lib/esm/data-grid/stories/datagrid-search-and-filters.stories.js +9 -6
  254. package/lib/esm/data-grid/stories/datagrid-search-and-filters.stories.js.map +1 -1
  255. package/lib/esm/date-picker/DatePicker.js +2 -1
  256. package/lib/esm/date-picker/DatePicker.js.map +1 -1
  257. package/lib/esm/date-picker/stories/date-picker-range.story.js +1 -1
  258. package/lib/esm/date-picker/stories/date-picker-range.story.js.map +1 -1
  259. package/lib/esm/date-picker/stories/date-picker.stories.js +1 -1
  260. package/lib/esm/date-picker/stories/date-picker.stories.js.map +1 -1
  261. package/lib/esm/dialog/Dialog.js +20 -13
  262. package/lib/esm/dialog/Dialog.js.map +1 -1
  263. package/lib/esm/dialog/dialog-context.js +1 -2
  264. package/lib/esm/dialog/dialog-context.js.map +1 -1
  265. package/lib/esm/dialog/stories/dialog.stories.js +1 -1
  266. package/lib/esm/dialog/stories/dialog.stories.js.map +1 -1
  267. package/lib/esm/divider/stories/divider.stories.js +1 -1
  268. package/lib/esm/divider/stories/divider.stories.js.map +1 -1
  269. package/lib/esm/drawer/Drawer.js +9 -8
  270. package/lib/esm/drawer/Drawer.js.map +1 -1
  271. package/lib/esm/dropdown-button/DropdownButton.js +14 -2
  272. package/lib/esm/dropdown-button/DropdownButton.js.map +1 -1
  273. package/lib/esm/dropzone/Dropzone.js +3 -2
  274. package/lib/esm/dropzone/Dropzone.js.map +1 -1
  275. package/lib/esm/dropzone/stories/dropzone-csv-files.story.js +1 -3
  276. package/lib/esm/dropzone/stories/dropzone-csv-files.story.js.map +1 -1
  277. package/lib/esm/dropzone/stories/dropzone-custom-extensions.story.js +1 -3
  278. package/lib/esm/dropzone/stories/dropzone-custom-extensions.story.js.map +1 -1
  279. package/lib/esm/dropzone/stories/dropzone-default.story.js +1 -3
  280. package/lib/esm/dropzone/stories/dropzone-default.story.js.map +1 -1
  281. package/lib/esm/dropzone/stories/dropzone-disabled.story.js +1 -3
  282. package/lib/esm/dropzone/stories/dropzone-disabled.story.js.map +1 -1
  283. package/lib/esm/flex/Flex.js +14 -2
  284. package/lib/esm/flex/Flex.js.map +1 -1
  285. package/lib/esm/graph-label/GraphLabel.js +18 -4
  286. package/lib/esm/graph-label/GraphLabel.js.map +1 -1
  287. package/lib/esm/icon-button/stories/icon-button.stories.js +1 -1
  288. package/lib/esm/icon-button/stories/icon-button.stories.js.map +1 -1
  289. package/lib/esm/icon-button-array/IconButtonArray.js +14 -2
  290. package/lib/esm/icon-button-array/IconButtonArray.js.map +1 -1
  291. package/lib/esm/icon-button-array/index.js +1 -1
  292. package/lib/esm/icon-button-array/index.js.map +1 -1
  293. package/lib/esm/icon-button-array/stories/icon-button-array.stories.js +1 -1
  294. package/lib/esm/icon-button-array/stories/icon-button-array.stories.js.map +1 -1
  295. package/lib/esm/icons/generated/custom/index.js +1 -0
  296. package/lib/esm/icons/generated/custom/index.js.map +1 -1
  297. package/lib/esm/icons/wrapIcon.js +1 -1
  298. package/lib/esm/icons/wrapIcon.js.map +1 -1
  299. package/lib/esm/inline-edit/InlineEdit.js +18 -6
  300. package/lib/esm/inline-edit/InlineEdit.js.map +1 -1
  301. package/lib/esm/kbd/Kbd.js +5 -3
  302. package/lib/esm/kbd/Kbd.js.map +1 -1
  303. package/lib/esm/kbd/stories/kbd.stories.js +1 -1
  304. package/lib/esm/kbd/stories/kbd.stories.js.map +1 -1
  305. package/lib/esm/loading-bar/LoadingBar.js +14 -2
  306. package/lib/esm/loading-bar/LoadingBar.js.map +1 -1
  307. package/lib/esm/loading-spinner/LoadingSpinner.js +1 -1
  308. package/lib/esm/loading-spinner/LoadingSpinner.js.map +1 -1
  309. package/lib/esm/logo/stories/logo.stories.js +1 -1
  310. package/lib/esm/logo/stories/logo.stories.js.map +1 -1
  311. package/lib/esm/menu/Menu.js +9 -6
  312. package/lib/esm/menu/Menu.js.map +1 -1
  313. package/lib/esm/popover/Popover.js +6 -4
  314. package/lib/esm/popover/Popover.js.map +1 -1
  315. package/lib/esm/popover/stories/popover-custom-offset.story.js +2 -1
  316. package/lib/esm/popover/stories/popover-custom-offset.story.js.map +1 -1
  317. package/lib/esm/popover/stories/popover-separate-anchor.story.js +1 -1
  318. package/lib/esm/popover/stories/popover-separate-anchor.story.js.map +1 -1
  319. package/lib/esm/progress-bar/ProgressBar.js +1 -1
  320. package/lib/esm/progress-bar/ProgressBar.js.map +1 -1
  321. package/lib/esm/radio/Radio.js +2 -1
  322. package/lib/esm/radio/Radio.js.map +1 -1
  323. package/lib/esm/radio/stories/radio.stories.js +1 -1
  324. package/lib/esm/radio/stories/radio.stories.js.map +1 -1
  325. package/lib/esm/select/Overrides.js +1 -1
  326. package/lib/esm/select/Overrides.js.map +1 -1
  327. package/lib/esm/select/Select.js +18 -6
  328. package/lib/esm/select/Select.js.map +1 -1
  329. package/lib/esm/side-navigation/SideNavigation.js +5 -4
  330. package/lib/esm/side-navigation/SideNavigation.js.map +1 -1
  331. package/lib/esm/skeleton/Skeleton.js +14 -2
  332. package/lib/esm/skeleton/Skeleton.js.map +1 -1
  333. package/lib/esm/skeleton/stories/skeleton.stories.js +1 -1
  334. package/lib/esm/skeleton/stories/skeleton.stories.js.map +1 -1
  335. package/lib/esm/spotlight/Spotlight.js +33 -14
  336. package/lib/esm/spotlight/Spotlight.js.map +1 -1
  337. package/lib/esm/spotlight/SpotlightProvider.js +6 -3
  338. package/lib/esm/spotlight/SpotlightProvider.js.map +1 -1
  339. package/lib/esm/spotlight/SpotlightTarget.js +14 -2
  340. package/lib/esm/spotlight/SpotlightTarget.js.map +1 -1
  341. package/lib/esm/spotlight/SpotlightTour.js +1 -1
  342. package/lib/esm/spotlight/SpotlightTour.js.map +1 -1
  343. package/lib/esm/spotlight/stories/spotlight.stories.js +1 -1
  344. package/lib/esm/spotlight/stories/spotlight.stories.js.map +1 -1
  345. package/lib/esm/spotlight/use-indicator.js +2 -1
  346. package/lib/esm/spotlight/use-indicator.js.map +1 -1
  347. package/lib/esm/status-label/StatusLabel.js +1 -1
  348. package/lib/esm/status-label/StatusLabel.js.map +1 -1
  349. package/lib/esm/switch/Switch.js +2 -1
  350. package/lib/esm/switch/Switch.js.map +1 -1
  351. package/lib/esm/switch/stories/switch.stories.js +1 -1
  352. package/lib/esm/switch/stories/switch.stories.js.map +1 -1
  353. package/lib/esm/tabs/stories/tabs-disabled.story.js +1 -1
  354. package/lib/esm/tabs/stories/tabs-disabled.story.js.map +1 -1
  355. package/lib/esm/tabs/stories/tabs-fill-variants.story.js +1 -1
  356. package/lib/esm/tabs/stories/tabs-fill-variants.story.js.map +1 -1
  357. package/lib/esm/tabs/stories/tabs-overflow.story.js +1 -1
  358. package/lib/esm/tabs/stories/tabs-overflow.story.js.map +1 -1
  359. package/lib/esm/tabs/stories/tabs-sizes.story.js +1 -1
  360. package/lib/esm/tabs/stories/tabs-sizes.story.js.map +1 -1
  361. package/lib/esm/tabs/use-tabs-scroll-overflow.js +8 -4
  362. package/lib/esm/tabs/use-tabs-scroll-overflow.js.map +1 -1
  363. package/lib/esm/tag/Tag.js +14 -2
  364. package/lib/esm/tag/Tag.js.map +1 -1
  365. package/lib/esm/text-area/TextArea.js +14 -2
  366. package/lib/esm/text-area/TextArea.js.map +1 -1
  367. package/lib/esm/text-area/stories/text-area.stories.js +1 -1
  368. package/lib/esm/text-area/stories/text-area.stories.js.map +1 -1
  369. package/lib/esm/text-input/TextInput.js +14 -2
  370. package/lib/esm/text-input/TextInput.js.map +1 -1
  371. package/lib/esm/text-link/TextLink.js +14 -2
  372. package/lib/esm/text-link/TextLink.js.map +1 -1
  373. package/lib/esm/text-overflow/TextOverflow.js +2 -1
  374. package/lib/esm/text-overflow/TextOverflow.js.map +1 -1
  375. package/lib/esm/text-overflow/stories/text-overflow.stories.js +1 -1
  376. package/lib/esm/text-overflow/stories/text-overflow.stories.js.map +1 -1
  377. package/lib/esm/text-overflow/text-overflow-utils.js +12 -6
  378. package/lib/esm/text-overflow/text-overflow-utils.js.map +1 -1
  379. package/lib/esm/text-overflow/use-ellipsis-observer.js +2 -1
  380. package/lib/esm/text-overflow/use-ellipsis-observer.js.map +1 -1
  381. package/lib/esm/text-overflow/use-truncate-with-button.js +4 -2
  382. package/lib/esm/text-overflow/use-truncate-with-button.js.map +1 -1
  383. package/lib/esm/theme/ThemeProvider.js +2 -1
  384. package/lib/esm/theme/ThemeProvider.js.map +1 -1
  385. package/lib/esm/time-picker/TimePicker.js +22 -8
  386. package/lib/esm/time-picker/TimePicker.js.map +1 -1
  387. package/lib/esm/time-picker/stories/time-picker.stories.js +1 -1
  388. package/lib/esm/time-picker/stories/time-picker.stories.js.map +1 -1
  389. package/lib/esm/timezone-picker/TimeZonePicker.js +8 -4
  390. package/lib/esm/timezone-picker/TimeZonePicker.js.map +1 -1
  391. package/lib/esm/timezone-picker/generate-timezone-options.js +15 -9
  392. package/lib/esm/timezone-picker/generate-timezone-options.js.map +1 -1
  393. package/lib/esm/timezone-picker/stories/timezone-picker.stories.js +1 -1
  394. package/lib/esm/timezone-picker/stories/timezone-picker.stories.js.map +1 -1
  395. package/lib/esm/toast/Toast.js +11 -6
  396. package/lib/esm/toast/Toast.js.map +1 -1
  397. package/lib/esm/tooltip/Tooltip.js +35 -15
  398. package/lib/esm/tooltip/Tooltip.js.map +1 -1
  399. package/lib/esm/tree-view/TreeItemWrapper.js +3 -1
  400. package/lib/esm/tree-view/TreeItemWrapper.js.map +1 -1
  401. package/lib/esm/tree-view/TreeView.js +2 -1
  402. package/lib/esm/tree-view/TreeView.js.map +1 -1
  403. package/lib/esm/tree-view/TreeViewItem.js +3 -1
  404. package/lib/esm/tree-view/TreeViewItem.js.map +1 -1
  405. package/lib/esm/tree-view/TreeViewTextItem.js +1 -2
  406. package/lib/esm/tree-view/TreeViewTextItem.js.map +1 -1
  407. package/lib/esm/tree-view/TreeViewTrail.js +14 -2
  408. package/lib/esm/tree-view/TreeViewTrail.js.map +1 -1
  409. package/lib/esm/wizard/Wizard.js +3 -2
  410. package/lib/esm/wizard/Wizard.js.map +1 -1
  411. package/lib/types/_common/CodeBlockWrapper.d.ts +1 -1
  412. package/lib/types/_common/CodeBlockWrapper.d.ts.map +1 -1
  413. package/lib/types/_common/utils.d.ts.map +1 -1
  414. package/lib/types/accordion/Accordion.d.ts +4 -4
  415. package/lib/types/accordion/Accordion.d.ts.map +1 -1
  416. package/lib/types/accordion/accordion-types.d.ts +1 -1
  417. package/lib/types/accordion/accordion-types.d.ts.map +1 -1
  418. package/lib/types/accordion/stories/accordion.stories.d.ts +4 -4
  419. package/lib/types/avatar/Avatar.d.ts.map +1 -1
  420. package/lib/types/banner/Banner.d.ts +1 -1
  421. package/lib/types/banner/Banner.d.ts.map +1 -1
  422. package/lib/types/box/Box.d.ts +1 -1
  423. package/lib/types/box/Box.d.ts.map +1 -1
  424. package/lib/types/box/stories/box.stories.d.ts +1 -1
  425. package/lib/types/breadcrumbs/Breadcrumbs.d.ts +3 -3
  426. package/lib/types/breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  427. package/lib/types/breadcrumbs/stories/breadcrumbs.stories.d.ts +3 -3
  428. package/lib/types/button/stories/button.stories.d.ts +1 -1
  429. package/lib/types/button/stories/button.stories.d.ts.map +1 -1
  430. package/lib/types/checkbox/Checkbox.d.ts.map +1 -1
  431. package/lib/types/clipboard-button/ClipboardButton.d.ts.map +1 -1
  432. package/lib/types/color-picker/ColorPicker.d.ts.map +1 -1
  433. package/lib/types/data-grid/Components.d.ts.map +1 -1
  434. package/lib/types/data-grid/DataGrid.d.ts +23 -23
  435. package/lib/types/data-grid/DataGrid.d.ts.map +1 -1
  436. package/lib/types/data-grid/data-grid-nav/data-grid-nav.d.ts.map +1 -1
  437. package/lib/types/data-grid/data-grid-nav/helpers.d.ts.map +1 -1
  438. package/lib/types/data-grid/stories/datagrid-component-overriding.story.d.ts.map +1 -1
  439. package/lib/types/data-grid/stories/datagrid-in-dialog.story.d.ts.map +1 -1
  440. package/lib/types/data-grid/stories/datagrid-keyboard-navigation.story.d.ts.map +1 -1
  441. package/lib/types/data-grid/stories/datagrid-kitchen-sink.story.d.ts.map +1 -1
  442. package/lib/types/data-grid/stories/datagrid-pinned-columns.stories.d.ts +1 -1
  443. package/lib/types/data-grid/stories/datagrid-placeholder-states.stories.d.ts +1 -1
  444. package/lib/types/data-grid/stories/datagrid-search-and-filters.stories.d.ts +1 -1
  445. package/lib/types/data-grid/stories/datagrid-search-and-filters.stories.d.ts.map +1 -1
  446. package/lib/types/date-picker/DatePicker.d.ts.map +1 -1
  447. package/lib/types/date-picker/stories/date-picker-range.story.d.ts.map +1 -1
  448. package/lib/types/dialog/Dialog.d.ts +6 -6
  449. package/lib/types/dialog/Dialog.d.ts.map +1 -1
  450. package/lib/types/dialog/dialog-context.d.ts.map +1 -1
  451. package/lib/types/drawer/Drawer.d.ts +3 -3
  452. package/lib/types/drawer/Drawer.d.ts.map +1 -1
  453. package/lib/types/dropdown-button/DropdownButton.d.ts +1 -1
  454. package/lib/types/dropdown-button/DropdownButton.d.ts.map +1 -1
  455. package/lib/types/dropzone/Dropzone.d.ts.map +1 -1
  456. package/lib/types/flex/Flex.d.ts +1 -1
  457. package/lib/types/flex/Flex.d.ts.map +1 -1
  458. package/lib/types/flex/stories/flex.stories.d.ts +1 -1
  459. package/lib/types/graph-label/GraphLabel.d.ts +1 -1
  460. package/lib/types/graph-label/GraphLabel.d.ts.map +1 -1
  461. package/lib/types/icon-button-array/IconButtonArray.d.ts +2 -2
  462. package/lib/types/icon-button-array/IconButtonArray.d.ts.map +1 -1
  463. package/lib/types/icon-button-array/index.d.ts +1 -1
  464. package/lib/types/icon-button-array/index.d.ts.map +1 -1
  465. package/lib/types/icons/generated/custom/index.d.ts +1 -0
  466. package/lib/types/icons/generated/custom/index.d.ts.map +1 -1
  467. package/lib/types/inline-edit/InlineEdit.d.ts +1 -1
  468. package/lib/types/inline-edit/InlineEdit.d.ts.map +1 -1
  469. package/lib/types/kbd/Kbd.d.ts.map +1 -1
  470. package/lib/types/loading-bar/LoadingBar.d.ts +1 -1
  471. package/lib/types/loading-bar/LoadingBar.d.ts.map +1 -1
  472. package/lib/types/menu/Menu.d.ts +2 -2
  473. package/lib/types/menu/Menu.d.ts.map +1 -1
  474. package/lib/types/popover/Popover.d.ts +1 -1
  475. package/lib/types/popover/Popover.d.ts.map +1 -1
  476. package/lib/types/popover/stories/popover-custom-offset.story.d.ts.map +1 -1
  477. package/lib/types/radio/Radio.d.ts.map +1 -1
  478. package/lib/types/select/Overrides.d.ts +1 -2
  479. package/lib/types/select/Overrides.d.ts.map +1 -1
  480. package/lib/types/select/Select.d.ts +1 -1
  481. package/lib/types/select/Select.d.ts.map +1 -1
  482. package/lib/types/side-navigation/SideNavigation.d.ts +1 -1
  483. package/lib/types/side-navigation/SideNavigation.d.ts.map +1 -1
  484. package/lib/types/side-navigation/stories/side-nav.stories.d.ts +1 -1
  485. package/lib/types/skeleton/Skeleton.d.ts +1 -1
  486. package/lib/types/skeleton/Skeleton.d.ts.map +1 -1
  487. package/lib/types/skeleton/stories/skeleton.stories.d.ts +1 -1
  488. package/lib/types/spotlight/Spotlight.d.ts +6 -6
  489. package/lib/types/spotlight/Spotlight.d.ts.map +1 -1
  490. package/lib/types/spotlight/SpotlightProvider.d.ts.map +1 -1
  491. package/lib/types/spotlight/SpotlightTarget.d.ts +1 -1
  492. package/lib/types/spotlight/SpotlightTarget.d.ts.map +1 -1
  493. package/lib/types/spotlight/use-indicator.d.ts.map +1 -1
  494. package/lib/types/switch/Switch.d.ts.map +1 -1
  495. package/lib/types/tabs/use-tabs-scroll-overflow.d.ts.map +1 -1
  496. package/lib/types/tag/Tag.d.ts +1 -1
  497. package/lib/types/tag/Tag.d.ts.map +1 -1
  498. package/lib/types/text-area/TextArea.d.ts +1 -1
  499. package/lib/types/text-area/TextArea.d.ts.map +1 -1
  500. package/lib/types/text-input/TextInput.d.ts +1 -1
  501. package/lib/types/text-input/TextInput.d.ts.map +1 -1
  502. package/lib/types/text-link/TextLink.d.ts +1 -1
  503. package/lib/types/text-link/TextLink.d.ts.map +1 -1
  504. package/lib/types/text-overflow/TextOverflow.d.ts.map +1 -1
  505. package/lib/types/text-overflow/text-overflow-utils.d.ts.map +1 -1
  506. package/lib/types/text-overflow/use-ellipsis-observer.d.ts.map +1 -1
  507. package/lib/types/text-overflow/use-truncate-with-button.d.ts.map +1 -1
  508. package/lib/types/theme/ThemeProvider.d.ts.map +1 -1
  509. package/lib/types/time-picker/TimePicker.d.ts +1 -1
  510. package/lib/types/time-picker/TimePicker.d.ts.map +1 -1
  511. package/lib/types/time-picker/stories/time-picker.stories.d.ts +1 -1
  512. package/lib/types/timezone-picker/TimeZonePicker.d.ts.map +1 -1
  513. package/lib/types/timezone-picker/generate-timezone-options.d.ts.map +1 -1
  514. package/lib/types/toast/Toast.d.ts +1 -1
  515. package/lib/types/toast/Toast.d.ts.map +1 -1
  516. package/lib/types/tooltip/Tooltip.d.ts +8 -7
  517. package/lib/types/tooltip/Tooltip.d.ts.map +1 -1
  518. package/lib/types/tree-view/TreeItemWrapper.d.ts.map +1 -1
  519. package/lib/types/tree-view/TreeView.d.ts.map +1 -1
  520. package/lib/types/tree-view/TreeViewItem.d.ts.map +1 -1
  521. package/lib/types/tree-view/TreeViewTrail.d.ts +2 -1
  522. package/lib/types/tree-view/TreeViewTrail.d.ts.map +1 -1
  523. package/lib/types/wizard/Wizard.d.ts +1 -1
  524. package/lib/types/wizard/Wizard.d.ts.map +1 -1
  525. package/package.json +1 -1
  526. package/lib/cjs/dropdown-button/avatar-test.stories.tsx.js +0 -31
  527. package/lib/cjs/dropdown-button/avatar-test.stories.tsx.js.map +0 -1
  528. package/lib/esm/dropdown-button/avatar-test.stories.tsx.js +0 -27
  529. package/lib/esm/dropdown-button/avatar-test.stories.tsx.js.map +0 -1
  530. package/lib/types/dropdown-button/avatar-test.stories.tsx.d.ts +0 -24
  531. package/lib/types/dropdown-button/avatar-test.stories.tsx.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"text-area.stories.js","sourceRoot":"","sources":["../../../../src/text-area/stories/text-area.stories.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { type Meta, type StoryObj } from '@storybook/react-vite';\n\nimport { TextArea } from '../../index';\nimport {\n TextAreaDefault,\n TextAreaDefaultSrc,\n TextAreaDisabled,\n TextAreaDisabledSrc,\n TextAreaError,\n TextAreaErrorSrc,\n TextAreaFluid,\n TextAreaFluidSrc,\n TextAreaInformationIcon,\n TextAreaInformationIconSrc,\n TextAreaOptional,\n TextAreaOptionalSrc,\n TextAreaResizable,\n TextAreaResizableSrc,\n TextAreaSizes,\n TextAreaSizesSrc,\n} from './';\n\nconst componentMeta: Meta<typeof TextArea> = {\n title: 'Components/TextArea',\n id: 'components-text-area',\n component: TextArea,\n tags: ['docsPage'],\n parameters: {\n controls: { disable: true },\n },\n decorators: [\n (Story) => (\n <div className=\"n-flex n-justify-center\">\n <Story />\n </div>\n ),\n ],\n};\n\nexport default componentMeta;\ntype Story = StoryObj<typeof componentMeta>;\n\nexport const Default: Story = {\n args: {},\n render: TextAreaDefault,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaDefaultSrc,\n },\n },\n },\n};\n\nexport const Resizable: Story = {\n args: {},\n render: TextAreaResizable,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaResizableSrc,\n },\n },\n },\n};\n\nexport const Optional: Story = {\n args: {},\n render: TextAreaOptional,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaOptionalSrc,\n },\n },\n },\n};\n\nexport const Error: Story = {\n args: {},\n render: TextAreaError,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaErrorSrc,\n },\n },\n },\n};\n\nexport const Disabled: Story = {\n args: {},\n render: TextAreaDisabled,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaDisabledSrc,\n },\n },\n },\n};\n\nexport const Fluid: Story = {\n args: {},\n render: TextAreaFluid,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaFluidSrc,\n },\n },\n },\n decorators: [\n (Story) => (\n <div className=\"n-w-full\">\n <Story />\n </div>\n ),\n ],\n};\n\nexport const Sizes: Story = {\n args: {},\n render: TextAreaSizes,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaSizesSrc,\n },\n },\n },\n};\n\nexport const InformationIcon: Story = {\n args: {},\n render: TextAreaInformationIcon,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaInformationIconSrc,\n },\n },\n },\n};\n"]}
1
+ {"version":3,"file":"text-area.stories.js","sourceRoot":"","sources":["../../../../src/text-area/stories/text-area.stories.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { type Meta, type StoryObj } from '@storybook/react-vite';\n\nimport { TextArea } from '../../index';\nimport {\n TextAreaDefault,\n TextAreaDefaultSrc,\n TextAreaDisabled,\n TextAreaDisabledSrc,\n TextAreaError,\n TextAreaErrorSrc,\n TextAreaFluid,\n TextAreaFluidSrc,\n TextAreaInformationIcon,\n TextAreaInformationIconSrc,\n TextAreaOptional,\n TextAreaOptionalSrc,\n TextAreaResizable,\n TextAreaResizableSrc,\n TextAreaSizes,\n TextAreaSizesSrc,\n} from '.';\n\nconst componentMeta: Meta<typeof TextArea> = {\n title: 'Components/TextArea',\n id: 'components-text-area',\n component: TextArea,\n tags: ['docsPage'],\n parameters: {\n controls: { disable: true },\n },\n decorators: [\n (Story) => (\n <div className=\"n-flex n-justify-center\">\n <Story />\n </div>\n ),\n ],\n};\n\nexport default componentMeta;\ntype Story = StoryObj<typeof componentMeta>;\n\nexport const Default: Story = {\n args: {},\n render: TextAreaDefault,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaDefaultSrc,\n },\n },\n },\n};\n\nexport const Resizable: Story = {\n args: {},\n render: TextAreaResizable,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaResizableSrc,\n },\n },\n },\n};\n\nexport const Optional: Story = {\n args: {},\n render: TextAreaOptional,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaOptionalSrc,\n },\n },\n },\n};\n\nexport const Error: Story = {\n args: {},\n render: TextAreaError,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaErrorSrc,\n },\n },\n },\n};\n\nexport const Disabled: Story = {\n args: {},\n render: TextAreaDisabled,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaDisabledSrc,\n },\n },\n },\n};\n\nexport const Fluid: Story = {\n args: {},\n render: TextAreaFluid,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaFluidSrc,\n },\n },\n },\n decorators: [\n (Story) => (\n <div className=\"n-w-full\">\n <Story />\n </div>\n ),\n ],\n};\n\nexport const Sizes: Story = {\n args: {},\n render: TextAreaSizes,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaSizesSrc,\n },\n },\n },\n};\n\nexport const InformationIcon: Story = {\n args: {},\n render: TextAreaInformationIcon,\n parameters: {\n docs: {\n source: {\n language: 'tsx',\n type: 'code',\n code: TextAreaInformationIconSrc,\n },\n },\n },\n};\n"]}
@@ -1,3 +1,14 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
1
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
13
  /**
3
14
  *
@@ -34,7 +45,8 @@ import { Typography } from '../typography';
34
45
  *
35
46
  *
36
47
  */
37
- export const TextInput = ({ label, isFluid, errorText, helpText, leadingElement, trailingElement, showRequiredOrOptionalLabel = false, moreInformationText, size = 'medium', placeholder, value, tooltipProps, htmlAttributes, isDisabled, isReadOnly, isRequired, onChange, className, style, isSkeletonLoading = false, skeletonProps, ref, }) => {
48
+ export const TextInput = (_a) => {
49
+ var { label, isFluid, errorText, helpText, leadingElement, trailingElement, showRequiredOrOptionalLabel = false, moreInformationText, size = 'medium', placeholder, value, tooltipProps, htmlAttributes, isDisabled, isReadOnly, isRequired, onChange, className, style, isSkeletonLoading = false, skeletonProps, ref } = _a, restProps = __rest(_a, ["label", "isFluid", "errorText", "helpText", "leadingElement", "trailingElement", "showRequiredOrOptionalLabel", "moreInformationText", "size", "placeholder", "value", "tooltipProps", "htmlAttributes", "isDisabled", "isReadOnly", "isRequired", "onChange", "className", "style", "isSkeletonLoading", "skeletonProps", "ref"]);
38
50
  const containerWrappingClasses = classNames(`ndl-text-input`, className, {
39
51
  'ndl-disabled': isDisabled,
40
52
  'ndl-has-error': errorText,
@@ -67,7 +79,7 @@ export const TextInput = ({ label, isFluid, errorText, helpText, leadingElement,
67
79
  'ndl-information-icon-large': size === 'large',
68
80
  'ndl-information-icon-small': size === 'small' || size === 'medium',
69
81
  });
70
- return (_jsxs("div", { className: containerWrappingClasses, style: style, children: [_jsxs("label", { className: labelWrappingClasses, children: [!hasEmptyLabelValue && (_jsx(Skeleton, Object.assign({ onBackground: "weak", shape: "rectangular" }, skeletonProps, { isLoading: isSkeletonLoading, children: _jsxs("div", { className: "ndl-label-text-wrapper", children: [_jsx(Typography, { variant: size === 'large' ? 'body-large' : 'body-medium', className: "ndl-label-text", children: label }), Boolean(moreInformationText) && (_jsxs(Tooltip, Object.assign({}, tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.root, { type: "simple", children: [_jsx(Tooltip.Trigger, Object.assign({}, tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.trigger, { className: informationIconClasses, hasButtonWrapper: true, children: _jsx("div", { tabIndex: 0, role: "button", "aria-label": "Information icon", children: _jsx(InformationCircleIconOutline, {}) }) })), _jsx(Tooltip.Content, Object.assign({}, tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.content, { children: moreInformationText }))] }))), showRequiredOrOptionalLabel && (_jsx(Typography, { variant: size === 'large' ? 'body-large' : 'body-medium', className: "ndl-form-item-optional", children: isRequired === true ? 'Required' : 'Optional' }))] }) }))), _jsx(Skeleton, Object.assign({ onBackground: "weak", shape: "rectangular" }, skeletonProps, { isLoading: isSkeletonLoading, children: _jsxs("div", { className: "ndl-input-wrapper", children: [leadingElement && (_jsx("div", { className: "ndl-element-leading ndl-element", children: leadingElement })), _jsx("input", Object.assign({ readOnly: isReadOnly, disabled: isDisabled, required: isRequired, value: value, placeholder: placeholder, type: "text", onChange: onChange }, combinedHtmlInputAttributes, { ref: ref })), trailingElement && (_jsx("div", { className: "ndl-element-trailing ndl-element", children: trailingElement }))] }) }))] }), Boolean(helpText) && !errorText && (_jsx(Skeleton, { onBackground: "weak", shape: "rectangular", isLoading: isSkeletonLoading, children: _jsx(Typography, { variant: size === 'large' ? 'body-medium' : 'body-small', className: "ndl-form-message", children: helpText }) })), Boolean(errorText) && (
82
+ return (_jsxs("div", { className: containerWrappingClasses, style: style, children: [_jsxs("label", { className: labelWrappingClasses, children: [!hasEmptyLabelValue && (_jsx(Skeleton, Object.assign({ onBackground: "weak", shape: "rectangular" }, skeletonProps, { isLoading: isSkeletonLoading, children: _jsxs("div", { className: "ndl-label-text-wrapper", children: [_jsx(Typography, { variant: size === 'large' ? 'body-large' : 'body-medium', className: "ndl-label-text", children: label }), Boolean(moreInformationText) && (_jsxs(Tooltip, Object.assign({}, tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.root, { type: "simple", children: [_jsx(Tooltip.Trigger, Object.assign({}, tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.trigger, { className: informationIconClasses, hasButtonWrapper: true, children: _jsx("div", { tabIndex: 0, role: "button", "aria-label": "Information icon", children: _jsx(InformationCircleIconOutline, {}) }) })), _jsx(Tooltip.Content, Object.assign({}, tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.content, { children: moreInformationText }))] }))), showRequiredOrOptionalLabel && (_jsx(Typography, { variant: size === 'large' ? 'body-large' : 'body-medium', className: "ndl-form-item-optional", children: isRequired === true ? 'Required' : 'Optional' }))] }) }))), _jsx(Skeleton, Object.assign({ onBackground: "weak", shape: "rectangular" }, skeletonProps, { isLoading: isSkeletonLoading, children: _jsxs("div", { className: "ndl-input-wrapper", children: [leadingElement && (_jsx("div", { className: "ndl-element-leading ndl-element", children: leadingElement })), _jsx("input", Object.assign({ readOnly: isReadOnly, disabled: isDisabled, required: isRequired, value: value, placeholder: placeholder, type: "text", onChange: onChange }, combinedHtmlInputAttributes, restProps, { ref: ref })), trailingElement && (_jsx("div", { className: "ndl-element-trailing ndl-element", children: trailingElement }))] }) }))] }), Boolean(helpText) && !errorText && (_jsx(Skeleton, { onBackground: "weak", shape: "rectangular", isLoading: isSkeletonLoading, children: _jsx(Typography, { variant: size === 'large' ? 'body-medium' : 'body-small', className: "ndl-form-message", children: helpText }) })), Boolean(errorText) && (
71
83
  // TODO v4: We might want to have a min width for the container for the messages to help skeleton loading.
72
84
  // Currently the message fills 100% of the width while the rest of the text input has a set width.
73
85
  _jsx(Skeleton, Object.assign({ onBackground: "weak", shape: "rectangular", width: "fit-content" }, skeletonProps, { isLoading: isSkeletonLoading, children: _jsxs("div", { className: "ndl-form-message", children: [_jsx("div", { className: "ndl-error-icon", children: _jsx(ExclamationCircleIconSolid, {}) }), _jsx(Typography, { className: "ndl-error-text", variant: size === 'large' ? 'body-medium' : 'body-small', children: errorText })] }) })))] }));
@@ -1 +1 @@
1
- {"version":3,"file":"TextInput.js","sourceRoot":"","sources":["../../../src/text-input/TextInput.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport classNames from 'classnames';\nimport {\n type InputHTMLAttributes,\n type ReactElement,\n type ReactNode,\n useMemo,\n} from 'react';\n\nimport { customLabelAndNoAriaLabelWarningMessage } from '../_common/messages';\nimport { type CommonProps, type TooltipObjectProps } from '../_common/types';\nimport { needleWarningMessage } from '../_common/utils';\nimport {\n ExclamationCircleIconSolid,\n InformationCircleIconOutline,\n} from '../icons';\nimport { Skeleton } from '../skeleton';\nimport { Tooltip } from '../tooltip';\nimport { Typography } from '../typography';\n\ntype TextInputProps = {\n /** Assistive text displayed below the input */\n helpText?: string | ReactNode;\n\n /** Error message displayed below the input. When provided, it overrides `helpText` and shows an error icon */\n errorText?: string | ReactNode;\n\n /** Leading element rendered inside the input */\n leadingElement?: ReactElement;\n\n /** Trailing element rendered inside the input */\n trailingElement?: ReactElement;\n\n /** Size of the input */\n size?: 'small' | 'medium' | 'large';\n\n /** Whether the input is read-only */\n isReadOnly?: boolean;\n\n /**\n * Whether to display the Required/Optional label next to the field label.\n * Shows Required if isRequired is true, otherwise shows Optional.\n * @default false\n */\n showRequiredOrOptionalLabel?: boolean;\n\n /** Whether the input is disabled */\n isDisabled?: boolean;\n\n /** Whether the input is required */\n isRequired?: boolean;\n\n /** The current value of the input */\n value?: React.ComponentPropsWithoutRef<'input'>['value'];\n\n /** Placeholder text displayed when the input is empty */\n placeholder?: React.ComponentPropsWithoutRef<'input'>['placeholder'];\n\n /** Callback function triggered when the input value changes */\n onChange?: React.ComponentPropsWithoutRef<'input'>['onChange'];\n\n /** Whether the input should take the full available width */\n isFluid?: boolean;\n\n /** Text displayed in the information tooltip shown next to the label */\n moreInformationText?: React.ReactNode;\n\n /** The label displayed above the input */\n label?: string | React.ReactNode;\n\n /** Props for the Tooltip component used by the information icon */\n tooltipProps?: TooltipObjectProps;\n\n /** Whether to render skeletons instead of content */\n isSkeletonLoading?: boolean;\n\n /** Additional props forwarded to the underlying Skeleton components */\n skeletonProps?: React.ComponentProps<typeof Skeleton>;\n};\n\n/**\n *\n *\n * TextInput Component\n *\n *\n */\n\nexport const TextInput = ({\n label,\n isFluid,\n errorText,\n helpText,\n leadingElement,\n trailingElement,\n showRequiredOrOptionalLabel = false,\n moreInformationText,\n size = 'medium',\n placeholder,\n value,\n tooltipProps,\n htmlAttributes,\n isDisabled,\n isReadOnly,\n isRequired,\n onChange,\n className,\n style,\n isSkeletonLoading = false,\n skeletonProps,\n ref,\n}: CommonProps<'input', TextInputProps>) => {\n const containerWrappingClasses = classNames(`ndl-text-input`, className, {\n 'ndl-disabled': isDisabled,\n 'ndl-has-error': errorText,\n 'ndl-has-icon': leadingElement || trailingElement || errorText,\n 'ndl-has-leading-icon': leadingElement,\n 'ndl-has-trailing-icon': trailingElement || errorText,\n 'ndl-large': size === 'large',\n 'ndl-medium': size === 'medium',\n 'ndl-read-only': isReadOnly,\n 'ndl-small': size === 'small',\n });\n\n const hasEmptyLabelValue =\n label === undefined || label === null || label === '';\n\n const labelWrappingClasses = classNames('ndl-form-item-label', {\n 'ndl-fluid': isFluid,\n 'ndl-form-item-no-label': hasEmptyLabelValue,\n });\n\n const combinedHtmlInputAttributes: InputHTMLAttributes<HTMLInputElement> = {\n ...htmlAttributes,\n className: classNames('ndl-input', htmlAttributes?.className),\n };\n const ariaLabel = combinedHtmlInputAttributes['aria-label'];\n const isCustomLabel = Boolean(label) && typeof label !== 'string';\n const hasCustomLabelAndNoAriaLabel =\n isCustomLabel && (ariaLabel === undefined || ariaLabel === '');\n\n useMemo(() => {\n if (!label && !ariaLabel) {\n needleWarningMessage(\n 'A TextInput without a label does not have an aria label, be sure to include an aria label for screen readers. Link: https://dequeuniversity.com/rules/axe/4.2/label?application=axeAPI',\n );\n }\n\n if (hasCustomLabelAndNoAriaLabel) {\n needleWarningMessage(customLabelAndNoAriaLabelWarningMessage);\n }\n }, [label, ariaLabel, hasCustomLabelAndNoAriaLabel]);\n\n const informationIconClasses = classNames({\n 'ndl-information-icon-large': size === 'large',\n 'ndl-information-icon-small': size === 'small' || size === 'medium',\n });\n\n return (\n <div className={containerWrappingClasses} style={style}>\n {/* We enable implicit label wrapping */}\n {/* Source: https://dequeuniversity.com/rules/axe/4.2/label?application=axeAPI */}\n <label className={labelWrappingClasses}>\n {!hasEmptyLabelValue && (\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-label-text-wrapper\">\n <Typography\n variant={size === 'large' ? 'body-large' : 'body-medium'}\n className=\"ndl-label-text\"\n >\n {label}\n </Typography>\n {Boolean(moreInformationText) && (\n <Tooltip {...tooltipProps?.root} type=\"simple\">\n <Tooltip.Trigger\n {...tooltipProps?.trigger}\n className={informationIconClasses}\n hasButtonWrapper\n >\n <div\n tabIndex={0}\n role=\"button\"\n aria-label=\"Information icon\"\n >\n <InformationCircleIconOutline />\n </div>\n </Tooltip.Trigger>\n <Tooltip.Content {...tooltipProps?.content}>\n {moreInformationText}\n </Tooltip.Content>\n </Tooltip>\n )}\n {showRequiredOrOptionalLabel && (\n <Typography\n variant={size === 'large' ? 'body-large' : 'body-medium'}\n className=\"ndl-form-item-optional\"\n >\n {isRequired === true ? 'Required' : 'Optional'}\n </Typography>\n )}\n </div>\n </Skeleton>\n )}\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-input-wrapper\">\n {leadingElement && (\n <div className=\"ndl-element-leading ndl-element\">\n {leadingElement}\n </div>\n )}\n <input\n readOnly={isReadOnly}\n disabled={isDisabled}\n required={isRequired}\n value={value}\n placeholder={placeholder}\n type=\"text\"\n onChange={onChange}\n {...combinedHtmlInputAttributes}\n ref={ref}\n />\n {trailingElement && (\n <div className=\"ndl-element-trailing ndl-element\">\n {trailingElement}\n </div>\n )}\n </div>\n </Skeleton>\n </label>\n {Boolean(helpText) && !errorText && (\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n isLoading={isSkeletonLoading}\n >\n <Typography\n variant={size === 'large' ? 'body-medium' : 'body-small'}\n className=\"ndl-form-message\"\n >\n {helpText}\n </Typography>\n </Skeleton>\n )}\n {Boolean(errorText) && (\n // TODO v4: We might want to have a min width for the container for the messages to help skeleton loading.\n // Currently the message fills 100% of the width while the rest of the text input has a set width.\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n width=\"fit-content\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-form-message\">\n <div className=\"ndl-error-icon\">\n <ExclamationCircleIconSolid />\n </div>\n <Typography\n className=\"ndl-error-text\"\n variant={size === 'large' ? 'body-medium' : 'body-small'}\n >\n {errorText}\n </Typography>\n </div>\n </Skeleton>\n )}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"TextInput.js","sourceRoot":"","sources":["../../../src/text-input/TextInput.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport classNames from 'classnames';\nimport {\n type InputHTMLAttributes,\n type ReactElement,\n type ReactNode,\n useMemo,\n} from 'react';\n\nimport { customLabelAndNoAriaLabelWarningMessage } from '../_common/messages';\nimport { type CommonProps, type TooltipObjectProps } from '../_common/types';\nimport { needleWarningMessage } from '../_common/utils';\nimport {\n ExclamationCircleIconSolid,\n InformationCircleIconOutline,\n} from '../icons';\nimport { Skeleton } from '../skeleton';\nimport { Tooltip } from '../tooltip';\nimport { Typography } from '../typography';\n\ntype TextInputProps = {\n /** Assistive text displayed below the input */\n helpText?: string | ReactNode;\n\n /** Error message displayed below the input. When provided, it overrides `helpText` and shows an error icon */\n errorText?: string | ReactNode;\n\n /** Leading element rendered inside the input */\n leadingElement?: ReactElement;\n\n /** Trailing element rendered inside the input */\n trailingElement?: ReactElement;\n\n /** Size of the input */\n size?: 'small' | 'medium' | 'large';\n\n /** Whether the input is read-only */\n isReadOnly?: boolean;\n\n /**\n * Whether to display the Required/Optional label next to the field label.\n * Shows Required if isRequired is true, otherwise shows Optional.\n * @default false\n */\n showRequiredOrOptionalLabel?: boolean;\n\n /** Whether the input is disabled */\n isDisabled?: boolean;\n\n /** Whether the input is required */\n isRequired?: boolean;\n\n /** The current value of the input */\n value?: React.ComponentPropsWithoutRef<'input'>['value'];\n\n /** Placeholder text displayed when the input is empty */\n placeholder?: React.ComponentPropsWithoutRef<'input'>['placeholder'];\n\n /** Callback function triggered when the input value changes */\n onChange?: React.ComponentPropsWithoutRef<'input'>['onChange'];\n\n /** Whether the input should take the full available width */\n isFluid?: boolean;\n\n /** Text displayed in the information tooltip shown next to the label */\n moreInformationText?: React.ReactNode;\n\n /** The label displayed above the input */\n label?: string | React.ReactNode;\n\n /** Props for the Tooltip component used by the information icon */\n tooltipProps?: TooltipObjectProps;\n\n /** Whether to render skeletons instead of content */\n isSkeletonLoading?: boolean;\n\n /** Additional props forwarded to the underlying Skeleton components */\n skeletonProps?: React.ComponentProps<typeof Skeleton>;\n};\n\n/**\n *\n *\n * TextInput Component\n *\n *\n */\n\nexport const TextInput = ({\n label,\n isFluid,\n errorText,\n helpText,\n leadingElement,\n trailingElement,\n showRequiredOrOptionalLabel = false,\n moreInformationText,\n size = 'medium',\n placeholder,\n value,\n tooltipProps,\n htmlAttributes,\n isDisabled,\n isReadOnly,\n isRequired,\n onChange,\n className,\n style,\n isSkeletonLoading = false,\n skeletonProps,\n ref,\n ...restProps\n}: CommonProps<'input', TextInputProps>) => {\n const containerWrappingClasses = classNames(`ndl-text-input`, className, {\n 'ndl-disabled': isDisabled,\n 'ndl-has-error': errorText,\n 'ndl-has-icon': leadingElement || trailingElement || errorText,\n 'ndl-has-leading-icon': leadingElement,\n 'ndl-has-trailing-icon': trailingElement || errorText,\n 'ndl-large': size === 'large',\n 'ndl-medium': size === 'medium',\n 'ndl-read-only': isReadOnly,\n 'ndl-small': size === 'small',\n });\n\n const hasEmptyLabelValue =\n label === undefined || label === null || label === '';\n\n const labelWrappingClasses = classNames('ndl-form-item-label', {\n 'ndl-fluid': isFluid,\n 'ndl-form-item-no-label': hasEmptyLabelValue,\n });\n\n const combinedHtmlInputAttributes: InputHTMLAttributes<HTMLInputElement> = {\n ...htmlAttributes,\n className: classNames('ndl-input', htmlAttributes?.className),\n };\n const ariaLabel = combinedHtmlInputAttributes['aria-label'];\n const isCustomLabel = Boolean(label) && typeof label !== 'string';\n const hasCustomLabelAndNoAriaLabel =\n isCustomLabel && (ariaLabel === undefined || ariaLabel === '');\n\n useMemo(() => {\n if (!label && !ariaLabel) {\n needleWarningMessage(\n 'A TextInput without a label does not have an aria label, be sure to include an aria label for screen readers. Link: https://dequeuniversity.com/rules/axe/4.2/label?application=axeAPI',\n );\n }\n\n if (hasCustomLabelAndNoAriaLabel) {\n needleWarningMessage(customLabelAndNoAriaLabelWarningMessage);\n }\n }, [label, ariaLabel, hasCustomLabelAndNoAriaLabel]);\n\n const informationIconClasses = classNames({\n 'ndl-information-icon-large': size === 'large',\n 'ndl-information-icon-small': size === 'small' || size === 'medium',\n });\n\n return (\n <div className={containerWrappingClasses} style={style}>\n {/* We enable implicit label wrapping */}\n {/* Source: https://dequeuniversity.com/rules/axe/4.2/label?application=axeAPI */}\n <label className={labelWrappingClasses}>\n {!hasEmptyLabelValue && (\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-label-text-wrapper\">\n <Typography\n variant={size === 'large' ? 'body-large' : 'body-medium'}\n className=\"ndl-label-text\"\n >\n {label}\n </Typography>\n {Boolean(moreInformationText) && (\n <Tooltip {...tooltipProps?.root} type=\"simple\">\n <Tooltip.Trigger\n {...tooltipProps?.trigger}\n className={informationIconClasses}\n hasButtonWrapper\n >\n <div\n tabIndex={0}\n role=\"button\"\n aria-label=\"Information icon\"\n >\n <InformationCircleIconOutline />\n </div>\n </Tooltip.Trigger>\n <Tooltip.Content {...tooltipProps?.content}>\n {moreInformationText}\n </Tooltip.Content>\n </Tooltip>\n )}\n {showRequiredOrOptionalLabel && (\n <Typography\n variant={size === 'large' ? 'body-large' : 'body-medium'}\n className=\"ndl-form-item-optional\"\n >\n {isRequired === true ? 'Required' : 'Optional'}\n </Typography>\n )}\n </div>\n </Skeleton>\n )}\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-input-wrapper\">\n {leadingElement && (\n <div className=\"ndl-element-leading ndl-element\">\n {leadingElement}\n </div>\n )}\n <input\n readOnly={isReadOnly}\n disabled={isDisabled}\n required={isRequired}\n value={value}\n placeholder={placeholder}\n type=\"text\"\n onChange={onChange}\n {...combinedHtmlInputAttributes}\n {...restProps}\n ref={ref}\n />\n {trailingElement && (\n <div className=\"ndl-element-trailing ndl-element\">\n {trailingElement}\n </div>\n )}\n </div>\n </Skeleton>\n </label>\n {Boolean(helpText) && !errorText && (\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n isLoading={isSkeletonLoading}\n >\n <Typography\n variant={size === 'large' ? 'body-medium' : 'body-small'}\n className=\"ndl-form-message\"\n >\n {helpText}\n </Typography>\n </Skeleton>\n )}\n {Boolean(errorText) && (\n // TODO v4: We might want to have a min width for the container for the messages to help skeleton loading.\n // Currently the message fills 100% of the width while the rest of the text input has a set width.\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n width=\"fit-content\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-form-message\">\n <div className=\"ndl-error-icon\">\n <ExclamationCircleIconSolid />\n </div>\n <Typography\n className=\"ndl-error-text\"\n variant={size === 'large' ? 'body-medium' : 'body-small'}\n >\n {errorText}\n </Typography>\n </div>\n </Skeleton>\n )}\n </div>\n );\n};\n"]}
@@ -1,3 +1,14 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
1
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
13
  /**
3
14
  *
@@ -21,7 +32,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
32
  */
22
33
  import classNames from 'classnames';
23
34
  import { ArrowUpRightIconOutline, ChevronRightIconOutline } from '../icons';
24
- export const TextLink = ({ children, href, type = 'internal', as, className, target, style, htmlAttributes, ref, }) => {
35
+ export const TextLink = (_a) => {
36
+ var { children, href, type = 'internal', as, className, target, style, htmlAttributes, ref } = _a, restProps = __rest(_a, ["children", "href", "type", "as", "className", "target", "style", "htmlAttributes", "ref"]);
25
37
  const propsTarget = target || type === 'external' ? '_blank' : '';
26
38
  const Component = as || 'a';
27
39
  const classes = classNames('ndl-text-link', className, {
@@ -29,6 +41,6 @@ export const TextLink = ({ children, href, type = 'internal', as, className, tar
29
41
  'ndl-internal-icon': type === 'internal-icon',
30
42
  'ndl-internal-underline': type === 'internal-underline',
31
43
  });
32
- return (_jsxs(Component, Object.assign({ className: classes, href: href, ref: ref, style: style }, (propsTarget && { target: propsTarget }), htmlAttributes, { children: [children, type === 'external' && (_jsx(ArrowUpRightIconOutline, { className: "ndl-external-link-icon" })), type === 'internal-icon' && (_jsx(ChevronRightIconOutline, { className: "ndl-external-link-icon" }))] })));
44
+ return (_jsxs(Component, Object.assign({ className: classes, href: href, ref: ref, style: style }, (propsTarget && { target: propsTarget }), restProps, htmlAttributes, { children: [children, type === 'external' && (_jsx(ArrowUpRightIconOutline, { className: "ndl-external-link-icon" })), type === 'internal-icon' && (_jsx(ChevronRightIconOutline, { className: "ndl-external-link-icon" }))] })));
33
45
  };
34
46
  //# sourceMappingURL=TextLink.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextLink.js","sourceRoot":"","sources":["../../../src/text-link/TextLink.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,UAAU,MAAM,YAAY,CAAC;AAIpC,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAgC5E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAoC,EAC1D,QAAQ,EACR,IAAI,EACJ,IAAI,GAAG,UAAU,EACjB,EAAE,EACF,SAAS,EACT,MAAM,EACN,KAAK,EACL,cAAc,EACd,GAAG,GACsC,EAAE,EAAE;IAC7C,MAAM,WAAW,GAAG,MAAM,IAAI,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAElE,MAAM,SAAS,GAAsB,EAAE,IAAI,GAAG,CAAC;IAE/C,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,EAAE,SAAS,EAAE;QACrD,mBAAmB,EAAE,IAAI,KAAK,UAAU;QACxC,mBAAmB,EAAE,IAAI,KAAK,eAAe;QAC7C,wBAAwB,EAAE,IAAI,KAAK,oBAAoB;KACxD,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,SAAS,kBACR,SAAS,EAAE,OAAO,EAClB,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,IACR,CAAC,WAAW,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EACxC,cAAc,eAEjB,QAAQ,EACR,IAAI,KAAK,UAAU,IAAI,CACtB,KAAC,uBAAuB,IAAC,SAAS,EAAC,wBAAwB,GAAG,CAC/D,EACA,IAAI,KAAK,eAAe,IAAI,CAC3B,KAAC,uBAAuB,IAAC,SAAS,EAAC,wBAAwB,GAAG,CAC/D,KACS,CACb,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport classNames from 'classnames';\nimport type React from 'react';\n\nimport { type PolymorphicCommonProps } from '../_common/types';\nimport { ArrowUpRightIconOutline, ChevronRightIconOutline } from '../icons';\n\ntype TextLinkType =\n | 'internal'\n | 'internal-underline'\n | 'internal-icon'\n | 'external';\n\ntype TextLinkProps = {\n /** The content displayed inside the link */\n children: React.ReactNode;\n\n /** The URL the link points to */\n href?: string;\n\n /**\n * The type of the text link\n * - 'internal': a link to another page within the application\n * - 'internal-underline': a link to another page within the application with an underline and support for text color\n * - 'internal-icon': a link to another page within the application with an icon\n * - 'external': a link to an external website\n * @default 'internal'\n */\n type?: TextLinkType;\n\n /** Specifies where to open the linked document. If omitted and `type` is `\"external\"` it defaults to `\"_blank\"`. */\n target?: string;\n\n /** Additional class name */\n className?: string;\n};\n\nexport const TextLink = <T extends React.ElementType = 'a'>({\n children,\n href,\n type = 'internal',\n as,\n className,\n target,\n style,\n htmlAttributes,\n ref,\n}: PolymorphicCommonProps<T, TextLinkProps>) => {\n const propsTarget = target || type === 'external' ? '_blank' : '';\n\n const Component: React.ElementType = as || 'a';\n\n const classes = classNames('ndl-text-link', className, {\n 'ndl-external-link': type === 'external',\n 'ndl-internal-icon': type === 'internal-icon',\n 'ndl-internal-underline': type === 'internal-underline',\n });\n\n return (\n <Component\n className={classes}\n href={href}\n ref={ref}\n style={style}\n {...(propsTarget && { target: propsTarget })}\n {...htmlAttributes}\n >\n {children}\n {type === 'external' && (\n <ArrowUpRightIconOutline className=\"ndl-external-link-icon\" />\n )}\n {type === 'internal-icon' && (\n <ChevronRightIconOutline className=\"ndl-external-link-icon\" />\n )}\n </Component>\n );\n};\n"]}
1
+ {"version":3,"file":"TextLink.js","sourceRoot":"","sources":["../../../src/text-link/TextLink.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,UAAU,MAAM,YAAY,CAAC;AAIpC,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAgC5E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAoC,EAWjB,EAAE,EAAE;QAXa,EAC1D,QAAQ,EACR,IAAI,EACJ,IAAI,GAAG,UAAU,EACjB,EAAE,EACF,SAAS,EACT,MAAM,EACN,KAAK,EACL,cAAc,EACd,GAAG,OAEsC,EADtC,SAAS,cAV8C,2FAW3D,CADa;IAEZ,MAAM,WAAW,GAAG,MAAM,IAAI,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAElE,MAAM,SAAS,GAAsB,EAAE,IAAI,GAAG,CAAC;IAE/C,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,EAAE,SAAS,EAAE;QACrD,mBAAmB,EAAE,IAAI,KAAK,UAAU;QACxC,mBAAmB,EAAE,IAAI,KAAK,eAAe;QAC7C,wBAAwB,EAAE,IAAI,KAAK,oBAAoB;KACxD,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,SAAS,kBACR,SAAS,EAAE,OAAO,EAClB,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,IACR,CAAC,WAAW,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EACxC,SAAS,EACT,cAAc,eAEjB,QAAQ,EACR,IAAI,KAAK,UAAU,IAAI,CACtB,KAAC,uBAAuB,IAAC,SAAS,EAAC,wBAAwB,GAAG,CAC/D,EACA,IAAI,KAAK,eAAe,IAAI,CAC3B,KAAC,uBAAuB,IAAC,SAAS,EAAC,wBAAwB,GAAG,CAC/D,KACS,CACb,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport classNames from 'classnames';\nimport type React from 'react';\n\nimport { type PolymorphicCommonProps } from '../_common/types';\nimport { ArrowUpRightIconOutline, ChevronRightIconOutline } from '../icons';\n\ntype TextLinkType =\n | 'internal'\n | 'internal-underline'\n | 'internal-icon'\n | 'external';\n\ntype TextLinkProps = {\n /** The content displayed inside the link */\n children: React.ReactNode;\n\n /** The URL the link points to */\n href?: string;\n\n /**\n * The type of the text link\n * - 'internal': a link to another page within the application\n * - 'internal-underline': a link to another page within the application with an underline and support for text color\n * - 'internal-icon': a link to another page within the application with an icon\n * - 'external': a link to an external website\n * @default 'internal'\n */\n type?: TextLinkType;\n\n /** Specifies where to open the linked document. If omitted and `type` is `\"external\"` it defaults to `\"_blank\"`. */\n target?: string;\n\n /** Additional class name */\n className?: string;\n};\n\nexport const TextLink = <T extends React.ElementType = 'a'>({\n children,\n href,\n type = 'internal',\n as,\n className,\n target,\n style,\n htmlAttributes,\n ref,\n ...restProps\n}: PolymorphicCommonProps<T, TextLinkProps>) => {\n const propsTarget = target || type === 'external' ? '_blank' : '';\n\n const Component: React.ElementType = as || 'a';\n\n const classes = classNames('ndl-text-link', className, {\n 'ndl-external-link': type === 'external',\n 'ndl-internal-icon': type === 'internal-icon',\n 'ndl-internal-underline': type === 'internal-underline',\n });\n\n return (\n <Component\n className={classes}\n href={href}\n ref={ref}\n style={style}\n {...(propsTarget && { target: propsTarget })}\n {...restProps}\n {...htmlAttributes}\n >\n {children}\n {type === 'external' && (\n <ArrowUpRightIconOutline className=\"ndl-external-link-icon\" />\n )}\n {type === 'internal-icon' && (\n <ChevronRightIconOutline className=\"ndl-external-link-icon\" />\n )}\n </Component>\n );\n};\n"]}
@@ -81,8 +81,9 @@ export const TextOverflow = (_a) => {
81
81
  return characterTruncatedContent !== null;
82
82
  }
83
83
  const element = textElementRef.current;
84
- if (element === null)
84
+ if (element === null) {
85
85
  return false;
86
+ }
86
87
  // Regular multiline truncation
87
88
  if (lines !== undefined && lines > 1) {
88
89
  return element.scrollHeight > element.clientHeight;
@@ -1 +1 @@
1
- {"version":3,"file":"TextOverflow.js","sourceRoot":"","sources":["../../../src/text-overflow/TextOverflow.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport classNames from 'classnames';\nimport type React from 'react';\nimport { useCallback, useMemo, useRef, useState } from 'react';\n\nimport type {\n PolymorphicCommonProps,\n TooltipObjectProps,\n} from '../_common/types';\nimport { TextLink } from '../text-link';\nimport { Tooltip } from '../tooltip';\nimport { Typography } from '../typography';\nimport { COLLAPSE_BUTTON_TEXT, ELLIPSIS_CHAR } from './constants';\nimport {\n getTextContent,\n truncateReactNodeByCharacters,\n} from './text-overflow-utils';\nimport { useTruncateWithButton } from './use-truncate-with-button';\n\ntype TextOverflowProps = {\n /** The content to be truncated. Can be text, Typography components, or complex JSX. */\n children: React.ReactNode;\n\n /**\n * Controls the expand/collapse UI.\n * - string: show expand/collapse button with custom text (e.g., \"View more\")\n * - undefined: content is not expandable, only truncated with ellipsis\n * @default undefined\n */\n expandButton?: 'view-more' | 'ellipsis';\n\n /**\n * Maximum number of characters to display. Takes precedence over line-based truncation when set.\n */\n maxCharacters?: number;\n\n /**\n * Number of lines to show before truncation.\n * Uses CSS line-clamp for non-expandable content.\n * Uses DOM measurement for expandable content.\n * **Note**: Ignored if `maxCharacters` is explicitly set to a custom value.\n */\n lines?: number;\n\n /**\n * Whether to show tooltip with full text on hover when content is truncated.\n * @default true\n */\n shouldShowTooltip?: boolean;\n\n /** Props to pass to tooltip component */\n tooltipProps?: TooltipObjectProps;\n\n /** Callback function called when content is expanded or collapsed */\n onExpandedToggle?: (isExpanded: boolean) => void;\n\n /**\n * The typography variant to use for the text.\n * @default 'body-medium'\n */\n typographyVariant?: React.ComponentProps<typeof Typography>['variant'];\n};\n\nconst expandButtonTexts = {\n ellipsis: ELLIPSIS_CHAR,\n 'view-more': 'View more',\n};\n\nexport const TextOverflow = <T extends React.ElementType = 'div'>({\n as,\n children,\n className,\n htmlAttributes,\n lines,\n tooltipProps,\n onExpandedToggle,\n expandButton,\n maxCharacters,\n shouldShowTooltip = true,\n typographyVariant = 'body-medium',\n ref,\n ...restProps\n}: PolymorphicCommonProps<T, TextOverflowProps>) => {\n const contentRef = useRef<HTMLDivElement>(null);\n const textElementRef = useRef<HTMLSpanElement>(null);\n const [isTooltipOpen, setIsTooltipOpen] = useState(false);\n\n // Use truncate with button hook when expandButton is provided\n const shouldUseTruncateWithButton = expandButton !== undefined;\n const truncateWithButtonResult = useTruncateWithButton({\n button: expandButtonTexts[expandButton!] || 'View more',\n buttonType: expandButton,\n closeTooltip: () => setIsTooltipOpen(false),\n content: children,\n // Disable expensive calculations when no expand button is needed\n isDisabled: !shouldUseTruncateWithButton,\n lineClamp: lines ?? 1,\n maxCharacters,\n onExpandedToggle,\n });\n\n // Handle character-based truncation when no expand button is used\n const characterTruncatedContent = useMemo(() => {\n if (maxCharacters !== undefined && expandButton === undefined) {\n const result = truncateReactNodeByCharacters(children, maxCharacters);\n return result.needsTruncation ? result.truncatedContent : null;\n }\n return null;\n }, [maxCharacters, expandButton, children]);\n\n // Memoize text content extraction to avoid repeated traversals\n const textContent = useMemo(() => getTextContent(children), [children]);\n\n // Memoize tooltip truncation detection logic\n const checkTruncationForTooltip = useCallback(() => {\n if (shouldUseTruncateWithButton) {\n return truncateWithButtonResult.isTruncated;\n }\n\n // Character based truncation\n if (maxCharacters !== undefined) {\n return characterTruncatedContent !== null;\n }\n\n const element = textElementRef.current;\n if (element === null) return false;\n\n // Regular multiline truncation\n if (lines !== undefined && lines > 1) {\n return element.scrollHeight > element.clientHeight;\n }\n\n // Regular single line truncation\n return element.scrollWidth > element.clientWidth;\n }, [\n shouldUseTruncateWithButton,\n truncateWithButtonResult.isTruncated,\n maxCharacters,\n characterTruncatedContent,\n lines,\n ]);\n\n const renderContent = () => {\n const isMultiline = typeof lines === 'number' && lines > 1;\n\n const textStyle = {\n '--ndl-line-clamp': isMultiline ? lines.toString() : undefined,\n } as React.CSSProperties;\n\n const textClasses = classNames({\n 'ndl-text-overflow-multi-line': isMultiline,\n 'ndl-text-overflow-single-line':\n !isMultiline && maxCharacters === undefined,\n });\n\n if (shouldUseTruncateWithButton) {\n return (\n <div ref={truncateWithButtonResult.containerRef}>\n <div\n className={truncateWithButtonResult.isExpanded ? '' : textClasses}\n style={textStyle}\n >\n {truncateWithButtonResult.contentToRender}\n {truncateWithButtonResult.isTruncated && (\n <TextLink\n as=\"button\"\n className={classNames('ndl-text-overflow-toggle', {\n 'ndl-text-overflow-toggle-margin-left':\n expandButton !== 'ellipsis' ||\n truncateWithButtonResult.isExpanded,\n })}\n htmlAttributes={{\n onClick: truncateWithButtonResult.toggleExpand,\n }}\n >\n {truncateWithButtonResult.isExpanded\n ? COLLAPSE_BUTTON_TEXT\n : expandButtonTexts[expandButton!]}\n </TextLink>\n )}\n </div>\n <div\n ref={truncateWithButtonResult.measureRef}\n style={{\n position: 'absolute',\n top: '-9999px',\n visibility: 'hidden',\n }}\n />\n </div>\n );\n }\n\n return (\n <span ref={textElementRef} className={textClasses} style={textStyle}>\n {characterTruncatedContent ?? children}\n </span>\n );\n };\n\n const isTooltipDisabled =\n !shouldShowTooltip ||\n (expandButton !== undefined && truncateWithButtonResult.isExpanded);\n\n return (\n <Tooltip\n {...tooltipProps?.root}\n type=\"simple\"\n isDisabled={isTooltipDisabled}\n isOpen={isTooltipOpen}\n onOpenChange={(open) => {\n if (open) {\n setIsTooltipOpen(checkTruncationForTooltip());\n } else {\n setIsTooltipOpen(false);\n }\n }}\n >\n <Tooltip.Trigger {...tooltipProps?.trigger} hasButtonWrapper>\n <Typography\n as={as ?? 'div'}\n ref={ref}\n variant={typographyVariant}\n className={classNames('ndl-text-overflow', className)}\n htmlAttributes={{\n ...htmlAttributes,\n }}\n {...restProps}\n {...(!isTooltipDisabled &&\n expandButton === undefined && {\n tabIndex: 0,\n })}\n >\n <div className=\"ndl-text-overflow-content\" ref={contentRef}>\n {renderContent()}\n </div>\n </Typography>\n </Tooltip.Trigger>\n <Tooltip.Content\n className={classNames(\n 'ndl-text-overflow-tooltip-content',\n tooltipProps?.content?.className,\n )}\n {...tooltipProps?.content}\n >\n {textContent}\n </Tooltip.Content>\n </Tooltip>\n );\n};\n"]}
1
+ {"version":3,"file":"TextOverflow.js","sourceRoot":"","sources":["../../../src/text-overflow/TextOverflow.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport classNames from 'classnames';\nimport type React from 'react';\nimport { useCallback, useMemo, useRef, useState } from 'react';\n\nimport type {\n PolymorphicCommonProps,\n TooltipObjectProps,\n} from '../_common/types';\nimport { TextLink } from '../text-link';\nimport { Tooltip } from '../tooltip';\nimport { Typography } from '../typography';\nimport { COLLAPSE_BUTTON_TEXT, ELLIPSIS_CHAR } from './constants';\nimport {\n getTextContent,\n truncateReactNodeByCharacters,\n} from './text-overflow-utils';\nimport { useTruncateWithButton } from './use-truncate-with-button';\n\ntype TextOverflowProps = {\n /** The content to be truncated. Can be text, Typography components, or complex JSX. */\n children: React.ReactNode;\n\n /**\n * Controls the expand/collapse UI.\n * - string: show expand/collapse button with custom text (e.g., \"View more\")\n * - undefined: content is not expandable, only truncated with ellipsis\n * @default undefined\n */\n expandButton?: 'view-more' | 'ellipsis';\n\n /**\n * Maximum number of characters to display. Takes precedence over line-based truncation when set.\n */\n maxCharacters?: number;\n\n /**\n * Number of lines to show before truncation.\n * Uses CSS line-clamp for non-expandable content.\n * Uses DOM measurement for expandable content.\n * **Note**: Ignored if `maxCharacters` is explicitly set to a custom value.\n */\n lines?: number;\n\n /**\n * Whether to show tooltip with full text on hover when content is truncated.\n * @default true\n */\n shouldShowTooltip?: boolean;\n\n /** Props to pass to tooltip component */\n tooltipProps?: TooltipObjectProps;\n\n /** Callback function called when content is expanded or collapsed */\n onExpandedToggle?: (isExpanded: boolean) => void;\n\n /**\n * The typography variant to use for the text.\n * @default 'body-medium'\n */\n typographyVariant?: React.ComponentProps<typeof Typography>['variant'];\n};\n\nconst expandButtonTexts = {\n ellipsis: ELLIPSIS_CHAR,\n 'view-more': 'View more',\n};\n\nexport const TextOverflow = <T extends React.ElementType = 'div'>({\n as,\n children,\n className,\n htmlAttributes,\n lines,\n tooltipProps,\n onExpandedToggle,\n expandButton,\n maxCharacters,\n shouldShowTooltip = true,\n typographyVariant = 'body-medium',\n ref,\n ...restProps\n}: PolymorphicCommonProps<T, TextOverflowProps>) => {\n const contentRef = useRef<HTMLDivElement>(null);\n const textElementRef = useRef<HTMLSpanElement>(null);\n const [isTooltipOpen, setIsTooltipOpen] = useState(false);\n\n // Use truncate with button hook when expandButton is provided\n const shouldUseTruncateWithButton = expandButton !== undefined;\n const truncateWithButtonResult = useTruncateWithButton({\n button: expandButtonTexts[expandButton!] || 'View more',\n buttonType: expandButton,\n closeTooltip: () => setIsTooltipOpen(false),\n content: children,\n // Disable expensive calculations when no expand button is needed\n isDisabled: !shouldUseTruncateWithButton,\n lineClamp: lines ?? 1,\n maxCharacters,\n onExpandedToggle,\n });\n\n // Handle character-based truncation when no expand button is used\n const characterTruncatedContent = useMemo(() => {\n if (maxCharacters !== undefined && expandButton === undefined) {\n const result = truncateReactNodeByCharacters(children, maxCharacters);\n return result.needsTruncation ? result.truncatedContent : null;\n }\n return null;\n }, [maxCharacters, expandButton, children]);\n\n // Memoize text content extraction to avoid repeated traversals\n const textContent = useMemo(() => getTextContent(children), [children]);\n\n // Memoize tooltip truncation detection logic\n const checkTruncationForTooltip = useCallback(() => {\n if (shouldUseTruncateWithButton) {\n return truncateWithButtonResult.isTruncated;\n }\n\n // Character based truncation\n if (maxCharacters !== undefined) {\n return characterTruncatedContent !== null;\n }\n\n const element = textElementRef.current;\n if (element === null) {\n return false;\n }\n\n // Regular multiline truncation\n if (lines !== undefined && lines > 1) {\n return element.scrollHeight > element.clientHeight;\n }\n\n // Regular single line truncation\n return element.scrollWidth > element.clientWidth;\n }, [\n shouldUseTruncateWithButton,\n truncateWithButtonResult.isTruncated,\n maxCharacters,\n characterTruncatedContent,\n lines,\n ]);\n\n const renderContent = () => {\n const isMultiline = typeof lines === 'number' && lines > 1;\n\n const textStyle = {\n '--ndl-line-clamp': isMultiline ? lines.toString() : undefined,\n } as React.CSSProperties;\n\n const textClasses = classNames({\n 'ndl-text-overflow-multi-line': isMultiline,\n 'ndl-text-overflow-single-line':\n !isMultiline && maxCharacters === undefined,\n });\n\n if (shouldUseTruncateWithButton) {\n return (\n <div ref={truncateWithButtonResult.containerRef}>\n <div\n className={truncateWithButtonResult.isExpanded ? '' : textClasses}\n style={textStyle}\n >\n {truncateWithButtonResult.contentToRender}\n {truncateWithButtonResult.isTruncated && (\n <TextLink\n as=\"button\"\n className={classNames('ndl-text-overflow-toggle', {\n 'ndl-text-overflow-toggle-margin-left':\n expandButton !== 'ellipsis' ||\n truncateWithButtonResult.isExpanded,\n })}\n htmlAttributes={{\n onClick: truncateWithButtonResult.toggleExpand,\n }}\n >\n {truncateWithButtonResult.isExpanded\n ? COLLAPSE_BUTTON_TEXT\n : expandButtonTexts[expandButton!]}\n </TextLink>\n )}\n </div>\n <div\n ref={truncateWithButtonResult.measureRef}\n style={{\n position: 'absolute',\n top: '-9999px',\n visibility: 'hidden',\n }}\n />\n </div>\n );\n }\n\n return (\n <span ref={textElementRef} className={textClasses} style={textStyle}>\n {characterTruncatedContent ?? children}\n </span>\n );\n };\n\n const isTooltipDisabled =\n !shouldShowTooltip ||\n (expandButton !== undefined && truncateWithButtonResult.isExpanded);\n\n return (\n <Tooltip\n {...tooltipProps?.root}\n type=\"simple\"\n isDisabled={isTooltipDisabled}\n isOpen={isTooltipOpen}\n onOpenChange={(open) => {\n if (open) {\n setIsTooltipOpen(checkTruncationForTooltip());\n } else {\n setIsTooltipOpen(false);\n }\n }}\n >\n <Tooltip.Trigger {...tooltipProps?.trigger} hasButtonWrapper>\n <Typography\n as={as ?? 'div'}\n ref={ref}\n variant={typographyVariant}\n className={classNames('ndl-text-overflow', className)}\n htmlAttributes={{\n ...htmlAttributes,\n }}\n {...restProps}\n {...(!isTooltipDisabled &&\n expandButton === undefined && {\n tabIndex: 0,\n })}\n >\n <div className=\"ndl-text-overflow-content\" ref={contentRef}>\n {renderContent()}\n </div>\n </Typography>\n </Tooltip.Trigger>\n <Tooltip.Content\n className={classNames(\n 'ndl-text-overflow-tooltip-content',\n tooltipProps?.content?.className,\n )}\n {...tooltipProps?.content}\n >\n {textContent}\n </Tooltip.Content>\n </Tooltip>\n );\n};\n"]}
@@ -21,7 +21,7 @@
21
21
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22
22
  */
23
23
  import { TextOverflow } from '../TextOverflow';
24
- import { CharacterLimitSrc, ExpandCollapseButtonsSrc, LineClampSrc, MixedContentSrc, TextOverflowCharacterLimit, TextOverflowExpandCollapseButtons, TextOverflowLineClamp, TextOverflowMixedContent, TextOverflowWidthBasedTruncation, WidthBasedTruncationSrc, } from './';
24
+ import { CharacterLimitSrc, ExpandCollapseButtonsSrc, LineClampSrc, MixedContentSrc, TextOverflowCharacterLimit, TextOverflowExpandCollapseButtons, TextOverflowLineClamp, TextOverflowMixedContent, TextOverflowWidthBasedTruncation, WidthBasedTruncationSrc, } from '.';
25
25
  const componentMeta = {
26
26
  component: TextOverflow,
27
27
  id: 'components-text-overflow',
@@ -1 +1 @@
1
- {"version":3,"file":"text-overflow.stories.js","sourceRoot":"","sources":["../../../../src/text-overflow/stories/text-overflow.stories.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,gCAAgC;AAChC;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,0BAA0B,EAC1B,iCAAiC,EACjC,qBAAqB,EACrB,wBAAwB,EACxB,gCAAgC,EAChC,uBAAuB,GACxB,MAAM,IAAI,CAAC;AAEZ,MAAM,aAAa,GAA8B;IAC/C,SAAS,EAAE,YAAY;IACvB,EAAE,EAAE,0BAA0B;IAC9B,UAAU,EAAE;QACV,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;KAC5B;IACD,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,KAAK,EAAE,yBAAyB;CACjC,CAAC;AAEF,eAAe,aAAa,CAAC;AAG7B,aAAa;AACb,MAAM,cAAc,GAAU;IAC5B,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,iBAAiB;gBACvB,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,0BAA0B;CACnC,CAAC;AAEF,aAAa;AACb,MAAM,qBAAqB,GAAU;IACnC,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,wBAAwB;gBAC9B,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,iCAAiC;CAC1C,CAAC;AAEF,aAAa;AACb,MAAM,SAAS,GAAU;IACvB,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,qBAAqB;CAC9B,CAAC;AAEF,aAAa;AACb,MAAM,YAAY,GAAU;IAC1B,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,wBAAwB;CACjC,CAAC;AAEF,aAAa;AACb,MAAM,oBAAoB,GAAU;IAClC,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,gCAAgC;CACzC,CAAC;AAEF,2DAA2D;AAC3D,WAAW;AACX,oBAAoB;AACpB,2BAA2B;AAC3B,eAAe;AACf,kBAAkB;AAClB,0BAA0B;AAC1B,KAAK","sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\n// oxlint-disable no-unused-vars\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type Meta, type StoryObj } from '@storybook/react-vite';\n\nimport { TextOverflow } from '../TextOverflow';\nimport {\n CharacterLimitSrc,\n ExpandCollapseButtonsSrc,\n LineClampSrc,\n MixedContentSrc,\n TextOverflowCharacterLimit,\n TextOverflowExpandCollapseButtons,\n TextOverflowLineClamp,\n TextOverflowMixedContent,\n TextOverflowWidthBasedTruncation,\n WidthBasedTruncationSrc,\n} from './';\n\nconst componentMeta: Meta<typeof TextOverflow> = {\n component: TextOverflow,\n id: 'components-text-overflow',\n parameters: {\n controls: { disable: true },\n },\n tags: ['docsPage'],\n title: 'Components/TextOverflow',\n};\n\nexport default componentMeta;\ntype Story = StoryObj<typeof componentMeta>;\n\n// @ts-ignore\nconst CharacterLimit: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: CharacterLimitSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowCharacterLimit,\n};\n\n// @ts-ignore\nconst ExpandCollapseButtons: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: ExpandCollapseButtonsSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowExpandCollapseButtons,\n};\n\n// @ts-ignore\nconst LineClamp: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: LineClampSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowLineClamp,\n};\n\n// @ts-ignore\nconst MixedContent: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: MixedContentSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowMixedContent,\n};\n\n// @ts-ignore\nconst WidthBasedTruncation: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: WidthBasedTruncationSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowWidthBasedTruncation,\n};\n\n// TODO: don't export until we want to release TextOverflow\n// export {\n// CharacterLimit,\n// ExpandCollapseButtons,\n// LineClamp,\n// MixedContent,\n// WidthBasedTruncation,\n// };\n"]}
1
+ {"version":3,"file":"text-overflow.stories.js","sourceRoot":"","sources":["../../../../src/text-overflow/stories/text-overflow.stories.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,gCAAgC;AAChC;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,0BAA0B,EAC1B,iCAAiC,EACjC,qBAAqB,EACrB,wBAAwB,EACxB,gCAAgC,EAChC,uBAAuB,GACxB,MAAM,GAAG,CAAC;AAEX,MAAM,aAAa,GAA8B;IAC/C,SAAS,EAAE,YAAY;IACvB,EAAE,EAAE,0BAA0B;IAC9B,UAAU,EAAE;QACV,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;KAC5B;IACD,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,KAAK,EAAE,yBAAyB;CACjC,CAAC;AAEF,eAAe,aAAa,CAAC;AAG7B,aAAa;AACb,MAAM,cAAc,GAAU;IAC5B,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,iBAAiB;gBACvB,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,0BAA0B;CACnC,CAAC;AAEF,aAAa;AACb,MAAM,qBAAqB,GAAU;IACnC,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,wBAAwB;gBAC9B,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,iCAAiC;CAC1C,CAAC;AAEF,aAAa;AACb,MAAM,SAAS,GAAU;IACvB,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,qBAAqB;CAC9B,CAAC;AAEF,aAAa;AACb,MAAM,YAAY,GAAU;IAC1B,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,wBAAwB;CACjC,CAAC;AAEF,aAAa;AACb,MAAM,oBAAoB,GAAU;IAClC,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,MAAM;aACb;SACF;KACF;IACD,MAAM,EAAE,gCAAgC;CACzC,CAAC;AAEF,2DAA2D;AAC3D,WAAW;AACX,oBAAoB;AACpB,2BAA2B;AAC3B,eAAe;AACf,kBAAkB;AAClB,0BAA0B;AAC1B,KAAK","sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\n// oxlint-disable no-unused-vars\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type Meta, type StoryObj } from '@storybook/react-vite';\n\nimport { TextOverflow } from '../TextOverflow';\nimport {\n CharacterLimitSrc,\n ExpandCollapseButtonsSrc,\n LineClampSrc,\n MixedContentSrc,\n TextOverflowCharacterLimit,\n TextOverflowExpandCollapseButtons,\n TextOverflowLineClamp,\n TextOverflowMixedContent,\n TextOverflowWidthBasedTruncation,\n WidthBasedTruncationSrc,\n} from '.';\n\nconst componentMeta: Meta<typeof TextOverflow> = {\n component: TextOverflow,\n id: 'components-text-overflow',\n parameters: {\n controls: { disable: true },\n },\n tags: ['docsPage'],\n title: 'Components/TextOverflow',\n};\n\nexport default componentMeta;\ntype Story = StoryObj<typeof componentMeta>;\n\n// @ts-ignore\nconst CharacterLimit: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: CharacterLimitSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowCharacterLimit,\n};\n\n// @ts-ignore\nconst ExpandCollapseButtons: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: ExpandCollapseButtonsSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowExpandCollapseButtons,\n};\n\n// @ts-ignore\nconst LineClamp: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: LineClampSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowLineClamp,\n};\n\n// @ts-ignore\nconst MixedContent: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: MixedContentSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowMixedContent,\n};\n\n// @ts-ignore\nconst WidthBasedTruncation: Story = {\n args: {},\n parameters: {\n docs: {\n source: {\n code: WidthBasedTruncationSrc,\n language: 'tsx',\n type: 'code',\n },\n },\n },\n render: TextOverflowWidthBasedTruncation,\n};\n\n// TODO: don't export until we want to release TextOverflow\n// export {\n// CharacterLimit,\n// ExpandCollapseButtons,\n// LineClamp,\n// MixedContent,\n// WidthBasedTruncation,\n// };\n"]}
@@ -24,10 +24,12 @@ import { ELLIPSIS_CHAR, ESTIMATION_FACTORS } from './constants';
24
24
  * Recursively extracts plain text from React nodes
25
25
  */
26
26
  export const getTextContent = (node) => {
27
- if (typeof node === 'string')
27
+ if (typeof node === 'string') {
28
28
  return node;
29
- if (typeof node === 'number')
29
+ }
30
+ if (typeof node === 'number') {
30
31
  return node.toString();
32
+ }
31
33
  if (React.isValidElement(node)) {
32
34
  // Type assertion to access props safely
33
35
  const element = node;
@@ -106,12 +108,14 @@ export const truncateReactNodeByCharacters = (node, maxCharacters, shouldAddElli
106
108
  return currentNode;
107
109
  }
108
110
  const { children } = currentNode.props;
109
- if (children == null)
111
+ if (children === null || children === undefined) {
110
112
  return currentNode;
113
+ }
111
114
  if (typeof children === 'string') {
112
115
  const truncatedChild = truncateNode(children);
113
- if (truncatedChild === null)
116
+ if (truncatedChild === null) {
114
117
  return null;
118
+ }
115
119
  return React.cloneElement(currentNode, {}, truncatedChild);
116
120
  }
117
121
  if (Array.isArray(children)) {
@@ -125,14 +129,16 @@ export const truncateReactNodeByCharacters = (node, maxCharacters, shouldAddElli
125
129
  truncatedChildren.push(truncatedChild);
126
130
  }
127
131
  }
128
- if (truncatedChildren.length === 0)
132
+ if (truncatedChildren.length === 0) {
129
133
  return null;
134
+ }
130
135
  return React.cloneElement(currentNode, {}, ...truncatedChildren);
131
136
  }
132
137
  // Single React element child
133
138
  const truncatedChild = truncateNode(children);
134
- if (truncatedChild === null)
139
+ if (truncatedChild === null) {
135
140
  return null;
141
+ }
136
142
  return React.cloneElement(currentNode, {}, truncatedChild);
137
143
  };
138
144
  const truncatedResult = truncateNode(normalizedNode);
@@ -1 +1 @@
1
- {"version":3,"file":"text-overflow-utils.js","sourceRoot":"","sources":["../../../src/text-overflow/text-overflow-utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport React, { type ReactNode } from 'react';\n\nimport { ELLIPSIS_CHAR, ESTIMATION_FACTORS } from './constants';\n\ntype ReactNodeTruncationResult = {\n needsTruncation: boolean;\n truncatedContent: React.ReactNode | null;\n};\n\n/**\n * Recursively extracts plain text from React nodes\n */\nexport const getTextContent = (node: React.ReactNode): string => {\n if (typeof node === 'string') return node;\n if (typeof node === 'number') return node.toString();\n if (React.isValidElement(node)) {\n // Type assertion to access props safely\n const element = node as React.ReactElement<{ children?: ReactNode }>;\n return getTextContent(element.props.children);\n }\n if (Array.isArray(node)) {\n return node.map(getTextContent).join('');\n }\n return '';\n};\n\n/**\n * Truncates React node content by character count while preserving element structure.\n */\nexport const truncateReactNodeByCharacters = (\n node: React.ReactNode,\n maxCharacters: number,\n shouldAddEllipsis = true,\n): ReactNodeTruncationResult => {\n // Handle the case where node is an array (React children)\n const normalizedNode = Array.isArray(node)\n ? React.createElement(React.Fragment, null, ...node)\n : node;\n\n // Get the total character count first to determine if truncation is needed\n const totalLength = getTextContent(normalizedNode).length;\n\n if (totalLength <= maxCharacters) {\n return { needsTruncation: false, truncatedContent: null };\n }\n\n let charCount = 0;\n let hasReachedLimit = false;\n\n const truncateNode = (currentNode: React.ReactNode): React.ReactNode => {\n // Stop processing if character limit is reached\n if (hasReachedLimit || charCount >= maxCharacters) {\n hasReachedLimit = true;\n return null;\n }\n\n // Handle arrays of children (mixed content case)\n if (Array.isArray(currentNode)) {\n const truncatedChildren: React.ReactNode[] = [];\n\n for (const child of currentNode) {\n if (hasReachedLimit || charCount >= maxCharacters) {\n break;\n }\n\n const truncatedChild = truncateNode(child);\n if (truncatedChild !== null) {\n truncatedChildren.push(truncatedChild);\n }\n }\n\n return truncatedChildren.length > 0 ? truncatedChildren : null;\n }\n\n if (typeof currentNode === 'string') {\n const availableChars = maxCharacters - charCount;\n\n if (currentNode.length <= availableChars) {\n charCount += currentNode.length;\n return currentNode;\n }\n\n // Truncate at character limit, preferring word boundaries\n let truncated = currentNode.substring(0, availableChars);\n const lastSpaceIndex = truncated.lastIndexOf(' ');\n\n if (lastSpaceIndex > availableChars * ESTIMATION_FACTORS.WORD_BOUNDARY) {\n truncated = truncated.substring(0, lastSpaceIndex);\n }\n\n truncated = truncated.trim();\n charCount += truncated.length;\n hasReachedLimit = true;\n return truncated;\n }\n\n if (typeof currentNode === 'number') {\n const str = currentNode.toString();\n const availableChars = maxCharacters - charCount;\n\n if (str.length <= availableChars) {\n charCount += str.length;\n return currentNode;\n }\n\n const truncated = str.substring(0, availableChars);\n charCount += truncated.length;\n hasReachedLimit = true;\n return truncated;\n }\n\n if (!React.isValidElement(currentNode)) {\n return currentNode;\n }\n\n const { children } = currentNode.props as { children?: ReactNode };\n if (children == null) return currentNode;\n\n if (typeof children === 'string') {\n const truncatedChild = truncateNode(children);\n if (truncatedChild === null) return null;\n return React.cloneElement(currentNode, {}, truncatedChild);\n }\n\n if (Array.isArray(children)) {\n const truncatedChildren: React.ReactNode[] = [];\n for (const child of children) {\n if (hasReachedLimit || charCount >= maxCharacters) {\n break;\n }\n\n const truncatedChild = truncateNode(child);\n if (truncatedChild !== null) {\n truncatedChildren.push(truncatedChild);\n }\n }\n\n if (truncatedChildren.length === 0) return null;\n return React.cloneElement(currentNode, {}, ...truncatedChildren);\n }\n\n // Single React element child\n const truncatedChild = truncateNode(children);\n if (truncatedChild === null) return null;\n return React.cloneElement(currentNode, {}, truncatedChild);\n };\n\n const truncatedResult = truncateNode(normalizedNode);\n\n // Convert array results to proper React elements\n const finalResult = Array.isArray(truncatedResult)\n ? React.createElement(React.Fragment, null, ...truncatedResult)\n : truncatedResult;\n\n // Add ellipsis if needed\n if (shouldAddEllipsis && finalResult !== null) {\n const withEllipsis = React.createElement(\n React.Fragment,\n null,\n finalResult,\n ELLIPSIS_CHAR,\n );\n return { needsTruncation: true, truncatedContent: withEllipsis };\n }\n\n return {\n needsTruncation: true,\n truncatedContent: finalResult,\n };\n};\n"]}
1
+ {"version":3,"file":"text-overflow-utils.js","sourceRoot":"","sources":["../../../src/text-overflow/text-overflow-utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport React, { type ReactNode } from 'react';\n\nimport { ELLIPSIS_CHAR, ESTIMATION_FACTORS } from './constants';\n\ntype ReactNodeTruncationResult = {\n needsTruncation: boolean;\n truncatedContent: React.ReactNode | null;\n};\n\n/**\n * Recursively extracts plain text from React nodes\n */\nexport const getTextContent = (node: React.ReactNode): string => {\n if (typeof node === 'string') {\n return node;\n }\n if (typeof node === 'number') {\n return node.toString();\n }\n if (React.isValidElement(node)) {\n // Type assertion to access props safely\n const element = node as React.ReactElement<{ children?: ReactNode }>;\n return getTextContent(element.props.children);\n }\n if (Array.isArray(node)) {\n return node.map(getTextContent).join('');\n }\n return '';\n};\n\n/**\n * Truncates React node content by character count while preserving element structure.\n */\nexport const truncateReactNodeByCharacters = (\n node: React.ReactNode,\n maxCharacters: number,\n shouldAddEllipsis = true,\n): ReactNodeTruncationResult => {\n // Handle the case where node is an array (React children)\n const normalizedNode = Array.isArray(node)\n ? React.createElement(React.Fragment, null, ...node)\n : node;\n\n // Get the total character count first to determine if truncation is needed\n const totalLength = getTextContent(normalizedNode).length;\n\n if (totalLength <= maxCharacters) {\n return { needsTruncation: false, truncatedContent: null };\n }\n\n let charCount = 0;\n let hasReachedLimit = false;\n\n const truncateNode = (currentNode: React.ReactNode): React.ReactNode => {\n // Stop processing if character limit is reached\n if (hasReachedLimit || charCount >= maxCharacters) {\n hasReachedLimit = true;\n return null;\n }\n\n // Handle arrays of children (mixed content case)\n if (Array.isArray(currentNode)) {\n const truncatedChildren: React.ReactNode[] = [];\n\n for (const child of currentNode) {\n if (hasReachedLimit || charCount >= maxCharacters) {\n break;\n }\n\n const truncatedChild = truncateNode(child);\n if (truncatedChild !== null) {\n truncatedChildren.push(truncatedChild);\n }\n }\n\n return truncatedChildren.length > 0 ? truncatedChildren : null;\n }\n\n if (typeof currentNode === 'string') {\n const availableChars = maxCharacters - charCount;\n\n if (currentNode.length <= availableChars) {\n charCount += currentNode.length;\n return currentNode;\n }\n\n // Truncate at character limit, preferring word boundaries\n let truncated = currentNode.substring(0, availableChars);\n const lastSpaceIndex = truncated.lastIndexOf(' ');\n\n if (lastSpaceIndex > availableChars * ESTIMATION_FACTORS.WORD_BOUNDARY) {\n truncated = truncated.substring(0, lastSpaceIndex);\n }\n\n truncated = truncated.trim();\n charCount += truncated.length;\n hasReachedLimit = true;\n return truncated;\n }\n\n if (typeof currentNode === 'number') {\n const str = currentNode.toString();\n const availableChars = maxCharacters - charCount;\n\n if (str.length <= availableChars) {\n charCount += str.length;\n return currentNode;\n }\n\n const truncated = str.substring(0, availableChars);\n charCount += truncated.length;\n hasReachedLimit = true;\n return truncated;\n }\n\n if (!React.isValidElement(currentNode)) {\n return currentNode;\n }\n\n const { children } = currentNode.props as { children?: ReactNode };\n if (children === null || children === undefined) {\n return currentNode;\n }\n\n if (typeof children === 'string') {\n const truncatedChild = truncateNode(children);\n if (truncatedChild === null) {\n return null;\n }\n return React.cloneElement(currentNode, {}, truncatedChild);\n }\n\n if (Array.isArray(children)) {\n const truncatedChildren: React.ReactNode[] = [];\n for (const child of children) {\n if (hasReachedLimit || charCount >= maxCharacters) {\n break;\n }\n\n const truncatedChild = truncateNode(child);\n if (truncatedChild !== null) {\n truncatedChildren.push(truncatedChild);\n }\n }\n\n if (truncatedChildren.length === 0) {\n return null;\n }\n return React.cloneElement(currentNode, {}, ...truncatedChildren);\n }\n\n // Single React element child\n const truncatedChild = truncateNode(children);\n if (truncatedChild === null) {\n return null;\n }\n return React.cloneElement(currentNode, {}, truncatedChild);\n };\n\n const truncatedResult = truncateNode(normalizedNode);\n\n // Convert array results to proper React elements\n const finalResult = Array.isArray(truncatedResult)\n ? React.createElement(React.Fragment, null, ...truncatedResult)\n : truncatedResult;\n\n // Add ellipsis if needed\n if (shouldAddEllipsis && finalResult !== null) {\n const withEllipsis = React.createElement(\n React.Fragment,\n null,\n finalResult,\n ELLIPSIS_CHAR,\n );\n return { needsTruncation: true, truncatedContent: withEllipsis };\n }\n\n return {\n needsTruncation: true,\n truncatedContent: finalResult,\n };\n};\n"]}
@@ -26,8 +26,9 @@ export function useEllipsisObserver(options = {}) {
26
26
  const [isEllipsized, setIsEllipsized] = useState(false);
27
27
  useEffect(() => {
28
28
  const el = ref.current;
29
- if (!el)
29
+ if (!el) {
30
30
  return;
31
+ }
31
32
  const checkEllipsis = () => {
32
33
  let hasEllipsis = false;
33
34
  if (lineClamp > 1) {
@@ -1 +1 @@
1
- {"version":3,"file":"use-ellipsis-observer.js","sourceRoot":"","sources":["../../../src/text-overflow/use-ellipsis-observer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAkB,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEpE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAO/C,MAAM,UAAU,mBAAmB,CACjC,UAAsC,EAAE;IAExC,MAAM,EAAE,SAAS,GAAG,CAAC,EAAE,UAAU,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,CAAW,IAAI,CAAC,CAAC;IACnC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,IAAI,CAAC,EAAE;YAAE,OAAO;QAEhB,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,IAAI,WAAW,GAAG,KAAK,CAAC;YAExB,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,uCAAuC;gBACvC,qDAAqD;gBACrD,WAAW,GAAG,EAAE,CAAC,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,qDAAqD;gBACrD,mDAAmD;gBACnD,WAAW,GAAG,EAAE,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC;YAChD,CAAC;YAED,eAAe,CAAC,WAAW,CAAC,CAAC;QAC/B,CAAC,CAAC;QAEF,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QAE3D,gBAAgB;QAChB,aAAa,EAAE,CAAC;QAEhB,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,cAAc,CAAC,CAAC;QAC1D,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAE3B,kEAAkE;QAClE,IAAI,EAAE,CAAC,aAAa,EAAE,CAAC;YACrB,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAElD,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACvD,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAE5B,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type RefObject, useEffect, useRef, useState } from 'react';\n\nimport { debounce } from '../helpers/debounce';\n\ninterface UseEllipsisObserverOptions {\n lineClamp?: number;\n debounceMs?: number;\n}\n\nexport function useEllipsisObserver<T extends Element = Element>(\n options: UseEllipsisObserverOptions = {},\n): [RefObject<T | null>, boolean] {\n const { lineClamp = 1, debounceMs = 100 } = options;\n const ref = useRef<T | null>(null);\n const [isEllipsized, setIsEllipsized] = useState(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const checkEllipsis = () => {\n let hasEllipsis = false;\n\n if (lineClamp > 1) {\n // For multi-line ellipsis (line-clamp)\n // Check if scrollHeight is greater than clientHeight\n hasEllipsis = el.scrollHeight > el.clientHeight;\n } else {\n // For single-line ellipsis (text-overflow: ellipsis)\n // Check if scrollWidth is greater than clientWidth\n hasEllipsis = el.scrollWidth > el.clientWidth;\n }\n\n setIsEllipsized(hasEllipsis);\n };\n\n const debouncedCheck = debounce(checkEllipsis, debounceMs);\n\n // Initial check\n checkEllipsis();\n\n const resizeObserver = new ResizeObserver(debouncedCheck);\n resizeObserver.observe(el);\n\n // Also observe the parent element to catch container size changes\n if (el.parentElement) {\n resizeObserver.observe(el.parentElement);\n }\n\n window.addEventListener('resize', debouncedCheck);\n\n return () => {\n resizeObserver.disconnect();\n window.removeEventListener('resize', debouncedCheck);\n };\n }, [lineClamp, debounceMs]);\n\n return [ref, isEllipsized];\n}\n"]}
1
+ {"version":3,"file":"use-ellipsis-observer.js","sourceRoot":"","sources":["../../../src/text-overflow/use-ellipsis-observer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAkB,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEpE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAO/C,MAAM,UAAU,mBAAmB,CACjC,UAAsC,EAAE;IAExC,MAAM,EAAE,SAAS,GAAG,CAAC,EAAE,UAAU,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,CAAW,IAAI,CAAC,CAAC;IACnC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO;QACT,CAAC;QAED,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,IAAI,WAAW,GAAG,KAAK,CAAC;YAExB,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,uCAAuC;gBACvC,qDAAqD;gBACrD,WAAW,GAAG,EAAE,CAAC,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,qDAAqD;gBACrD,mDAAmD;gBACnD,WAAW,GAAG,EAAE,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC;YAChD,CAAC;YAED,eAAe,CAAC,WAAW,CAAC,CAAC;QAC/B,CAAC,CAAC;QAEF,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QAE3D,gBAAgB;QAChB,aAAa,EAAE,CAAC;QAEhB,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,cAAc,CAAC,CAAC;QAC1D,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAE3B,kEAAkE;QAClE,IAAI,EAAE,CAAC,aAAa,EAAE,CAAC;YACrB,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAElD,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACvD,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAE5B,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type RefObject, useEffect, useRef, useState } from 'react';\n\nimport { debounce } from '../helpers/debounce';\n\ninterface UseEllipsisObserverOptions {\n lineClamp?: number;\n debounceMs?: number;\n}\n\nexport function useEllipsisObserver<T extends Element = Element>(\n options: UseEllipsisObserverOptions = {},\n): [RefObject<T | null>, boolean] {\n const { lineClamp = 1, debounceMs = 100 } = options;\n const ref = useRef<T | null>(null);\n const [isEllipsized, setIsEllipsized] = useState(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const checkEllipsis = () => {\n let hasEllipsis = false;\n\n if (lineClamp > 1) {\n // For multi-line ellipsis (line-clamp)\n // Check if scrollHeight is greater than clientHeight\n hasEllipsis = el.scrollHeight > el.clientHeight;\n } else {\n // For single-line ellipsis (text-overflow: ellipsis)\n // Check if scrollWidth is greater than clientWidth\n hasEllipsis = el.scrollWidth > el.clientWidth;\n }\n\n setIsEllipsized(hasEllipsis);\n };\n\n const debouncedCheck = debounce(checkEllipsis, debounceMs);\n\n // Initial check\n checkEllipsis();\n\n const resizeObserver = new ResizeObserver(debouncedCheck);\n resizeObserver.observe(el);\n\n // Also observe the parent element to catch container size changes\n if (el.parentElement) {\n resizeObserver.observe(el.parentElement);\n }\n\n window.addEventListener('resize', debouncedCheck);\n\n return () => {\n resizeObserver.disconnect();\n window.removeEventListener('resize', debouncedCheck);\n };\n }, [lineClamp, debounceMs]);\n\n return [ref, isEllipsized];\n}\n"]}
@@ -116,8 +116,9 @@ export function useTruncateWithButton({ content, lineClamp, button, onExpandedTo
116
116
  return;
117
117
  }
118
118
  // Fallback to line-based truncation
119
- if (!measureRef.current || !containerRef.current)
119
+ if (!measureRef.current || !containerRef.current) {
120
120
  return;
121
+ }
121
122
  const measure = measureRef.current;
122
123
  const container = containerRef.current;
123
124
  copyStylesForMeasurement(measure, container);
@@ -166,8 +167,9 @@ export function useTruncateWithButton({ content, lineClamp, button, onExpandedTo
166
167
  recalculateTruncation();
167
168
  // Set up resize observer for container size changes
168
169
  const container = containerRef.current;
169
- if (!container)
170
+ if (!container) {
170
171
  return;
172
+ }
171
173
  const resizeObserver = new ResizeObserver(() => {
172
174
  debouncedRecalculateTruncation();
173
175
  });
@@ -1 +1 @@
1
- {"version":3,"file":"use-truncate-with-button.js","sourceRoot":"","sources":["../../../src/text-overflow/use-truncate-with-button.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { tokens } from '@neo4j-ndl/base';\nimport {\n type ReactNode,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useDebounceCallback } from '../hooks';\nimport {\n getTextContent,\n truncateReactNodeByCharacters,\n} from './text-overflow-utils';\n\n// Cache for computed styles to avoid repeated getComputedStyle calls\nconst styleCache = new WeakMap<HTMLElement, CSSStyleDeclaration>();\n\n// Helper function to copy relevant styles for measurement\nconst copyStylesForMeasurement = (\n measureElement: HTMLElement,\n sourceElement: HTMLElement,\n) => {\n // Use cached styles if available\n let sourceStyles = styleCache.get(sourceElement);\n if (sourceStyles === undefined) {\n sourceStyles = window.getComputedStyle(sourceElement);\n styleCache.set(sourceElement, sourceStyles);\n }\n\n measureElement.style.position = 'absolute';\n measureElement.style.visibility = 'hidden';\n measureElement.style.top = '-9999px';\n measureElement.style.left = '-9999px';\n measureElement.style.width = sourceStyles.width;\n measureElement.style.fontFamily = sourceStyles.fontFamily;\n measureElement.style.fontSize = sourceStyles.fontSize;\n measureElement.style.fontWeight = sourceStyles.fontWeight;\n measureElement.style.lineHeight = sourceStyles.lineHeight;\n measureElement.style.letterSpacing = sourceStyles.letterSpacing;\n measureElement.style.wordSpacing = sourceStyles.wordSpacing;\n measureElement.style.overflow = 'hidden';\n measureElement.style.wordBreak = 'break-word';\n};\n\n// Helper function to find the optimal truncation point using optimized binary search\nconst findTruncationPoint = (\n content: ReactNode,\n allText: string,\n measureElement: HTMLElement,\n maxHeight: number,\n button: ReactNode,\n buttonType?: 'view-more' | 'ellipsis',\n) => {\n let low = 0;\n let high = allText.length;\n let bestFitContent: ReactNode = null;\n\n // Pre-calculate button text to avoid repeated string operations\n const buttonText = typeof button === 'string' ? button : 'View more';\n const buttonMargin = buttonType !== 'ellipsis' ? tokens.space[4] : '0';\n\n // Create reusable DOM elements to avoid repeated creation\n const tempSpan = document.createElement('span');\n const btnSpan = document.createElement('span');\n btnSpan.style.display = 'inline-block';\n btnSpan.style.marginLeft = buttonMargin;\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const testText = allText.slice(0, mid);\n\n measureElement.innerHTML = '';\n\n // Reuse span elements\n tempSpan.textContent =\n buttonType === 'ellipsis' ? testText : `${testText}\\u2026`;\n measureElement.appendChild(tempSpan);\n\n btnSpan.textContent = buttonText;\n measureElement.appendChild(btnSpan);\n\n if (measureElement.scrollHeight <= maxHeight) {\n bestFitContent = truncateReactNodeByCharacters(\n content,\n mid,\n buttonType !== 'ellipsis',\n ).truncatedContent;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return bestFitContent;\n};\n\ninterface UseTruncateOptions {\n button: ReactNode;\n content: ReactNode;\n lineClamp: number;\n onExpandedToggle?: (isExpanded: boolean) => void;\n maxCharacters?: number;\n buttonType?: 'view-more' | 'ellipsis';\n closeTooltip?: () => void;\n /**\n * When true, skips all expensive DOM calculations and measurements.\n * Useful for performance optimization when the hook functionality isn't needed.\n */\n isDisabled?: boolean;\n}\n\nexport function useTruncateWithButton({\n content,\n lineClamp,\n button,\n onExpandedToggle,\n maxCharacters,\n buttonType,\n closeTooltip,\n isDisabled,\n}: UseTruncateOptions) {\n const containerRef = useRef<HTMLDivElement>(null);\n const measureRef = useRef<HTMLDivElement>(null);\n\n const [isExpanded, setIsExpanded] = useState(false);\n const [isTruncated, setIsTruncated] = useState(false);\n const [truncatedContent, setTruncatedContent] = useState<ReactNode>(content);\n\n // Memoize text content to avoid repeated traversals\n const textContent = useMemo(() => getTextContent(content), [content]);\n\n const toggleExpand = useCallback(() => {\n if (isDisabled === true) {\n return;\n }\n\n const shouldExpand = !isExpanded;\n setIsExpanded(shouldExpand);\n\n if (shouldExpand) {\n onExpandedToggle?.(true);\n closeTooltip?.();\n } else {\n onExpandedToggle?.(false);\n }\n }, [isExpanded, onExpandedToggle, closeTooltip, isDisabled]);\n\n const recalculateTruncation = useCallback(() => {\n // If disabled, don't perform any calculations\n if (isDisabled === true) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // Character-based truncation takes precedence\n if (typeof maxCharacters === 'number') {\n const result = truncateReactNodeByCharacters(content, maxCharacters);\n setIsTruncated(result.needsTruncation);\n setTruncatedContent(\n result.needsTruncation ? result.truncatedContent : content,\n );\n return;\n }\n\n // Fallback to line-based truncation\n if (!measureRef.current || !containerRef.current) return;\n\n const measure = measureRef.current;\n const container = containerRef.current;\n\n copyStylesForMeasurement(measure, container);\n const containerStyles = window.getComputedStyle(container);\n const lineHeight = parseFloat(containerStyles.lineHeight);\n const maxHeight = lineHeight * lineClamp;\n\n const allText = textContent;\n\n // Early exit if no text content\n if (allText.length === 0) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // First, check if truncation is needed at all\n measure.innerHTML = '';\n const fullTextSpan = document.createElement('span');\n fullTextSpan.textContent = allText;\n measure.appendChild(fullTextSpan);\n\n const isTruncationNeeded = measure.scrollHeight > maxHeight;\n\n if (!isTruncationNeeded) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // Binary search for truncation point\n const bestFitContent = findTruncationPoint(\n content,\n allText,\n measure,\n maxHeight,\n button,\n buttonType,\n );\n\n setIsTruncated(true);\n setTruncatedContent(bestFitContent);\n }, [\n content,\n button,\n lineClamp,\n maxCharacters,\n buttonType,\n isDisabled,\n textContent,\n ]);\n\n // Create debounced version of recalculateTruncation for resize events\n const debouncedRecalculateTruncation = useDebounceCallback(\n recalculateTruncation,\n 100,\n );\n\n // Initial calculation and resize handling\n useLayoutEffect(() => {\n // If disabled, don't set up any observers or event listeners\n if (isDisabled === true) {\n return;\n }\n\n recalculateTruncation();\n\n // Set up resize observer for container size changes\n const container = containerRef.current;\n if (!container) return;\n\n const resizeObserver = new ResizeObserver(() => {\n debouncedRecalculateTruncation();\n });\n\n resizeObserver.observe(container);\n\n // Also observe parent element to catch container size changes\n if (container.parentElement) {\n resizeObserver.observe(container.parentElement);\n }\n\n // Handle window resize events\n const handleWindowResize = () => {\n debouncedRecalculateTruncation();\n };\n\n window.addEventListener('resize', handleWindowResize);\n\n return () => {\n resizeObserver.disconnect();\n window.removeEventListener('resize', handleWindowResize);\n };\n }, [recalculateTruncation, debouncedRecalculateTruncation, isDisabled]);\n\n // Compute the final content to render based on expanded state\n const contentToRender = isExpanded ? content : truncatedContent;\n\n return {\n containerRef,\n contentToRender,\n isExpanded,\n isTruncated,\n measureRef,\n toggleExpand,\n };\n}\n"]}
1
+ {"version":3,"file":"use-truncate-with-button.js","sourceRoot":"","sources":["../../../src/text-overflow/use-truncate-with-button.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { tokens } from '@neo4j-ndl/base';\nimport {\n type ReactNode,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useDebounceCallback } from '../hooks';\nimport {\n getTextContent,\n truncateReactNodeByCharacters,\n} from './text-overflow-utils';\n\n// Cache for computed styles to avoid repeated getComputedStyle calls\nconst styleCache = new WeakMap<HTMLElement, CSSStyleDeclaration>();\n\n// Helper function to copy relevant styles for measurement\nconst copyStylesForMeasurement = (\n measureElement: HTMLElement,\n sourceElement: HTMLElement,\n) => {\n // Use cached styles if available\n let sourceStyles = styleCache.get(sourceElement);\n if (sourceStyles === undefined) {\n sourceStyles = window.getComputedStyle(sourceElement);\n styleCache.set(sourceElement, sourceStyles);\n }\n\n measureElement.style.position = 'absolute';\n measureElement.style.visibility = 'hidden';\n measureElement.style.top = '-9999px';\n measureElement.style.left = '-9999px';\n measureElement.style.width = sourceStyles.width;\n measureElement.style.fontFamily = sourceStyles.fontFamily;\n measureElement.style.fontSize = sourceStyles.fontSize;\n measureElement.style.fontWeight = sourceStyles.fontWeight;\n measureElement.style.lineHeight = sourceStyles.lineHeight;\n measureElement.style.letterSpacing = sourceStyles.letterSpacing;\n measureElement.style.wordSpacing = sourceStyles.wordSpacing;\n measureElement.style.overflow = 'hidden';\n measureElement.style.wordBreak = 'break-word';\n};\n\n// Helper function to find the optimal truncation point using optimized binary search\nconst findTruncationPoint = (\n content: ReactNode,\n allText: string,\n measureElement: HTMLElement,\n maxHeight: number,\n button: ReactNode,\n buttonType?: 'view-more' | 'ellipsis',\n) => {\n let low = 0;\n let high = allText.length;\n let bestFitContent: ReactNode = null;\n\n // Pre-calculate button text to avoid repeated string operations\n const buttonText = typeof button === 'string' ? button : 'View more';\n const buttonMargin = buttonType !== 'ellipsis' ? tokens.space[4] : '0';\n\n // Create reusable DOM elements to avoid repeated creation\n const tempSpan = document.createElement('span');\n const btnSpan = document.createElement('span');\n btnSpan.style.display = 'inline-block';\n btnSpan.style.marginLeft = buttonMargin;\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const testText = allText.slice(0, mid);\n\n measureElement.innerHTML = '';\n\n // Reuse span elements\n tempSpan.textContent =\n buttonType === 'ellipsis' ? testText : `${testText}\\u2026`;\n measureElement.appendChild(tempSpan);\n\n btnSpan.textContent = buttonText;\n measureElement.appendChild(btnSpan);\n\n if (measureElement.scrollHeight <= maxHeight) {\n bestFitContent = truncateReactNodeByCharacters(\n content,\n mid,\n buttonType !== 'ellipsis',\n ).truncatedContent;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return bestFitContent;\n};\n\ninterface UseTruncateOptions {\n button: ReactNode;\n content: ReactNode;\n lineClamp: number;\n onExpandedToggle?: (isExpanded: boolean) => void;\n maxCharacters?: number;\n buttonType?: 'view-more' | 'ellipsis';\n closeTooltip?: () => void;\n /**\n * When true, skips all expensive DOM calculations and measurements.\n * Useful for performance optimization when the hook functionality isn't needed.\n */\n isDisabled?: boolean;\n}\n\nexport function useTruncateWithButton({\n content,\n lineClamp,\n button,\n onExpandedToggle,\n maxCharacters,\n buttonType,\n closeTooltip,\n isDisabled,\n}: UseTruncateOptions) {\n const containerRef = useRef<HTMLDivElement>(null);\n const measureRef = useRef<HTMLDivElement>(null);\n\n const [isExpanded, setIsExpanded] = useState(false);\n const [isTruncated, setIsTruncated] = useState(false);\n const [truncatedContent, setTruncatedContent] = useState<ReactNode>(content);\n\n // Memoize text content to avoid repeated traversals\n const textContent = useMemo(() => getTextContent(content), [content]);\n\n const toggleExpand = useCallback(() => {\n if (isDisabled === true) {\n return;\n }\n\n const shouldExpand = !isExpanded;\n setIsExpanded(shouldExpand);\n\n if (shouldExpand) {\n onExpandedToggle?.(true);\n closeTooltip?.();\n } else {\n onExpandedToggle?.(false);\n }\n }, [isExpanded, onExpandedToggle, closeTooltip, isDisabled]);\n\n const recalculateTruncation = useCallback(() => {\n // If disabled, don't perform any calculations\n if (isDisabled === true) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // Character-based truncation takes precedence\n if (typeof maxCharacters === 'number') {\n const result = truncateReactNodeByCharacters(content, maxCharacters);\n setIsTruncated(result.needsTruncation);\n setTruncatedContent(\n result.needsTruncation ? result.truncatedContent : content,\n );\n return;\n }\n\n // Fallback to line-based truncation\n if (!measureRef.current || !containerRef.current) {\n return;\n }\n\n const measure = measureRef.current;\n const container = containerRef.current;\n\n copyStylesForMeasurement(measure, container);\n const containerStyles = window.getComputedStyle(container);\n const lineHeight = parseFloat(containerStyles.lineHeight);\n const maxHeight = lineHeight * lineClamp;\n\n const allText = textContent;\n\n // Early exit if no text content\n if (allText.length === 0) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // First, check if truncation is needed at all\n measure.innerHTML = '';\n const fullTextSpan = document.createElement('span');\n fullTextSpan.textContent = allText;\n measure.appendChild(fullTextSpan);\n\n const isTruncationNeeded = measure.scrollHeight > maxHeight;\n\n if (!isTruncationNeeded) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // Binary search for truncation point\n const bestFitContent = findTruncationPoint(\n content,\n allText,\n measure,\n maxHeight,\n button,\n buttonType,\n );\n\n setIsTruncated(true);\n setTruncatedContent(bestFitContent);\n }, [\n content,\n button,\n lineClamp,\n maxCharacters,\n buttonType,\n isDisabled,\n textContent,\n ]);\n\n // Create debounced version of recalculateTruncation for resize events\n const debouncedRecalculateTruncation = useDebounceCallback(\n recalculateTruncation,\n 100,\n );\n\n // Initial calculation and resize handling\n useLayoutEffect(() => {\n // If disabled, don't set up any observers or event listeners\n if (isDisabled === true) {\n return;\n }\n\n recalculateTruncation();\n\n // Set up resize observer for container size changes\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const resizeObserver = new ResizeObserver(() => {\n debouncedRecalculateTruncation();\n });\n\n resizeObserver.observe(container);\n\n // Also observe parent element to catch container size changes\n if (container.parentElement) {\n resizeObserver.observe(container.parentElement);\n }\n\n // Handle window resize events\n const handleWindowResize = () => {\n debouncedRecalculateTruncation();\n };\n\n window.addEventListener('resize', handleWindowResize);\n\n return () => {\n resizeObserver.disconnect();\n window.removeEventListener('resize', handleWindowResize);\n };\n }, [recalculateTruncation, debouncedRecalculateTruncation, isDisabled]);\n\n // Compute the final content to render based on expanded state\n const contentToRender = isExpanded ? content : truncatedContent;\n\n return {\n containerRef,\n contentToRender,\n isExpanded,\n isTruncated,\n measureRef,\n toggleExpand,\n };\n}\n"]}
@@ -44,8 +44,9 @@ export const useNeedleTheme = () => {
44
44
  * inside a `NeedleThemeProvider` .
45
45
  * Defaults to `light` theme.
46
46
  */
47
- if (theme === undefined)
47
+ if (theme === undefined) {
48
48
  theme = 'light';
49
+ }
49
50
  const tokens = useContext(TokensContext);
50
51
  return {
51
52
  theme,