@gabvdl/ui 0.0.14

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 (330) hide show
  1. package/README.md +95 -0
  2. package/dist/components/button/button.d.ts +39 -0
  3. package/dist/components/button/button.d.ts.map +1 -0
  4. package/dist/components/button/button.js +72 -0
  5. package/dist/components/button/button.js.map +1 -0
  6. package/dist/components/button/index.d.ts +5 -0
  7. package/dist/components/button/index.d.ts.map +1 -0
  8. package/dist/components/button/tooltip.d.ts +31 -0
  9. package/dist/components/button/tooltip.d.ts.map +1 -0
  10. package/dist/components/button/tooltip.js +83 -0
  11. package/dist/components/button/tooltip.js.map +1 -0
  12. package/dist/components/changelog/changelog.d.ts +52 -0
  13. package/dist/components/changelog/changelog.d.ts.map +1 -0
  14. package/dist/components/changelog/changelog.js +164 -0
  15. package/dist/components/changelog/changelog.js.map +1 -0
  16. package/dist/components/changelog/index.d.ts +3 -0
  17. package/dist/components/changelog/index.d.ts.map +1 -0
  18. package/dist/components/copy-button/copy-button.d.ts +16 -0
  19. package/dist/components/copy-button/copy-button.d.ts.map +1 -0
  20. package/dist/components/copy-button/copy-button.js +40 -0
  21. package/dist/components/copy-button/copy-button.js.map +1 -0
  22. package/dist/components/copy-button/index.d.ts +3 -0
  23. package/dist/components/copy-button/index.d.ts.map +1 -0
  24. package/dist/components/drop-zone/drop-zone.d.ts +20 -0
  25. package/dist/components/drop-zone/drop-zone.d.ts.map +1 -0
  26. package/dist/components/drop-zone/drop-zone.js +54 -0
  27. package/dist/components/drop-zone/drop-zone.js.map +1 -0
  28. package/dist/components/drop-zone/index.d.ts +5 -0
  29. package/dist/components/drop-zone/index.d.ts.map +1 -0
  30. package/dist/components/drop-zone/use-file-drop.d.ts +45 -0
  31. package/dist/components/drop-zone/use-file-drop.d.ts.map +1 -0
  32. package/dist/components/drop-zone/use-file-drop.js +97 -0
  33. package/dist/components/drop-zone/use-file-drop.js.map +1 -0
  34. package/dist/components/element-picker/element-picker-field.d.ts +30 -0
  35. package/dist/components/element-picker/element-picker-field.d.ts.map +1 -0
  36. package/dist/components/element-picker/element-picker-field.js +273 -0
  37. package/dist/components/element-picker/element-picker-field.js.map +1 -0
  38. package/dist/components/element-picker/element-picker.d.ts +45 -0
  39. package/dist/components/element-picker/element-picker.d.ts.map +1 -0
  40. package/dist/components/element-picker/element-picker.js +179 -0
  41. package/dist/components/element-picker/element-picker.js.map +1 -0
  42. package/dist/components/element-picker/element-preview.d.ts +23 -0
  43. package/dist/components/element-picker/element-preview.d.ts.map +1 -0
  44. package/dist/components/element-picker/element-preview.js +72 -0
  45. package/dist/components/element-picker/element-preview.js.map +1 -0
  46. package/dist/components/element-picker/index.d.ts +12 -0
  47. package/dist/components/element-picker/index.d.ts.map +1 -0
  48. package/dist/components/element-picker/parse.d.ts +32 -0
  49. package/dist/components/element-picker/parse.d.ts.map +1 -0
  50. package/dist/components/element-picker/parse.js +230 -0
  51. package/dist/components/element-picker/parse.js.map +1 -0
  52. package/dist/components/element-picker/types.d.ts +72 -0
  53. package/dist/components/element-picker/types.d.ts.map +1 -0
  54. package/dist/components/element-picker/use-element-picker.d.ts +56 -0
  55. package/dist/components/element-picker/use-element-picker.d.ts.map +1 -0
  56. package/dist/components/element-picker/use-element-picker.js +201 -0
  57. package/dist/components/element-picker/use-element-picker.js.map +1 -0
  58. package/dist/components/empty-state/empty-state.d.ts +16 -0
  59. package/dist/components/empty-state/empty-state.d.ts.map +1 -0
  60. package/dist/components/empty-state/empty-state.js +41 -0
  61. package/dist/components/empty-state/empty-state.js.map +1 -0
  62. package/dist/components/empty-state/index.d.ts +3 -0
  63. package/dist/components/empty-state/index.d.ts.map +1 -0
  64. package/dist/components/floating-panel/dock-context.d.ts +66 -0
  65. package/dist/components/floating-panel/dock-context.d.ts.map +1 -0
  66. package/dist/components/floating-panel/dock-context.js +96 -0
  67. package/dist/components/floating-panel/dock-context.js.map +1 -0
  68. package/dist/components/floating-panel/dock.d.ts +26 -0
  69. package/dist/components/floating-panel/dock.d.ts.map +1 -0
  70. package/dist/components/floating-panel/dock.js +46 -0
  71. package/dist/components/floating-panel/dock.js.map +1 -0
  72. package/dist/components/floating-panel/floating-panel.d.ts +69 -0
  73. package/dist/components/floating-panel/floating-panel.d.ts.map +1 -0
  74. package/dist/components/floating-panel/floating-panel.js +285 -0
  75. package/dist/components/floating-panel/floating-panel.js.map +1 -0
  76. package/dist/components/floating-panel/index.d.ts +7 -0
  77. package/dist/components/floating-panel/index.d.ts.map +1 -0
  78. package/dist/components/fuzzy-list/fuzzy-list.d.ts +96 -0
  79. package/dist/components/fuzzy-list/fuzzy-list.d.ts.map +1 -0
  80. package/dist/components/fuzzy-list/fuzzy-list.js +127 -0
  81. package/dist/components/fuzzy-list/fuzzy-list.js.map +1 -0
  82. package/dist/components/fuzzy-list/index.d.ts +4 -0
  83. package/dist/components/fuzzy-list/index.d.ts.map +1 -0
  84. package/dist/components/global-search/global-search.d.ts +78 -0
  85. package/dist/components/global-search/global-search.d.ts.map +1 -0
  86. package/dist/components/global-search/global-search.js +181 -0
  87. package/dist/components/global-search/global-search.js.map +1 -0
  88. package/dist/components/global-search/hotkey.d.ts +23 -0
  89. package/dist/components/global-search/hotkey.d.ts.map +1 -0
  90. package/dist/components/global-search/hotkey.js +41 -0
  91. package/dist/components/global-search/hotkey.js.map +1 -0
  92. package/dist/components/global-search/index.d.ts +5 -0
  93. package/dist/components/global-search/index.d.ts.map +1 -0
  94. package/dist/components/iframe-preview/iframe-preview.d.ts +64 -0
  95. package/dist/components/iframe-preview/iframe-preview.d.ts.map +1 -0
  96. package/dist/components/iframe-preview/iframe-preview.js +257 -0
  97. package/dist/components/iframe-preview/iframe-preview.js.map +1 -0
  98. package/dist/components/iframe-preview/index.d.ts +3 -0
  99. package/dist/components/iframe-preview/index.d.ts.map +1 -0
  100. package/dist/components/image-viewer/image-viewer.d.ts +30 -0
  101. package/dist/components/image-viewer/image-viewer.d.ts.map +1 -0
  102. package/dist/components/image-viewer/image-viewer.js +226 -0
  103. package/dist/components/image-viewer/image-viewer.js.map +1 -0
  104. package/dist/components/image-viewer/index.d.ts +4 -0
  105. package/dist/components/image-viewer/index.d.ts.map +1 -0
  106. package/dist/components/image-viewer/progressive-image.d.ts +20 -0
  107. package/dist/components/image-viewer/progressive-image.d.ts.map +1 -0
  108. package/dist/components/image-viewer/progressive-image.js +62 -0
  109. package/dist/components/image-viewer/progressive-image.js.map +1 -0
  110. package/dist/components/image-viewer/viewable-image.d.ts +17 -0
  111. package/dist/components/image-viewer/viewable-image.d.ts.map +1 -0
  112. package/dist/components/image-viewer/viewable-image.js +38 -0
  113. package/dist/components/image-viewer/viewable-image.js.map +1 -0
  114. package/dist/components/input/index.d.ts +3 -0
  115. package/dist/components/input/index.d.ts.map +1 -0
  116. package/dist/components/input/input.d.ts +15 -0
  117. package/dist/components/input/input.d.ts.map +1 -0
  118. package/dist/components/input/input.js +56 -0
  119. package/dist/components/input/input.js.map +1 -0
  120. package/dist/components/modal/index.d.ts +5 -0
  121. package/dist/components/modal/index.d.ts.map +1 -0
  122. package/dist/components/modal/modal-context.d.ts +37 -0
  123. package/dist/components/modal/modal-context.d.ts.map +1 -0
  124. package/dist/components/modal/modal-context.js +81 -0
  125. package/dist/components/modal/modal-context.js.map +1 -0
  126. package/dist/components/modal/modal.d.ts +28 -0
  127. package/dist/components/modal/modal.d.ts.map +1 -0
  128. package/dist/components/modal/modal.js +94 -0
  129. package/dist/components/modal/modal.js.map +1 -0
  130. package/dist/components/nav-2d/index.d.ts +3 -0
  131. package/dist/components/nav-2d/index.d.ts.map +1 -0
  132. package/dist/components/nav-2d/nav-2d.d.ts +59 -0
  133. package/dist/components/nav-2d/nav-2d.d.ts.map +1 -0
  134. package/dist/components/nav-2d/nav-2d.js +290 -0
  135. package/dist/components/nav-2d/nav-2d.js.map +1 -0
  136. package/dist/components/phone-preview/index.d.ts +3 -0
  137. package/dist/components/phone-preview/index.d.ts.map +1 -0
  138. package/dist/components/phone-preview/phone-preview.d.ts +45 -0
  139. package/dist/components/phone-preview/phone-preview.d.ts.map +1 -0
  140. package/dist/components/phone-preview/phone-preview.js +117 -0
  141. package/dist/components/phone-preview/phone-preview.js.map +1 -0
  142. package/dist/components/progressive-bash/index.d.ts +7 -0
  143. package/dist/components/progressive-bash/index.d.ts.map +1 -0
  144. package/dist/components/progressive-bash/parse.d.ts +88 -0
  145. package/dist/components/progressive-bash/parse.d.ts.map +1 -0
  146. package/dist/components/progressive-bash/parse.js +120 -0
  147. package/dist/components/progressive-bash/parse.js.map +1 -0
  148. package/dist/components/progressive-bash/playback.d.ts +50 -0
  149. package/dist/components/progressive-bash/playback.d.ts.map +1 -0
  150. package/dist/components/progressive-bash/playback.js +19 -0
  151. package/dist/components/progressive-bash/playback.js.map +1 -0
  152. package/dist/components/progressive-bash/progressive-bash.d.ts +97 -0
  153. package/dist/components/progressive-bash/progressive-bash.d.ts.map +1 -0
  154. package/dist/components/progressive-bash/progressive-bash.js +377 -0
  155. package/dist/components/progressive-bash/progressive-bash.js.map +1 -0
  156. package/dist/components/progressive-list/index.d.ts +3 -0
  157. package/dist/components/progressive-list/index.d.ts.map +1 -0
  158. package/dist/components/progressive-list/progressive-list.d.ts +55 -0
  159. package/dist/components/progressive-list/progressive-list.d.ts.map +1 -0
  160. package/dist/components/progressive-list/progressive-list.js +83 -0
  161. package/dist/components/progressive-list/progressive-list.js.map +1 -0
  162. package/dist/components/progressive-table/index.d.ts +3 -0
  163. package/dist/components/progressive-table/index.d.ts.map +1 -0
  164. package/dist/components/progressive-table/progressive-table.d.ts +58 -0
  165. package/dist/components/progressive-table/progressive-table.d.ts.map +1 -0
  166. package/dist/components/progressive-table/progressive-table.js +86 -0
  167. package/dist/components/progressive-table/progressive-table.js.map +1 -0
  168. package/dist/components/progressive-text/index.d.ts +3 -0
  169. package/dist/components/progressive-text/index.d.ts.map +1 -0
  170. package/dist/components/progressive-text/progressive-text.d.ts +54 -0
  171. package/dist/components/progressive-text/progressive-text.d.ts.map +1 -0
  172. package/dist/components/progressive-text/progressive-text.js +97 -0
  173. package/dist/components/progressive-text/progressive-text.js.map +1 -0
  174. package/dist/components/progressive-timeline/index.d.ts +3 -0
  175. package/dist/components/progressive-timeline/index.d.ts.map +1 -0
  176. package/dist/components/progressive-timeline/progressive-timeline.d.ts +46 -0
  177. package/dist/components/progressive-timeline/progressive-timeline.d.ts.map +1 -0
  178. package/dist/components/progressive-timeline/progressive-timeline.js +62 -0
  179. package/dist/components/progressive-timeline/progressive-timeline.js.map +1 -0
  180. package/dist/components/relative-time/index.d.ts +3 -0
  181. package/dist/components/relative-time/index.d.ts.map +1 -0
  182. package/dist/components/relative-time/relative-time.d.ts +14 -0
  183. package/dist/components/relative-time/relative-time.d.ts.map +1 -0
  184. package/dist/components/relative-time/relative-time.js +15 -0
  185. package/dist/components/relative-time/relative-time.js.map +1 -0
  186. package/dist/components/resizable-layout/index.d.ts +3 -0
  187. package/dist/components/resizable-layout/index.d.ts.map +1 -0
  188. package/dist/components/resizable-layout/resizable-layout.d.ts +113 -0
  189. package/dist/components/resizable-layout/resizable-layout.d.ts.map +1 -0
  190. package/dist/components/resizable-layout/resizable-layout.js +398 -0
  191. package/dist/components/resizable-layout/resizable-layout.js.map +1 -0
  192. package/dist/components/rich-input/compose.d.ts +13 -0
  193. package/dist/components/rich-input/compose.d.ts.map +1 -0
  194. package/dist/components/rich-input/compose.js +28 -0
  195. package/dist/components/rich-input/compose.js.map +1 -0
  196. package/dist/components/rich-input/index.d.ts +5 -0
  197. package/dist/components/rich-input/index.d.ts.map +1 -0
  198. package/dist/components/rich-input/parts.d.ts +53 -0
  199. package/dist/components/rich-input/parts.d.ts.map +1 -0
  200. package/dist/components/rich-input/parts.js +285 -0
  201. package/dist/components/rich-input/parts.js.map +1 -0
  202. package/dist/components/rich-input/rich-input.d.ts +64 -0
  203. package/dist/components/rich-input/rich-input.d.ts.map +1 -0
  204. package/dist/components/rich-input/rich-input.js +351 -0
  205. package/dist/components/rich-input/rich-input.js.map +1 -0
  206. package/dist/components/rich-input/types.d.ts +92 -0
  207. package/dist/components/rich-input/types.d.ts.map +1 -0
  208. package/dist/components/rich-input/use-draft.d.ts +9 -0
  209. package/dist/components/rich-input/use-draft.d.ts.map +1 -0
  210. package/dist/components/rich-input/use-draft.js +47 -0
  211. package/dist/components/rich-input/use-draft.js.map +1 -0
  212. package/dist/components/rich-input/use-file-upload.d.ts +18 -0
  213. package/dist/components/rich-input/use-file-upload.d.ts.map +1 -0
  214. package/dist/components/rich-input/use-file-upload.js +88 -0
  215. package/dist/components/rich-input/use-file-upload.js.map +1 -0
  216. package/dist/components/rich-input/use-guidelines.d.ts +16 -0
  217. package/dist/components/rich-input/use-guidelines.d.ts.map +1 -0
  218. package/dist/components/rich-input/use-guidelines.js +85 -0
  219. package/dist/components/rich-input/use-guidelines.js.map +1 -0
  220. package/dist/components/rich-input/use-input-history.d.ts +22 -0
  221. package/dist/components/rich-input/use-input-history.d.ts.map +1 -0
  222. package/dist/components/rich-input/use-input-history.js +61 -0
  223. package/dist/components/rich-input/use-input-history.js.map +1 -0
  224. package/dist/components/rich-input/use-mention.d.ts +24 -0
  225. package/dist/components/rich-input/use-mention.d.ts.map +1 -0
  226. package/dist/components/rich-input/use-mention.js +54 -0
  227. package/dist/components/rich-input/use-mention.js.map +1 -0
  228. package/dist/components/search-input/index.d.ts +3 -0
  229. package/dist/components/search-input/index.d.ts.map +1 -0
  230. package/dist/components/search-input/search-input.d.ts +14 -0
  231. package/dist/components/search-input/search-input.d.ts.map +1 -0
  232. package/dist/components/search-input/search-input.js +63 -0
  233. package/dist/components/search-input/search-input.js.map +1 -0
  234. package/dist/components/skeleton/index.d.ts +3 -0
  235. package/dist/components/skeleton/index.d.ts.map +1 -0
  236. package/dist/components/skeleton/skeleton.d.ts +19 -0
  237. package/dist/components/skeleton/skeleton.d.ts.map +1 -0
  238. package/dist/components/skeleton/skeleton.js +29 -0
  239. package/dist/components/skeleton/skeleton.js.map +1 -0
  240. package/dist/components/spinner/index.d.ts +3 -0
  241. package/dist/components/spinner/index.d.ts.map +1 -0
  242. package/dist/components/spinner/spinner.d.ts +11 -0
  243. package/dist/components/spinner/spinner.d.ts.map +1 -0
  244. package/dist/components/spinner/spinner.js +32 -0
  245. package/dist/components/spinner/spinner.js.map +1 -0
  246. package/dist/components/status-badge/index.d.ts +3 -0
  247. package/dist/components/status-badge/index.d.ts.map +1 -0
  248. package/dist/components/status-badge/status-badge.d.ts +31 -0
  249. package/dist/components/status-badge/status-badge.d.ts.map +1 -0
  250. package/dist/components/status-badge/status-badge.js +53 -0
  251. package/dist/components/status-badge/status-badge.js.map +1 -0
  252. package/dist/components/theme/index.d.ts +5 -0
  253. package/dist/components/theme/index.d.ts.map +1 -0
  254. package/dist/components/theme/theme-toggle.d.ts +11 -0
  255. package/dist/components/theme/theme-toggle.d.ts.map +1 -0
  256. package/dist/components/theme/theme-toggle.js +57 -0
  257. package/dist/components/theme/theme-toggle.js.map +1 -0
  258. package/dist/components/theme/theme.d.ts +29 -0
  259. package/dist/components/theme/theme.d.ts.map +1 -0
  260. package/dist/components/theme/theme.js +70 -0
  261. package/dist/components/theme/theme.js.map +1 -0
  262. package/dist/components/toast/index.d.ts +3 -0
  263. package/dist/components/toast/index.d.ts.map +1 -0
  264. package/dist/components/toast/toast.d.ts +64 -0
  265. package/dist/components/toast/toast.d.ts.map +1 -0
  266. package/dist/components/toast/toast.js +155 -0
  267. package/dist/components/toast/toast.js.map +1 -0
  268. package/dist/components/virtual-list/index.d.ts +3 -0
  269. package/dist/components/virtual-list/index.d.ts.map +1 -0
  270. package/dist/components/virtual-list/virtual-list.d.ts +71 -0
  271. package/dist/components/virtual-list/virtual-list.d.ts.map +1 -0
  272. package/dist/components/virtual-list/virtual-list.js +65 -0
  273. package/dist/components/virtual-list/virtual-list.js.map +1 -0
  274. package/dist/hooks/index.d.ts +12 -0
  275. package/dist/hooks/index.d.ts.map +1 -0
  276. package/dist/hooks/use-copy-to-clipboard.d.ts +26 -0
  277. package/dist/hooks/use-copy-to-clipboard.d.ts.map +1 -0
  278. package/dist/hooks/use-copy-to-clipboard.js +36 -0
  279. package/dist/hooks/use-copy-to-clipboard.js.map +1 -0
  280. package/dist/hooks/use-debounced-value.d.ts +23 -0
  281. package/dist/hooks/use-debounced-value.d.ts.map +1 -0
  282. package/dist/hooks/use-debounced-value.js +19 -0
  283. package/dist/hooks/use-debounced-value.js.map +1 -0
  284. package/dist/hooks/use-intersection.d.ts +25 -0
  285. package/dist/hooks/use-intersection.d.ts.map +1 -0
  286. package/dist/hooks/use-intersection.js +38 -0
  287. package/dist/hooks/use-intersection.js.map +1 -0
  288. package/dist/hooks/use-local-storage.d.ts +12 -0
  289. package/dist/hooks/use-local-storage.d.ts.map +1 -0
  290. package/dist/hooks/use-local-storage.js +43 -0
  291. package/dist/hooks/use-local-storage.js.map +1 -0
  292. package/dist/hooks/use-long-press.d.ts +37 -0
  293. package/dist/hooks/use-long-press.d.ts.map +1 -0
  294. package/dist/hooks/use-long-press.js +39 -0
  295. package/dist/hooks/use-long-press.js.map +1 -0
  296. package/dist/hooks/use-media-query.d.ts +17 -0
  297. package/dist/hooks/use-media-query.d.ts.map +1 -0
  298. package/dist/hooks/use-media-query.js +37 -0
  299. package/dist/hooks/use-media-query.js.map +1 -0
  300. package/dist/hooks/use-overlay.d.ts +20 -0
  301. package/dist/hooks/use-overlay.d.ts.map +1 -0
  302. package/dist/hooks/use-overlay.js +42 -0
  303. package/dist/hooks/use-overlay.js.map +1 -0
  304. package/dist/image-viewer.css +152 -0
  305. package/dist/index.d.ts +67 -0
  306. package/dist/index.d.ts.map +1 -0
  307. package/dist/index.js +161 -0
  308. package/dist/index.js.map +1 -0
  309. package/dist/lib/format.d.ts +19 -0
  310. package/dist/lib/format.d.ts.map +1 -0
  311. package/dist/lib/format.js +62 -0
  312. package/dist/lib/format.js.map +1 -0
  313. package/dist/lib/highlight.d.ts +15 -0
  314. package/dist/lib/highlight.d.ts.map +1 -0
  315. package/dist/lib/highlight.js +39 -0
  316. package/dist/lib/highlight.js.map +1 -0
  317. package/dist/lib/search.d.ts +40 -0
  318. package/dist/lib/search.d.ts.map +1 -0
  319. package/dist/lib/search.js +91 -0
  320. package/dist/lib/search.js.map +1 -0
  321. package/dist/lib/utils.d.ts +4 -0
  322. package/dist/lib/utils.d.ts.map +1 -0
  323. package/dist/lib/utils.js +9 -0
  324. package/dist/lib/utils.js.map +1 -0
  325. package/dist/overlay.css +78 -0
  326. package/dist/styles.css +6 -0
  327. package/dist/theme.css +81 -0
  328. package/dist/tooltip.css +53 -0
  329. package/dist/virtual-list.css +29 -0
  330. package/package.json +77 -0
@@ -0,0 +1,351 @@
1
+ import { jsxs as h, jsx as n, Fragment as Be } from "react/jsx-runtime";
2
+ import { forwardRef as Ke, useRef as F, useState as d, useCallback as l, useEffect as w, useLayoutEffect as Ve, useImperativeHandle as Qe } from "react";
3
+ import { Upload as _e, Loader2 as $e, Paperclip as Ge, History as Je, SendHorizontal as Xe } from "lucide-react";
4
+ import { cn as W } from "../../lib/utils.js";
5
+ import { useFileDrop as Ye } from "../drop-zone/use-file-drop.js";
6
+ import { defaultComposePrompt as Ze } from "./compose.js";
7
+ import { useDraft as We } from "./use-draft.js";
8
+ import { useFileUpload as et } from "./use-file-upload.js";
9
+ import { useGuidelines as tt } from "./use-guidelines.js";
10
+ import { useInputHistory as rt } from "./use-input-history.js";
11
+ import { useMention as nt } from "./use-mention.js";
12
+ import { UnsendBanner as st, ReverseSearchBar as ot, MentionMenu as it, AttachmentChips as lt, TagChips as ct, GuidelinesSwitch as at, TagScrollList as ut, HistorySheet as dt } from "./parts.js";
13
+ const he = 22, Dt = Ke(function({
14
+ defaultValue: N = "",
15
+ placeholder: q = "Type a message…",
16
+ disabled: v = !1,
17
+ className: M,
18
+ autoFocus: xe = !1,
19
+ minRows: ye = 2,
20
+ maxRows: O = 12,
21
+ onSubmit: S,
22
+ undoWindowMs: D = 3e3,
23
+ submitKey: j = "enter",
24
+ cacheKey: ee,
25
+ cacheLocation: be = "local",
26
+ uploadFiles: k,
27
+ accept: C,
28
+ maxFiles: T,
29
+ fileFilter: we,
30
+ fileDrop: Ne,
31
+ dropDirectories: Se = !0,
32
+ tags: te = [],
33
+ onTagsChange: A,
34
+ guidelines: De,
35
+ guidelinesToggle: U = !1,
36
+ defaultGuidelinesOn: ke = !0,
37
+ onGuidelinesToggle: R,
38
+ tagListRows: Ce = 3,
39
+ showMax: Ae,
40
+ mentionPrefix: re = "#",
41
+ history: m = !0,
42
+ composePrompt: ne = Ze,
43
+ toolbarExtra: Re
44
+ }, He) {
45
+ const a = F(null), se = F(null), [i, B, oe] = We(ee, be), [ie, ze] = d(!1), o = tt(te), r = et({ upload: k, accept: C, maxFiles: T, filter: we }), s = rt(m ? ee ?? "default" : null), Ie = k !== void 0 || C !== void 0 || T !== void 0, K = v || r.uploading, V = Ye({
46
+ onFiles: (e) => void r.add(e),
47
+ disabled: !(Ne ?? Ie) || K,
48
+ recursive: Se
49
+ }), [Q, Ee] = d(!1), [Pe, le] = d(!1), [Fe, _] = d(!1), [H, Le] = d(ke), $ = !U || H, [f, x] = d(null), [z, G] = d(null), [qe, ce] = d(0), y = F(null), I = F(null), c = l(
50
+ (e) => {
51
+ B(e);
52
+ },
53
+ [B]
54
+ );
55
+ w(() => {
56
+ ie || (ze(!0), N && !i && B(N));
57
+ }, [ie]), w(() => {
58
+ var g;
59
+ if (typeof window > "u" || !window.matchMedia) return;
60
+ const e = window.matchMedia("(pointer: coarse)"), t = () => Ee(e.matches);
61
+ return t(), (g = e.addEventListener) == null || g.call(e, "change", t), () => {
62
+ var P;
63
+ return (P = e.removeEventListener) == null ? void 0 : P.call(e, "change", t);
64
+ };
65
+ }, []), w(() => A == null ? void 0 : A(o.active), [o.active, A]), w(() => R == null ? void 0 : R(H), [H, R]);
66
+ const u = nt({
67
+ tags: te,
68
+ value: i,
69
+ setValue: c,
70
+ taRef: a,
71
+ prefix: re,
72
+ onPick: (e) => o.setOn(e.id, !0)
73
+ });
74
+ Ve(() => {
75
+ const e = a.current;
76
+ e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, O * he)}px`);
77
+ }, [i, O]);
78
+ const p = l(() => {
79
+ y.current && clearTimeout(y.current), I.current && clearInterval(I.current), y.current = null, I.current = null;
80
+ }, []);
81
+ w(() => () => p(), [p]);
82
+ const E = l(() => {
83
+ oe(), r.reset(), o.clear(), le(!1), s.resetCursor();
84
+ }, [oe, r, o, s]), J = o.toggles.filter((e) => (e.group ?? "guideline") !== "tag"), ae = o.toggles.filter((e) => e.group === "tag"), ue = (De ?? J.length > 0) && $, de = l(() => {
85
+ const e = i.trim();
86
+ if (!e && r.files.length === 0 || r.uploading) return null;
87
+ const t = $ ? o.lines : [], g = ne({ text: e, guidelines: t, tags: o.active, files: r.files });
88
+ return { text: e, prompt: g, files: r.files, tags: o.active };
89
+ }, [i, r.files, r.uploading, ne, o.lines, o.active, $]), X = l(
90
+ (e) => {
91
+ S == null || S(e);
92
+ },
93
+ [S]
94
+ ), b = l(() => {
95
+ const e = de();
96
+ if (e) {
97
+ if (s.push(e.text), E(), D <= 0) {
98
+ X(e);
99
+ return;
100
+ }
101
+ p(), G(e), ce(Math.ceil(D / 1e3)), I.current = setInterval(() => ce((t) => Math.max(0, t - 1)), 1e3), y.current = setTimeout(() => {
102
+ p(), G(null), X(e);
103
+ }, D);
104
+ }
105
+ }, [de, s, E, D, p, X]), Y = l(() => {
106
+ if (!y.current || !z) return null;
107
+ p();
108
+ const e = z;
109
+ G(null), c(e.text), r.setFiles(e.files);
110
+ for (const t of e.tags) o.setOn(t.id, !0);
111
+ return requestAnimationFrame(() => {
112
+ var t;
113
+ return (t = a.current) == null ? void 0 : t.focus();
114
+ }), e;
115
+ }, [z, p, c, r, o]);
116
+ Qe(
117
+ He,
118
+ () => ({
119
+ focus: () => {
120
+ var e;
121
+ return (e = a.current) == null ? void 0 : e.focus();
122
+ },
123
+ blur: () => {
124
+ var e;
125
+ return (e = a.current) == null ? void 0 : e.blur();
126
+ },
127
+ clear: () => E(),
128
+ getValue: () => i,
129
+ setValue: (e) => c(e),
130
+ setFiles: (e) => r.setFiles(e),
131
+ submit: b,
132
+ cancelSend: Y
133
+ }),
134
+ [E, i, c, r, b, Y]
135
+ );
136
+ const fe = l(() => {
137
+ const e = a.current, t = s.prev(i);
138
+ return t == null ? !1 : (c(t), requestAnimationFrame(() => e == null ? void 0 : e.setSelectionRange(t.length, t.length)), !0);
139
+ }, [s, i, c]), pe = l(() => {
140
+ const e = s.next();
141
+ if (e == null) return !1;
142
+ c(e);
143
+ const t = a.current;
144
+ return requestAnimationFrame(() => t == null ? void 0 : t.setSelectionRange(e.length, e.length)), !0;
145
+ }, [s, c]), me = l(() => {
146
+ s.resetSearch(), x({ query: "", match: null });
147
+ }, [s]), Me = l(
148
+ (e) => x({ query: e, match: s.reverseSearch(e) }),
149
+ [s]
150
+ ), Oe = l(
151
+ () => x((e) => e && { ...e, match: s.reverseSearch(e.query, !0) }),
152
+ [s]
153
+ ), je = l(() => {
154
+ const e = f == null ? void 0 : f.match;
155
+ x(null), e != null && (c(e), requestAnimationFrame(() => {
156
+ const t = a.current;
157
+ t == null || t.focus(), t == null || t.setSelectionRange(e.length, e.length);
158
+ }));
159
+ }, [f, c]), Te = l(
160
+ (e) => {
161
+ if (u.onKeyDown(e)) return;
162
+ if (e.ctrlKey && e.key.toLowerCase() === "r" && m) {
163
+ e.preventDefault(), me();
164
+ return;
165
+ }
166
+ const t = e.currentTarget, g = t.selectionStart === 0 && t.selectionEnd === 0, P = t.selectionStart === i.length && t.selectionEnd === i.length;
167
+ if (e.key === "ArrowUp" && m && g && fe()) {
168
+ e.preventDefault();
169
+ return;
170
+ }
171
+ if (e.key === "ArrowDown" && m && s.browsing && P && pe()) {
172
+ e.preventDefault();
173
+ return;
174
+ }
175
+ if (e.key === "Enter") {
176
+ const Z = e.metaKey || e.ctrlKey, Ue = j === "mod+enter" ? Z : !e.shiftKey && (Q ? Z : !0);
177
+ if (Q && j !== "mod+enter" && !Z) return;
178
+ Ue && (e.preventDefault(), b());
179
+ }
180
+ },
181
+ [u, m, me, i.length, fe, pe, s.browsing, j, Q, b]
182
+ ), ge = (i.trim().length > 0 || r.files.length > 0) && !K;
183
+ return /* @__PURE__ */ h("div", { className: W("flex flex-col gap-2", M), children: [
184
+ z ? /* @__PURE__ */ n(st, { countdown: qe, onUndo: Y }) : /* @__PURE__ */ h(
185
+ "div",
186
+ {
187
+ ...V.rootProps,
188
+ className: W(
189
+ "relative rounded-2xl border border-input bg-card p-2 transition-colors focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/40",
190
+ v && "opacity-60",
191
+ V.dragging && "border-primary ring-2 ring-primary/40"
192
+ ),
193
+ children: [
194
+ V.dragging && /* @__PURE__ */ h("div", { className: "pointer-events-none absolute inset-0 z-20 flex items-center justify-center gap-2 rounded-2xl border-2 border-dashed border-primary/60 bg-card/80 text-xs font-medium text-primary", children: [
195
+ /* @__PURE__ */ n(_e, { className: "size-4" }),
196
+ "Drop files to attach"
197
+ ] }),
198
+ f ? /* @__PURE__ */ n(
199
+ ot,
200
+ {
201
+ query: f.query,
202
+ match: f.match,
203
+ onQueryChange: Me,
204
+ onNext: Oe,
205
+ onAccept: je,
206
+ onClose: () => x(null)
207
+ }
208
+ ) : u.open ? /* @__PURE__ */ n(
209
+ it,
210
+ {
211
+ matches: u.matches,
212
+ active: u.active,
213
+ prefix: re,
214
+ onHover: u.setActive,
215
+ onPick: u.pick
216
+ }
217
+ ) : null,
218
+ /* @__PURE__ */ n(lt, { files: r.files, onRemove: r.remove }),
219
+ /* @__PURE__ */ n(
220
+ "textarea",
221
+ {
222
+ ref: a,
223
+ value: i,
224
+ disabled: v,
225
+ autoFocus: xe,
226
+ placeholder: q,
227
+ rows: ye,
228
+ onChange: (e) => {
229
+ c(e.target.value), s.resetCursor(), u.syncCaret();
230
+ },
231
+ onSelect: u.syncCaret,
232
+ onKeyDown: Te,
233
+ onPaste: (e) => {
234
+ k && e.clipboardData.files.length > 0 && (e.preventDefault(), r.add(e.clipboardData.files));
235
+ },
236
+ style: { maxHeight: O * he },
237
+ className: "w-full resize-none bg-transparent px-2 py-1 text-sm leading-[22px] text-foreground outline-none placeholder:text-muted-foreground"
238
+ }
239
+ ),
240
+ (U || ue && J.length > 0) && /* @__PURE__ */ n("div", { className: "px-1 pt-1.5", children: /* @__PURE__ */ n(
241
+ ct,
242
+ {
243
+ tags: ue ? J : [],
244
+ selected: o.selected,
245
+ onToggle: o.toggle,
246
+ showMax: Ae,
247
+ expanded: Pe,
248
+ onExpand: () => le(!0),
249
+ leading: U ? /* @__PURE__ */ n(at, { on: H, onToggle: () => Le((e) => !e) }) : void 0
250
+ }
251
+ ) }),
252
+ ae.length > 0 && /* @__PURE__ */ n("div", { className: "px-1 pt-1.5", children: /* @__PURE__ */ n(
253
+ ut,
254
+ {
255
+ tags: ae,
256
+ selected: o.selected,
257
+ onToggle: o.toggle,
258
+ rows: Ce
259
+ }
260
+ ) }),
261
+ r.error && /* @__PURE__ */ n("p", { className: "px-2 pt-1 text-xs text-destructive", children: r.error }),
262
+ /* @__PURE__ */ h("div", { className: "mt-1.5 flex items-center gap-1.5 px-1", children: [
263
+ k !== void 0 || C !== void 0 || T !== void 0 ? /* @__PURE__ */ h(Be, { children: [
264
+ /* @__PURE__ */ n(
265
+ "input",
266
+ {
267
+ ref: se,
268
+ type: "file",
269
+ multiple: !0,
270
+ accept: C,
271
+ className: "hidden",
272
+ onChange: (e) => void r.add(e.target.files),
273
+ onClick: (e) => {
274
+ e.currentTarget.value = "";
275
+ }
276
+ }
277
+ ),
278
+ /* @__PURE__ */ n(
279
+ ve,
280
+ {
281
+ label: "Attach files",
282
+ disabled: K,
283
+ onClick: () => {
284
+ var e;
285
+ return (e = se.current) == null ? void 0 : e.click();
286
+ },
287
+ children: r.uploading ? /* @__PURE__ */ n($e, { className: "size-4 animate-spin" }) : /* @__PURE__ */ n(Ge, { className: "size-4" })
288
+ }
289
+ )
290
+ ] }) : null,
291
+ Re,
292
+ /* @__PURE__ */ h("div", { className: "ml-auto flex items-center gap-1.5", children: [
293
+ m && s.entries.length > 0 && /* @__PURE__ */ n(ve, { label: "History", onClick: () => _(!0), children: /* @__PURE__ */ n(Je, { className: "size-4" }) }),
294
+ /* @__PURE__ */ n(
295
+ "button",
296
+ {
297
+ type: "button",
298
+ "aria-label": "Send",
299
+ disabled: !ge,
300
+ onClick: b,
301
+ className: W(
302
+ "inline-flex size-8 items-center justify-center rounded-lg transition-colors",
303
+ ge ? "bg-primary text-primary-foreground hover:bg-primary/90" : "bg-muted text-muted-foreground"
304
+ ),
305
+ children: /* @__PURE__ */ n(Xe, { className: "size-4" })
306
+ }
307
+ )
308
+ ] })
309
+ ] })
310
+ ]
311
+ }
312
+ ),
313
+ Fe && /* @__PURE__ */ n(
314
+ dt,
315
+ {
316
+ entries: s.entries,
317
+ onClose: () => _(!1),
318
+ onPick: (e) => {
319
+ c(e), _(!1), requestAnimationFrame(() => {
320
+ const t = a.current;
321
+ t == null || t.focus(), t == null || t.setSelectionRange(e.length, e.length);
322
+ });
323
+ }
324
+ }
325
+ )
326
+ ] });
327
+ });
328
+ function ve({
329
+ label: L,
330
+ disabled: N,
331
+ onClick: q,
332
+ children: v
333
+ }) {
334
+ return /* @__PURE__ */ n(
335
+ "button",
336
+ {
337
+ type: "button",
338
+ "aria-label": L,
339
+ title: L,
340
+ disabled: N,
341
+ onMouseDown: (M) => M.preventDefault(),
342
+ onClick: q,
343
+ className: "inline-flex size-8 items-center justify-center rounded-lg border border-transparent text-muted-foreground transition-colors hover:border-input hover:text-foreground disabled:opacity-50",
344
+ children: v
345
+ }
346
+ );
347
+ }
348
+ export {
349
+ Dt as RichInput
350
+ };
351
+ //# sourceMappingURL=rich-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rich-input.js","sources":["../../../src/components/rich-input/rich-input.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport { History, Loader2, Paperclip, SendHorizontal, Upload } from 'lucide-react';\n\nimport { cn } from '../../lib/utils';\nimport { useFileDrop } from '../drop-zone/use-file-drop';\nimport { defaultComposePrompt } from './compose';\nimport { useDraft } from './use-draft';\nimport { useFileUpload } from './use-file-upload';\nimport { useGuidelines } from './use-guidelines';\nimport { useInputHistory } from './use-input-history';\nimport { useMention } from './use-mention';\nimport {\n AttachmentChips,\n GuidelinesSwitch,\n HistorySheet,\n MentionMenu,\n ReverseSearchBar,\n TagChips,\n TagScrollList,\n UnsendBanner,\n} from './parts';\nimport type { ComposeInput, GuidelineTag, RichFile, RichInputHandle, RichSendPayload } from './types';\n\nconst LINE_HEIGHT = 22;\n\nexport interface RichInputProps {\n /** Initial text (ignored when a cached draft exists). */\n defaultValue?: string;\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n autoFocus?: boolean;\n minRows?: number;\n maxRows?: number;\n\n /** Fired once the un-send window elapses (or immediately when it is 0). */\n onSubmit?: (payload: RichSendPayload) => void | Promise<void>;\n /** ms to hold a submission so it can be un-sent. 0 disables. Default 3000. */\n undoWindowMs?: number;\n /** `'enter'` (default): Enter submits, Shift+Enter newline. `'mod+enter'`: ⌘/Ctrl+Enter submits. */\n submitKey?: 'enter' | 'mod+enter';\n\n /** Persist the draft under this key (localStorage). Also namespaces history. */\n cacheKey?: string;\n cacheLocation?: 'local' | 'session';\n\n /** Upload handler. Omit to keep files client-side (object URLs). */\n uploadFiles?: (files: File[]) => Promise<RichFile[]>;\n accept?: string;\n maxFiles?: number;\n fileFilter?: (file: File) => boolean | string;\n /**\n * Attach files dropped anywhere on the composer. On by default whenever file\n * support is (i.e. one of `uploadFiles` / `accept` / `maxFiles` is set); the\n * drops go through the same `accept` / `maxFiles` / `fileFilter` checks as the\n * paperclip. Dragged text still drops into the textarea as usual.\n */\n fileDrop?: boolean;\n /** Expand dropped folders into their files (Chromium/WebKit). Default true. */\n dropDirectories?: boolean;\n\n /** Guideline / mention tags. */\n tags?: GuidelineTag[];\n onTagsChange?: (active: GuidelineTag[]) => void;\n /** Show the guideline toggle chip row. Defaults to true when toggle tags exist. */\n guidelines?: boolean;\n /**\n * Render a built-in on/off master switch for the guideline chips. When off,\n * the guideline lines are dropped from the composed prompt and the guideline\n * chip row is hidden; `group: 'tag'` chips are unaffected. Default false.\n */\n guidelinesToggle?: boolean;\n /** Initial state of the guidelines master switch. Default true. */\n defaultGuidelinesOn?: boolean;\n /** Notified when the guidelines master switch flips. */\n onGuidelinesToggle?: (on: boolean) => void;\n /** Height (in chip rows) of the scrollable `group: 'tag'` list. Default 3. */\n tagListRows?: number;\n /** Chips shown before a \"+N more\" button. */\n showMax?: number;\n /** Mention trigger symbol. Default `#`. */\n mentionPrefix?: string;\n\n /** Enable Up-arrow / Ctrl+R history + the mobile history sheet. Default true. */\n history?: boolean;\n\n /** Override how the final prompt string is composed. */\n composePrompt?: (input: ComposeInput) => string;\n\n /** Extra buttons rendered in the toolbar's left cluster. */\n toolbarExtra?: ReactNode;\n}\n\nexport const RichInput = forwardRef<RichInputHandle, RichInputProps>(function RichInput(\n {\n defaultValue = '',\n placeholder = 'Type a message…',\n disabled = false,\n className,\n autoFocus = false,\n minRows = 2,\n maxRows = 12,\n onSubmit,\n undoWindowMs = 3000,\n submitKey = 'enter',\n cacheKey,\n cacheLocation = 'local',\n uploadFiles,\n accept,\n maxFiles,\n fileFilter,\n fileDrop,\n dropDirectories = true,\n tags = [],\n onTagsChange,\n guidelines,\n guidelinesToggle = false,\n defaultGuidelinesOn = true,\n onGuidelinesToggle,\n tagListRows = 3,\n showMax,\n mentionPrefix = '#',\n history: historyEnabled = true,\n composePrompt = defaultComposePrompt,\n toolbarExtra,\n },\n ref,\n) {\n const taRef = useRef<HTMLTextAreaElement>(null);\n const fileRef = useRef<HTMLInputElement>(null);\n\n const [value, setValueRaw, clearDraft] = useDraft(cacheKey, cacheLocation);\n const [seeded, setSeeded] = useState(false);\n const gl = useGuidelines(tags);\n const files = useFileUpload({ upload: uploadFiles, accept, maxFiles, filter: fileFilter });\n const hist = useInputHistory(historyEnabled ? (cacheKey ?? 'default') : null);\n\n const filesEnabled = uploadFiles !== undefined || accept !== undefined || maxFiles !== undefined;\n const busy = disabled || files.uploading;\n\n // A drop is just another way to pick files: useFileDrop only hands us the\n // dragged files (expanding folders), `files.add` still runs the accept /\n // maxFiles / fileFilter checks and surfaces the same errors as the paperclip.\n const drop = useFileDrop({\n onFiles: (list) => void files.add(list),\n disabled: !(fileDrop ?? filesEnabled) || busy,\n recursive: dropDirectories,\n });\n\n const [coarse, setCoarse] = useState(false);\n const [expanded, setExpanded] = useState(false);\n const [sheetOpen, setSheetOpen] = useState(false);\n\n // Guideline master switch (only surfaced when `guidelinesToggle` is set).\n const [guidelinesOn, setGuidelinesOn] = useState(defaultGuidelinesOn);\n const guidelinesActive = !guidelinesToggle || guidelinesOn;\n\n // Reverse search (Ctrl+R).\n const [rsearch, setRsearch] = useState<{ query: string; match: string | null } | null>(null);\n\n // Un-send window.\n const [pending, setPending] = useState<RichSendPayload | null>(null);\n const [countdown, setCountdown] = useState(0);\n const queueTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const tickTimer = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const setValue = useCallback(\n (v: string) => {\n setValueRaw(v);\n },\n [setValueRaw],\n );\n\n // Seed the initial defaultValue once (only when there is no cached draft).\n useEffect(() => {\n if (seeded) return;\n setSeeded(true);\n if (defaultValue && !value) setValueRaw(defaultValue);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [seeded]);\n\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return;\n const mq = window.matchMedia('(pointer: coarse)');\n const update = () => setCoarse(mq.matches);\n update();\n mq.addEventListener?.('change', update);\n return () => mq.removeEventListener?.('change', update);\n }, []);\n\n useEffect(() => onTagsChange?.(gl.active), [gl.active, onTagsChange]);\n useEffect(() => onGuidelinesToggle?.(guidelinesOn), [guidelinesOn, onGuidelinesToggle]);\n\n const mention = useMention({\n tags,\n value,\n setValue,\n taRef,\n prefix: mentionPrefix,\n onPick: (tag) => gl.setOn(tag.id, true),\n });\n\n // Auto-grow the textarea between min/max rows.\n useLayoutEffect(() => {\n const el = taRef.current;\n if (!el) return;\n el.style.height = 'auto';\n el.style.height = `${Math.min(el.scrollHeight, maxRows * LINE_HEIGHT)}px`;\n }, [value, maxRows]);\n\n const clearTimers = useCallback(() => {\n if (queueTimer.current) clearTimeout(queueTimer.current);\n if (tickTimer.current) clearInterval(tickTimer.current);\n queueTimer.current = null;\n tickTimer.current = null;\n }, []);\n\n useEffect(() => () => clearTimers(), [clearTimers]);\n\n const resetInput = useCallback(() => {\n clearDraft();\n files.reset();\n gl.clear();\n setExpanded(false);\n hist.resetCursor();\n }, [clearDraft, files, gl, hist]);\n\n // Guideline toggles (default group) vs. scrollable tag toggles (`group: 'tag'`).\n const guidelineToggles = gl.toggles.filter((t) => (t.group ?? 'guideline') !== 'tag');\n const tagToggles = gl.toggles.filter((t) => t.group === 'tag');\n // The guideline chip row shows when there are guideline chips (or forced via\n // `guidelines`), and only while the master switch is on.\n const showGuidelines = (guidelines ?? guidelineToggles.length > 0) && guidelinesActive;\n\n const buildPayload = useCallback((): RichSendPayload | null => {\n const base = value.trim();\n if ((!base && files.files.length === 0) || files.uploading) return null;\n // Master switch off ⇒ drop the guideline lines (send the prompt as typed).\n const lines = guidelinesActive ? gl.lines : [];\n const prompt = composePrompt({ text: base, guidelines: lines, tags: gl.active, files: files.files });\n return { text: base, prompt, files: files.files, tags: gl.active };\n }, [value, files.files, files.uploading, composePrompt, gl.lines, gl.active, guidelinesActive]);\n\n const fire = useCallback(\n (payload: RichSendPayload) => {\n void onSubmit?.(payload);\n },\n [onSubmit],\n );\n\n const submit = useCallback(() => {\n const payload = buildPayload();\n if (!payload) return;\n hist.push(payload.text);\n resetInput();\n\n if (undoWindowMs <= 0) {\n fire(payload);\n return;\n }\n clearTimers();\n setPending(payload);\n setCountdown(Math.ceil(undoWindowMs / 1000));\n tickTimer.current = setInterval(() => setCountdown((c) => Math.max(0, c - 1)), 1000);\n queueTimer.current = setTimeout(() => {\n clearTimers();\n setPending(null);\n fire(payload);\n }, undoWindowMs);\n }, [buildPayload, hist, resetInput, undoWindowMs, clearTimers, fire]);\n\n const cancelSend = useCallback((): RichSendPayload | null => {\n if (!queueTimer.current || !pending) return null;\n clearTimers();\n const restored = pending;\n setPending(null);\n setValue(restored.text);\n files.setFiles(restored.files);\n for (const t of restored.tags) gl.setOn(t.id, true);\n requestAnimationFrame(() => taRef.current?.focus());\n return restored;\n }, [pending, clearTimers, setValue, files, gl]);\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => taRef.current?.focus(),\n blur: () => taRef.current?.blur(),\n clear: () => resetInput(),\n getValue: () => value,\n setValue: (v: string) => setValue(v),\n setFiles: (f) => files.setFiles(f),\n submit,\n cancelSend,\n }),\n [resetInput, value, setValue, files, submit, cancelSend],\n );\n\n /* ── history navigation ──────────────────────────────────────────────── */\n const recallPrev = useCallback(() => {\n const el = taRef.current;\n const got = hist.prev(value);\n if (got == null) return false;\n setValue(got);\n requestAnimationFrame(() => el?.setSelectionRange(got.length, got.length));\n return true;\n }, [hist, value, setValue]);\n\n const recallNext = useCallback(() => {\n const got = hist.next();\n if (got == null) return false;\n setValue(got);\n const el = taRef.current;\n requestAnimationFrame(() => el?.setSelectionRange(got.length, got.length));\n return true;\n }, [hist, setValue]);\n\n /* ── reverse search ──────────────────────────────────────────────────── */\n const openReverse = useCallback(() => {\n hist.resetSearch();\n setRsearch({ query: '', match: null });\n }, [hist]);\n\n const reverseType = useCallback(\n (query: string) => setRsearch({ query, match: hist.reverseSearch(query) }),\n [hist],\n );\n const reverseNext = useCallback(\n () => setRsearch((s) => (s ? { ...s, match: hist.reverseSearch(s.query, true) } : s)),\n [hist],\n );\n const reverseAccept = useCallback(() => {\n const m = rsearch?.match;\n setRsearch(null);\n if (m != null) {\n setValue(m);\n requestAnimationFrame(() => {\n const el = taRef.current;\n el?.focus();\n el?.setSelectionRange(m.length, m.length);\n });\n }\n }, [rsearch, setValue]);\n\n /* ── keyboard ────────────────────────────────────────────────────────── */\n const onKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (mention.onKeyDown(e)) return;\n\n if (e.ctrlKey && e.key.toLowerCase() === 'r' && historyEnabled) {\n e.preventDefault();\n openReverse();\n return;\n }\n\n const el = e.currentTarget;\n const atStart = el.selectionStart === 0 && el.selectionEnd === 0;\n const atEnd = el.selectionStart === value.length && el.selectionEnd === value.length;\n\n if (e.key === 'ArrowUp' && historyEnabled && atStart) {\n if (recallPrev()) {\n e.preventDefault();\n return;\n }\n }\n if (e.key === 'ArrowDown' && historyEnabled && hist.browsing && atEnd) {\n if (recallNext()) {\n e.preventDefault();\n return;\n }\n }\n\n if (e.key === 'Enter') {\n const mod = e.metaKey || e.ctrlKey;\n const wantsSubmit = submitKey === 'mod+enter' ? mod : !e.shiftKey && (coarse ? mod : true);\n // On touch devices, plain Enter always inserts a newline (submit via button).\n if (coarse && submitKey !== 'mod+enter' && !mod) return;\n if (wantsSubmit) {\n e.preventDefault();\n submit();\n }\n }\n },\n [mention, historyEnabled, openReverse, value.length, recallPrev, recallNext, hist.browsing, submitKey, coarse, submit],\n );\n\n const canSend = (value.trim().length > 0 || files.files.length > 0) && !busy;\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {pending ? (\n <UnsendBanner countdown={countdown} onUndo={cancelSend} />\n ) : (\n <div\n {...drop.rootProps}\n className={cn(\n 'relative rounded-2xl border border-input bg-card p-2 transition-colors focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/40',\n disabled && 'opacity-60',\n drop.dragging && 'border-primary ring-2 ring-primary/40',\n )}\n >\n {drop.dragging && (\n <div className=\"pointer-events-none absolute inset-0 z-20 flex items-center justify-center gap-2 rounded-2xl border-2 border-dashed border-primary/60 bg-card/80 text-xs font-medium text-primary\">\n <Upload className=\"size-4\" />\n Drop files to attach\n </div>\n )}\n\n {rsearch ? (\n <ReverseSearchBar\n query={rsearch.query}\n match={rsearch.match}\n onQueryChange={reverseType}\n onNext={reverseNext}\n onAccept={reverseAccept}\n onClose={() => setRsearch(null)}\n />\n ) : mention.open ? (\n <MentionMenu\n matches={mention.matches}\n active={mention.active}\n prefix={mentionPrefix}\n onHover={mention.setActive}\n onPick={mention.pick}\n />\n ) : null}\n\n <AttachmentChips files={files.files} onRemove={files.remove} />\n\n <textarea\n ref={taRef}\n value={value}\n disabled={disabled}\n autoFocus={autoFocus}\n placeholder={placeholder}\n rows={minRows}\n onChange={(e) => {\n setValue(e.target.value);\n hist.resetCursor();\n mention.syncCaret();\n }}\n onSelect={mention.syncCaret}\n onKeyDown={onKeyDown}\n onPaste={(e) => {\n if (uploadFiles && e.clipboardData.files.length > 0) {\n e.preventDefault();\n void files.add(e.clipboardData.files);\n }\n }}\n style={{ maxHeight: maxRows * LINE_HEIGHT }}\n className=\"w-full resize-none bg-transparent px-2 py-1 text-sm leading-[22px] text-foreground outline-none placeholder:text-muted-foreground\"\n />\n\n {(guidelinesToggle || (showGuidelines && guidelineToggles.length > 0)) && (\n <div className=\"px-1 pt-1.5\">\n <TagChips\n tags={showGuidelines ? guidelineToggles : []}\n selected={gl.selected}\n onToggle={gl.toggle}\n showMax={showMax}\n expanded={expanded}\n onExpand={() => setExpanded(true)}\n leading={\n guidelinesToggle ? (\n <GuidelinesSwitch on={guidelinesOn} onToggle={() => setGuidelinesOn((v) => !v)} />\n ) : undefined\n }\n />\n </div>\n )}\n\n {tagToggles.length > 0 && (\n <div className=\"px-1 pt-1.5\">\n <TagScrollList\n tags={tagToggles}\n selected={gl.selected}\n onToggle={gl.toggle}\n rows={tagListRows}\n />\n </div>\n )}\n\n {files.error && <p className=\"px-2 pt-1 text-xs text-destructive\">{files.error}</p>}\n\n <div className=\"mt-1.5 flex items-center gap-1.5 px-1\">\n {uploadFiles !== undefined || accept !== undefined || maxFiles !== undefined ? (\n <>\n <input\n ref={fileRef}\n type=\"file\"\n multiple\n accept={accept}\n className=\"hidden\"\n onChange={(e) => void files.add(e.target.files)}\n onClick={(e) => {\n (e.currentTarget as HTMLInputElement).value = '';\n }}\n />\n <IconButton\n label=\"Attach files\"\n disabled={busy}\n onClick={() => fileRef.current?.click()}\n >\n {files.uploading ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Paperclip className=\"size-4\" />\n )}\n </IconButton>\n </>\n ) : null}\n\n {toolbarExtra}\n\n <div className=\"ml-auto flex items-center gap-1.5\">\n {historyEnabled && hist.entries.length > 0 && (\n <IconButton label=\"History\" onClick={() => setSheetOpen(true)}>\n <History className=\"size-4\" />\n </IconButton>\n )}\n <button\n type=\"button\"\n aria-label=\"Send\"\n disabled={!canSend}\n onClick={submit}\n className={cn(\n 'inline-flex size-8 items-center justify-center rounded-lg transition-colors',\n canSend\n ? 'bg-primary text-primary-foreground hover:bg-primary/90'\n : 'bg-muted text-muted-foreground',\n )}\n >\n <SendHorizontal className=\"size-4\" />\n </button>\n </div>\n </div>\n </div>\n )}\n\n {sheetOpen && (\n <HistorySheet\n entries={hist.entries}\n onClose={() => setSheetOpen(false)}\n onPick={(v) => {\n setValue(v);\n setSheetOpen(false);\n requestAnimationFrame(() => {\n const el = taRef.current;\n el?.focus();\n el?.setSelectionRange(v.length, v.length);\n });\n }}\n />\n )}\n </div>\n );\n});\n\nfunction IconButton({\n label,\n disabled,\n onClick,\n children,\n}: {\n label: string;\n disabled?: boolean;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={onClick}\n className=\"inline-flex size-8 items-center justify-center rounded-lg border border-transparent text-muted-foreground transition-colors hover:border-input hover:text-foreground disabled:opacity-50\"\n >\n {children}\n </button>\n );\n}\n"],"names":["LINE_HEIGHT","RichInput","forwardRef","defaultValue","placeholder","disabled","className","autoFocus","minRows","maxRows","onSubmit","undoWindowMs","submitKey","cacheKey","cacheLocation","uploadFiles","accept","maxFiles","fileFilter","fileDrop","dropDirectories","tags","onTagsChange","guidelines","guidelinesToggle","defaultGuidelinesOn","onGuidelinesToggle","tagListRows","showMax","mentionPrefix","historyEnabled","composePrompt","defaultComposePrompt","toolbarExtra","ref","taRef","useRef","fileRef","value","setValueRaw","clearDraft","useDraft","seeded","setSeeded","useState","gl","useGuidelines","files","useFileUpload","hist","useInputHistory","filesEnabled","busy","drop","useFileDrop","list","coarse","setCoarse","expanded","setExpanded","sheetOpen","setSheetOpen","guidelinesOn","setGuidelinesOn","guidelinesActive","rsearch","setRsearch","pending","setPending","countdown","setCountdown","queueTimer","tickTimer","setValue","useCallback","v","useEffect","mq","update","_a","mention","useMention","tag","useLayoutEffect","el","clearTimers","resetInput","guidelineToggles","t","tagToggles","showGuidelines","buildPayload","base","lines","prompt","fire","payload","submit","c","cancelSend","restored","useImperativeHandle","f","recallPrev","got","recallNext","openReverse","reverseType","query","reverseNext","s","reverseAccept","m","onKeyDown","atStart","atEnd","mod","wantsSubmit","canSend","cn","jsx","UnsendBanner","jsxs","Upload","ReverseSearchBar","MentionMenu","AttachmentChips","TagChips","GuidelinesSwitch","TagScrollList","Fragment","IconButton","Loader2","Paperclip","History","SendHorizontal","HistorySheet","label","onClick","children","e"],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { ReactNode } from 'react';
2
+ /** A file that has been accepted (and usually uploaded) by the composer. */
3
+ export interface RichFile {
4
+ /** Stable identity used for de-dupe and removal. */
5
+ id: string;
6
+ name: string;
7
+ size: number;
8
+ contentType: string;
9
+ /** Optional preview/serve URL — images with a `url` render as a thumbnail. */
10
+ url?: string;
11
+ /** Arbitrary caller payload (e.g. a repo-relative path to weave into the prompt). */
12
+ meta?: unknown;
13
+ }
14
+ /**
15
+ * A guideline tag. In its default form it is a toggle chip that injects
16
+ * {@link prompt} into the composed text when on (or {@link promptOff} when off).
17
+ * With `kind: 'mention'` it is hidden from the chip row and only reachable by
18
+ * typing the mention prefix (`#` by default) + its {@link slug}.
19
+ */
20
+ export interface GuidelineTag {
21
+ id: string;
22
+ label: string;
23
+ /** Alternate label shown while the toggle is off. */
24
+ labelOff?: string;
25
+ /** Text woven into the composed prompt while the tag is on. */
26
+ prompt?: string;
27
+ /** Text woven in while the tag is off (for either/or toggles). */
28
+ promptOff?: string;
29
+ /** Whether the toggle starts on. Default false. */
30
+ defaultOn?: boolean;
31
+ /** Leading icon for the chip / mention row. */
32
+ icon?: ReactNode;
33
+ /** `'toggle'` (a chip, default) or `'mention'` (search-only). */
34
+ kind?: 'toggle' | 'mention';
35
+ /**
36
+ * Which cluster a toggle chip renders in:
37
+ * - `'guideline'` (default) — a chip in the guideline row, governed by the
38
+ * guidelines master switch (see {@link RichInputProps.guidelinesToggle}).
39
+ * - `'tag'` — a chip in the scrollable tag list (e.g. project/service
40
+ * locations); never affected by the guidelines switch.
41
+ */
42
+ group?: 'guideline' | 'tag';
43
+ /**
44
+ * Radio behaviour: tags sharing an `exclusive` key are mutually exclusive —
45
+ * turning one on turns the others in that key off (e.g. a model picker).
46
+ * Turning the active one off again leaves the key with no selection.
47
+ */
48
+ exclusive?: string;
49
+ /** Token typed after the prefix to insert this tag. Defaults to `id`. */
50
+ slug?: string;
51
+ /** One-line blurb shown in the mention menu. */
52
+ description?: string;
53
+ }
54
+ /** What `onSubmit` receives (and what an un-send restores). */
55
+ export interface RichSendPayload {
56
+ /** Raw textarea text. */
57
+ text: string;
58
+ /** Composed text: guidelines + tags + attachments woven into `text`. */
59
+ prompt: string;
60
+ /** Attached files at submit time. */
61
+ files: RichFile[];
62
+ /** Tags that were active (toggled on, or picked via mention). */
63
+ tags: GuidelineTag[];
64
+ }
65
+ /** Inputs handed to a custom {@link RichInputProps.composePrompt}. */
66
+ export interface ComposeInput {
67
+ text: string;
68
+ /** Injected lines from the active guideline tags. */
69
+ guidelines: string[];
70
+ /** The active tags themselves. */
71
+ tags: GuidelineTag[];
72
+ files: RichFile[];
73
+ }
74
+ /** Imperative handle exposed through `ref`. */
75
+ export interface RichInputHandle {
76
+ focus: () => void;
77
+ blur: () => void;
78
+ /** Clear the text, attachments and tag selection (and the cached draft). */
79
+ clear: () => void;
80
+ getValue: () => string;
81
+ setValue: (value: string) => void;
82
+ /** Replace the attachment list (e.g. to restore files after an external un-send). */
83
+ setFiles: (files: RichFile[]) => void;
84
+ /** Programmatically submit (starts the un-send window). */
85
+ submit: () => void;
86
+ /**
87
+ * Cancel a submission still inside its un-send window and get the payload
88
+ * back (or `null` if nothing is pending / it already fired).
89
+ */
90
+ cancelSend: () => RichSendPayload | null;
91
+ }
92
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/rich-input/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,4EAA4E;AAC5E,MAAM,WAAW,QAAQ;IACvB,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,iEAAiE;IACjE,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAC5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,iEAAiE;IACjE,IAAI,EAAE,YAAY,EAAE,CAAC;CACtB;AAED,sEAAsE;AACtE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kCAAkC;IAClC,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,4EAA4E;IAC5E,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,qFAAqF;IACrF,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACtC,2DAA2D;IAC3D,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;;OAGG;IACH,UAAU,EAAE,MAAM,eAAe,GAAG,IAAI,CAAC;CAC1C"}
@@ -0,0 +1,9 @@
1
+ type Where = 'local' | 'session';
2
+ /**
3
+ * A debounced, storage-backed draft. Returns `[value, setValue, clear]`. When
4
+ * `key` is falsy the value is kept purely in memory. An empty value removes the
5
+ * stored key; changing `key` re-loads its draft.
6
+ */
7
+ export declare function useDraft(key: string | null | undefined, where?: Where, debounceMs?: number): readonly [string, (v: string) => void, () => void];
8
+ export {};
9
+ //# sourceMappingURL=use-draft.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-draft.d.ts","sourceRoot":"","sources":["../../../src/components/rich-input/use-draft.ts"],"names":[],"mappings":"AAKA,KAAK,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;AAqBjC;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC9B,KAAK,GAAE,KAAe,EACtB,UAAU,SAAsB,GAC/B,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAAE,MAAM,IAAI,CAAC,CAqCpD"}
@@ -0,0 +1,47 @@
1
+ import { useState as m, useRef as d, useEffect as p, useCallback as w } from "react";
2
+ const E = "rich-input:draft:", I = 250;
3
+ function s(n) {
4
+ if (typeof window > "u") return null;
5
+ try {
6
+ return n === "session" ? window.sessionStorage : window.localStorage;
7
+ } catch {
8
+ return null;
9
+ }
10
+ }
11
+ function a(n, r) {
12
+ const o = n ? s(r) : null;
13
+ if (!o || !n) return "";
14
+ try {
15
+ return o.getItem(n) ?? "";
16
+ } catch {
17
+ return "";
18
+ }
19
+ }
20
+ function v(n, r = "local", o = I) {
21
+ const t = n ? E + n : null, [u, c] = m(() => a(t, r)), i = d(t);
22
+ i.current !== t && (i.current = t, c(a(t, r))), p(() => {
23
+ if (!t) return;
24
+ const e = s(r);
25
+ if (!e) return;
26
+ const f = window.setTimeout(() => {
27
+ try {
28
+ u ? e.setItem(t, u) : e.removeItem(t);
29
+ } catch {
30
+ }
31
+ }, o);
32
+ return () => window.clearTimeout(f);
33
+ }, [u, t, r, o]);
34
+ const l = w(() => {
35
+ var e;
36
+ if (c(""), !!t)
37
+ try {
38
+ (e = s(r)) == null || e.removeItem(t);
39
+ } catch {
40
+ }
41
+ }, [t, r]);
42
+ return [u, c, l];
43
+ }
44
+ export {
45
+ v as useDraft
46
+ };
47
+ //# sourceMappingURL=use-draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-draft.js","sources":["../../../src/components/rich-input/use-draft.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nconst PREFIX = 'rich-input:draft:';\nconst DEFAULT_DEBOUNCE_MS = 250;\n\ntype Where = 'local' | 'session';\n\nfunction store(where: Where): Storage | null {\n if (typeof window === 'undefined') return null;\n try {\n return where === 'session' ? window.sessionStorage : window.localStorage;\n } catch {\n return null;\n }\n}\n\nfunction read(key: string | null, where: Where): string {\n const s = key ? store(where) : null;\n if (!s || !key) return '';\n try {\n return s.getItem(key) ?? '';\n } catch {\n return '';\n }\n}\n\n/**\n * A debounced, storage-backed draft. Returns `[value, setValue, clear]`. When\n * `key` is falsy the value is kept purely in memory. An empty value removes the\n * stored key; changing `key` re-loads its draft.\n */\nexport function useDraft(\n key: string | null | undefined,\n where: Where = 'local',\n debounceMs = DEFAULT_DEBOUNCE_MS,\n): readonly [string, (v: string) => void, () => void] {\n const storageKey = key ? PREFIX + key : null;\n const [value, setValue] = useState<string>(() => read(storageKey, where));\n\n // Re-load when the key changes (reset during render, no effect flash).\n const prevKey = useRef(storageKey);\n if (prevKey.current !== storageKey) {\n prevKey.current = storageKey;\n setValue(read(storageKey, where));\n }\n\n useEffect(() => {\n if (!storageKey) return;\n const s = store(where);\n if (!s) return;\n const t = window.setTimeout(() => {\n try {\n if (value) s.setItem(storageKey, value);\n else s.removeItem(storageKey);\n } catch {\n /* best-effort */\n }\n }, debounceMs);\n return () => window.clearTimeout(t);\n }, [value, storageKey, where, debounceMs]);\n\n const clear = useCallback(() => {\n setValue('');\n if (!storageKey) return;\n try {\n store(where)?.removeItem(storageKey);\n } catch {\n /* ignore */\n }\n }, [storageKey, where]);\n\n return [value, setValue, clear] as const;\n}\n"],"names":["PREFIX","DEFAULT_DEBOUNCE_MS","store","where","read","key","s","useDraft","debounceMs","storageKey","value","setValue","useState","prevKey","useRef","useEffect","t","clear","useCallback","_a"],"mappings":";AAEA,MAAMA,IAAS,qBACTC,IAAsB;AAI5B,SAASC,EAAMC,GAA8B;AAC3C,MAAI,OAAO,SAAW,IAAa,QAAO;AAC1C,MAAI;AACF,WAAOA,MAAU,YAAY,OAAO,iBAAiB,OAAO;AAAA,EAC9D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,EAAKC,GAAoBF,GAAsB;AACtD,QAAMG,IAAID,IAAMH,EAAMC,CAAK,IAAI;AAC/B,MAAI,CAACG,KAAK,CAACD,EAAK,QAAO;AACvB,MAAI;AACF,WAAOC,EAAE,QAAQD,CAAG,KAAK;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOO,SAASE,EACdF,GACAF,IAAe,SACfK,IAAaP,GACuC;AACpD,QAAMQ,IAAaJ,IAAML,IAASK,IAAM,MAClC,CAACK,GAAOC,CAAQ,IAAIC,EAAiB,MAAMR,EAAKK,GAAYN,CAAK,CAAC,GAGlEU,IAAUC,EAAOL,CAAU;AACjC,EAAII,EAAQ,YAAYJ,MACtBI,EAAQ,UAAUJ,GAClBE,EAASP,EAAKK,GAAYN,CAAK,CAAC,IAGlCY,EAAU,MAAM;AACd,QAAI,CAACN,EAAY;AACjB,UAAMH,IAAIJ,EAAMC,CAAK;AACrB,QAAI,CAACG,EAAG;AACR,UAAMU,IAAI,OAAO,WAAW,MAAM;AAChC,UAAI;AACF,QAAIN,IAAOJ,EAAE,QAAQG,GAAYC,CAAK,IACjCJ,EAAE,WAAWG,CAAU;AAAA,MAC9B,QAAQ;AAAA,MAER;AAAA,IACF,GAAGD,CAAU;AACb,WAAO,MAAM,OAAO,aAAaQ,CAAC;AAAA,EACpC,GAAG,CAACN,GAAOD,GAAYN,GAAOK,CAAU,CAAC;AAEzC,QAAMS,IAAQC,EAAY,MAAM;;AAE9B,QADAP,EAAS,EAAE,GACP,EAACF;AACL,UAAI;AACF,SAAAU,IAAAjB,EAAMC,CAAK,MAAX,QAAAgB,EAAc,WAAWV;AAAA,MAC3B,QAAQ;AAAA,MAER;AAAA,EACF,GAAG,CAACA,GAAYN,CAAK,CAAC;AAEtB,SAAO,CAACO,GAAOC,GAAUM,CAAK;AAChC;"}
@@ -0,0 +1,18 @@
1
+ import { RichFile } from './types';
2
+ export interface FileUpload {
3
+ files: RichFile[];
4
+ uploading: boolean;
5
+ error: string | null;
6
+ add: (list: FileList | File[] | null) => Promise<void>;
7
+ remove: (id: string) => void;
8
+ reset: () => void;
9
+ setFiles: (files: RichFile[]) => void;
10
+ }
11
+ export declare function useFileUpload({ upload, accept, maxFiles, filter, }: {
12
+ upload?: (files: File[]) => Promise<RichFile[]>;
13
+ accept?: string;
14
+ maxFiles?: number;
15
+ /** Return `true` to keep, `false`/reason-string to reject a file. */
16
+ filter?: (file: File) => boolean | string;
17
+ }): FileUpload;
18
+ //# sourceMappingURL=use-file-upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-file-upload.d.ts","sourceRoot":"","sources":["../../../src/components/rich-input/use-file-upload.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA8BxC,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;CACvC;AAED,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,MAAM,EACN,QAAQ,EACR,MAAM,GACP,EAAE;IACD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,GAAG,MAAM,CAAC;CAC3C,GAAG,UAAU,CAyEb"}